pc_keyboard/layouts/
us104.rs

1//! United States keyboard support
2
3use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers};
4
5/// A standard United States 101-key (or 104-key including Windows keys) keyboard.
6///
7/// Has a 1-row high Enter key, with Oem5 above (ANSI layout).
8pub struct Us104Key;
9
10impl KeyboardLayout for Us104Key {
11    fn map_keycode(
12        &self,
13        keycode: KeyCode,
14        modifiers: &Modifiers,
15        handle_ctrl: HandleControl,
16    ) -> DecodedKey {
17        let map_to_unicode = handle_ctrl == HandleControl::MapLettersToUnicode;
18        match keycode {
19            KeyCode::Oem8 => {
20                if modifiers.is_shifted() {
21                    DecodedKey::Unicode('~')
22                } else {
23                    DecodedKey::Unicode('`')
24                }
25            }
26            KeyCode::Escape => DecodedKey::Unicode(0x1B.into()),
27            KeyCode::Key1 => {
28                if modifiers.is_shifted() {
29                    DecodedKey::Unicode('!')
30                } else {
31                    DecodedKey::Unicode('1')
32                }
33            }
34            KeyCode::Key2 => {
35                if modifiers.is_shifted() {
36                    DecodedKey::Unicode('@')
37                } else {
38                    DecodedKey::Unicode('2')
39                }
40            }
41            KeyCode::Key3 => {
42                if modifiers.is_shifted() {
43                    DecodedKey::Unicode('#')
44                } else {
45                    DecodedKey::Unicode('3')
46                }
47            }
48            KeyCode::Key4 => {
49                if modifiers.is_shifted() {
50                    DecodedKey::Unicode('$')
51                } else {
52                    DecodedKey::Unicode('4')
53                }
54            }
55            KeyCode::Key5 => {
56                if modifiers.is_shifted() {
57                    DecodedKey::Unicode('%')
58                } else {
59                    DecodedKey::Unicode('5')
60                }
61            }
62            KeyCode::Key6 => {
63                if modifiers.is_shifted() {
64                    DecodedKey::Unicode('^')
65                } else {
66                    DecodedKey::Unicode('6')
67                }
68            }
69            KeyCode::Key7 => {
70                if modifiers.is_shifted() {
71                    DecodedKey::Unicode('&')
72                } else {
73                    DecodedKey::Unicode('7')
74                }
75            }
76            KeyCode::Key8 => {
77                if modifiers.is_shifted() {
78                    DecodedKey::Unicode('*')
79                } else {
80                    DecodedKey::Unicode('8')
81                }
82            }
83            KeyCode::Key9 => {
84                if modifiers.is_shifted() {
85                    DecodedKey::Unicode('(')
86                } else {
87                    DecodedKey::Unicode('9')
88                }
89            }
90            KeyCode::Key0 => {
91                if modifiers.is_shifted() {
92                    DecodedKey::Unicode(')')
93                } else {
94                    DecodedKey::Unicode('0')
95                }
96            }
97            KeyCode::OemMinus => {
98                if modifiers.is_shifted() {
99                    DecodedKey::Unicode('_')
100                } else {
101                    DecodedKey::Unicode('-')
102                }
103            }
104            KeyCode::OemPlus => {
105                if modifiers.is_shifted() {
106                    DecodedKey::Unicode('+')
107                } else {
108                    DecodedKey::Unicode('=')
109                }
110            }
111            KeyCode::Backspace => DecodedKey::Unicode(0x08.into()),
112            KeyCode::Tab => DecodedKey::Unicode(0x09.into()),
113            KeyCode::Q => {
114                if map_to_unicode && modifiers.is_ctrl() {
115                    DecodedKey::Unicode('\u{0011}')
116                } else if modifiers.is_caps() {
117                    DecodedKey::Unicode('Q')
118                } else {
119                    DecodedKey::Unicode('q')
120                }
121            }
122            KeyCode::W => {
123                if map_to_unicode && modifiers.is_ctrl() {
124                    DecodedKey::Unicode('\u{0017}')
125                } else if modifiers.is_caps() {
126                    DecodedKey::Unicode('W')
127                } else {
128                    DecodedKey::Unicode('w')
129                }
130            }
131            KeyCode::E => {
132                if map_to_unicode && modifiers.is_ctrl() {
133                    DecodedKey::Unicode('\u{0005}')
134                } else if modifiers.is_caps() {
135                    DecodedKey::Unicode('E')
136                } else {
137                    DecodedKey::Unicode('e')
138                }
139            }
140            KeyCode::R => {
141                if map_to_unicode && modifiers.is_ctrl() {
142                    DecodedKey::Unicode('\u{0012}')
143                } else if modifiers.is_caps() {
144                    DecodedKey::Unicode('R')
145                } else {
146                    DecodedKey::Unicode('r')
147                }
148            }
149            KeyCode::T => {
150                if map_to_unicode && modifiers.is_ctrl() {
151                    DecodedKey::Unicode('\u{0014}')
152                } else if modifiers.is_caps() {
153                    DecodedKey::Unicode('T')
154                } else {
155                    DecodedKey::Unicode('t')
156                }
157            }
158            KeyCode::Y => {
159                if map_to_unicode && modifiers.is_ctrl() {
160                    DecodedKey::Unicode('\u{0019}')
161                } else if modifiers.is_caps() {
162                    DecodedKey::Unicode('Y')
163                } else {
164                    DecodedKey::Unicode('y')
165                }
166            }
167            KeyCode::U => {
168                if map_to_unicode && modifiers.is_ctrl() {
169                    DecodedKey::Unicode('\u{0015}')
170                } else if modifiers.is_caps() {
171                    DecodedKey::Unicode('U')
172                } else {
173                    DecodedKey::Unicode('u')
174                }
175            }
176            KeyCode::I => {
177                if map_to_unicode && modifiers.is_ctrl() {
178                    DecodedKey::Unicode('\u{0009}')
179                } else if modifiers.is_caps() {
180                    DecodedKey::Unicode('I')
181                } else {
182                    DecodedKey::Unicode('i')
183                }
184            }
185            KeyCode::O => {
186                if map_to_unicode && modifiers.is_ctrl() {
187                    DecodedKey::Unicode('\u{000F}')
188                } else if modifiers.is_caps() {
189                    DecodedKey::Unicode('O')
190                } else {
191                    DecodedKey::Unicode('o')
192                }
193            }
194            KeyCode::P => {
195                if map_to_unicode && modifiers.is_ctrl() {
196                    DecodedKey::Unicode('\u{0010}')
197                } else if modifiers.is_caps() {
198                    DecodedKey::Unicode('P')
199                } else {
200                    DecodedKey::Unicode('p')
201                }
202            }
203            KeyCode::Oem4 => {
204                if modifiers.is_shifted() {
205                    DecodedKey::Unicode('{')
206                } else {
207                    DecodedKey::Unicode('[')
208                }
209            }
210            KeyCode::Oem6 => {
211                if modifiers.is_shifted() {
212                    DecodedKey::Unicode('}')
213                } else {
214                    DecodedKey::Unicode(']')
215                }
216            }
217            KeyCode::Oem7 => {
218                if modifiers.is_shifted() {
219                    DecodedKey::Unicode('|')
220                } else {
221                    DecodedKey::Unicode('\\')
222                }
223            }
224            KeyCode::A => {
225                if map_to_unicode && modifiers.is_ctrl() {
226                    DecodedKey::Unicode('\u{0001}')
227                } else if modifiers.is_caps() {
228                    DecodedKey::Unicode('A')
229                } else {
230                    DecodedKey::Unicode('a')
231                }
232            }
233            KeyCode::S => {
234                if map_to_unicode && modifiers.is_ctrl() {
235                    DecodedKey::Unicode('\u{0013}')
236                } else if modifiers.is_caps() {
237                    DecodedKey::Unicode('S')
238                } else {
239                    DecodedKey::Unicode('s')
240                }
241            }
242            KeyCode::D => {
243                if map_to_unicode && modifiers.is_ctrl() {
244                    DecodedKey::Unicode('\u{0004}')
245                } else if modifiers.is_caps() {
246                    DecodedKey::Unicode('D')
247                } else {
248                    DecodedKey::Unicode('d')
249                }
250            }
251            KeyCode::F => {
252                if map_to_unicode && modifiers.is_ctrl() {
253                    DecodedKey::Unicode('\u{0006}')
254                } else if modifiers.is_caps() {
255                    DecodedKey::Unicode('F')
256                } else {
257                    DecodedKey::Unicode('f')
258                }
259            }
260            KeyCode::G => {
261                if map_to_unicode && modifiers.is_ctrl() {
262                    DecodedKey::Unicode('\u{0007}')
263                } else if modifiers.is_caps() {
264                    DecodedKey::Unicode('G')
265                } else {
266                    DecodedKey::Unicode('g')
267                }
268            }
269            KeyCode::H => {
270                if map_to_unicode && modifiers.is_ctrl() {
271                    DecodedKey::Unicode('\u{0008}')
272                } else if modifiers.is_caps() {
273                    DecodedKey::Unicode('H')
274                } else {
275                    DecodedKey::Unicode('h')
276                }
277            }
278            KeyCode::J => {
279                if map_to_unicode && modifiers.is_ctrl() {
280                    DecodedKey::Unicode('\u{000A}')
281                } else if modifiers.is_caps() {
282                    DecodedKey::Unicode('J')
283                } else {
284                    DecodedKey::Unicode('j')
285                }
286            }
287            KeyCode::K => {
288                if map_to_unicode && modifiers.is_ctrl() {
289                    DecodedKey::Unicode('\u{000B}')
290                } else if modifiers.is_caps() {
291                    DecodedKey::Unicode('K')
292                } else {
293                    DecodedKey::Unicode('k')
294                }
295            }
296            KeyCode::L => {
297                if map_to_unicode && modifiers.is_ctrl() {
298                    DecodedKey::Unicode('\u{000C}')
299                } else if modifiers.is_caps() {
300                    DecodedKey::Unicode('L')
301                } else {
302                    DecodedKey::Unicode('l')
303                }
304            }
305            KeyCode::Oem1 => {
306                if modifiers.is_shifted() {
307                    DecodedKey::Unicode(':')
308                } else {
309                    DecodedKey::Unicode(';')
310                }
311            }
312            KeyCode::Oem3 => {
313                if modifiers.is_shifted() {
314                    DecodedKey::Unicode('"')
315                } else {
316                    DecodedKey::Unicode('\'')
317                }
318            }
319            // Enter gives LF, not CRLF or CR
320            KeyCode::Return => DecodedKey::Unicode(10.into()),
321            KeyCode::Z => {
322                if map_to_unicode && modifiers.is_ctrl() {
323                    DecodedKey::Unicode('\u{001A}')
324                } else if modifiers.is_caps() {
325                    DecodedKey::Unicode('Z')
326                } else {
327                    DecodedKey::Unicode('z')
328                }
329            }
330            KeyCode::X => {
331                if map_to_unicode && modifiers.is_ctrl() {
332                    DecodedKey::Unicode('\u{0018}')
333                } else if modifiers.is_caps() {
334                    DecodedKey::Unicode('X')
335                } else {
336                    DecodedKey::Unicode('x')
337                }
338            }
339            KeyCode::C => {
340                if map_to_unicode && modifiers.is_ctrl() {
341                    DecodedKey::Unicode('\u{0003}')
342                } else if modifiers.is_caps() {
343                    DecodedKey::Unicode('C')
344                } else {
345                    DecodedKey::Unicode('c')
346                }
347            }
348            KeyCode::V => {
349                if map_to_unicode && modifiers.is_ctrl() {
350                    DecodedKey::Unicode('\u{0016}')
351                } else if modifiers.is_caps() {
352                    DecodedKey::Unicode('V')
353                } else {
354                    DecodedKey::Unicode('v')
355                }
356            }
357            KeyCode::B => {
358                if map_to_unicode && modifiers.is_ctrl() {
359                    DecodedKey::Unicode('\u{0002}')
360                } else if modifiers.is_caps() {
361                    DecodedKey::Unicode('B')
362                } else {
363                    DecodedKey::Unicode('b')
364                }
365            }
366            KeyCode::N => {
367                if map_to_unicode && modifiers.is_ctrl() {
368                    DecodedKey::Unicode('\u{000E}')
369                } else if modifiers.is_caps() {
370                    DecodedKey::Unicode('N')
371                } else {
372                    DecodedKey::Unicode('n')
373                }
374            }
375            KeyCode::M => {
376                if map_to_unicode && modifiers.is_ctrl() {
377                    DecodedKey::Unicode('\u{000D}')
378                } else if modifiers.is_caps() {
379                    DecodedKey::Unicode('M')
380                } else {
381                    DecodedKey::Unicode('m')
382                }
383            }
384            KeyCode::OemComma => {
385                if modifiers.is_shifted() {
386                    DecodedKey::Unicode('<')
387                } else {
388                    DecodedKey::Unicode(',')
389                }
390            }
391            KeyCode::OemPeriod => {
392                if modifiers.is_shifted() {
393                    DecodedKey::Unicode('>')
394                } else {
395                    DecodedKey::Unicode('.')
396                }
397            }
398            KeyCode::Oem2 => {
399                if modifiers.is_shifted() {
400                    DecodedKey::Unicode('?')
401                } else {
402                    DecodedKey::Unicode('/')
403                }
404            }
405            KeyCode::Spacebar => DecodedKey::Unicode(' '),
406            KeyCode::Delete => DecodedKey::Unicode(127.into()),
407            KeyCode::NumpadDivide => DecodedKey::Unicode('/'),
408            KeyCode::NumpadMultiply => DecodedKey::Unicode('*'),
409            KeyCode::NumpadSubtract => DecodedKey::Unicode('-'),
410            KeyCode::Numpad7 => {
411                if modifiers.numlock {
412                    DecodedKey::Unicode('7')
413                } else {
414                    DecodedKey::RawKey(KeyCode::Home)
415                }
416            }
417            KeyCode::Numpad8 => {
418                if modifiers.numlock {
419                    DecodedKey::Unicode('8')
420                } else {
421                    DecodedKey::RawKey(KeyCode::ArrowUp)
422                }
423            }
424            KeyCode::Numpad9 => {
425                if modifiers.numlock {
426                    DecodedKey::Unicode('9')
427                } else {
428                    DecodedKey::RawKey(KeyCode::PageUp)
429                }
430            }
431            KeyCode::NumpadAdd => DecodedKey::Unicode('+'),
432            KeyCode::Numpad4 => {
433                if modifiers.numlock {
434                    DecodedKey::Unicode('4')
435                } else {
436                    DecodedKey::RawKey(KeyCode::ArrowLeft)
437                }
438            }
439            KeyCode::Numpad5 => DecodedKey::Unicode('5'),
440            KeyCode::Numpad6 => {
441                if modifiers.numlock {
442                    DecodedKey::Unicode('6')
443                } else {
444                    DecodedKey::RawKey(KeyCode::ArrowRight)
445                }
446            }
447            KeyCode::Numpad1 => {
448                if modifiers.numlock {
449                    DecodedKey::Unicode('1')
450                } else {
451                    DecodedKey::RawKey(KeyCode::End)
452                }
453            }
454            KeyCode::Numpad2 => {
455                if modifiers.numlock {
456                    DecodedKey::Unicode('2')
457                } else {
458                    DecodedKey::RawKey(KeyCode::ArrowDown)
459                }
460            }
461            KeyCode::Numpad3 => {
462                if modifiers.numlock {
463                    DecodedKey::Unicode('3')
464                } else {
465                    DecodedKey::RawKey(KeyCode::PageDown)
466                }
467            }
468            KeyCode::Numpad0 => {
469                if modifiers.numlock {
470                    DecodedKey::Unicode('0')
471                } else {
472                    DecodedKey::RawKey(KeyCode::Insert)
473                }
474            }
475            KeyCode::NumpadPeriod => {
476                if modifiers.numlock {
477                    DecodedKey::Unicode('.')
478                } else {
479                    DecodedKey::Unicode(127.into())
480                }
481            }
482            KeyCode::NumpadEnter => DecodedKey::Unicode(10.into()),
483            k => DecodedKey::RawKey(k),
484        }
485    }
486}
487
488#[cfg(test)]
489mod test {
490    use super::*;
491    use crate::{EventDecoder, ScancodeSet, ScancodeSet1};
492
493    #[test]
494    fn layout() {
495        // Codes taken from https://kbdlayout.info/kbdus/overview+scancodes?arrangement=ANSI104
496        let mut s = ScancodeSet1::new();
497        let mut dec = EventDecoder::new(Us104Key, HandleControl::Ignore);
498        let data = [
499            (0x29, '`'),
500            (0x02, '1'),
501            (0x03, '2'),
502            (0x04, '3'),
503            (0x05, '4'),
504            (0x06, '5'),
505            (0x07, '6'),
506            (0x08, '7'),
507            (0x09, '8'),
508            (0x0a, '9'),
509            (0x0b, '0'),
510            (0x0c, '-'),
511            (0x0d, '='),
512            (0x0f, '\t'),
513            (0x10, 'q'),
514            (0x11, 'w'),
515            (0x12, 'e'),
516            (0x13, 'r'),
517            (0x14, 't'),
518            (0x15, 'y'),
519            (0x16, 'u'),
520            (0x17, 'i'),
521            (0x18, 'o'),
522            (0x19, 'p'),
523            (0x1a, '['),
524            (0x1b, ']'),
525            (0x2b, '\\'),
526            (0x1e, 'a'),
527            (0x1f, 's'),
528            (0x20, 'd'),
529            (0x21, 'f'),
530            (0x22, 'g'),
531            (0x23, 'h'),
532            (0x24, 'j'),
533            (0x25, 'k'),
534            (0x26, 'l'),
535            (0x27, ';'),
536            (0x28, '\''),
537            (0x1c, '\n'),
538            (0x2c, 'z'),
539            (0x2d, 'x'),
540            (0x2e, 'c'),
541            (0x2f, 'v'),
542            (0x30, 'b'),
543            (0x31, 'n'),
544            (0x32, 'm'),
545            (0x33, ','),
546            (0x34, '.'),
547            (0x35, '/'),
548        ];
549        for (code, unicode) in data {
550            let ev = s.advance_state(code).unwrap().unwrap();
551            assert_eq!(Some(DecodedKey::Unicode(unicode)), dec.process_keyevent(ev));
552        }
553    }
554}