1use crate::scancode::Scancode;
8
9pub const SCANCODE_MASK: u32 = 1 << 30;
12
13#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
15#[repr(transparent)]
16pub struct Keycode(pub u32);
17
18impl Keycode {
19 #[inline]
20 pub const fn new(raw: u32) -> Self {
21 Self(raw)
22 }
23
24 #[inline]
25 pub const fn raw(self) -> u32 {
26 self.0
27 }
28
29 #[inline]
31 pub const fn from_scancode(sc: Scancode) -> Self {
32 Self(sc.raw() | SCANCODE_MASK)
33 }
34
35 #[inline]
37 pub const fn to_scancode(self) -> Option<Scancode> {
38 if self.0 & SCANCODE_MASK != 0 {
39 Some(Scancode::new(self.0 & !SCANCODE_MASK))
40 } else {
41 None
42 }
43 }
44
45 #[inline]
47 pub fn to_char(self) -> Option<char> {
48 if self.0 & SCANCODE_MASK != 0 {
49 None
50 } else {
51 char::from_u32(self.0)
52 }
53 }
54}
55
56impl From<u32> for Keycode {
57 #[inline]
58 fn from(value: u32) -> Self {
59 Keycode(value)
60 }
61}
62
63impl From<Keycode> for u32 {
64 #[inline]
65 fn from(value: Keycode) -> Self {
66 value.0
67 }
68}
69
70impl From<char> for Keycode {
71 #[inline]
72 fn from(c: char) -> Self {
73 Keycode(c as u32)
74 }
75}
76
77impl Keycode {
79 pub const UNKNOWN: Keycode = Keycode(0);
80 pub const RETURN: Keycode = Keycode(b'\r' as u32);
81 pub const ESCAPE: Keycode = Keycode::from_scancode(Scancode::ESCAPE);
82 pub const BACKSPACE: Keycode = Keycode(0x08);
83 pub const TAB: Keycode = Keycode(b'\t' as u32);
84 pub const SPACE: Keycode = Keycode(b' ' as u32);
85
86 pub const EXCLAIM: Keycode = Keycode(b'!' as u32);
87 pub const QUOTEDBL: Keycode = Keycode(b'"' as u32);
88 pub const HASH: Keycode = Keycode(b'#' as u32);
89 pub const DOLLAR: Keycode = Keycode(b'$' as u32);
90 pub const PERCENT: Keycode = Keycode(b'%' as u32);
91 pub const AMPERSAND: Keycode = Keycode(b'&' as u32);
92 pub const QUOTE: Keycode = Keycode(b'\'' as u32);
93 pub const LEFTPAREN: Keycode = Keycode(b'(' as u32);
94 pub const RIGHTPAREN: Keycode = Keycode(b')' as u32);
95 pub const ASTERISK: Keycode = Keycode(b'*' as u32);
96 pub const PLUS: Keycode = Keycode(b'+' as u32);
97 pub const COMMA: Keycode = Keycode(b',' as u32);
98 pub const MINUS: Keycode = Keycode(b'-' as u32);
99 pub const PERIOD: Keycode = Keycode(b'.' as u32);
100 pub const SLASH: Keycode = Keycode(b'/' as u32);
101
102 pub const NUM_0: Keycode = Keycode(b'0' as u32);
103 pub const NUM_1: Keycode = Keycode(b'1' as u32);
104 pub const NUM_2: Keycode = Keycode(b'2' as u32);
105 pub const NUM_3: Keycode = Keycode(b'3' as u32);
106 pub const NUM_4: Keycode = Keycode(b'4' as u32);
107 pub const NUM_5: Keycode = Keycode(b'5' as u32);
108 pub const NUM_6: Keycode = Keycode(b'6' as u32);
109 pub const NUM_7: Keycode = Keycode(b'7' as u32);
110 pub const NUM_8: Keycode = Keycode(b'8' as u32);
111 pub const NUM_9: Keycode = Keycode(b'9' as u32);
112
113 pub const COLON: Keycode = Keycode(b':' as u32);
114 pub const SEMICOLON: Keycode = Keycode(b';' as u32);
115 pub const LESS: Keycode = Keycode(b'<' as u32);
116 pub const EQUALS: Keycode = Keycode(b'=' as u32);
117 pub const GREATER: Keycode = Keycode(b'>' as u32);
118 pub const QUESTION: Keycode = Keycode(b'?' as u32);
119 pub const AT: Keycode = Keycode(b'@' as u32);
120 pub const LEFTBRACKET: Keycode = Keycode(b'[' as u32);
121 pub const BACKSLASH: Keycode = Keycode(b'\\' as u32);
122 pub const RIGHTBRACKET: Keycode = Keycode(b']' as u32);
123 pub const CARET: Keycode = Keycode(b'^' as u32);
124 pub const UNDERSCORE: Keycode = Keycode(b'_' as u32);
125 pub const BACKQUOTE: Keycode = Keycode(b'`' as u32);
126
127 pub const A: Keycode = Keycode(b'a' as u32);
129 pub const B: Keycode = Keycode(b'b' as u32);
130 pub const C: Keycode = Keycode(b'c' as u32);
131 pub const D: Keycode = Keycode(b'd' as u32);
132 pub const E: Keycode = Keycode(b'e' as u32);
133 pub const F: Keycode = Keycode(b'f' as u32);
134 pub const G: Keycode = Keycode(b'g' as u32);
135 pub const H: Keycode = Keycode(b'h' as u32);
136 pub const I: Keycode = Keycode(b'i' as u32);
137 pub const J: Keycode = Keycode(b'j' as u32);
138 pub const K: Keycode = Keycode(b'k' as u32);
139 pub const L: Keycode = Keycode(b'l' as u32);
140 pub const M: Keycode = Keycode(b'm' as u32);
141 pub const N: Keycode = Keycode(b'n' as u32);
142 pub const O: Keycode = Keycode(b'o' as u32);
143 pub const P: Keycode = Keycode(b'p' as u32);
144 pub const Q: Keycode = Keycode(b'q' as u32);
145 pub const R: Keycode = Keycode(b'r' as u32);
146 pub const S: Keycode = Keycode(b's' as u32);
147 pub const T: Keycode = Keycode(b't' as u32);
148 pub const U: Keycode = Keycode(b'u' as u32);
149 pub const V: Keycode = Keycode(b'v' as u32);
150 pub const W: Keycode = Keycode(b'w' as u32);
151 pub const X: Keycode = Keycode(b'x' as u32);
152 pub const Y: Keycode = Keycode(b'y' as u32);
153 pub const Z: Keycode = Keycode(b'z' as u32);
154
155 pub const CAPSLOCK: Keycode = Keycode::from_scancode(Scancode::CAPSLOCK);
157
158 pub const F1: Keycode = Keycode::from_scancode(Scancode::F1);
159 pub const F2: Keycode = Keycode::from_scancode(Scancode::F2);
160 pub const F3: Keycode = Keycode::from_scancode(Scancode::F3);
161 pub const F4: Keycode = Keycode::from_scancode(Scancode::F4);
162 pub const F5: Keycode = Keycode::from_scancode(Scancode::F5);
163 pub const F6: Keycode = Keycode::from_scancode(Scancode::F6);
164 pub const F7: Keycode = Keycode::from_scancode(Scancode::F7);
165 pub const F8: Keycode = Keycode::from_scancode(Scancode::F8);
166 pub const F9: Keycode = Keycode::from_scancode(Scancode::F9);
167 pub const F10: Keycode = Keycode::from_scancode(Scancode::F10);
168 pub const F11: Keycode = Keycode::from_scancode(Scancode::F11);
169 pub const F12: Keycode = Keycode::from_scancode(Scancode::F12);
170 pub const F13: Keycode = Keycode::from_scancode(Scancode::F13);
171 pub const F14: Keycode = Keycode::from_scancode(Scancode::F14);
172 pub const F15: Keycode = Keycode::from_scancode(Scancode::F15);
173 pub const F16: Keycode = Keycode::from_scancode(Scancode::F16);
174 pub const F17: Keycode = Keycode::from_scancode(Scancode::F17);
175 pub const F18: Keycode = Keycode::from_scancode(Scancode::F18);
176 pub const F19: Keycode = Keycode::from_scancode(Scancode::F19);
177 pub const F20: Keycode = Keycode::from_scancode(Scancode::F20);
178 pub const F21: Keycode = Keycode::from_scancode(Scancode::F21);
179 pub const F22: Keycode = Keycode::from_scancode(Scancode::F22);
180 pub const F23: Keycode = Keycode::from_scancode(Scancode::F23);
181 pub const F24: Keycode = Keycode::from_scancode(Scancode::F24);
182
183 pub const PRINT_SCREEN: Keycode = Keycode::from_scancode(Scancode::PRINT_SCREEN);
184 pub const SCROLL_LOCK: Keycode = Keycode::from_scancode(Scancode::SCROLL_LOCK);
185 pub const PAUSE: Keycode = Keycode::from_scancode(Scancode::PAUSE);
186 pub const INSERT: Keycode = Keycode::from_scancode(Scancode::INSERT);
187 pub const HOME: Keycode = Keycode::from_scancode(Scancode::HOME);
188 pub const PAGE_UP: Keycode = Keycode::from_scancode(Scancode::PAGE_UP);
189 pub const DELETE: Keycode = Keycode(0x7f);
190 pub const END: Keycode = Keycode::from_scancode(Scancode::END);
191 pub const PAGE_DOWN: Keycode = Keycode::from_scancode(Scancode::PAGE_DOWN);
192 pub const RIGHT: Keycode = Keycode::from_scancode(Scancode::RIGHT);
193 pub const LEFT: Keycode = Keycode::from_scancode(Scancode::LEFT);
194 pub const DOWN: Keycode = Keycode::from_scancode(Scancode::DOWN);
195 pub const UP: Keycode = Keycode::from_scancode(Scancode::UP);
196
197 pub const NUM_LOCK_CLEAR: Keycode = Keycode::from_scancode(Scancode::NUM_LOCK_CLEAR);
198 pub const KP_DIVIDE: Keycode = Keycode::from_scancode(Scancode::KP_DIVIDE);
199 pub const KP_MULTIPLY: Keycode = Keycode::from_scancode(Scancode::KP_MULTIPLY);
200 pub const KP_MINUS: Keycode = Keycode::from_scancode(Scancode::KP_MINUS);
201 pub const KP_PLUS: Keycode = Keycode::from_scancode(Scancode::KP_PLUS);
202 pub const KP_ENTER: Keycode = Keycode::from_scancode(Scancode::KP_ENTER);
203 pub const KP_1: Keycode = Keycode::from_scancode(Scancode::KP_1);
204 pub const KP_2: Keycode = Keycode::from_scancode(Scancode::KP_2);
205 pub const KP_3: Keycode = Keycode::from_scancode(Scancode::KP_3);
206 pub const KP_4: Keycode = Keycode::from_scancode(Scancode::KP_4);
207 pub const KP_5: Keycode = Keycode::from_scancode(Scancode::KP_5);
208 pub const KP_6: Keycode = Keycode::from_scancode(Scancode::KP_6);
209 pub const KP_7: Keycode = Keycode::from_scancode(Scancode::KP_7);
210 pub const KP_8: Keycode = Keycode::from_scancode(Scancode::KP_8);
211 pub const KP_9: Keycode = Keycode::from_scancode(Scancode::KP_9);
212 pub const KP_0: Keycode = Keycode::from_scancode(Scancode::KP_0);
213 pub const KP_PERIOD: Keycode = Keycode::from_scancode(Scancode::KP_PERIOD);
214 pub const KP_EQUALS: Keycode = Keycode::from_scancode(Scancode::KP_EQUALS);
215
216 pub const APPLICATION: Keycode = Keycode::from_scancode(Scancode::APPLICATION);
217 pub const MENU: Keycode = Keycode::from_scancode(Scancode::MENU);
218
219 pub const LCTRL: Keycode = Keycode::from_scancode(Scancode::LCTRL);
220 pub const LSHIFT: Keycode = Keycode::from_scancode(Scancode::LSHIFT);
221 pub const LALT: Keycode = Keycode::from_scancode(Scancode::LALT);
222 pub const LGUI: Keycode = Keycode::from_scancode(Scancode::LGUI);
223 pub const RCTRL: Keycode = Keycode::from_scancode(Scancode::RCTRL);
224 pub const RSHIFT: Keycode = Keycode::from_scancode(Scancode::RSHIFT);
225 pub const RALT: Keycode = Keycode::from_scancode(Scancode::RALT);
226 pub const RGUI: Keycode = Keycode::from_scancode(Scancode::RGUI);
227}
228
229#[cfg(test)]
230mod tests {
231 use super::*;
232
233 #[test]
234 fn printable_keycodes_are_unicode() {
235 assert_eq!(Keycode::A.raw(), 0x61);
236 assert_eq!(Keycode::Z.raw(), 0x7A);
237 assert_eq!(Keycode::SPACE.raw(), 0x20);
238 assert_eq!(Keycode::A.to_char(), Some('a'));
239 assert_eq!(Keycode::SPACE.to_scancode(), None);
240 }
241
242 #[test]
243 fn nonprintable_keycodes_use_scancode_mask() {
244 assert!(Keycode::ESCAPE.raw() & SCANCODE_MASK != 0);
245 assert_eq!(Keycode::ESCAPE.to_scancode(), Some(Scancode::ESCAPE));
246 assert_eq!(Keycode::F5.to_scancode(), Some(Scancode::F5));
247 assert_eq!(Keycode::F5.to_char(), None);
248 }
249}