Skip to content

Commit

Permalink
fix(QuickAccess): Implement quick access in all gamepad target devices.
Browse files Browse the repository at this point in the history
  • Loading branch information
pastaq committed Jul 27, 2024
1 parent f4581ed commit 5d274d9
Show file tree
Hide file tree
Showing 8 changed files with 176 additions and 21 deletions.
2 changes: 1 addition & 1 deletion rootfs/usr/share/inputplumber/devices/50-legion_go.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,6 @@ source_devices:

# The target input device(s) that the virtual device profile can use
target_devices:
- deck
- xbox-elite
- mouse
- keyboard
2 changes: 1 addition & 1 deletion rootfs/usr/share/inputplumber/devices/50-orangepi_neo.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ source_devices:

# The target input device(s) that the virtual device profile can use
target_devices:
- deck
- xbox-elite
- mouse
- keyboard

Expand Down
2 changes: 1 addition & 1 deletion rootfs/usr/share/inputplumber/devices/50-steam_deck.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ source_devices:

# The target input device(s) that the virtual device profile can use
target_devices:
- deck
- xbox-elite
- mouse
- keyboard
- touchscreen
9 changes: 0 additions & 9 deletions rootfs/usr/share/inputplumber/profiles/default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,6 @@ name: Default

# Profile mappings
mapping:
- name: QuickAccess
source_event:
gamepad:
button: QuickAccess
target_events:
- gamepad:
button: Guide
- gamepad:
button: South
- name: LeftTop
source_event:
gamepad:
Expand Down
38 changes: 36 additions & 2 deletions src/input/target/dualsense.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//! The DualSense implementation is based on the great work done by NeroReflex
//! and the ROGueENEMY project:
//! https://github.com/NeroReflex/ROGueENEMY/
use std::{cmp::Ordering, error::Error, fmt::Debug, fs::File};
use std::{cmp::Ordering, error::Error, fmt::Debug, fs::File, time::Duration};

use packed_struct::prelude::*;
use rand::Rng;
Expand Down Expand Up @@ -118,6 +118,7 @@ pub struct DualSenseDevice {
state: PackedInputDataReport,
timestamp: u8,
hardware: DualSenseHardware,
queued_events: Vec<ScheduledNativeEvent>,
}

impl DualSenseDevice {
Expand All @@ -128,6 +129,7 @@ impl DualSenseDevice {
state: PackedInputDataReport::Usb(USBPackedInputDataReport::new()),
timestamp: 0,
hardware,
queued_events: Vec::new(),
})
}

