1use ferroui_base::input::PhysicalKey;
9
10pub 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 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 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}