#usb-hid #usb #hid #ps2 #keyboard #key #key-mapping

no-std keycode

A Rust crate for translating keycodes based on Chrome's mapping of keys

9 releases (1 stable)

1.0.0 Mar 19, 2025
0.4.0 Sep 1, 2022
0.3.0 Jan 2, 2020
0.2.2 Jul 8, 2019
0.1.1 Jan 27, 2019

#92 in Hardware support

Download history 366/week @ 2024-12-06 406/week @ 2024-12-13 157/week @ 2024-12-20 164/week @ 2024-12-27 627/week @ 2025-01-03 393/week @ 2025-01-10 472/week @ 2025-01-17 295/week @ 2025-01-24 880/week @ 2025-01-31 763/week @ 2025-02-07 524/week @ 2025-02-14 629/week @ 2025-02-21 711/week @ 2025-02-28 419/week @ 2025-03-07 729/week @ 2025-03-14 374/week @ 2025-03-21

2,365 downloads per month
Used in 5 crates (4 directly)

MIT license

17KB
198 lines

keycode

A Rust crate for translating keycodes based on Chrome's mapping of keys.

Easily convert, generate, listen for, or map keycodes for Linux, Windows, Mac, USB, and browsers! Includes a struct to manage the state of pressed keys and generate USB HID reports. Can be used for #![no_std] crates.

Source Data

Source of keycodes data:

How to update source file:

curl -sL 'https://chromium.googlesource.com/chromium/src/+/master/ui/events/keycodes/dom/keycode_converter_data.inc?format=TEXT' | base64 --decode > keycode_converter_data.inc

Examples

Get a key mapping

use keycode::{KeyMap, KeyMappingId};

// Check the USB HID value of the "a" key
fn main() {
    let a = KeyMap::from(KeyMappingId::UsA);
    assert_eq!(a.usb, 0x0004);
    assert_eq!(a.evdev, 0x001e);
    assert_eq!(a.xkb, 0x0026);
    assert_eq!(a.win, 0x001e);
    assert_eq!(a.mac, 0x0000);
}

Generate a USB HID report

use keycode::{KeyboardState, KeyMap, KeyMappingId, KeyState};

// Press and release the "A" key
fn main() {
    // Generate a keyboard state with n-key rollover
    let mut keyboard_state = KeyboardState::new(None);

    // Get key mappings
    let a = KeyMap::from(KeyMappingId::UsA);
    let shift = KeyMap::from(KeyMappingId::ShiftLeft);

    // USB HID report for "no keys pressed"
    assert_eq!(keyboard_state.usb_input_report(), &[0; 8]);

    // Press "shift" and "a" keys
    keyboard_state.update_key(a, KeyState::Pressed);
    keyboard_state.update_key(shift, KeyState::Pressed);

    // USB HID report for "'A' is pressed"
    assert_eq!(
        keyboard_state.usb_input_report(),
        &[shift.modifier.unwrap().bits(), 0, a.usb as u8, 0, 0, 0, 0, 0]
    );

    // Release "shift" and "a" keys
    keyboard_state.update_key(a, KeyState::Released);
    keyboard_state.update_key(shift, KeyState::Released);

    // USB HID report for "no keys pressed"
    assert_eq!(keyboard_state.usb_input_report(), &[0; 8]);
}

Supported Rust Versions

Requires Rust 1.34.0 or newer due to use of TryFrom.

Developing

I recommend to use Nix and the flake within this repo:

nix develop

Dependencies

~380–650KB
~13K SLoC