2023-10-27 15:44:07 +08:00
|
|
|
use crate::{common::TraitCapturer, x11, TraitFrame, Pixfmt};
|
|
|
|
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>> {
|
|
|
|
Ok(self.0.frame()?)
|
2022-07-21 20:04:39 +08:00
|
|
|
}
|
2023-10-27 15:44:07 +08:00
|
|
|
}
|
2021-03-29 15:59:14 +08:00
|
|
|
|
2023-10-27 15:44:07 +08:00
|
|
|
pub struct Frame<'a>{
|
|
|
|
pub data: &'a [u8],
|
|
|
|
pub pixfmt:Pixfmt,
|
|
|
|
pub stride:Vec<usize>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> Frame<'a> {
|
|
|
|
pub fn new(data:&'a [u8], pixfmt:Pixfmt, h:usize) -> Self {
|
|
|
|
let stride = data.len() / h;
|
|
|
|
let mut v = Vec::new();
|
|
|
|
v.push(stride);
|
|
|
|
Self { data, pixfmt, stride: v }
|
2021-03-29 15:59:14 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-27 15:44:07 +08:00
|
|
|
impl<'a> TraitFrame for Frame<'a> {
|
|
|
|
fn data(&self) -> &[u8] {
|
|
|
|
self.data
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
}
|