Skip to main content

ferroui_linuxframebuffer/input/ev_dev/
ev_dev_key_table.rs

1//! The kernel's key codes as physical keys.
2//!
3//! An addition (docs/porting/linux-framebuffer-platform.md, section 7):
4//! the reference reads no keys. The codes are those of
5//! `linux/input-event-codes.h`; they name positions on the keyboard, which
6//! is what a physical key is.
7
8use ferroui_base::input::PhysicalKey;
9
10/// The physical key of a key code (`KEY_*`), or `None` for a code that is
11/// not a key of a keyboard the framework knows.
12pub fn physical_key_from_ev_key(code: u16) -> PhysicalKey {
13    use PhysicalKey::*;
14    match code {
15        1 => Escape,
16        2 => Digit1,
17        3 => Digit2,
18        4 => Digit3,
19        5 => Digit4,
20        6 => Digit5,
21        7 => Digit6,
22        8 => Digit7,
23        9 => Digit8,
24        10 => Digit9,
25        11 => Digit0,
26        12 => Minus,
27        13 => Equal,
28        14 => Backspace,
29        15 => Tab,
30        16 => Q,
31        17 => W,
32        18 => E,
33        19 => R,
34        20 => T,
35        21 => Y,
36        22 => U,
37        23 => I,
38        24 => O,
39        25 => P,
40        26 => BracketLeft,
41        27 => BracketRight,
42        28 => Enter,
43        29 => ControlLeft,
44        30 => A,
45        31 => S,
46        32 => D,
47        33 => F,
48        34 => G,
49        35 => H,
50        36 => J,
51        37 => K,
52        38 => L,
53        39 => Semicolon,
54        40 => Quote,
55        41 => Backquote,
56        42 => ShiftLeft,
57        43 => Backslash,
58        44 => Z,
59        45 => X,
60        46 => C,
61        47 => V,
62        48 => B,
63        49 => N,
64        50 => M,
65        51 => Comma,
66        52 => Period,
67        53 => Slash,
68        54 => ShiftRight,
69        55 => NumPadMultiply,
70        56 => AltLeft,
71        57 => Space,
72        58 => CapsLock,
73        59 => F1,
74        60 => F2,
75        61 => F3,
76        62 => F4,
77        63 => F5,
78        64 => F6,
79        65 => F7,
80        66 => F8,
81        67 => F9,
82        68 => F10,
83        69 => NumLock,
84        70 => ScrollLock,
85        71 => NumPad7,
86        72 => NumPad8,
87        73 => NumPad9,
88        74 => NumPadSubtract,
89        75 => NumPad4,
90        76 => NumPad5,
91        77 => NumPad6,
92        78 => NumPadAdd,
93        79 => NumPad1,
94        80 => NumPad2,
95        81 => NumPad3,
96        82 => NumPad0,
97        83 => NumPadDecimal,
98        85 => Lang5,
99        86 => IntlBackslash,
100        87 => F11,
101        88 => F12,
102        89 => IntlRo,
103        90 => Lang3,
104        91 => Lang4,
105        92 => Convert,
106        93 => KanaMode,
107        94 => NonConvert,
108        95 => NumPadComma,
109        96 => NumPadEnter,
110        97 => ControlRight,
111        98 => NumPadDivide,
112        99 => PrintScreen,
113        100 => AltRight,
114        102 => Home,
115        103 => ArrowUp,
116        104 => PageUp,
117        105 => ArrowLeft,
118        106 => ArrowRight,
119        107 => End,
120        108 => ArrowDown,
121        109 => PageDown,
122        110 => Insert,
123        111 => Delete,
124        113 => AudioVolumeMute,
125        114 => AudioVolumeDown,
126        115 => AudioVolumeUp,
127        116 => Power,
128        117 => NumPadEqual,
129        119 => Pause,
130        121 => NumPadComma,
131        122 => Lang1,
132        123 => Lang2,
133        124 => IntlYen,
134        125 => MetaLeft,
135        126 => MetaRight,
136        127 => ContextMenu,
137        128 => BrowserStop,
138        129 => Again,
139        130 => Props,
140        131 => Undo,
141        133 => Copy,
142        134 => Open,
143        135 => Paste,
144        136 => Find,
145        137 => Cut,
146        138 => Help,
147        140 => LaunchApp2,
148        142 => Sleep,
149        143 => WakeUp,
150        155 => LaunchMail,
151        156 => BrowserFavorites,
152        158 => BrowserBack,
153        159 => BrowserForward,
154        161 => Eject,
155        163 => MediaTrackNext,
156        164 => MediaPlayPause,
157        165 => MediaTrackPrevious,
158        166 => MediaStop,
159        172 => BrowserHome,
160        173 => BrowserRefresh,
161        179 => NumPadParenLeft,
162        180 => NumPadParenRight,
163        183 => F13,
164        184 => F14,
165        185 => F15,
166        186 => F16,
167        187 => F17,
168        188 => F18,
169        189 => F19,
170        190 => F20,
171        191 => F21,
172        192 => F22,
173        193 => F23,
174        194 => F24,
175        217 => BrowserSearch,
176        226 => MediaSelect,
177        _ => None,
178    }
179}
180
181#[cfg(test)]
182mod tests {
183    use super::*;
184    use ferroui_base::input::Key;
185    use std::collections::HashSet;
186
187    #[test]
188    fn the_rows_of_a_keyboard_are_in_their_places() {
189        // KEY_Q .. KEY_P, KEY_A .. KEY_L, KEY_Z .. KEY_M.
190        let row = |codes: std::ops::RangeInclusive<u16>| -> String {
191            codes.map(|code| physical_key_from_ev_key(code).to_qwerty_key_symbol(false).unwrap()).collect()
192        };
193        assert_eq!(row(16..=25), "qwertyuiop");
194        assert_eq!(row(30..=38), "asdfghjkl");
195        assert_eq!(row(44..=50), "zxcvbnm");
196        assert_eq!(row(2..=11), "1234567890");
197        assert_eq!(row(71..=73), "789");
198    }
199
200    #[test]
201    fn the_keys_the_framework_names_are_the_kernels() {
202        for (code, key) in [
203            (1, Key::Escape),
204            (14, Key::Back),
205            (15, Key::Tab),
206            (28, Key::Return),
207            (57, Key::Space),
208            (59, Key::F1),
209            (88, Key::F12),
210            (96, Key::Return),
211            (102, Key::Home),
212            (103, Key::Up),
213            (105, Key::Left),
214            (106, Key::Right),
215            (108, Key::Down),
216            (111, Key::Delete),
217        ] {
218            assert_eq!(physical_key_from_ev_key(code).to_qwerty_key(), key, "code {code}");
219        }
220        assert_eq!(physical_key_from_ev_key(0), PhysicalKey::None);
221        // The buttons are not keys.
222        assert_eq!(physical_key_from_ev_key(0x110), PhysicalKey::None);
223    }
224
225    #[test]
226    fn no_two_codes_but_the_two_keypad_commas_share_a_key() {
227        let mut seen = HashSet::new();
228        for code in 0..0x300u16 {
229            let key = physical_key_from_ev_key(code);
230            if key != PhysicalKey::None && code != 121 {
231                assert!(seen.insert(key), "code {code} repeats {key:?}");
232            }
233        }
234        assert!(seen.len() > 140);
235    }
236}