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
use libc;
use std::ptr;
use std::rc::Rc;
use super::{Display, Rect, Server};
use super::ffi::*;
pub struct DisplayIter {
outer: xcb_screen_iterator_t,
inner: Option<(xcb_randr_monitor_info_iterator_t, xcb_window_t)>,
server: Rc<Server>,
}
impl DisplayIter {
pub unsafe fn new(server: Rc<Server>) -> DisplayIter {
let mut outer = xcb_setup_roots_iterator(server.setup());
let inner = Self::next_screen(&mut outer, &server);
DisplayIter { outer, inner, server }
}
fn next_screen(
outer: &mut xcb_screen_iterator_t,
server: &Server
) -> Option<(xcb_randr_monitor_info_iterator_t, xcb_window_t)> {
if outer.rem == 0 {
return None;
}
unsafe {
let root = (*outer.data).root;
let cookie = xcb_randr_get_monitors_unchecked(
server.raw(),
root,
1,
);
let response = xcb_randr_get_monitors_reply(
server.raw(),
cookie,
ptr::null_mut(),
);
let inner = xcb_randr_get_monitors_monitors_iterator(response);
libc::free(response as *mut _);
xcb_screen_next(outer);
Some((inner, root))
}
}
}
impl Iterator for DisplayIter {
type Item = Display;
fn next(&mut self) -> Option<Display> {
loop {
if let Some((ref mut inner, root)) = self.inner {
if inner.rem != 0 {unsafe {
let data = &*inner.data;
let display = Display::new(
self.server.clone(),
data.primary != 0,
Rect {
x: data.x,
y: data.y,
w: data.width,
h: data.height,
},
root
);
xcb_randr_monitor_info_next(inner);
return Some(display);
}}
} else {
return None;
}
self.inner = Self::next_screen(&mut self.outer, &self.server);
}
}
}