2 | 2 |
|
3 | 3 |
use std::ffi::CString;
|
4 | 4 |
use std::{mem,ptr};
|
5 | |
use std::os::raw::c_int;
|
| 5 |
use std::os::raw::{c_int,c_uchar};
|
6 | 6 |
|
7 | 7 |
pub struct Window {
|
8 | 8 |
pub display: *mut xlib::_XDisplay,
|
|
46 | 46 |
}
|
47 | 47 |
}
|
48 | 48 |
|
| 49 |
pub fn set_input_masks(&mut self) {
|
| 50 |
let mut opcode = 0;
|
| 51 |
let mut event = 0;
|
| 52 |
let mut error = 0;
|
| 53 |
|
| 54 |
let xinput_str = CString::new("XInputExtension").unwrap();
|
| 55 |
unsafe {
|
| 56 |
xlib::XQueryExtension(
|
| 57 |
self.display,
|
| 58 |
xinput_str.as_ptr(),
|
| 59 |
&mut opcode,
|
| 60 |
&mut event,
|
| 61 |
&mut error,
|
| 62 |
);
|
| 63 |
}
|
| 64 |
|
| 65 |
let mut mask: [c_uchar;1] = [0];
|
| 66 |
let mut input_event_mask = xinput2::XIEventMask {
|
| 67 |
deviceid: xinput2::XIAllMasterDevices,
|
| 68 |
mask_len: mask.len() as i32,
|
| 69 |
mask: mask.as_mut_ptr(),
|
| 70 |
};
|
| 71 |
let events = &[
|
| 72 |
xinput2::XI_ButtonPress,
|
| 73 |
xinput2::XI_ButtonRelease,
|
| 74 |
];
|
| 75 |
for &event in events {
|
| 76 |
xinput2::XISetMask(&mut mask, event);
|
| 77 |
}
|
| 78 |
|
| 79 |
match unsafe {
|
| 80 |
xinput2::XISelectEvents(
|
| 81 |
self.display,
|
| 82 |
self.window,
|
| 83 |
&mut input_event_mask,
|
| 84 |
1,
|
| 85 |
)
|
| 86 |
} {
|
| 87 |
status if status as u8 == xlib::Success => (),
|
| 88 |
err => panic!("Failed to select events {:?}", err)
|
| 89 |
}
|
| 90 |
|
| 91 |
}
|
| 92 |
|
49 | 93 |
pub fn set_protocols(&mut self) {
|
50 | 94 |
let mut protocols = [self.intern("WM_DELETE_WINDOW")];
|
51 | 95 |
unsafe {
|
|
81 | 125 |
}
|
82 | 126 |
}
|
83 | 127 |
|
84 | |
pub fn change_property(&mut self, prop: &str, val: &str) {
|
| 128 |
pub fn change_property<T: XProperty>(&mut self, prop: &str, val: &[T]) {
|
85 | 129 |
let prop = self.intern(prop);
|
86 | |
let val = self.intern(val);
|
87 | |
unsafe {
|
88 | |
xlib::XChangeProperty(
|
89 | |
self.display,
|
90 | |
self.window,
|
91 | |
prop,
|
92 | |
xlib::XA_ATOM,
|
93 | |
32,
|
94 | |
xlib::PropModeReplace,
|
95 | |
mem::transmute(&val),
|
96 | |
1,
|
97 | |
);
|
| 130 |
unsafe {
|
| 131 |
let len = val.len();
|
| 132 |
T::with_ptr(val, self, |w, typ, ptr| {
|
| 133 |
xlib::XChangeProperty(
|
| 134 |
w.display,
|
| 135 |
w.window,
|
| 136 |
prop,
|
| 137 |
typ,
|
| 138 |
32,
|
| 139 |
xlib::PropModeReplace,
|
| 140 |
ptr,
|
| 141 |
len as c_int,
|
| 142 |
);
|
| 143 |
});
|
98 | 144 |
}
|
99 | 145 |
}
|
100 | 146 |
|
|
128 | 174 |
}
|
129 | 175 |
|
130 | 176 |
xlib::Expose => return Event::ShowEvent,
|
131 | |
|
| 177 |
|
132 | 178 |
xlib::GenericEvent => {
|
133 | 179 |
let mut cookie: xlib::XGenericEventCookie = From::from(e);
|
134 | 180 |
unsafe { xlib::XGetEventData(self.display, &mut cookie) };
|
|
152 | 198 |
}
|
153 | 199 |
}
|
154 | 200 |
|
155 | |
pub fn show(&mut self) {
|
156 | |
unsafe {
|
157 | |
xlib::XClearArea(
|
158 | |
self.display,
|
159 | |
self.window,
|
160 | |
0,
|
161 | |
0,
|
162 | |
3840,
|
163 | |
36,
|
164 | |
1
|
165 | |
);
|
166 | |
}
|
167 | |
}
|
168 | |
|
169 | 201 |
pub fn get_fd(&mut self) -> i32 {
|
170 | 202 |
unsafe {
|
171 | 203 |
xlib::XConnectionNumber(self.display)
|
|
173 | 205 |
}
|
174 | 206 |
}
|
175 | 207 |
|
| 208 |
pub trait XProperty : Sized {
|
| 209 |
fn with_ptr(xs: &[Self], w: &mut Window, f: impl FnOnce(&mut Window, u64, *const u8));
|
| 210 |
}
|
| 211 |
|
| 212 |
impl XProperty for i64 {
|
| 213 |
fn with_ptr(xs: &[Self], w: &mut Window, f: impl FnOnce(&mut Window, u64, *const u8)) {
|
| 214 |
f(w, xlib::XA_CARDINAL, unsafe { mem::transmute(xs.as_ptr()) })
|
| 215 |
}
|
| 216 |
}
|
| 217 |
|
| 218 |
impl XProperty for &str {
|
| 219 |
fn with_ptr(xs: &[Self], w: &mut Window, f: impl FnOnce(&mut Window, u64, *const u8)) {
|
| 220 |
let xs: Vec<u64> = xs.iter().map(|s| w.intern(s)).collect();
|
| 221 |
f(w, xlib::XA_ATOM, unsafe { mem::transmute(xs.as_ptr()) })
|
| 222 |
}
|
| 223 |
}
|
176 | 224 |
|
177 | 225 |
impl Drop for Window {
|
178 | 226 |
fn drop(&mut self) {
|