Share keymap with Arc

This commit is contained in:
Travis Burtrum 2017-11-15 22:59:17 -05:00
parent 363ede21d3
commit 47f8231d33
3 changed files with 30 additions and 29 deletions

View File

@ -88,7 +88,7 @@ impl Builder {
self
}
pub fn event(mut self, key_codes: Values<&str, *const c_int>) -> Res<Self> {
pub fn event(mut self, key_codes: Values<&str, c_int>) -> Res<Self> {
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));
}

View File

@ -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<u16> {
fn parse_keymap_numeric(key_map: &HashMap<&'static str, c_int>, keymap: &str) -> Vec<u16> {
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<u16> {
fn parse_keymap_u16(key_map: &HashMap<&'static str, c_int>, keymap: &str) -> Vec<u16> {
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<Key> {
fn parse_keymap(key_map: &HashMap<&'static str, c_int>, keymap: &str) -> Vec<Key> {
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<P: AsRef<Path>>(key_map: &HashMap<&'static str, *const c_int>, path: P) -> KeyMaps {
pub fn from_cfg<P: AsRef<Path>>(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<P: AsRef<Path>>(path: P) -> Result<KeymapConfig> {
}
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()
}
}

View File

@ -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<HashMap<&'static str, c_int>>, 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<HashMap<&'static str, c_int>>, 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())?