feat(gamepad): virtual DualSense on the Windows host (UMDF shm channel)

Wire the Windows UMDF DualSense driver into the host as a real pad backend, so a
client that requests a DualSense gets a genuine one on a Windows host (instead of
folding to Xbox 360).

- Extract the transport-independent DualSense contract (DsState + from_gamepad,
  serialize_state, parse_ds_output, DUALSENSE_RDESC, feature blobs, DS_* consts)
  out of the Linux-only UHID backend into inject/dualsense_proto.rs, shared by both
  platforms; dualsense.rs is now just the /dev/uhid plumbing.
- Add inject/dualsense_windows.rs: DualSenseWindowsManager mirroring the Linux
  DualSenseManager (same new/handle/apply_rich/pump/heartbeat surface) over a
  DsWinPad that creates the Global\pfds-shm-<idx> section (CreateFileMappingW +
  SDDL D:(A;;GA;;;WD) so WUDFHost can open it), writes serialize_state -> input
  slot, polls output_seq -> parse_ds_output -> rumble/hidout callbacks.
- Un-gate the seam: PadBackend::DualSenseWindows arm; pick_gamepad gains a
  windows flag (DualSense honored on linux||windows; DS4/Xbox One stay Linux-only).

Verified: Linux cargo test gamepad_resolution_precedence + clippy clean; Windows
cargo check + clippy -D warnings clean (on the RTX box). Device lifecycle still
uses an out-of-band devnode (devgen/installer); SwDeviceCreate per session is next.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-21 20:36:53 +00:00
parent aa159df33f
commit 4a73102d48
8 changed files with 896 additions and 487 deletions
+7
View File
@@ -423,6 +423,13 @@ fn gs_button_to_evdev(b: u32) -> Option<u32> {
#[cfg(target_os = "linux")]
pub mod dualsense;
/// Transport-independent DualSense HID contract, shared by the Linux UHID backend ([`dualsense`])
/// and the Windows UMDF-driver backend ([`dualsense_windows`]).
#[cfg(any(target_os = "linux", target_os = "windows"))]
pub mod dualsense_proto;
/// Windows: virtual DualSense via the UMDF minidriver + a shared-memory host channel.
#[cfg(target_os = "windows")]
pub mod dualsense_windows;
#[cfg(target_os = "linux")]
pub mod dualshock4;
#[cfg(target_os = "linux")]