1use crate::rdev::Key;
2
3macro_rules! decl_keycodes {
4 ($($key:ident, $code:literal, $scancode:literal),*) => {
5 pub fn code_from_key(key: Key) -> Option<u32> {
7 match key {
8 $(
9 Key::$key => Some($code),
10 )*
11 Key::Unknown(code) => Some(code as _),
12 _ => None,
13 }
14 }
15
16 pub fn key_from_code(code: u32) -> Key {
18 #[allow(unreachable_patterns)]
19 match code {
20 $(
21 $code => Key::$key,
22 )*
23 _ => Key::Unknown(code as _)
24 }
25 }
26
27 pub fn scancode_from_key(key: Key) -> Option<u32> {
28 match key {
29 $(
30 Key::$key => Some($scancode),
31 )*
32 Key::Unknown(code) => Some(code as u32),
33 _ => None,
34 }
35 }
36
37 pub fn key_from_scancode(scancode: u32) -> Key{
38 #[allow(unreachable_patterns)]
39 match scancode {
40 0 => Key::Unknown(0),
41 $(
42 $scancode => Key::$key,
43 )*
44 _ => Key::Unknown(scancode as _)
45 }
46 }
47
48 pub fn get_win_key(keycode: u32, scancode: u32) -> Key{
49 let key = key_from_code(keycode);
50 let scancode_key = key_from_scancode(scancode);
51
52 if key == Key::AltGr || key == Key::KpDivide || key == Key::ControlRight {
53 key
57 } else if scancode_key != Key::Unknown(scancode) {
58 scancode_key
60 } else {
61 key
62 }
63 }
64
65 pub fn get_win_codes(key: Key) -> Option<(u32, u32)>{
66 let keycode = code_from_key(key)?;
67 let key = if key == Key::Unknown(keycode){
68 key_from_code(keycode)
69 }else{
70 key
71 };
72 let scancode = scancode_from_key(key)?;
73 Some((keycode, scancode))
74 }
75 };
76}
77
78decl_keycodes! {
85 Alt, 164, 0x38,
86 AltGr, 165, 0xE038,
87 Backspace, 0x08, 0x0E,
88 CapsLock, 20, 0x3A,
89 ControlLeft, 162, 0x1D,
90 ControlRight, 163, 0xE01D,
91 Delete, 46, 0xE053, UpArrow, 38, 0xE048, DownArrow, 40, 0xE050, LeftArrow, 37, 0xE04B, RightArrow, 39, 0xE04D, End, 35, 0xE04F, Escape, 27, 0x01,
98 F1, 112, 0x3B,
99 F2, 113, 0x3C,
100 F3, 114, 0x3D,
101 F4, 115, 0x3E,
102 F5, 116, 0x3F,
103 F6, 117, 0x40,
104 F7, 118, 0x41,
105 F8, 119, 0x42,
106 F9, 120, 0x43,
107 F10, 121, 0x44,
108 F11, 122, 0x57,
109 F12, 123, 0x58,
110 F13, 0x7C, 0x64,
111 F14, 0x7D, 0x65,
112 F15, 0x7E, 0x66,
113 F16, 0x7F, 0x67,
114 F17, 0x80, 0x68,
115 F18, 0x81, 0x69,
116 F19, 0x82, 0x6A,
117 F20, 0x83, 0x6B,
118 F21, 0x84, 0x6C,
119 F22, 0x85, 0x6D,
120 F23, 0x86, 0x6E,
121 F24, 0x87, 0x76,
122 Home, 36, 0xE047, MetaLeft, 91, 0xE05B,
124 PageDown, 34, 0xE051, PageUp, 33, 0xE049,
126 Return, 13, 0x1C,
127 ShiftLeft, 160, 0x2A,
128 ShiftRight, 161, 0x36,
129 Space, 32, 0x39,
130 Tab, 0x09, 0x0F,
131 PrintScreen, 44, 0xE037, ScrollLock, 145, 0x46,
133 NumLock, 144, 0x45,
134 BackQuote, 192, 0x29,
135 Num1, 49, 0x02,
136 Num2, 50, 0x03,
137 Num3, 51, 0x04,
138 Num4, 52, 0x05,
139 Num5, 53, 0x06,
140 Num6, 54, 0x07,
141 Num7, 55, 0x08,
142 Num8, 56, 0x09,
143 Num9, 57, 0x0A,
144 Num0, 48, 0x0B,
145 Minus, 189, 0x0C,
146 Equal, 187, 0x0D,
147 KeyQ, 81, 0x10,
148 KeyW, 87, 0x11,
149 KeyE, 69, 0x12,
150 KeyR, 82, 0x13,
151 KeyT, 84, 0x14,
152 KeyY, 89, 0x15,
153 KeyU, 85, 0x16,
154 KeyI, 73, 0x17,
155 KeyO, 79, 0x18,
156 KeyP, 80, 0x19,
157 LeftBracket, 219, 0x1A,
158 RightBracket, 221, 0x1B,
159 BackSlash, 220, 0x2B,
160 KeyA, 65, 0x1E,
161 KeyS, 83, 0x1F,
162 KeyD, 68, 0x20,
163 KeyF, 70, 0x21,
164 KeyG, 71, 0x22,
165 KeyH, 72, 0x23,
166 KeyJ, 74, 0x24,
167 KeyK, 75, 0x25,
168 KeyL, 76, 0x26,
169 SemiColon, 186, 0x27,
170 Quote, 222, 0x28,
171 IntlBackslash, 226, 0x56,
172 IntlRo, 0x00E2, 0x0073,
173 IntlYen, 0x00DC, 0x007D,
174 KanaMode, 0x0000, 0x70,
175 KeyZ, 90, 0x2C,
176 KeyX, 88, 0x2D,
177 KeyC, 67, 0x2E,
178 KeyV, 86, 0x2F,
179 KeyB, 66, 0x30,
180 KeyN, 78, 0x31,
181 KeyM, 77, 0x32,
182 Comma, 188, 0x33,
183 Dot, 190, 0x34,
184 Slash, 191, 0x35,
185 Insert, 45, 0xE052, KpMinus, 109, 0x4A,
187 KpPlus, 107, 0x4E,
188 KpMultiply, 106, 0x37,
189 KpDivide, 111, 0xE035,
190 KpDecimal, 110, 0x53,
191 KpReturn, 13, 0xE01C,
192 KpEqual, 0x0000, 0x59,
193 KpComma, 0x0000, 0x7E,
194 Kp0, 96, 0x52,
195 Kp1, 97, 0x4F,
196 Kp2, 98, 0x50,
197 Kp3, 99, 0x51,
198 Kp4, 100, 0x4B,
199 Kp5, 101, 0x4C,
200 Kp6, 102, 0x4D,
201 Kp7, 103, 0x47,
202 Kp8, 104, 0x48,
203 Kp9, 105, 0x49,
204 MetaRight, 92, 0xE05C,
205 Apps, 93, 0xE05D,
206 VolumeUp, 0x00AF, 0xE030,
207 VolumeDown, 0x00AE, 0xE02E,
208 VolumeMute, 0x00AD, 0xE020,
209 Lang1, 0x1D, 0x007b,
210 Lang2, 0x1C, 0x0079,
211 Lang3, 0x0000, 0x0078,
212 Lang4, 0x0000, 0x0077,
213 Lang5, 0x0000, 0x0076,
214 Cancel, 0x03, 0x0000,
215 Clear, 12, 0x0000,
216 Kana, 0x15, 0x0080,
217 Junja, 0x17, 0x0000,
218 Final, 0x18, 0x0000,
219 Hanja, 0x19, 0x00f1,
220 Select, 0x29, 0x0000,
221 Print, 0x2A, 0x0000,
222 Execute, 0x2B, 0x0000,
223 Help, 0x2F, 0x0000,
224 Sleep, 0x5F, 0x0000,
225 Separator, 0x6C, 0x0000,
226 Pause, 19, 0x0000
227}
228
229#[cfg(test)]
230mod test {
231 use super::{code_from_key, key_from_code};
232 #[test]
233 fn test_reversible() {
234 for code in 0..65535 {
235 let key = key_from_code(code);
236 if let Some(code2) = code_from_key(key) {
237 assert_eq!(code, code2)
238 } else {
239 assert!(false, "We could not convert back code: {:?}", code);
240 }
241 }
242 }
243}