Add configurable support for filtering automatically grabbed keyboards on linux
This commit is contained in:
parent
82421be440
commit
1eb82d21b3
122
Cargo.lock
generated
122
Cargo.lock
generated
@ -1,24 +1,33 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.2.1"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.71"
|
||||
version = "1.2.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79c2681d6594606957bbb8631c4b90a7fcaaa72cdb714743a437b156d6a7eedd"
|
||||
checksum = "755717a7de9ec452bf7f3f1a3099085deabd7f2962b861dae91ecd7a365903d2"
|
||||
dependencies = [
|
||||
"shlex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
@ -28,9 +37,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.1"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a89e2ae426ea83155dccf10c0fa6b1463ef6d5fcb44cee0b224a408fa640a62"
|
||||
checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
@ -38,17 +47,17 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.2"
|
||||
version = "0.8.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b"
|
||||
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
||||
|
||||
[[package]]
|
||||
name = "core-graphics"
|
||||
version = "0.22.2"
|
||||
version = "0.22.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "269f35f69b542b80e736a20a89a05215c0ce80c2c03c514abb2e318b78379d86"
|
||||
checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"core-foundation",
|
||||
"core-graphics-types",
|
||||
"foreign-types",
|
||||
@ -57,23 +66,22 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "core-graphics-types"
|
||||
version = "0.1.1"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b"
|
||||
checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"core-foundation",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "epoll"
|
||||
version = "4.3.1"
|
||||
version = "4.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "20df693c700404f7e19d4d6fae6b15215d2913c27955d2b9d6f2c0f537511cd0"
|
||||
checksum = "74351c3392ea1ff6cd2628e0042d268ac2371cb613252ff383b6dfa50d22fa79"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 2.8.0",
|
||||
"libc",
|
||||
]
|
||||
|
||||
@ -103,11 +111,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "inotify"
|
||||
version = "0.9.5"
|
||||
version = "0.9.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e5fc8f41dbaa9c8492a96c8afffda4f76896ee041d6a57606e70581b80c901f"
|
||||
checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"inotify-sys",
|
||||
"libc",
|
||||
]
|
||||
@ -123,32 +131,32 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.103"
|
||||
version = "0.2.169"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6"
|
||||
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.6.4"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9"
|
||||
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.22.2"
|
||||
version = "0.22.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3bb9a13fa32bc5aeb64150cd3f32d6cf4c748f8f8a417cce5d2eb976a8370ba"
|
||||
checksum = "e4916f159ed8e5de0082076562152a76b7a1f64a01fd9d1e0fea002c37624faf"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
@ -157,18 +165,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.29"
|
||||
version = "1.0.93"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d"
|
||||
checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.10"
|
||||
version = "1.0.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05"
|
||||
checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
@ -192,18 +200,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.130"
|
||||
version = "1.0.217"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913"
|
||||
checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.130"
|
||||
version = "1.0.217"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b"
|
||||
checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -211,36 +219,42 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.80"
|
||||
name = "shlex"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d010a1623fbd906d51d650a9916aaefc05ffa0e4053ff7fe601167f3e715d194"
|
||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.98"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.5.8"
|
||||
version = "0.5.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa"
|
||||
checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.9"
|
||||
name = "unicode-ident"
|
||||
version = "1.0.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
|
||||
checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.2"
|
||||
name = "unicode-width"
|
||||
version = "0.1.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
|
21
keymap.toml
21
keymap.toml
@ -45,3 +45,24 @@ keymaps = [
|
||||
LCTL, LGUI, LALT, SPC, RALT, RGUI, APP, RCTL, LEFT,DOWN,RGHT, *P0:*BSLS, *PDOT:*SCLN, PENT
|
||||
""",
|
||||
]
|
||||
|
||||
# these are optional configs to support automatically grabbing only specific devices, or skipping specific devices
|
||||
# the logic is that empty grab means everything, and empty skip means skip nothing, but otherise any grab has to match and no skip can match, or the device is skipped, a log message is printed when a new device is grabbed or skipped
|
||||
# on linux you can get vendor/product with `lsusb`, but they are hex, so preceed with 0x
|
||||
|
||||
# the default is to skip vendor 0x1050 which is Yubico, if you modify these, you may want to include this too
|
||||
# [[devices.skip]]
|
||||
# vendor = 0x1050
|
||||
|
||||
# example that will grab only this
|
||||
# [[devices.grab]]
|
||||
# vendor = 0x5a69
|
||||
# product = 0xe200
|
||||
# bustype = 1
|
||||
# version = 1
|
||||
|
||||
# ergosnm, a custom QMK board
|
||||
# [[devices.skip]]
|
||||
# vendor = 0x5a69
|
||||
# product = 0xe200
|
||||
|
||||
|
135
src/keymapper.rs
135
src/keymapper.rs
@ -111,6 +111,7 @@ where
|
||||
key_state: [bool; KEY_MAX],
|
||||
revert_default_keys: Vec<T>,
|
||||
revert_keymap_index: usize,
|
||||
pub devices: DeviceMatchers,
|
||||
// above do not change, below does
|
||||
chosen_keymap_index: usize,
|
||||
current_keymap_index: usize,
|
||||
@ -281,6 +282,7 @@ where
|
||||
revert_keymap_index: config.revert_keymap_index,
|
||||
chosen_keymap_index: config.default_keymap_index,
|
||||
current_keymap_index: config.default_keymap_index,
|
||||
devices: config.devices,
|
||||
}
|
||||
}
|
||||
//}
|
||||
@ -490,8 +492,78 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub trait DeviceIds {
|
||||
fn bustype(&self) -> Option<u16>;
|
||||
fn vendor(&self) -> Option<u16>;
|
||||
fn product(&self) -> Option<u16>;
|
||||
fn version(&self) -> Option<u16>;
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
#[cfg_attr(feature = "toml_serde", derive(serde::Deserialize))]
|
||||
#[cfg_attr(feature = "toml_serde", serde(deny_unknown_fields))]
|
||||
pub struct DeviceMatcher {
|
||||
pub bustype: Option<u16>,
|
||||
pub vendor: Option<u16>,
|
||||
pub product: Option<u16>,
|
||||
pub version: Option<u16>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "toml_serde", derive(serde::Deserialize))]
|
||||
#[cfg_attr(feature = "toml_serde", serde(deny_unknown_fields))]
|
||||
pub struct DeviceMatchers {
|
||||
#[cfg_attr(feature = "toml_serde", serde(default))]
|
||||
grab: Vec<DeviceMatcher>,
|
||||
#[cfg_attr(feature = "toml_serde", serde(default = "default_skip"))]
|
||||
skip: Vec<DeviceMatcher>,
|
||||
}
|
||||
|
||||
impl Default for DeviceMatchers {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
grab: Default::default(),
|
||||
skip: default_skip(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn default_skip() -> Vec<DeviceMatcher> {
|
||||
vec![
|
||||
// 0x1050 is Yubico
|
||||
DeviceMatcher {
|
||||
vendor: Some(0x1050),
|
||||
..Default::default()
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn um(rule: Option<u16>, data: Option<u16>) -> bool {
|
||||
rule.is_none() || rule == data
|
||||
}
|
||||
|
||||
impl DeviceMatcher {
|
||||
pub fn matches(&self, device: &dyn DeviceIds) -> bool {
|
||||
um(self.bustype, device.bustype())
|
||||
&& um(self.vendor, device.vendor())
|
||||
&& um(self.product, device.product())
|
||||
&& um(self.version, device.version())
|
||||
}
|
||||
}
|
||||
|
||||
impl DeviceMatchers {
|
||||
pub fn grab(&self, device: &dyn DeviceIds) -> bool {
|
||||
// we should grab this device if grab is empty or any single entry matches
|
||||
(self.grab.is_empty() || self.grab.iter().any(|d| d.matches(device)))
|
||||
// and skip is empty or no skip entry matches
|
||||
&& (self.skip.is_empty() || !self.skip.iter().any(|d| d.matches(device)))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "toml_serde")]
|
||||
#[derive(serde::Deserialize, Debug)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct KeymapConfig {
|
||||
switch_layout_keys: Vec<String>,
|
||||
revert_default_key: Option<String>,
|
||||
@ -499,6 +571,8 @@ pub struct KeymapConfig {
|
||||
revert_keymap_index: usize,
|
||||
default_keymap_index: usize,
|
||||
keymaps: Vec<String>,
|
||||
#[serde(default)]
|
||||
devices: DeviceMatchers,
|
||||
}
|
||||
|
||||
#[cfg(feature = "toml_serde")]
|
||||
@ -519,6 +593,7 @@ pub struct KeymapConfig {
|
||||
revert_keymap_index: usize,
|
||||
default_keymap_index: usize,
|
||||
keymaps: Vec<&'static str>,
|
||||
devices: DeviceMatchers,
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "toml_serde"))]
|
||||
@ -570,6 +645,66 @@ impl Default for KeymapConfig {
|
||||
"###,
|
||||
],
|
||||
revert_default_key: None, // use revert_default_keys instead
|
||||
devices: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use libc::input_id;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_device_matchers() {
|
||||
// test default
|
||||
let devices: DeviceMatchers = toml::from_str("").unwrap();
|
||||
assert!(devices.grab.is_empty());
|
||||
assert_eq!(devices.skip.len(), 1);
|
||||
let yubi = input_id {
|
||||
vendor: 0x1050,
|
||||
product: 0x0406,
|
||||
bustype: 0,
|
||||
version: 0,
|
||||
};
|
||||
let yubi2 = input_id {
|
||||
vendor: 0x1050,
|
||||
product: 0x0407,
|
||||
bustype: 0,
|
||||
version: 0,
|
||||
};
|
||||
let ergosnm = input_id {
|
||||
vendor: 0x5a69,
|
||||
product: 0xe200,
|
||||
bustype: 0,
|
||||
version: 0,
|
||||
};
|
||||
let rando = input_id {
|
||||
vendor: 1,
|
||||
product: 2,
|
||||
bustype: 3,
|
||||
version: 4,
|
||||
};
|
||||
assert!(!devices.grab(&yubi));
|
||||
assert!(!devices.grab(&yubi2));
|
||||
assert!(devices.grab(&ergosnm));
|
||||
assert!(devices.grab(&rando));
|
||||
let devices: DeviceMatchers = toml::from_str(
|
||||
r###"
|
||||
# yubikey
|
||||
[[skip]]
|
||||
vendor = 0x1050
|
||||
# ergosnm
|
||||
[[skip]]
|
||||
vendor = 0x5a69
|
||||
product = 0xe200
|
||||
"###,
|
||||
)
|
||||
.unwrap();
|
||||
assert!(!devices.grab(&yubi));
|
||||
assert!(!devices.grab(&yubi2));
|
||||
assert!(!devices.grab(&ergosnm));
|
||||
assert!(devices.grab(&rando));
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use libc::{c_int, input_event};
|
||||
use nix::{ioctl_read_buf, ioctl_write_ptr};
|
||||
use libc::{c_int, input_event, input_id};
|
||||
use nix::{ioctl_read, ioctl_read_buf, ioctl_write_ptr};
|
||||
use std::{fs::File, io::Read, mem, os::unix::io::AsRawFd};
|
||||
|
||||
#[cfg(feature = "epoll_inotify")]
|
||||
@ -7,13 +7,14 @@ use std::os::unix::prelude::RawFd;
|
||||
|
||||
use crate::{
|
||||
linux::{BTN_LEFT, EV_KEY, KEY_A, KEY_D, KEY_MAX, KEY_S, KEY_W, NAME},
|
||||
Error, Result,
|
||||
DeviceIds, DeviceMatchers, Error, Result,
|
||||
};
|
||||
|
||||
ioctl_write_ptr!(eviocgrab, b'E', 0x90, c_int);
|
||||
ioctl_read_buf!(eviocgname, b'E', 0x06, u8);
|
||||
ioctl_read_buf!(eviocgbit, b'E', 0x20, u8);
|
||||
ioctl_read_buf!(eviocgbit_ev_key, b'E', 0x20 + EV_KEY, u8);
|
||||
ioctl_read!(eviocgid, b'E', 0x02, input_id);
|
||||
|
||||
const SIZE_OF_INPUT_EVENT: usize = mem::size_of::<input_event>();
|
||||
|
||||
@ -47,7 +48,7 @@ impl InputDevice {
|
||||
Ok(event)
|
||||
}
|
||||
|
||||
pub fn valid_keyboard_device(self) -> Result<Self> {
|
||||
pub fn valid_keyboard_device(self, devices: &DeviceMatchers) -> Result<Self> {
|
||||
use std::os::unix::fs::FileTypeExt;
|
||||
|
||||
// must be a character device
|
||||
@ -85,11 +86,28 @@ impl InputDevice {
|
||||
// is it another running copy of rusty-keys ?
|
||||
let mut name = [0u8; NAME.len()];
|
||||
unsafe { eviocgname(raw_fd, &mut name)? };
|
||||
// exclude anything starting with "Yubico" also
|
||||
if NAME.as_bytes() == &name || "Yubico".as_bytes() == &name[0..6] {
|
||||
if NAME.as_bytes() == &name {
|
||||
return Err(Error::NotAKeyboard);
|
||||
}
|
||||
return Ok(self);
|
||||
|
||||
let mut id = input_id {
|
||||
bustype: 0,
|
||||
vendor: 0,
|
||||
product: 0,
|
||||
version: 0,
|
||||
};
|
||||
unsafe { eviocgid(raw_fd, &mut id)? };
|
||||
print!(
|
||||
"vendor: 0x{:x} product: 0x{:x}, bustype: 0x{:x}, version: 0x{:x}: ",
|
||||
id.vendor, id.product, id.bustype, id.version
|
||||
);
|
||||
if devices.grab(&id) {
|
||||
println!("skipped");
|
||||
Err(Error::NotAKeyboard)
|
||||
} else {
|
||||
println!("grabbed");
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn grab(mut self) -> Result<Self> {
|
||||
@ -160,3 +178,21 @@ impl Drop for InputDevice {
|
||||
self.epoll_del().ok();
|
||||
}
|
||||
}
|
||||
|
||||
impl DeviceIds for input_id {
|
||||
fn bustype(&self) -> Option<u16> {
|
||||
Some(self.bustype)
|
||||
}
|
||||
|
||||
fn vendor(&self) -> Option<u16> {
|
||||
Some(self.vendor)
|
||||
}
|
||||
|
||||
fn product(&self) -> Option<u16> {
|
||||
Some(self.product)
|
||||
}
|
||||
|
||||
fn version(&self) -> Option<u16> {
|
||||
Some(self.version)
|
||||
}
|
||||
}
|
||||
|
@ -159,7 +159,7 @@ pub fn main_res() -> Result<()> {
|
||||
// there is a slight race condition here, if a keyboard is plugged in between the time we
|
||||
// enumerate the devices and set up the inotify watch, we'll miss it, doing it the other way
|
||||
// can bring duplicates though, todo: think about this...
|
||||
let device_files = get_keyboard_devices();
|
||||
let device_files = get_keyboard_devices(&key_map.devices);
|
||||
let mut inotify = Inotify::init()?;
|
||||
inotify.add_watch(INPUT_FOLDER, WatchMask::CREATE)?;
|
||||
let epoll_event = epoll::Event::new(
|
||||
@ -226,7 +226,7 @@ pub fn main_res() -> Result<()> {
|
||||
path.push(device_file);
|
||||
|
||||
if let Ok(input_device) = InputDevice::open(path)
|
||||
.and_then(|id| id.valid_keyboard_device())
|
||||
.and_then(|id| id.valid_keyboard_device(&key_map.devices))
|
||||
{
|
||||
println!(
|
||||
"starting mapping for new keyboard: {}",
|
||||
@ -313,13 +313,13 @@ fn parse_args() -> Config {
|
||||
}
|
||||
|
||||
#[cfg(feature = "epoll_inotify")]
|
||||
fn get_keyboard_devices() -> Vec<InputDevice> {
|
||||
fn get_keyboard_devices(devices: &crate::DeviceMatchers) -> Vec<InputDevice> {
|
||||
let mut res = Vec::new();
|
||||
if let Ok(entries) = std::fs::read_dir(INPUT_FOLDER) {
|
||||
for entry in entries {
|
||||
if let Ok(entry) = entry {
|
||||
if let Ok(input_device) =
|
||||
InputDevice::open(entry.path()).and_then(|id| id.valid_keyboard_device())
|
||||
InputDevice::open(entry.path()).and_then(|id| id.valid_keyboard_device(devices))
|
||||
{
|
||||
res.push(input_device);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user