Skip to content

Commit

Permalink
feat(CompositeDevice): add get device profile name and target capabil…
Browse files Browse the repository at this point in the history
…ities
  • Loading branch information
ShadowApex committed May 7, 2024
1 parent f2b6f4f commit 3bbb78c
Show file tree
Hide file tree
Showing 8 changed files with 411 additions and 15 deletions.
103 changes: 102 additions & 1 deletion src/input/composite_device/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,11 @@ pub enum InterceptMode {
/// dispatched as they come in.
#[derive(Debug, Clone)]
pub enum Command {
GetName(mpsc::Sender<String>),
ProcessEvent(String, Event),
ProcessOutputEvent(OutputEvent),
GetCapabilities(mpsc::Sender<HashSet<Capability>>),
GetTargetCapabilities(mpsc::Sender<HashSet<Capability>>),
SetInterceptMode(InterceptMode),
GetInterceptMode(mpsc::Sender<InterceptMode>),
GetSourceDevicePaths(mpsc::Sender<Vec<String>>),
Expand Down Expand Up @@ -102,7 +104,16 @@ impl DBusInterface {
/// Name of the composite device
#[dbus_interface(property)]
async fn name(&self) -> fdo::Result<String> {
Ok("CompositeDevice".into())
let (sender, mut receiver) = mpsc::channel::<String>(1);
self.tx
.send(Command::GetName(sender))
.await
.map_err(|e| fdo::Error::Failed(e.to_string()))?;
let Some(name) = receiver.recv().await else {
return Ok("".to_string());
};

Ok(name)
}

/// Name of the currently loaded profile
Expand Down Expand Up @@ -345,6 +356,41 @@ impl DBusInterface {
Ok(capability_strings)
}

/// List of capabilities that all target devices implement
#[dbus_interface(property)]
async fn target_capabilities(&self) -> fdo::Result<Vec<String>> {
let (sender, mut receiver) = mpsc::channel::<HashSet<Capability>>(1);
self.tx
.send(Command::GetTargetCapabilities(sender))
.await
.map_err(|e| fdo::Error::Failed(e.to_string()))?;
let Some(capabilities) = receiver.recv().await else {
return Ok(Vec::new());
};

let mut capability_strings = Vec::new();
for cap in capabilities {
let str = match cap {
Capability::Gamepad(gamepad) => match gamepad {
Gamepad::Button(button) => format!("Gamepad:Button:{}", button),
Gamepad::Axis(axis) => format!("Gamepad:Axis:{}", axis),
Gamepad::Trigger(trigger) => format!("Gamepad:Trigger:{}", trigger),
Gamepad::Accelerometer => "Gamepad:Accelerometer".to_string(),
Gamepad::Gyro => "Gamepad:Gyro".to_string(),
},
Capability::Mouse(mouse) => match mouse {
Mouse::Motion => "Mouse:Motion".to_string(),
Mouse::Button(button) => format!("Mouse:Button:{}", button),
},
Capability::Keyboard(key) => format!("Keyboard:{}", key),
_ => cap.to_string(),
};
capability_strings.push(str);
}

Ok(capability_strings)
}

/// List of source devices that this composite device is processing inputs for
#[dbus_interface(property)]
async fn source_device_paths(&self) -> fdo::Result<Vec<String>> {
Expand Down Expand Up @@ -435,6 +481,8 @@ pub struct CompositeDevice {
manager: broadcast::Sender<ManagerCommand>,
/// Configuration for the CompositeDevice
config: CompositeDeviceConfig,
/// Name of the [CompositeDeviceConfig] loaded for the device
name: String,
/// Capabilities describe all input capabilities from all source devices
capabilities: HashSet<Capability>,
/// Capability mapping for the CompositeDevice
Expand Down Expand Up @@ -514,10 +562,12 @@ impl CompositeDevice {
) -> Result<Self, Box<dyn Error>> {
log::info!("Creating CompositeDevice with config: {}", config.name);
let (tx, rx) = mpsc::channel(BUFFER_SIZE);
let name = config.name.clone();
let mut device = Self {
conn,
manager,
config,
name,
capabilities: HashSet::new(),
capability_map,
device_profile: None,
Expand Down Expand Up @@ -646,6 +696,18 @@ impl CompositeDevice {
log::error!("Failed to send capabilities: {:?}", e);
}
}
Command::GetTargetCapabilities(sender) => {
let target_caps = match self.get_target_capabilities().await {
Ok(caps) => caps,
Err(e) => {
log::error!("Failed to get target capabilities: {e:?}");
continue;
}
};
if let Err(e) = sender.send(target_caps).await {
log::error!("Failed to send target capabilities: {:?}", e);
}
}
Command::SetInterceptMode(mode) => self.set_intercept_mode(mode),
Command::GetInterceptMode(sender) => {
if let Err(e) = sender.send(self.intercept_mode.clone()).await {
Expand Down Expand Up @@ -710,6 +772,12 @@ impl CompositeDevice {
log::error!("Failed to attach target devices: {e:?}");
}
}
Command::GetName(sender) => {
let name = self.name.clone();
if let Err(e) = sender.send(name).await {
log::error!("Failed to send device name: {:?}", e);
}
}
Command::GetProfileName(sender) => {
let profile_name = self.device_profile.clone().unwrap_or_default();
if let Err(e) = sender.send(profile_name).await {
Expand Down Expand Up @@ -2048,6 +2116,39 @@ impl CompositeDevice {
Ok(())
}

// Get the capabilities of all target devices
async fn get_target_capabilities(&self) -> Result<HashSet<Capability>, Box<dyn Error>> {
let mut target_caps = HashSet::new();
for target in self.target_devices.values() {
let (tx, mut rx) = mpsc::channel(1);
let cmd = TargetCommand::GetCapabilities(tx);
if let Err(e) = target.send(cmd).await {
return Err(format!("Failed to get target capabilities: {e:?}").into());
}
let Some(caps) = rx.recv().await else {
return Err("Failed to receive target capabilities".into());
};
for cap in caps {
target_caps.insert(cap);
}
}
for target in self.target_dbus_devices.values() {
let (tx, mut rx) = mpsc::channel(1);
let cmd = TargetCommand::GetCapabilities(tx);
if let Err(e) = target.send(cmd).await {
return Err(format!("Failed to get target capabilities: {e:?}").into());
}
let Some(caps) = rx.recv().await else {
return Err("Failed to receive target capabilities".into());
};
for cap in caps {
target_caps.insert(cap);
}
}

Ok(target_caps)
}

/// Attach the given target devices to the composite device
async fn attach_target_devices(
&mut self,
Expand Down
37 changes: 37 additions & 0 deletions src/input/target/dbus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use zbus::{fdo, Connection, SignalContext};
use zbus_macros::dbus_interface;

use crate::input::{
capability::Capability,
composite_device,
event::{
dbus::{Action, DBusEvent},
Expand Down Expand Up @@ -125,6 +126,12 @@ impl DBusDevice {
self.write_dbus_event(dbus_event).await?;
}
}
TargetCommand::GetCapabilities(tx) => {
let caps = self.get_capabilities();
if let Err(e) = tx.send(caps).await {
log::error!("Failed to send target capabilities: {e:?}");
}
}
TargetCommand::Stop => break,
};
}
Expand Down Expand Up @@ -245,4 +252,34 @@ impl DBusDevice {

Ok(())
}

/// Returns capabilities of the target device
fn get_capabilities(&self) -> Vec<Capability> {
vec![
Capability::DBus(Action::Guide),
Capability::DBus(Action::Quick),
Capability::DBus(Action::Quick2),
Capability::DBus(Action::Context),
Capability::DBus(Action::Option),
Capability::DBus(Action::Select),
Capability::DBus(Action::Accept),
Capability::DBus(Action::Back),
Capability::DBus(Action::ActOn),
Capability::DBus(Action::Left),
Capability::DBus(Action::Right),
Capability::DBus(Action::Up),
Capability::DBus(Action::Down),
Capability::DBus(Action::L1),
Capability::DBus(Action::L2),
Capability::DBus(Action::L3),
Capability::DBus(Action::R1),
Capability::DBus(Action::R2),
Capability::DBus(Action::R3),
Capability::DBus(Action::VolumeUp),
Capability::DBus(Action::VolumeDown),
Capability::DBus(Action::VolumeMute),
Capability::DBus(Action::Keyboard),
Capability::DBus(Action::Screenshot),
]
}
}
37 changes: 37 additions & 0 deletions src/input/target/dualsense.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,12 @@ impl DualSenseDevice {
// Update internal state
self.update_state(event);
}
TargetCommand::GetCapabilities(tx) => {
let caps = self.get_capabilities();
if let Err(e) = tx.send(caps).await {
log::error!("Failed to send target capabilities: {e:?}");
}
}
TargetCommand::Stop => return Err("Device stopped".into()),
}
}
Expand Down Expand Up @@ -1768,6 +1774,37 @@ impl DualSenseDevice {
Capability::DBus(_) => (),
};
}

/// Returns capabilities of the target device
fn get_capabilities(&self) -> Vec<Capability> {
vec![
Capability::Gamepad(Gamepad::Button(GamepadButton::South)),
Capability::Gamepad(Gamepad::Button(GamepadButton::North)),
Capability::Gamepad(Gamepad::Button(GamepadButton::East)),
Capability::Gamepad(Gamepad::Button(GamepadButton::West)),
Capability::Gamepad(Gamepad::Button(GamepadButton::Start)),
Capability::Gamepad(Gamepad::Button(GamepadButton::Select)),
Capability::Gamepad(Gamepad::Button(GamepadButton::Guide)),
Capability::Gamepad(Gamepad::Button(GamepadButton::DPadDown)),
Capability::Gamepad(Gamepad::Button(GamepadButton::DPadUp)),
Capability::Gamepad(Gamepad::Button(GamepadButton::DPadLeft)),
Capability::Gamepad(Gamepad::Button(GamepadButton::DPadRight)),
Capability::Gamepad(Gamepad::Button(GamepadButton::LeftBumper)),
Capability::Gamepad(Gamepad::Button(GamepadButton::LeftTrigger)),
Capability::Gamepad(Gamepad::Button(GamepadButton::LeftStick)),
Capability::Gamepad(Gamepad::Button(GamepadButton::LeftPaddle1)),
Capability::Gamepad(Gamepad::Button(GamepadButton::RightBumper)),
Capability::Gamepad(Gamepad::Button(GamepadButton::RightTrigger)),
Capability::Gamepad(Gamepad::Button(GamepadButton::RightStick)),
Capability::Gamepad(Gamepad::Button(GamepadButton::RightPaddle1)),
Capability::Gamepad(Gamepad::Axis(GamepadAxis::LeftStick)),
Capability::Gamepad(Gamepad::Axis(GamepadAxis::RightStick)),
Capability::Gamepad(Gamepad::Trigger(GamepadTrigger::LeftTrigger)),
Capability::Gamepad(Gamepad::Trigger(GamepadTrigger::RightTrigger)),
Capability::Gamepad(Gamepad::Accelerometer),
Capability::Gamepad(Gamepad::Gyro),
]
}
}

/// Convert the given normalized value between -1.0 - 1.0 to the real value
Expand Down
46 changes: 34 additions & 12 deletions src/input/target/gamepad.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use zbus::{fdo, Connection};
use zbus_macros::dbus_interface;

use crate::input::{
capability::Capability,
capability::{Capability, Gamepad, GamepadAxis, GamepadButton, GamepadTrigger},
composite_device::Command,
event::{evdev::EvdevEvent, native::NativeEvent},
output_event::{OutputEvent, UinputOutputEvent},
Expand Down Expand Up @@ -73,17 +73,6 @@ impl GenericGamepad {
}
}

/// Returns all the native capabilities that the device can emit
pub fn _get_capabilities() -> Vec<Capability> {
use crate::input::capability::{Gamepad, GamepadButton};
vec![
Capability::Gamepad(Gamepad::Button(GamepadButton::South)),
Capability::Gamepad(Gamepad::Button(GamepadButton::North)),
Capability::Gamepad(Gamepad::Button(GamepadButton::East)),
Capability::Gamepad(Gamepad::Button(GamepadButton::West)),
]
}

/// Returns the DBus path of this device
pub fn get_dbus_path(&self) -> Option<String> {
self.dbus_path.clone()
Expand Down Expand Up @@ -146,6 +135,12 @@ impl GenericGamepad {
])?;
}
}
TargetCommand::GetCapabilities(tx) => {
let caps = self.get_capabilities();
if let Err(e) = tx.send(caps).await {
log::error!("Failed to send target capabilities: {e:?}");
}
}
TargetCommand::Stop => break,
}
}
Expand Down Expand Up @@ -400,4 +395,31 @@ impl GenericGamepad {

Ok(())
}

