1 | // Welcome to the util module, where we try to keep you from shooting yourself in the foot. |
2 | // *results may vary |
3 | |
4 | use std::mem::{self, MaybeUninit}; |
5 | use std::ops::BitAnd; |
6 | use std::os::raw::*; |
7 | |
8 | mod client_msg; |
9 | pub mod cookie; |
10 | mod cursor; |
11 | mod geometry; |
12 | mod hint; |
13 | mod icon; |
14 | mod input; |
15 | pub mod keys; |
16 | pub(crate) mod memory; |
17 | mod mouse; |
18 | mod randr; |
19 | mod window_property; |
20 | mod wm; |
21 | mod xmodmap; |
22 | |
23 | pub use self::cursor::*; |
24 | pub use self::geometry::*; |
25 | pub use self::hint::*; |
26 | pub use self::input::*; |
27 | pub use self::mouse::*; |
28 | pub use self::window_property::*; |
29 | pub use self::wm::*; |
30 | pub use self::xmodmap::ModifierKeymap; |
31 | |
32 | use super::atoms::*; |
33 | use super::{ffi, VoidCookie, X11Error, XConnection, XError}; |
34 | use x11rb::protocol::xproto::{self, ConnectionExt as _}; |
35 | |
36 | pub fn maybe_change<T: PartialEq>(field: &mut Option<T>, value: T) -> bool { |
37 | let wrapped: Option = Some(value); |
38 | if *field != wrapped { |
39 | *field = wrapped; |
40 | true |
41 | } else { |
42 | false |
43 | } |
44 | } |
45 | |
46 | pub fn has_flag<T>(bitset: T, flag: T) -> bool |
47 | where |
48 | T: Copy + PartialEq + BitAnd<T, Output = T>, |
49 | { |
50 | bitset & flag == flag |
51 | } |
52 | |
53 | impl XConnection { |
54 | // This is impoartant, so pay attention! |
55 | // Xlib has an output buffer, and tries to hide the async nature of X from you. |
56 | // This buffer contains the requests you make, and is flushed under various circumstances: |
57 | // 1. `XPending`, `XNextEvent`, and `XWindowEvent` flush "as needed" |
58 | // 2. `XFlush` explicitly flushes |
59 | // 3. `XSync` flushes and blocks until all requests are responded to |
60 | // 4. Calls that have a return dependent on a response (i.e. `XGetWindowProperty`) sync |
61 | // internally. When in doubt, check the X11 source; if a function calls `_XReply`, it flushes |
62 | // and waits. |
63 | // All util functions that abstract an async function will return a `Flusher`. |
64 | pub fn flush_requests(&self) -> Result<(), XError> { |
65 | unsafe { (self.xlib.XFlush)(self.display) }; |
66 | // println!("XFlush"); |
67 | // This isn't necessarily a useful time to check for errors (since our request hasn't |
68 | // necessarily been processed yet) |
69 | self.check_errors() |
70 | } |
71 | |
72 | pub fn sync_with_server(&self) -> Result<(), XError> { |
73 | unsafe { (self.xlib.XSync)(self.display, ffi::False) }; |
74 | // println!("XSync"); |
75 | self.check_errors() |
76 | } |
77 | } |
78 | |