Expand Down Expand Up @@ -888,6 +890,33 @@ impl DualSenseDevice {
impl TargetInputDevice for DualSenseDevice {
fn write_event(&mut self, event: NativeEvent) -> Result<(), InputError> {
log::trace!("Received event: {event:?}");
// Check for QuickAccess, create chord for event.
let cap = event.as_capability();
if cap == Capability::Gamepad(Gamepad::Button(GamepadButton::QuickAccess)) {
let pressed = event.pressed();
let guide = NativeEvent::new(
Capability::Gamepad(Gamepad::Button(GamepadButton::Guide)),
event.get_value(),
);
let south = NativeEvent::new(
Capability::Gamepad(Gamepad::Button(GamepadButton::South)),
event.get_value(),
);

let (guide, south) = if pressed {
let guide = ScheduledNativeEvent::new(guide, Duration::from_millis(0));
let south = ScheduledNativeEvent::new(south, Duration::from_millis(80));
(guide, south)
} else {
let guide = ScheduledNativeEvent::new(guide, Duration::from_millis(160));
let south = ScheduledNativeEvent::new(south, Duration::from_millis(80));
(guide, south)
};

self.queued_events.push(guide);
self.queued_events.push(south);
return Ok(());
}
self.update_state(event);

// Check if the timestamp needs to be updated
Expand Down Expand Up @@ -916,6 +945,7 @@ impl TargetInputDevice for DualSenseDevice {
Capability::Gamepad(Gamepad::Button(GamepadButton::LeftStick)),
Capability::Gamepad(Gamepad::Button(GamepadButton::LeftTrigger)),
Capability::Gamepad(Gamepad::Button(GamepadButton::North)),
Capability::Gamepad(Gamepad::Button(GamepadButton::QuickAccess)),
Capability::Gamepad(Gamepad::Button(GamepadButton::RightBumper)),
Capability::Gamepad(Gamepad::Button(GamepadButton::RightPaddle1)),
Capability::Gamepad(Gamepad::Button(GamepadButton::RightPaddle2)),
Expand All @@ -934,8 +964,12 @@ impl TargetInputDevice for DualSenseDevice {
])
}

/// Returns any events in the queue up to the [TargetDriver]
fn scheduled_events(&mut self) -> Option<Vec<ScheduledNativeEvent>> {
None
if self.queued_events.is_empty() {
return None;
}
Some(self.queued_events.drain(..).collect())
}

fn stop(&mut self) -> Result<(), InputError> {
Expand Down
47 changes: 45 additions & 2 deletions src/input/target/xb360.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use nix::fcntl::{FcntlArg, OFlag};
use crate::input::capability::{Capability, Gamepad, GamepadAxis, GamepadButton, GamepadTrigger};
use crate::input::composite_device::client::CompositeDeviceClient;
use crate::input::event::evdev::EvdevEvent;
use crate::input::event::native::NativeEvent;
use crate::input::event::native::{NativeEvent, ScheduledNativeEvent};
use crate::input::output_capability::OutputCapability;
use crate::input::output_event::{OutputEvent, UinputOutputEvent};

Expand All @@ -23,13 +23,18 @@ use super::{InputError, OutputError, TargetInputDevice, TargetOutputDevice};
pub struct XBox360Controller {
device: VirtualDevice,
axis_map: HashMap<AbsoluteAxisCode, AbsInfo>,
queued_events: Vec<ScheduledNativeEvent>,
}

impl XBox360Controller {
pub fn new() -> Result<Self, Box<dyn Error>> {
let axis_map = XBox360Controller::get_abs_info();
let device = XBox360Controller::create_virtual_device(&axis_map)?;
Ok(Self { device, axis_map })
Ok(Self {
device,
axis_map,
queued_events: Vec::new(),
})
}

/// Return a hashmap of ABS information for this virtual device. This information
Expand Down Expand Up @@ -145,6 +150,35 @@ impl XBox360Controller {
impl TargetInputDevice for XBox360Controller {
fn write_event(&mut self, event: NativeEvent) -> Result<(), InputError> {
log::trace!("Received event: {event:?}");

// Check for QuickAccess, create chord for event.
let cap = event.as_capability();
if cap == Capability::Gamepad(Gamepad::Button(GamepadButton::QuickAccess)) {
let pressed = event.pressed();
let guide = NativeEvent::new(
Capability::Gamepad(Gamepad::Button(GamepadButton::Guide)),
event.get_value(),
);
let south = NativeEvent::new(
Capability::Gamepad(Gamepad::Button(GamepadButton::South)),
event.get_value(),
);

let (guide, south) = if pressed {
let guide = ScheduledNativeEvent::new(guide, Duration::from_millis(0));
let south = ScheduledNativeEvent::new(south, Duration::from_millis(80));
(guide, south)
} else {
let guide = ScheduledNativeEvent::new(guide, Duration::from_millis(160));
let south = ScheduledNativeEvent::new(south, Duration::from_millis(80));
(guide, south)
};

self.queued_events.push(guide);
self.queued_events.push(south);
return Ok(());
}

let evdev_events = self.translate_event(event);
self.device.emit(evdev_events.as_slice())?;
Ok(())
Expand All @@ -164,6 +198,7 @@ impl TargetInputDevice for XBox360Controller {
Capability::Gamepad(Gamepad::Button(GamepadButton::LeftStick)),
Capability::Gamepad(Gamepad::Button(GamepadButton::LeftTrigger)),
Capability::Gamepad(Gamepad::Button(GamepadButton::North)),
Capability::Gamepad(Gamepad::Button(GamepadButton::QuickAccess)),
Capability::Gamepad(Gamepad::Button(GamepadButton::RightBumper)),
Capability::Gamepad(Gamepad::Button(GamepadButton::RightStick)),
Capability::Gamepad(Gamepad::Button(GamepadButton::RightTrigger)),
Expand All @@ -175,6 +210,14 @@ impl TargetInputDevice for XBox360Controller {
Capability::Gamepad(Gamepad::Trigger(GamepadTrigger::RightTrigger)),
])
}

/// Returns any events in the queue up to the [TargetDriver]
fn scheduled_events(&mut self) -> Option<Vec<ScheduledNativeEvent>> {
if self.queued_events.is_empty() {
return None;
}
Some(self.queued_events.drain(..).collect())
}
}

impl TargetOutputDevice for XBox360Controller {
Expand Down
50 changes: 47 additions & 3 deletions src/input/target/xbox_elite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use nix::fcntl::{FcntlArg, OFlag};
use crate::input::capability::{Capability, Gamepad, GamepadAxis, GamepadButton, GamepadTrigger};
use crate::input::composite_device::client::CompositeDeviceClient;
use crate::input::event::evdev::EvdevEvent;
use crate::input::event::native::NativeEvent;
use crate::input::event::native::{NativeEvent, ScheduledNativeEvent};
use crate::input::output_capability::OutputCapability;
use crate::input::output_event::{OutputEvent, UinputOutputEvent};

Expand All @@ -23,13 +23,18 @@ use super::{InputError, OutputError, TargetInputDevice, TargetOutputDevice};
pub struct XboxEliteController {
device: VirtualDevice,
axis_map: HashMap<AbsoluteAxisCode, AbsInfo>,
queued_events: Vec<ScheduledNativeEvent>,
}

impl XboxEliteController {
pub fn new() -> Result<Self, Box<dyn Error>> {
let axis_map = XboxEliteController::get_abs_info();
let device = XboxEliteController::create_virtual_device(&axis_map)?;
Ok(Self { device, axis_map })
Ok(Self {
device,
axis_map,
queued_events: Vec::new(),
})
}

/// Return a hashmap of ABS information for this virtual device. This information
Expand Down Expand Up @@ -149,7 +154,37 @@ impl XboxEliteController {

impl TargetInputDevice for XboxEliteController {
fn write_event(&mut self, event: NativeEvent) -> Result<(), InputError> {
log::trace!("Received event: {event:?}");
log::debug!("Received event: {event:?}");

// Check for QuickAccess, create chord for event.
let cap = event.as_capability();
if cap == Capability::Gamepad(Gamepad::Button(GamepadButton::QuickAccess)) {
let pressed = event.pressed();
let guide = NativeEvent::new(
Capability::Gamepad(Gamepad::Button(GamepadButton::Guide)),
event.get_value(),
);
let south = NativeEvent::new(
Capability::Gamepad(Gamepad::Button(GamepadButton::South)),
event.get_value(),
);

let (guide, south) = if pressed {
let guide = ScheduledNativeEvent::new(guide, Duration::from_millis(0));
let south = ScheduledNativeEvent::new(south, Duration::from_millis(80));
(guide, south)
} else {
let guide = ScheduledNativeEvent::new(guide, Duration::from_millis(160));
let south = ScheduledNativeEvent::new(south, Duration::from_millis(80));
(guide, south)
};

self.queued_events.push(guide);
self.queued_events.push(south);
log::debug!("Added QAM Chord to queued events!");
return Ok(());
}

let evdev_events = self.translate_event(event);
self.device.emit(evdev_events.as_slice())?;
Ok(())
Expand All @@ -171,6 +206,7 @@ impl TargetInputDevice for XboxEliteController {
Capability::Gamepad(Gamepad::Button(GamepadButton::LeftStick)),
Capability::Gamepad(Gamepad::Button(GamepadButton::LeftTrigger)),
Capability::Gamepad(Gamepad::Button(GamepadButton::North)),
Capability::Gamepad(Gamepad::Button(GamepadButton::QuickAccess)),
Capability::Gamepad(Gamepad::Button(GamepadButton::RightBumper)),
Capability::Gamepad(Gamepad::Button(GamepadButton::RightPaddle1)),
Capability::Gamepad(Gamepad::Button(GamepadButton::RightPaddle2)),
Expand All @@ -185,6 +221,14 @@ impl TargetInputDevice for XboxEliteController {
Capability::Gamepad(Gamepad::Trigger(GamepadTrigger::RightTrigger)),
])
}

/// Returns any events in the queue up to the [TargetDriver]
fn scheduled_events(&mut self) -> Option<Vec<ScheduledNativeEvent>> {
if self.queued_events.is_empty() {
return None;
}
Some(self.queued_events.drain(..).collect())
}
}

impl TargetOutputDevice for XboxEliteController {
Expand Down
47 changes: 45 additions & 2 deletions src/input/target/xbox_series.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use nix::fcntl::{FcntlArg, OFlag};
use crate::input::capability::{Capability, Gamepad, GamepadAxis, GamepadButton, GamepadTrigger};
use crate::input::composite_device::client::CompositeDeviceClient;
use crate::input::event::evdev::EvdevEvent;
use crate::input::event::native::NativeEvent;
use crate::input::event::native::{NativeEvent, ScheduledNativeEvent};
use crate::input::output_capability::OutputCapability;
use crate::input::output_event::{OutputEvent, UinputOutputEvent};

Expand All @@ -23,13 +23,18 @@ use super::{InputError, OutputError, TargetInputDevice, TargetOutputDevice};
pub struct XboxSeriesController {
device: VirtualDevice,
axis_map: HashMap<AbsoluteAxisCode, AbsInfo>,
queued_events: Vec<ScheduledNativeEvent>,
}

impl XboxSeriesController {
pub fn new() -> Result<Self, Box<dyn Error>> {
let axis_map = XboxSeriesController::get_abs_info();
let device = XboxSeriesController::create_virtual_device(&axis_map)?;
Ok(Self { device, axis_map })
Ok(Self {
device,
axis_map,
queued_events: Vec::new(),
})
}

/// Return a hashmap of ABS information for this virtual device. This information
Expand Down Expand Up @@ -146,6 +151,35 @@ impl XboxSeriesController {
impl TargetInputDevice for XboxSeriesController {
fn write_event(&mut self, event: NativeEvent) -> Result<(), InputError> {
log::trace!("Received event: {event:?}");

// Check for QuickAccess, create chord for event.
let cap = event.as_capability();
if cap == Capability::Gamepad(Gamepad::Button(GamepadButton::QuickAccess)) {
let pressed = event.pressed();
let guide = NativeEvent::new(
Capability::Gamepad(Gamepad::Button(GamepadButton::Guide)),
event.get_value(),
);
let south = NativeEvent::new(
Capability::Gamepad(Gamepad::Button(GamepadButton::South)),
event.get_value(),
);

let (guide, south) = if pressed {
let guide = ScheduledNativeEvent::new(guide, Duration::from_millis(0));
let south = ScheduledNativeEvent::new(south, Duration::from_millis(80));
(guide, south)
} else {
let guide = ScheduledNativeEvent::new(guide, Duration::from_millis(160));
let south = ScheduledNativeEvent::new(south, Duration::from_millis(80));
(guide, south)
};

self.queued_events.push(guide);
self.queued_events.push(south);
return Ok(());
}

let evdev_events = self.translate_event(event);
self.device.emit(evdev_events.as_slice())?;
Ok(())
Expand All @@ -165,6 +199,7 @@ impl TargetInputDevice for XboxSeriesController {
Capability::Gamepad(Gamepad::Button(GamepadButton::LeftStick)),
Capability::Gamepad(Gamepad::Button(GamepadButton::LeftTrigger)),
Capability::Gamepad(Gamepad::Button(GamepadButton::North)),
Capability::Gamepad(Gamepad::Button(GamepadButton::QuickAccess)),
Capability::Gamepad(Gamepad::Button(GamepadButton::RightBumper)),
Capability::Gamepad(Gamepad::Button(GamepadButton::RightStick)),
Capability::Gamepad(Gamepad::Button(GamepadButton::RightTrigger)),
Expand All @@ -177,6 +212,14 @@ impl TargetInputDevice for XboxSeriesController {
Capability::Gamepad(Gamepad::Trigger(GamepadTrigger::RightTrigger)),
])
}

/// Returns any events in the queue up to the [TargetDriver]
fn scheduled_events(&mut self) -> Option<Vec<ScheduledNativeEvent>> {
if self.queued_events.is_empty() {
return None;
}
Some(self.queued_events.drain(..).collect())
}
}

impl TargetOutputDevice for XboxSeriesController {
Expand Down

0 comments on commit 5d274d9

Please sign in to comment.