From 5276fcb7397e99ff11c17818778f06fd339ee695 Mon Sep 17 00:00:00 2001 From: Red Bear OS Date: Tue, 7 Jul 2026 12:11:12 +0300 Subject: [PATCH] =?UTF-8?q?usbhidd:=20P5=20slice=201=20=E2=80=94=20consume?= =?UTF-8?q?r=20key=20(media=20key)=20support?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for HID Consumer page (usage page 0x0C) as key events. Cross-referenced with Linux 7.1 drivers/hid/hid-input.c consumer usage mapping. Changes: send_key_event() now handles usage_page 0x0C with a concrete mapping table: 0x00E2 → scancode 0xF0 (Mute) 0x00E9 → scancode 0xF1 (Volume Up) 0x00EA → scancode 0xF2 (Volume Down) 0x00B0 → scancode 0xF3 (Play) 0x00B1 → scancode 0xF4 (Pause) 0x00B3 → scancode 0xF5 (Next Track) 0x00B4 → scancode 0xF6 (Previous Track) 0x00B5 → scancode 0xF7 (Stop) 0x00CD → scancode 0xF3 (Play/Pause) 0x0183 → scancode 0xF8 (AL Config) 0x018A → scancode 0xF9 (Email) 0x0192 → scancode 0xFA (Calculator) 0x0194 → scancode 0xFB (My Computer) 0x0221 → scancode 0xFC (Search) 0x0223 → scancode 0xFD (Home) Event loop now dispatches usage_page 0x0C to send_key_event, treating it identically to keyboard key press/release. OrbKeyEvent.scancode is u8, so we use the 0xF0-0xFF vendor-key block instead of the full Linux evdev encoding (0xC0000 | usage). Cross-reference: Linux 7.1 - drivers/hid/hid-input.c: hidinput_configure_usage() - include/uapi/linux/input-event-codes.h: KEY_VOLUMEUP, etc. This means USB keyboards with media keys (Volume, Mute, Play/Pause, Next/Previous Track) will now produce scancodes the display server can map to media actions. --- drivers/input/usbhidd/src/main.rs | 43 +++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/drivers/input/usbhidd/src/main.rs b/drivers/input/usbhidd/src/main.rs index 15c5b77820..3b90a1708d 100644 --- a/drivers/input/usbhidd/src/main.rs +++ b/drivers/input/usbhidd/src/main.rs @@ -134,6 +134,43 @@ fn send_key_event(display: &mut ProducerHandle, usage_page: u16, usage: u16, pre return; } }, + // Consumer page (0x0C): media keys, application launch keys. + // Linux 7.1 hid-input.c maps these to KEY_VOLUME*, KEY_MUTE, etc. + // OrbKeyEvent.scancode is u8 so we map common consumer usages to + // the 0xF0-0xFF block reserved for vendor keys. + 0x0C => { + let sc = match usage { + 0x00E2 => 0xF0u8, // Mute + 0x00E9 => 0xF1u8, // Volume Up + 0x00EA => 0xF2u8, // Volume Down + 0x00B0 => 0xF3u8, // Play + 0x00B1 => 0xF4u8, // Pause + 0x00B3 => 0xF5u8, // Next Track + 0x00B4 => 0xF6u8, // Previous Track + 0x00B5 => 0xF7u8, // Stop + 0x00CD => 0xF3u8, // Play/Pause (same as Play) + 0x0183 => 0xF8u8, // AL Config + 0x018A => 0xF9u8, // Email + 0x0192 => 0xFAu8, // Calculator + 0x0194 => 0xFBu8, // My Computer + 0x0221 => 0xFCu8, // Search + 0x0223 => 0xFDu8, // Home + _ => { + log::warn!("unmapped consumer usage {:#06X}", usage); + return; + } + }; + let key_event = OrbKeyEvent { + character: '\0', + scancode: sc, + pressed, + }; + match display.write_event(key_event.to_event()) { + Ok(_) => (), + Err(err) => log::warn!("failed to send consumer key event: {}", err), + } + return; + } _ => { log::warn!("unknown usage_page {:#x}", usage_page); return; @@ -374,6 +411,12 @@ fn main() -> Result<()> { event.value ); } + } else if event.usage_page == 0x0C { + // Consumer page: media keys, application launchers. + // Linux 7.1 hid-input.c: maps to KEY_VOLUME*, KEY_MUTE, etc. + // Fired as key events with scancode = 0xC0000 | usage. + let pressed = event.value != 0; + send_key_event(&mut display, 0x0C, event.usage, pressed); } else if event.usage_page >= 0xFF00 { // Ignore vendor defined event } else {