Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 52 additions & 40 deletions src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};

Expand Down Expand Up @@ -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<SourceDevice> {
pub fn get_matching_device(&self, device: &DeviceInfo) -> Option<SourceDevice> {
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<SourceDevice> {
// 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
Expand Down
6 changes: 3 additions & 3 deletions src/input/composite_device/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -208,15 +208,15 @@ 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?;
Ok(())
}

/// 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?;
Expand Down
8 changes: 4 additions & 4 deletions src/input/composite_device/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -40,9 +40,9 @@ pub enum CompositeCommand {
SetInterceptActivation(Vec<Capability>, Capability),
SetInterceptMode(InterceptMode),
SetTargetDevices(Vec<TargetDeviceTypeId>),
SourceDeviceAdded(UdevDevice),
SourceDeviceRemoved(UdevDevice),
SourceDeviceStopped(UdevDevice),
SourceDeviceAdded(DeviceInfo),
SourceDeviceRemoved(DeviceInfo),
SourceDeviceStopped(DeviceInfo),
#[allow(dead_code)]
UpdateSourceCapabilities(String, HashSet<Capability>),
UpdateTargetCapabilities(String, HashSet<Capability>),
Expand Down
117 changes: 63 additions & 54 deletions src/input/composite_device/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -161,7 +161,7 @@ impl CompositeDevice {
conn: Connection,
manager: mpsc::Sender<ManagerCommand>,
config: CompositeDeviceConfig,
device_info: UdevDevice,
device_info: DeviceInfo,
dbus_path: String,
capability_map: Option<CapabilityMapConfig>,
) -> Result<Self, Box<dyn Error>> {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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.");
Expand All @@ -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 {
Expand Down Expand Up @@ -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<dyn Error>> {
async fn on_source_device_added(&mut self, device: DeviceInfo) -> Result<(), Box<dyn Error>> {
if let Err(e) = self.add_source_device(device) {
return Err(e.to_string().into());
}
Expand All @@ -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<dyn Error>> {
let path = device.devnode();
async fn on_source_device_removed(&mut self, device: DeviceInfo) -> Result<(), Box<dyn Error>> {
let path = device.path();
let id = device.get_id();

// Remove any ffb effects this device registered
Expand Down Expand Up @@ -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<dyn Error + Send + Sync>> {
// Check to see if this source device should be blocked.
let mut is_blocked = false;
Expand All @@ -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())
}
};

Expand All @@ -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
Expand Down
Loading