sdl-keybridge
The universal Rosetta Stone for SDL keyboards.
A static correspondence table that exposes, for every key press, all of its parallel representations — physical scancode, logical keycode, textual or symbolic glyph, localized label — across all the layout × platform combinations supported by SDL.
No other Rust crate combines layout-awareness (AZERTY/QWERTZ/JCUKEN), i18n of named keys (Escape → Échap/Esc/エスケープ), and a cross-layout binding bridge via scancode as a universal pivot.
Philosophy: Rosette, not Champollion
This crate is a static lookup table (Rosette). It exposes parallel data and individual labels. It does not interpret and does not package presentation conventions.
Anything that interprets — formatting a Ctrl+Shift+A combo,
serializing a binding, rebasing a config from one layout to another — is
Champollion territory: the job of the consuming application. The
Rosette gives you the raw correspondence data; you pick the separator,
the ordering, the storage format.
The four public functions
use ;
let loc = new;
// 1. Forward lookup — every parallel representation in one pass.
let r = resolve;
assert_eq!; // Shift+A on AZERTY → 'Q'
// 2. Reverse lookup — find the scancode for a keycode in a layout.
let sc = scancode_for;
assert_eq!;
// 3. Platform-aware modifier label.
let s = modifier_label;
assert_eq!;
// 4. Parse a textual key name back into a keycode.
assert_eq!;
Cross-layout binding bridge
Two lines of consumer code translate a binding from one layout to another through scancode-as-pivot:
use ;
# let keycode_ru = from;
let loc = new;
let sc = scancode_for.unwrap;
let r = resolve;
// r.glyph_local is what the user sees on their French AZERTY keyboard.
Combo formatting (consumer-side)
There is no format_combo() in this crate — the separator and ordering
are yours. Assemble the individual labels the way your UI expects:
use ;
# let loc = new;
# let layout = "linux/fr-t-k0-azerty";
# let locale = "fr";
# let style = Textual;
let ctrl = modifier_label;
let r = resolve;
let combo = format!; // "Ctrl+q" on AZERTY
SDL2 + SDL3 compatibility
There are no sdl2 / sdl3 feature flags. The API takes primitive types
(u32 for scancodes / keycodes, u16 for the modifier bitmask), whose
numeric values are identical between SDL2 and SDL3 for every constant
exposed here. Use the same crate regardless of your SDL binding.
Locales
26 locales available as individual Cargo features:
| Code | Language | Code | Language | Code | Language |
|---|---|---|---|---|---|
en (default) |
English | fr |
Français | de |
Deutsch |
es |
Español | it |
Italiano | pt |
Português |
nl |
Nederlands | sv |
Svenska | fi |
Suomi |
pl |
Polski | cs |
Čeština | sk |
Slovenčina |
tr |
Türkçe | ru |
Русский | ar |
العربية |
hi |
हिन्दी | bn |
বাংলা | ur |
اردو |
zh-hans |
简体中文 | zh-hant |
繁體中文 | ja |
日本語 |
ko |
한국어 | id |
Bahasa Indonesia | sw |
Kiswahili |
vi |
Tiếng Việt | th |
ภาษาไทย |
Enable only what you need; use the aggregate all-locales feature to
pull them all in.
[]
= { = "0.1", = ["fr", "de", "ja"] }
Layouts
v0.1 ships hand-curated layouts for US QWERTY, French AZERTY, German QWERTZ, Russian JCUKEN and US Dvorak — each available for macOS, Windows and Linux. Layout ids follow the BCP 47 + CLDR keyboard extension convention:
mac/en-US-t-k0-qwerty,windows/en-US-t-k0-qwerty,linux/en-US-t-k0-qwertymac/fr-t-k0-azerty,windows/fr-t-k0-azerty,linux/fr-t-k0-azertymac/de-t-k0-qwertz,windows/de-t-k0-qwertz,linux/de-t-k0-qwertzwindows/ru-t-k0-jcuken,linux/ru-t-k0-jcuken,mac/ru-t-k0-jcukenmac/en-US-t-k0-dvorak,windows/en-US-t-k0-dvorak,linux/en-US-t-k0-dvorak
Full Unicode CLDR keyboard data import is on the roadmap — see CONTRIBUTING.md.
What this crate will not do (non-goals)
- Detect the current OS layout — the caller provides the BCP 47 id. No Rust solution reliably covers all five SDL platforms.
- Dead keys / text composition — a scancode + modifiers resolves to
one glyph. Composition (e.g.
^+e→ê) is the OS/IME's job, triggered bySDL_StartTextInput, not by us. - Package a
format_combo()— presentation conventions vary; the consumer assembles the labels it receives. - Package a binding serializer — config format is yours (JSON, INI, RON, binary, …).
License
Dual-licensed under either of
- Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.