usbhidd: P5 slice 1 — consumer key (media key) support

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.
This commit is contained in:
Red Bear OS
2026-07-07 12:11:12 +03:00
parent df509fe737
commit 5276fcb739
+43
View File
@@ -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 {