Serenity Operating System
1/*
2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#pragma once
8
9#include <AK/Types.h>
10
11#define ENUMERATE_KEY_CODES \
12 __ENUMERATE_KEY_CODE(Invalid, "Invalid") \
13 __ENUMERATE_KEY_CODE(Escape, "Escape") \
14 __ENUMERATE_KEY_CODE(Tab, "Tab") \
15 __ENUMERATE_KEY_CODE(Backspace, "Backspace") \
16 __ENUMERATE_KEY_CODE(Return, "Return") \
17 __ENUMERATE_KEY_CODE(Insert, "Insert") \
18 __ENUMERATE_KEY_CODE(Delete, "Delete") \
19 __ENUMERATE_KEY_CODE(PrintScreen, "PrintScreen") \
20 __ENUMERATE_KEY_CODE(SysRq, "SysRq") \
21 __ENUMERATE_KEY_CODE(Home, "Home") \
22 __ENUMERATE_KEY_CODE(End, "End") \
23 __ENUMERATE_KEY_CODE(Left, "Left") \
24 __ENUMERATE_KEY_CODE(Up, "Up") \
25 __ENUMERATE_KEY_CODE(Right, "Right") \
26 __ENUMERATE_KEY_CODE(Down, "Down") \
27 __ENUMERATE_KEY_CODE(PageUp, "PageUp") \
28 __ENUMERATE_KEY_CODE(PageDown, "PageDown") \
29 __ENUMERATE_KEY_CODE(LeftShift, "LeftShift") \
30 __ENUMERATE_KEY_CODE(RightShift, "RightShift") \
31 __ENUMERATE_KEY_CODE(Control, "Ctrl") \
32 __ENUMERATE_KEY_CODE(Alt, "Alt") \
33 __ENUMERATE_KEY_CODE(CapsLock, "CapsLock") \
34 __ENUMERATE_KEY_CODE(NumLock, "NumLock") \
35 __ENUMERATE_KEY_CODE(ScrollLock, "ScrollLock") \
36 __ENUMERATE_KEY_CODE(F1, "F1") \
37 __ENUMERATE_KEY_CODE(F2, "F2") \
38 __ENUMERATE_KEY_CODE(F3, "F3") \
39 __ENUMERATE_KEY_CODE(F4, "F4") \
40 __ENUMERATE_KEY_CODE(F5, "F5") \
41 __ENUMERATE_KEY_CODE(F6, "F6") \
42 __ENUMERATE_KEY_CODE(F7, "F7") \
43 __ENUMERATE_KEY_CODE(F8, "F8") \
44 __ENUMERATE_KEY_CODE(F9, "F9") \
45 __ENUMERATE_KEY_CODE(F10, "F10") \
46 __ENUMERATE_KEY_CODE(F11, "F11") \
47 __ENUMERATE_KEY_CODE(F12, "F12") \
48 __ENUMERATE_KEY_CODE(Space, "Space") \
49 __ENUMERATE_KEY_CODE(ExclamationPoint, "!") \
50 __ENUMERATE_KEY_CODE(DoubleQuote, "\"") \
51 __ENUMERATE_KEY_CODE(Hashtag, "#") \
52 __ENUMERATE_KEY_CODE(Dollar, "$") \
53 __ENUMERATE_KEY_CODE(Percent, "%") \
54 __ENUMERATE_KEY_CODE(Ampersand, "&") \
55 __ENUMERATE_KEY_CODE(Apostrophe, "'") \
56 __ENUMERATE_KEY_CODE(LeftParen, "(") \
57 __ENUMERATE_KEY_CODE(RightParen, ")") \
58 __ENUMERATE_KEY_CODE(Asterisk, "*") \
59 __ENUMERATE_KEY_CODE(Plus, "+") \
60 __ENUMERATE_KEY_CODE(Comma, ",") \
61 __ENUMERATE_KEY_CODE(Minus, "-") \
62 __ENUMERATE_KEY_CODE(Period, ".") \
63 __ENUMERATE_KEY_CODE(Slash, "/") \
64 __ENUMERATE_KEY_CODE(0, "0") \
65 __ENUMERATE_KEY_CODE(1, "1") \
66 __ENUMERATE_KEY_CODE(2, "2") \
67 __ENUMERATE_KEY_CODE(3, "3") \
68 __ENUMERATE_KEY_CODE(4, "4") \
69 __ENUMERATE_KEY_CODE(5, "5") \
70 __ENUMERATE_KEY_CODE(6, "6") \
71 __ENUMERATE_KEY_CODE(7, "7") \
72 __ENUMERATE_KEY_CODE(8, "8") \
73 __ENUMERATE_KEY_CODE(9, "9") \
74 __ENUMERATE_KEY_CODE(Colon, ":") \
75 __ENUMERATE_KEY_CODE(Semicolon, ";") \
76 __ENUMERATE_KEY_CODE(LessThan, "<") \
77 __ENUMERATE_KEY_CODE(Equal, "=") \
78 __ENUMERATE_KEY_CODE(GreaterThan, ">") \
79 __ENUMERATE_KEY_CODE(QuestionMark, "?") \
80 __ENUMERATE_KEY_CODE(AtSign, "@") \
81 __ENUMERATE_KEY_CODE(A, "A") \
82 __ENUMERATE_KEY_CODE(B, "B") \
83 __ENUMERATE_KEY_CODE(C, "C") \
84 __ENUMERATE_KEY_CODE(D, "D") \
85 __ENUMERATE_KEY_CODE(E, "E") \
86 __ENUMERATE_KEY_CODE(F, "F") \
87 __ENUMERATE_KEY_CODE(G, "G") \
88 __ENUMERATE_KEY_CODE(H, "H") \
89 __ENUMERATE_KEY_CODE(I, "I") \
90 __ENUMERATE_KEY_CODE(J, "J") \
91 __ENUMERATE_KEY_CODE(K, "K") \
92 __ENUMERATE_KEY_CODE(L, "L") \
93 __ENUMERATE_KEY_CODE(M, "M") \
94 __ENUMERATE_KEY_CODE(N, "N") \
95 __ENUMERATE_KEY_CODE(O, "O") \
96 __ENUMERATE_KEY_CODE(P, "P") \
97 __ENUMERATE_KEY_CODE(Q, "Q") \
98 __ENUMERATE_KEY_CODE(R, "R") \
99 __ENUMERATE_KEY_CODE(S, "S") \
100 __ENUMERATE_KEY_CODE(T, "T") \
101 __ENUMERATE_KEY_CODE(U, "U") \
102 __ENUMERATE_KEY_CODE(V, "V") \
103 __ENUMERATE_KEY_CODE(W, "W") \
104 __ENUMERATE_KEY_CODE(X, "X") \
105 __ENUMERATE_KEY_CODE(Y, "Y") \
106 __ENUMERATE_KEY_CODE(Z, "Z") \
107 __ENUMERATE_KEY_CODE(LeftBracket, "[") \
108 __ENUMERATE_KEY_CODE(RightBracket, "]") \
109 __ENUMERATE_KEY_CODE(Backslash, "\\") \
110 __ENUMERATE_KEY_CODE(Circumflex, "^") \
111 __ENUMERATE_KEY_CODE(Underscore, "_") \
112 __ENUMERATE_KEY_CODE(LeftBrace, "{") \
113 __ENUMERATE_KEY_CODE(RightBrace, "}") \
114 __ENUMERATE_KEY_CODE(Pipe, "|") \
115 __ENUMERATE_KEY_CODE(Tilde, "~") \
116 __ENUMERATE_KEY_CODE(Backtick, "`") \
117 __ENUMERATE_KEY_CODE(Super, "Super") \
118 __ENUMERATE_KEY_CODE(Menu, "Menu")
119
120enum KeyCode : u8 {
121#define __ENUMERATE_KEY_CODE(name, ui_name) Key_##name,
122 ENUMERATE_KEY_CODES
123#undef __ENUMERATE_KEY_CODE
124
125 Key_Shift
126 = Key_LeftShift,
127};
128int const key_code_count = Key_Menu;
129
130enum KeyModifier {
131 Mod_None = 0x00,
132 Mod_Alt = 0x01,
133 Mod_Ctrl = 0x02,
134 Mod_Shift = 0x04,
135 Mod_Super = 0x08,
136 Mod_AltGr = 0x10,
137 Mod_Mask = 0x1f,
138
139 Is_Press = 0x80,
140};
141
142struct KeyEvent {
143 KeyCode key { Key_Invalid };
144 u32 scancode { 0 };
145 u32 code_point { 0 };
146 u8 flags { 0 };
147 bool caps_lock_on { false };
148 bool e0_prefix { false };
149 bool alt() const { return flags & Mod_Alt; }
150 bool ctrl() const { return flags & Mod_Ctrl; }
151 bool shift() const { return flags & Mod_Shift; }
152 bool super() const { return flags & Mod_Super; }
153 bool altgr() const { return flags & Mod_AltGr; }
154 unsigned modifiers() const { return flags & Mod_Mask; }
155 bool is_press() const { return flags & Is_Press; }
156};
157
158inline char const* key_code_to_string(KeyCode key)
159{
160 switch (key) {
161#define __ENUMERATE_KEY_CODE(name, ui_name) \
162 case Key_##name: \
163 return ui_name;
164 ENUMERATE_KEY_CODES
165#undef __ENUMERATE_KEY_CODE
166 default:
167 return nullptr;
168 }
169}
170
171inline KeyCode code_point_to_key_code(u32 code_point)
172{
173 switch (code_point) {
174#define MATCH_ALPHA(letter) \
175 case #letter[0]: \
176 case #letter[0] + 32: \
177 return KeyCode::Key_##letter;
178 MATCH_ALPHA(A)
179 MATCH_ALPHA(B)
180 MATCH_ALPHA(C)
181 MATCH_ALPHA(D)
182 MATCH_ALPHA(E)
183 MATCH_ALPHA(F)
184 MATCH_ALPHA(G)
185 MATCH_ALPHA(H)
186 MATCH_ALPHA(I)
187 MATCH_ALPHA(J)
188 MATCH_ALPHA(K)
189 MATCH_ALPHA(L)
190 MATCH_ALPHA(M)
191 MATCH_ALPHA(N)
192 MATCH_ALPHA(O)
193 MATCH_ALPHA(P)
194 MATCH_ALPHA(Q)
195 MATCH_ALPHA(R)
196 MATCH_ALPHA(S)
197 MATCH_ALPHA(T)
198 MATCH_ALPHA(U)
199 MATCH_ALPHA(V)
200 MATCH_ALPHA(W)
201 MATCH_ALPHA(X)
202 MATCH_ALPHA(Y)
203 MATCH_ALPHA(Z)
204#undef MATCH_ALPHA
205
206#define MATCH_KEY(name, character) \
207 case character: \
208 return KeyCode::Key_##name;
209 MATCH_KEY(ExclamationPoint, '!')
210 MATCH_KEY(DoubleQuote, '"')
211 MATCH_KEY(Hashtag, '#')
212 MATCH_KEY(Dollar, '$')
213 MATCH_KEY(Percent, '%')
214 MATCH_KEY(Ampersand, '&')
215 MATCH_KEY(Apostrophe, '\'')
216 MATCH_KEY(LeftParen, '(')
217 MATCH_KEY(RightParen, ')')
218 MATCH_KEY(Asterisk, '*')
219 MATCH_KEY(Plus, '+')
220 MATCH_KEY(Comma, ',')
221 MATCH_KEY(Minus, '-')
222 MATCH_KEY(Period, '.')
223 MATCH_KEY(Slash, '/')
224 MATCH_KEY(0, '0')
225 MATCH_KEY(1, '1')
226 MATCH_KEY(2, '2')
227 MATCH_KEY(3, '3')
228 MATCH_KEY(4, '4')
229 MATCH_KEY(5, '5')
230 MATCH_KEY(6, '6')
231 MATCH_KEY(7, '7')
232 MATCH_KEY(8, '8')
233 MATCH_KEY(9, '9')
234 MATCH_KEY(Colon, ':')
235 MATCH_KEY(Semicolon, ';')
236 MATCH_KEY(LessThan, '<')
237 MATCH_KEY(Equal, '=')
238 MATCH_KEY(GreaterThan, '>')
239 MATCH_KEY(QuestionMark, '?')
240 MATCH_KEY(AtSign, '@')
241 MATCH_KEY(LeftBracket, '[')
242 MATCH_KEY(RightBracket, ']')
243 MATCH_KEY(Backslash, '\\')
244 MATCH_KEY(Circumflex, '^')
245 MATCH_KEY(Underscore, '_')
246 MATCH_KEY(LeftBrace, '{')
247 MATCH_KEY(RightBrace, '}')
248 MATCH_KEY(Pipe, '|')
249 MATCH_KEY(Tilde, '~')
250 MATCH_KEY(Backtick, '`')
251 MATCH_KEY(Space, ' ')
252 MATCH_KEY(Tab, '\t')
253 MATCH_KEY(Backspace, '\b')
254#undef MATCH_KEY
255
256 default:
257 return KeyCode::Key_Invalid;
258 }
259}