1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#![warn(missing_docs)]
use image::RgbImage;
use std::{ptr, slice};
use x11::xlib;
pub struct Screen {
display: *mut xlib::Display,
screen: *mut xlib::Screen,
window: xlib::Window,
}
#[derive(Debug)]
struct Bgr {
b: u8,
g: u8,
r: u8,
_pad: u8,
}
impl Screen {
pub fn open() -> Option<Screen> {
unsafe {
let display = xlib::XOpenDisplay(ptr::null());
if display.is_null() {
return None;
}
let screen = xlib::XDefaultScreenOfDisplay(display);
let root = xlib::XRootWindowOfScreen(screen);
Some(Screen {
display,
screen,
window: root,
})
}
}
pub fn capture(&self) -> Option<RgbImage> {
let screen: &mut xlib::Screen = &mut unsafe { *self.screen };
self.capture_area(screen.width as u32, screen.height as u32, 0, 0)
}
pub fn capture_area(&self, w: u32, h: u32, x: i32, y: i32) -> Option<RgbImage> {
let img =
unsafe { xlib::XGetImage(self.display, self.window, x, y, w, h, !1, xlib::ZPixmap) };
if !img.is_null() {
let image = unsafe { &mut *img };
let sl: &[Bgr] = unsafe {
slice::from_raw_parts(
(image).data as *const _,
(image).width as usize * (image).height as usize,
)
};
let mut bgr_iter = sl.iter();
let mut image_buffer = RgbImage::new(w, h);
for pix in image_buffer.pixels_mut() {
let bgr = bgr_iter.next().unwrap();
pix.0 = [bgr.r, bgr.g, bgr.b];
}
unsafe {
xlib::XDestroyImage(img as *mut _);
}
Some(image_buffer)
} else {
None
}
}
}
impl Drop for Screen {
fn drop(&mut self) {
unsafe {
xlib::XCloseDisplay(self.display);
}
}
}