Share keymap with Arc
This commit is contained in:
parent
363ede21d3
commit
47f8231d33
|
@ -88,7 +88,7 @@ impl Builder {
|
||||||
self
|
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;
|
self.abs = None;
|
||||||
//let test_ev_key : c_int = EV_KEY as c_int;
|
//let test_ev_key : c_int = EV_KEY as c_int;
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -97,7 +97,7 @@ impl Builder {
|
||||||
ui_set_evbit(self.fd, EV_KEY as *const c_int)?;
|
ui_set_evbit(self.fd, EV_KEY as *const c_int)?;
|
||||||
//ui_set_keybit(self.fd, KEY_H as *const c_int)?;
|
//ui_set_keybit(self.fd, KEY_H as *const c_int)?;
|
||||||
for key_code in key_codes {
|
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));
|
//try!(ui_set_keybit(self.fd, &KEY_H));
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,18 +41,18 @@ pub struct KeyMaps {
|
||||||
current_keymap_index: usize,
|
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)) {
|
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,
|
Some(key_code) => *key_code as u16,
|
||||||
None => panic!("unknown key: {}", key.trim())
|
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()
|
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 {
|
HalfInvertedKey {
|
||||||
code: parse_key(key_map, key),
|
code: parse_key(key_map, key),
|
||||||
invert_shift: key.contains(INVERT_KEY_FLAG),
|
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 :
|
// 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()
|
keymap.split(",").map(|k| parse_key(key_map, k)).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: how do I return an iterator here instead of .collect to Vec?
|
// 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| {
|
keymap.split(",").map(|k| {
|
||||||
let ret: Key = if k.contains(HALF_KEY_SEPARATOR) {
|
let ret: Key = if k.contains(HALF_KEY_SEPARATOR) {
|
||||||
let keys: Vec<&str> = k.split(HALF_KEY_SEPARATOR).collect();
|
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 {
|
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");
|
let key_map_config = parse_cfg(path).expect("provided config cannot be found/parsed");
|
||||||
KeyMaps::new(key_map, key_map_config)
|
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 {
|
if config.keymaps.len() < 2 {
|
||||||
panic!("must have at least 2 keymaps (original and mapped) but only have {},", config.keymaps.len());
|
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 {
|
impl KeyMaps {
|
||||||
pub fn key_map() -> HashMap<&'static str, *const c_int> {
|
pub fn key_map() -> HashMap<&'static str, c_int> {
|
||||||
[
|
[
|
||||||
// generated like:
|
// 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"),"}'
|
// 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),
|
("P0", KEY_KP0),
|
||||||
("PDOT", KEY_KPDOT),
|
("PDOT", KEY_KPDOT),
|
||||||
("PENT", KEY_KPENTER),
|
("PENT", KEY_KPENTER),
|
||||||
].iter().cloned().map(|(m, v)| (m, v as *const c_int)).collect()
|
].iter().cloned().map(|(m, v)| (m, v)).collect()
|
||||||
}
|
}
|
||||||
}
|
}
|
37
src/main.rs
37
src/main.rs
|
@ -20,7 +20,8 @@ use std::fs::File;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::{env, mem};
|
use std::{env, mem};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::sync::mpsc;
|
use std::sync::{Arc, mpsc};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use std::os::unix::io::AsRawFd;
|
use std::os::unix::io::AsRawFd;
|
||||||
|
|
||||||
|
@ -52,6 +53,9 @@ fn main() {
|
||||||
let config = parse_args();
|
let config = parse_args();
|
||||||
//println!("Config: {:?}", config);
|
//println!("Config: {:?}", config);
|
||||||
|
|
||||||
|
let key_map = Arc::new(KeyMaps::key_map());
|
||||||
|
//println!("key_map: {:?}", key_map);
|
||||||
|
|
||||||
if config.device_files.len() > 0 {
|
if config.device_files.len() > 0 {
|
||||||
// we only want to operate on device files sent in then quit
|
// we only want to operate on device files sent in then quit
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
|
@ -60,8 +64,9 @@ fn main() {
|
||||||
let device_file = device_file.clone();
|
let device_file = device_file.clone();
|
||||||
let config_file = config.config_file.clone();
|
let config_file = config.config_file.clone();
|
||||||
let tx = tx.clone();
|
let tx = tx.clone();
|
||||||
|
let key_map = Arc::clone(&key_map);
|
||||||
thread::spawn(move || {
|
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 {
|
if let Err(e) = ret {
|
||||||
println!("mapping for {} ended due to error: {}", device_file, e);
|
println!("mapping for {} ended due to error: {}", device_file, e);
|
||||||
}
|
}
|
||||||
|
@ -85,7 +90,7 @@ fn main() {
|
||||||
let device_files = get_keyboard_device_filenames();
|
let device_files = get_keyboard_device_filenames();
|
||||||
println!("Detected devices: {:?}", device_files);
|
println!("Detected devices: {:?}", device_files);
|
||||||
for device_file in device_files.iter() {
|
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];
|
let mut buffer = [0u8; 4096];
|
||||||
|
@ -95,16 +100,14 @@ fn main() {
|
||||||
if let Ok(events) = events {
|
if let Ok(events) = events {
|
||||||
for event in events {
|
for event in events {
|
||||||
if !event.mask.contains(EventMask::ISDIR) {
|
if !event.mask.contains(EventMask::ISDIR) {
|
||||||
if let Some(name) = event.name {
|
if let Some(device_file) = event.name.and_then(|name|name.to_str()) {
|
||||||
if let Some(device_file) = name.to_str() {
|
// check if this is an eligible keyboard device
|
||||||
// check if this is an eligible keyboard device
|
let device_files = get_keyboard_device_filenames();
|
||||||
let device_files = get_keyboard_device_filenames();
|
if !device_files.contains(&device_file.to_string()) {
|
||||||
if !device_files.contains(&device_file.to_string()) {
|
continue;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
println!("starting mapping thread for: {}", device_file);
|
|
||||||
inotify_spawn_thread(device_file.clone(), config.config_file.clone());
|
|
||||||
}
|
}
|
||||||
|
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();
|
let mut filename = "/dev/input/".to_string();
|
||||||
filename.push_str(&device_file);
|
filename.push_str(&device_file);
|
||||||
|
let key_map = Arc::clone(&key_map);
|
||||||
thread::spawn(move || {
|
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 {
|
if let Err(e) = ret {
|
||||||
println!("mapping for {} ended due to error: {}", filename, e);
|
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)?;
|
let mut input_device = InputDevice::open(device_file)?;
|
||||||
input_device.grab()?;
|
input_device.grab()?;
|
||||||
|
|
||||||
let key_map = KeyMaps::key_map();
|
|
||||||
//println!("key_map: {:?}", key_map);
|
|
||||||
|
|
||||||
let device = rusty_keys::open("/dev/uinput")
|
let device = rusty_keys::open("/dev/uinput")
|
||||||
.or_else(|_| rusty_keys::open("/dev/input/uinput"))
|
.or_else(|_| rusty_keys::open("/dev/input/uinput"))
|
||||||
.or_else(|_| rusty_keys::default())?
|
.or_else(|_| rusty_keys::default())?
|
||||||
|
|
Loading…
Reference in New Issue