Skip to content

Commit

Permalink
feat: expose generic target interface on every target interface
Browse files Browse the repository at this point in the history
  • Loading branch information
imLinguin authored and ShadowApex committed Feb 10, 2025
1 parent efe0f03 commit b3d00bd
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 55 deletions.
15 changes: 12 additions & 3 deletions src/dbus/interface/target/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,21 @@ use zbus_macros::interface;
/// a target input device.
pub struct TargetInterface {
dev_name: String,
device_type: String,
}

impl TargetInterface {
pub fn new(dev_name: String) -> TargetInterface {
TargetInterface { dev_name }
pub fn new(dev_name: String, device_type: String) -> TargetInterface {
TargetInterface {
dev_name,
device_type,
}
}
}

impl Default for TargetInterface {
fn default() -> Self {
Self::new("Gamepad".to_string())
Self::new("Gamepad".to_string(), "gamepad".to_string())
}
}

Expand All @@ -32,4 +36,9 @@ impl TargetInterface {
async fn name(&self) -> fdo::Result<String> {
Ok(self.dev_name.clone())
}

#[zbus(property)]
async fn device_type(&self) -> fdo::Result<String> {
Ok(self.device_type.clone())
}
}
32 changes: 20 additions & 12 deletions src/input/target/dbus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{collections::HashMap, error::Error};
use zbus::Connection;

use crate::{
dbus::interface::target::dbus::TargetDBusInterface,
dbus::interface::target::{dbus::TargetDBusInterface, TargetInterface},
input::{
capability::{Capability, Gamepad, GamepadButton},
event::{
Expand Down Expand Up @@ -300,16 +300,23 @@ impl TargetInputDevice for DBusDevice {
dbus: Connection,
path: String,
_client: TargetDeviceClient,
type_id: String,
) {
log::debug!("Starting dbus interface: {path}");
self.dbus_path = Some(path.clone());
tokio::task::spawn(async move {
let generic_interface = TargetInterface::new("DBusDevice".into(), type_id);
let iface = TargetDBusInterface::new();
if let Err(e) = dbus.object_server().at(path.clone(), iface).await {
log::debug!("Failed to start dbus interface {path}: {e:?}");
let object_server = dbus.object_server();
let (gen_result, result) = tokio::join!(
object_server.at(path.clone(), generic_interface),
object_server.at(path.clone(), iface)
);
if gen_result.is_err() || result.is_err() {
log::debug!("Failed to start dbus interface: {path} generic: {gen_result:?} type-specific: {result:?}");
} else {
log::debug!("Started dbus interface on {path}");
};
log::debug!("Started dbus interface: {path}");
}
});
}

Expand Down Expand Up @@ -368,15 +375,16 @@ impl TargetInputDevice for DBusDevice {
fn stop_dbus_interface(&mut self, dbus: Connection, path: String) {
log::debug!("Stopping dbus interface for {path}");
tokio::task::spawn(async move {
let result = dbus
.object_server()
.remove::<TargetDBusInterface, String>(path.clone())
.await;
if let Err(e) = result {
log::error!("Failed to stop dbus interface {path}: {e:?}");
let object_server = dbus.object_server();
let (target, generic) = tokio::join!(
object_server.remove::<TargetDBusInterface, String>(path.clone()),
object_server.remove::<TargetInterface, String>(path.clone())
);
if generic.is_err() || target.is_err() {
log::debug!("Failed to stop dbus interface: {path} generic: {generic:?} type-specific: {target:?}");
} else {
log::debug!("Stopped dbus interface for {path}");
};
}
});
}
}
Expand Down
40 changes: 27 additions & 13 deletions src/input/target/keyboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use evdev::{
use zbus::Connection;

use crate::{
dbus::interface::target::keyboard::TargetKeyboardInterface,
dbus::interface::target::{keyboard::TargetKeyboardInterface, TargetInterface},
input::{
capability::{Capability, Keyboard},
event::{evdev::EvdevEvent, native::NativeEvent},
Expand Down Expand Up @@ -216,15 +216,28 @@ impl KeyboardDevice {
}

impl TargetInputDevice for KeyboardDevice {
fn start_dbus_interface(&mut self, dbus: Connection, path: String, client: TargetDeviceClient) {
fn start_dbus_interface(
&mut self,
dbus: Connection,
path: String,
client: TargetDeviceClient,
type_id: String,
) {
log::debug!("Starting dbus interface: {path}");
tokio::task::spawn(async move {
let generic_interface = TargetInterface::new("Keyboard".into(), type_id);
let iface = TargetKeyboardInterface::new(client);
if let Err(e) = dbus.object_server().at(path.clone(), iface).await {
log::debug!("Failed to start dbus interface {path}: {e:?}");

let object_server = dbus.object_server();
let (gen_result, result) = tokio::join!(
object_server.at(path.clone(), generic_interface),
object_server.at(path.clone(), iface)
);
if gen_result.is_err() || result.is_err() {
log::debug!("Failed to start dbus interface: {path} generic: {gen_result:?} type-specific: {result:?}");
} else {
log::debug!("Started dbus interface on {path}");
};
log::debug!("Started dbus interface: {path}");
}
});
}

Expand Down Expand Up @@ -407,15 +420,16 @@ impl TargetInputDevice for KeyboardDevice {
fn stop_dbus_interface(&mut self, dbus: Connection, path: String) {
log::debug!("Stopping dbus interface for {path}");
tokio::task::spawn(async move {
let result = dbus
.object_server()
.remove::<TargetKeyboardInterface, String>(path.clone())
.await;
if let Err(e) = result {
log::error!("Failed to stop dbus interface {path}: {e:?}");
let object_server = dbus.object_server();
let (target, generic) = tokio::join!(
object_server.remove::<TargetKeyboardInterface, String>(path.clone()),
object_server.remove::<TargetInterface, String>(path.clone())
);
if generic.is_err() || target.is_err() {
log::debug!("Failed to stop dbus interface: {path} generic: {generic:?} type-specific: {target:?}");
} else {
log::debug!("Stopped dbus interface for {path}");
};
}
});
}
}
Expand Down
48 changes: 34 additions & 14 deletions src/input/target/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use horipad_steam::HoripadSteamDevice;
use thiserror::Error;
use tokio::sync::mpsc::{self, error::TryRecvError};

use crate::dbus::interface::target::gamepad::TargetGamepadInterface;
use crate::dbus::interface::target::{gamepad::TargetGamepadInterface, TargetInterface};

use super::{
capability::Capability,
Expand Down Expand Up @@ -244,17 +244,31 @@ impl TryFrom<&str> for TargetDeviceTypeId {
/// a composite device, and are sent to a target device to be emitted.
pub trait TargetInputDevice {
/// Start the DBus interface for this target device
fn start_dbus_interface(&mut self, dbus: Connection, path: String, client: TargetDeviceClient) {
fn start_dbus_interface(
&mut self,
dbus: Connection,
path: String,
client: TargetDeviceClient,
type_id: String,
) {
log::debug!("Starting dbus interface: {path}");
log::trace!("Using device client: {client:?}");
tokio::task::spawn(async move {
let name = "Gamepad".to_string();
let generic_interface = TargetInterface::new(name.clone(), type_id);
let iface = TargetGamepadInterface::new(name);
if let Err(e) = dbus.object_server().at(path.clone(), iface).await {
log::debug!("Failed to start dbus interface {path}: {e:?}");

let object_server = dbus.object_server();
let (gen_result, result) = tokio::join!(
object_server.at(path.clone(), generic_interface),
object_server.at(path.clone(), iface)
);

if gen_result.is_err() || result.is_err() {
log::debug!("Failed to start dbus interface: {path} generic: {gen_result:?} type-specific: {result:?}");
} else {
log::debug!("Started dbus interface on {path}");
};
log::debug!("Started dbus interface: {path}");
}
});
}

Expand All @@ -280,15 +294,16 @@ pub trait TargetInputDevice {
fn stop_dbus_interface(&mut self, dbus: Connection, path: String) {
log::debug!("Stopping dbus interface for {path}");
tokio::task::spawn(async move {
let result = dbus
.object_server()
.remove::<TargetGamepadInterface, String>(path.clone())
.await;
if let Err(e) = result {
log::error!("Failed to stop dbus interface {path}: {e:?}");
let object_server = dbus.object_server();
let (target, generic) = tokio::join!(
object_server.remove::<TargetGamepadInterface, String>(path.clone()),
object_server.remove::<TargetInterface, String>(path.clone())
);
if generic.is_err() || target.is_err() {
log::debug!("Failed to stop dbus interface: {path} generic: {generic:?} type-specific: {target:?}");
} else {
log::debug!("Stopped dbus interface for {path}");
};
}
});
}

Expand Down Expand Up @@ -410,7 +425,12 @@ impl<T: TargetInputDevice + TargetOutputDevice + Send + 'static> TargetDriver<T>
let mut implementation = self.implementation.lock().unwrap();

// Start the DBus interface for the device
implementation.start_dbus_interface(self.dbus.clone(), dbus_path.clone(), client);
implementation.start_dbus_interface(
self.dbus.clone(),
dbus_path.clone(),
client,
self.type_id.as_str().to_owned(),
);

log::debug!("Target device running: {dbus_path}");
loop {
Expand Down
40 changes: 27 additions & 13 deletions src/input/target/mouse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use evdev::{
use zbus::Connection;

use crate::{
dbus::interface::target::mouse::TargetMouseInterface,
dbus::interface::target::{mouse::TargetMouseInterface, TargetInterface},
input::{
capability::{Capability, Mouse, MouseButton},
composite_device::client::CompositeDeviceClient,
Expand Down Expand Up @@ -138,15 +138,28 @@ impl MouseDevice {
}

impl TargetInputDevice for MouseDevice {
fn start_dbus_interface(&mut self, dbus: Connection, path: String, client: TargetDeviceClient) {
fn start_dbus_interface(
&mut self,
dbus: Connection,
path: String,
client: TargetDeviceClient,
type_id: String,
) {
log::debug!("Starting dbus interface: {path}");
tokio::task::spawn(async move {
let generic_interface = TargetInterface::new("Mouse".into(), type_id);
let iface = TargetMouseInterface::new(client);
if let Err(e) = dbus.object_server().at(path.clone(), iface).await {
log::debug!("Failed to start dbus interface {path}: {e:?}");

let gen_result = dbus
.object_server()
.at(path.clone(), generic_interface)
.await;
let result = dbus.object_server().at(path.clone(), iface).await;
if gen_result.is_err() || result.is_err() {
log::debug!("Failed to start dbus interface: {path} generic: {gen_result:?} type-specific: {result:?}");
} else {
log::debug!("Started dbus interface on {path}");
};
log::debug!("Started dbus interface: {path}");
}
});
}

Expand Down Expand Up @@ -188,15 +201,16 @@ impl TargetInputDevice for MouseDevice {
fn stop_dbus_interface(&mut self, dbus: Connection, path: String) {
log::debug!("Stopping dbus interface for {path}");
tokio::task::spawn(async move {
let result = dbus
.object_server()
.remove::<TargetMouseInterface, String>(path.clone())
.await;
if let Err(e) = result {
log::error!("Failed to stop dbus interface {path}: {e:?}");
let object_server = dbus.object_server();
let (target, generic) = tokio::join!(
object_server.remove::<TargetMouseInterface, String>(path.clone()),
object_server.remove::<TargetInterface, String>(path.clone())
);
if generic.is_err() || target.is_err() {
log::debug!("Failed to stop dbus interface: {path} generic: {generic:?} type-specific: {target:?}");
} else {
log::debug!("Stopped dbus interface for {path}");
};
}
});
}

Expand Down

0 comments on commit b3d00bd

Please sign in to comment.