Skip to main content

openloaf_rdev/keycodes/
windows.rs

1use crate::rdev::Key;
2
3macro_rules! decl_keycodes {
4    ($($key:ident, $code:literal, $scancode:literal),*) => {
5        //TODO: make const when rust lang issue #49146 is fixed
6        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        //TODO: make const when rust lang issue #49146 is fixed
17        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                // note: alt and altgr have same scancode.
54                // slash and divide.
55                // left control and right control .
56                key
57            } else if scancode_key != Key::Unknown(scancode) {
58                // note: numpad should use scancode directly,
59                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
78// TODO: 0
79
80// https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
81// https://learn.microsoft.com/en-us/windows/win32/inputdev/about-keyboard-input
82// https://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/translate.pdf
83// We redefined here for Letter and number keys which are not in winapi crate (and don't have a name either in win32)
84decl_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,     // Note 1
92    UpArrow, 38, 0xE048,    // Note 1
93    DownArrow, 40, 0xE050,  // Note 1
94    LeftArrow, 37, 0xE04B,  // Note 1
95    RightArrow, 39, 0xE04D, // Note 1
96    End, 35, 0xE04F,        // Note 1
97    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,       // Note 1
123    MetaLeft, 91, 0xE05B,
124    PageDown, 34, 0xE051,   // Note 1
125    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,    // Note 4. Make: E0 2A  E0 37, Break E0 B7  E0 AA
132    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,     // Note 1
186    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}