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