From 30352bbc1e6d1453153c1e6fe985e2d235452e3f Mon Sep 17 00:00:00 2001 From: AethanFoot Date: Sun, 10 Mar 2024 13:32:03 +0000 Subject: [PATCH] Switch to evdev from evdev-rs --- Cargo.lock | 98 ++- lefthk-core/Cargo.toml | 2 +- lefthk-core/src/evdev.rs | 115 +-- lefthk-core/src/keysym_lookup.rs | 1190 ++++++++++++++---------------- lefthk-core/src/worker/mod.rs | 46 +- 5 files changed, 748 insertions(+), 703 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 85dd747..9d7fc2c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -79,6 +79,18 @@ dependencies = [ "serde", ] +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "bytes" version = "1.5.0" @@ -133,27 +145,18 @@ dependencies = [ ] [[package]] -name = "evdev-rs" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9812d5790fb6fcce449333eb6713dad335e8c979225ed98755c84a3987e06dba" -dependencies = [ - "bitflags 1.3.2", - "evdev-sys", - "libc", - "log", - "serde", -] - -[[package]] -name = "evdev-sys" -version = "0.2.5" +name = "evdev" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14ead42b547b15d47089c1243d907bcf0eb94e457046d3b315a26ac9c9e9ea6d" +checksum = "2bed59fcc8cfd6b190814a509018388462d3b203cf6dd10db5c00087e72a83f3" dependencies = [ - "cc", + "bitvec", + "cfg-if", + "futures-core", "libc", - "pkg-config", + "nix 0.23.2", + "thiserror", + "tokio", ] [[package]] @@ -162,6 +165,18 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + [[package]] name = "gimli" version = "0.28.1" @@ -242,10 +257,10 @@ dependencies = [ name = "lefthk-core" version = "0.2.1" dependencies = [ - "evdev-rs", + "evdev", "inventory", "mio", - "nix", + "nix 0.27.1", "ron", "serde", "signal-hook", @@ -300,6 +315,15 @@ version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + [[package]] name = "miniz_oxide" version = "0.7.2" @@ -321,6 +345,19 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "nix" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3790c00a0150112de0f4cd161e3d7fc4b2d8a5542ffc35f099a2562aecb35c" +dependencies = [ + "bitflags 1.3.2", + "cc", + "cfg-if", + "libc", + "memoffset", +] + [[package]] name = "nix" version = "0.27.1" @@ -409,6 +446,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + [[package]] name = "regex" version = "1.10.3" @@ -565,6 +608,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + [[package]] name = "tempfile" version = "3.10.1" @@ -905,6 +954,15 @@ version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + [[package]] name = "xdg" version = "2.5.2" diff --git a/lefthk-core/Cargo.toml b/lefthk-core/Cargo.toml index 44e4b6b..644bea4 100644 --- a/lefthk-core/Cargo.toml +++ b/lefthk-core/Cargo.toml @@ -8,7 +8,7 @@ repository = "https://github.com/leftwm/lefthk" description = "A hotkey daemon for Adventurers" [dependencies] -evdev-rs = { version = "0.6.1", features = ["serde"] } +evdev = { version = "0.12.1", features = ["tokio"] } mio = "0.8.11" nix = { version = "0.27.1", features = ["fs", "signal"] } signal-hook = "0.3.4" diff --git a/lefthk-core/src/evdev.rs b/lefthk-core/src/evdev.rs index ec0b242..de2d75c 100644 --- a/lefthk-core/src/evdev.rs +++ b/lefthk-core/src/evdev.rs @@ -1,6 +1,5 @@ -use evdev_rs::{Device, DeviceWrapper, InputEvent, ReadFlag, ReadStatus, UInputDevice}; -use std::future::poll_fn; -use std::os::fd::AsRawFd; +use evdev::uinput::{VirtualDevice, VirtualDeviceBuilder}; +use evdev::{AttributeSet, BusType, Device, InputEvent, InputId, Key, RelativeAxisType}; use std::path::PathBuf; use std::{collections::HashMap, ffi::OsStr}; use tokio::sync::{mpsc, oneshot}; @@ -15,7 +14,7 @@ pub enum Task { } pub struct EvDev { - pub devices: HashMap, + pub device: VirtualDevice, pub task_receiver: mpsc::Receiver, task_transmitter: mpsc::Sender, task_guards: HashMap>, @@ -24,7 +23,39 @@ pub struct EvDev { impl Default for EvDev { fn default() -> Self { - let devices: HashMap = HashMap::new(); + let keys = AttributeSet::from_iter( + (Key::KEY_RESERVED.code()..Key::BTN_TRIGGER_HAPPY40.code()).map(Key::new), + ); + let relative_axes = evdev::AttributeSet::from_iter([ + RelativeAxisType::REL_WHEEL, + RelativeAxisType::REL_HWHEEL, + RelativeAxisType::REL_X, + RelativeAxisType::REL_Y, + RelativeAxisType::REL_Z, + RelativeAxisType::REL_RX, + RelativeAxisType::REL_RY, + RelativeAxisType::REL_RZ, + RelativeAxisType::REL_DIAL, + RelativeAxisType::REL_MISC, + RelativeAxisType::REL_WHEEL_HI_RES, + RelativeAxisType::REL_HWHEEL_HI_RES, + ]); + + let builder = errors::exit!(VirtualDeviceBuilder::new()); + + let mut device = builder + .name("LeftHK Virtual Keyboard") + .input_id(InputId::new(BusType::BUS_I8042, 1, 1, 1)) + .with_keys(&keys) + .unwrap() + .with_relative_axes(&relative_axes) + .unwrap() + .build() + .unwrap(); + println!("Device: {:?}", device.get_syspath()); + + let devnode = device.enumerate_dev_nodes_blocking().unwrap().next(); + println!("Devnode: {:?}", devnode); let (task_transmitter, task_receiver) = mpsc::channel(128); @@ -33,7 +64,7 @@ impl Default for EvDev { let task_guards: HashMap> = HashMap::new(); let mut evdev = EvDev { - devices, + device, task_receiver, task_transmitter, task_guards, @@ -56,58 +87,43 @@ impl Default for EvDev { impl EvDev { pub fn add_device(&mut self, path: PathBuf) { tracing::info!("Adding device with path: {:?}", path); - if let Some(mut device) = device_with_path(path.clone()) { - device.set_name(&format!("LeftHK virtual input for {:?}", path)); - let uinput = errors::r#return!(UInputDevice::create_from_device(&device)); - errors::r#return!(device.grab(evdev_rs::GrabMode::Grab)); + if let Ok(mut device) = Device::open(path.clone()) { + wait_for_all_keys_unpressed(&device); + errors::r#return!(device.grab()); + errors::r#return!(device.ungrab()); + errors::r#return!(device.grab()); - let (mut guard, task_guard) = oneshot::channel(); + let (guard, task_guard) = oneshot::channel(); let transmitter = self.task_transmitter.clone(); - const SERVER: mio::Token = mio::Token(0); - let fd = device.file().as_raw_fd(); - let mut poll = errors::exit!(mio::Poll::new()); - let mut events = mio::Events::with_capacity(1); - errors::exit!(poll.registry().register( - &mut mio::unix::SourceFd(&fd), - SERVER, - mio::Interest::READABLE, - )); + + let mut stream = errors::r#return!(device.into_event_stream()); let p = path.clone(); tokio::task::spawn(async move { while !guard.is_closed() { - if let Err(err) = poll.poll(&mut events, None) { - tracing::warn!("Evdev device poll failed with {:?}", err); - continue; - } - - while device.has_event_pending() { - match device.next_event(ReadFlag::NORMAL) { - Ok((ReadStatus::Success, event)) => { - transmitter - .send(Task::KeyboardEvent((p.clone(), event))) - .await - .unwrap(); - } - Err(_) => { - poll_fn(|cx| guard.poll_closed(cx)).await; - break; - } - _ => {} + match stream.next_event().await { + Ok(event) => { + transmitter + .send(Task::KeyboardEvent((p.clone(), event))) + .await + .unwrap(); + } + Err(err) => { + tracing::warn!("Evdev device stream failed with {:?}", err); + // poll_fn(|cx| guard.poll_closed(cx)).await; + break; } } } tracing::info!("Device loop has closed."); - errors::r#return!(device.grab(evdev_rs::GrabMode::Ungrab)); + errors::r#return!(stream.device_mut().ungrab()); }); - self.devices.insert(path.clone(), uinput); self.task_guards.insert(path, task_guard); } } pub fn remove_device(&mut self, path: PathBuf) { tracing::info!("Removing device with path: {:?}", path); self.task_guards.remove(&path); - self.devices.remove(&path); } } @@ -135,14 +151,17 @@ fn find_keyboards() -> Option> { Some(devices) } -fn device_with_path(path: PathBuf) -> Option { - let device = Device::new_from_path(path).ok()?; - if device.has(evdev_rs::enums::EventType::EV_KEY) - && device.phys().unwrap_or("").contains("input0") - { - return Some(device); +fn wait_for_all_keys_unpressed(device: &Device) { + let mut pending_release = false; + loop { + match device.get_key_state() { + Ok(keys) if keys.iter().count() > 0 => pending_release = true, + _ => break, + } + } + if pending_release { + std::thread::sleep(std::time::Duration::from_micros(100)); } - None } #[derive(Debug)] diff --git a/lefthk-core/src/keysym_lookup.rs b/lefthk-core/src/keysym_lookup.rs index d203cdf..85ef765 100644 --- a/lefthk-core/src/keysym_lookup.rs +++ b/lefthk-core/src/keysym_lookup.rs @@ -1,4 +1,4 @@ -use evdev_rs::enums::EV_KEY; +use evdev::Key; #[allow(non_camel_case_types)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] @@ -12,37 +12,37 @@ pub enum MOD_MASK { MASK_SCROLLLOCK, } -impl TryFrom for MOD_MASK { +impl TryFrom for MOD_MASK { type Error = (); - fn try_from(key: EV_KEY) -> Result { + fn try_from(key: Key) -> Result { match key { - EV_KEY::KEY_LEFTSHIFT | EV_KEY::KEY_RIGHTSHIFT => Ok(Self::MASK_SHIFT), - EV_KEY::KEY_LEFTCTRL | EV_KEY::KEY_RIGHTCTRL => Ok(Self::MASK_CTRL), - EV_KEY::KEY_LEFTALT | EV_KEY::KEY_RIGHTALT => Ok(Self::MASK_ALT), - EV_KEY::KEY_LEFTMETA | EV_KEY::KEY_RIGHTMETA => Ok(Self::MASK_META), - EV_KEY::KEY_CAPSLOCK => Ok(Self::MASK_CAPSLOCK), - EV_KEY::KEY_NUMLOCK => Ok(Self::MASK_NUMLOCK), - EV_KEY::KEY_SCROLLLOCK => Ok(Self::MASK_SCROLLLOCK), + Key::KEY_LEFTSHIFT | Key::KEY_RIGHTSHIFT => Ok(Self::MASK_SHIFT), + Key::KEY_LEFTCTRL | Key::KEY_RIGHTCTRL => Ok(Self::MASK_CTRL), + Key::KEY_LEFTALT | Key::KEY_RIGHTALT => Ok(Self::MASK_ALT), + Key::KEY_LEFTMETA | Key::KEY_RIGHTMETA => Ok(Self::MASK_META), + Key::KEY_CAPSLOCK => Ok(Self::MASK_CAPSLOCK), + Key::KEY_NUMLOCK => Ok(Self::MASK_NUMLOCK), + Key::KEY_SCROLLLOCK => Ok(Self::MASK_SCROLLLOCK), _ => Err(()), } } } -pub fn is_modifier(key: &EV_KEY) -> bool { +pub fn is_modifier(key: &Key) -> bool { matches!( key, - EV_KEY::KEY_LEFTSHIFT - | EV_KEY::KEY_RIGHTSHIFT - | EV_KEY::KEY_LEFTCTRL - | EV_KEY::KEY_RIGHTCTRL - | EV_KEY::KEY_LEFTALT - | EV_KEY::KEY_RIGHTALT - | EV_KEY::KEY_LEFTMETA - | EV_KEY::KEY_RIGHTMETA - | EV_KEY::KEY_CAPSLOCK - | EV_KEY::KEY_NUMLOCK - | EV_KEY::KEY_SCROLLLOCK + &Key::KEY_LEFTSHIFT + | &Key::KEY_RIGHTSHIFT + | &Key::KEY_LEFTCTRL + | &Key::KEY_RIGHTCTRL + | &Key::KEY_LEFTALT + | &Key::KEY_RIGHTALT + | &Key::KEY_LEFTMETA + | &Key::KEY_RIGHTMETA + | &Key::KEY_CAPSLOCK + | &Key::KEY_NUMLOCK + | &Key::KEY_SCROLLLOCK ) } @@ -69,7 +69,7 @@ pub fn into_mod(key: &str) -> Option { } } -pub fn into_keys(keys: &[String]) -> Vec { +pub fn into_keys(keys: &[String]) -> Vec { let mut result = Vec::new(); for key in keys { if let Some(key) = into_key(key) { @@ -82,604 +82,554 @@ pub fn into_keys(keys: &[String]) -> Vec { // We allow this because this function is simply a mapping wrapper. #[allow(clippy::too_many_lines)] #[must_use] -pub fn into_key(key: &str) -> Option { +pub fn into_key(key: &str) -> Option { match key { - "Reserved" => Some(EV_KEY::KEY_RESERVED), - "Escape" => Some(EV_KEY::KEY_ESC), - "1" => Some(EV_KEY::KEY_1), - "2" => Some(EV_KEY::KEY_2), - "3" => Some(EV_KEY::KEY_3), - "4" => Some(EV_KEY::KEY_4), - "5" => Some(EV_KEY::KEY_5), - "6" => Some(EV_KEY::KEY_6), - "7" => Some(EV_KEY::KEY_7), - "8" => Some(EV_KEY::KEY_8), - "9" => Some(EV_KEY::KEY_9), - "0" => Some(EV_KEY::KEY_0), - "Minus" => Some(EV_KEY::KEY_MINUS), - "Equal" => Some(EV_KEY::KEY_EQUAL), - "Backspace" => Some(EV_KEY::KEY_BACKSPACE), - "Tab" => Some(EV_KEY::KEY_TAB), - "q" => Some(EV_KEY::KEY_Q), - "w" => Some(EV_KEY::KEY_W), - "e" => Some(EV_KEY::KEY_E), - "r" => Some(EV_KEY::KEY_R), - "t" => Some(EV_KEY::KEY_T), - "y" => Some(EV_KEY::KEY_Y), - "u" => Some(EV_KEY::KEY_U), - "i" => Some(EV_KEY::KEY_I), - "o" => Some(EV_KEY::KEY_O), - "p" => Some(EV_KEY::KEY_P), - "Leftbrace" => Some(EV_KEY::KEY_LEFTBRACE), - "Rightbrace" => Some(EV_KEY::KEY_RIGHTBRACE), - "Enter" => Some(EV_KEY::KEY_ENTER), - "Leftctrl" => Some(EV_KEY::KEY_LEFTCTRL), - "a" => Some(EV_KEY::KEY_A), - "s" => Some(EV_KEY::KEY_S), - "d" => Some(EV_KEY::KEY_D), - "f" => Some(EV_KEY::KEY_F), - "g" => Some(EV_KEY::KEY_G), - "h" => Some(EV_KEY::KEY_H), - "j" => Some(EV_KEY::KEY_J), - "k" => Some(EV_KEY::KEY_K), - "l" => Some(EV_KEY::KEY_L), - "Semicolon" => Some(EV_KEY::KEY_SEMICOLON), - "Apostrophe" => Some(EV_KEY::KEY_APOSTROPHE), - "Grave" => Some(EV_KEY::KEY_GRAVE), - "Leftshift" => Some(EV_KEY::KEY_LEFTSHIFT), - "Backslash" => Some(EV_KEY::KEY_BACKSLASH), - "z" => Some(EV_KEY::KEY_Z), - "x" => Some(EV_KEY::KEY_X), - "c" => Some(EV_KEY::KEY_C), - "v" => Some(EV_KEY::KEY_V), - "b" => Some(EV_KEY::KEY_B), - "n" => Some(EV_KEY::KEY_N), - "m" => Some(EV_KEY::KEY_M), - "Comma" => Some(EV_KEY::KEY_COMMA), - "Dot" => Some(EV_KEY::KEY_DOT), - "Slash" => Some(EV_KEY::KEY_SLASH), - "Rightshift" => Some(EV_KEY::KEY_RIGHTSHIFT), - "Kpasterisk" => Some(EV_KEY::KEY_KPASTERISK), - "Leftalt" => Some(EV_KEY::KEY_LEFTALT), - "Space" => Some(EV_KEY::KEY_SPACE), - "Capslock" => Some(EV_KEY::KEY_CAPSLOCK), - "F1" => Some(EV_KEY::KEY_F1), - "F2" => Some(EV_KEY::KEY_F2), - "F3" => Some(EV_KEY::KEY_F3), - "F4" => Some(EV_KEY::KEY_F4), - "F5" => Some(EV_KEY::KEY_F5), - "F6" => Some(EV_KEY::KEY_F6), - "F7" => Some(EV_KEY::KEY_F7), - "F8" => Some(EV_KEY::KEY_F8), - "F9" => Some(EV_KEY::KEY_F9), - "F10" => Some(EV_KEY::KEY_F10), - "Numlock" => Some(EV_KEY::KEY_NUMLOCK), - "Scrolllock" => Some(EV_KEY::KEY_SCROLLLOCK), - "Kp7" => Some(EV_KEY::KEY_KP7), - "Kp8" => Some(EV_KEY::KEY_KP8), - "Kp9" => Some(EV_KEY::KEY_KP9), - "Kpminus" => Some(EV_KEY::KEY_KPMINUS), - "Kp4" => Some(EV_KEY::KEY_KP4), - "Kp5" => Some(EV_KEY::KEY_KP5), - "Kp6" => Some(EV_KEY::KEY_KP6), - "Kpplus" => Some(EV_KEY::KEY_KPPLUS), - "Kp1" => Some(EV_KEY::KEY_KP1), - "Kp2" => Some(EV_KEY::KEY_KP2), - "Kp3" => Some(EV_KEY::KEY_KP3), - "Kp0" => Some(EV_KEY::KEY_KP0), - "Kpdot" => Some(EV_KEY::KEY_KPDOT), - "Zenkakuhankaku" => Some(EV_KEY::KEY_ZENKAKUHANKAKU), - "102nd" => Some(EV_KEY::KEY_102ND), - "F11" => Some(EV_KEY::KEY_F11), - "F12" => Some(EV_KEY::KEY_F12), - "Ro" => Some(EV_KEY::KEY_RO), - "Katakana" => Some(EV_KEY::KEY_KATAKANA), - "Hiragana" => Some(EV_KEY::KEY_HIRAGANA), - "Henkan" => Some(EV_KEY::KEY_HENKAN), - "Katakanahiragana" => Some(EV_KEY::KEY_KATAKANAHIRAGANA), - "Muhenkan" => Some(EV_KEY::KEY_MUHENKAN), - "Kpjpcomma" => Some(EV_KEY::KEY_KPJPCOMMA), - "Kpenter" => Some(EV_KEY::KEY_KPENTER), - "Rightctrl" => Some(EV_KEY::KEY_RIGHTCTRL), - "Kpslash" => Some(EV_KEY::KEY_KPSLASH), - "Sysrq" => Some(EV_KEY::KEY_SYSRQ), - "Rightalt" => Some(EV_KEY::KEY_RIGHTALT), - "Linefeed" => Some(EV_KEY::KEY_LINEFEED), - "Home" => Some(EV_KEY::KEY_HOME), - "Up" => Some(EV_KEY::KEY_UP), - "Pageup" => Some(EV_KEY::KEY_PAGEUP), - "Left" => Some(EV_KEY::KEY_LEFT), - "Right" => Some(EV_KEY::KEY_RIGHT), - "End" => Some(EV_KEY::KEY_END), - "Down" => Some(EV_KEY::KEY_DOWN), - "Pagedown" => Some(EV_KEY::KEY_PAGEDOWN), - "Insert" => Some(EV_KEY::KEY_INSERT), - "Delete" => Some(EV_KEY::KEY_DELETE), - "Macro" => Some(EV_KEY::KEY_MACRO), - "Mute" => Some(EV_KEY::KEY_MUTE), - "Volumedown" => Some(EV_KEY::KEY_VOLUMEDOWN), - "Volumeup" => Some(EV_KEY::KEY_VOLUMEUP), - "Power" => Some(EV_KEY::KEY_POWER), - "Kpequal" => Some(EV_KEY::KEY_KPEQUAL), - "Kpplusminus" => Some(EV_KEY::KEY_KPPLUSMINUS), - "Pause" => Some(EV_KEY::KEY_PAUSE), - "Scale" => Some(EV_KEY::KEY_SCALE), - "Kpcomma" => Some(EV_KEY::KEY_KPCOMMA), - "Hangeul" => Some(EV_KEY::KEY_HANGEUL), - "Hanja" => Some(EV_KEY::KEY_HANJA), - "Yen" => Some(EV_KEY::KEY_YEN), - "Leftmeta" => Some(EV_KEY::KEY_LEFTMETA), - "Rightmeta" => Some(EV_KEY::KEY_RIGHTMETA), - "Compose" => Some(EV_KEY::KEY_COMPOSE), - "Stop" => Some(EV_KEY::KEY_STOP), - "Again" => Some(EV_KEY::KEY_AGAIN), - "Props" => Some(EV_KEY::KEY_PROPS), - "Undo" => Some(EV_KEY::KEY_UNDO), - "Front" => Some(EV_KEY::KEY_FRONT), - "Copy" => Some(EV_KEY::KEY_COPY), - "Open" => Some(EV_KEY::KEY_OPEN), - "Paste" => Some(EV_KEY::KEY_PASTE), - "Find" => Some(EV_KEY::KEY_FIND), - "Cut" => Some(EV_KEY::KEY_CUT), - "Help" => Some(EV_KEY::KEY_HELP), - "Menu" => Some(EV_KEY::KEY_MENU), - "Calc" => Some(EV_KEY::KEY_CALC), - "Setup" => Some(EV_KEY::KEY_SETUP), - "Sleep" => Some(EV_KEY::KEY_SLEEP), - "Wakeup" => Some(EV_KEY::KEY_WAKEUP), - "File" => Some(EV_KEY::KEY_FILE), - "Sendfile" => Some(EV_KEY::KEY_SENDFILE), - "Deletefile" => Some(EV_KEY::KEY_DELETEFILE), - "Xfer" => Some(EV_KEY::KEY_XFER), - "Prog1" => Some(EV_KEY::KEY_PROG1), - "Prog2" => Some(EV_KEY::KEY_PROG2), - "Www" => Some(EV_KEY::KEY_WWW), - "Msdos" => Some(EV_KEY::KEY_MSDOS), - "Coffee" => Some(EV_KEY::KEY_COFFEE), - "Rotate_display" => Some(EV_KEY::KEY_ROTATE_DISPLAY), - "Cyclewindows" => Some(EV_KEY::KEY_CYCLEWINDOWS), - "Mail" => Some(EV_KEY::KEY_MAIL), - "Bookmarks" => Some(EV_KEY::KEY_BOOKMARKS), - "Computer" => Some(EV_KEY::KEY_COMPUTER), - "Back" => Some(EV_KEY::KEY_BACK), - "Forward" => Some(EV_KEY::KEY_FORWARD), - "Closecd" => Some(EV_KEY::KEY_CLOSECD), - "Ejectcd" => Some(EV_KEY::KEY_EJECTCD), - "Ejectclosecd" => Some(EV_KEY::KEY_EJECTCLOSECD), - "Nextsong" => Some(EV_KEY::KEY_NEXTSONG), - "Playpause" => Some(EV_KEY::KEY_PLAYPAUSE), - "Previoussong" => Some(EV_KEY::KEY_PREVIOUSSONG), - "Stopcd" => Some(EV_KEY::KEY_STOPCD), - "Record" => Some(EV_KEY::KEY_RECORD), - "Rewind" => Some(EV_KEY::KEY_REWIND), - "Phone" => Some(EV_KEY::KEY_PHONE), - "Iso" => Some(EV_KEY::KEY_ISO), - "Config" => Some(EV_KEY::KEY_CONFIG), - "Homepage" => Some(EV_KEY::KEY_HOMEPAGE), - "Refresh" => Some(EV_KEY::KEY_REFRESH), - "Exit" => Some(EV_KEY::KEY_EXIT), - "Move" => Some(EV_KEY::KEY_MOVE), - "Edit" => Some(EV_KEY::KEY_EDIT), - "Scrollup" => Some(EV_KEY::KEY_SCROLLUP), - "Scrolldown" => Some(EV_KEY::KEY_SCROLLDOWN), - "Kpleftparen" => Some(EV_KEY::KEY_KPLEFTPAREN), - "Kprightparen" => Some(EV_KEY::KEY_KPRIGHTPAREN), - "New" => Some(EV_KEY::KEY_NEW), - "Redo" => Some(EV_KEY::KEY_REDO), - "F13" => Some(EV_KEY::KEY_F13), - "F14" => Some(EV_KEY::KEY_F14), - "F15" => Some(EV_KEY::KEY_F15), - "F16" => Some(EV_KEY::KEY_F16), - "F17" => Some(EV_KEY::KEY_F17), - "F18" => Some(EV_KEY::KEY_F18), - "F19" => Some(EV_KEY::KEY_F19), - "F20" => Some(EV_KEY::KEY_F20), - "F21" => Some(EV_KEY::KEY_F21), - "F22" => Some(EV_KEY::KEY_F22), - "F23" => Some(EV_KEY::KEY_F23), - "F24" => Some(EV_KEY::KEY_F24), - "Playcd" => Some(EV_KEY::KEY_PLAYCD), - "Pausecd" => Some(EV_KEY::KEY_PAUSECD), - "Prog3" => Some(EV_KEY::KEY_PROG3), - "Prog4" => Some(EV_KEY::KEY_PROG4), - "All_applications" => Some(EV_KEY::KEY_ALL_APPLICATIONS), - "Suspend" => Some(EV_KEY::KEY_SUSPEND), - "Close" => Some(EV_KEY::KEY_CLOSE), - "Play" => Some(EV_KEY::KEY_PLAY), - "Fastforward" => Some(EV_KEY::KEY_FASTFORWARD), - "Bassboost" => Some(EV_KEY::KEY_BASSBOOST), - "Print" => Some(EV_KEY::KEY_PRINT), - "Hp" => Some(EV_KEY::KEY_HP), - "Camera" => Some(EV_KEY::KEY_CAMERA), - "Sound" => Some(EV_KEY::KEY_SOUND), - "Question" => Some(EV_KEY::KEY_QUESTION), - "Email" => Some(EV_KEY::KEY_EMAIL), - "Chat" => Some(EV_KEY::KEY_CHAT), - "Search" => Some(EV_KEY::KEY_SEARCH), - "Connect" => Some(EV_KEY::KEY_CONNECT), - "Finance" => Some(EV_KEY::KEY_FINANCE), - "Sport" => Some(EV_KEY::KEY_SPORT), - "Shop" => Some(EV_KEY::KEY_SHOP), - "Alterase" => Some(EV_KEY::KEY_ALTERASE), - "Cancel" => Some(EV_KEY::KEY_CANCEL), - "Brightnessdown" => Some(EV_KEY::KEY_BRIGHTNESSDOWN), - "Brightnessup" => Some(EV_KEY::KEY_BRIGHTNESSUP), - "Media" => Some(EV_KEY::KEY_MEDIA), - "Switchvideomode" => Some(EV_KEY::KEY_SWITCHVIDEOMODE), - "Kbdillumtoggle" => Some(EV_KEY::KEY_KBDILLUMTOGGLE), - "Kbdillumdown" => Some(EV_KEY::KEY_KBDILLUMDOWN), - "Kbdillumup" => Some(EV_KEY::KEY_KBDILLUMUP), - "Send" => Some(EV_KEY::KEY_SEND), - "Reply" => Some(EV_KEY::KEY_REPLY), - "Forwardmail" => Some(EV_KEY::KEY_FORWARDMAIL), - "Save" => Some(EV_KEY::KEY_SAVE), - "Documents" => Some(EV_KEY::KEY_DOCUMENTS), - "Battery" => Some(EV_KEY::KEY_BATTERY), - "Bluetooth" => Some(EV_KEY::KEY_BLUETOOTH), - "Wlan" => Some(EV_KEY::KEY_WLAN), - "Uwb" => Some(EV_KEY::KEY_UWB), - "Unknown" => Some(EV_KEY::KEY_UNKNOWN), - "Video_next" => Some(EV_KEY::KEY_VIDEO_NEXT), - "Video_prev" => Some(EV_KEY::KEY_VIDEO_PREV), - "Brightness_cycle" => Some(EV_KEY::KEY_BRIGHTNESS_CYCLE), - "Brightness_auto" => Some(EV_KEY::KEY_BRIGHTNESS_AUTO), - "Display_off" => Some(EV_KEY::KEY_DISPLAY_OFF), - "Wwan" => Some(EV_KEY::KEY_WWAN), - "Rfkill" => Some(EV_KEY::KEY_RFKILL), - "Micmute" => Some(EV_KEY::KEY_MICMUTE), - "Ok" => Some(EV_KEY::KEY_OK), - "Select" => Some(EV_KEY::KEY_SELECT), - "Goto" => Some(EV_KEY::KEY_GOTO), - "Clear" => Some(EV_KEY::KEY_CLEAR), - "Power2" => Some(EV_KEY::KEY_POWER2), - "Option" => Some(EV_KEY::KEY_OPTION), - "Info" => Some(EV_KEY::KEY_INFO), - "Time" => Some(EV_KEY::KEY_TIME), - "Vendor" => Some(EV_KEY::KEY_VENDOR), - "Archive" => Some(EV_KEY::KEY_ARCHIVE), - "Program" => Some(EV_KEY::KEY_PROGRAM), - "Channel" => Some(EV_KEY::KEY_CHANNEL), - "Favorites" => Some(EV_KEY::KEY_FAVORITES), - "Epg" => Some(EV_KEY::KEY_EPG), - "Pvr" => Some(EV_KEY::KEY_PVR), - "Mhp" => Some(EV_KEY::KEY_MHP), - "Language" => Some(EV_KEY::KEY_LANGUAGE), - "Title" => Some(EV_KEY::KEY_TITLE), - "Subtitle" => Some(EV_KEY::KEY_SUBTITLE), - "Angle" => Some(EV_KEY::KEY_ANGLE), - "Full_screen" => Some(EV_KEY::KEY_FULL_SCREEN), - "Mode" => Some(EV_KEY::KEY_MODE), - "Keyboard" => Some(EV_KEY::KEY_KEYBOARD), - "Aspect_ratio" => Some(EV_KEY::KEY_ASPECT_RATIO), - "Pc" => Some(EV_KEY::KEY_PC), - "Tv" => Some(EV_KEY::KEY_TV), - "Tv2" => Some(EV_KEY::KEY_TV2), - "Vcr" => Some(EV_KEY::KEY_VCR), - "Vcr2" => Some(EV_KEY::KEY_VCR2), - "Sat" => Some(EV_KEY::KEY_SAT), - "Sat2" => Some(EV_KEY::KEY_SAT2), - "Cd" => Some(EV_KEY::KEY_CD), - "Tape" => Some(EV_KEY::KEY_TAPE), - "Radio" => Some(EV_KEY::KEY_RADIO), - "Tuner" => Some(EV_KEY::KEY_TUNER), - "Player" => Some(EV_KEY::KEY_PLAYER), - "Text" => Some(EV_KEY::KEY_TEXT), - "Dvd" => Some(EV_KEY::KEY_DVD), - "Aux" => Some(EV_KEY::KEY_AUX), - "Mp3" => Some(EV_KEY::KEY_MP3), - "Audio" => Some(EV_KEY::KEY_AUDIO), - "Video" => Some(EV_KEY::KEY_VIDEO), - "Directory" => Some(EV_KEY::KEY_DIRECTORY), - "List" => Some(EV_KEY::KEY_LIST), - "Memo" => Some(EV_KEY::KEY_MEMO), - "Calendar" => Some(EV_KEY::KEY_CALENDAR), - "Red" => Some(EV_KEY::KEY_RED), - "Green" => Some(EV_KEY::KEY_GREEN), - "Yellow" => Some(EV_KEY::KEY_YELLOW), - "Blue" => Some(EV_KEY::KEY_BLUE), - "Channelup" => Some(EV_KEY::KEY_CHANNELUP), - "Channeldown" => Some(EV_KEY::KEY_CHANNELDOWN), - "First" => Some(EV_KEY::KEY_FIRST), - "Last" => Some(EV_KEY::KEY_LAST), - "Ab" => Some(EV_KEY::KEY_AB), - "Next" => Some(EV_KEY::KEY_NEXT), - "Restart" => Some(EV_KEY::KEY_RESTART), - "Slow" => Some(EV_KEY::KEY_SLOW), - "Shuffle" => Some(EV_KEY::KEY_SHUFFLE), - "Break" => Some(EV_KEY::KEY_BREAK), - "Previous" => Some(EV_KEY::KEY_PREVIOUS), - "Digits" => Some(EV_KEY::KEY_DIGITS), - "Teen" => Some(EV_KEY::KEY_TEEN), - "Twen" => Some(EV_KEY::KEY_TWEN), - "Videophone" => Some(EV_KEY::KEY_VIDEOPHONE), - "Games" => Some(EV_KEY::KEY_GAMES), - "Zoomin" => Some(EV_KEY::KEY_ZOOMIN), - "Zoomout" => Some(EV_KEY::KEY_ZOOMOUT), - "Zoomreset" => Some(EV_KEY::KEY_ZOOMRESET), - "Wordprocessor" => Some(EV_KEY::KEY_WORDPROCESSOR), - "Editor" => Some(EV_KEY::KEY_EDITOR), - "Spreadsheet" => Some(EV_KEY::KEY_SPREADSHEET), - "Graphicseditor" => Some(EV_KEY::KEY_GRAPHICSEDITOR), - "Presentation" => Some(EV_KEY::KEY_PRESENTATION), - "Database" => Some(EV_KEY::KEY_DATABASE), - "News" => Some(EV_KEY::KEY_NEWS), - "Voicemail" => Some(EV_KEY::KEY_VOICEMAIL), - "Addressbook" => Some(EV_KEY::KEY_ADDRESSBOOK), - "Messenger" => Some(EV_KEY::KEY_MESSENGER), - "Displaytoggle" => Some(EV_KEY::KEY_DISPLAYTOGGLE), - "Spellcheck" => Some(EV_KEY::KEY_SPELLCHECK), - "Logoff" => Some(EV_KEY::KEY_LOGOFF), - "Dollar" => Some(EV_KEY::KEY_DOLLAR), - "Euro" => Some(EV_KEY::KEY_EURO), - "Frameback" => Some(EV_KEY::KEY_FRAMEBACK), - "Frameforward" => Some(EV_KEY::KEY_FRAMEFORWARD), - "Context_menu" => Some(EV_KEY::KEY_CONTEXT_MENU), - "Media_repeat" => Some(EV_KEY::KEY_MEDIA_REPEAT), - "10channelsup" => Some(EV_KEY::KEY_10CHANNELSUP), - "10channelsdown" => Some(EV_KEY::KEY_10CHANNELSDOWN), - "Images" => Some(EV_KEY::KEY_IMAGES), - "Notification_center" => Some(EV_KEY::KEY_NOTIFICATION_CENTER), - "Pickup_phone" => Some(EV_KEY::KEY_PICKUP_PHONE), - "Hangup_phone" => Some(EV_KEY::KEY_HANGUP_PHONE), - "Del_eol" => Some(EV_KEY::KEY_DEL_EOL), - "Del_eos" => Some(EV_KEY::KEY_DEL_EOS), - "Ins_line" => Some(EV_KEY::KEY_INS_LINE), - "Del_line" => Some(EV_KEY::KEY_DEL_LINE), - "Fn" => Some(EV_KEY::KEY_FN), - "Fn_esc" => Some(EV_KEY::KEY_FN_ESC), - "Fn_f1" => Some(EV_KEY::KEY_FN_F1), - "Fn_f2" => Some(EV_KEY::KEY_FN_F2), - "Fn_f3" => Some(EV_KEY::KEY_FN_F3), - "Fn_f4" => Some(EV_KEY::KEY_FN_F4), - "Fn_f5" => Some(EV_KEY::KEY_FN_F5), - "Fn_f6" => Some(EV_KEY::KEY_FN_F6), - "Fn_f7" => Some(EV_KEY::KEY_FN_F7), - "Fn_f8" => Some(EV_KEY::KEY_FN_F8), - "Fn_f9" => Some(EV_KEY::KEY_FN_F9), - "Fn_f10" => Some(EV_KEY::KEY_FN_F10), - "Fn_f11" => Some(EV_KEY::KEY_FN_F11), - "Fn_f12" => Some(EV_KEY::KEY_FN_F12), - "Fn_1" => Some(EV_KEY::KEY_FN_1), - "Fn_2" => Some(EV_KEY::KEY_FN_2), - "Fn_d" => Some(EV_KEY::KEY_FN_D), - "Fn_e" => Some(EV_KEY::KEY_FN_E), - "Fn_f" => Some(EV_KEY::KEY_FN_F), - "Fn_s" => Some(EV_KEY::KEY_FN_S), - "Fn_b" => Some(EV_KEY::KEY_FN_B), - "Fn_right_shift" => Some(EV_KEY::KEY_FN_RIGHT_SHIFT), - "Brl_dot1" => Some(EV_KEY::KEY_BRL_DOT1), - "Brl_dot2" => Some(EV_KEY::KEY_BRL_DOT2), - "Brl_dot3" => Some(EV_KEY::KEY_BRL_DOT3), - "Brl_dot4" => Some(EV_KEY::KEY_BRL_DOT4), - "Brl_dot5" => Some(EV_KEY::KEY_BRL_DOT5), - "Brl_dot6" => Some(EV_KEY::KEY_BRL_DOT6), - "Brl_dot7" => Some(EV_KEY::KEY_BRL_DOT7), - "Brl_dot8" => Some(EV_KEY::KEY_BRL_DOT8), - "Brl_dot9" => Some(EV_KEY::KEY_BRL_DOT9), - "Brl_dot10" => Some(EV_KEY::KEY_BRL_DOT10), - "Numeric_0" => Some(EV_KEY::KEY_NUMERIC_0), - "Numeric_1" => Some(EV_KEY::KEY_NUMERIC_1), - "Numeric_2" => Some(EV_KEY::KEY_NUMERIC_2), - "Numeric_3" => Some(EV_KEY::KEY_NUMERIC_3), - "Numeric_4" => Some(EV_KEY::KEY_NUMERIC_4), - "Numeric_5" => Some(EV_KEY::KEY_NUMERIC_5), - "Numeric_6" => Some(EV_KEY::KEY_NUMERIC_6), - "Numeric_7" => Some(EV_KEY::KEY_NUMERIC_7), - "Numeric_8" => Some(EV_KEY::KEY_NUMERIC_8), - "Numeric_9" => Some(EV_KEY::KEY_NUMERIC_9), - "Numeric_star" => Some(EV_KEY::KEY_NUMERIC_STAR), - "Numeric_pound" => Some(EV_KEY::KEY_NUMERIC_POUND), - "Numeric_a" => Some(EV_KEY::KEY_NUMERIC_A), - "Numeric_b" => Some(EV_KEY::KEY_NUMERIC_B), - "Numeric_c" => Some(EV_KEY::KEY_NUMERIC_C), - "Numeric_d" => Some(EV_KEY::KEY_NUMERIC_D), - "Camera_focus" => Some(EV_KEY::KEY_CAMERA_FOCUS), - "Wps_button" => Some(EV_KEY::KEY_WPS_BUTTON), - "Touchpad_toggle" => Some(EV_KEY::KEY_TOUCHPAD_TOGGLE), - "Touchpad_on" => Some(EV_KEY::KEY_TOUCHPAD_ON), - "Touchpad_off" => Some(EV_KEY::KEY_TOUCHPAD_OFF), - "Camera_zoomin" => Some(EV_KEY::KEY_CAMERA_ZOOMIN), - "Camera_zoomout" => Some(EV_KEY::KEY_CAMERA_ZOOMOUT), - "Camera_up" => Some(EV_KEY::KEY_CAMERA_UP), - "Camera_down" => Some(EV_KEY::KEY_CAMERA_DOWN), - "Camera_left" => Some(EV_KEY::KEY_CAMERA_LEFT), - "Camera_right" => Some(EV_KEY::KEY_CAMERA_RIGHT), - "Attendant_on" => Some(EV_KEY::KEY_ATTENDANT_ON), - "Attendant_off" => Some(EV_KEY::KEY_ATTENDANT_OFF), - "Attendant_toggle" => Some(EV_KEY::KEY_ATTENDANT_TOGGLE), - "Lights_toggle" => Some(EV_KEY::KEY_LIGHTS_TOGGLE), - "Als_toggle" => Some(EV_KEY::KEY_ALS_TOGGLE), - "Rotate_lock_toggle" => Some(EV_KEY::KEY_ROTATE_LOCK_TOGGLE), - "Buttonconfig" => Some(EV_KEY::KEY_BUTTONCONFIG), - "Taskmanager" => Some(EV_KEY::KEY_TASKMANAGER), - "Journal" => Some(EV_KEY::KEY_JOURNAL), - "Controlpanel" => Some(EV_KEY::KEY_CONTROLPANEL), - "Appselect" => Some(EV_KEY::KEY_APPSELECT), - "Screensaver" => Some(EV_KEY::KEY_SCREENSAVER), - "Voicecommand" => Some(EV_KEY::KEY_VOICECOMMAND), - "Assistant" => Some(EV_KEY::KEY_ASSISTANT), - "Kbd_layout_next" => Some(EV_KEY::KEY_KBD_LAYOUT_NEXT), - "Emoji_picker" => Some(EV_KEY::KEY_EMOJI_PICKER), - "Dictate" => Some(EV_KEY::KEY_DICTATE), - "Brightness_min" => Some(EV_KEY::KEY_BRIGHTNESS_MIN), - "Brightness_max" => Some(EV_KEY::KEY_BRIGHTNESS_MAX), - "Kbdinputassist_prev" => Some(EV_KEY::KEY_KBDINPUTASSIST_PREV), - "Kbdinputassist_next" => Some(EV_KEY::KEY_KBDINPUTASSIST_NEXT), - "Kbdinputassist_prevgroup" => Some(EV_KEY::KEY_KBDINPUTASSIST_PREVGROUP), - "Kbdinputassist_nextgroup" => Some(EV_KEY::KEY_KBDINPUTASSIST_NEXTGROUP), - "Kbdinputassist_accept" => Some(EV_KEY::KEY_KBDINPUTASSIST_ACCEPT), - "Kbdinputassist_cancel" => Some(EV_KEY::KEY_KBDINPUTASSIST_CANCEL), - "Right_up" => Some(EV_KEY::KEY_RIGHT_UP), - "Right_down" => Some(EV_KEY::KEY_RIGHT_DOWN), - "Left_up" => Some(EV_KEY::KEY_LEFT_UP), - "Left_down" => Some(EV_KEY::KEY_LEFT_DOWN), - "Root_menu" => Some(EV_KEY::KEY_ROOT_MENU), - "Media_top_menu" => Some(EV_KEY::KEY_MEDIA_TOP_MENU), - "Numeric_11" => Some(EV_KEY::KEY_NUMERIC_11), - "Numeric_12" => Some(EV_KEY::KEY_NUMERIC_12), - "Audio_desc" => Some(EV_KEY::KEY_AUDIO_DESC), - "3d_mode" => Some(EV_KEY::KEY_3D_MODE), - "Next_favorite" => Some(EV_KEY::KEY_NEXT_FAVORITE), - "Stop_record" => Some(EV_KEY::KEY_STOP_RECORD), - "Pause_record" => Some(EV_KEY::KEY_PAUSE_RECORD), - "Vod" => Some(EV_KEY::KEY_VOD), - "Unmute" => Some(EV_KEY::KEY_UNMUTE), - "Fastreverse" => Some(EV_KEY::KEY_FASTREVERSE), - "Slowreverse" => Some(EV_KEY::KEY_SLOWREVERSE), - "Data" => Some(EV_KEY::KEY_DATA), - "Onscreen_keyboard" => Some(EV_KEY::KEY_ONSCREEN_KEYBOARD), - "Privacy_screen_toggle" => Some(EV_KEY::KEY_PRIVACY_SCREEN_TOGGLE), - "Selective_screenshot" => Some(EV_KEY::KEY_SELECTIVE_SCREENSHOT), - "Macro1" => Some(EV_KEY::KEY_MACRO1), - "Macro2" => Some(EV_KEY::KEY_MACRO2), - "Macro3" => Some(EV_KEY::KEY_MACRO3), - "Macro4" => Some(EV_KEY::KEY_MACRO4), - "Macro5" => Some(EV_KEY::KEY_MACRO5), - "Macro6" => Some(EV_KEY::KEY_MACRO6), - "Macro7" => Some(EV_KEY::KEY_MACRO7), - "Macro8" => Some(EV_KEY::KEY_MACRO8), - "Macro9" => Some(EV_KEY::KEY_MACRO9), - "Macro10" => Some(EV_KEY::KEY_MACRO10), - "Macro11" => Some(EV_KEY::KEY_MACRO11), - "Macro12" => Some(EV_KEY::KEY_MACRO12), - "Macro13" => Some(EV_KEY::KEY_MACRO13), - "Macro14" => Some(EV_KEY::KEY_MACRO14), - "Macro15" => Some(EV_KEY::KEY_MACRO15), - "Macro16" => Some(EV_KEY::KEY_MACRO16), - "Macro17" => Some(EV_KEY::KEY_MACRO17), - "Macro18" => Some(EV_KEY::KEY_MACRO18), - "Macro19" => Some(EV_KEY::KEY_MACRO19), - "Macro20" => Some(EV_KEY::KEY_MACRO20), - "Macro21" => Some(EV_KEY::KEY_MACRO21), - "Macro22" => Some(EV_KEY::KEY_MACRO22), - "Macro23" => Some(EV_KEY::KEY_MACRO23), - "Macro24" => Some(EV_KEY::KEY_MACRO24), - "Macro25" => Some(EV_KEY::KEY_MACRO25), - "Macro26" => Some(EV_KEY::KEY_MACRO26), - "Macro27" => Some(EV_KEY::KEY_MACRO27), - "Macro28" => Some(EV_KEY::KEY_MACRO28), - "Macro29" => Some(EV_KEY::KEY_MACRO29), - "Macro30" => Some(EV_KEY::KEY_MACRO30), - "Macro_record_start" => Some(EV_KEY::KEY_MACRO_RECORD_START), - "Macro_record_stop" => Some(EV_KEY::KEY_MACRO_RECORD_STOP), - "Macro_preset_cycle" => Some(EV_KEY::KEY_MACRO_PRESET_CYCLE), - "Macro_preset1" => Some(EV_KEY::KEY_MACRO_PRESET1), - "Macro_preset2" => Some(EV_KEY::KEY_MACRO_PRESET2), - "Macro_preset3" => Some(EV_KEY::KEY_MACRO_PRESET3), - "Kbd_lcd_menu1" => Some(EV_KEY::KEY_KBD_LCD_MENU1), - "Kbd_lcd_menu2" => Some(EV_KEY::KEY_KBD_LCD_MENU2), - "Kbd_lcd_menu3" => Some(EV_KEY::KEY_KBD_LCD_MENU3), - "Kbd_lcd_menu4" => Some(EV_KEY::KEY_KBD_LCD_MENU4), - "Kbd_lcd_menu5" => Some(EV_KEY::KEY_KBD_LCD_MENU5), - "Max" => Some(EV_KEY::KEY_MAX), - "Btn_0" => Some(EV_KEY::BTN_0), - "Btn_1" => Some(EV_KEY::BTN_1), - "Btn_2" => Some(EV_KEY::BTN_2), - "Btn_3" => Some(EV_KEY::BTN_3), - "Btn_4" => Some(EV_KEY::BTN_4), - "Btn_5" => Some(EV_KEY::BTN_5), - "Btn_6" => Some(EV_KEY::BTN_6), - "Btn_7" => Some(EV_KEY::BTN_7), - "Btn_8" => Some(EV_KEY::BTN_8), - "Btn_9" => Some(EV_KEY::BTN_9), - "Btn_left" => Some(EV_KEY::BTN_LEFT), - "Btn_right" => Some(EV_KEY::BTN_RIGHT), - "Btn_middle" => Some(EV_KEY::BTN_MIDDLE), - "Btn_side" => Some(EV_KEY::BTN_SIDE), - "Btn_extra" => Some(EV_KEY::BTN_EXTRA), - "Btn_forward" => Some(EV_KEY::BTN_FORWARD), - "Btn_back" => Some(EV_KEY::BTN_BACK), - "Btn_task" => Some(EV_KEY::BTN_TASK), - "Btn_trigger" => Some(EV_KEY::BTN_TRIGGER), - "Btn_thumb" => Some(EV_KEY::BTN_THUMB), - "Btn_thumb2" => Some(EV_KEY::BTN_THUMB2), - "Btn_top" => Some(EV_KEY::BTN_TOP), - "Btn_top2" => Some(EV_KEY::BTN_TOP2), - "Btn_pinkie" => Some(EV_KEY::BTN_PINKIE), - "Btn_base" => Some(EV_KEY::BTN_BASE), - "Btn_base2" => Some(EV_KEY::BTN_BASE2), - "Btn_base3" => Some(EV_KEY::BTN_BASE3), - "Btn_base4" => Some(EV_KEY::BTN_BASE4), - "Btn_base5" => Some(EV_KEY::BTN_BASE5), - "Btn_base6" => Some(EV_KEY::BTN_BASE6), - "Btn_dead" => Some(EV_KEY::BTN_DEAD), - "Btn_south" => Some(EV_KEY::BTN_SOUTH), - "Btn_east" => Some(EV_KEY::BTN_EAST), - "Btn_c" => Some(EV_KEY::BTN_C), - "Btn_north" => Some(EV_KEY::BTN_NORTH), - "Btn_west" => Some(EV_KEY::BTN_WEST), - "Btn_z" => Some(EV_KEY::BTN_Z), - "Btn_tl" => Some(EV_KEY::BTN_TL), - "Btn_tr" => Some(EV_KEY::BTN_TR), - "Btn_tl2" => Some(EV_KEY::BTN_TL2), - "Btn_tr2" => Some(EV_KEY::BTN_TR2), - "Btn_select" => Some(EV_KEY::BTN_SELECT), - "Btn_start" => Some(EV_KEY::BTN_START), - "Btn_mode" => Some(EV_KEY::BTN_MODE), - "Btn_thumbl" => Some(EV_KEY::BTN_THUMBL), - "Btn_thumbr" => Some(EV_KEY::BTN_THUMBR), - "Btn_tool_pen" => Some(EV_KEY::BTN_TOOL_PEN), - "Btn_tool_rubber" => Some(EV_KEY::BTN_TOOL_RUBBER), - "Btn_tool_brush" => Some(EV_KEY::BTN_TOOL_BRUSH), - "Btn_tool_pencil" => Some(EV_KEY::BTN_TOOL_PENCIL), - "Btn_tool_airbrush" => Some(EV_KEY::BTN_TOOL_AIRBRUSH), - "Btn_tool_finger" => Some(EV_KEY::BTN_TOOL_FINGER), - "Btn_tool_mouse" => Some(EV_KEY::BTN_TOOL_MOUSE), - "Btn_tool_lens" => Some(EV_KEY::BTN_TOOL_LENS), - "Btn_tool_quinttap" => Some(EV_KEY::BTN_TOOL_QUINTTAP), - "Btn_stylus3" => Some(EV_KEY::BTN_STYLUS3), - "Btn_touch" => Some(EV_KEY::BTN_TOUCH), - "Btn_stylus" => Some(EV_KEY::BTN_STYLUS), - "Btn_stylus2" => Some(EV_KEY::BTN_STYLUS2), - "Btn_tool_doubletap" => Some(EV_KEY::BTN_TOOL_DOUBLETAP), - "Btn_tool_tripletap" => Some(EV_KEY::BTN_TOOL_TRIPLETAP), - "Btn_tool_quadtap" => Some(EV_KEY::BTN_TOOL_QUADTAP), - "Btn_gear_down" => Some(EV_KEY::BTN_GEAR_DOWN), - "Btn_gear_up" => Some(EV_KEY::BTN_GEAR_UP), - "Btn_dpad_up" => Some(EV_KEY::BTN_DPAD_UP), - "Btn_dpad_down" => Some(EV_KEY::BTN_DPAD_DOWN), - "Btn_dpad_left" => Some(EV_KEY::BTN_DPAD_LEFT), - "Btn_dpad_right" => Some(EV_KEY::BTN_DPAD_RIGHT), - "Btn_trigger_happy1" => Some(EV_KEY::BTN_TRIGGER_HAPPY1), - "Btn_trigger_happy2" => Some(EV_KEY::BTN_TRIGGER_HAPPY2), - "Btn_trigger_happy3" => Some(EV_KEY::BTN_TRIGGER_HAPPY3), - "Btn_trigger_happy4" => Some(EV_KEY::BTN_TRIGGER_HAPPY4), - "Btn_trigger_happy5" => Some(EV_KEY::BTN_TRIGGER_HAPPY5), - "Btn_trigger_happy6" => Some(EV_KEY::BTN_TRIGGER_HAPPY6), - "Btn_trigger_happy7" => Some(EV_KEY::BTN_TRIGGER_HAPPY7), - "Btn_trigger_happy8" => Some(EV_KEY::BTN_TRIGGER_HAPPY8), - "Btn_trigger_happy9" => Some(EV_KEY::BTN_TRIGGER_HAPPY9), - "Btn_trigger_happy10" => Some(EV_KEY::BTN_TRIGGER_HAPPY10), - "Btn_trigger_happy11" => Some(EV_KEY::BTN_TRIGGER_HAPPY11), - "Btn_trigger_happy12" => Some(EV_KEY::BTN_TRIGGER_HAPPY12), - "Btn_trigger_happy13" => Some(EV_KEY::BTN_TRIGGER_HAPPY13), - "Btn_trigger_happy14" => Some(EV_KEY::BTN_TRIGGER_HAPPY14), - "Btn_trigger_happy15" => Some(EV_KEY::BTN_TRIGGER_HAPPY15), - "Btn_trigger_happy16" => Some(EV_KEY::BTN_TRIGGER_HAPPY16), - "Btn_trigger_happy17" => Some(EV_KEY::BTN_TRIGGER_HAPPY17), - "Btn_trigger_happy18" => Some(EV_KEY::BTN_TRIGGER_HAPPY18), - "Btn_trigger_happy19" => Some(EV_KEY::BTN_TRIGGER_HAPPY19), - "Btn_trigger_happy20" => Some(EV_KEY::BTN_TRIGGER_HAPPY20), - "Btn_trigger_happy21" => Some(EV_KEY::BTN_TRIGGER_HAPPY21), - "Btn_trigger_happy22" => Some(EV_KEY::BTN_TRIGGER_HAPPY22), - "Btn_trigger_happy23" => Some(EV_KEY::BTN_TRIGGER_HAPPY23), - "Btn_trigger_happy24" => Some(EV_KEY::BTN_TRIGGER_HAPPY24), - "Btn_trigger_happy25" => Some(EV_KEY::BTN_TRIGGER_HAPPY25), - "Btn_trigger_happy26" => Some(EV_KEY::BTN_TRIGGER_HAPPY26), - "Btn_trigger_happy27" => Some(EV_KEY::BTN_TRIGGER_HAPPY27), - "Btn_trigger_happy28" => Some(EV_KEY::BTN_TRIGGER_HAPPY28), - "Btn_trigger_happy29" => Some(EV_KEY::BTN_TRIGGER_HAPPY29), - "Btn_trigger_happy30" => Some(EV_KEY::BTN_TRIGGER_HAPPY30), - "Btn_trigger_happy31" => Some(EV_KEY::BTN_TRIGGER_HAPPY31), - "Btn_trigger_happy32" => Some(EV_KEY::BTN_TRIGGER_HAPPY32), - "Btn_trigger_happy33" => Some(EV_KEY::BTN_TRIGGER_HAPPY33), - "Btn_trigger_happy34" => Some(EV_KEY::BTN_TRIGGER_HAPPY34), - "Btn_trigger_happy35" => Some(EV_KEY::BTN_TRIGGER_HAPPY35), - "Btn_trigger_happy36" => Some(EV_KEY::BTN_TRIGGER_HAPPY36), - "Btn_trigger_happy37" => Some(EV_KEY::BTN_TRIGGER_HAPPY37), - "Btn_trigger_happy38" => Some(EV_KEY::BTN_TRIGGER_HAPPY38), - "Btn_trigger_happy39" => Some(EV_KEY::BTN_TRIGGER_HAPPY39), - "Btn_trigger_happy40" => Some(EV_KEY::BTN_TRIGGER_HAPPY40), + "Reserved" => Some(Key::KEY_RESERVED), + "Escape" => Some(Key::KEY_ESC), + "1" => Some(Key::KEY_1), + "2" => Some(Key::KEY_2), + "3" => Some(Key::KEY_3), + "4" => Some(Key::KEY_4), + "5" => Some(Key::KEY_5), + "6" => Some(Key::KEY_6), + "7" => Some(Key::KEY_7), + "8" => Some(Key::KEY_8), + "9" => Some(Key::KEY_9), + "0" => Some(Key::KEY_0), + "Minus" => Some(Key::KEY_MINUS), + "Equal" => Some(Key::KEY_EQUAL), + "Backspace" => Some(Key::KEY_BACKSPACE), + "Tab" => Some(Key::KEY_TAB), + "q" => Some(Key::KEY_Q), + "w" => Some(Key::KEY_W), + "e" => Some(Key::KEY_E), + "r" => Some(Key::KEY_R), + "t" => Some(Key::KEY_T), + "y" => Some(Key::KEY_Y), + "u" => Some(Key::KEY_U), + "i" => Some(Key::KEY_I), + "o" => Some(Key::KEY_O), + "p" => Some(Key::KEY_P), + "Leftbrace" => Some(Key::KEY_LEFTBRACE), + "Rightbrace" => Some(Key::KEY_RIGHTBRACE), + "Enter" => Some(Key::KEY_ENTER), + "Leftctrl" => Some(Key::KEY_LEFTCTRL), + "a" => Some(Key::KEY_A), + "s" => Some(Key::KEY_S), + "d" => Some(Key::KEY_D), + "f" => Some(Key::KEY_F), + "g" => Some(Key::KEY_G), + "h" => Some(Key::KEY_H), + "j" => Some(Key::KEY_J), + "k" => Some(Key::KEY_K), + "l" => Some(Key::KEY_L), + "Semicolon" => Some(Key::KEY_SEMICOLON), + "Apostrophe" => Some(Key::KEY_APOSTROPHE), + "Grave" => Some(Key::KEY_GRAVE), + "Leftshift" => Some(Key::KEY_LEFTSHIFT), + "Backslash" => Some(Key::KEY_BACKSLASH), + "z" => Some(Key::KEY_Z), + "x" => Some(Key::KEY_X), + "c" => Some(Key::KEY_C), + "v" => Some(Key::KEY_V), + "b" => Some(Key::KEY_B), + "n" => Some(Key::KEY_N), + "m" => Some(Key::KEY_M), + "Comma" => Some(Key::KEY_COMMA), + "Dot" => Some(Key::KEY_DOT), + "Slash" => Some(Key::KEY_SLASH), + "Rightshift" => Some(Key::KEY_RIGHTSHIFT), + "Kpasterisk" => Some(Key::KEY_KPASTERISK), + "Leftalt" => Some(Key::KEY_LEFTALT), + "Space" => Some(Key::KEY_SPACE), + "Capslock" => Some(Key::KEY_CAPSLOCK), + "F1" => Some(Key::KEY_F1), + "F2" => Some(Key::KEY_F2), + "F3" => Some(Key::KEY_F3), + "F4" => Some(Key::KEY_F4), + "F5" => Some(Key::KEY_F5), + "F6" => Some(Key::KEY_F6), + "F7" => Some(Key::KEY_F7), + "F8" => Some(Key::KEY_F8), + "F9" => Some(Key::KEY_F9), + "F10" => Some(Key::KEY_F10), + "Numlock" => Some(Key::KEY_NUMLOCK), + "Scrolllock" => Some(Key::KEY_SCROLLLOCK), + "Kp7" => Some(Key::KEY_KP7), + "Kp8" => Some(Key::KEY_KP8), + "Kp9" => Some(Key::KEY_KP9), + "Kpminus" => Some(Key::KEY_KPMINUS), + "Kp4" => Some(Key::KEY_KP4), + "Kp5" => Some(Key::KEY_KP5), + "Kp6" => Some(Key::KEY_KP6), + "Kpplus" => Some(Key::KEY_KPPLUS), + "Kp1" => Some(Key::KEY_KP1), + "Kp2" => Some(Key::KEY_KP2), + "Kp3" => Some(Key::KEY_KP3), + "Kp0" => Some(Key::KEY_KP0), + "Kpdot" => Some(Key::KEY_KPDOT), + "Zenkakuhankaku" => Some(Key::KEY_ZENKAKUHANKAKU), + "102nd" => Some(Key::KEY_102ND), + "F11" => Some(Key::KEY_F11), + "F12" => Some(Key::KEY_F12), + "Ro" => Some(Key::KEY_RO), + "Katakana" => Some(Key::KEY_KATAKANA), + "Hiragana" => Some(Key::KEY_HIRAGANA), + "Henkan" => Some(Key::KEY_HENKAN), + "Katakanahiragana" => Some(Key::KEY_KATAKANAHIRAGANA), + "Muhenkan" => Some(Key::KEY_MUHENKAN), + "Kpjpcomma" => Some(Key::KEY_KPJPCOMMA), + "Kpenter" => Some(Key::KEY_KPENTER), + "Rightctrl" => Some(Key::KEY_RIGHTCTRL), + "Kpslash" => Some(Key::KEY_KPSLASH), + "Sysrq" => Some(Key::KEY_SYSRQ), + "Rightalt" => Some(Key::KEY_RIGHTALT), + "Linefeed" => Some(Key::KEY_LINEFEED), + "Home" => Some(Key::KEY_HOME), + "Up" => Some(Key::KEY_UP), + "Pageup" => Some(Key::KEY_PAGEUP), + "Left" => Some(Key::KEY_LEFT), + "Right" => Some(Key::KEY_RIGHT), + "End" => Some(Key::KEY_END), + "Down" => Some(Key::KEY_DOWN), + "Pagedown" => Some(Key::KEY_PAGEDOWN), + "Insert" => Some(Key::KEY_INSERT), + "Delete" => Some(Key::KEY_DELETE), + "Macro" => Some(Key::KEY_MACRO), + "Mute" => Some(Key::KEY_MUTE), + "Volumedown" => Some(Key::KEY_VOLUMEDOWN), + "Volumeup" => Some(Key::KEY_VOLUMEUP), + "Power" => Some(Key::KEY_POWER), + "Kpequal" => Some(Key::KEY_KPEQUAL), + "Kpplusminus" => Some(Key::KEY_KPPLUSMINUS), + "Pause" => Some(Key::KEY_PAUSE), + "Scale" => Some(Key::KEY_SCALE), + "Kpcomma" => Some(Key::KEY_KPCOMMA), + "Hangeul" => Some(Key::KEY_HANGEUL), + "Hanja" => Some(Key::KEY_HANJA), + "Yen" => Some(Key::KEY_YEN), + "Leftmeta" => Some(Key::KEY_LEFTMETA), + "Rightmeta" => Some(Key::KEY_RIGHTMETA), + "Compose" => Some(Key::KEY_COMPOSE), + "Stop" => Some(Key::KEY_STOP), + "Again" => Some(Key::KEY_AGAIN), + "Props" => Some(Key::KEY_PROPS), + "Undo" => Some(Key::KEY_UNDO), + "Front" => Some(Key::KEY_FRONT), + "Copy" => Some(Key::KEY_COPY), + "Open" => Some(Key::KEY_OPEN), + "Paste" => Some(Key::KEY_PASTE), + "Find" => Some(Key::KEY_FIND), + "Cut" => Some(Key::KEY_CUT), + "Help" => Some(Key::KEY_HELP), + "Menu" => Some(Key::KEY_MENU), + "Calc" => Some(Key::KEY_CALC), + "Setup" => Some(Key::KEY_SETUP), + "Sleep" => Some(Key::KEY_SLEEP), + "Wakeup" => Some(Key::KEY_WAKEUP), + "File" => Some(Key::KEY_FILE), + "Sendfile" => Some(Key::KEY_SENDFILE), + "Deletefile" => Some(Key::KEY_DELETEFILE), + "Xfer" => Some(Key::KEY_XFER), + "Prog1" => Some(Key::KEY_PROG1), + "Prog2" => Some(Key::KEY_PROG2), + "Www" => Some(Key::KEY_WWW), + "Msdos" => Some(Key::KEY_MSDOS), + "Coffee" => Some(Key::KEY_COFFEE), + "Rotate_display" => Some(Key::KEY_ROTATE_DISPLAY), + "Cyclewindows" => Some(Key::KEY_CYCLEWINDOWS), + "Mail" => Some(Key::KEY_MAIL), + "Bookmarks" => Some(Key::KEY_BOOKMARKS), + "Computer" => Some(Key::KEY_COMPUTER), + "Back" => Some(Key::KEY_BACK), + "Forward" => Some(Key::KEY_FORWARD), + "Closecd" => Some(Key::KEY_CLOSECD), + "Ejectcd" => Some(Key::KEY_EJECTCD), + "Ejectclosecd" => Some(Key::KEY_EJECTCLOSECD), + "Nextsong" => Some(Key::KEY_NEXTSONG), + "Playpause" => Some(Key::KEY_PLAYPAUSE), + "Previoussong" => Some(Key::KEY_PREVIOUSSONG), + "Stopcd" => Some(Key::KEY_STOPCD), + "Record" => Some(Key::KEY_RECORD), + "Rewind" => Some(Key::KEY_REWIND), + "Phone" => Some(Key::KEY_PHONE), + "Iso" => Some(Key::KEY_ISO), + "Config" => Some(Key::KEY_CONFIG), + "Homepage" => Some(Key::KEY_HOMEPAGE), + "Refresh" => Some(Key::KEY_REFRESH), + "Exit" => Some(Key::KEY_EXIT), + "Move" => Some(Key::KEY_MOVE), + "Edit" => Some(Key::KEY_EDIT), + "Scrollup" => Some(Key::KEY_SCROLLUP), + "Scrolldown" => Some(Key::KEY_SCROLLDOWN), + "Kpleftparen" => Some(Key::KEY_KPLEFTPAREN), + "Kprightparen" => Some(Key::KEY_KPRIGHTPAREN), + "New" => Some(Key::KEY_NEW), + "Redo" => Some(Key::KEY_REDO), + "F13" => Some(Key::KEY_F13), + "F14" => Some(Key::KEY_F14), + "F15" => Some(Key::KEY_F15), + "F16" => Some(Key::KEY_F16), + "F17" => Some(Key::KEY_F17), + "F18" => Some(Key::KEY_F18), + "F19" => Some(Key::KEY_F19), + "F20" => Some(Key::KEY_F20), + "F21" => Some(Key::KEY_F21), + "F22" => Some(Key::KEY_F22), + "F23" => Some(Key::KEY_F23), + "F24" => Some(Key::KEY_F24), + "Playcd" => Some(Key::KEY_PLAYCD), + "Pausecd" => Some(Key::KEY_PAUSECD), + "Prog3" => Some(Key::KEY_PROG3), + "Prog4" => Some(Key::KEY_PROG4), + "Dashboard" => Some(Key::KEY_DASHBOARD), + "Suspend" => Some(Key::KEY_SUSPEND), + "Close" => Some(Key::KEY_CLOSE), + "Play" => Some(Key::KEY_PLAY), + "Fastforward" => Some(Key::KEY_FASTFORWARD), + "Bassboost" => Some(Key::KEY_BASSBOOST), + "Print" => Some(Key::KEY_PRINT), + "Hp" => Some(Key::KEY_HP), + "Camera" => Some(Key::KEY_CAMERA), + "Sound" => Some(Key::KEY_SOUND), + "Question" => Some(Key::KEY_QUESTION), + "Email" => Some(Key::KEY_EMAIL), + "Chat" => Some(Key::KEY_CHAT), + "Search" => Some(Key::KEY_SEARCH), + "Connect" => Some(Key::KEY_CONNECT), + "Finance" => Some(Key::KEY_FINANCE), + "Sport" => Some(Key::KEY_SPORT), + "Shop" => Some(Key::KEY_SHOP), + "Alterase" => Some(Key::KEY_ALTERASE), + "Cancel" => Some(Key::KEY_CANCEL), + "Brightnessdown" => Some(Key::KEY_BRIGHTNESSDOWN), + "Brightnessup" => Some(Key::KEY_BRIGHTNESSUP), + "Media" => Some(Key::KEY_MEDIA), + "Switchvideomode" => Some(Key::KEY_SWITCHVIDEOMODE), + "Kbdillumtoggle" => Some(Key::KEY_KBDILLUMTOGGLE), + "Kbdillumdown" => Some(Key::KEY_KBDILLUMDOWN), + "Kbdillumup" => Some(Key::KEY_KBDILLUMUP), + "Send" => Some(Key::KEY_SEND), + "Reply" => Some(Key::KEY_REPLY), + "Forwardmail" => Some(Key::KEY_FORWARDMAIL), + "Save" => Some(Key::KEY_SAVE), + "Documents" => Some(Key::KEY_DOCUMENTS), + "Battery" => Some(Key::KEY_BATTERY), + "Bluetooth" => Some(Key::KEY_BLUETOOTH), + "Wlan" => Some(Key::KEY_WLAN), + "Uwb" => Some(Key::KEY_UWB), + "Unknown" => Some(Key::KEY_UNKNOWN), + "Video_next" => Some(Key::KEY_VIDEO_NEXT), + "Video_prev" => Some(Key::KEY_VIDEO_PREV), + "Brightness_cycle" => Some(Key::KEY_BRIGHTNESS_CYCLE), + "Brightness_auto" => Some(Key::KEY_BRIGHTNESS_AUTO), + "Display_off" => Some(Key::KEY_DISPLAY_OFF), + "Wwan" => Some(Key::KEY_WWAN), + "Rfkill" => Some(Key::KEY_RFKILL), + "Micmute" => Some(Key::KEY_MICMUTE), + "Ok" => Some(Key::KEY_OK), + "Select" => Some(Key::KEY_SELECT), + "Goto" => Some(Key::KEY_GOTO), + "Clear" => Some(Key::KEY_CLEAR), + "Power2" => Some(Key::KEY_POWER2), + "Option" => Some(Key::KEY_OPTION), + "Info" => Some(Key::KEY_INFO), + "Time" => Some(Key::KEY_TIME), + "Vendor" => Some(Key::KEY_VENDOR), + "Archive" => Some(Key::KEY_ARCHIVE), + "Program" => Some(Key::KEY_PROGRAM), + "Channel" => Some(Key::KEY_CHANNEL), + "Favorites" => Some(Key::KEY_FAVORITES), + "Epg" => Some(Key::KEY_EPG), + "Pvr" => Some(Key::KEY_PVR), + "Mhp" => Some(Key::KEY_MHP), + "Language" => Some(Key::KEY_LANGUAGE), + "Title" => Some(Key::KEY_TITLE), + "Subtitle" => Some(Key::KEY_SUBTITLE), + "Angle" => Some(Key::KEY_ANGLE), + "Full_screen" => Some(Key::KEY_FULL_SCREEN), + "Mode" => Some(Key::KEY_MODE), + "Keyboard" => Some(Key::KEY_KEYBOARD), + "Screen" => Some(Key::KEY_SCREEN), + "Pc" => Some(Key::KEY_PC), + "Tv" => Some(Key::KEY_TV), + "Tv2" => Some(Key::KEY_TV2), + "Vcr" => Some(Key::KEY_VCR), + "Vcr2" => Some(Key::KEY_VCR2), + "Sat" => Some(Key::KEY_SAT), + "Sat2" => Some(Key::KEY_SAT2), + "Cd" => Some(Key::KEY_CD), + "Tape" => Some(Key::KEY_TAPE), + "Radio" => Some(Key::KEY_RADIO), + "Tuner" => Some(Key::KEY_TUNER), + "Player" => Some(Key::KEY_PLAYER), + "Text" => Some(Key::KEY_TEXT), + "Dvd" => Some(Key::KEY_DVD), + "Aux" => Some(Key::KEY_AUX), + "Mp3" => Some(Key::KEY_MP3), + "Audio" => Some(Key::KEY_AUDIO), + "Video" => Some(Key::KEY_VIDEO), + "Directory" => Some(Key::KEY_DIRECTORY), + "List" => Some(Key::KEY_LIST), + "Memo" => Some(Key::KEY_MEMO), + "Calendar" => Some(Key::KEY_CALENDAR), + "Red" => Some(Key::KEY_RED), + "Green" => Some(Key::KEY_GREEN), + "Yellow" => Some(Key::KEY_YELLOW), + "Blue" => Some(Key::KEY_BLUE), + "Channelup" => Some(Key::KEY_CHANNELUP), + "Channeldown" => Some(Key::KEY_CHANNELDOWN), + "First" => Some(Key::KEY_FIRST), + "Last" => Some(Key::KEY_LAST), + "Ab" => Some(Key::KEY_AB), + "Next" => Some(Key::KEY_NEXT), + "Restart" => Some(Key::KEY_RESTART), + "Slow" => Some(Key::KEY_SLOW), + "Shuffle" => Some(Key::KEY_SHUFFLE), + "Break" => Some(Key::KEY_BREAK), + "Previous" => Some(Key::KEY_PREVIOUS), + "Digits" => Some(Key::KEY_DIGITS), + "Teen" => Some(Key::KEY_TEEN), + "Twen" => Some(Key::KEY_TWEN), + "Videophone" => Some(Key::KEY_VIDEOPHONE), + "Games" => Some(Key::KEY_GAMES), + "Zoomin" => Some(Key::KEY_ZOOMIN), + "Zoomout" => Some(Key::KEY_ZOOMOUT), + "Zoomreset" => Some(Key::KEY_ZOOMRESET), + "Wordprocessor" => Some(Key::KEY_WORDPROCESSOR), + "Editor" => Some(Key::KEY_EDITOR), + "Spreadsheet" => Some(Key::KEY_SPREADSHEET), + "Graphicseditor" => Some(Key::KEY_GRAPHICSEDITOR), + "Presentation" => Some(Key::KEY_PRESENTATION), + "Database" => Some(Key::KEY_DATABASE), + "News" => Some(Key::KEY_NEWS), + "Voicemail" => Some(Key::KEY_VOICEMAIL), + "Addressbook" => Some(Key::KEY_ADDRESSBOOK), + "Messenger" => Some(Key::KEY_MESSENGER), + "Displaytoggle" => Some(Key::KEY_DISPLAYTOGGLE), + "Spellcheck" => Some(Key::KEY_SPELLCHECK), + "Logoff" => Some(Key::KEY_LOGOFF), + "Dollar" => Some(Key::KEY_DOLLAR), + "Euro" => Some(Key::KEY_EURO), + "Frameback" => Some(Key::KEY_FRAMEBACK), + "Frameforward" => Some(Key::KEY_FRAMEFORWARD), + "Context_menu" => Some(Key::KEY_CONTEXT_MENU), + "Media_repeat" => Some(Key::KEY_MEDIA_REPEAT), + "10channelsup" => Some(Key::KEY_10CHANNELSUP), + "10channelsdown" => Some(Key::KEY_10CHANNELSDOWN), + "Images" => Some(Key::KEY_IMAGES), + "Del_eol" => Some(Key::KEY_DEL_EOL), + "Del_eos" => Some(Key::KEY_DEL_EOS), + "Ins_line" => Some(Key::KEY_INS_LINE), + "Del_line" => Some(Key::KEY_DEL_LINE), + "Fn" => Some(Key::KEY_FN), + "Fn_esc" => Some(Key::KEY_FN_ESC), + "Fn_f1" => Some(Key::KEY_FN_F1), + "Fn_f2" => Some(Key::KEY_FN_F2), + "Fn_f3" => Some(Key::KEY_FN_F3), + "Fn_f4" => Some(Key::KEY_FN_F4), + "Fn_f5" => Some(Key::KEY_FN_F5), + "Fn_f6" => Some(Key::KEY_FN_F6), + "Fn_f7" => Some(Key::KEY_FN_F7), + "Fn_f8" => Some(Key::KEY_FN_F8), + "Fn_f9" => Some(Key::KEY_FN_F9), + "Fn_f10" => Some(Key::KEY_FN_F10), + "Fn_f11" => Some(Key::KEY_FN_F11), + "Fn_f12" => Some(Key::KEY_FN_F12), + "Fn_1" => Some(Key::KEY_FN_1), + "Fn_2" => Some(Key::KEY_FN_2), + "Fn_d" => Some(Key::KEY_FN_D), + "Fn_e" => Some(Key::KEY_FN_E), + "Fn_f" => Some(Key::KEY_FN_F), + "Fn_s" => Some(Key::KEY_FN_S), + "Fn_b" => Some(Key::KEY_FN_B), + "Brl_dot1" => Some(Key::KEY_BRL_DOT1), + "Brl_dot2" => Some(Key::KEY_BRL_DOT2), + "Brl_dot3" => Some(Key::KEY_BRL_DOT3), + "Brl_dot4" => Some(Key::KEY_BRL_DOT4), + "Brl_dot5" => Some(Key::KEY_BRL_DOT5), + "Brl_dot6" => Some(Key::KEY_BRL_DOT6), + "Brl_dot7" => Some(Key::KEY_BRL_DOT7), + "Brl_dot8" => Some(Key::KEY_BRL_DOT8), + "Brl_dot9" => Some(Key::KEY_BRL_DOT9), + "Brl_dot10" => Some(Key::KEY_BRL_DOT10), + "Numeric_0" => Some(Key::KEY_NUMERIC_0), + "Numeric_1" => Some(Key::KEY_NUMERIC_1), + "Numeric_2" => Some(Key::KEY_NUMERIC_2), + "Numeric_3" => Some(Key::KEY_NUMERIC_3), + "Numeric_4" => Some(Key::KEY_NUMERIC_4), + "Numeric_5" => Some(Key::KEY_NUMERIC_5), + "Numeric_6" => Some(Key::KEY_NUMERIC_6), + "Numeric_7" => Some(Key::KEY_NUMERIC_7), + "Numeric_8" => Some(Key::KEY_NUMERIC_8), + "Numeric_9" => Some(Key::KEY_NUMERIC_9), + "Numeric_star" => Some(Key::KEY_NUMERIC_STAR), + "Numeric_pound" => Some(Key::KEY_NUMERIC_POUND), + "Numeric_a" => Some(Key::KEY_NUMERIC_A), + "Numeric_b" => Some(Key::KEY_NUMERIC_B), + "Numeric_c" => Some(Key::KEY_NUMERIC_C), + "Numeric_d" => Some(Key::KEY_NUMERIC_D), + "Camera_focus" => Some(Key::KEY_CAMERA_FOCUS), + "Wps_button" => Some(Key::KEY_WPS_BUTTON), + "Touchpad_toggle" => Some(Key::KEY_TOUCHPAD_TOGGLE), + "Touchpad_on" => Some(Key::KEY_TOUCHPAD_ON), + "Touchpad_off" => Some(Key::KEY_TOUCHPAD_OFF), + "Camera_zoomin" => Some(Key::KEY_CAMERA_ZOOMIN), + "Camera_zoomout" => Some(Key::KEY_CAMERA_ZOOMOUT), + "Camera_up" => Some(Key::KEY_CAMERA_UP), + "Camera_down" => Some(Key::KEY_CAMERA_DOWN), + "Camera_left" => Some(Key::KEY_CAMERA_LEFT), + "Camera_right" => Some(Key::KEY_CAMERA_RIGHT), + "Attendant_on" => Some(Key::KEY_ATTENDANT_ON), + "Attendant_off" => Some(Key::KEY_ATTENDANT_OFF), + "Attendant_toggle" => Some(Key::KEY_ATTENDANT_TOGGLE), + "Lights_toggle" => Some(Key::KEY_LIGHTS_TOGGLE), + "Als_toggle" => Some(Key::KEY_ALS_TOGGLE), + "Buttonconfig" => Some(Key::KEY_BUTTONCONFIG), + "Taskmanager" => Some(Key::KEY_TASKMANAGER), + "Journal" => Some(Key::KEY_JOURNAL), + "Controlpanel" => Some(Key::KEY_CONTROLPANEL), + "Appselect" => Some(Key::KEY_APPSELECT), + "Screensaver" => Some(Key::KEY_SCREENSAVER), + "Voicecommand" => Some(Key::KEY_VOICECOMMAND), + "Assistant" => Some(Key::KEY_ASSISTANT), + "Kbd_layout_next" => Some(Key::KEY_KBD_LAYOUT_NEXT), + "Brightness_min" => Some(Key::KEY_BRIGHTNESS_MIN), + "Brightness_max" => Some(Key::KEY_BRIGHTNESS_MAX), + "Kbdinputassist_prev" => Some(Key::KEY_KBDINPUTASSIST_PREV), + "Kbdinputassist_next" => Some(Key::KEY_KBDINPUTASSIST_NEXT), + "Kbdinputassist_prevgroup" => Some(Key::KEY_KBDINPUTASSIST_PREVGROUP), + "Kbdinputassist_nextgroup" => Some(Key::KEY_KBDINPUTASSIST_NEXTGROUP), + "Kbdinputassist_accept" => Some(Key::KEY_KBDINPUTASSIST_ACCEPT), + "Kbdinputassist_cancel" => Some(Key::KEY_KBDINPUTASSIST_CANCEL), + "Right_up" => Some(Key::KEY_RIGHT_UP), + "Right_down" => Some(Key::KEY_RIGHT_DOWN), + "Left_up" => Some(Key::KEY_LEFT_UP), + "Left_down" => Some(Key::KEY_LEFT_DOWN), + "Root_menu" => Some(Key::KEY_ROOT_MENU), + "Media_top_menu" => Some(Key::KEY_MEDIA_TOP_MENU), + "Numeric_11" => Some(Key::KEY_NUMERIC_11), + "Numeric_12" => Some(Key::KEY_NUMERIC_12), + "Audio_desc" => Some(Key::KEY_AUDIO_DESC), + "3d_mode" => Some(Key::KEY_3D_MODE), + "Next_favorite" => Some(Key::KEY_NEXT_FAVORITE), + "Stop_record" => Some(Key::KEY_STOP_RECORD), + "Pause_record" => Some(Key::KEY_PAUSE_RECORD), + "Vod" => Some(Key::KEY_VOD), + "Unmute" => Some(Key::KEY_UNMUTE), + "Fastreverse" => Some(Key::KEY_FASTREVERSE), + "Slowreverse" => Some(Key::KEY_SLOWREVERSE), + "Data" => Some(Key::KEY_DATA), + "Onscreen_keyboard" => Some(Key::KEY_ONSCREEN_KEYBOARD), + "Privacy_screen_toggle" => Some(Key::KEY_PRIVACY_SCREEN_TOGGLE), + "Selective_screenshot" => Some(Key::KEY_SELECTIVE_SCREENSHOT), + "Btn_0" => Some(Key::BTN_0), + "Btn_1" => Some(Key::BTN_1), + "Btn_2" => Some(Key::BTN_2), + "Btn_3" => Some(Key::BTN_3), + "Btn_4" => Some(Key::BTN_4), + "Btn_5" => Some(Key::BTN_5), + "Btn_6" => Some(Key::BTN_6), + "Btn_7" => Some(Key::BTN_7), + "Btn_8" => Some(Key::BTN_8), + "Btn_9" => Some(Key::BTN_9), + "Btn_left" => Some(Key::BTN_LEFT), + "Btn_right" => Some(Key::BTN_RIGHT), + "Btn_middle" => Some(Key::BTN_MIDDLE), + "Btn_side" => Some(Key::BTN_SIDE), + "Btn_extra" => Some(Key::BTN_EXTRA), + "Btn_forward" => Some(Key::BTN_FORWARD), + "Btn_back" => Some(Key::BTN_BACK), + "Btn_task" => Some(Key::BTN_TASK), + "Btn_trigger" => Some(Key::BTN_TRIGGER), + "Btn_thumb" => Some(Key::BTN_THUMB), + "Btn_thumb2" => Some(Key::BTN_THUMB2), + "Btn_top" => Some(Key::BTN_TOP), + "Btn_top2" => Some(Key::BTN_TOP2), + "Btn_pinkie" => Some(Key::BTN_PINKIE), + "Btn_base" => Some(Key::BTN_BASE), + "Btn_base2" => Some(Key::BTN_BASE2), + "Btn_base3" => Some(Key::BTN_BASE3), + "Btn_base4" => Some(Key::BTN_BASE4), + "Btn_base5" => Some(Key::BTN_BASE5), + "Btn_base6" => Some(Key::BTN_BASE6), + "Btn_dead" => Some(Key::BTN_DEAD), + "Btn_south" => Some(Key::BTN_SOUTH), + "Btn_east" => Some(Key::BTN_EAST), + "Btn_c" => Some(Key::BTN_C), + "Btn_north" => Some(Key::BTN_NORTH), + "Btn_west" => Some(Key::BTN_WEST), + "Btn_z" => Some(Key::BTN_Z), + "Btn_tl" => Some(Key::BTN_TL), + "Btn_tr" => Some(Key::BTN_TR), + "Btn_tl2" => Some(Key::BTN_TL2), + "Btn_tr2" => Some(Key::BTN_TR2), + "Btn_select" => Some(Key::BTN_SELECT), + "Btn_start" => Some(Key::BTN_START), + "Btn_mode" => Some(Key::BTN_MODE), + "Btn_thumbl" => Some(Key::BTN_THUMBL), + "Btn_thumbr" => Some(Key::BTN_THUMBR), + "Btn_tool_pen" => Some(Key::BTN_TOOL_PEN), + "Btn_tool_rubber" => Some(Key::BTN_TOOL_RUBBER), + "Btn_tool_brush" => Some(Key::BTN_TOOL_BRUSH), + "Btn_tool_pencil" => Some(Key::BTN_TOOL_PENCIL), + "Btn_tool_airbrush" => Some(Key::BTN_TOOL_AIRBRUSH), + "Btn_tool_finger" => Some(Key::BTN_TOOL_FINGER), + "Btn_tool_mouse" => Some(Key::BTN_TOOL_MOUSE), + "Btn_tool_lens" => Some(Key::BTN_TOOL_LENS), + "Btn_tool_quinttap" => Some(Key::BTN_TOOL_QUINTTAP), + "Btn_touch" => Some(Key::BTN_TOUCH), + "Btn_stylus" => Some(Key::BTN_STYLUS), + "Btn_stylus2" => Some(Key::BTN_STYLUS2), + "Btn_tool_doubletap" => Some(Key::BTN_TOOL_DOUBLETAP), + "Btn_tool_tripletap" => Some(Key::BTN_TOOL_TRIPLETAP), + "Btn_tool_quadtap" => Some(Key::BTN_TOOL_QUADTAP), + "Btn_gear_down" => Some(Key::BTN_GEAR_DOWN), + "Btn_gear_up" => Some(Key::BTN_GEAR_UP), + "Btn_dpad_up" => Some(Key::BTN_DPAD_UP), + "Btn_dpad_down" => Some(Key::BTN_DPAD_DOWN), + "Btn_dpad_left" => Some(Key::BTN_DPAD_LEFT), + "Btn_dpad_right" => Some(Key::BTN_DPAD_RIGHT), + "Btn_trigger_happy1" => Some(Key::BTN_TRIGGER_HAPPY1), + "Btn_trigger_happy2" => Some(Key::BTN_TRIGGER_HAPPY2), + "Btn_trigger_happy3" => Some(Key::BTN_TRIGGER_HAPPY3), + "Btn_trigger_happy4" => Some(Key::BTN_TRIGGER_HAPPY4), + "Btn_trigger_happy5" => Some(Key::BTN_TRIGGER_HAPPY5), + "Btn_trigger_happy6" => Some(Key::BTN_TRIGGER_HAPPY6), + "Btn_trigger_happy7" => Some(Key::BTN_TRIGGER_HAPPY7), + "Btn_trigger_happy8" => Some(Key::BTN_TRIGGER_HAPPY8), + "Btn_trigger_happy9" => Some(Key::BTN_TRIGGER_HAPPY9), + "Btn_trigger_happy10" => Some(Key::BTN_TRIGGER_HAPPY10), + "Btn_trigger_happy11" => Some(Key::BTN_TRIGGER_HAPPY11), + "Btn_trigger_happy12" => Some(Key::BTN_TRIGGER_HAPPY12), + "Btn_trigger_happy13" => Some(Key::BTN_TRIGGER_HAPPY13), + "Btn_trigger_happy14" => Some(Key::BTN_TRIGGER_HAPPY14), + "Btn_trigger_happy15" => Some(Key::BTN_TRIGGER_HAPPY15), + "Btn_trigger_happy16" => Some(Key::BTN_TRIGGER_HAPPY16), + "Btn_trigger_happy17" => Some(Key::BTN_TRIGGER_HAPPY17), + "Btn_trigger_happy18" => Some(Key::BTN_TRIGGER_HAPPY18), + "Btn_trigger_happy19" => Some(Key::BTN_TRIGGER_HAPPY19), + "Btn_trigger_happy20" => Some(Key::BTN_TRIGGER_HAPPY20), + "Btn_trigger_happy21" => Some(Key::BTN_TRIGGER_HAPPY21), + "Btn_trigger_happy22" => Some(Key::BTN_TRIGGER_HAPPY22), + "Btn_trigger_happy23" => Some(Key::BTN_TRIGGER_HAPPY23), + "Btn_trigger_happy24" => Some(Key::BTN_TRIGGER_HAPPY24), + "Btn_trigger_happy25" => Some(Key::BTN_TRIGGER_HAPPY25), + "Btn_trigger_happy26" => Some(Key::BTN_TRIGGER_HAPPY26), + "Btn_trigger_happy27" => Some(Key::BTN_TRIGGER_HAPPY27), + "Btn_trigger_happy28" => Some(Key::BTN_TRIGGER_HAPPY28), + "Btn_trigger_happy29" => Some(Key::BTN_TRIGGER_HAPPY29), + "Btn_trigger_happy30" => Some(Key::BTN_TRIGGER_HAPPY30), + "Btn_trigger_happy31" => Some(Key::BTN_TRIGGER_HAPPY31), + "Btn_trigger_happy32" => Some(Key::BTN_TRIGGER_HAPPY32), + "Btn_trigger_happy33" => Some(Key::BTN_TRIGGER_HAPPY33), + "Btn_trigger_happy34" => Some(Key::BTN_TRIGGER_HAPPY34), + "Btn_trigger_happy35" => Some(Key::BTN_TRIGGER_HAPPY35), + "Btn_trigger_happy36" => Some(Key::BTN_TRIGGER_HAPPY36), + "Btn_trigger_happy37" => Some(Key::BTN_TRIGGER_HAPPY37), + "Btn_trigger_happy38" => Some(Key::BTN_TRIGGER_HAPPY38), + "Btn_trigger_happy39" => Some(Key::BTN_TRIGGER_HAPPY39), + "Btn_trigger_happy40" => Some(Key::BTN_TRIGGER_HAPPY40), _ => None, } } diff --git a/lefthk-core/src/worker/mod.rs b/lefthk-core/src/worker/mod.rs index e91546e..98bfc17 100644 --- a/lefthk-core/src/worker/mod.rs +++ b/lefthk-core/src/worker/mod.rs @@ -8,8 +8,7 @@ use crate::errors::{self, LeftError}; use crate::evdev::{EvDev, Task}; use crate::ipc::Pipe; use crate::keysym_lookup::{self, is_modifier, MOD_MASK}; -use evdev_rs::enums::{EventCode, EV_KEY}; -use evdev_rs::InputEvent; +use evdev::{EventType, InputEvent, InputEventKind, Key}; use xdg::BaseDirectories; #[derive(Clone, Copy, Debug)] @@ -42,9 +41,9 @@ pub struct Worker { keybinds: Vec, base_directory: BaseDirectories, - keys_pressed: Vec, + keys_pressed: Vec, mods_pressed: Vec, - eaten_keys: Vec, + eaten_keys: Vec, eaten_mods: Vec, pub evdev: EvDev, @@ -85,7 +84,7 @@ impl Worker { Some(task) = self.evdev.task_receiver.recv() => { match task { Task::KeyboardEvent((path, event)) => { - self.handle_event(path, &event); + self.handle_event(path, event); } Task::KeyboardAdded(path) => { self.evdev.add_device(path); @@ -110,12 +109,12 @@ impl Worker { errors::exit!(Pipe::new(pipe_file).await) } - fn handle_event(&mut self, path: PathBuf, event: &InputEvent) { - let r#type = KeyEventType::from(event.value); + fn handle_event(&mut self, path: PathBuf, event: InputEvent) { + let r#type = KeyEventType::from(event.value()); let mut eaten = false; match r#type { KeyEventType::Release => { - if let EventCode::EV_KEY(key) = event.event_code { + if let InputEventKind::Key(key) = event.kind() { if is_modifier(&key) { if let Ok(modifier) = key.try_into() { self.mods_pressed.retain(|&m| m != modifier); @@ -135,7 +134,7 @@ impl Worker { } KeyEventType::Press => { let mut new_key = false; - if let EventCode::EV_KEY(key) = event.event_code { + if let InputEventKind::Key(key) = event.kind() { if is_modifier(&key) { match key.try_into() { Ok(modifier) if !self.mods_pressed.contains(&modifier) => { @@ -173,12 +172,31 @@ impl Worker { } } - fn pass_event(&self, path: PathBuf, event: &InputEvent) { - // println!("Passing event: {:?}", event); - match self.evdev.devices.get(&path) { - Some(device) => errors::log!(device.write_event(event)), - None => errors::log!(Err(LeftError::UInputNotFound)), + fn pass_event(&mut self, _path: PathBuf, event: InputEvent) { + match self.evdev.device.emit(&[event]) { + Ok(_) => { + tracing::debug!("Successfully sent event: {:?}", event); + } + Err(err) => { + tracing::warn!("Failed to pass event: {:?}", err); + } } + let code = Key::KEY_K.code(); + let down_event = InputEvent::new(EventType::KEY, code, 1); + self.evdev.device.emit(&[down_event]).unwrap(); + println!("Pressed."); + // sleep(Duration::from_secs(2)); + + // alternativeley we can create a InputEvent, which will be any variant of InputEvent + // depending on the type_ value + let up_event = InputEvent::new(EventType::KEY, code, 0); + self.evdev.device.emit(&[up_event]).unwrap(); + println!("Released."); + // sleep(Duration::from_secs(2)); + // match self.evdev.devices.get(&path) { + // Some(device) => errors::log!(device.write_event(event)), + // None => errors::log!(Err(LeftError::UInputNotFound)), + // } } fn check_for_keybind(&self) -> Option {