gdritter repos knurling / b318e31
Add an abstraction for polymorphic XChangeProperty Getty Ritter 5 years ago
2 changed file(s) with 94 addition(s) and 97 deletion(s). Collapse all Expand all
11 mod window;
22
3 use x11::xlib;
4 use x11::xinput2;
5
6 use std::ffi::CString;
7 use std::os::raw::{c_int,c_uchar};
83 use std::ptr;
94 use std::io::Write;
105 use std::os::unix::io::AsRawFd;
1611 fn main() {
1712 unsafe {
1813 let mut w = Window::create();
19 w.change_property("_NET_WM_WINDOW_TYPE", "_NET_WM_WINDOW_TYPE_DOCK");
14 w.change_property(
15 "_NET_WM_WINDOW_TYPE",
16 &["_NET_WM_WINDOW_TYPE_DOCK"],
17 );
2018
21 {
22 let prop = w.intern("_NET_WM_STRUT_PARTIAL");
23 let val = [
24 0i64, 0, 36, 0,
25 0, 0, 0, 0,
26 0, 3840, 0, 0,
27 ];
28 xlib::XChangeProperty(
29 w.display,
30 w.window,
31 prop,
32 xlib::XA_CARDINAL,
33 32,
34 xlib::PropModeReplace,
35 std::mem::transmute(val.as_ptr()),
36 val.len() as c_int,
37 );
38 }
39
40 {
41 let prop = w.intern("_NET_WM_STRUT");
42 let val = &[
43 0i64, 0, 36, 0,
44 ];
45 xlib::XChangeProperty(
46 w.display,
47 w.window,
48 prop,
49 xlib::XA_CARDINAL,
50 32,
51 xlib::PropModeReplace,
52 std::mem::transmute(val.as_ptr()),
53 val.len() as c_int,
54 );
55 }
19 w.change_property(
20 "_NET_WM_STRUT_PARTIAL",
21 &[
22 0, 0, 36, 0,
23 0, 0, 0, 0,
24 0, 3840, 0, 0i64,
25 ],
26 );
27 w.change_property(
28 "_NET_WM_STRUT",
29 &[0i64, 0, 36, 0],
30 );
5631
5732 w.set_title("rbar");
5833
59 {
60 let mut opcode = 0;
61 let mut event = 0;
62 let mut error = 0;
63 let xinput_str = CString::new("XInputExtension").unwrap();
64 let _xinput_available =
65 xlib::XQueryExtension(w.display, xinput_str.as_ptr(), &mut opcode, &mut event, &mut error);
66
67 let mut mask: [c_uchar;1] = [0];
68 let mut input_event_mask = xinput2::XIEventMask {
69 deviceid: xinput2::XIAllMasterDevices,
70 mask_len: mask.len() as i32,
71 mask: mask.as_mut_ptr(),
72 };
73 let events = &[
74 xinput2::XI_ButtonPress,
75 xinput2::XI_ButtonRelease,
76 ];
77 for &event in events {
78 xinput2::XISetMask(&mut mask, event);
79 }
80
81 match xinput2::XISelectEvents(w.display, w.window, &mut input_event_mask, 1) {
82 status if status as u8 == xlib::Success => (),
83 err => panic!("Failed to select events {:?}", err)
84 }
85 }
34 w.set_input_masks();
8635
8736 w.set_protocols();
8837 w.map();
22
33 use std::ffi::CString;
44 use std::{mem,ptr};
5 use std::os::raw::c_int;
5 use std::os::raw::{c_int,c_uchar};
66
77 pub struct Window {
88 pub display: *mut xlib::_XDisplay,
4646 }
4747 }
4848
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
4993 pub fn set_protocols(&mut self) {
5094 let mut protocols = [self.intern("WM_DELETE_WINDOW")];
5195 unsafe {
81125 }
82126 }
83127
84 pub fn change_property(&mut self, prop: &str, val: &str) {
128 pub fn change_property<T: XProperty>(&mut self, prop: &str, val: &[T]) {
85129 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 });
98144 }
99145 }
100146
128174 }
129175
130176 xlib::Expose => return Event::ShowEvent,
131
177
132178 xlib::GenericEvent => {
133179 let mut cookie: xlib::XGenericEventCookie = From::from(e);
134180 unsafe { xlib::XGetEventData(self.display, &mut cookie) };
152198 }
153199 }
154200
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
169201 pub fn get_fd(&mut self) -> i32 {
170202 unsafe {
171203 xlib::XConnectionNumber(self.display)
173205 }
174206 }
175207
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 }
176224
177225 impl Drop for Window {
178226 fn drop(&mut self) {