Skip to content

Commit

Permalink
LED: implement leds as a source output device
Browse files Browse the repository at this point in the history
Perform a code cleanup:
  - remove a method that was used only once just to avoid calling .clone()
  - remove a lot of duplicated code
  - use a specific function to resolve configuration matches instead of using device-specific matches for each device type
  - solve the SourceDevice scope creep that was in need (for no reason) to know specific internal details about sub-types

Removing the duplicated code has the additional effect of activating LEDs devices acquisition and activation.

This commit adds the ability of defining a fixed RGB color the abblied on device acquisition and never be overwritten.
  • Loading branch information
NeroReflex committed Dec 31, 2024
1 parent 2ea44a7 commit ca1968c
Show file tree
Hide file tree
Showing 9 changed files with 430 additions and 565 deletions.
17 changes: 15 additions & 2 deletions src/input/composite_device/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ use crate::{
Event,
},
output_event::UinputOutputEvent,
source::{evdev::EventDevice, hidraw::HidRawDevice, iio::IioDevice, SourceDevice},
source::{
evdev::EventDevice, hidraw::HidRawDevice, iio::IioDevice, led::LedDevice, SourceDevice,
},
},
udev::{device::UdevDevice, hide_device, unhide_device},
};
Expand Down Expand Up @@ -627,7 +629,7 @@ 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();
let device = source_device.get_device_ref().clone();
if let SourceDevice::Iio(_) = source_device {
SourceIioImuInterface::listen_on_dbus(self.conn.clone(), device.clone()).await?;
}
Expand Down Expand Up @@ -1439,6 +1441,17 @@ impl CompositeDevice {
let device = IioDevice::new(device, self.client(), config)?;
SourceDevice::Iio(device)
}
"leds" => {
// Get any defined config for the IIO device
let config = if let Some(device_config) = self.config.get_matching_device(&device) {
device_config.led
} else {
None
};

log::debug!("Adding source device: {:?}", device.name());
SourceDevice::Led(LedDevice::new(device, self.client(), config)?)
}
_ => {
return Err(format!(
"Unspported subsystem: {subsystem}, unable to add source device {}",
Expand Down
511 changes: 115 additions & 396 deletions src/input/manager.rs

Large diffs are not rendered by default.

48 changes: 47 additions & 1 deletion src/input/source/evdev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::{

use self::{blocked::BlockedEventDevice, gamepad::GamepadEventDevice};

use super::{SourceDriver, SourceDriverOptions};
use super::{SourceDeviceCompatible, SourceDriver, SourceDriverOptions};

/// List of available drivers
enum DriverType {
Expand All @@ -27,6 +27,52 @@ pub enum EventDevice {
Gamepad(SourceDriver<GamepadEventDevice>),
}

impl SourceDeviceCompatible for EventDevice {
fn get_device_ref(&self) -> &UdevDevice {
match self {
EventDevice::Blocked(source_driver) => source_driver.info_ref(),
EventDevice::Gamepad(source_driver) => source_driver.info_ref(),
}
}

fn get_id(&self) -> String {
match self {
EventDevice::Blocked(source_driver) => source_driver.get_id(),
EventDevice::Gamepad(source_driver) => source_driver.get_id(),
}
}

fn client(&self) -> super::client::SourceDeviceClient {
match self {
EventDevice::Blocked(source_driver) => source_driver.client(),
EventDevice::Gamepad(source_driver) => source_driver.client(),
}
}

async fn run(self) -> Result<(), Box<dyn Error>> {
match self {
EventDevice::Blocked(source_driver) => source_driver.run().await,
EventDevice::Gamepad(source_driver) => source_driver.run().await,
}
}

fn get_capabilities(
&self,
) -> Result<Vec<crate::input::capability::Capability>, super::InputError> {
match self {
EventDevice::Blocked(source_driver) => source_driver.get_capabilities(),
EventDevice::Gamepad(source_driver) => source_driver.get_capabilities(),
}
}

fn get_device_path(&self) -> String {
match self {
EventDevice::Blocked(source_driver) => source_driver.get_device_path(),
EventDevice::Gamepad(source_driver) => source_driver.get_device_path(),
}
}
}

impl EventDevice {
pub fn new(
device_info: UdevDevice,
Expand Down
96 changes: 95 additions & 1 deletion src/input/source/hidraw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use self::{
opineo::OrangePiNeoTouchpad, steam_deck::DeckController,
};

use super::{SourceDriver, SourceDriverOptions};
use super::{SourceDeviceCompatible, SourceDriver, SourceDriverOptions};

/// List of available drivers
enum DriverType {
Expand Down Expand Up @@ -58,6 +58,100 @@ pub enum HidRawDevice {
RogAlly(SourceDriver<RogAlly>),
}

impl SourceDeviceCompatible for HidRawDevice {
fn get_device_ref(&self) -> &UdevDevice {
match self {
HidRawDevice::DualSense(source_driver) => source_driver.info_ref(),
HidRawDevice::SteamDeck(source_driver) => source_driver.info_ref(),
HidRawDevice::LegionGoDCombined(source_driver) => source_driver.info_ref(),
HidRawDevice::LegionGoDSplit(source_driver) => source_driver.info_ref(),
HidRawDevice::LegionGoFPS(source_driver) => source_driver.info_ref(),
HidRawDevice::LegionGoX(source_driver) => source_driver.info_ref(),
HidRawDevice::OrangePiNeo(source_driver) => source_driver.info_ref(),
HidRawDevice::Fts3528Touchscreen(source_driver) => source_driver.info_ref(),
HidRawDevice::XpadUhid(source_driver) => source_driver.info_ref(),
HidRawDevice::RogAlly(source_driver) => source_driver.info_ref(),
}
}

fn get_id(&self) -> String {
match self {
HidRawDevice::DualSense(source_driver) => source_driver.get_id(),
HidRawDevice::SteamDeck(source_driver) => source_driver.get_id(),
HidRawDevice::LegionGoDCombined(source_driver) => source_driver.get_id(),
HidRawDevice::LegionGoDSplit(source_driver) => source_driver.get_id(),
HidRawDevice::LegionGoFPS(source_driver) => source_driver.get_id(),
HidRawDevice::LegionGoX(source_driver) => source_driver.get_id(),
HidRawDevice::OrangePiNeo(source_driver) => source_driver.get_id(),
HidRawDevice::Fts3528Touchscreen(source_driver) => source_driver.get_id(),
HidRawDevice::XpadUhid(source_driver) => source_driver.get_id(),
HidRawDevice::RogAlly(source_driver) => source_driver.get_id(),
}
}

fn client(&self) -> super::client::SourceDeviceClient {
match self {
HidRawDevice::DualSense(source_driver) => source_driver.client(),
HidRawDevice::SteamDeck(source_driver) => source_driver.client(),
HidRawDevice::LegionGoDCombined(source_driver) => source_driver.client(),
HidRawDevice::LegionGoDSplit(source_driver) => source_driver.client(),
HidRawDevice::LegionGoFPS(source_driver) => source_driver.client(),
HidRawDevice::LegionGoX(source_driver) => source_driver.client(),
HidRawDevice::OrangePiNeo(source_driver) => source_driver.client(),
HidRawDevice::Fts3528Touchscreen(source_driver) => source_driver.client(),
HidRawDevice::XpadUhid(source_driver) => source_driver.client(),
HidRawDevice::RogAlly(source_driver) => source_driver.client(),
}
}

async fn run(self) -> Result<(), Box<dyn Error>> {
match self {
HidRawDevice::DualSense(source_driver) => source_driver.run().await,
HidRawDevice::SteamDeck(source_driver) => source_driver.run().await,
HidRawDevice::LegionGoDCombined(source_driver) => source_driver.run().await,
HidRawDevice::LegionGoDSplit(source_driver) => source_driver.run().await,
HidRawDevice::LegionGoFPS(source_driver) => source_driver.run().await,
HidRawDevice::LegionGoX(source_driver) => source_driver.run().await,
HidRawDevice::OrangePiNeo(source_driver) => source_driver.run().await,
HidRawDevice::Fts3528Touchscreen(source_driver) => source_driver.run().await,
HidRawDevice::XpadUhid(source_driver) => source_driver.run().await,
HidRawDevice::RogAlly(source_driver) => source_driver.run().await,
}
}

fn get_capabilities(
&self,
) -> Result<Vec<crate::input::capability::Capability>, super::InputError> {
match self {
HidRawDevice::DualSense(source_driver) => source_driver.get_capabilities(),
HidRawDevice::SteamDeck(source_driver) => source_driver.get_capabilities(),
HidRawDevice::LegionGoDCombined(source_driver) => source_driver.get_capabilities(),
HidRawDevice::LegionGoDSplit(source_driver) => source_driver.get_capabilities(),
HidRawDevice::LegionGoFPS(source_driver) => source_driver.get_capabilities(),
HidRawDevice::LegionGoX(source_driver) => source_driver.get_capabilities(),
HidRawDevice::OrangePiNeo(source_driver) => source_driver.get_capabilities(),
HidRawDevice::Fts3528Touchscreen(source_driver) => source_driver.get_capabilities(),
HidRawDevice::XpadUhid(source_driver) => source_driver.get_capabilities(),
HidRawDevice::RogAlly(source_driver) => source_driver.get_capabilities(),
}
}

fn get_device_path(&self) -> String {
match self {
HidRawDevice::DualSense(source_driver) => source_driver.get_device_path(),
HidRawDevice::SteamDeck(source_driver) => source_driver.get_device_path(),
HidRawDevice::LegionGoDCombined(source_driver) => source_driver.get_device_path(),
HidRawDevice::LegionGoDSplit(source_driver) => source_driver.get_device_path(),
HidRawDevice::LegionGoFPS(source_driver) => source_driver.get_device_path(),
HidRawDevice::LegionGoX(source_driver) => source_driver.get_device_path(),
HidRawDevice::OrangePiNeo(source_driver) => source_driver.get_device_path(),
HidRawDevice::Fts3528Touchscreen(source_driver) => source_driver.get_device_path(),
HidRawDevice::XpadUhid(source_driver) => source_driver.get_device_path(),
HidRawDevice::RogAlly(source_driver) => source_driver.get_device_path(),
}
}
}

impl HidRawDevice {
/// Create a new [HidRawDevice] associated with the given device and
/// composite device. The appropriate driver will be selected based on
Expand Down
48 changes: 47 additions & 1 deletion src/input/source/iio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::{

use self::{accel_gyro_3d_new::AccelGyro3dImu, bmi_imu_new::BmiImu};

use super::SourceDriver;
use super::{SourceDeviceCompatible, SourceDriver};

/// List of available drivers
enum DriverType {
Expand All @@ -30,6 +30,52 @@ pub enum IioDevice {
AccelGryo3D(SourceDriver<AccelGyro3dImu>),
}

impl SourceDeviceCompatible for IioDevice {
fn get_device_ref(&self) -> &UdevDevice {
match self {
IioDevice::BmiImu(source_driver) => source_driver.info_ref(),
IioDevice::AccelGryo3D(source_driver) => source_driver.info_ref(),
}
}

fn get_id(&self) -> String {
match self {
IioDevice::BmiImu(source_driver) => source_driver.get_id(),
IioDevice::AccelGryo3D(source_driver) => source_driver.get_id(),
}
}

fn client(&self) -> super::client::SourceDeviceClient {
match self {
IioDevice::BmiImu(source_driver) => source_driver.client(),
IioDevice::AccelGryo3D(source_driver) => source_driver.client(),
}
}

async fn run(self) -> Result<(), Box<dyn Error>> {
match self {
IioDevice::BmiImu(source_driver) => source_driver.run().await,
IioDevice::AccelGryo3D(source_driver) => source_driver.run().await,
}
}

fn get_capabilities(
&self,
) -> Result<Vec<crate::input::capability::Capability>, super::InputError> {
match self {
IioDevice::BmiImu(source_driver) => source_driver.get_capabilities(),
IioDevice::AccelGryo3D(source_driver) => source_driver.get_capabilities(),
}
}

fn get_device_path(&self) -> String {
match self {
IioDevice::BmiImu(source_driver) => source_driver.get_device_path(),
IioDevice::AccelGryo3D(source_driver) => source_driver.get_device_path(),
}
}
}

impl IioDevice {
/// Create a new [IioDevice] associated with the given device and
/// composite device. The appropriate driver will be selected based on
Expand Down
42 changes: 41 additions & 1 deletion src/input/source/led.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ pub mod multicolor_chassis;
use std::error::Error;
//use glob_match::glob_match;
use self::multicolor_chassis::MultiColorChassis;
use super::SourceDriver;
use super::{SourceDeviceCompatible, SourceDriver};
use crate::{
config, constants::BUS_SOURCES_PREFIX, input::composite_device::client::CompositeDeviceClient,
udev::device::UdevDevice,
Expand All @@ -17,6 +17,46 @@ pub enum LedDevice {
MultiColorChassis(SourceDriver<MultiColorChassis>),
}

impl SourceDeviceCompatible for LedDevice {
fn get_device_ref(&self) -> &UdevDevice {
match self {
LedDevice::MultiColorChassis(source_driver) => source_driver.info_ref(),
}
}

fn get_id(&self) -> String {
match self {
LedDevice::MultiColorChassis(source_driver) => source_driver.get_id(),
}
}

fn client(&self) -> super::client::SourceDeviceClient {
match self {
LedDevice::MultiColorChassis(source_driver) => source_driver.client(),
}
}

async fn run(self) -> Result<(), Box<dyn Error>> {
match self {
LedDevice::MultiColorChassis(source_driver) => source_driver.run().await,
}
}

fn get_capabilities(
&self,
) -> Result<Vec<crate::input::capability::Capability>, super::InputError> {
match self {
LedDevice::MultiColorChassis(source_driver) => source_driver.get_capabilities(),
}
}

fn get_device_path(&self) -> String {
match self {
LedDevice::MultiColorChassis(source_driver) => source_driver.get_device_path(),
}
}
}

impl LedDevice {
/// Create a new [IioDevice] associated with the given device and
/// composite device. The appropriate driver will be selected based on
Expand Down
Loading

0 comments on commit ca1968c

Please sign in to comment.