Skip to main content

pc_keyboard/
lib.rs

1//! Driver for a PS/2 PC keyboard.
2//!
3//! Supports PS/2 Scan Code Set 1 and 2, on a variety of keyboard layouts. See
4//! [the OSDev Wiki](https://wiki.osdev.org/PS/2_Keyboard).
5//!
6//! ## Supports:
7//!
8//! -   Scancode Set 1 (from the i8042 PC keyboard controller)
9//! -   Scancode Set 2 (direct from the AT or PS/2 interface keyboard)
10//! -   Several keyboard layouts:
11//!
12//! | Name                                    | No. Keys | Description                                                              | Link                                                                                |
13//! | --------------------------------------- | -------- | ------------------------------------------------------------------------ | ----------------------------------------------------------------------------------- |
14//! | [`Us104Key`](layouts::Us104Key)         | 101/104  | North American standard English                                          | [Wikipedia](https://en.wikipedia.org/wiki/QWERTY#United_States)                     |
15//! | [`Uk105Key`](layouts::Uk105Key)         | 102/105  | United Kingdom standard English                                          | [Wikipedia](https://en.wikipedia.org/wiki/QWERTY#United_Kingdom)                    |
16//! | [`Azerty`](layouts::Azerty)             | 102/105  | Typically used in French locales                                         | [Wikipedia](https://en.wikipedia.org/wiki/AZERTY)                                   |
17//! | [`De105Key`](layouts::De105Key)         | 102/105  | German layout                                                            | [Wikipedia](https://en.wikipedia.org/wiki/QWERTZ)                                   |
18//! | [`FiSe105Key`](layouts::FiSe105Key)     | 102/105  | Finnish/Swedish layout                                                   | [Wikipedia](https://en.wikipedia.org/wiki/QWERTY#Finnish%E2%80%93Swedish)           |
19//! | [`No105Key`](layouts::No105Key)         | 102/105  | Norwegian layout                                                         | [Wikipedia](https://en.wikipedia.org/wiki/QWERTY#Norwegian)                         |
20//! | [`Jis109Key`](layouts::Jis109Key)       | 106/109  | JIS 109-key layout (Latin chars only)                                    | [Wikipedia](https://en.wikipedia.org/wiki/Japanese_input_method#Japanese_keyboards) |
21//! | [`Colemak`](layouts::Colemak)           | 101/104  | A keyboard layout designed to make typing more efficient and comfortable | [Wikipedia](https://en.wikipedia.org/wiki/Colemak)                                  |
22//! | [`Dvorak104Key`](layouts::Dvorak104Key) | 101/104  | The more 'ergonomic' alternative to QWERTY                               | [Wikipedia](https://en.wikipedia.org/wiki/Dvorak_keyboard_layout)                   |
23//! | [`DVP104Key`](layouts::DVP104Key)       | 101/104  | Dvorak for Programmers                                                   | [Wikipedia](https://en.wikipedia.org/wiki/Dvorak_keyboard_layout#Programmer_Dvorak) |
24//!
25//! 101/104 keys is ANSI layout (wide Enter key) and 102/105 keys is ISO layout
26//! (tall Enter key). The difference between 101 and 104 (and between 102 and
27//! 105) comes from the two Windows keys and the Menu key that were added when
28//! Windows 95 came out. JIS keyboards have extra keys, added by making the
29//! space-bar and backspace keys shorter.
30//!
31//! ## Usage
32//!
33//! There are three basic steps to handling keyboard input. Your application
34//! may bypass some of these.
35//!
36//! * `Ps2Decoder` - converts 11-bit PS/2 words into bytes, removing the start/stop
37//!   bits and checking the parity bits. Only needed if you talk to the PS/2
38//!   keyboard over GPIO pins and not required if you talk to the i8042 PC keyboard
39//!   controller.
40//! * `ScancodeSet` - converts from Scancode Set 1 (i8042 PC keyboard controller) or
41//!   Scancode Set 2 (raw PS/2 keyboard output) into a symbolic `KeyCode` and an
42//!   up/down `KeyState`.
43//! * `EventDecoder` - converts symbolic `KeyCode` and `KeyState` into a
44//!   Unicode characters (where possible) according to the currently selected
45//!   `KeyboardLayout`.
46//!
47//! There is also `PS2Keyboard` which combines the above three functions into a
48//! single object.
49//!
50//! See the [`examples`](./examples) folder for more details.
51//!
52//! ## Keycodes
53//!
54//! This crate uses symbolic keycodes to abstract over Scancode Set 1 and
55//! Scancode Set 2. They represented by the `KeyCode` enum. The scancodes can
56//! come from one of three supported physical keyboard layouts: 102/105 key
57//! ISO, 101/104 key ANSI and 106/109-key JIS. Note that the symbolic
58//! keycodes for letter keys are named after how the keys are used on a US or
59//! UK English Keyboard. If you use a French AZERTY layout, the `KeyCode::Q`
60//! key will produce the Unicode character `'A'`.
61//!
62//! ### 102/105 key [ISO](PhysicalKeyboard::Iso)
63//!
64//! This is the mapping of `KeyCode` to a 102/105-key ISO keyboard:
65//!
66//! ```text
67//! ┌────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐   ┌────┬────┬────┐
68//! │Esc │  │ F1 │ F2 │ F3 │ F4 │  │ F5 │ F6 │ F7 │ F8 │  │ F9 │F10 │F11 │F12 │   │PrSc│Scrl│PBrk│
69//! └────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘   └────┴────┴────┘
70//!
71//! ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐  ┌────┬────┬────┐  ┌────┬────┬────┬────┐
72//! │Oem8│Key1│Key2│Key3│Key4│Key5│Key6│Key7│Key8│Key9│Key0│Oem─│Oem+│Backspace│  │Inse│Home│PgUp│  │NumL│Num/│Num*│Num─│
73//! ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤  ├────┼────┼────┤  ├────┼────┼────┼────┤
74//! │ Tab │ Q  │ W  │ E  │ R  │ T  │ Y  │ U  │ I  │ O  │ P  │Oem4│Oem6│ Enter  │  │Dele│End │PgDo│  │Num7│Num8│Num9│    │
75//! ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐       │  └────┴────┴────┘  ├────┼────┼────┤Num+│
76//! │CapsLo│ A  │ S  │ D  │ F  │ G  │ H  │ J  │ K  │ L  │Oem1│Oem3│Oem7│       │                    │Num4│Num5│Num6│    │
77//! ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤       ┌────┐       ├────┼────┼────┼────┤
78//! │LShf│Oem5│ Z  │ X  │ C  │ V  │ B  │ N  │ M  │OemC│OemP│Oem2│   RShift     │       │ Up │       │Num1│Num2│Num3│    │
79//! ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤  ┌────┼────┼────┐  ├────┴────┼────┤Num │
80//! │LCtrl│LWin │ Alt │       Space                  │AltGr│RWin │ Menu │RCtrl │  │Left│Down│Righ│  │Num0     │NumP│Ente│
81//! └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘  └────┴────┴────┘  └─────────┴────┴────┘
82//! ```
83//!
84//! The 102-key is missing `LWin`, `RWin`, and `Menu`.
85//!
86//! (Reference: <https://kbdlayout.info/KBDUK/scancodes+virtualkeys?arrangement=ISO105>)
87//!
88//! ### 101/104 key [ANSI](PhysicalKeyboard::Ansi)
89//!
90//! This is the mapping of `KeyCode` to a 101/104-key ANSI keyboard:
91//!
92//! ```text
93//! ┌────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐   ┌────┬────┬────┐
94//! │Esc │  │ F1 │ F2 │ F3 │ F4 │  │ F5 │ F6 │ F7 │ F8 │  │ F9 │F10 │F11 │F12 │   │PrSc│Scrl│PBrk│
95//! └────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘   └────┴────┴────┘
96//!
97//! ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐  ┌────┬────┬────┐  ┌────┬────┬────┬────┐
98//! │Oem8│Key1│Key2│Key3│Key4│Key5│Key6│Key7│Key8│Key9│Key0│Oem─│Oem+│Backspace│  │Inse│Home│PgUp│  │NumL│Num/│Num*│Num─│
99//! ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤  ├────┼────┼────┤  ├────┼────┼────┼────┤
100//! │ Tab │ Q  │ W  │ E  │ R  │ T  │ Y  │ U  │ I  │ O  │ P  │Oem4│Oem6│  Oem7  │  │Dele│End │PgDo│  │Num7│Num8│Num9│    │
101//! ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤  └────┴────┴────┘  ├────┼────┼────┤Num+│
102//! │CapsLo│ A  │ S  │ D  │ F  │ G  │ H  │ J  │ K  │ L  │Oem1│Oem3│   Enter    │                    │Num4│Num5│Num6│    │
103//! ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤       ┌────┐       ├────┼────┼────┼────┤
104//! │ LShift  │ Z  │ X  │ C  │ V  │ B  │ N  │ M  │OemC│OemP│Oem2│   RShift     │       │ Up │       │Num1│Num2│Num3│    │
105//! ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤  ┌────┼────┼────┐  ├────┴────┼────┤Num │
106//! │LCtrl│LWin │ Alt │       Space                  │AltGr│RWin │ Menu │RCtrl │  │Left│Down│Righ│  │Num0     │NumP│Ente│
107//! └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘  └────┴────┴────┘  └─────────┴────┴────┘
108//! ```
109//!
110//! Note that the `Oem5` key is missing on the 104-key ANSI keyboard.
111//!
112//! The 101-key is also missing `LWin`, `RWin`, and `Menu`.
113//!
114//! (Reference: <https://kbdlayout.info/KBDUK/scancodes+virtualkeys?arrangement=ANSI104>)
115//!
116//! ### 106/109 key [JIS](PhysicalKeyboard::Jis)
117//!
118//! This is the mapping of `KeyCode` to a 106/109-key JIS keyboard:
119//!
120//! ```text
121//! ┌────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐   ┌────┬────┬────┐
122//! │Esc │  │ F1 │ F2 │ F3 │ F4 │  │ F5 │ F6 │ F7 │ F8 │  │ F9 │F10 │F11 │F12 │   │PrSc│Scrl│PBrk│
123//! └────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘   └────┴────┴────┘
124//!
125//! ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐  ┌────┬────┬────┐  ┌────┬────┬────┬────┐
126//! │Oem8│Key1│Key2│Key3│Key4│Key5│Key6│Key7│Key8│Key9│Key0│Oem─│Oem+│Om13│BkSp│  │Inse│Home│PgUp│  │NumL│Num/│Num*│Num─│
127//! ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤  ├────┼────┼────┤  ├────┼────┼────┼────┤
128//! │ Tab │ Q  │ W  │ E  │ R  │ T  │ Y  │ U  │ I  │ O  │ P  │Oem4│Oem6│ Enter  │  │Dele│End │PgDo│  │Num7│Num8│Num9│    │
129//! ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐       │  └────┴────┴────┘  ├────┼────┼────┤Num+│
130//! │CapsLo│ A  │ S  │ D  │ F  │ G  │ H  │ J  │ K  │ L  │Oem1│Oem3│Oem7│       │                    │Num4│Num5│Num6│    │
131//! ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤       ┌────┐       ├────┼────┼────┼────┤
132//! │LShift   │ Z  │ X  │ C  │ V  │ B  │ N  │ M  │OemC│OemP│Oem2│Oem12 │RShift │       │ Up │       │Num1│Num2│Num3│    │
133//! ├─────┬───┴─┬──┴──┬─┴───┬┴────┴────┴────┴────┴┬───┴─┬──┴──┬─┴──┬───┴┬──────┤  ┌────┼────┼────┐  ├────┴────┼────┤Num │
134//! │LCtrl│LWin │LAlt │Oem9 │ Space Bar           │Oem10│Oem11│RWin│Menu│RCtrl │  │Left│Down│Righ│  │Num0     │NumP│Ente│
135//! └─────┴─────┴─────┴─────┴─────────────────────┴─────┴─────┴────┴────┴──────┘  └────┴────┴────┘  └─────────┴────┴────┘
136//! ```
137//!
138//! Note that the `Oem5` is missing on the 109-key JIS layout, but `Oem9`
139//! (Muhenkan), `Oem10` (Henkan/Zenkouho), `Oem11`
140//! (Hiragana/Katakana), `Oem12` (Backslash) and `Oem13` (¥) are added.
141//!
142//! The 106-key is missing `LWin`, `RWin`, and `Menu`.
143//!
144//! (Reference: <https://kbdlayout.info/KBDUK/scancodes+virtualkeys?arrangement=OADG109A>)
145//!
146//! ### Conversion Table
147//!
148//! Scancode Set 1 and Scancode Set 2 can be losslessly converted. Indeed, this is
149//! what the i8042 keyboard controller in your PC does - it takes Scancode Set 2
150//! from the keyboard and provides Scancode Set 1 to the Operating System. This
151//! allowed them to change the keyboard design without breaking compatibility with
152//! any MS-DOS applications that read raw scancodes from the keyboard.
153//!
154//! This table shows the correspondence between our symbolic KeyCode, Scancode Set 1
155//! and Scancode Set 2. Any codes prefixed `0xE0` or `0xE1` are *extended* multi-byte
156//! scancodes. Typically these are keys that were not on the IBM PC and PC/XT
157//! keyboards so they they were added in such a way that if you ignored the 0xE0,
158//! you got a reasonable result anyway. For example `ArrowLeft` is `0xE04B` in
159//! Scancode Set 1 because `Numpad4` is `0x4B` and that was the left-arrow key on an
160//! IBM PC or PC/XT.
161//!
162//! | Symbolic Key   | Scancode Set 1 | Scancode Set 2 | USB HID |
163//! | -------------- | -------------- | -------------- | ------- |
164//! | Escape         | 0x01           | 0x76           | 0x29    |
165//! | F1             | 0x3B           | 0x05           | 0x3A    |
166//! | F2             | 0x3C           | 0x06           | 0x3B    |
167//! | F3             | 0x3D           | 0x04           | 0x3C    |
168//! | F4             | 0x3E           | 0x0C           | 0x3D    |
169//! | F5             | 0x3F           | 0x03           | 0x3E    |
170//! | F6             | 0x40           | 0x0B           | 0x3F    |
171//! | F7             | 0x41           | 0x83           | 0x40    |
172//! | F8             | 0x42           | 0x0A           | 0x41    |
173//! | F9             | 0x43           | 0x01           | 0x42    |
174//! | F10            | 0x44           | 0x09           | 0x43    |
175//! | F11            | 0x57           | 0x78           | 0x44    |
176//! | F12            | 0x58           | 0x07           | 0x45    |
177//! | PrintScreen    | 0xE037         | 0xE07C         | 0x46    |
178//! | SysRq          | 0x54           | 0x7F           | --      |
179//! | ScrollLock     | 0x46           | 0x7E           | 0x47    |
180//! | PauseBreak     | --             | --             | 0x48    |
181//! | -              | --             | --             | --      |
182//! | Oem8           | 0x29           | 0x0E           | 0x35    |
183//! | Key1           | 0x02           | 0x16           | 0x1E    |
184//! | Key2           | 0x03           | 0x1E           | 0x1F    |
185//! | Key3           | 0x04           | 0x26           | 0x20    |
186//! | Key4           | 0x05           | 0x25           | 0x21    |
187//! | Key5           | 0x06           | 0x2E           | 0x22    |
188//! | Key6           | 0x07           | 0x36           | 0x23    |
189//! | Key7           | 0x08           | 0x3D           | 0x24    |
190//! | Key8           | 0x09           | 0x3E           | 0x25    |
191//! | Key9           | 0x0A           | 0x46           | 0x26    |
192//! | Key0           | 0x0B           | 0x45           | 0x27    |
193//! | OemMinus       | 0x0C           | 0x4E           | 0x2D    |
194//! | OemPlus        | 0x0D           | 0x55           | 0x2E    |
195//! | Backspace      | 0x0E           | 0x66           | 0x2A    |
196//! | Insert         | 0xE052         | 0xE070         | 0x49    |
197//! | Home           | 0xE047         | 0xE06C         | 0x4A    |
198//! | PageUp         | 0xE049         | 0xE07D         | 0x4B    |
199//! | NumpadLock     | 0x45           | 0x77           | 0x53    |
200//! | NumpadDivide   | 0xE035         | 0xE04A         | 0x54    |
201//! | NumpadMultiply | 0x37           | 0x7C           | 0x55    |
202//! | NumpadSubtract | 0x4A           | 0x7B           | 0x56    |
203//! | -              | --             | --             | --      |
204//! | Tab            | 0x0F           | 0x0D           | 0x2B    |
205//! | Q              | 0x10           | 0x15           | 0x14    |
206//! | W              | 0x11           | 0x1D           | 0x1A    |
207//! | E              | 0x12           | 0x24           | 0x08    |
208//! | R              | 0x13           | 0x2D           | 0x15    |
209//! | T              | 0x14           | 0x2C           | 0x17    |
210//! | Y              | 0x15           | 0x35           | 0x1C    |
211//! | U              | 0x16           | 0x3C           | 0x18    |
212//! | I              | 0x17           | 0x43           | 0x0C    |
213//! | O              | 0x18           | 0x44           | 0x12    |
214//! | P              | 0x19           | 0x4D           | 0x13    |
215//! | Oem4           | 0x1A           | 0x54           | 0x2F    |
216//! | Oem6           | 0x1B           | 0x5B           | 0x30    |
217//! | Oem5           | 0x56           | 0x61           | 0x64    |
218//! | Oem7           | 0x2B           | 0x5D           | 0x31    |
219//! | Delete         | 0xE053         | 0xE071         | 0x4C    |
220//! | End            | 0xE04F         | 0xE069         | 0x4D    |
221//! | PageDown       | 0xE051         | 0xE07A         | 0x4E    |
222//! | Numpad7        | 0x47           | 0x6C           | 0x5F    |
223//! | Numpad8        | 0x48           | 0x75           | 0x60    |
224//! | Numpad9        | 0x49           | 0x7D           | 0x61    |
225//! | NumpadAdd      | 0x4E           | 0x79           | 0x57    |
226//! | -              | --             | --             | --      |
227//! | CapsLock       | 0x3A           | 0x58           | 0x39    |
228//! | A              | 0x1E           | 0x1C           | 0x04    |
229//! | S              | 0x1F           | 0x1B           | 0x16    |
230//! | D              | 0x20           | 0x23           | 0x07    |
231//! | F              | 0x21           | 0x2B           | 0x09    |
232//! | G              | 0x22           | 0x34           | 0x0A    |
233//! | H              | 0x23           | 0x33           | 0x0B    |
234//! | J              | 0x24           | 0x3B           | 0x0D    |
235//! | K              | 0x25           | 0x42           | 0x0E    |
236//! | L              | 0x26           | 0x4B           | 0x0F    |
237//! | Oem1           | 0x27           | 0x4C           | 0x33    |
238//! | Oem3           | 0x28           | 0x52           | 0x34    |
239//! | Return         | 0x1C           | 0x5A           | 0x28    |
240//! | Numpad4        | 0x4B           | 0x6B           | 0x5C    |
241//! | Numpad5        | 0x4C           | 0x73           | 0x5D    |
242//! | Numpad6        | 0x4D           | 0x74           | 0x5E    |
243//! | -              | --             | --             | --      |
244//! | LShift         | 0x2A           | 0x12           | 0xE1    |
245//! | Z              | 0x2C           | 0x1A           | 0x1D    |
246//! | X              | 0x2D           | 0x22           | 0x1B    |
247//! | C              | 0x2E           | 0x21           | 0x06    |
248//! | V              | 0x2F           | 0x2A           | 0x19    |
249//! | B              | 0x30           | 0x32           | 0x05    |
250//! | N              | 0x31           | 0x31           | 0x11    |
251//! | M              | 0x32           | 0x3A           | 0x10    |
252//! | OemComma       | 0x33           | 0x41           | 0x36    |
253//! | OemPeriod      | 0x34           | 0x49           | 0x37    |
254//! | Oem2           | 0x35           | 0x4A           | 0x38    |
255//! | RShift         | 0x36           | 0x59           | 0xE5    |
256//! | ArrowUp        | 0xE048         | 0xE075         | 0x52    |
257//! | Numpad1        | 0x4F           | 0x69           | 0x59    |
258//! | Numpad2        | 0x50           | 0x72           | 0x5A    |
259//! | Numpad3        | 0x51           | 0x7A           | 0x5B    |
260//! | NumpadEnter    | 0xE01C         | 0xE075         | 0x58    |
261//! | -              | --             | --             | --      |
262//! | LControl       | 0x1D           | 0x14           | 0xE0    |
263//! | LWin           | 0xE05B         | 0xE01F         | 0xE3    |
264//! | LAlt           | 0x38           | 0x11           | 0xE2    |
265//! | Spacebar       | 0x39           | 0x29           | 0x2C    |
266//! | RAltGr         | 0xE038         | 0xE011         | 0xE6    |
267//! | RWin           | 0xE05C         | 0xE027         | 0xE7    |
268//! | Apps           | 0xE05C         | 0xE02F         | 0x65    |
269//! | RControl       | 0xE01D         | 0xE014         | 0xE4    |
270//! | ArrowLeft      | 0xE04B         | 0xE06B         | 0x50    |
271//! | ArrowDown      | 0xE050         | 0xE072         | 0x51    |
272//! | ArrowRight     | 0xE04D         | 0xE074         | 0x52    |
273//! | Numpad0        | 0x52           | 0x70           | 0x62    |
274//! | NumpadPeriod   | 0x53           | 0x71           | 0x63    |
275//! | -              | --             | --             | --      |
276//! | Oem9           | 0x7B           | 0x67           | ??      |
277//! | Oem10          | 0x79           | 0x64           | ??      |
278//! | Oem11          | 0x70           | 0x13           | ??      |
279//! | Oem12          | 0x73           | 0x51           | ??      |
280//! | Oem13          | 0x7D           | 0x6A           | ??      |
281//! | -              | --             | --             | ??      |
282//! | PrevTrack      | 0xE010         | 0xE015         | ??      |
283//! | NextTrack      | 0xE019         | 0xE04D         | ??      |
284//! | Mute           | 0xE020         | 0xE023         | ??      |
285//! | Calculator     | 0xE021         | 0xE02B         | ??      |
286//! | Play           | 0xE022         | 0xE034         | ??      |
287//! | Stop           | 0xE024         | 0xE03B         | ??      |
288//! | VolumeDown     | 0xE02E         | 0xE021         | ??      |
289//! | VolumeUp       | 0xE030         | 0xE032         | ??      |
290//! | WWWHome        | 0xE032         | 0xE03A         | ??      |
291//! | TooManyKeys    | --             | 0x00           | ??      |
292//! | PowerOnTestOk  | --             | 0xAA           | ??      |
293//! | RControl2      | 0xE11D         | 0xE114         | ??      |
294//! | RAlt2          | 0xE02A         | 0xE012         | ??      |
295//!
296//! __Note 1:__ `PauseBreak` does not have a scancode because it's something we infer from a
297//! sequence of other keypresses (`NumLock` with `RControl2` held).
298//!
299//! __Note 2:__ `SysReq` doesn't have a key on the diagram, because the scancode is
300//! only generated when you do `Alt` + `PrintScreen`.
301
302#![cfg_attr(not(test), no_std)]
303
304// ****************************************************************************
305//
306// Modules
307//
308// ****************************************************************************
309
310pub mod layouts;
311
312mod scancodes;
313pub use crate::scancodes::{ScancodeSet1, ScancodeSet2, UsbModifiers};
314
315// ****************************************************************************
316//
317// Public Types
318//
319// ****************************************************************************
320
321/// Encapsulates decode/sampling logic, and handles state transitions and key events for PS/2 Keyboards
322#[derive(Debug)]
323pub struct PS2Keyboard<L, S>
324where
325    S: ScancodeSet,
326    L: KeyboardLayout,
327{
328    ps2_decoder: Ps2Decoder,
329    scancode_set: S,
330    event_decoder: EventDecoder<L>,
331}
332
333/// Handles decoding of IBM PS/2 Keyboard (and IBM PC/AT Keyboard) bit-streams.
334#[derive(Debug)]
335pub struct Ps2Decoder {
336    register: u16,
337    num_bits: u8,
338}
339
340/// Encapsulates HID frame handling, and handles state transitions and key events for USB HID Keyboards
341#[derive(Debug)]
342pub struct UsbKeyboard<L>
343where
344    L: KeyboardLayout,
345{
346    event_decoder: EventDecoder<L>,
347    last_report: UsbBootKeyboardReport,
348}
349
350/// A USB HID report as received from a keyboard in Boot Mode
351#[derive(Debug, Clone, Default)]
352pub struct UsbBootKeyboardReport {
353    /// Modifier Keys - the first byte in the report
354    pub modifiers: u8,
355    /// Keycodes - the last six bytes in the report
356    pub keys: [u8; 6],
357}
358
359/// An Iterator that produces ['KeyEvent'] values
360pub struct UsbKeyEventIter<'parent, L>
361where
362    L: KeyboardLayout,
363{
364    parent: &'parent mut UsbKeyboard<L>,
365    new_report: UsbBootKeyboardReport,
366}
367
368/// An Iterator that produces ['DecodedKey'] values, using an [`EventDecoder`]
369pub struct UsbDecodedKeyIter<'parent, L>
370where
371    L: KeyboardLayout,
372{
373    inner: UsbKeyEventIter<'parent, L>,
374}
375
376/// Converts KeyEvents into Unicode, according to the current Keyboard Layout
377#[derive(Debug)]
378pub struct EventDecoder<L>
379where
380    L: KeyboardLayout,
381{
382    handle_ctrl: HandleControl,
383    modifiers: Modifiers,
384    layout: L,
385}
386
387/// Indicates different error conditions.
388#[derive(Debug, PartialEq, Eq, Copy, Clone)]
389#[non_exhaustive]
390pub enum Error {
391    BadStartBit,
392    BadStopBit,
393    ParityError,
394    UnknownKeyCode,
395}
396
397/// Keycodes that can be generated by a keyboard.
398///
399/// We use this enum to abstract over Scan Code Set 1 and Scan Code Set 2.
400///
401/// See <https://kbdlayout.info/kbduk/shiftstates+virtualkeys/base>
402#[derive(Debug, PartialEq, Eq, Copy, Clone, PartialOrd, Ord)]
403#[repr(u8)]
404pub enum KeyCode {
405    // ========= Row 1 (the F-keys) =========
406    /// Top Left of the Keyboard
407    Escape,
408    /// Function Key F1
409    F1,
410    /// Function Key F2
411    F2,
412    /// Function Key F3
413    F3,
414    /// Function Key F4
415    F4,
416    /// Function Key F5
417    F5,
418    /// Function Key F6
419    F6,
420    /// Function Key F7
421    F7,
422    /// Function Key F8
423    F8,
424    /// Function Key F9
425    F9,
426    /// Function Key F10
427    F10,
428    /// Function Key F11
429    F11,
430    /// Function Key F12
431    F12,
432
433    /// The Print Screen Key
434    PrintScreen,
435    /// The Sys Req key (you get this keycode with Alt + PrintScreen)
436    SysRq,
437    /// The Scroll Lock key
438    ScrollLock,
439    /// The Pause/Break key
440    PauseBreak,
441
442    // ========= Row 2 (the numbers) =========
443    /// Symbol key to the left of `Key1`
444    Oem8,
445    /// Number Line, Digit 1
446    Key1,
447    /// Number Line, Digit 2
448    Key2,
449    /// Number Line, Digit 3
450    Key3,
451    /// Number Line, Digit 4
452    Key4,
453    /// Number Line, Digit 5
454    Key5,
455    /// Number Line, Digit 6
456    Key6,
457    /// Number Line, Digit 7
458    Key7,
459    /// Number Line, Digit 8
460    Key8,
461    /// Number Line, Digit 9
462    Key9,
463    /// Number Line, Digit 0
464    Key0,
465    /// US Minus/Underscore Key (right of 'Key0')
466    OemMinus,
467    /// US Equals/Plus Key (right of 'OemMinus')
468    OemPlus,
469    /// Backspace
470    Backspace,
471
472    /// Top Left of the Extended Block
473    Insert,
474    /// Top Middle of the Extended Block
475    Home,
476    /// Top Right of the Extended Block
477    PageUp,
478
479    /// The Num Lock key
480    NumpadLock,
481    /// The Numpad Divide (or Slash) key
482    NumpadDivide,
483    /// The Numpad Multiple (or Star) key
484    NumpadMultiply,
485    /// The Numpad Subtract (or Minus) key
486    NumpadSubtract,
487
488    // ========= Row 3 (QWERTY) =========
489    /// The Tab Key
490    Tab,
491    /// Letters, Top Row #1
492    Q,
493    /// Letters, Top Row #2
494    W,
495    /// Letters, Top Row #3
496    E,
497    /// Letters, Top Row #4
498    R,
499    /// Letters, Top Row #5
500    T,
501    /// Letters, Top Row #6
502    Y,
503    /// Letters, Top Row #7
504    U,
505    /// Letters, Top Row #8
506    I,
507    /// Letters, Top Row #9
508    O,
509    /// Letters, Top Row #10
510    P,
511    /// US ANSI Left-Square-Bracket key
512    Oem4,
513    /// US ANSI Right-Square-Bracket key
514    Oem6,
515    /// US ANSI Backslash Key / UK ISO Backslash Key
516    Oem5,
517    /// The UK/ISO Hash/Tilde key (ISO layout only)
518    Oem7,
519
520    /// The Delete key - bottom Left of the Extended Block
521    Delete,
522    /// The End key - bottom Middle of the Extended Block
523    End,
524    /// The Page Down key - -bottom Right of the Extended Block
525    PageDown,
526
527    /// The Numpad 7/Home key
528    Numpad7,
529    /// The Numpad 8/Up Arrow key
530    Numpad8,
531    /// The Numpad 9/Page Up key
532    Numpad9,
533    /// The Numpad Add/Plus key
534    NumpadAdd,
535
536    // ========= Row 4 (ASDF) =========
537    /// Caps Lock
538    CapsLock,
539    /// Letters, Middle Row #1
540    A,
541    /// Letters, Middle Row #2
542    S,
543    /// Letters, Middle Row #3
544    D,
545    /// Letters, Middle Row #4
546    F,
547    /// Letters, Middle Row #5
548    G,
549    /// Letters, Middle Row #6
550    H,
551    /// Letters, Middle Row #7
552    J,
553    /// Letters, Middle Row #8
554    K,
555    /// Letters, Middle Row #9
556    L,
557    /// The US ANSI Semicolon/Colon key
558    Oem1,
559    /// The US ANSI Single-Quote/At key
560    Oem3,
561
562    /// The Return Key
563    Return,
564
565    /// The Numpad 4/Left Arrow key
566    Numpad4,
567    /// The Numpad 5 Key
568    Numpad5,
569    /// The Numpad 6/Right Arrow key
570    Numpad6,
571
572    // ========= Row 5 (ZXCV) =========
573    /// Left Shift
574    LShift,
575    /// Letters, Bottom Row #1
576    Z,
577    /// Letters, Bottom Row #2
578    X,
579    /// Letters, Bottom Row #3
580    C,
581    /// Letters, Bottom Row #4
582    V,
583    /// Letters, Bottom Row #5
584    B,
585    /// Letters, Bottom Row #6
586    N,
587    /// Letters, Bottom Row #7
588    M,
589    /// US ANSI `,<` key
590    OemComma,
591    /// US ANSI `.>` Key
592    OemPeriod,
593    /// US ANSI `/?` Key
594    Oem2,
595    /// Right Shift
596    RShift,
597
598    /// The up-arrow in the inverted-T
599    ArrowUp,
600
601    /// Numpad 1/End Key
602    Numpad1,
603    /// Numpad 2/Arrow Down Key
604    Numpad2,
605    /// Numpad 3/Page Down Key
606    Numpad3,
607    /// Numpad Enter
608    NumpadEnter,
609
610    // ========= Row 6 (modifers and space bar) =========
611    /// The left-hand Control key
612    LControl,
613    /// The left-hand 'Windows' key
614    LWin,
615    /// The left-hand Alt key
616    LAlt,
617    /// The Space Bar
618    Spacebar,
619    /// The right-hand AltGr key
620    RAltGr,
621    /// The right-hand Win key
622    RWin,
623    /// The 'Apps' key (aka 'Menu' or 'Right-Click')
624    Apps,
625    /// The right-hand Control key
626    RControl,
627
628    /// The left-arrow in the inverted-T
629    ArrowLeft,
630    /// The down-arrow in the inverted-T
631    ArrowDown,
632    /// The right-arrow in the inverted-T
633    ArrowRight,
634
635    /// The Numpad 0/Insert Key
636    Numpad0,
637    /// The Numppad Period/Delete Key
638    NumpadPeriod,
639
640    // ========= JIS 109-key extra keys =========
641    /// Extra JIS key (0x7B)
642    Oem9,
643    /// Extra JIS key (0x79)
644    Oem10,
645    /// Extra JIS key (0x70)
646    Oem11,
647    /// Extra JIS symbol key (0x73)
648    Oem12,
649    /// Extra JIS symbol key (0x7D)
650    Oem13,
651
652    // ========= Extra Keys =========
653    /// Multi-media keys - Previous Track
654    PrevTrack,
655    /// Multi-media keys - Next Track
656    NextTrack,
657    /// Multi-media keys - Volume Mute Toggle
658    Mute,
659    /// Multi-media keys - Open Calculator
660    Calculator,
661    /// Multi-media keys - Play
662    Play,
663    /// Multi-media keys - Stop
664    Stop,
665    /// Multi-media keys - Increase Volume
666    VolumeDown,
667    /// Multi-media keys - Decrease Volume
668    VolumeUp,
669    /// Multi-media keys - Open Browser
670    WWWHome,
671    /// Sent when the keyboard boots
672    PowerOnTestOk,
673    /// Sent by the keyboard when too many keys are pressed
674    TooManyKeys,
675    /// Used as a 'hidden' Right Control Key (Pause = RControl2 + Num Lock)
676    RControl2,
677    /// Used as a 'hidden' Right Alt Key (Print Screen = RAlt2 + PrntScr)
678    RAlt2,
679    /// Represents a key we don't know about
680    Unknown,
681}
682
683/// The new state for a key, as part of a key event.
684#[derive(Debug, PartialEq, Eq, Copy, Clone)]
685pub enum KeyState {
686    /// Key has just been released
687    Up,
688    /// Key has just been pressed
689    Down,
690    /// Key was pressed and then released as an atomic action. Or it's like a
691    /// PowerOnSelfTest event which doesn't have an 'Up' or a 'Down'.
692    SingleShot,
693}
694
695/// Options for how we can handle what happens when the Ctrl key is held down
696/// and a letter is pressed.
697#[derive(Debug, PartialEq, Eq, Copy, Clone)]
698pub enum HandleControl {
699    /// If either Ctrl key is held down, convert the letters A through Z into
700    /// Unicode chars U+0001 through U+001A. If the Ctrl keys are not held
701    /// down, letters go through normally.
702    MapLettersToUnicode,
703    /// Don't do anything special - send through the Ctrl key up/down events,
704    /// and leave the letters as letters.
705    Ignore,
706}
707
708/// A event describing something happen to a key on your keyboard.
709#[derive(Debug, PartialEq, Eq, Clone)]
710pub struct KeyEvent {
711    /// Which key this event is for
712    pub code: KeyCode,
713    /// The new state for the key
714    pub state: KeyState,
715}
716
717/// Describes a physical keyboard
718pub enum PhysicalKeyboard {
719    /// 102 or 105 key ISO, as used by UK English keyboards (and others)
720    Iso,
721    /// 101 or 104 key ANSI, as used by US English keyboards (and others)
722    Ansi,
723    /// 106 or 109 key JIS, as used by Japanese keyboards (and others)
724    Jis,
725}
726
727/// Describes a Keyboard Layout.
728///
729/// Layouts might include "en_US", or "en_GB", or "de_GR".
730pub trait KeyboardLayout {
731    /// Convert a `KeyCode` enum to a Unicode character, if possible.
732    /// `KeyCode::A` maps to `DecodedKey::Unicode('a')` (or
733    /// `DecodedKey::Unicode('A')` if shifted), while `KeyCode::LAlt` becomes
734    /// `DecodedKey::RawKey(KeyCode::LAlt)` because there's no Unicode equivalent.
735    fn map_keycode(
736        &self,
737        keycode: KeyCode,
738        modifiers: &Modifiers,
739        handle_ctrl: HandleControl,
740    ) -> DecodedKey;
741
742    /// Which physical keyboard does this layout work on?
743    fn get_physical(&self) -> PhysicalKeyboard;
744}
745
746/// A mechanism to convert bytes from a Keyboard into [`KeyCode`] values.
747///
748/// This conversion is stateful.
749pub trait ScancodeSet {
750    /// Handles the state logic for the decoding of scan codes into key events.
751    fn advance_state(&mut self, code: u8) -> Result<Option<KeyEvent>, Error>;
752}
753
754/// The set of modifier keys you have on a keyboard.
755#[derive(Debug, Default, Clone, Eq, PartialEq, Hash)]
756pub struct Modifiers {
757    /// The left shift key is down
758    pub lshift: bool,
759    /// The right shift key is down
760    pub rshift: bool,
761    /// The left control key is down
762    pub lctrl: bool,
763    /// The right control key is down
764    pub rctrl: bool,
765    /// The Num Lock toggle is on
766    pub numlock: bool,
767    /// The caps lock toggle is on
768    pub capslock: bool,
769    /// The left alt key is down
770    pub lalt: bool,
771    /// The right alt key is down
772    pub ralt: bool,
773    /// Special 'hidden' control key is down (used when you press Pause)
774    pub rctrl2: bool,
775}
776
777/// Contains either a Unicode character, or a raw key code.
778#[derive(Debug, PartialEq, Eq, Copy, Clone)]
779pub enum DecodedKey {
780    RawKey(KeyCode),
781    Unicode(char),
782}
783
784// ****************************************************************************
785//
786// Public Data
787//
788// ****************************************************************************
789
790// None
791
792// ****************************************************************************
793//
794// Private Types
795//
796// ****************************************************************************
797
798/// Tracls
799#[derive(Debug, Copy, Clone, Eq, PartialEq)]
800enum DecodeState {
801    Start,
802    Extended,
803    Release,
804    ExtendedRelease,
805    Extended2,
806    Extended2Release,
807}
808
809// ****************************************************************************
810//
811// Private Data
812//
813// ****************************************************************************
814
815const KEYCODE_BITS: u8 = 11;
816const EXTENDED_KEY_CODE: u8 = 0xE0;
817const EXTENDED2_KEY_CODE: u8 = 0xE1;
818const KEY_RELEASE_CODE: u8 = 0xF0;
819
820const QUO: char = '\'';
821const SLS: char = '\\';
822
823// ****************************************************************************
824//
825// Public Functions and Implementation
826//
827// ****************************************************************************
828
829impl<L, S> PS2Keyboard<L, S>
830where
831    L: KeyboardLayout,
832    S: ScancodeSet,
833{
834    /// Make a new Keyboard object with the given layout.
835    pub const fn new(scancode_set: S, layout: L, handle_ctrl: HandleControl) -> PS2Keyboard<L, S> {
836        PS2Keyboard {
837            ps2_decoder: Ps2Decoder::new(),
838            scancode_set,
839            event_decoder: EventDecoder::new(layout, handle_ctrl),
840        }
841    }
842
843    /// Get the current key modifier states.
844    pub const fn get_modifiers(&self) -> &Modifiers {
845        &self.event_decoder.modifiers
846    }
847
848    /// Change the Ctrl key mapping.
849    pub fn set_ctrl_handling(&mut self, new_value: HandleControl) {
850        self.event_decoder.set_ctrl_handling(new_value);
851    }
852
853    /// Get the current Ctrl key mapping.
854    pub const fn get_ctrl_handling(&self) -> HandleControl {
855        self.event_decoder.get_ctrl_handling()
856    }
857
858    /// Clears the bit register.
859    ///
860    /// Call this when there is a timeout reading data from the keyboard.
861    pub fn clear(&mut self) {
862        self.ps2_decoder.clear();
863    }
864
865    /// Processes a 16-bit word from the keyboard.
866    ///
867    /// * The start bit (0) must be in bit 0.
868    /// * The data octet must be in bits 1..8, with the LSB in bit 1 and the
869    ///   MSB in bit 8.
870    /// * The parity bit must be in bit 9.
871    /// * The stop bit (1) must be in bit 10.
872    pub fn add_word(&mut self, word: u16) -> Result<Option<KeyEvent>, Error> {
873        let byte = self.ps2_decoder.add_word(word)?;
874        self.add_byte(byte)
875    }
876
877    /// Processes an 8-bit byte from the keyboard.
878    ///
879    /// We assume the start, stop and parity bits have been processed and
880    /// verified.
881    pub fn add_byte(&mut self, byte: u8) -> Result<Option<KeyEvent>, Error> {
882        self.scancode_set.advance_state(byte)
883    }
884
885    /// Shift a bit into the register.
886    ///
887    /// Call this /or/ call `add_word` - don't call both.
888    /// Until the last bit is added you get Ok(None) returned.
889    pub fn add_bit(&mut self, bit: bool) -> Result<Option<KeyEvent>, Error> {
890        if let Some(byte) = self.ps2_decoder.add_bit(bit)? {
891            self.scancode_set.advance_state(byte)
892        } else {
893            Ok(None)
894        }
895    }
896
897    /// Processes a `KeyEvent` returned from `add_bit`, `add_byte` or `add_word`
898    /// and produces a decoded key.
899    ///
900    /// For example, the KeyEvent for pressing the '5' key on your keyboard
901    /// gives a DecodedKey of unicode character '5', unless the shift key is
902    /// held in which case you get the unicode character '%'.
903    pub fn process_keyevent(&mut self, ev: KeyEvent) -> Option<DecodedKey> {
904        self.event_decoder.process_keyevent(ev)
905    }
906}
907
908impl Ps2Decoder {
909    /// Build a new PS/2 protocol decoder.
910    pub const fn new() -> Ps2Decoder {
911        Ps2Decoder {
912            register: 0,
913            num_bits: 0,
914        }
915    }
916
917    /// Clears the bit register.
918    ///
919    /// Call this when there is a timeout reading data from the keyboard.
920    pub fn clear(&mut self) {
921        self.register = 0;
922        self.num_bits = 0;
923    }
924
925    /// Shift a bit into the register.
926    ///
927    /// Until the last bit is added you get Ok(None) returned.
928    pub fn add_bit(&mut self, bit: bool) -> Result<Option<u8>, Error> {
929        self.register |= (bit as u16) << self.num_bits;
930        self.num_bits += 1;
931        if self.num_bits == KEYCODE_BITS {
932            let word = self.register;
933            self.register = 0;
934            self.num_bits = 0;
935            let byte = Self::check_word(word)?;
936            Ok(Some(byte))
937        } else {
938            Ok(None)
939        }
940    }
941
942    /// Process an entire 11-bit word.
943    ///
944    /// Must be packed into the bottom 11-bits of the 16-bit value.
945    pub fn add_word(&self, word: u16) -> Result<u8, Error> {
946        Self::check_word(word)
947    }
948
949    /// Check 11-bit word has 1 start bit, 1 stop bit and an odd parity bit.
950    const fn check_word(word: u16) -> Result<u8, Error> {
951        let start_bit = Self::get_bit(word, 0);
952        let parity_bit = Self::get_bit(word, 9);
953        let stop_bit = Self::get_bit(word, 10);
954        let data = ((word >> 1) & 0xFF) as u8;
955
956        if start_bit {
957            return Err(Error::BadStartBit);
958        }
959
960        if !stop_bit {
961            return Err(Error::BadStopBit);
962        }
963
964        // We have odd parity, so if there are an even number of 1 bits, we need
965        // the parity bit set to make it odd.
966        let need_parity = Self::has_even_number_bits(data);
967
968        if need_parity != parity_bit {
969            return Err(Error::ParityError);
970        }
971
972        Ok(data)
973    }
974
975    const fn get_bit(word: u16, offset: usize) -> bool {
976        ((word >> offset) & 0x0001) != 0
977    }
978
979    const fn has_even_number_bits(data: u8) -> bool {
980        (data.count_ones() % 2) == 0
981    }
982}
983
984impl Default for Ps2Decoder {
985    fn default() -> Self {
986        Ps2Decoder::new()
987    }
988}
989
990impl<L> UsbKeyboard<L>
991where
992    L: KeyboardLayout,
993{
994    /// Construct USB HID keyboard handler
995    pub fn new(layout: L, handle_ctrl: HandleControl) -> UsbKeyboard<L> {
996        UsbKeyboard {
997            event_decoder: EventDecoder::new(layout, handle_ctrl),
998            last_report: Default::default(),
999        }
1000    }
1001
1002    /// Reset the USB HID state
1003    ///
1004    /// We only get changes in key state from the keyboard, so this function
1005    /// resets our internal state.
1006    pub fn reset_state(&mut self) {
1007        self.last_report = Default::default();
1008    }
1009
1010    /// Process a new USB HID Frame into KeyEvents
1011    ///
1012    /// You are given an iterator, which will process the incoming report. Do
1013    /// not drop the iterator until it starts returning None.
1014    pub fn handle_report_raw<'kb>(
1015        &'kb mut self,
1016        report: &UsbBootKeyboardReport,
1017    ) -> UsbKeyEventIter<'kb, L> {
1018        UsbKeyEventIter {
1019            parent: self,
1020            new_report: report.clone(),
1021        }
1022    }
1023
1024    /// Process a new USB HID Frame into Decoded keys
1025    ///
1026    /// You are given an iterator, which will process the incoming report. Do
1027    /// not drop the iterator until it starts returning None.
1028    pub fn handle_report<'kb>(
1029        &'kb mut self,
1030        report: &UsbBootKeyboardReport,
1031    ) -> UsbDecodedKeyIter<'kb, L> {
1032        UsbDecodedKeyIter {
1033            inner: self.handle_report_raw(report),
1034        }
1035    }
1036}
1037
1038impl<'kb, L> UsbKeyEventIter<'kb, L>
1039where
1040    L: KeyboardLayout,
1041{
1042    const MODIFIERS: [(KeyCode, scancodes::UsbModifiers); 8] = [
1043        (KeyCode::LControl, scancodes::UsbModifiers::LCtrl),
1044        (KeyCode::LShift, scancodes::UsbModifiers::LShift),
1045        (KeyCode::LAlt, scancodes::UsbModifiers::LAlt),
1046        (KeyCode::LWin, scancodes::UsbModifiers::LGui),
1047        (KeyCode::RControl, scancodes::UsbModifiers::RCtrl),
1048        (KeyCode::RShift, scancodes::UsbModifiers::RShift),
1049        (KeyCode::RAltGr, scancodes::UsbModifiers::RAlt),
1050        (KeyCode::RWin, scancodes::UsbModifiers::RGui),
1051    ];
1052
1053    /// Returns true (and updates the old modifiers) if a modifier was pressed but has now been released
1054    fn modifier_was_released(
1055        old_modifiers: &mut u8,
1056        new_modifiers: u8,
1057        key: scancodes::UsbModifiers,
1058    ) -> bool {
1059        let key = key as u8;
1060        if ((*old_modifiers & key) != 0) && ((new_modifiers & key) == 0) {
1061            // was released - clear it
1062            *old_modifiers &= !key;
1063            true
1064        } else {
1065            false
1066        }
1067    }
1068
1069    /// Returns true (and updates the old modifiers) if a modifier was released but has now been pressed
1070    fn modifier_was_pressed(
1071        old_modifiers: &mut u8,
1072        new_modifiers: u8,
1073        key: scancodes::UsbModifiers,
1074    ) -> bool {
1075        let key = key as u8;
1076        if ((*old_modifiers & key) == 0) && ((new_modifiers & key) != 0) {
1077            // was pressed - set it
1078            *old_modifiers |= key;
1079            true
1080        } else {
1081            false
1082        }
1083    }
1084}
1085
1086impl<'kb, L> Iterator for UsbKeyEventIter<'kb, L>
1087where
1088    L: KeyboardLayout,
1089{
1090    type Item = KeyEvent;
1091
1092    fn next(&mut self) -> Option<Self::Item> {
1093        // for every modifier that was on and is now off, send a key release
1094        for (keycode, modifier) in Self::MODIFIERS {
1095            if Self::modifier_was_released(
1096                &mut self.parent.last_report.modifiers,
1097                self.new_report.modifiers,
1098                modifier,
1099            ) {
1100                return Some(KeyEvent {
1101                    code: keycode,
1102                    state: KeyState::Up,
1103                });
1104            }
1105        }
1106
1107        // for every modifier that was off and is now on, send a key down
1108        for (keycode, modifier) in Self::MODIFIERS {
1109            if Self::modifier_was_pressed(
1110                &mut self.parent.last_report.modifiers,
1111                self.new_report.modifiers,
1112                modifier,
1113            ) {
1114                return Some(KeyEvent {
1115                    code: keycode,
1116                    state: KeyState::Down,
1117                });
1118            }
1119        }
1120
1121        // for every keycode that was on and is now off, send a key release
1122        for old_place in self.parent.last_report.keys.iter_mut().filter(|x| **x != 0) {
1123            if !self.new_report.keys.contains(old_place) {
1124                // cannot find old key in new report => it has been released
1125                let output = Some(KeyEvent {
1126                    code: scancodes::usb_convert(*old_place),
1127                    state: KeyState::Up,
1128                });
1129                *old_place = 0;
1130                return output;
1131            }
1132        }
1133
1134        // for every keycode that was on and is now off, send a key down
1135        for new_place in self.new_report.keys.iter().filter(|x| **x != 0) {
1136            if !self.parent.last_report.keys.contains(new_place) {
1137                // cannot find new key in old report => it has been pressed
1138                let output = Some(KeyEvent {
1139                    code: scancodes::usb_convert(*new_place),
1140                    state: KeyState::Down,
1141                });
1142                // we know we must have space in the old report because if all
1143                // the codes in the new report are new, then all the old
1144                // codes will have been expunged already. So the unwrap is
1145                // fine.
1146                let old_gap = self
1147                    .parent
1148                    .last_report
1149                    .keys
1150                    .iter_mut()
1151                    .find(|x| **x == 0)
1152                    .unwrap();
1153                *old_gap = *new_place;
1154                return output;
1155            }
1156        }
1157        None
1158    }
1159}
1160
1161impl<'kb, L> Iterator for UsbDecodedKeyIter<'kb, L>
1162where
1163    L: KeyboardLayout,
1164{
1165    type Item = DecodedKey;
1166
1167    fn next(&mut self) -> Option<Self::Item> {
1168        while let Some(ev) = self.inner.next() {
1169            if let Some(decoded) = self.inner.parent.event_decoder.process_keyevent(ev) {
1170                return Some(decoded);
1171            }
1172        }
1173        None
1174    }
1175}
1176
1177impl<L> EventDecoder<L>
1178where
1179    L: KeyboardLayout,
1180{
1181    /// Construct a new event decoder.
1182    pub const fn new(layout: L, handle_ctrl: HandleControl) -> EventDecoder<L> {
1183        EventDecoder {
1184            handle_ctrl,
1185            modifiers: Modifiers {
1186                lshift: false,
1187                rshift: false,
1188                lctrl: false,
1189                rctrl: false,
1190                numlock: true,
1191                capslock: false,
1192                lalt: false,
1193                ralt: false,
1194                rctrl2: false,
1195            },
1196            layout,
1197        }
1198    }
1199
1200    /// Change the Ctrl key mapping.
1201    pub fn set_ctrl_handling(&mut self, new_value: HandleControl) {
1202        self.handle_ctrl = new_value;
1203    }
1204
1205    /// Get the current Ctrl key mapping.
1206    pub const fn get_ctrl_handling(&self) -> HandleControl {
1207        self.handle_ctrl
1208    }
1209
1210    /// Processes a `KeyEvent` returned from `add_bit`, `add_byte` or `add_word`
1211    /// and produces a decoded key.
1212    ///
1213    /// For example, the KeyEvent for pressing the '5' key on your keyboard
1214    /// gives a DecodedKey of unicode character '5', unless the shift key is
1215    /// held in which case you get the unicode character '%'.
1216    pub fn process_keyevent(&mut self, ev: KeyEvent) -> Option<DecodedKey> {
1217        match ev {
1218            KeyEvent {
1219                code: KeyCode::LShift,
1220                state: KeyState::Down,
1221            } => {
1222                self.modifiers.lshift = true;
1223                Some(DecodedKey::RawKey(KeyCode::LShift))
1224            }
1225            KeyEvent {
1226                code: KeyCode::RShift,
1227                state: KeyState::Down,
1228            } => {
1229                self.modifiers.rshift = true;
1230                Some(DecodedKey::RawKey(KeyCode::RShift))
1231            }
1232            KeyEvent {
1233                code: KeyCode::LShift,
1234                state: KeyState::Up,
1235            } => {
1236                self.modifiers.lshift = false;
1237                None
1238            }
1239            KeyEvent {
1240                code: KeyCode::RShift,
1241                state: KeyState::Up,
1242            } => {
1243                self.modifiers.rshift = false;
1244                None
1245            }
1246            KeyEvent {
1247                code: KeyCode::CapsLock,
1248                state: KeyState::Down,
1249            } => {
1250                self.modifiers.capslock = !self.modifiers.capslock;
1251                Some(DecodedKey::RawKey(KeyCode::CapsLock))
1252            }
1253            KeyEvent {
1254                code: KeyCode::NumpadLock,
1255                state: KeyState::Down,
1256            } => {
1257                if self.modifiers.rctrl2 {
1258                    // It's a Pause key because we got the 'hidden' rctrl2
1259                    // sequence first.
1260                    Some(DecodedKey::RawKey(KeyCode::PauseBreak))
1261                } else {
1262                    // It's a numlock toggle
1263                    self.modifiers.numlock = !self.modifiers.numlock;
1264                    Some(DecodedKey::RawKey(KeyCode::NumpadLock))
1265                }
1266            }
1267            KeyEvent {
1268                code: KeyCode::LControl,
1269                state: KeyState::Down,
1270            } => {
1271                self.modifiers.lctrl = true;
1272                Some(DecodedKey::RawKey(KeyCode::LControl))
1273            }
1274            KeyEvent {
1275                code: KeyCode::LControl,
1276                state: KeyState::Up,
1277            } => {
1278                self.modifiers.lctrl = false;
1279                None
1280            }
1281            KeyEvent {
1282                code: KeyCode::RControl,
1283                state: KeyState::Down,
1284            } => {
1285                self.modifiers.rctrl = true;
1286                Some(DecodedKey::RawKey(KeyCode::RControl))
1287            }
1288            KeyEvent {
1289                code: KeyCode::RControl,
1290                state: KeyState::Up,
1291            } => {
1292                self.modifiers.rctrl = false;
1293                None
1294            }
1295            KeyEvent {
1296                code: KeyCode::LAlt,
1297                state: KeyState::Down,
1298            } => {
1299                self.modifiers.lalt = true;
1300                Some(DecodedKey::RawKey(KeyCode::LAlt))
1301            }
1302            KeyEvent {
1303                code: KeyCode::LAlt,
1304                state: KeyState::Up,
1305            } => {
1306                self.modifiers.lalt = false;
1307                None
1308            }
1309            KeyEvent {
1310                code: KeyCode::RAltGr,
1311                state: KeyState::Down,
1312            } => {
1313                self.modifiers.ralt = true;
1314                Some(DecodedKey::RawKey(KeyCode::RAltGr))
1315            }
1316            KeyEvent {
1317                code: KeyCode::RAltGr,
1318                state: KeyState::Up,
1319            } => {
1320                self.modifiers.ralt = false;
1321                None
1322            }
1323            KeyEvent {
1324                code: KeyCode::RControl2,
1325                state: KeyState::Down,
1326            } => {
1327                self.modifiers.rctrl2 = true;
1328                Some(DecodedKey::RawKey(KeyCode::RControl2))
1329            }
1330            KeyEvent {
1331                code: KeyCode::RControl2,
1332                state: KeyState::Up,
1333            } => {
1334                self.modifiers.rctrl2 = false;
1335                None
1336            }
1337            KeyEvent {
1338                code: c,
1339                state: KeyState::Down,
1340            } => Some(
1341                self.layout
1342                    .map_keycode(c, &self.modifiers, self.handle_ctrl),
1343            ),
1344            _ => None,
1345        }
1346    }
1347
1348    /// Change the keyboard layout.
1349    ///
1350    /// Only useful with [`layouts::AnyLayout`], otherwise you can only change a
1351    /// layout for exactly the same layout.
1352    pub fn change_layout(&mut self, new_layout: L) {
1353        self.layout = new_layout;
1354    }
1355}
1356
1357impl KeyEvent {
1358    pub const fn new(code: KeyCode, state: KeyState) -> KeyEvent {
1359        KeyEvent { code, state }
1360    }
1361}
1362
1363impl Modifiers {
1364    pub const fn is_shifted(&self) -> bool {
1365        self.lshift | self.rshift
1366    }
1367
1368    pub const fn is_ctrl(&self) -> bool {
1369        self.lctrl | self.rctrl
1370    }
1371
1372    pub const fn is_alt(&self) -> bool {
1373        self.lalt | self.ralt
1374    }
1375
1376    pub const fn is_altgr(&self) -> bool {
1377        self.ralt | (self.lalt & self.is_ctrl())
1378    }
1379
1380    pub const fn is_caps(&self) -> bool {
1381        self.is_shifted() ^ self.capslock
1382    }
1383
1384    /// Handle letter keys with standard ASCII 'A'..'Z' keycaps.
1385    ///
1386    /// ONLY pass 'A'..='Z' - nothing else.
1387    ///
1388    /// You will get a `DecodedKey::Unicode` value with the appropriate lower
1389    /// or upper case letter, according to state of the the Caps Lock and
1390    /// Shift modifiers.
1391    pub(crate) fn handle_ascii_2(&self, letter: char, handle_ctrl: HandleControl) -> DecodedKey {
1392        debug_assert!(letter.is_ascii_uppercase());
1393        if handle_ctrl == HandleControl::MapLettersToUnicode && self.is_ctrl() {
1394            // Get a Control code, like Ctrl+C => U+0003
1395            const ASCII_UPPERCASE_START_OFFSET: u8 = 64;
1396            DecodedKey::Unicode((letter as u8 - ASCII_UPPERCASE_START_OFFSET) as char)
1397        } else if self.is_caps() {
1398            // Capital letter
1399            DecodedKey::Unicode(letter)
1400        } else {
1401            // Lowercase letter
1402            const ASCII_UPPER_TO_LOWER_OFFSET: u8 = 32;
1403            DecodedKey::Unicode((letter as u8 + ASCII_UPPER_TO_LOWER_OFFSET) as char)
1404        }
1405    }
1406
1407    /// Handle letter keys with just two variants (lower and upper case).
1408    ///
1409    /// Designed for non-ASCII keys, this does not produce control codes.
1410    ///
1411    /// You will get a `DecodedKey::Unicode` value with the appropriate lower
1412    /// or upper case letter, according to state of the the Caps Lock and
1413    /// Shift modifiers.
1414    ///
1415    /// We make you pass both upper and lower case variants to avoid having to
1416    /// use the `char::to_lowercase` function.
1417    pub(crate) fn handle_letter2(&self, letter_lower: char, letter_upper: char) -> DecodedKey {
1418        if self.is_caps() {
1419            DecodedKey::Unicode(letter_upper)
1420        } else {
1421            DecodedKey::Unicode(letter_lower)
1422        }
1423    }
1424
1425    /// Handle letter keys with standard ASCII 'A'..'Z' keycaps with two extra symbols.
1426    ///
1427    /// ONLY pass 'A'..='Z' - nothing else
1428    ///
1429    /// You will get a `DecodedKey::Unicode` value with the appropriate lower
1430    /// or upper case letter, according to state of the the Caps Lock and
1431    /// Shift modifiers. Or, if AltGr is held, you get either the alternate
1432    /// character. Useful if your alternate character is e.g. `€`.
1433    ///
1434    /// We make you pass both upper and lower case variants to avoid having to
1435    /// use the `char::to_lowercase` function.
1436    pub(crate) fn handle_ascii_3(
1437        &self,
1438        letter_upper: char,
1439        alt: char,
1440        handle_ctrl: HandleControl,
1441    ) -> DecodedKey {
1442        debug_assert!(letter_upper.is_ascii_uppercase());
1443        if handle_ctrl == HandleControl::MapLettersToUnicode && self.is_ctrl() {
1444            // Get a Control code, like Ctrl+C => U+0003
1445            const ASCII_UPPERCASE_START_OFFSET: u8 = 64;
1446            DecodedKey::Unicode((letter_upper as u8 - ASCII_UPPERCASE_START_OFFSET) as char)
1447        } else if self.ralt {
1448            // Alternate character
1449            DecodedKey::Unicode(alt)
1450        } else if self.is_caps() {
1451            // Capital letter
1452            DecodedKey::Unicode(letter_upper)
1453        } else {
1454            // Lowercase letter
1455            const ASCII_UPPER_TO_LOWER_OFFSET: u8 = 32;
1456            DecodedKey::Unicode((letter_upper as u8 + ASCII_UPPER_TO_LOWER_OFFSET) as char)
1457        }
1458    }
1459
1460    /// Handle letter keys with standard ASCII 'A'..'Z' keycaps with two extra symbols.
1461    ///
1462    /// ONLY pass 'A'..='Z' - nothing else
1463    ///
1464    /// You will get a `DecodedKey::Unicode` value with the appropriate lower
1465    /// or upper case letter, according to state of the the Caps Lock and
1466    /// Shift modifiers. Or, if AltGr is held, you get either the upper or
1467    /// lower case alternate character. Useful if your alternate character is
1468    /// e.g. `é` (or `É` if Shift or Caps Lock is enabled).
1469    ///
1470    /// We make you pass both upper and lower case variants to avoid having to
1471    /// use the `char::to_lowercase` function.
1472    pub(crate) fn handle_ascii_4(
1473        &self,
1474        letter_upper: char,
1475        alt_letter_lower: char,
1476        alt_letter_upper: char,
1477        handle_ctrl: HandleControl,
1478    ) -> DecodedKey {
1479        debug_assert!(letter_upper.is_ascii_uppercase());
1480        if handle_ctrl == HandleControl::MapLettersToUnicode && self.is_ctrl() {
1481            // Get a Control code, like Ctrl+C => U+0003
1482            const ASCII_UPPERCASE_START_OFFSET: u8 = 64;
1483            DecodedKey::Unicode((letter_upper as u8 - ASCII_UPPERCASE_START_OFFSET) as char)
1484        } else if self.ralt && self.is_caps() {
1485            // Capital letter
1486            DecodedKey::Unicode(alt_letter_upper)
1487        } else if self.ralt {
1488            // Lowercase letter
1489            DecodedKey::Unicode(alt_letter_lower)
1490        } else if self.is_caps() {
1491            // Capital letter
1492            DecodedKey::Unicode(letter_upper)
1493        } else {
1494            // Lowercase letter
1495            const ASCII_UPPER_TO_LOWER_OFFSET: u8 = 32;
1496            DecodedKey::Unicode((letter_upper as u8 + ASCII_UPPER_TO_LOWER_OFFSET) as char)
1497        }
1498    }
1499
1500    /// Handle numpad keys which are either a character or a raw key
1501    pub(crate) fn handle_num_pad(&self, letter: char, key: KeyCode) -> DecodedKey {
1502        if self.numlock {
1503            DecodedKey::Unicode(letter)
1504        } else {
1505            DecodedKey::RawKey(key)
1506        }
1507    }
1508
1509    /// Handle numpad keys which produce a pair of characters
1510    ///
1511    /// This is usually just for Numpad Delete.
1512    pub(crate) fn handle_num_del(&self, letter: char, other: char) -> DecodedKey {
1513        if self.numlock {
1514            DecodedKey::Unicode(letter)
1515        } else {
1516            DecodedKey::Unicode(other)
1517        }
1518    }
1519
1520    /// Handle standard two-glyph shifted keys
1521    ///
1522    /// Caps Lock is ignored here - only shift matters.
1523    pub(crate) fn handle_symbol2(&self, plain: char, shifted: char) -> DecodedKey {
1524        if self.is_shifted() {
1525            DecodedKey::Unicode(shifted)
1526        } else {
1527            DecodedKey::Unicode(plain)
1528        }
1529    }
1530
1531    /// Handle standard three-glyph shifted keys
1532    ///
1533    /// Caps Lock is ignored here - only shift matters. AltGr gets you the
1534    /// alternate letter, regardless of Shift status.
1535    pub(crate) fn handle_symbol3(&self, plain: char, shifted: char, alt: char) -> DecodedKey {
1536        if self.is_altgr() {
1537            DecodedKey::Unicode(alt)
1538        } else if self.is_shifted() {
1539            DecodedKey::Unicode(shifted)
1540        } else {
1541            DecodedKey::Unicode(plain)
1542        }
1543    }
1544}
1545
1546// ****************************************************************************
1547//
1548// Tests
1549//
1550// ****************************************************************************
1551
1552#[cfg(test)]
1553mod test {
1554    use super::*;
1555
1556    fn add_bytes<L, S>(keyboard: &mut PS2Keyboard<L, S>, test_sequence: &[(u8, Option<KeyEvent>)])
1557    where
1558        L: KeyboardLayout,
1559        S: ScancodeSet,
1560    {
1561        for (byte, expected_key) in test_sequence.iter().cloned() {
1562            let result = keyboard.add_byte(byte);
1563            assert_eq!(
1564                result,
1565                Ok(expected_key.clone()),
1566                "0x{:02x} should have given {:?} not {:?}",
1567                byte,
1568                expected_key,
1569                result
1570            );
1571        }
1572    }
1573
1574    fn process_keyevents<L, S>(
1575        keyboard: &mut PS2Keyboard<L, S>,
1576        test_sequence: &[(KeyEvent, Option<DecodedKey>)],
1577    ) where
1578        L: KeyboardLayout,
1579        S: ScancodeSet,
1580    {
1581        for (idx, (event, expected_decode)) in test_sequence.iter().cloned().enumerate() {
1582            let result = keyboard.process_keyevent(event.clone());
1583            assert_eq!(
1584                result,
1585                expected_decode.clone(),
1586                "Entry {} {:?} should have given {:?} not {:?}",
1587                idx,
1588                event,
1589                expected_decode,
1590                result
1591            );
1592        }
1593    }
1594
1595    #[test]
1596    fn test_f9() {
1597        let mut k = PS2Keyboard::new(
1598            ScancodeSet2::new(),
1599            layouts::Us104Key,
1600            HandleControl::MapLettersToUnicode,
1601        );
1602        // start
1603        assert_eq!(k.add_bit(false), Ok(None));
1604        // 8 data bits (LSB first)
1605        assert_eq!(k.add_bit(true), Ok(None));
1606        assert_eq!(k.add_bit(false), Ok(None));
1607        assert_eq!(k.add_bit(false), Ok(None));
1608        assert_eq!(k.add_bit(false), Ok(None));
1609        assert_eq!(k.add_bit(false), Ok(None));
1610        assert_eq!(k.add_bit(false), Ok(None));
1611        assert_eq!(k.add_bit(false), Ok(None));
1612        assert_eq!(k.add_bit(false), Ok(None));
1613        // parity
1614        assert_eq!(k.add_bit(false), Ok(None));
1615        // stop
1616        assert_eq!(
1617            k.add_bit(true),
1618            Ok(Some(KeyEvent::new(KeyCode::F9, KeyState::Down)))
1619        );
1620    }
1621
1622    #[test]
1623    fn test_f9_word() {
1624        let mut k = PS2Keyboard::new(
1625            ScancodeSet2::new(),
1626            layouts::Us104Key,
1627            HandleControl::MapLettersToUnicode,
1628        );
1629        assert_eq!(
1630            k.add_word(0x0402),
1631            Ok(Some(KeyEvent::new(KeyCode::F9, KeyState::Down)))
1632        );
1633    }
1634
1635    #[test]
1636    fn test_f9_byte() {
1637        let mut k = PS2Keyboard::new(
1638            ScancodeSet2::new(),
1639            layouts::Us104Key,
1640            HandleControl::MapLettersToUnicode,
1641        );
1642
1643        let test_sequence = [(0x01, Some(KeyEvent::new(KeyCode::F9, KeyState::Down)))];
1644        add_bytes(&mut k, &test_sequence);
1645    }
1646
1647    #[test]
1648    fn test_keyup_keydown() {
1649        let mut k = PS2Keyboard::new(
1650            ScancodeSet2::new(),
1651            layouts::Us104Key,
1652            HandleControl::MapLettersToUnicode,
1653        );
1654        let test_sequence = [
1655            (0x01, Some(KeyEvent::new(KeyCode::F9, KeyState::Down))),
1656            (0x01, Some(KeyEvent::new(KeyCode::F9, KeyState::Down))),
1657            (0xF0, None),
1658            (0x01, Some(KeyEvent::new(KeyCode::F9, KeyState::Up))),
1659        ];
1660        add_bytes(&mut k, &test_sequence);
1661    }
1662
1663    #[test]
1664    fn test_f5() {
1665        let mut k = PS2Keyboard::new(
1666            ScancodeSet2::new(),
1667            layouts::Us104Key,
1668            HandleControl::MapLettersToUnicode,
1669        );
1670        // start
1671        assert_eq!(k.add_bit(false), Ok(None));
1672        // 8 data bits (LSB first)
1673        assert_eq!(k.add_bit(true), Ok(None));
1674        assert_eq!(k.add_bit(true), Ok(None));
1675        assert_eq!(k.add_bit(false), Ok(None));
1676        assert_eq!(k.add_bit(false), Ok(None));
1677        assert_eq!(k.add_bit(false), Ok(None));
1678        assert_eq!(k.add_bit(false), Ok(None));
1679        assert_eq!(k.add_bit(false), Ok(None));
1680        assert_eq!(k.add_bit(false), Ok(None));
1681        // parity
1682        assert_eq!(k.add_bit(true), Ok(None));
1683        // stop
1684        assert_eq!(
1685            k.add_bit(true),
1686            Ok(Some(KeyEvent::new(KeyCode::F5, KeyState::Down)))
1687        );
1688    }
1689
1690    #[test]
1691    fn test_f5_up() {
1692        let mut k = PS2Keyboard::new(
1693            ScancodeSet2::new(),
1694            layouts::Us104Key,
1695            HandleControl::MapLettersToUnicode,
1696        );
1697        // Send F0
1698
1699        // start
1700        assert_eq!(k.add_bit(false), Ok(None));
1701        // 8 data bits (LSB first)
1702        assert_eq!(k.add_bit(false), Ok(None));
1703        assert_eq!(k.add_bit(false), Ok(None));
1704        assert_eq!(k.add_bit(false), Ok(None));
1705        assert_eq!(k.add_bit(false), Ok(None));
1706        assert_eq!(k.add_bit(true), Ok(None));
1707        assert_eq!(k.add_bit(true), Ok(None));
1708        assert_eq!(k.add_bit(true), Ok(None));
1709        assert_eq!(k.add_bit(true), Ok(None));
1710        // parity
1711        assert_eq!(k.add_bit(true), Ok(None));
1712        // stop
1713        assert_eq!(k.add_bit(true), Ok(None));
1714
1715        // Send 03
1716
1717        // start
1718        assert_eq!(k.add_bit(false), Ok(None));
1719        // 8 data bits (LSB first)
1720        assert_eq!(k.add_bit(true), Ok(None));
1721        assert_eq!(k.add_bit(true), Ok(None));
1722        assert_eq!(k.add_bit(false), Ok(None));
1723        assert_eq!(k.add_bit(false), Ok(None));
1724        assert_eq!(k.add_bit(false), Ok(None));
1725        assert_eq!(k.add_bit(false), Ok(None));
1726        assert_eq!(k.add_bit(false), Ok(None));
1727        assert_eq!(k.add_bit(false), Ok(None));
1728        // parity
1729        assert_eq!(k.add_bit(true), Ok(None));
1730        // stop
1731        assert_eq!(
1732            k.add_bit(true),
1733            Ok(Some(KeyEvent::new(KeyCode::F5, KeyState::Up)))
1734        );
1735    }
1736
1737    #[test]
1738    fn test_shift() {
1739        let mut k = PS2Keyboard::new(
1740            ScancodeSet2::new(),
1741            layouts::Uk105Key,
1742            HandleControl::MapLettersToUnicode,
1743        );
1744        let test_sequence = [
1745            // A with left shift held
1746            (
1747                KeyEvent::new(KeyCode::LShift, KeyState::Down),
1748                Some(DecodedKey::RawKey(KeyCode::LShift)),
1749            ),
1750            (
1751                KeyEvent::new(KeyCode::A, KeyState::Down),
1752                Some(DecodedKey::Unicode('A')),
1753            ),
1754            (KeyEvent::new(KeyCode::A, KeyState::Up), None),
1755            (KeyEvent::new(KeyCode::LShift, KeyState::Up), None),
1756            // A with no shift
1757            (
1758                KeyEvent::new(KeyCode::A, KeyState::Down),
1759                Some(DecodedKey::Unicode('a')),
1760            ),
1761            (KeyEvent::new(KeyCode::A, KeyState::Up), None),
1762            // A with right shift held
1763            (
1764                KeyEvent::new(KeyCode::RShift, KeyState::Down),
1765                Some(DecodedKey::RawKey(KeyCode::RShift)),
1766            ),
1767            (
1768                KeyEvent::new(KeyCode::A, KeyState::Down),
1769                Some(DecodedKey::Unicode('A')),
1770            ),
1771            (KeyEvent::new(KeyCode::A, KeyState::Up), None),
1772            (KeyEvent::new(KeyCode::RShift, KeyState::Up), None),
1773            // Caps lock ON
1774            (
1775                KeyEvent::new(KeyCode::CapsLock, KeyState::Down),
1776                Some(DecodedKey::RawKey(KeyCode::CapsLock)),
1777            ),
1778            (KeyEvent::new(KeyCode::CapsLock, KeyState::Up), None),
1779            // Letters are now caps
1780            (
1781                KeyEvent::new(KeyCode::X, KeyState::Down),
1782                Some(DecodedKey::Unicode('X')),
1783            ),
1784            (KeyEvent::new(KeyCode::X, KeyState::Up), None),
1785            // Unless you press shift
1786            (
1787                KeyEvent::new(KeyCode::RShift, KeyState::Down),
1788                Some(DecodedKey::RawKey(KeyCode::RShift)),
1789            ),
1790            (
1791                KeyEvent::new(KeyCode::A, KeyState::Down),
1792                Some(DecodedKey::Unicode('a')),
1793            ),
1794            (KeyEvent::new(KeyCode::A, KeyState::Up), None),
1795            (KeyEvent::new(KeyCode::RShift, KeyState::Up), None),
1796            // Numbers are not shifted
1797            (
1798                KeyEvent::new(KeyCode::Key1, KeyState::Down),
1799                Some(DecodedKey::Unicode('1')),
1800            ),
1801            (KeyEvent::new(KeyCode::Key1, KeyState::Up), None),
1802        ];
1803
1804        process_keyevents(&mut k, &test_sequence);
1805    }
1806
1807    #[test]
1808    fn test_ctrl() {
1809        let mut k = PS2Keyboard::new(
1810            ScancodeSet2::new(),
1811            layouts::Us104Key,
1812            HandleControl::MapLettersToUnicode,
1813        );
1814        let test_sequence = [
1815            // Normal
1816            (
1817                KeyEvent::new(KeyCode::A, KeyState::Down),
1818                Some(DecodedKey::Unicode('a')),
1819            ),
1820            (KeyEvent::new(KeyCode::A, KeyState::Up), None),
1821            // Left Control
1822            (
1823                KeyEvent::new(KeyCode::LControl, KeyState::Down),
1824                Some(DecodedKey::RawKey(KeyCode::LControl)),
1825            ),
1826            (
1827                KeyEvent::new(KeyCode::A, KeyState::Down),
1828                Some(DecodedKey::Unicode('\u{0001}')),
1829            ),
1830            (KeyEvent::new(KeyCode::LControl, KeyState::Up), None),
1831            (KeyEvent::new(KeyCode::A, KeyState::Up), None),
1832            // Normal
1833            (
1834                KeyEvent::new(KeyCode::A, KeyState::Down),
1835                Some(DecodedKey::Unicode('a')),
1836            ),
1837            (KeyEvent::new(KeyCode::A, KeyState::Up), None),
1838            // Right Control
1839            (
1840                KeyEvent::new(KeyCode::RControl, KeyState::Down),
1841                Some(DecodedKey::RawKey(KeyCode::RControl)),
1842            ),
1843            (
1844                KeyEvent::new(KeyCode::A, KeyState::Down),
1845                Some(DecodedKey::Unicode('\u{0001}')),
1846            ),
1847            (KeyEvent::new(KeyCode::RControl, KeyState::Up), None),
1848            (KeyEvent::new(KeyCode::A, KeyState::Up), None),
1849        ];
1850        process_keyevents(&mut k, &test_sequence);
1851    }
1852
1853    #[test]
1854    fn test_numlock() {
1855        let mut k = PS2Keyboard::new(
1856            ScancodeSet2::new(),
1857            layouts::Uk105Key,
1858            HandleControl::MapLettersToUnicode,
1859        );
1860
1861        let test_sequence = [
1862            // Numlock ON by default so we get digits
1863            (
1864                KeyEvent::new(KeyCode::Numpad0, KeyState::Down),
1865                Some(DecodedKey::Unicode('0')),
1866            ),
1867            (KeyEvent::new(KeyCode::Numpad0, KeyState::Up), None),
1868            // Numlock OFF
1869            (
1870                KeyEvent::new(KeyCode::NumpadLock, KeyState::Down),
1871                Some(DecodedKey::RawKey(KeyCode::NumpadLock)),
1872            ),
1873            (KeyEvent::new(KeyCode::NumpadLock, KeyState::Up), None),
1874            // Now KP_0 produces INSERT
1875            (
1876                KeyEvent::new(KeyCode::Numpad0, KeyState::Down),
1877                Some(DecodedKey::RawKey(KeyCode::Insert)),
1878            ),
1879            (KeyEvent::new(KeyCode::Numpad0, KeyState::Up), None),
1880        ];
1881        process_keyevents(&mut k, &test_sequence);
1882    }
1883
1884    #[test]
1885    fn test_set_1_down_up_down() {
1886        let mut k = PS2Keyboard::new(
1887            ScancodeSet1::new(),
1888            layouts::Us104Key,
1889            HandleControl::MapLettersToUnicode,
1890        );
1891        let test_sequence = [
1892            (0x1e, Some(KeyEvent::new(KeyCode::A, KeyState::Down))),
1893            (0x9e, Some(KeyEvent::new(KeyCode::A, KeyState::Up))),
1894            (0x1f, Some(KeyEvent::new(KeyCode::S, KeyState::Down))),
1895        ];
1896
1897        add_bytes(&mut k, &test_sequence);
1898    }
1899
1900    #[test]
1901    fn test_set_1_ext_down_up_down() {
1902        let mut k = PS2Keyboard::new(
1903            ScancodeSet1::new(),
1904            layouts::Us104Key,
1905            HandleControl::MapLettersToUnicode,
1906        );
1907        let test_sequence = [
1908            (0xe0, None),
1909            (
1910                0x1c,
1911                Some(KeyEvent::new(KeyCode::NumpadEnter, KeyState::Down)),
1912            ),
1913            (0xe0, None),
1914            (
1915                0x9c,
1916                Some(KeyEvent::new(KeyCode::NumpadEnter, KeyState::Up)),
1917            ),
1918        ];
1919        add_bytes(&mut k, &test_sequence);
1920    }
1921
1922    #[test]
1923    fn test_set_2_poweron() {
1924        let mut k = PS2Keyboard::new(
1925            ScancodeSet2::new(),
1926            layouts::Us104Key,
1927            HandleControl::MapLettersToUnicode,
1928        );
1929        let test_sequence = [(
1930            0xAA,
1931            Some(KeyEvent::new(KeyCode::PowerOnTestOk, KeyState::SingleShot)),
1932        )];
1933        add_bytes(&mut k, &test_sequence);
1934    }
1935
1936    #[test]
1937    fn test_set_2_toomanykeys() {
1938        let mut k = PS2Keyboard::new(
1939            ScancodeSet2::new(),
1940            layouts::Us104Key,
1941            HandleControl::MapLettersToUnicode,
1942        );
1943        let test_sequence = [(
1944            0x00,
1945            Some(KeyEvent::new(KeyCode::TooManyKeys, KeyState::SingleShot)),
1946        )];
1947        add_bytes(&mut k, &test_sequence);
1948    }
1949
1950    #[test]
1951    fn test_set_2_down_up() {
1952        let mut k = PS2Keyboard::new(
1953            ScancodeSet2::new(),
1954            layouts::Us104Key,
1955            HandleControl::MapLettersToUnicode,
1956        );
1957        let test_sequence = [
1958            (0x29, Some(KeyEvent::new(KeyCode::Spacebar, KeyState::Down))),
1959            (0xF0, None),
1960            (0x29, Some(KeyEvent::new(KeyCode::Spacebar, KeyState::Up))),
1961            (0x29, Some(KeyEvent::new(KeyCode::Spacebar, KeyState::Down))),
1962            (0xF0, None),
1963            (0x29, Some(KeyEvent::new(KeyCode::Spacebar, KeyState::Up))),
1964            (0x29, Some(KeyEvent::new(KeyCode::Spacebar, KeyState::Down))),
1965            (0xF0, None),
1966            (0x29, Some(KeyEvent::new(KeyCode::Spacebar, KeyState::Up))),
1967        ];
1968        add_bytes(&mut k, &test_sequence);
1969    }
1970
1971    #[test]
1972    fn test_set_2_ext_down_up() {
1973        let mut k = PS2Keyboard::new(
1974            ScancodeSet2::new(),
1975            layouts::Us104Key,
1976            HandleControl::MapLettersToUnicode,
1977        );
1978        let test_sequence = [
1979            (0xE0, None),
1980            (0x6C, Some(KeyEvent::new(KeyCode::Home, KeyState::Down))),
1981            (0xE0, None),
1982            (0xF0, None),
1983            (0x6C, Some(KeyEvent::new(KeyCode::Home, KeyState::Up))),
1984        ];
1985        add_bytes(&mut k, &test_sequence);
1986    }
1987
1988    #[test]
1989    fn test_pause_set1() {
1990        let mut k = PS2Keyboard::new(
1991            ScancodeSet1::new(),
1992            layouts::Uk105Key,
1993            HandleControl::MapLettersToUnicode,
1994        );
1995
1996        // A Pause keypress generates this sequence all in one go. There is no
1997        // 'Break' code for this key.
1998        let test_sequence = [
1999            // rctrl2
2000            (0xE1, None),
2001            (
2002                0x1D,
2003                Some(KeyEvent {
2004                    code: KeyCode::RControl2,
2005                    state: KeyState::Down,
2006                }),
2007            ),
2008            // Numlock
2009            (
2010                0x45,
2011                Some(KeyEvent {
2012                    code: KeyCode::NumpadLock,
2013                    state: KeyState::Down,
2014                }),
2015            ),
2016            // Release rctrl2
2017            (0xE1, None),
2018            (
2019                0x9D,
2020                Some(KeyEvent {
2021                    code: KeyCode::RControl2,
2022                    state: KeyState::Up,
2023                }),
2024            ),
2025            // Release Numlock
2026            (
2027                0xC5,
2028                Some(KeyEvent {
2029                    code: KeyCode::NumpadLock,
2030                    state: KeyState::Up,
2031                }),
2032            ),
2033        ];
2034
2035        add_bytes(&mut k, &test_sequence);
2036    }
2037
2038    #[test]
2039    fn test_pause_set2() {
2040        let mut k = PS2Keyboard::new(
2041            ScancodeSet2::new(),
2042            layouts::Uk105Key,
2043            HandleControl::MapLettersToUnicode,
2044        );
2045
2046        // A Pause keypress generates this sequence all in one go. There is no
2047        // 'Break' code for this key.
2048        let test_sequence = [
2049            // rctrl2
2050            (0xE1, None),
2051            (
2052                0x14,
2053                Some(KeyEvent {
2054                    code: KeyCode::RControl2,
2055                    state: KeyState::Down,
2056                }),
2057            ),
2058            // Numlock
2059            (
2060                0x77,
2061                Some(KeyEvent {
2062                    code: KeyCode::NumpadLock,
2063                    state: KeyState::Down,
2064                }),
2065            ),
2066            // Release rctrl2
2067            (0xE1, None),
2068            (0xF0, None),
2069            (
2070                0x14,
2071                Some(KeyEvent {
2072                    code: KeyCode::RControl2,
2073                    state: KeyState::Up,
2074                }),
2075            ),
2076            // Release Numlock
2077            (0xF0, None),
2078            (
2079                0x77,
2080                Some(KeyEvent {
2081                    code: KeyCode::NumpadLock,
2082                    state: KeyState::Up,
2083                }),
2084            ),
2085        ];
2086        add_bytes(&mut k, &test_sequence);
2087    }
2088
2089    #[test]
2090    fn test_pause_events() {
2091        let mut k = PS2Keyboard::new(
2092            ScancodeSet2::new(),
2093            layouts::Uk105Key,
2094            HandleControl::MapLettersToUnicode,
2095        );
2096
2097        // A Pause keypress generates this sequence all in one go. There is no
2098        // 'Break' code for this key.
2099        let test_sequence = [
2100            // rctrl2
2101            (
2102                KeyEvent {
2103                    code: KeyCode::RControl2,
2104                    state: KeyState::Down,
2105                },
2106                Some(DecodedKey::RawKey(KeyCode::RControl2)),
2107            ),
2108            // Numlock
2109            (
2110                KeyEvent {
2111                    code: KeyCode::NumpadLock,
2112                    state: KeyState::Down,
2113                },
2114                Some(DecodedKey::RawKey(KeyCode::PauseBreak)),
2115            ),
2116            // Release rctrl2
2117            (
2118                KeyEvent {
2119                    code: KeyCode::RControl2,
2120                    state: KeyState::Up,
2121                },
2122                None,
2123            ),
2124            // Release Numlock
2125            (
2126                KeyEvent {
2127                    code: KeyCode::NumpadLock,
2128                    state: KeyState::Up,
2129                },
2130                None,
2131            ),
2132        ];
2133        process_keyevents(&mut k, &test_sequence);
2134    }
2135
2136    #[test]
2137    fn test_print_screen_set1() {
2138        let mut k = PS2Keyboard::new(
2139            ScancodeSet1::new(),
2140            layouts::Uk105Key,
2141            HandleControl::MapLettersToUnicode,
2142        );
2143
2144        // A Print Screen keypress generates this sequence on make and break.
2145        let test_sequence = [
2146            // ralt2
2147            (0xE0, None),
2148            (
2149                0x2A,
2150                Some(KeyEvent {
2151                    code: KeyCode::RAlt2,
2152                    state: KeyState::Down,
2153                }),
2154            ),
2155            // Print Screen
2156            (0xE0, None),
2157            (
2158                0x37,
2159                Some(KeyEvent {
2160                    code: KeyCode::PrintScreen,
2161                    state: KeyState::Down,
2162                }),
2163            ),
2164            // Release Print Screen
2165            (0xE0, None),
2166            (
2167                0xB7,
2168                Some(KeyEvent {
2169                    code: KeyCode::PrintScreen,
2170                    state: KeyState::Up,
2171                }),
2172            ),
2173            // Release ralt2
2174            (0xE0, None),
2175            (
2176                0xAA,
2177                Some(KeyEvent {
2178                    code: KeyCode::RAlt2,
2179                    state: KeyState::Up,
2180                }),
2181            ),
2182        ];
2183        add_bytes(&mut k, &test_sequence);
2184    }
2185
2186    #[test]
2187    fn test_print_screen_set2() {
2188        let mut k = PS2Keyboard::new(
2189            ScancodeSet2::new(),
2190            layouts::Uk105Key,
2191            HandleControl::MapLettersToUnicode,
2192        );
2193
2194        // A Print Screen keypress generates this sequence on make and break.
2195        let test_sequence = [
2196            // ralt2
2197            (0xE0, None),
2198            (
2199                0x12,
2200                Some(KeyEvent {
2201                    code: KeyCode::RAlt2,
2202                    state: KeyState::Down,
2203                }),
2204            ),
2205            // Print Screen
2206            (0xE0, None),
2207            (
2208                0x7C,
2209                Some(KeyEvent {
2210                    code: KeyCode::PrintScreen,
2211                    state: KeyState::Down,
2212                }),
2213            ),
2214            // Release Print Screen
2215            (0xE0, None),
2216            (0xF0, None),
2217            (
2218                0x7C,
2219                Some(KeyEvent {
2220                    code: KeyCode::PrintScreen,
2221                    state: KeyState::Up,
2222                }),
2223            ),
2224            // Release ralt2
2225            (0xE0, None),
2226            (0xF0, None),
2227            (
2228                0x12,
2229                Some(KeyEvent {
2230                    code: KeyCode::RAlt2,
2231                    state: KeyState::Up,
2232                }),
2233            ),
2234        ];
2235
2236        add_bytes(&mut k, &test_sequence);
2237    }
2238
2239    #[test]
2240    fn test_print_screen_events() {
2241        let mut k = PS2Keyboard::new(
2242            ScancodeSet2::new(),
2243            layouts::Uk105Key,
2244            HandleControl::MapLettersToUnicode,
2245        );
2246
2247        // A Print Screen keypress generates this sequence on make and break.
2248        let test_sequence = [
2249            // ralt2
2250            (
2251                KeyEvent {
2252                    code: KeyCode::RAlt2,
2253                    state: KeyState::Down,
2254                },
2255                Some(DecodedKey::RawKey(KeyCode::RAlt2)),
2256            ),
2257            // Print Screen
2258            (
2259                KeyEvent {
2260                    code: KeyCode::PrintScreen,
2261                    state: KeyState::Down,
2262                },
2263                Some(DecodedKey::RawKey(KeyCode::PrintScreen)),
2264            ),
2265            // Release Print Screen
2266            (
2267                KeyEvent {
2268                    code: KeyCode::PrintScreen,
2269                    state: KeyState::Up,
2270                },
2271                None,
2272            ),
2273            // Release ralt2
2274            (
2275                KeyEvent {
2276                    code: KeyCode::RAlt2,
2277                    state: KeyState::Up,
2278                },
2279                None,
2280            ),
2281        ];
2282
2283        process_keyevents(&mut k, &test_sequence);
2284    }
2285
2286    #[test]
2287    fn test_modifier_state_shift() {
2288        let mut k = PS2Keyboard::new(
2289            ScancodeSet2::new(),
2290            layouts::Uk105Key,
2291            HandleControl::MapLettersToUnicode,
2292        );
2293        assert!(!k.get_modifiers().lshift);
2294
2295        k.process_keyevent(KeyEvent {
2296            code: KeyCode::LShift,
2297            state: KeyState::Down,
2298        });
2299        assert!(k.get_modifiers().lshift);
2300
2301        k.process_keyevent(KeyEvent {
2302            code: KeyCode::LShift,
2303            state: KeyState::Up,
2304        });
2305        assert!(!k.get_modifiers().lshift);
2306    }
2307
2308    #[test]
2309    fn usb_left_control() {
2310        let mut keyboard = UsbKeyboard::new(layouts::Us104Key, HandleControl::MapLettersToUnicode);
2311        let iter = keyboard.handle_report_raw(&UsbBootKeyboardReport {
2312            modifiers: 0x01,
2313            keys: [0; 6],
2314        });
2315        let events: Vec<KeyEvent> = iter.collect();
2316        assert_eq!(
2317            &events,
2318            &[KeyEvent {
2319                code: KeyCode::LControl,
2320                state: KeyState::Down
2321            }]
2322        );
2323
2324        let iter = keyboard.handle_report_raw(&UsbBootKeyboardReport {
2325            modifiers: 0x00,
2326            keys: [0; 6],
2327        });
2328        let events: Vec<KeyEvent> = iter.collect();
2329        assert_eq!(
2330            &events,
2331            &[KeyEvent {
2332                code: KeyCode::LControl,
2333                state: KeyState::Up
2334            }]
2335        );
2336
2337        let iter = keyboard.handle_report_raw(&UsbBootKeyboardReport {
2338            modifiers: 0x00,
2339            keys: [0; 6],
2340        });
2341        let events: Vec<KeyEvent> = iter.collect();
2342        assert!(events.is_empty());
2343    }
2344
2345    #[test]
2346    fn usb_right_gui() {
2347        let mut keyboard = UsbKeyboard::new(layouts::Us104Key, HandleControl::MapLettersToUnicode);
2348        let iter = keyboard.handle_report_raw(&UsbBootKeyboardReport {
2349            modifiers: 0x80,
2350            keys: [0; 6],
2351        });
2352        let events: Vec<KeyEvent> = iter.collect();
2353        assert_eq!(
2354            &events,
2355            &[KeyEvent {
2356                code: KeyCode::RWin,
2357                state: KeyState::Down
2358            }]
2359        );
2360
2361        let iter = keyboard.handle_report_raw(&UsbBootKeyboardReport {
2362            modifiers: 0x00,
2363            keys: [0; 6],
2364        });
2365        let events: Vec<KeyEvent> = iter.collect();
2366        assert_eq!(
2367            &events,
2368            &[KeyEvent {
2369                code: KeyCode::RWin,
2370                state: KeyState::Up
2371            }]
2372        );
2373
2374        let iter = keyboard.handle_report_raw(&UsbBootKeyboardReport {
2375            modifiers: 0x00,
2376            keys: [0; 6],
2377        });
2378        let events: Vec<KeyEvent> = iter.collect();
2379        assert!(events.is_empty());
2380    }
2381
2382    #[test]
2383    fn usb_two_modifiers() {
2384        let mut keyboard = UsbKeyboard::new(layouts::Us104Key, HandleControl::MapLettersToUnicode);
2385        let iter = keyboard.handle_report_raw(&UsbBootKeyboardReport {
2386            modifiers: 0x82,
2387            keys: [0; 6],
2388        });
2389        let events: Vec<KeyEvent> = iter.collect();
2390        assert_eq!(
2391            &events,
2392            &[
2393                KeyEvent {
2394                    code: KeyCode::LShift,
2395                    state: KeyState::Down
2396                },
2397                KeyEvent {
2398                    code: KeyCode::RWin,
2399                    state: KeyState::Down
2400                },
2401            ]
2402        );
2403
2404        let iter = keyboard.handle_report_raw(&UsbBootKeyboardReport {
2405            modifiers: 0x18,
2406            keys: [0; 6],
2407        });
2408        let events: Vec<KeyEvent> = iter.collect();
2409        assert_eq!(
2410            &events,
2411            &[
2412                KeyEvent {
2413                    code: KeyCode::LShift,
2414                    state: KeyState::Up
2415                },
2416                KeyEvent {
2417                    code: KeyCode::RWin,
2418                    state: KeyState::Up
2419                },
2420                KeyEvent {
2421                    code: KeyCode::LWin,
2422                    state: KeyState::Down
2423                },
2424                KeyEvent {
2425                    code: KeyCode::RControl,
2426                    state: KeyState::Down
2427                },
2428            ]
2429        );
2430
2431        let iter = keyboard.handle_report_raw(&UsbBootKeyboardReport {
2432            modifiers: 0x00,
2433            keys: [0; 6],
2434        });
2435        let events: Vec<KeyEvent> = iter.collect();
2436        assert_eq!(
2437            &events,
2438            &[
2439                KeyEvent {
2440                    code: KeyCode::LWin,
2441                    state: KeyState::Up
2442                },
2443                KeyEvent {
2444                    code: KeyCode::RControl,
2445                    state: KeyState::Up
2446                },
2447            ]
2448        );
2449    }
2450
2451    #[test]
2452    fn usb_change_all_letters() {
2453        let mut keyboard = UsbKeyboard::new(layouts::Us104Key, HandleControl::MapLettersToUnicode);
2454        let iter = keyboard.handle_report_raw(&UsbBootKeyboardReport {
2455            modifiers: 0x00,
2456            keys: [0x04, 0x05, 0x06, 0x07, 0x08, 0x09],
2457        });
2458        let events: Vec<KeyEvent> = iter.collect();
2459        assert_eq!(
2460            &events,
2461            &[
2462                KeyEvent {
2463                    code: KeyCode::A,
2464                    state: KeyState::Down
2465                },
2466                KeyEvent {
2467                    code: KeyCode::B,
2468                    state: KeyState::Down
2469                },
2470                KeyEvent {
2471                    code: KeyCode::C,
2472                    state: KeyState::Down
2473                },
2474                KeyEvent {
2475                    code: KeyCode::D,
2476                    state: KeyState::Down
2477                },
2478                KeyEvent {
2479                    code: KeyCode::E,
2480                    state: KeyState::Down
2481                },
2482                KeyEvent {
2483                    code: KeyCode::F,
2484                    state: KeyState::Down
2485                },
2486            ]
2487        );
2488
2489        let iter = keyboard.handle_report_raw(&UsbBootKeyboardReport {
2490            modifiers: 0x00,
2491            keys: [0x0A, 0x0B, 0x0C, 0xD, 0xE, 0xF],
2492        });
2493        let events: Vec<KeyEvent> = iter.collect();
2494        assert_eq!(
2495            &events,
2496            &[
2497                KeyEvent {
2498                    code: KeyCode::A,
2499                    state: KeyState::Up
2500                },
2501                KeyEvent {
2502                    code: KeyCode::B,
2503                    state: KeyState::Up
2504                },
2505                KeyEvent {
2506                    code: KeyCode::C,
2507                    state: KeyState::Up
2508                },
2509                KeyEvent {
2510                    code: KeyCode::D,
2511                    state: KeyState::Up
2512                },
2513                KeyEvent {
2514                    code: KeyCode::E,
2515                    state: KeyState::Up
2516                },
2517                KeyEvent {
2518                    code: KeyCode::F,
2519                    state: KeyState::Up
2520                },
2521                KeyEvent {
2522                    code: KeyCode::G,
2523                    state: KeyState::Down
2524                },
2525                KeyEvent {
2526                    code: KeyCode::H,
2527                    state: KeyState::Down
2528                },
2529                KeyEvent {
2530                    code: KeyCode::I,
2531                    state: KeyState::Down
2532                },
2533                KeyEvent {
2534                    code: KeyCode::J,
2535                    state: KeyState::Down
2536                },
2537                KeyEvent {
2538                    code: KeyCode::K,
2539                    state: KeyState::Down
2540                },
2541                KeyEvent {
2542                    code: KeyCode::L,
2543                    state: KeyState::Down
2544                },
2545            ]
2546        );
2547
2548        let iter = keyboard.handle_report_raw(&UsbBootKeyboardReport {
2549            modifiers: 0x00,
2550            keys: [0; 6],
2551        });
2552        let events: Vec<KeyEvent> = iter.collect();
2553        assert_eq!(
2554            &events,
2555            &[
2556                KeyEvent {
2557                    code: KeyCode::G,
2558                    state: KeyState::Up
2559                },
2560                KeyEvent {
2561                    code: KeyCode::H,
2562                    state: KeyState::Up
2563                },
2564                KeyEvent {
2565                    code: KeyCode::I,
2566                    state: KeyState::Up
2567                },
2568                KeyEvent {
2569                    code: KeyCode::J,
2570                    state: KeyState::Up
2571                },
2572                KeyEvent {
2573                    code: KeyCode::K,
2574                    state: KeyState::Up
2575                },
2576                KeyEvent {
2577                    code: KeyCode::L,
2578                    state: KeyState::Up
2579                },
2580            ]
2581        );
2582
2583        let iter = keyboard.handle_report_raw(&UsbBootKeyboardReport {
2584            modifiers: 0x00,
2585            keys: [0; 6],
2586        });
2587        let events: Vec<KeyEvent> = iter.collect();
2588        assert!(events.is_empty());
2589    }
2590
2591    #[test]
2592    fn usb_letters() {
2593        let mut keyboard = UsbKeyboard::new(layouts::Us104Key, HandleControl::MapLettersToUnicode);
2594        let iter = keyboard.handle_report_raw(&UsbBootKeyboardReport {
2595            modifiers: 0x00,
2596            keys: [0x04, 0x00, 0x00, 0x00, 0x00, 0x00],
2597        });
2598        let events: Vec<KeyEvent> = iter.collect();
2599        assert_eq!(
2600            &events,
2601            &[KeyEvent {
2602                code: KeyCode::A,
2603                state: KeyState::Down
2604            }]
2605        );
2606
2607        let iter = keyboard.handle_report_raw(&UsbBootKeyboardReport {
2608            modifiers: 0x00,
2609            keys: [0x05, 0x04, 0x00, 0x00, 0x00, 0x00],
2610        });
2611        let events: Vec<KeyEvent> = iter.collect();
2612        assert_eq!(
2613            &events,
2614            &[KeyEvent {
2615                code: KeyCode::B,
2616                state: KeyState::Down
2617            }]
2618        );
2619
2620        let iter = keyboard.handle_report_raw(&UsbBootKeyboardReport {
2621            modifiers: 0x00,
2622            keys: [0x05, 0x06, 0x00, 0x00, 0x00, 0x00],
2623        });
2624        let events: Vec<KeyEvent> = iter.collect();
2625        assert_eq!(
2626            &events,
2627            &[
2628                KeyEvent {
2629                    code: KeyCode::A,
2630                    state: KeyState::Up
2631                },
2632                KeyEvent {
2633                    code: KeyCode::C,
2634                    state: KeyState::Down
2635                },
2636            ]
2637        );
2638
2639        let iter = keyboard.handle_report_raw(&UsbBootKeyboardReport {
2640            modifiers: 0x00,
2641            keys: [0x05, 0x00, 0x00, 0x00, 0x00, 0x00],
2642        });
2643        let events: Vec<KeyEvent> = iter.collect();
2644        assert_eq!(
2645            &events,
2646            &[KeyEvent {
2647                code: KeyCode::C,
2648                state: KeyState::Up
2649            },]
2650        );
2651
2652        let iter = keyboard.handle_report_raw(&UsbBootKeyboardReport {
2653            modifiers: 0x00,
2654            keys: [0; 6],
2655        });
2656        let events: Vec<KeyEvent> = iter.collect();
2657        assert_eq!(
2658            &events,
2659            &[KeyEvent {
2660                code: KeyCode::B,
2661                state: KeyState::Up
2662            },]
2663        );
2664
2665        let iter = keyboard.handle_report_raw(&UsbBootKeyboardReport {
2666            modifiers: 0x00,
2667            keys: [0; 6],
2668        });
2669        let events: Vec<KeyEvent> = iter.collect();
2670        assert!(events.is_empty());
2671    }
2672
2673    #[test]
2674    fn usb_reports() {
2675        // Reports, as captured with `sudo usbhid-dump -a 1:4 -es | tee capture.log`
2676        let reports = [
2677            UsbBootKeyboardReport {
2678                modifiers: 0x02,
2679                keys: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
2680            },
2681            UsbBootKeyboardReport {
2682                modifiers: 0x02,
2683                keys: [0x0B, 0x00, 0x00, 0x00, 0x00, 0x00],
2684            },
2685            UsbBootKeyboardReport {
2686                modifiers: 0x02,
2687                keys: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
2688            },
2689            UsbBootKeyboardReport {
2690                modifiers: 0x00,
2691                keys: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
2692            },
2693            UsbBootKeyboardReport {
2694                modifiers: 0x00,
2695                keys: [0x08, 0x00, 0x00, 0x00, 0x00, 0x00],
2696            },
2697            UsbBootKeyboardReport {
2698                modifiers: 0x00,
2699                keys: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
2700            },
2701            UsbBootKeyboardReport {
2702                modifiers: 0x00,
2703                keys: [0x0F, 0x00, 0x00, 0x00, 0x00, 0x00],
2704            },
2705            UsbBootKeyboardReport {
2706                modifiers: 0x00,
2707                keys: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
2708            },
2709            UsbBootKeyboardReport {
2710                modifiers: 0x00,
2711                keys: [0x0F, 0x00, 0x00, 0x00, 0x00, 0x00],
2712            },
2713            UsbBootKeyboardReport {
2714                modifiers: 0x00,
2715                keys: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
2716            },
2717            UsbBootKeyboardReport {
2718                modifiers: 0x00,
2719                keys: [0x12, 0x00, 0x00, 0x00, 0x00, 0x00],
2720            },
2721            UsbBootKeyboardReport {
2722                modifiers: 0x00,
2723                keys: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
2724            },
2725            UsbBootKeyboardReport {
2726                modifiers: 0x00,
2727                keys: [0x2C, 0x00, 0x00, 0x00, 0x00, 0x00],
2728            },
2729            UsbBootKeyboardReport {
2730                modifiers: 0x00,
2731                keys: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
2732            },
2733            UsbBootKeyboardReport {
2734                modifiers: 0x00,
2735                keys: [0x17, 0x00, 0x00, 0x00, 0x00, 0x00],
2736            },
2737            UsbBootKeyboardReport {
2738                modifiers: 0x00,
2739                keys: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
2740            },
2741            UsbBootKeyboardReport {
2742                modifiers: 0x00,
2743                keys: [0x0B, 0x00, 0x00, 0x00, 0x00, 0x00],
2744            },
2745            UsbBootKeyboardReport {
2746                modifiers: 0x00,
2747                keys: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
2748            },
2749            UsbBootKeyboardReport {
2750                modifiers: 0x00,
2751                keys: [0x0C, 0x00, 0x00, 0x00, 0x00, 0x00],
2752            },
2753            UsbBootKeyboardReport {
2754                modifiers: 0x00,
2755                keys: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
2756            },
2757            UsbBootKeyboardReport {
2758                modifiers: 0x00,
2759                keys: [0x16, 0x00, 0x00, 0x00, 0x00, 0x00],
2760            },
2761            UsbBootKeyboardReport {
2762                modifiers: 0x00,
2763                keys: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
2764            },
2765            UsbBootKeyboardReport {
2766                modifiers: 0x00,
2767                keys: [0x2C, 0x00, 0x00, 0x00, 0x00, 0x00],
2768            },
2769            UsbBootKeyboardReport {
2770                modifiers: 0x00,
2771                keys: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
2772            },
2773            UsbBootKeyboardReport {
2774                modifiers: 0x00,
2775                keys: [0x0C, 0x00, 0x00, 0x00, 0x00, 0x00],
2776            },
2777            UsbBootKeyboardReport {
2778                modifiers: 0x00,
2779                keys: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
2780            },
2781            UsbBootKeyboardReport {
2782                modifiers: 0x00,
2783                keys: [0x16, 0x00, 0x00, 0x00, 0x00, 0x00],
2784            },
2785            UsbBootKeyboardReport {
2786                modifiers: 0x00,
2787                keys: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
2788            },
2789            UsbBootKeyboardReport {
2790                modifiers: 0x00,
2791                keys: [0x2C, 0x00, 0x00, 0x00, 0x00, 0x00],
2792            },
2793            UsbBootKeyboardReport {
2794                modifiers: 0x00,
2795                keys: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
2796            },
2797            UsbBootKeyboardReport {
2798                modifiers: 0x00,
2799                keys: [0x04, 0x00, 0x00, 0x00, 0x00, 0x00],
2800            },
2801            UsbBootKeyboardReport {
2802                modifiers: 0x00,
2803                keys: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
2804            },
2805            UsbBootKeyboardReport {
2806                modifiers: 0x00,
2807                keys: [0x2C, 0x00, 0x00, 0x00, 0x00, 0x00],
2808            },
2809            UsbBootKeyboardReport {
2810                modifiers: 0x00,
2811                keys: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
2812            },
2813            UsbBootKeyboardReport {
2814                modifiers: 0x00,
2815                keys: [0x17, 0x00, 0x00, 0x00, 0x00, 0x00],
2816            },
2817            UsbBootKeyboardReport {
2818                modifiers: 0x00,
2819                keys: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
2820            },
2821            UsbBootKeyboardReport {
2822                modifiers: 0x00,
2823                keys: [0x08, 0x00, 0x00, 0x00, 0x00, 0x00],
2824            },
2825            UsbBootKeyboardReport {
2826                modifiers: 0x00,
2827                keys: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
2828            },
2829            UsbBootKeyboardReport {
2830                modifiers: 0x00,
2831                keys: [0x16, 0x00, 0x00, 0x00, 0x00, 0x00],
2832            },
2833            UsbBootKeyboardReport {
2834                modifiers: 0x00,
2835                keys: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
2836            },
2837            UsbBootKeyboardReport {
2838                modifiers: 0x00,
2839                keys: [0x17, 0x00, 0x00, 0x00, 0x00, 0x00],
2840            },
2841            UsbBootKeyboardReport {
2842                modifiers: 0x00,
2843                keys: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
2844            },
2845            UsbBootKeyboardReport {
2846                modifiers: 0x02,
2847                keys: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
2848            },
2849            UsbBootKeyboardReport {
2850                modifiers: 0x02,
2851                keys: [0x1E, 0x00, 0x00, 0x00, 0x00, 0x00],
2852            },
2853            UsbBootKeyboardReport {
2854                modifiers: 0x02,
2855                keys: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
2856            },
2857            UsbBootKeyboardReport {
2858                modifiers: 0x00,
2859                keys: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
2860            },
2861            UsbBootKeyboardReport {
2862                modifiers: 0x00,
2863                keys: [0x28, 0x00, 0x00, 0x00, 0x00, 0x00],
2864            },
2865            UsbBootKeyboardReport {
2866                modifiers: 0x00,
2867                keys: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
2868            },
2869        ];
2870        let mut output = String::new();
2871        let mut keyboard = UsbKeyboard::new(layouts::Us104Key, HandleControl::MapLettersToUnicode);
2872        for report in reports.iter() {
2873            for ev in keyboard.handle_report(report) {
2874                if let DecodedKey::Unicode(ch) = ev {
2875                    output.push(ch);
2876                }
2877            }
2878        }
2879        assert_eq!("Hello this is a test!\n", output);
2880    }
2881}
2882
2883// ****************************************************************************
2884//
2885// End Of File
2886//
2887// ****************************************************************************