Skip to main content

pc_keyboard/layouts/
us104.rs

1//! # United States keyboard support
2
3use crate::{
4    DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, PhysicalKeyboard, QUO, SLS,
5};
6
7/// A standard United States 101-key (or 104-key including Windows keys) keyboard.
8///
9/// Has a 1-row high Enter key, with Oem5 above (ANSI layout).
10///
11/// These diagrams illustrate the conversion from [`KeyCode`] to Unicode. We
12/// show either a Unicode glyph, or a hex number if the glyph isn't a
13/// printable character. Blank spaces are passed through as
14/// [`DecodedKey::RawKey`].
15///
16/// Run the `print_keyboard` example to re-generate these images.
17///
18/// ## Unmodified
19///
20/// ```text
21/// ┌────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐   ┌────┬────┬────┐
22/// │001b│  │    │    │    │    │  │    │    │    │    │  │    │    │    │    │   │    │    │    │
23/// └────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘   └────┴────┴────┘
24///
25/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐  ┌────┬────┬────┐  ┌────┬────┬────┬────┐
26/// │ `  │ 1  │ 2  │ 3  │ 4  │ 5  │ 6  │ 7  │ 8  │ 9  │ 0  │ -  │ =  │  0008   │  │    │    │    │  │    │ /  │ *  │ -  │
27/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤  ├────┼────┼────┤  ├────┼────┼────┼────┤
28/// │0009 │ q  │ w  │ e  │ r  │ t  │ y  │ u  │ i  │ o  │ p  │ [  │ ]  │   \    │  │007f│    │    │  │ 7  │ 8  │ 9  │    │
29/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤  └────┴────┴────┘  ├────┼────┼────┤ +  │
30/// │      │ a  │ s  │ d  │ f  │ g  │ h  │ j  │ k  │ l  │ ;  │ '  │   000a     │                    │ 4  │ 5  │ 6  │    │
31/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤       ┌────┐       ├────┼────┼────┼────┤
32/// │         │ z  │ x  │ c  │ v  │ b  │ n  │ m  │ ,  │ .  │ /  │              │       │    │       │ 1  │ 2  │ 3  │    │
33/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤  ┌────┼────┼────┐  ├────┴────┼────┤000a│
34/// │     │     │     │             0020             │     │     │      │      │  │    │    │    │  │ 0       │ .  │    │
35/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘  └────┴────┴────┘  └─────────┴────┴────┘
36/// ```
37///
38/// ## Caps Lock
39///
40/// ```text
41/// ┌────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐   ┌────┬────┬────┐
42/// │001b│  │    │    │    │    │  │    │    │    │    │  │    │    │    │    │   │    │    │    │
43/// └────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘   └────┴────┴────┘
44///
45/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐  ┌────┬────┬────┐  ┌────┬────┬────┬────┐
46/// │ `  │ 1  │ 2  │ 3  │ 4  │ 5  │ 6  │ 7  │ 8  │ 9  │ 0  │ -  │ =  │  0008   │  │    │    │    │  │    │ /  │ *  │ -  │
47/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤  ├────┼────┼────┤  ├────┼────┼────┼────┤
48/// │0009 │ Q  │ W  │ E  │ R  │ T  │ Y  │ U  │ I  │ O  │ P  │ [  │ ]  │   \    │  │007f│    │    │  │ 7  │ 8  │ 9  │    │
49/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤  └────┴────┴────┘  ├────┼────┼────┤ +  │
50/// │      │ A  │ S  │ D  │ F  │ G  │ H  │ J  │ K  │ L  │ ;  │ '  │   000a     │                    │ 4  │ 5  │ 6  │    │
51/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤       ┌────┐       ├────┼────┼────┼────┤
52/// │         │ Z  │ X  │ C  │ V  │ B  │ N  │ M  │ ,  │ .  │ /  │              │       │    │       │ 1  │ 2  │ 3  │    │
53/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤  ┌────┼────┼────┐  ├────┴────┼────┤000a│
54/// │     │     │     │             0020             │     │     │      │      │  │    │    │    │  │ 0       │ .  │    │
55/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘  └────┴────┴────┘  └─────────┴────┴────┘
56/// ```
57///
58/// ## Shifted
59///
60/// ```text
61/// ┌────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐   ┌────┬────┬────┐
62/// │001b│  │    │    │    │    │  │    │    │    │    │  │    │    │    │    │   │    │    │    │
63/// └────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘   └────┴────┴────┘
64///
65/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐  ┌────┬────┬────┐  ┌────┬────┬────┬────┐
66/// │ ~  │ !  │ @  │ #  │ $  │ %  │ ^  │ &  │ *  │ (  │ )  │ _  │ +  │  0008   │  │    │    │    │  │    │ /  │ *  │ -  │
67/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤  ├────┼────┼────┤  ├────┼────┼────┼────┤
68/// │0009 │ Q  │ W  │ E  │ R  │ T  │ Y  │ U  │ I  │ O  │ P  │ {  │ }  │   |    │  │007f│    │    │  │ 7  │ 8  │ 9  │    │
69/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤  └────┴────┴────┘  ├────┼────┼────┤ +  │
70/// │      │ A  │ S  │ D  │ F  │ G  │ H  │ J  │ K  │ L  │ :  │ "  │   000a     │                    │ 4  │ 5  │ 6  │    │
71/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤       ┌────┐       ├────┼────┼────┼────┤
72/// │         │ Z  │ X  │ C  │ V  │ B  │ N  │ M  │ <  │ >  │ ?  │              │       │    │       │ 1  │ 2  │ 3  │    │
73/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤  ┌────┼────┼────┐  ├────┴────┼────┤000a│
74/// │     │     │     │             0020             │     │     │      │      │  │    │    │    │  │ 0       │ .  │    │
75/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘  └────┴────┴────┘  └─────────┴────┴────┘
76/// ```
77///
78/// ## Control
79///
80/// ```text
81/// ┌────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐   ┌────┬────┬────┐
82/// │001b│  │    │    │    │    │  │    │    │    │    │  │    │    │    │    │   │    │    │    │
83/// └────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘   └────┴────┴────┘
84///
85/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐  ┌────┬────┬────┐  ┌────┬────┬────┬────┐
86/// │ `  │ 1  │ 2  │ 3  │ 4  │ 5  │ 6  │ 7  │ 8  │ 9  │ 0  │ -  │ =  │  0008   │  │    │    │    │  │    │ /  │ *  │ -  │
87/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤  ├────┼────┼────┤  ├────┼────┼────┼────┤
88/// │0009 │0011│0017│0005│0012│0014│0019│0015│0009│000f│0010│ [  │ ]  │   \    │  │007f│    │    │  │ 7  │ 8  │ 9  │    │
89/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤  └────┴────┴────┘  ├────┼────┼────┤ +  │
90/// │      │0001│0013│0004│0006│0007│0008│000a│000b│000c│ ;  │ '  │   000a     │                    │ 4  │ 5  │ 6  │    │
91/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤       ┌────┐       ├────┼────┼────┼────┤
92/// │         │001a│0018│0003│0016│0002│000e│000d│ ,  │ .  │ /  │              │       │    │       │ 1  │ 2  │ 3  │    │
93/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤  ┌────┼────┼────┐  ├────┴────┼────┤000a│
94/// │     │     │     │             0020             │     │     │      │      │  │    │    │    │  │ 0       │ .  │    │
95/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘  └────┴────┴────┘  └─────────┴────┴────┘
96/// ```
97///
98/// ## AltGr
99///
100/// ```text
101/// ┌────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐   ┌────┬────┬────┐
102/// │001b│  │    │    │    │    │  │    │    │    │    │  │    │    │    │    │   │    │    │    │
103/// └────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘   └────┴────┴────┘
104///
105/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐  ┌────┬────┬────┐  ┌────┬────┬────┬────┐
106/// │ `  │ 1  │ 2  │ 3  │ 4  │ 5  │ 6  │ 7  │ 8  │ 9  │ 0  │ -  │ =  │  0008   │  │    │    │    │  │    │ /  │ *  │ -  │
107/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤  ├────┼────┼────┤  ├────┼────┼────┼────┤
108/// │0009 │ q  │ w  │ e  │ r  │ t  │ y  │ u  │ i  │ o  │ p  │ [  │ ]  │   \    │  │007f│    │    │  │ 7  │ 8  │ 9  │    │
109/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤  └────┴────┴────┘  ├────┼────┼────┤ +  │
110/// │      │ a  │ s  │ d  │ f  │ g  │ h  │ j  │ k  │ l  │ ;  │ '  │   000a     │                    │ 4  │ 5  │ 6  │    │
111/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤       ┌────┐       ├────┼────┼────┼────┤
112/// │         │ z  │ x  │ c  │ v  │ b  │ n  │ m  │ ,  │ .  │ /  │              │       │    │       │ 1  │ 2  │ 3  │    │
113/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤  ┌────┼────┼────┐  ├────┴────┼────┤000a│
114/// │     │     │     │             0020             │     │     │      │      │  │    │    │    │  │ 0       │ .  │    │
115/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘  └────┴────┴────┘  └─────────┴────┴────┘
116/// ```
117///
118/// ## Shift AltGr
119///
120/// ```text
121/// ┌────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐  ┌────┬────┬────┬────┐   ┌────┬────┬────┐
122/// │001b│  │    │    │    │    │  │    │    │    │    │  │    │    │    │    │   │    │    │    │
123/// └────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘  └────┴────┴────┴────┘   └────┴────┴────┘
124///
125/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐  ┌────┬────┬────┐  ┌────┬────┬────┬────┐
126/// │ ~  │ !  │ @  │ #  │ $  │ %  │ ^  │ &  │ *  │ (  │ )  │ _  │ +  │  0008   │  │    │    │    │  │    │ /  │ *  │ -  │
127/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤  ├────┼────┼────┤  ├────┼────┼────┼────┤
128/// │0009 │ Q  │ W  │ E  │ R  │ T  │ Y  │ U  │ I  │ O  │ P  │ {  │ }  │   |    │  │007f│    │    │  │ 7  │ 8  │ 9  │    │
129/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴────────┤  └────┴────┴────┘  ├────┼────┼────┤ +  │
130/// │      │ A  │ S  │ D  │ F  │ G  │ H  │ J  │ K  │ L  │ :  │ "  │   000a     │                    │ 4  │ 5  │ 6  │    │
131/// ├──────┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────────────┤       ┌────┐       ├────┼────┼────┼────┤
132/// │         │ Z  │ X  │ C  │ V  │ B  │ N  │ M  │ <  │ >  │ ?  │              │       │    │       │ 1  │ 2  │ 3  │    │
133/// ├─────┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤  ┌────┼────┼────┐  ├────┴────┼────┤000a│
134/// │     │     │     │             0020             │     │     │      │      │  │    │    │    │  │ 0       │ .  │    │
135/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘  └────┴────┴────┘  └─────────┴────┴────┘
136/// ```
137pub struct Us104Key;
138
139impl KeyboardLayout for Us104Key {
140    #[rustfmt::skip]
141    fn map_keycode(
142        &self,
143        keycode: KeyCode,
144        modifiers: &Modifiers,
145        handle_ctrl: HandleControl,
146    ) -> DecodedKey {
147        match keycode {
148            // ========= Row 2 (the numbers) =========
149            KeyCode::Oem8            => modifiers.handle_symbol2('`', '~'),
150            KeyCode::Escape          => DecodedKey::Unicode('\u{001B}'),
151            KeyCode::Key1            => modifiers.handle_symbol2('1', '!'),
152            KeyCode::Key2            => modifiers.handle_symbol2('2', '@'),
153            KeyCode::Key3            => modifiers.handle_symbol2('3', '#'),
154            KeyCode::Key4            => modifiers.handle_symbol2('4', '$'),
155            KeyCode::Key5            => modifiers.handle_symbol2('5', '%'),
156            KeyCode::Key6            => modifiers.handle_symbol2('6', '^'),
157            KeyCode::Key7            => modifiers.handle_symbol2('7', '&'),
158            KeyCode::Key8            => modifiers.handle_symbol2('8', '*'),
159            KeyCode::Key9            => modifiers.handle_symbol2('9', '('),
160            KeyCode::Key0            => modifiers.handle_symbol2('0', ')'),
161            KeyCode::OemMinus        => modifiers.handle_symbol2('-', '_'),
162            KeyCode::OemPlus         => modifiers.handle_symbol2('=', '+'),
163            KeyCode::Backspace       => DecodedKey::Unicode('\u{0008}'),
164            // ========= Row 3 (QWERTY) =========
165            KeyCode::Tab             => DecodedKey::Unicode('\u{0009}'),
166            KeyCode::Q               => modifiers.handle_ascii_2('Q', handle_ctrl),
167            KeyCode::W               => modifiers.handle_ascii_2('W', handle_ctrl),
168            KeyCode::E               => modifiers.handle_ascii_2('E', handle_ctrl),
169            KeyCode::R               => modifiers.handle_ascii_2('R', handle_ctrl),
170            KeyCode::T               => modifiers.handle_ascii_2('T', handle_ctrl),
171            KeyCode::Y               => modifiers.handle_ascii_2('Y', handle_ctrl),
172            KeyCode::U               => modifiers.handle_ascii_2('U', handle_ctrl),
173            KeyCode::I               => modifiers.handle_ascii_2('I', handle_ctrl),
174            KeyCode::O               => modifiers.handle_ascii_2('O', handle_ctrl),
175            KeyCode::P               => modifiers.handle_ascii_2('P', handle_ctrl),
176            KeyCode::Oem4            => modifiers.handle_symbol2('[', '{'),
177            KeyCode::Oem6            => modifiers.handle_symbol2(']', '}'),
178            KeyCode::Oem7            => modifiers.handle_symbol2(SLS, '|'),
179            // ========= Row 4 (ASDFG) =========
180            KeyCode::A               => modifiers.handle_ascii_2('A', handle_ctrl),
181            KeyCode::S               => modifiers.handle_ascii_2('S', handle_ctrl),
182            KeyCode::D               => modifiers.handle_ascii_2('D', handle_ctrl),
183            KeyCode::F               => modifiers.handle_ascii_2('F', handle_ctrl),
184            KeyCode::G               => modifiers.handle_ascii_2('G', handle_ctrl),
185            KeyCode::H               => modifiers.handle_ascii_2('H', handle_ctrl),
186            KeyCode::J               => modifiers.handle_ascii_2('J', handle_ctrl),
187            KeyCode::K               => modifiers.handle_ascii_2('K', handle_ctrl),
188            KeyCode::L               => modifiers.handle_ascii_2('L', handle_ctrl),
189            KeyCode::Oem1            => modifiers.handle_symbol2(';', ':'),
190            KeyCode::Oem3            => modifiers.handle_symbol2(QUO, '"'),
191            KeyCode::Return          => DecodedKey::Unicode('\u{000A}'),
192            // ========= Row 5 (ZXCVB) =========
193            KeyCode::Z               => modifiers.handle_ascii_2('Z', handle_ctrl),
194            KeyCode::X               => modifiers.handle_ascii_2('X', handle_ctrl),
195            KeyCode::C               => modifiers.handle_ascii_2('C', handle_ctrl),
196            KeyCode::V               => modifiers.handle_ascii_2('V', handle_ctrl),
197            KeyCode::B               => modifiers.handle_ascii_2('B', handle_ctrl),
198            KeyCode::N               => modifiers.handle_ascii_2('N', handle_ctrl),
199            KeyCode::M               => modifiers.handle_ascii_2('M', handle_ctrl),
200            KeyCode::OemComma        => modifiers.handle_symbol2(',', '<'),
201            KeyCode::OemPeriod       => modifiers.handle_symbol2('.', '>'),
202            KeyCode::Oem2            => modifiers.handle_symbol2('/', '?'),
203            // ========= Unicode Specials =========
204            KeyCode::Spacebar        => DecodedKey::Unicode(' '),
205            KeyCode::Delete          => DecodedKey::Unicode('\u{007f}'),
206            // ========= Numpad =========
207            KeyCode::NumpadDivide    => DecodedKey::Unicode('/'),
208            KeyCode::NumpadMultiply  => DecodedKey::Unicode('*'),
209            KeyCode::NumpadSubtract  => DecodedKey::Unicode('-'),
210            KeyCode::Numpad7         => modifiers.handle_num_pad('7', KeyCode::Home),
211            KeyCode::Numpad8         => modifiers.handle_num_pad('8', KeyCode::ArrowUp),
212            KeyCode::Numpad9         => modifiers.handle_num_pad('9', KeyCode::PageUp),
213            KeyCode::NumpadAdd       => DecodedKey::Unicode('+'),
214            KeyCode::Numpad4         => modifiers.handle_num_pad('4', KeyCode::ArrowLeft),
215            KeyCode::Numpad5         => DecodedKey::Unicode('5'),
216            KeyCode::Numpad6         => modifiers.handle_num_pad('6', KeyCode::ArrowRight),
217            KeyCode::Numpad1         => modifiers.handle_num_pad('1', KeyCode::End),
218            KeyCode::Numpad2         => modifiers.handle_num_pad('2', KeyCode::ArrowDown),
219            KeyCode::Numpad3         => modifiers.handle_num_pad('3', KeyCode::PageDown),
220            KeyCode::Numpad0         => modifiers.handle_num_pad('0', KeyCode::Insert),
221            KeyCode::NumpadPeriod    => modifiers.handle_num_del('.', '\u{007f}'),
222            KeyCode::NumpadEnter     => DecodedKey::Unicode('\u{000A}'),
223            // ========= Fallback =========
224            k                        => DecodedKey::RawKey(k),
225        }
226    }
227
228    fn get_physical(&self) -> PhysicalKeyboard {
229        PhysicalKeyboard::Ansi
230    }
231}
232
233#[cfg(test)]
234mod test {
235    use super::*;
236    use crate::{EventDecoder, ScancodeSet, ScancodeSet1};
237
238    #[test]
239    fn layout() {
240        // Codes taken from https://kbdlayout.info/kbdus/overview+scancodes?arrangement=ANSI104
241        let mut s = ScancodeSet1::new();
242        let mut dec = EventDecoder::new(Us104Key, HandleControl::Ignore);
243        let data = [
244            (0x29, '`'),
245            (0x02, '1'),
246            (0x03, '2'),
247            (0x04, '3'),
248            (0x05, '4'),
249            (0x06, '5'),
250            (0x07, '6'),
251            (0x08, '7'),
252            (0x09, '8'),
253            (0x0a, '9'),
254            (0x0b, '0'),
255            (0x0c, '-'),
256            (0x0d, '='),
257            (0x0f, '\t'),
258            (0x10, 'q'),
259            (0x11, 'w'),
260            (0x12, 'e'),
261            (0x13, 'r'),
262            (0x14, 't'),
263            (0x15, 'y'),
264            (0x16, 'u'),
265            (0x17, 'i'),
266            (0x18, 'o'),
267            (0x19, 'p'),
268            (0x1a, '['),
269            (0x1b, ']'),
270            (0x2b, '\\'),
271            (0x1e, 'a'),
272            (0x1f, 's'),
273            (0x20, 'd'),
274            (0x21, 'f'),
275            (0x22, 'g'),
276            (0x23, 'h'),
277            (0x24, 'j'),
278            (0x25, 'k'),
279            (0x26, 'l'),
280            (0x27, ';'),
281            (0x28, '\''),
282            (0x1c, '\n'),
283            (0x2c, 'z'),
284            (0x2d, 'x'),
285            (0x2e, 'c'),
286            (0x2f, 'v'),
287            (0x30, 'b'),
288            (0x31, 'n'),
289            (0x32, 'm'),
290            (0x33, ','),
291            (0x34, '.'),
292            (0x35, '/'),
293        ];
294        for (code, unicode) in data {
295            let ev = s.advance_state(code).unwrap().unwrap();
296            assert_eq!(Some(DecodedKey::Unicode(unicode)), dec.process_keyevent(ev));
297        }
298    }
299
300    #[test]
301    fn lowercase() {
302        let modifiers = Modifiers {
303            capslock: false,
304            lalt: false,
305            lctrl: false,
306            lshift: false,
307            numlock: false,
308            ralt: false,
309            rctrl: false,
310            rctrl2: false,
311            rshift: false,
312        };
313        assert_eq!(
314            modifiers.handle_ascii_2('A', HandleControl::MapLettersToUnicode),
315            DecodedKey::Unicode('a')
316        );
317    }
318
319    #[test]
320    fn uppercase() {
321        let modifiers = Modifiers {
322            capslock: true,
323            lalt: false,
324            lctrl: false,
325            lshift: false,
326            numlock: false,
327            ralt: false,
328            rctrl: false,
329            rctrl2: false,
330            rshift: false,
331        };
332        assert_eq!(
333            modifiers.handle_ascii_2('A', HandleControl::MapLettersToUnicode),
334            DecodedKey::Unicode('A')
335        );
336    }
337
338    #[test]
339    fn shifted() {
340        let modifiers = Modifiers {
341            capslock: false,
342            lalt: false,
343            lctrl: false,
344            lshift: true,
345            numlock: false,
346            ralt: false,
347            rctrl: false,
348            rctrl2: false,
349            rshift: false,
350        };
351        assert_eq!(
352            modifiers.handle_ascii_2('A', HandleControl::MapLettersToUnicode),
353            DecodedKey::Unicode('A')
354        );
355    }
356
357    #[test]
358    fn shift_caps() {
359        let modifiers = Modifiers {
360            capslock: true,
361            lalt: false,
362            lctrl: false,
363            lshift: true,
364            numlock: false,
365            ralt: false,
366            rctrl: false,
367            rctrl2: false,
368            rshift: false,
369        };
370        assert_eq!(
371            modifiers.handle_ascii_2('A', HandleControl::MapLettersToUnicode),
372            DecodedKey::Unicode('a')
373        );
374    }
375
376    #[test]
377    fn ctrl() {
378        let modifiers = Modifiers {
379            capslock: true,
380            lalt: false,
381            lctrl: true,
382            lshift: true,
383            numlock: false,
384            ralt: false,
385            rctrl: false,
386            rctrl2: false,
387            rshift: false,
388        };
389        assert_eq!(
390            modifiers.handle_ascii_2('A', HandleControl::MapLettersToUnicode),
391            DecodedKey::Unicode('\u{0001}')
392        );
393    }
394}