/// Returns capabilities of the target device
fn get_capabilities(&self) -> Vec<Capability> {
vec![
Capability::Gamepad(Gamepad::Button(GamepadButton::South)),
Capability::Gamepad(Gamepad::Button(GamepadButton::North)),
Capability::Gamepad(Gamepad::Button(GamepadButton::East)),
Capability::Gamepad(Gamepad::Button(GamepadButton::West)),
Capability::Gamepad(Gamepad::Button(GamepadButton::Start)),
Capability::Gamepad(Gamepad::Button(GamepadButton::Select)),
Capability::Gamepad(Gamepad::Button(GamepadButton::Guide)),
Capability::Gamepad(Gamepad::Button(GamepadButton::DPadDown)),
Capability::Gamepad(Gamepad::Button(GamepadButton::DPadUp)),
Capability::Gamepad(Gamepad::Button(GamepadButton::DPadLeft)),
Capability::Gamepad(Gamepad::Button(GamepadButton::DPadRight)),
Capability::Gamepad(Gamepad::Button(GamepadButton::LeftBumper)),
Capability::Gamepad(Gamepad::Button(GamepadButton::LeftTrigger)),
Capability::Gamepad(Gamepad::Button(GamepadButton::LeftStick)),
Capability::Gamepad(Gamepad::Button(GamepadButton::RightBumper)),
Capability::Gamepad(Gamepad::Button(GamepadButton::RightTrigger)),
Capability::Gamepad(Gamepad::Button(GamepadButton::RightStick)),
Capability::Gamepad(Gamepad::Axis(GamepadAxis::LeftStick)),
Capability::Gamepad(Gamepad::Axis(GamepadAxis::RightStick)),
Capability::Gamepad(Gamepad::Trigger(GamepadTrigger::LeftTrigger)),
Capability::Gamepad(Gamepad::Trigger(GamepadTrigger::RightTrigger)),
]
}
}
Loading

0 comments on commit 3bbb78c

Please sign in to comment.