diff --git a/packages/tools/virtualisation/evdev-proxy/add-evdev-selector.patch b/packages/tools/virtualisation/evdev-proxy/add-evdev-selector.patch new file mode 100644 index 0000000..58913a1 --- /dev/null +++ b/packages/tools/virtualisation/evdev-proxy/add-evdev-selector.patch @@ -0,0 +1,101 @@ +diff --git a/config.toml b/config.toml +index ba11ce4..3021e89 100644 +--- a/config.toml ++++ b/config.toml +@@ -27,6 +27,8 @@ log_level = "INFO" + # on it's usb vendor:model identificator and device + # class (Mouse/Keyboard), useful for wireless devices + # with single receiver (e.g. Logitech Unifying Receiver) ++# * EVDEVClass -- Simple selector based on the PHYS udev attribute. Mainly ++# useful for use with key-mapper + # + # Example devices: + #[[device]] +diff --git a/src/config.rs b/src/config.rs +index 06ae8f5..10d7721 100644 +--- a/src/config.rs ++++ b/src/config.rs +@@ -35,6 +35,9 @@ pub enum DeviceSelector { + model: u16, + class: USBHIDClass, + }, ++ EVDEVClass{ ++ phys: String, ++ }, + } + + pub fn read_config + Debug + ToString>(path: P) -> Result { +diff --git a/src/main.rs b/src/main.rs +index 19055c7..b5c46ec 100644 +--- a/src/main.rs ++++ b/src/main.rs +@@ -21,7 +21,10 @@ fn selector_by_config(s: &config::DeviceSelector) -> Box { + Box::new(udevdetect::USBIDClassFilter::new(*vendor, *model, *class)) +- } ++ }, ++ config::DeviceSelector::EVDEVClass{phys} => { ++ Box::new(udevdetect::EVDEVFilter::new(String::from(phys))) ++ }, + } + } + +diff --git a/src/udevdetect/filter_evdev.rs b/src/udevdetect/filter_evdev.rs +new file mode 100644 +index 0000000..51dc81e +--- /dev/null ++++ b/src/udevdetect/filter_evdev.rs +@@ -0,0 +1,34 @@ ++use udev::{Device, Event}; ++ ++use crate::udevdetect::{DevFilter, get_device_property}; ++ ++#[derive(Debug)] ++pub struct EVDEVFilter { ++ phys: String, ++} ++impl EVDEVFilter { ++ pub fn new(phys: String) -> Self { ++ let f = EVDEVFilter { ++ phys: phys, ++ }; ++ debug!("New EVDEV Filter for: {:?}", f.phys); ++ f ++ } ++} ++impl DevFilter for EVDEVFilter { ++ fn match_event(&self, e: &Event) -> bool { ++ return self.match_device(&e.device()); ++ } ++ ++ fn match_device(&self, e: &Device) -> bool { ++ match e.parent() { ++ Some(parent) => { ++ if get_device_property(&parent, "PHYS") != self.phys { ++ return false ++ } ++ true ++ }, ++ None => false ++ } ++ } ++} +diff --git a/src/udevdetect/mod.rs b/src/udevdetect/mod.rs +index c2009a9..e9ed274 100644 +--- a/src/udevdetect/mod.rs ++++ b/src/udevdetect/mod.rs +@@ -9,11 +9,13 @@ pub use self::filter::DevFilter; + pub use self::filter_usbid::USBIDFilter; + pub use self::filter_usbidclass::USBIDClassFilter; + pub use self::filter_usbidclass::USBHIDClass; ++pub use self::filter_evdev::EVDEVFilter; + + mod listener; + mod filter; + mod filter_usbid; + mod filter_usbidclass; ++mod filter_evdev; + + fn get_event_property<'a>(ev: &'a Event, key: &'a str) -> &'a str { + ev.property_value(key).unwrap_or(OsStr::new("")).to_str().unwrap_or("") diff --git a/packages/tools/virtualisation/evdev-proxy/default.nix b/packages/tools/virtualisation/evdev-proxy/default.nix new file mode 100644 index 0000000..6b05fa7 --- /dev/null +++ b/packages/tools/virtualisation/evdev-proxy/default.nix @@ -0,0 +1,34 @@ +{ lib, rustPlatform, + pkgconfig, udev }: + +rustPlatform.buildRustPackage { + pname = "evdev-proxy"; + version = "0.1.1"; + + src = builtins.fetchGit { + url = "https://github.com/redrampage/evdev-proxy.git"; + ref = "a21092a7b52144c3bb2b630704c990cee24cb745"; + }; + + cargoSha256 = "18y3pjkiwqpwkwrn5dbkn4rdj86c96h6i2b9ih73jajlw1xli1qy"; + + patches = [ ./add-evdev-selector.patch ]; + + nativeBuildInputs = [ pkgconfig ]; + + buildInputs = [ udev ]; + + postInstall = '' + # Install udev rules + mkdir -p $out/lib/udev/rules.d/ + cp 70-uinput-evdev-proxy.rules $out/lib/udev/rules.d/70-uinput-evdev-proxy.rules + ''; + + meta = with lib; { + description = "Creates virtual device to proxy evdev devices events"; + homepage = "https://github.com/redrampage/evdev-proxy"; + license = licenses.gpl3; + maintainers = []; + platforms = platforms.linux; + }; +}