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 49 50 51 52
use std::collections::HashMap; use std::ffi::CStr; use x11::xlib::{ Display, KeyCode, KeySym, XDisplayKeycodes, XFree, XGetKeyboardMapping, XKeysymToString, }; pub type XmodmapPke = HashMap<u8, Vec<String>>; pub unsafe fn xmodmap_pke(dpy: *mut Display) -> Result<XmodmapPke, String> { let mut xmodmap_pke_table: XmodmapPke = HashMap::new(); let mut min_keycode = 0; let mut max_keycode = 0; let mut keysyms_per_keycode = 0; let mut keymap: *mut KeySym; let origkeymap: *mut KeySym; XDisplayKeycodes(dpy, &mut min_keycode, &mut max_keycode); origkeymap = XGetKeyboardMapping( dpy, min_keycode as KeyCode, max_keycode - min_keycode + 1_i32, &mut keysyms_per_keycode, ); if origkeymap.is_null() { return Err("unable to get keyboard mapping table.".to_string()); } keymap = origkeymap; for i in min_keycode..=max_keycode { let mut max; max = keysyms_per_keycode - 1; while max >= 0 && *keymap.offset(max as isize) == 0_i64 as libc::c_ulong { max -= 1 } let mut ksyms: Vec<String> = Vec::new(); for j in 0..=max { let ks: KeySym = *keymap.offset(j as isize); let s = if ks != 0_i64 as libc::c_ulong { CStr::from_ptr(XKeysymToString(ks)).to_str().unwrap() } else { "NoSymbol" }; if !s.is_empty() { ksyms.push(s.to_string()); } else { ksyms.push(format!("{:0>4x}", ks)); } } keymap = keymap.offset(keysyms_per_keycode as isize); xmodmap_pke_table.insert(i as u8, ksyms); } XFree(origkeymap as *mut libc::c_char as *mut libc::c_void); Ok(xmodmap_pke_table) }