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// ****************************************************************************