diff --git a/src/config/mod.rs b/src/config/mod.rs index b10c96c7..e48985b5 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -14,7 +14,10 @@ use thiserror::Error; use crate::{ dmi::data::DMIData, - input::event::{native::NativeEvent, value::InputValue}, + input::{ + event::{native::NativeEvent, value::InputValue}, + info::DeviceInfo, + }, udev::device::UdevDevice, }; @@ -397,54 +400,63 @@ impl CompositeDeviceConfig { .collect() } - /// Returns a [SourceDevice] if it matches the given [UdevDevice]. Will return + /// Returns a [SourceDevice] if it matches the given [DeviceInfo]. Will return /// the first [SourceDevice] match found if multiple matches exist. - pub fn get_matching_device(&self, udevice: &UdevDevice) -> Option { + pub fn get_matching_device(&self, device: &DeviceInfo) -> Option { for config in self.source_devices.iter() { - // Check udev matches first - if let Some(udev_config) = config.udev.as_ref() { - if self.has_matching_udev(udevice, udev_config) { - return Some(config.clone()); - } + let matched_config = match device { + DeviceInfo::Udev(udevice) => self.get_matching_udev_device(config, udevice), + }; + if matched_config.is_some() { + return matched_config; } + } - // Use subsystem-specific device matching - let subsystem = udevice.subsystem(); - match subsystem.as_str() { - "input" => { - let Some(evdev_config) = config.evdev.as_ref() else { - continue; - }; - if self.has_matching_evdev(udevice, evdev_config) { - return Some(config.clone()); - } + None + } + + /// Returns a copy of the given [SourceDevice] config if it matches the given + /// [UdevDevice]. + fn get_matching_udev_device( + &self, + config: &SourceDevice, + udevice: &UdevDevice, + ) -> Option { + // Check udev matches first + if let Some(udev_config) = config.udev.as_ref() { + if self.has_matching_udev(udevice, udev_config) { + return Some(config.clone()); + } + } + + // Use subsystem-specific device matching + let subsystem = udevice.subsystem(); + match subsystem.as_str() { + "input" => { + let evdev_config = config.evdev.as_ref()?; + if self.has_matching_evdev(udevice, evdev_config) { + return Some(config.clone()); } - "hidraw" => { - let Some(hidraw_config) = config.hidraw.as_ref() else { - continue; - }; - if self.has_matching_hidraw(udevice, hidraw_config) { - return Some(config.clone()); - } + } + "hidraw" => { + let hidraw_config = config.hidraw.as_ref()?; + if self.has_matching_hidraw(udevice, hidraw_config) { + return Some(config.clone()); } - "iio" => { - let Some(iio_config) = config.iio.as_ref() else { - continue; - }; - if self.has_matching_iio(udevice, iio_config) { - return Some(config.clone()); - } + } + "iio" => { + let iio_config = config.iio.as_ref()?; + if self.has_matching_iio(udevice, iio_config) { + return Some(config.clone()); } - "leds" => { - let Some(led_config) = config.led.as_ref() else { - continue; - }; - if self.has_matching_led(udevice, led_config) { - return Some(config.clone()); - } + } + "leds" => { + let led_config = config.led.as_ref()?; + if self.has_matching_led(udevice, led_config) { + return Some(config.clone()); } - _ => (), } + _ => (), } None diff --git a/src/input/composite_device/client.rs b/src/input/composite_device/client.rs index d2773a4a..18fda153 100644 --- a/src/input/composite_device/client.rs +++ b/src/input/composite_device/client.rs @@ -4,10 +4,10 @@ use tokio::sync::mpsc::{channel, error::SendError, Sender}; use crate::config::CompositeDeviceConfig; use crate::input::event::native::NativeEvent; +use crate::input::info::DeviceInfo; use crate::input::target::client::TargetDeviceClient; use crate::input::target::TargetDeviceTypeId; use crate::input::{capability::Capability, event::Event, output_event::OutputEvent}; -use crate::udev::device::UdevDevice; use super::{CompositeCommand, InterceptMode}; @@ -208,7 +208,7 @@ impl CompositeDeviceClient { } /// Add the given source device to the composite device - pub async fn add_source_device(&self, device: UdevDevice) -> Result<(), ClientError> { + pub async fn add_source_device(&self, device: DeviceInfo) -> Result<(), ClientError> { self.tx .send(CompositeCommand::SourceDeviceAdded(device)) .await?; @@ -216,7 +216,7 @@ impl CompositeDeviceClient { } /// Remove the given source device from the composite device - pub async fn remove_source_device(&self, device: UdevDevice) -> Result<(), ClientError> { + pub async fn remove_source_device(&self, device: DeviceInfo) -> Result<(), ClientError> { self.tx .send(CompositeCommand::SourceDeviceRemoved(device)) .await?; diff --git a/src/input/composite_device/command.rs b/src/input/composite_device/command.rs index bf02db3b..8bcd3f3c 100644 --- a/src/input/composite_device/command.rs +++ b/src/input/composite_device/command.rs @@ -7,10 +7,10 @@ use crate::{ input::{ capability::Capability, event::{native::NativeEvent, Event}, + info::DeviceInfo, output_event::OutputEvent, target::{client::TargetDeviceClient, TargetDeviceTypeId}, }, - udev::device::UdevDevice, }; use super::InterceptMode; @@ -40,9 +40,9 @@ pub enum CompositeCommand { SetInterceptActivation(Vec, Capability), SetInterceptMode(InterceptMode), SetTargetDevices(Vec), - SourceDeviceAdded(UdevDevice), - SourceDeviceRemoved(UdevDevice), - SourceDeviceStopped(UdevDevice), + SourceDeviceAdded(DeviceInfo), + SourceDeviceRemoved(DeviceInfo), + SourceDeviceStopped(DeviceInfo), #[allow(dead_code)] UpdateSourceCapabilities(String, HashSet), UpdateTargetCapabilities(String, HashSet), diff --git a/src/input/composite_device/mod.rs b/src/input/composite_device/mod.rs index c8368a3b..d86cf419 100644 --- a/src/input/composite_device/mod.rs +++ b/src/input/composite_device/mod.rs @@ -41,14 +41,14 @@ use crate::{ }, target::TargetDeviceTypeId, }, - udev::{device::UdevDevice, hide_device, unhide_device}, + udev::{hide_device, unhide_device}, }; use self::{client::CompositeDeviceClient, command::CompositeCommand}; use super::{ - manager::ManagerCommand, output_event::OutputEvent, source::client::SourceDeviceClient, - target::client::TargetDeviceClient, + info::DeviceInfo, manager::ManagerCommand, output_event::OutputEvent, + source::client::SourceDeviceClient, target::client::TargetDeviceClient, }; /// Size of the command channel buffer for processing input events and commands. @@ -161,7 +161,7 @@ impl CompositeDevice { conn: Connection, manager: mpsc::Sender, config: CompositeDeviceConfig, - device_info: UdevDevice, + device_info: DeviceInfo, dbus_path: String, capability_map: Option, ) -> Result> { @@ -369,13 +369,13 @@ impl CompositeDevice { } } CompositeCommand::SourceDeviceStopped(device) => { - log::debug!("Detected source device stopped: {}", device.devnode()); + log::debug!("Detected source device stopped: {}", device.path()); if let Err(e) = self.on_source_device_removed(device).await { log::error!("Failed to remove source device: {:?}", e); } } CompositeCommand::SourceDeviceRemoved(device) => { - log::debug!("Detected source device removed: {}", device.devnode()); + log::debug!("Detected source device removed: {}", device.path()); devices_removed = true; if let Err(e) = self.on_source_device_removed(device).await { log::error!("Failed to remove source device: {:?}", e); @@ -608,6 +608,7 @@ impl CompositeDevice { let sources = self.source_devices_discovered.drain(..); for source_device in sources { let device_id = source_device.get_id(); + log::debug!("Starting source device: {device_id}"); // If the source device is blocked, don't bother running it if self.source_devices_blocked.contains(&device_id) { log::debug!("Source device '{device_id}' blocked. Skipping running."); @@ -620,9 +621,10 @@ impl CompositeDevice { // Add the IIO IMU Dbus interface. We do this here because it needs the source // device transmitter and this is the only place we can refrence it at the moment. - let device = source_device.get_device_ref().clone(); + let device = source_device.get_device_ref().to_owned(); if let SourceDevice::Iio(_) = source_device { - SourceIioImuInterface::listen_on_dbus(self.conn.clone(), device.clone()).await?; + let DeviceInfo::Udev(device) = device.clone(); + SourceIioImuInterface::listen_on_dbus(self.conn.clone(), device).await?; } self.source_device_tasks.spawn(async move { @@ -1471,7 +1473,7 @@ impl CompositeDevice { } /// Executed whenever a source device is added to this [CompositeDevice]. - async fn on_source_device_added(&mut self, device: UdevDevice) -> Result<(), Box> { + async fn on_source_device_added(&mut self, device: DeviceInfo) -> Result<(), Box> { if let Err(e) = self.add_source_device(device) { return Err(e.to_string().into()); } @@ -1488,8 +1490,8 @@ impl CompositeDevice { } /// Executed whenever a source device is removed from this [CompositeDevice] - async fn on_source_device_removed(&mut self, device: UdevDevice) -> Result<(), Box> { - let path = device.devnode(); + async fn on_source_device_removed(&mut self, device: DeviceInfo) -> Result<(), Box> { + let path = device.path(); let id = device.get_id(); // Remove any ffb effects this device registered @@ -1541,7 +1543,7 @@ impl CompositeDevice { /// Creates and adds a source device using the given [SourceDeviceInfo] fn add_source_device( &mut self, - device: UdevDevice, + device: DeviceInfo, ) -> Result<(), Box> { // Check to see if this source device should be blocked. let mut is_blocked = false; @@ -1553,49 +1555,56 @@ impl CompositeDevice { } } - let subsystem = device.subsystem(); - - // Hide the device if specified - let should_passthru = source_config - .as_ref() - .and_then(|c| c.passthrough) - .unwrap_or(false); - let should_hide = !should_passthru && subsystem.as_str() != "iio"; - if should_hide { - let source_path = device.devnode(); - self.source_devices_to_hide.push(source_path); - } + log::debug!("Adding source device: {:?}", device.name()); + let source_device = match device { + DeviceInfo::Udev(device) => { + let subsystem = device.subsystem(); + + // Hide the device if specified + let should_passthru = source_config + .as_ref() + .and_then(|c| c.passthrough) + .unwrap_or(false); + let should_hide = !should_passthru && subsystem.as_str() != "iio"; + if should_hide { + let source_path = device.devnode(); + self.source_devices_to_hide.push(source_path); + } - let source_device = match subsystem.as_str() { - "input" => { - log::debug!("Adding EVDEV source device: {:?}", device.name()); - if is_blocked { - is_blocked_evdev = true; + match subsystem.as_str() { + "input" => { + log::debug!("Adding EVDEV source device: {:?}", device.name()); + if is_blocked { + is_blocked_evdev = true; + } + let device = + EventDevice::new(device, self.client(), source_config.clone())?; + SourceDevice::Event(device) + } + "hidraw" => { + log::debug!("Adding HIDRAW source device: {:?}", device.name()); + let device = + HidRawDevice::new(device, self.client(), source_config.clone())?; + SourceDevice::HidRaw(device) + } + "iio" => { + log::debug!("Adding IIO source device: {:?}", device.name()); + let device = IioDevice::new(device, self.client(), source_config.clone())?; + SourceDevice::Iio(device) + } + "leds" => { + log::debug!("Adding LED source device: {:?}", device.sysname()); + let device = LedDevice::new(device, self.client(), source_config.clone())?; + SourceDevice::Led(device) + } + _ => { + return Err(format!( + "Unspported subsystem: {subsystem}, unable to add source device {}", + device.name() + ) + .into()) + } } - let device = EventDevice::new(device, self.client(), source_config.clone())?; - SourceDevice::Event(device) - } - "hidraw" => { - log::debug!("Adding HIDRAW source device: {:?}", device.name()); - let device = HidRawDevice::new(device, self.client(), source_config.clone())?; - SourceDevice::HidRaw(device) - } - "iio" => { - log::debug!("Adding IIO source device: {:?}", device.name()); - let device = IioDevice::new(device, self.client(), source_config.clone())?; - SourceDevice::Iio(device) - } - "leds" => { - log::debug!("Adding LED source device: {:?}", device.sysname()); - let device = LedDevice::new(device, self.client(), source_config.clone())?; - SourceDevice::Led(device) - } - _ => { - return Err(format!( - "Unspported subsystem: {subsystem}, unable to add source device {}", - device.name() - ) - .into()) } }; @@ -1616,7 +1625,7 @@ impl CompositeDevice { let id = source_device.get_id(); if let Some(device_config) = self .config - .get_matching_device(source_device.get_device_ref()) + .get_matching_device(&source_device.get_device_ref().to_owned()) { if let Some(blocked) = device_config.blocked { // Blocked event devices should still be run so they can be diff --git a/src/input/info.rs b/src/input/info.rs new file mode 100644 index 00000000..e9e2c63d --- /dev/null +++ b/src/input/info.rs @@ -0,0 +1,69 @@ +use crate::udev::device::UdevDevice; + +#[derive(Debug, Clone)] +pub enum DeviceInfo { + Udev(UdevDevice), +} + +impl DeviceInfo { + /// Name of the device + pub fn name(&self) -> String { + match self { + DeviceInfo::Udev(device) => device.name(), + } + } + + /// Return a unique identifier for the device based on the subsystem and + /// sysname. E.g. "evdev://event3", "hidraw://hidraw0", "ws://127.0.0.1:8080::192.168.0.3:12345" + pub fn get_id(&self) -> String { + match self { + DeviceInfo::Udev(device) => device.get_id(), + } + } + + /// Path to the device (e.g. /dev/hidraw1, /dev/input/event12, ws://127.0.0.1:12345) + pub fn path(&self) -> String { + match self { + DeviceInfo::Udev(device) => device.devnode(), + } + } + + /// The subsystem of the device if it is udev, or networking type + pub fn kind(&self) -> String { + match self { + DeviceInfo::Udev(device) => device.subsystem(), + } + } +} + +impl From<::udev::Device> for DeviceInfo { + fn from(device: ::udev::Device) -> Self { + Self::Udev(device.into()) + } +} + +impl From for DeviceInfo { + fn from(device: UdevDevice) -> Self { + Self::Udev(device) + } +} + +/// Reference to device information +#[derive(Debug, Clone)] +pub enum DeviceInfoRef<'a> { + Udev(&'a UdevDevice), +} + +impl DeviceInfoRef<'_> { + pub fn to_owned(&self) -> DeviceInfo { + match self { + DeviceInfoRef::Udev(device) => DeviceInfo::Udev(device.to_owned().clone()), + } + } +} + +impl<'a> From<&'a UdevDevice> for DeviceInfoRef<'a> { + fn from(device: &'a UdevDevice) -> Self { + Self::Udev(device) + } +} diff --git a/src/input/manager.rs b/src/input/manager.rs index af8922f1..40605ac4 100644 --- a/src/input/manager.rs +++ b/src/input/manager.rs @@ -47,6 +47,7 @@ use crate::udev::device::AttributeGetter; use crate::udev::device::UdevDevice; use super::composite_device::client::CompositeDeviceClient; +use super::info::DeviceInfo; use super::target::client::TargetDeviceClient; use crate::watcher; @@ -76,10 +77,10 @@ pub enum ManagerError { #[derive(Debug, Clone)] pub enum ManagerCommand { DeviceAdded { - device: UdevDevice, + device: DeviceInfo, }, DeviceRemoved { - device: UdevDevice, + device: DeviceInfo, }, CreateCompositeDevice { config: CompositeDeviceConfig, @@ -383,19 +384,23 @@ impl Manager { log::info!("Gamepad order: {:?}", self.target_gamepad_order); } - ManagerCommand::DeviceAdded { device } => { - let dev_name = device.name(); - let dev_sysname = device.sysname(); + ManagerCommand::DeviceAdded { device } => match device { + DeviceInfo::Udev(device) => { + let dev_name = device.name(); + let dev_sysname = device.sysname(); - if let Err(e) = self.on_device_added(device).await { - log::error!("Error adding device '{dev_name} ({dev_sysname})': {e}"); + if let Err(e) = self.on_udev_device_added(device).await { + log::error!("Error adding device '{dev_name} ({dev_sysname})': {e}"); + } } - } - ManagerCommand::DeviceRemoved { device } => { - if let Err(e) = self.on_device_removed(device).await { - log::error!("Error removing device: {e}"); + }, + ManagerCommand::DeviceRemoved { device } => match device { + DeviceInfo::Udev(device) => { + if let Err(e) = self.on_udev_device_removed(device).await { + log::error!("Error removing device: {e}"); + } } - } + }, ManagerCommand::SetManageAllDevices(manage_all_devices) => { log::debug!("Setting management of all devices to: {manage_all_devices}"); if self.manage_all_devices == manage_all_devices { @@ -530,7 +535,7 @@ impl Manager { async fn create_composite_device_from_config( &mut self, config: &CompositeDeviceConfig, - device: UdevDevice, + device: DeviceInfo, ) -> Result> { // Lookup the capability map associated with this config if it exists let capability_map = if let Some(map_id) = config.capability_map_id.clone() { @@ -939,7 +944,7 @@ impl Manager { async fn on_source_device_added( &mut self, id: String, - device: UdevDevice, + device: DeviceInfo, ) -> Result<(), Box> { // Check all existing composite devices to see if this device is part of // their config @@ -1020,7 +1025,7 @@ impl Manager { } } - log::info!("Found missing {} device, adding source device {id} to existing composite device: {composite_device:?}", device.subsystem()); + log::info!("Found missing {} device, adding source device {id} to existing composite device: {composite_device:?}", device.kind()); let Some(client) = self.composite_devices.get(composite_device.as_str()) else { log::error!("No existing composite device found for key {composite_device:?}"); continue; @@ -1083,7 +1088,7 @@ impl Manager { } log::info!( "Found a matching {} device {id}, creating CompositeDevice", - device.subsystem() + device.kind() ); let dev = self .create_composite_device_from_config(&config, device) @@ -1114,7 +1119,7 @@ impl Manager { /// Called when any source device is removed async fn on_source_device_removed( &mut self, - device: UdevDevice, + device: DeviceInfo, id: String, ) -> Result<(), Box> { let dev_name = device.name(); @@ -1152,7 +1157,7 @@ impl Manager { } /// Called when a new device is detected by udev - async fn on_device_added(&mut self, device: UdevDevice) -> Result<(), Box> { + async fn on_udev_device_added(&mut self, device: UdevDevice) -> Result<(), Box> { let dev_path = device.devpath(); let dev_name = device.name(); let dev_sysname = device.sysname(); @@ -1252,7 +1257,8 @@ impl Manager { // Signal that a source device was added log::debug!("Spawning task to add source device: {id}"); - self.on_source_device_added(id.clone(), device).await?; + self.on_source_device_added(id.clone(), device.into()) + .await?; log::debug!("Finished adding {id}"); } "hidraw" => { @@ -1350,7 +1356,8 @@ impl Manager { // Signal that a source device was added log::debug!("Spawing task to add source device: {id}"); - self.on_source_device_added(id.clone(), device).await?; + self.on_source_device_added(id.clone(), device.into()) + .await?; log::debug!("Finished adding hidraw device {id}"); } @@ -1400,7 +1407,8 @@ impl Manager { // Signal that a source device was added log::debug!("Spawing task to add source device: {id}"); - self.on_source_device_added(id.clone(), device).await?; + self.on_source_device_added(id.clone(), device.into()) + .await?; log::debug!("Finished adding event device {id}"); } @@ -1424,7 +1432,8 @@ impl Manager { // Signal that a source device was added log::debug!("Spawing task to add source device: {id}"); - self.on_source_device_added(id.clone(), device).await?; + self.on_source_device_added(id.clone(), device.into()) + .await?; log::debug!("Finished adding LED device {id}"); } @@ -1436,7 +1445,7 @@ impl Manager { Ok(()) } - async fn on_device_removed(&mut self, device: UdevDevice) -> Result<(), Box> { + async fn on_udev_device_removed(&mut self, device: UdevDevice) -> Result<(), Box> { let dev_name = device.name(); let sys_name = device.sysname(); let subsystem = device.subsystem(); @@ -1494,7 +1503,7 @@ impl Manager { log::debug!("Device ID: {id}"); // Signal that a source device was removed - self.on_source_device_removed(device, id).await?; + self.on_source_device_removed(device.into(), id).await?; Ok(()) } @@ -1668,7 +1677,11 @@ impl Manager { WatchEvent::Delete { name, base_path } => { let device = UdevDevice::from_devnode(base_path.as_str(), name.as_str()); log::debug!("Got inotify remove action for {base_path}/{name}"); - let result = cmd_tx.send(ManagerCommand::DeviceRemoved { device }).await; + let result = cmd_tx + .send(ManagerCommand::DeviceRemoved { + device: device.into(), + }) + .await; if let Err(e) = result { log::error!("Unable to send command: {:?}", e); } @@ -1707,7 +1720,9 @@ impl Manager { ) -> Result<(), Box> { for device in devices { manager_tx - .send(ManagerCommand::DeviceAdded { device }) + .send(ManagerCommand::DeviceAdded { + device: device.into(), + }) .await?; } @@ -1770,7 +1785,7 @@ impl Manager { async fn add_device_to_composite_device( &self, - device: UdevDevice, + device: DeviceInfo, client: &CompositeDeviceClient, ) -> Result<(), Box> { client.add_source_device(device).await?; diff --git a/src/input/mod.rs b/src/input/mod.rs index b2e2445e..7a961771 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -2,6 +2,7 @@ pub mod capability; pub mod composite_device; pub mod event; +pub mod info; pub mod manager; pub mod output_capability; pub mod output_event; diff --git a/src/input/source/evdev.rs b/src/input/source/evdev.rs index dca8f840..07650011 100644 --- a/src/input/source/evdev.rs +++ b/src/input/source/evdev.rs @@ -15,7 +15,7 @@ use crate::{ capability_map::{load_capability_mappings, CapabilityMapConfig}, }, constants::BUS_SOURCES_PREFIX, - input::composite_device::client::CompositeDeviceClient, + input::{composite_device::client::CompositeDeviceClient, info::DeviceInfoRef}, udev::device::UdevDevice, }; @@ -41,7 +41,7 @@ pub enum EventDevice { } impl SourceDeviceCompatible for EventDevice { - fn get_device_ref(&self) -> &UdevDevice { + fn get_device_ref(&self) -> DeviceInfoRef { match self { EventDevice::Blocked(source_driver) => source_driver.info_ref(), EventDevice::Gamepad(source_driver) => source_driver.info_ref(), @@ -127,7 +127,7 @@ impl EventDevice { let source_device = SourceDriver::new_with_options( composite_device, device, - device_info, + device_info.into(), options, conf, ); @@ -135,7 +135,8 @@ impl EventDevice { } DriverType::Gamepad => { let device = GamepadEventDevice::new(device_info.clone(), capability_map)?; - let source_device = SourceDriver::new(composite_device, device, device_info, conf); + let source_device = + SourceDriver::new(composite_device, device, device_info.into(), conf); Ok(Self::Gamepad(source_device)) } DriverType::Touchscreen => { @@ -145,12 +146,14 @@ impl EventDevice { .and_then(|c| c.touchscreen); let device = TouchscreenEventDevice::new(device_info.clone(), touch_config, capability_map)?; - let source_device = SourceDriver::new(composite_device, device, device_info, conf); + let source_device = + SourceDriver::new(composite_device, device, device_info.into(), conf); Ok(Self::Touchscreen(source_device)) } DriverType::Keyboard => { let device = KeyboardEventDevice::new(device_info.clone(), &conf, capability_map)?; - let source_device = SourceDriver::new(composite_device, device, device_info, conf); + let source_device = + SourceDriver::new(composite_device, device, device_info.into(), conf); Ok(Self::Keyboard(source_device)) } } diff --git a/src/input/source/hidraw.rs b/src/input/source/hidraw.rs index de64713c..a7e39e93 100644 --- a/src/input/source/hidraw.rs +++ b/src/input/source/hidraw.rs @@ -32,8 +32,11 @@ use xpad_uhid::XpadUhid; use zotac_zone::ZotacZone; use crate::{ - config, constants::BUS_SOURCES_PREFIX, drivers, - input::composite_device::client::CompositeDeviceClient, udev::device::UdevDevice, + config, + constants::BUS_SOURCES_PREFIX, + drivers, + input::{composite_device::client::CompositeDeviceClient, info::DeviceInfoRef}, + udev::device::UdevDevice, }; use self::{ @@ -94,7 +97,7 @@ pub enum HidRawDevice { } impl SourceDeviceCompatible for HidRawDevice { - fn get_device_ref(&self) -> &UdevDevice { + fn get_device_ref(&self) -> DeviceInfoRef { match self { HidRawDevice::Blocked(source_driver) => source_driver.info_ref(), HidRawDevice::DualSense(source_driver) => source_driver.info_ref(), @@ -264,7 +267,7 @@ impl HidRawDevice { let source_device = SourceDriver::new_with_options( composite_device, device, - device_info, + device_info.into(), options, conf, ); @@ -279,7 +282,7 @@ impl HidRawDevice { let source_device = SourceDriver::new_with_options( composite_device, device, - device_info, + device_info.into(), options, conf, ); @@ -294,7 +297,7 @@ impl HidRawDevice { let source_device = SourceDriver::new_with_options( composite_device, device, - device_info, + device_info.into(), options, conf, ); @@ -302,22 +305,26 @@ impl HidRawDevice { } DriverType::LegionGoDCombined => { let device = LegionControllerDCombined::new(device_info.clone())?; - let source_device = SourceDriver::new(composite_device, device, device_info, conf); + let source_device = + SourceDriver::new(composite_device, device, device_info.into(), conf); Ok(Self::LegionGoDCombined(source_device)) } DriverType::LegionGoDSplit => { let device = LegionControllerDSplit::new(device_info.clone())?; - let source_device = SourceDriver::new(composite_device, device, device_info, conf); + let source_device = + SourceDriver::new(composite_device, device, device_info.into(), conf); Ok(Self::LegionGoDSplit(source_device)) } DriverType::LegionGoFPS => { let device = LegionControllerFPS::new(device_info.clone())?; - let source_device = SourceDriver::new(composite_device, device, device_info, conf); + let source_device = + SourceDriver::new(composite_device, device, device_info.into(), conf); Ok(Self::LegionGoFPS(source_device)) } DriverType::LegionGoXInput => { let device = LegionControllerX::new(device_info.clone())?; - let source_device = SourceDriver::new(composite_device, device, device_info, conf); + let source_device = + SourceDriver::new(composite_device, device, device_info.into(), conf); Ok(Self::LegionGoXInput(source_device)) } DriverType::LegionGoSConfig => { @@ -329,7 +336,7 @@ impl HidRawDevice { let source_device = SourceDriver::new_with_options( composite_device, device, - device_info, + device_info.into(), options, conf, ); @@ -344,7 +351,7 @@ impl HidRawDevice { let source_device = SourceDriver::new_with_options( composite_device, device, - device_info, + device_info.into(), options, conf, ); @@ -359,7 +366,7 @@ impl HidRawDevice { let source_device = SourceDriver::new_with_options( composite_device, device, - device_info, + device_info.into(), options, conf, ); @@ -374,7 +381,7 @@ impl HidRawDevice { let source_device = SourceDriver::new_with_options( composite_device, device, - device_info, + device_info.into(), options, conf, ); @@ -382,22 +389,26 @@ impl HidRawDevice { } DriverType::OrangePiNeo => { let device = OrangePiNeoTouchpad::new(device_info.clone())?; - let source_device = SourceDriver::new(composite_device, device, device_info, conf); + let source_device = + SourceDriver::new(composite_device, device, device_info.into(), conf); Ok(Self::OrangePiNeo(source_device)) } DriverType::MsiClaw => { let device = MsiClaw::new(device_info.clone())?; - let source_device = SourceDriver::new(composite_device, device, device_info, conf); + let source_device = + SourceDriver::new(composite_device, device, device_info.into(), conf); Ok(Self::MsiClaw(source_device)) } DriverType::Fts3528Touchscreen => { let device = Fts3528Touchscreen::new(device_info.clone())?; - let source_device = SourceDriver::new(composite_device, device, device_info, conf); + let source_device = + SourceDriver::new(composite_device, device, device_info.into(), conf); Ok(Self::Fts3528Touchscreen(source_device)) } DriverType::XpadUhid => { let device = XpadUhid::new(device_info.clone())?; - let source_device = SourceDriver::new(composite_device, device, device_info, conf); + let source_device = + SourceDriver::new(composite_device, device, device_info.into(), conf); Ok(Self::XpadUhid(source_device)) } DriverType::RogAlly => { @@ -409,7 +420,7 @@ impl HidRawDevice { let source_device = SourceDriver::new_with_options( composite_device, device, - device_info, + device_info.into(), options, conf, ); @@ -417,7 +428,8 @@ impl HidRawDevice { } DriverType::HoripadSteam => { let device = HoripadSteam::new(device_info.clone())?; - let source_device = SourceDriver::new(composite_device, device, device_info, conf); + let source_device = + SourceDriver::new(composite_device, device, device_info.into(), conf); Ok(Self::HoripadSteam(source_device)) } DriverType::Vader4Pro => { @@ -429,7 +441,7 @@ impl HidRawDevice { let source_device = SourceDriver::new_with_options( composite_device, device, - device_info, + device_info.into(), options, conf, ); @@ -444,7 +456,7 @@ impl HidRawDevice { let source_device = SourceDriver::new_with_options( composite_device, device, - device_info, + device_info.into(), options, conf, ); diff --git a/src/input/source/iio.rs b/src/input/source/iio.rs index 4acad5f8..557b909f 100644 --- a/src/input/source/iio.rs +++ b/src/input/source/iio.rs @@ -6,7 +6,9 @@ use std::error::Error; use glob_match::glob_match; use crate::{ - config, constants::BUS_SOURCES_PREFIX, input::composite_device::client::CompositeDeviceClient, + config, + constants::BUS_SOURCES_PREFIX, + input::{composite_device::client::CompositeDeviceClient, info::DeviceInfoRef}, udev::device::UdevDevice, }; @@ -29,7 +31,7 @@ pub enum IioDevice { } impl SourceDeviceCompatible for IioDevice { - fn get_device_ref(&self) -> &UdevDevice { + fn get_device_ref(&self) -> DeviceInfoRef { match self { IioDevice::BmiImu(source_driver) => source_driver.info_ref(), IioDevice::AccelGryo3D(source_driver) => source_driver.info_ref(), @@ -90,12 +92,14 @@ impl IioDevice { DriverType::Unknown => Err("No driver for iio interface found".into()), DriverType::BmiImu => { let device = BmiImu::new(device_info.clone(), iio_config)?; - let source_device = SourceDriver::new(composite_device, device, device_info, conf); + let source_device = + SourceDriver::new(composite_device, device, device_info.into(), conf); Ok(Self::BmiImu(source_device)) } DriverType::AccelGryo3D => { let device = AccelGyro3dImu::new(device_info.clone(), iio_config)?; - let source_device = SourceDriver::new(composite_device, device, device_info, conf); + let source_device = + SourceDriver::new(composite_device, device, device_info.into(), conf); Ok(Self::AccelGryo3D(source_device)) } } diff --git a/src/input/source/led.rs b/src/input/source/led.rs index b7b79257..9e157a2f 100644 --- a/src/input/source/led.rs +++ b/src/input/source/led.rs @@ -2,7 +2,9 @@ pub mod multicolor; use self::multicolor::LedMultiColor; use super::{SourceDeviceCompatible, SourceDriver}; use crate::{ - config, constants::BUS_SOURCES_PREFIX, input::composite_device::client::CompositeDeviceClient, + config, + constants::BUS_SOURCES_PREFIX, + input::{composite_device::client::CompositeDeviceClient, info::DeviceInfoRef}, udev::device::UdevDevice, }; use std::error::Error; @@ -17,7 +19,7 @@ pub enum LedDevice { } impl SourceDeviceCompatible for LedDevice { - fn get_device_ref(&self) -> &UdevDevice { + fn get_device_ref(&self) -> DeviceInfoRef { match self { LedDevice::MultiColor(source_driver) => source_driver.info_ref(), } @@ -69,11 +71,13 @@ impl LedDevice { match driver_type { DriverType::LedMultiColor => { let device = LedMultiColor::new(device_info.clone())?; - let source_device = SourceDriver::new(composite_device, device, device_info, conf); + let source_device = + SourceDriver::new(composite_device, device, device_info.into(), conf); Ok(Self::MultiColor(source_device)) } } } + /// Return the driver type for the given device info fn get_driver_type(device: &UdevDevice) -> DriverType { let device_name = device.sysname(); diff --git a/src/input/source/mod.rs b/src/input/source/mod.rs index e3a15b37..acac8159 100644 --- a/src/input/source/mod.rs +++ b/src/input/source/mod.rs @@ -13,7 +13,7 @@ use led::LedDevice; use thiserror::Error; use tokio::sync::mpsc::{self, error::TryRecvError}; -use crate::{config, udev::device::UdevDevice}; +use crate::config; use self::{ client::SourceDeviceClient, command::SourceCommand, evdev::EventDevice, hidraw::HidRawDevice, @@ -24,6 +24,7 @@ use super::{ capability::Capability, composite_device::client::CompositeDeviceClient, event::{context::EventContext, native::NativeEvent, Event}, + info::{DeviceInfo, DeviceInfoRef}, output_event::OutputEvent, }; @@ -180,7 +181,7 @@ pub struct SourceDriver { event_include_list: HashSet, event_exclude_list: HashSet, implementation: Arc>, - device_info: UdevDevice, + device_info: DeviceInfo, composite_device: CompositeDeviceClient, tx: mpsc::Sender, rx: mpsc::Receiver, @@ -191,7 +192,7 @@ impl SourceDriver pub fn new( composite_device: CompositeDeviceClient, device: T, - device_info: UdevDevice, + device_info: DeviceInfo, config: Option, ) -> Self { let options = SourceDriverOptions::default(); @@ -202,7 +203,7 @@ impl SourceDriver pub fn new_with_options( composite_device: CompositeDeviceClient, device: T, - device_info: UdevDevice, + device_info: DeviceInfo, options: SourceDriverOptions, config: Option, ) -> Self { @@ -235,7 +236,7 @@ impl SourceDriver } let event_filter_enabled = !events_exclude.is_empty() || !events_include.is_empty(); if event_filter_enabled { - let devnode = device_info.devnode(); + let devnode = device_info.path(); if !events_include.is_empty() { log::debug!("Source device '{devnode}' filter includes events: {events_include:?}"); } @@ -315,7 +316,7 @@ impl SourceDriver /// Returns the path to the device (e.g. "/dev/input/event0") pub fn get_device_path(&self) -> String { - self.device_info.devnode() + self.device_info.path() } /// Returns a transmitter channel that can be used to send events to this device @@ -324,8 +325,10 @@ impl SourceDriver } /// Returns udev device information about the device as a reference - pub fn info_ref(&self) -> &UdevDevice { - &self.device_info + pub fn info_ref(&self) -> DeviceInfoRef { + match &self.device_info { + DeviceInfo::Udev(device) => device.into(), + } } /// Run the source device, consuming the device. @@ -482,7 +485,7 @@ impl SourceDriver pub(crate) trait SourceDeviceCompatible { /// Returns a copy of the UdevDevice - fn get_device_ref(&self) -> &UdevDevice; + fn get_device_ref(&self) -> DeviceInfoRef; /// Returns a unique identifier for the source device. fn get_id(&self) -> String; @@ -510,8 +513,8 @@ pub enum SourceDevice { } impl SourceDevice { - /// Returns a copy of the UdevDevice - pub fn get_device_ref(&self) -> &UdevDevice { + /// Returns a copy of the DeviceInfo + pub fn get_device_ref(&self) -> DeviceInfoRef { match self { SourceDevice::Event(device) => device.get_device_ref(), SourceDevice::HidRaw(device) => device.get_device_ref(),