pc_keyboard/layouts/uk105.rs
1//! United Kingdom keyboard support
2
3use crate::{
4 DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers, PhysicalKeyboard, QUO, SLS,
5};
6
7/// A standard United Kingdom 102-key (or 105-key including Windows keys) keyboard.
8///
9/// Has a 2-row high Enter key, with Oem5 next to the left shift (ISO format).
10///
11/// Based on US 101/104 key, with minor changes.
12///
13/// These diagrams illustrate the conversion from [`KeyCode`] to Unicode. We
14/// show either a Unicode glyph, or a hex number if the glyph isn't a
15/// printable character. Blank spaces are passed through as
16/// [`DecodedKey::RawKey`].
17///
18/// Run the `print_keyboard` example to re-generate these images.
19///
20/// ## Unmodified
21///
22/// ```text
23/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐
24/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
25/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘
26///
27/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐
28/// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │
29/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤
30/// │0009 │ q │ w │ e │ r │ t │ y │ u │ i │ o │ p │ [ │ ] │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │
31/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │
32/// │ │ a │ s │ d │ f │ g │ h │ j │ k │ l │ ; │ ' │ # │ │ │ 4 │ 5 │ 6 │ │
33/// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤
34/// │ │ \ │ z │ x │ c │ v │ b │ n │ m │ , │ . │ / │ │ │ │ │ 1 │ 2 │ 3 │ │
35/// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│
36/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │
37/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘
38/// ```
39///
40/// ## Caps Lock
41///
42/// ```text
43/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐
44/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
45/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘
46///
47/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐
48/// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │
49/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤
50/// │0009 │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ [ │ ] │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │
51/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │
52/// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ; │ ' │ # │ │ │ 4 │ 5 │ 6 │ │
53/// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤
54/// │ │ \ │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ / │ │ │ │ │ 1 │ 2 │ 3 │ │
55/// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│
56/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │
57/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘
58/// ```
59///
60/// ## Shifted
61///
62/// ```text
63/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐
64/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
65/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘
66///
67/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐
68/// │ ¬ │ ! │ " │ £ │ $ │ % │ ^ │ & │ * │ ( │ ) │ _ │ + │ 0008 │ │ │ │ │ │ │ / │ * │ - │
69/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤
70/// │0009 │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ { │ } │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │
71/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │
72/// │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ : │ @ │ ~ │ │ │ 4 │ 5 │ 6 │ │
73/// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤
74/// │ │ | │ Z │ X │ C │ V │ B │ N │ M │ < │ > │ ? │ │ │ │ │ 1 │ 2 │ 3 │ │
75/// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│
76/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │
77/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘
78/// ```
79///
80/// ## Control
81///
82/// ```text
83/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐
84/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
85/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘
86///
87/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐
88/// │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │
89/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤
90/// │0009 │0011│0017│0005│0012│0014│0019│0015│0009│000f│0010│ [ │ ] │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │
91/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │
92/// │ │0001│0013│0004│0006│0007│0008│000a│000b│000c│ ; │ ' │ # │ │ │ 4 │ 5 │ 6 │ │
93/// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤
94/// │ │ \ │001a│0018│0003│0016│0002│000e│000d│ , │ . │ / │ │ │ │ │ 1 │ 2 │ 3 │ │
95/// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│
96/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │
97/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘
98/// ```
99///
100/// ## AltGr
101///
102/// ```text
103/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐
104/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
105/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘
106///
107/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐
108/// │ ¦ │ 1 │ 2 │ 3 │ € │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ 0008 │ │ │ │ │ │ │ / │ * │ - │
109/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤
110/// │0009 │ q │ w │ é │ r │ t │ y │ ú │ í │ ó │ p │ [ │ ] │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │
111/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │
112/// │ │ á │ s │ d │ f │ g │ h │ j │ k │ l │ ; │ ' │ # │ │ │ 4 │ 5 │ 6 │ │
113/// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤
114/// │ │ \ │ z │ x │ c │ v │ b │ n │ m │ , │ . │ / │ │ │ │ │ 1 │ 2 │ 3 │ │
115/// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│
116/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │
117/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘
118/// ```
119///
120/// ## Shift AltGr
121///
122/// ```text
123/// ┌────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┬────┐ ┌────┬────┬────┐
124/// │001b│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
125/// └────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┴────┘ └────┴────┴────┘
126///
127/// ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐ ┌────┬────┬────┐ ┌────┬────┬────┬────┐
128/// │ ¦ │ ! │ " │ £ │ € │ % │ ^ │ & │ * │ ( │ ) │ _ │ + │ 0008 │ │ │ │ │ │ │ / │ * │ - │
129/// ├────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬────────┤ ├────┼────┼────┤ ├────┼────┼────┼────┤
130/// │0009 │ Q │ W │ É │ R │ T │ Y │ Ú │ Í │ Ó │ P │ { │ } │ 000a │ │007f│ │ │ │ 7 │ 8 │ 9 │ │
131/// ├─────┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┬───┴┐ │ └────┴────┴────┘ ├────┼────┼────┤ + │
132/// │ │ Á │ S │ D │ F │ G │ H │ J │ K │ L │ : │ @ │ ~ │ │ │ 4 │ 5 │ 6 │ │
133/// ├────┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴──┬─┴────┴───────┤ ┌────┐ ├────┼────┼────┼────┤
134/// │ │ | │ Z │ X │ C │ V │ B │ N │ M │ < │ > │ ? │ │ │ │ │ 1 │ 2 │ 3 │ │
135/// ├────┴┬───┴─┬──┴──┬─┴────┴────┴────┴────┴────┴───┬┴────┼────┴┬──────┬──────┤ ┌────┼────┼────┐ ├────┴────┼────┤000a│
136/// │ │ │ │ 0020 │ │ │ │ │ │ │ │ │ │ 0 │ . │ │
137/// └─────┴─────┴─────┴──────────────────────────────┴─────┴─────┴──────┴──────┘ └────┴────┴────┘ └─────────┴────┴────┘
138/// ```
139pub struct Uk105Key;
140
141impl KeyboardLayout for Uk105Key {
142 #[rustfmt::skip]
143 fn map_keycode(
144 &self,
145 keycode: KeyCode,
146 modifiers: &Modifiers,
147 handle_ctrl: HandleControl,
148 ) -> DecodedKey {
149 match keycode {
150 KeyCode::Key2 => modifiers.handle_symbol2('2', '"'),
151 KeyCode::Key3 => modifiers.handle_symbol2('3', '£'),
152 KeyCode::Key4 => modifiers.handle_symbol3('4', '$', '€'),
153 KeyCode::Oem3 => modifiers.handle_symbol2(QUO, '@'),
154 KeyCode::Oem5 => modifiers.handle_symbol2(SLS, '|'),
155 KeyCode::Oem7 => modifiers.handle_symbol2('#', '~'),
156 KeyCode::Oem8 => modifiers.handle_symbol3('`', '¬', '¦'),
157 KeyCode::E => modifiers.handle_ascii_4('E', 'é', 'É', handle_ctrl),
158 KeyCode::U => modifiers.handle_ascii_4('U', 'ú', 'Ú', handle_ctrl),
159 KeyCode::I => modifiers.handle_ascii_4('I', 'í', 'Í', handle_ctrl),
160 KeyCode::O => modifiers.handle_ascii_4('O', 'ó', 'Ó', handle_ctrl),
161 KeyCode::A => modifiers.handle_ascii_4('A', 'á', 'Á', handle_ctrl),
162 e => super::Us104Key.map_keycode(e, modifiers, handle_ctrl),
163 }
164 }
165
166 fn get_physical(&self) -> PhysicalKeyboard {
167 PhysicalKeyboard::Iso
168 }
169}
170
171#[cfg(test)]
172mod test {
173 use super::*;
174 use crate::{
175 EventDecoder, HandleControl, PS2Keyboard, ScancodeSet, ScancodeSet1, ScancodeSet2,
176 };
177
178 #[test]
179 fn layout() {
180 // Codes taken from https://kbdlayout.info/kbduk/overview+scancodes?arrangement=ISO105
181 let mut s = ScancodeSet1::new();
182 let mut dec = EventDecoder::new(Uk105Key, HandleControl::Ignore);
183 let data = [
184 (0x29, '`'),
185 (0x02, '1'),
186 (0x03, '2'),
187 (0x04, '3'),
188 (0x05, '4'),
189 (0x06, '5'),
190 (0x07, '6'),
191 (0x08, '7'),
192 (0x09, '8'),
193 (0x0a, '9'),
194 (0x0b, '0'),
195 (0x0c, '-'),
196 (0x0d, '='),
197 (0x0f, '\t'),
198 (0x10, 'q'),
199 (0x11, 'w'),
200 (0x12, 'e'),
201 (0x13, 'r'),
202 (0x14, 't'),
203 (0x15, 'y'),
204 (0x16, 'u'),
205 (0x17, 'i'),
206 (0x18, 'o'),
207 (0x19, 'p'),
208 (0x1a, '['),
209 (0x1b, ']'),
210 (0x1e, 'a'),
211 (0x1f, 's'),
212 (0x20, 'd'),
213 (0x21, 'f'),
214 (0x22, 'g'),
215 (0x23, 'h'),
216 (0x24, 'j'),
217 (0x25, 'k'),
218 (0x26, 'l'),
219 (0x27, ';'),
220 (0x28, '\''),
221 (0x2B, '#'),
222 (0x1c, '\n'),
223 (0x56, '\\'),
224 (0x2c, 'z'),
225 (0x2d, 'x'),
226 (0x2e, 'c'),
227 (0x2f, 'v'),
228 (0x30, 'b'),
229 (0x31, 'n'),
230 (0x32, 'm'),
231 (0x33, ','),
232 (0x34, '.'),
233 (0x35, '/'),
234 ];
235 for (code, unicode) in data {
236 let ev = s.advance_state(code).unwrap().unwrap();
237 assert_eq!(Some(DecodedKey::Unicode(unicode)), dec.process_keyevent(ev));
238 }
239 }
240
241 #[test]
242 fn test_hash() {
243 let mut k = PS2Keyboard::new(
244 ScancodeSet2::new(),
245 Uk105Key,
246 HandleControl::MapLettersToUnicode,
247 );
248 // As seen on a UK 105 key Dell PS/2 keyboard when pressing `~#`
249 let ev = k.add_byte(0x5D).unwrap().unwrap();
250 let decoded_key = k.process_keyevent(ev);
251 assert_eq!(decoded_key, Some(DecodedKey::Unicode('#')));
252 }
253
254 #[test]
255 fn test_backslash() {
256 let mut k = PS2Keyboard::new(
257 ScancodeSet2::new(),
258 Uk105Key,
259 HandleControl::MapLettersToUnicode,
260 );
261 // As seen on a UK 105 key Dell PS/2 keyboard when pressing `|\`
262 let ev = k.add_byte(0x61).unwrap().unwrap();
263 let decoded_key = k.process_keyevent(ev);
264 assert_eq!(decoded_key, Some(DecodedKey::Unicode('\\')));
265 }
266
267 #[test]
268 fn test_tilde() {
269 let mut k = PS2Keyboard::new(
270 ScancodeSet2::new(),
271 Uk105Key,
272 HandleControl::MapLettersToUnicode,
273 );
274 // As seen on a UK 105 key Dell PS/2 keyboard when pressing Shift and `~#`
275 let ev = k.add_byte(0x12).unwrap().unwrap();
276 let _ = k.process_keyevent(ev);
277 let ev = k.add_byte(0x5D).unwrap().unwrap();
278 let decoded_key = k.process_keyevent(ev);
279 assert_eq!(decoded_key, Some(DecodedKey::Unicode('~')));
280 }
281
282 #[test]
283 fn test_pipe() {
284 let mut k = PS2Keyboard::new(
285 ScancodeSet2::new(),
286 Uk105Key,
287 HandleControl::MapLettersToUnicode,
288 );
289 // As seen on a UK 105 key Dell PS/2 keyboard when pressing Shift and `|\`
290 let ev = k.add_byte(0x12).unwrap().unwrap();
291 let _ = k.process_keyevent(ev);
292 let ev = k.add_byte(0x61).unwrap().unwrap();
293 let decoded_key = k.process_keyevent(ev);
294 assert_eq!(decoded_key, Some(DecodedKey::Unicode('|')));
295 }
296}