xmodmap_pke_umberwm/
lib.rs

1use std::collections::HashMap;
2use std::ffi::CStr;
3use xcb::xproto;
4
5pub type XmodmapPke = HashMap<u8, Vec<String>>;
6
7pub fn xmodmap_pke(conn: &xcb::Connection) -> Result<XmodmapPke, anyhow::Error> {
8    let setup = conn.get_setup();
9    let length = setup.max_keycode() - setup.min_keycode() + 1;
10    let keyboard_mapping =
11        xproto::get_keyboard_mapping(&conn, setup.min_keycode(), length).get_reply()?;
12    let keysyms = keyboard_mapping.keysyms();
13    let keysyms_per_keycode = keyboard_mapping.keysyms_per_keycode();
14    let ptr_value = unsafe { &*(keyboard_mapping.ptr) };
15    let n_keycodes = ptr_value.length / keysyms_per_keycode as u32;
16    let mut result = HashMap::new();
17    for keycode_idx in 0..n_keycodes {
18        let mut syms = vec![];
19        for keysym_idx in 0..keysyms_per_keycode {
20            let sym =
21                keysyms[keysym_idx as usize + keycode_idx as usize * keysyms_per_keycode as usize];
22            if sym != 0 {
23                let string_ptr = unsafe { x11::xlib::XKeysymToString(sym as u64) };
24                if !string_ptr.is_null() {
25                    let str: String = unsafe { CStr::from_ptr(string_ptr) }
26                        .to_str()
27                        .unwrap()
28                        .to_owned();
29                    syms.push(str);
30                } else {
31                    syms.push("NoSymbol".to_string());
32                }
33            };
34        }
35        result.insert(setup.min_keycode() + keycode_idx as u8, syms);
36    }
37    Ok(result)
38}
39
40pub fn print_xmodmap_pke(xmodmap_pke: &XmodmapPke) {
41    for (key, values) in xmodmap_pke {
42        print!("keycode {:3} =", key);
43        for value in values {
44            print!(" {}", value);
45        }
46        println!()
47    }
48}