* Clarify video capture method * fix improper level of pointer usage of xcb_generic_error_t * add ffi of xcb_shm_query_version * throw a warn about MIT-SHM not working * add missing #[cfg] * checks SHM validity on the fly, rather than cache on creation --------- Co-authored-by: root <root@localhost> Co-authored-by: rustdesk-fork <rustdesk@fork.com>
		
			
				
	
	
		
			139 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			139 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| use crate::{common::TraitCapturer, x11, Frame, Pixfmt, TraitPixelBuffer};
 | |
| use std::{io, time::Duration};
 | |
| 
 | |
| pub struct Capturer(x11::Capturer);
 | |
| 
 | |
| pub const IS_CURSOR_EMBEDDED: bool = false;
 | |
| 
 | |
| impl Capturer {
 | |
|     pub fn new(display: Display) -> io::Result<Capturer> {
 | |
|         x11::Capturer::new(display.0).map(Capturer)
 | |
|     }
 | |
| 
 | |
|     pub fn width(&self) -> usize {
 | |
|         self.0.display().rect().w as usize
 | |
|     }
 | |
| 
 | |
|     pub fn height(&self) -> usize {
 | |
|         self.0.display().rect().h as usize
 | |
|     }
 | |
| }
 | |
| 
 | |
| impl TraitCapturer for Capturer {
 | |
|     fn frame<'a>(&'a mut self, _timeout: Duration) -> io::Result<Frame<'a>> {
 | |
|         let width = self.width();
 | |
|         let height = self.height();
 | |
|         Ok(Frame::PixelBuffer(PixelBuffer::new(
 | |
|             self.0.frame()?,
 | |
|             Pixfmt::BGRA,
 | |
|             width,
 | |
|             height,
 | |
|         )))
 | |
|     }
 | |
| }
 | |
| 
 | |
| pub struct PixelBuffer<'a> {
 | |
|     data: &'a [u8],
 | |
|     pixfmt: Pixfmt,
 | |
|     width: usize,
 | |
|     height: usize,
 | |
|     stride: Vec<usize>,
 | |
| }
 | |
| 
 | |
| impl<'a> PixelBuffer<'a> {
 | |
|     pub fn new(data: &'a [u8], pixfmt: Pixfmt, width: usize, height: usize) -> Self {
 | |
|         let stride0 = data.len() / height;
 | |
|         let mut stride = Vec::new();
 | |
|         stride.push(stride0);
 | |
|         Self {
 | |
|             data,
 | |
|             pixfmt,
 | |
|             width,
 | |
|             height,
 | |
|             stride,
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| impl<'a> TraitPixelBuffer for PixelBuffer<'a> {
 | |
|     fn data(&self) -> &[u8] {
 | |
|         self.data
 | |
|     }
 | |
| 
 | |
|     fn width(&self) -> usize {
 | |
|         self.width
 | |
|     }
 | |
| 
 | |
|     fn height(&self) -> usize {
 | |
|         self.height
 | |
|     }
 | |
| 
 | |
|     fn stride(&self) -> Vec<usize> {
 | |
|         self.stride.clone()
 | |
|     }
 | |
| 
 | |
|     fn pixfmt(&self) -> crate::Pixfmt {
 | |
|         self.pixfmt
 | |
|     }
 | |
| }
 | |
| 
 | |
| pub struct Display(x11::Display);
 | |
| 
 | |
| impl Display {
 | |
|     pub fn primary() -> io::Result<Display> {
 | |
|         let server = match x11::Server::default() {
 | |
|             Ok(server) => server,
 | |
|             Err(_) => return Err(io::ErrorKind::ConnectionRefused.into()),
 | |
|         };
 | |
| 
 | |
|         let mut displays = x11::Server::displays(server);
 | |
|         let mut best = displays.next();
 | |
|         if best.as_ref().map(|x| x.is_default()) == Some(false) {
 | |
|             best = displays.find(|x| x.is_default()).or(best);
 | |
|         }
 | |
| 
 | |
|         match best {
 | |
|             Some(best) => Ok(Display(best)),
 | |
|             None => Err(io::ErrorKind::NotFound.into()),
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     pub fn all() -> io::Result<Vec<Display>> {
 | |
|         let server = match x11::Server::default() {
 | |
|             Ok(server) => server,
 | |
|             Err(_) => return Err(io::ErrorKind::ConnectionRefused.into()),
 | |
|         };
 | |
| 
 | |
|         Ok(x11::Server::displays(server).map(Display).collect())
 | |
|     }
 | |
| 
 | |
|     pub fn width(&self) -> usize {
 | |
|         self.0.rect().w as usize
 | |
|     }
 | |
| 
 | |
|     pub fn height(&self) -> usize {
 | |
|         self.0.rect().h as usize
 | |
|     }
 | |
| 
 | |
|     pub fn origin(&self) -> (i32, i32) {
 | |
|         let r = self.0.rect();
 | |
|         (r.x as _, r.y as _)
 | |
|     }
 | |
| 
 | |
|     pub fn is_online(&self) -> bool {
 | |
|         true
 | |
|     }
 | |
| 
 | |
|     pub fn is_primary(&self) -> bool {
 | |
|         self.0.is_default()
 | |
|     }
 | |
| 
 | |
|     pub fn name(&self) -> String {
 | |
|         self.0.name()
 | |
|     }
 | |
| 
 | |
|     pub fn get_shm_status(&self) -> Result<(), x11::Error> {
 | |
|         self.0.server().get_shm_status()
 | |
|     }
 | |
| }
 |