diff --git a/drivers/input/usbhidd/src/main.rs b/drivers/input/usbhidd/src/main.rs index e37b6795ff..80ffcfebf0 100644 --- a/drivers/input/usbhidd/src/main.rs +++ b/drivers/input/usbhidd/src/main.rs @@ -360,6 +360,10 @@ fn main() -> Result<()> { let mut mouse_dy = 0i32; let mut scroll_y = 0i32; let mut buttons = last_buttons; + // Gamepad state (Linux 7.1 hid-input.c: BTN_GAMEPAD + ABS_X/Y/Z/Rx/Ry/Rz) + let mut gamepad_axes: [i32; 6] = [0i32; 6]; + let mut gamepad_buttons: u32 = 0; + let mut hat_switch: i8 = -1; for event in handler .handle(&report_buffer) .expect("failed to parse report") @@ -371,12 +375,14 @@ fn main() -> Result<()> { mouse_dx += event.value as i32; } else { mouse_pos.0 = event.value as i32; + gamepad_axes[0] = event.value as i32; } } else if event.usage == GenericDesktopUsage::Y as u16 { if event.relative { mouse_dy += event.value as i32; } else { mouse_pos.1 = event.value as i32; + gamepad_axes[1] = event.value as i32; } } else if event.usage == GenericDesktopUsage::Wheel as u16 { //TODO: what is X scroll? @@ -385,6 +391,24 @@ fn main() -> Result<()> { } else { log::warn!("absolute mouse wheel not supported"); } + // Gamepad axes per Linux 7.1 hid-input.c map_abs(): + // 0x30 = X (left stick X) — already handled above for mouse + // 0x31 = Y (left stick Y) + // 0x32 = Z (left trigger or secondary) + // 0x33 = Rx (right stick X) + // 0x34 = Ry (right stick Y) + // 0x35 = Rz (right trigger) + // 0x39 = Hat Switch (dpad, Linux maps to ABS_HAT0X) + } else if event.usage == 0x32 { + gamepad_axes[2] = event.value as i32; + } else if event.usage == 0x33 { + gamepad_axes[3] = event.value as i32; + } else if event.usage == 0x34 { + gamepad_axes[4] = event.value as i32; + } else if event.usage == 0x35 { + gamepad_axes[5] = event.value as i32; + } else if event.usage == 0x39 { + hat_switch = event.value as i8; } else { log::info!( "unsupported generic desktop usage 0x{:X}:0x{:X} value {}", @@ -415,11 +439,20 @@ fn main() -> Result<()> { } send_key_event(&mut display, event.usage_page, event.usage, pressed); } else if event.usage_page == UsagePage::Button as u16 { - if event.usage > 0 && event.usage as usize <= buttons.len() { - buttons[event.usage as usize - 1] = event.value != 0; + if event.usage > 0 && event.usage <= 32 { + let bit = 1u32 << (event.usage - 1); + if event.value != 0 { + gamepad_buttons |= bit; + } else { + gamepad_buttons &= !bit; + } + // Also track first 3 as mouse buttons for backward compat + if event.usage <= 3 { + buttons[event.usage as usize - 1] = event.value != 0; + } } else { log::info!( - "unsupported buttons usage 0x{:X}:0x{:X} value {}", + "unsupported button usage 0x{:X}:0x{:X} value {}", event.usage_page, event.usage, event.value