vncrs 0.1.1

A pure Rust VNC server library for Windows
Documentation
use super::ScreenCapture;
use crate::error::{Result, VncError};
use std::io::ErrorKind;
use std::thread;
use std::time::{Duration, Instant};

pub struct ScrapCapture {
    capturer: scrap::Capturer,
    width: u16,
    height: u16,
    stride: usize,
}

impl ScrapCapture {
    pub fn new() -> Result<Self> {
        let display = scrap::Display::primary().map_err(|e| VncError::Capture(e.to_string()))?;
        let w = display.width() as u16;
        let h = display.height() as u16;
        let capturer =
            scrap::Capturer::new(display).map_err(|e| VncError::Capture(e.to_string()))?;

        Ok(Self {
            capturer,
            width: w,
            height: h,
            stride: w as usize * 4,
        })
    }
}

impl ScreenCapture for ScrapCapture {
    fn width(&self) -> u16 {
        self.width
    }

    fn height(&self) -> u16 {
        self.height
    }

    fn stride(&self) -> usize {
        self.stride
    }

    fn capture_frame(&mut self) -> Result<Option<Vec<u8>>> {
        let start = Instant::now();
        let timeout = Duration::from_millis(50);

        loop {
            match self.capturer.frame() {
                Ok(frame) => {
                    self.stride = frame.len() / self.height as usize;

                    return Ok(Some(frame.to_vec()));
                }
                Err(ref e) if e.kind() == ErrorKind::WouldBlock => {
                    if start.elapsed() > timeout {
                        return Ok(None);
                    }
                    thread::sleep(Duration::from_millis(1));
                }
                Err(e) => return Err(VncError::Capture(e.to_string())),
            }
        }
    }
}