| 
									
										
										
										
											2024-01-02 16:58:10 +08:00
										 |  |  | use crate::{common::TraitCapturer, x11, Frame, Pixfmt, TraitPixelBuffer};
 | 
					
						
							| 
									
										
										
										
											2023-10-27 15:44:07 +08:00
										 |  |  | use std::{io, time::Duration};
 | 
					
						
							| 
									
										
										
										
											2021-03-29 15:59:14 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | pub struct Capturer(x11::Capturer);
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-05 14:58:38 +08:00
										 |  |  | pub const IS_CURSOR_EMBEDDED: bool = false;
 | 
					
						
							| 
									
										
										
										
											2022-11-29 16:36:35 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-29 15:59:14 +08:00
										 |  |  | impl Capturer {
 | 
					
						
							| 
									
										
										
										
											2023-10-27 15:44:07 +08:00
										 |  |  |     pub fn new(display: Display) -> io::Result<Capturer> {
 | 
					
						
							|  |  |  |         x11::Capturer::new(display.0).map(Capturer)
 | 
					
						
							| 
									
										
										
										
											2021-03-29 15:59:14 +08:00
										 |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     pub fn width(&self) -> usize {
 | 
					
						
							|  |  |  |         self.0.display().rect().w as usize
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     pub fn height(&self) -> usize {
 | 
					
						
							|  |  |  |         self.0.display().rect().h as usize
 | 
					
						
							|  |  |  |     }
 | 
					
						
							| 
									
										
										
										
											2022-07-21 20:04:39 +08:00
										 |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | impl TraitCapturer for Capturer {
 | 
					
						
							| 
									
										
										
										
											2023-10-27 15:44:07 +08:00
										 |  |  |     fn frame<'a>(&'a mut self, _timeout: Duration) -> io::Result<Frame<'a>> {
 | 
					
						
							| 
									
										
										
										
											2024-01-02 16:58:10 +08:00
										 |  |  |         let width = self.width();
 | 
					
						
							|  |  |  |         let height = self.height();
 | 
					
						
							|  |  |  |         Ok(Frame::PixelBuffer(PixelBuffer::new(
 | 
					
						
							|  |  |  |             self.0.frame()?,
 | 
					
						
							|  |  |  |             Pixfmt::BGRA,
 | 
					
						
							|  |  |  |             width,
 | 
					
						
							|  |  |  |             height,
 | 
					
						
							|  |  |  |         )))
 | 
					
						
							| 
									
										
										
										
											2022-07-21 20:04:39 +08:00
										 |  |  |     }
 | 
					
						
							| 
									
										
										
										
											2023-10-27 15:44:07 +08:00
										 |  |  | }
 | 
					
						
							| 
									
										
										
										
											2021-03-29 15:59:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-02 16:58:10 +08:00
										 |  |  | pub struct PixelBuffer<'a> {
 | 
					
						
							|  |  |  |     data: &'a [u8],
 | 
					
						
							|  |  |  |     pixfmt: Pixfmt,
 | 
					
						
							|  |  |  |     width: usize,
 | 
					
						
							|  |  |  |     height: usize,
 | 
					
						
							|  |  |  |     stride: Vec<usize>,
 | 
					
						
							| 
									
										
										
										
											2023-10-27 15:44:07 +08:00
										 |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-02 16:58:10 +08:00
										 |  |  | impl<'a> PixelBuffer<'a> {
 | 
					
						
							| 
									
										
										
										
											2024-01-31 17:49:09 +08:00
										 |  |  |     pub fn new(data: &'a [u8], pixfmt: Pixfmt, width: usize, height: usize) -> Self {
 | 
					
						
							| 
									
										
										
										
											2023-11-02 16:57:24 +08:00
										 |  |  |         let stride0 = data.len() / height;
 | 
					
						
							|  |  |  |         let mut stride = Vec::new();
 | 
					
						
							|  |  |  |         stride.push(stride0);
 | 
					
						
							|  |  |  |         Self {
 | 
					
						
							|  |  |  |             data,
 | 
					
						
							|  |  |  |             pixfmt,
 | 
					
						
							|  |  |  |             width,
 | 
					
						
							|  |  |  |             height,
 | 
					
						
							|  |  |  |             stride,
 | 
					
						
							|  |  |  |         }
 | 
					
						
							| 
									
										
										
										
											2021-03-29 15:59:14 +08:00
										 |  |  |     }
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-02 16:58:10 +08:00
										 |  |  | impl<'a> TraitPixelBuffer for PixelBuffer<'a> {
 | 
					
						
							| 
									
										
										
										
											2023-10-27 15:44:07 +08:00
										 |  |  |     fn data(&self) -> &[u8] {
 | 
					
						
							|  |  |  |         self.data
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-02 16:57:24 +08:00
										 |  |  |     fn width(&self) -> usize {
 | 
					
						
							|  |  |  |         self.width
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     fn height(&self) -> usize {
 | 
					
						
							|  |  |  |         self.height
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-27 15:44:07 +08:00
										 |  |  |     fn stride(&self) -> Vec<usize> {
 | 
					
						
							|  |  |  |         self.stride.clone()
 | 
					
						
							|  |  |  |     }
 | 
					
						
							| 
									
										
										
										
											2021-03-29 15:59:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-27 15:44:07 +08:00
										 |  |  |     fn pixfmt(&self) -> crate::Pixfmt {
 | 
					
						
							|  |  |  |         self.pixfmt
 | 
					
						
							| 
									
										
										
										
											2021-03-29 15:59:14 +08:00
										 |  |  |     }
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-17 20:46:02 +08:00
										 |  |  |     pub fn origin(&self) -> (i32, i32) {
 | 
					
						
							| 
									
										
										
										
											2021-03-29 15:59:14 +08:00
										 |  |  |         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 {
 | 
					
						
							| 
									
										
										
										
											2023-02-11 19:04:33 +08:00
										 |  |  |         self.0.name()
 | 
					
						
							| 
									
										
										
										
											2021-03-29 15:59:14 +08:00
										 |  |  |     }
 | 
					
						
							| 
									
										
										
										
											2024-01-31 17:49:09 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     pub fn get_shm_status(&self) -> Result<(), x11::Error> {
 | 
					
						
							|  |  |  |         self.0.server().get_shm_status()
 | 
					
						
							|  |  |  |     }
 | 
					
						
							| 
									
										
										
										
											2021-03-29 15:59:14 +08:00
										 |  |  | }
 |