From 47f8231d337bde4f77a8e86ae860c7c2b4195e25 Mon Sep 17 00:00:00 2001 From: moparisthebest Date: Wed, 15 Nov 2017 22:59:17 -0500 Subject: [PATCH] Share keymap with Arc --- src/device/builder.rs | 4 ++-- src/keymapper.rs | 18 +++++++++--------- src/main.rs | 37 +++++++++++++++++++------------------ 3 files changed, 30 insertions(+), 29 deletions(-) diff --git a/src/device/builder.rs b/src/device/builder.rs index 28bd930..526d716 100644 --- a/src/device/builder.rs +++ b/src/device/builder.rs @@ -88,7 +88,7 @@ impl Builder { self } - pub fn event(mut self, key_codes: Values<&str, *const c_int>) -> Res { + pub fn event(mut self, key_codes: Values<&str, c_int>) -> Res { self.abs = None; //let test_ev_key : c_int = EV_KEY as c_int; unsafe { @@ -97,7 +97,7 @@ impl Builder { ui_set_evbit(self.fd, EV_KEY as *const c_int)?; //ui_set_keybit(self.fd, KEY_H as *const c_int)?; for key_code in key_codes { - ui_set_keybit(self.fd, *key_code)?; + ui_set_keybit(self.fd, *key_code as *const c_int)?; } //try!(ui_set_keybit(self.fd, &KEY_H)); } diff --git a/src/keymapper.rs b/src/keymapper.rs index e33684f..a9718f6 100644 --- a/src/keymapper.rs +++ b/src/keymapper.rs @@ -41,18 +41,18 @@ pub struct KeyMaps { current_keymap_index: usize, } -fn parse_key(key_map: &HashMap<&'static str, *const c_int>, key: &str) -> u16 { +fn parse_key(key_map: &HashMap<&'static str, c_int>, key: &str) -> u16 { match key_map.get(key.trim_matches(|c: char| c.is_whitespace() || c == INVERT_KEY_FLAG || c == CAPS_MODIFY_KEY_FLAG)) { Some(key_code) => *key_code as u16, None => panic!("unknown key: {}", key.trim()) } } -fn parse_keymap_numeric(key_map: &HashMap<&'static str, *const c_int>, keymap: &str) -> Vec { +fn parse_keymap_numeric(key_map: &HashMap<&'static str, c_int>, keymap: &str) -> Vec { keymap.split(",").map(|k| parse_key(key_map, k)).collect() } -fn parse_key_half_inverted(key_map: &HashMap<&'static str, *const c_int>, key: &str) -> HalfInvertedKey { +fn parse_key_half_inverted(key_map: &HashMap<&'static str, c_int>, key: &str) -> HalfInvertedKey { HalfInvertedKey { code: parse_key(key_map, key), invert_shift: key.contains(INVERT_KEY_FLAG), @@ -61,12 +61,12 @@ fn parse_key_half_inverted(key_map: &HashMap<&'static str, *const c_int>, key: & } // maybe shortcut to this if not contains * or : -fn parse_keymap_u16(key_map: &HashMap<&'static str, *const c_int>, keymap: &str) -> Vec { +fn parse_keymap_u16(key_map: &HashMap<&'static str, c_int>, keymap: &str) -> Vec { keymap.split(",").map(|k| parse_key(key_map, k)).collect() } // todo: how do I return an iterator here instead of .collect to Vec? -fn parse_keymap(key_map: &HashMap<&'static str, *const c_int>, keymap: &str) -> Vec { +fn parse_keymap(key_map: &HashMap<&'static str, c_int>, keymap: &str) -> Vec { keymap.split(",").map(|k| { let ret: Key = if k.contains(HALF_KEY_SEPARATOR) { let keys: Vec<&str> = k.split(HALF_KEY_SEPARATOR).collect(); @@ -86,12 +86,12 @@ fn parse_keymap(key_map: &HashMap<&'static str, *const c_int>, keymap: &str) -> } impl KeyMaps { - pub fn from_cfg>(key_map: &HashMap<&'static str, *const c_int>, path: P) -> KeyMaps { + pub fn from_cfg>(key_map: &HashMap<&'static str, c_int>, path: P) -> KeyMaps { let key_map_config = parse_cfg(path).expect("provided config cannot be found/parsed"); KeyMaps::new(key_map, key_map_config) } - pub fn new(key_map: &HashMap<&'static str, *const c_int>, config: KeymapConfig) -> KeyMaps { + pub fn new(key_map: &HashMap<&'static str, c_int>, config: KeymapConfig) -> KeyMaps { if config.keymaps.len() < 2 { panic!("must have at least 2 keymaps (original and mapped) but only have {},", config.keymaps.len()); } @@ -420,7 +420,7 @@ fn parse_cfg>(path: P) -> Result { } impl KeyMaps { - pub fn key_map() -> HashMap<&'static str, *const c_int> { + pub fn key_map() -> HashMap<&'static str, c_int> { [ // generated like: // grep -o 'KEY_[^ :;]*' ~/.cargo/registry/src/github.com-1ecc6299db9ec823/uinput-sys-0.1.3/src/events.rs | sed 's/^KEY_//' | awk '{print "(\""$1"\", KEY_"$1"),"}' @@ -728,6 +728,6 @@ impl KeyMaps { ("P0", KEY_KP0), ("PDOT", KEY_KPDOT), ("PENT", KEY_KPENTER), - ].iter().cloned().map(|(m, v)| (m, v as *const c_int)).collect() + ].iter().cloned().map(|(m, v)| (m, v)).collect() } } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 20bbdca..1a9226e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,7 +20,8 @@ use std::fs::File; use std::io::Read; use std::{env, mem}; use std::thread; -use std::sync::mpsc; +use std::sync::{Arc, mpsc}; +use std::collections::HashMap; use std::os::unix::io::AsRawFd; @@ -52,6 +53,9 @@ fn main() { let config = parse_args(); //println!("Config: {:?}", config); + let key_map = Arc::new(KeyMaps::key_map()); + //println!("key_map: {:?}", key_map); + if config.device_files.len() > 0 { // we only want to operate on device files sent in then quit let (tx, rx) = mpsc::channel(); @@ -60,8 +64,9 @@ fn main() { let device_file = device_file.clone(); let config_file = config.config_file.clone(); let tx = tx.clone(); + let key_map = Arc::clone(&key_map); thread::spawn(move || { - let ret = spawn_map_thread(&device_file, &config_file); + let ret = spawn_map_thread(key_map, &device_file, &config_file); if let Err(e) = ret { println!("mapping for {} ended due to error: {}", device_file, e); } @@ -85,7 +90,7 @@ fn main() { let device_files = get_keyboard_device_filenames(); println!("Detected devices: {:?}", device_files); for device_file in device_files.iter() { - inotify_spawn_thread(device_file, config.config_file.clone()); + inotify_spawn_thread(&key_map, device_file, config.config_file.clone()); } let mut buffer = [0u8; 4096]; @@ -95,16 +100,14 @@ fn main() { if let Ok(events) = events { for event in events { if !event.mask.contains(EventMask::ISDIR) { - if let Some(name) = event.name { - if let Some(device_file) = name.to_str() { - // check if this is an eligible keyboard device - let device_files = get_keyboard_device_filenames(); - if !device_files.contains(&device_file.to_string()) { - continue; - } - println!("starting mapping thread for: {}", device_file); - inotify_spawn_thread(device_file.clone(), config.config_file.clone()); + if let Some(device_file) = event.name.and_then(|name|name.to_str()) { + // check if this is an eligible keyboard device + let device_files = get_keyboard_device_filenames(); + if !device_files.contains(&device_file.to_string()) { + continue; } + println!("starting mapping thread for: {}", device_file); + inotify_spawn_thread(&key_map, device_file.clone(), config.config_file.clone()); } } } @@ -113,24 +116,22 @@ fn main() { } } -fn inotify_spawn_thread(device_file: &str, config_file: String) { +fn inotify_spawn_thread(key_map: &Arc>, device_file: &str, config_file: String) { let mut filename = "/dev/input/".to_string(); filename.push_str(&device_file); + let key_map = Arc::clone(&key_map); thread::spawn(move || { - let ret = spawn_map_thread(&filename, &config_file); + let ret = spawn_map_thread(key_map, &filename, &config_file); if let Err(e) = ret { println!("mapping for {} ended due to error: {}", filename, e); } }); } -fn spawn_map_thread(device_file: &str, config_file: &str) -> Result<()> { +fn spawn_map_thread(key_map: Arc>, device_file: &str, config_file: &str) -> Result<()> { let mut input_device = InputDevice::open(device_file)?; input_device.grab()?; - let key_map = KeyMaps::key_map(); - //println!("key_map: {:?}", key_map); - let device = rusty_keys::open("/dev/uinput") .or_else(|_| rusty_keys::open("/dev/input/uinput")) .or_else(|_| rusty_keys::default())?