winit/platform_impl/linux/x11/util/
xmodmap.rs
1use std::collections::HashSet;
2use std::slice;
3
4use x11_dl::xlib::{KeyCode as XKeyCode, XModifierKeymap};
5
6const NUM_MODS: usize = 8;
14
15#[derive(Debug, Default)]
17pub struct ModifierKeymap {
18 modifiers: HashSet<XKeyCode>,
20}
21
22impl ModifierKeymap {
23 pub fn new() -> ModifierKeymap {
24 ModifierKeymap::default()
25 }
26
27 pub fn is_modifier(&self, keycode: XKeyCode) -> bool {
28 self.modifiers.contains(&keycode)
29 }
30
31 pub fn reload_from_x_connection(&mut self, xconn: &super::XConnection) {
32 unsafe {
33 let keymap = (xconn.xlib.XGetModifierMapping)(xconn.display);
34
35 if keymap.is_null() {
36 return;
37 }
38
39 self.reset_from_x_keymap(&*keymap);
40
41 (xconn.xlib.XFreeModifiermap)(keymap);
42 }
43 }
44
45 fn reset_from_x_keymap(&mut self, keymap: &XModifierKeymap) {
46 let keys_per_mod = keymap.max_keypermod as usize;
47
48 let keys = unsafe {
49 slice::from_raw_parts(keymap.modifiermap as *const _, keys_per_mod * NUM_MODS)
50 };
51 self.modifiers.clear();
52 for key in keys {
53 self.modifiers.insert(*key);
54 }
55 }
56}