Coverage Report

Created: 2025-03-04 07:22

/src/serenity/Kernel/API/KeyCode.h
Line
Count
Source (jump to first uncovered line)
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/EnumBits.h>
10
#include <AK/Platform.h>
11
#include <AK/Types.h>
12
13
#define ENUMERATE_KEY_CODES                                    \
14
0
    __ENUMERATE_KEY_CODE(Invalid, "Invalid")                   \
15
0
    __ENUMERATE_KEY_CODE(Escape, "Escape")                     \
16
0
    __ENUMERATE_KEY_CODE(Tab, "Tab")                           \
17
0
    __ENUMERATE_KEY_CODE(Backspace, "Backspace")               \
18
0
    __ENUMERATE_KEY_CODE(Return, "Return")                     \
19
0
    __ENUMERATE_KEY_CODE(Insert, "Insert")                     \
20
0
    __ENUMERATE_KEY_CODE(Delete, "Delete")                     \
21
0
    __ENUMERATE_KEY_CODE(PrintScreen, "PrintScreen")           \
22
0
    __ENUMERATE_KEY_CODE(PauseBreak, "PauseBreak")             \
23
0
    __ENUMERATE_KEY_CODE(SysRq, "SysRq")                       \
24
0
    __ENUMERATE_KEY_CODE(Home, "Home")                         \
25
0
    __ENUMERATE_KEY_CODE(End, "End")                           \
26
0
    __ENUMERATE_KEY_CODE(Left, "Left")                         \
27
0
    __ENUMERATE_KEY_CODE(Up, "Up")                             \
28
0
    __ENUMERATE_KEY_CODE(Right, "Right")                       \
29
0
    __ENUMERATE_KEY_CODE(Down, "Down")                         \
30
0
    __ENUMERATE_KEY_CODE(PageUp, "PageUp")                     \
31
0
    __ENUMERATE_KEY_CODE(PageDown, "PageDown")                 \
32
0
    __ENUMERATE_KEY_CODE(LeftShift, "LeftShift")               \
33
0
    __ENUMERATE_KEY_CODE(RightShift, "RightShift")             \
34
0
    __ENUMERATE_KEY_CODE(LeftControl, "LeftControl")           \
35
0
    __ENUMERATE_KEY_CODE(RightControl, "RightControl")         \
36
0
    __ENUMERATE_KEY_CODE(LeftAlt, "LeftAlt")                   \
37
0
    __ENUMERATE_KEY_CODE(RightAlt, "RightAlt")                 \
38
0
    __ENUMERATE_KEY_CODE(AltGr, "AltGr")                       \
39
0
    __ENUMERATE_KEY_CODE(CapsLock, "CapsLock")                 \
40
0
    __ENUMERATE_KEY_CODE(NumLock, "NumLock")                   \
41
0
    __ENUMERATE_KEY_CODE(ScrollLock, "ScrollLock")             \
42
0
    __ENUMERATE_KEY_CODE(F1, "F1")                             \
43
0
    __ENUMERATE_KEY_CODE(F2, "F2")                             \
44
0
    __ENUMERATE_KEY_CODE(F3, "F3")                             \
45
0
    __ENUMERATE_KEY_CODE(F4, "F4")                             \
46
0
    __ENUMERATE_KEY_CODE(F5, "F5")                             \
47
0
    __ENUMERATE_KEY_CODE(F6, "F6")                             \
48
0
    __ENUMERATE_KEY_CODE(F7, "F7")                             \
49
0
    __ENUMERATE_KEY_CODE(F8, "F8")                             \
50
0
    __ENUMERATE_KEY_CODE(F9, "F9")                             \
51
0
    __ENUMERATE_KEY_CODE(F10, "F10")                           \
52
0
    __ENUMERATE_KEY_CODE(F11, "F11")                           \
53
0
    __ENUMERATE_KEY_CODE(F12, "F12")                           \
54
0
    __ENUMERATE_KEY_CODE(Space, "Space")                       \
55
0
    __ENUMERATE_KEY_CODE(ExclamationPoint, "!")                \
56
0
    __ENUMERATE_KEY_CODE(DoubleQuote, "\"")                    \
57
0
    __ENUMERATE_KEY_CODE(Hashtag, "#")                         \
58
0
    __ENUMERATE_KEY_CODE(Dollar, "$")                          \
59
0
    __ENUMERATE_KEY_CODE(Percent, "%")                         \
60
0
    __ENUMERATE_KEY_CODE(Ampersand, "&")                       \
61
0
    __ENUMERATE_KEY_CODE(Apostrophe, "'")                      \
62
0
    __ENUMERATE_KEY_CODE(LeftParen, "(")                       \
63
0
    __ENUMERATE_KEY_CODE(RightParen, ")")                      \
64
0
    __ENUMERATE_KEY_CODE(Asterisk, "*")                        \
65
0
    __ENUMERATE_KEY_CODE(Plus, "+")                            \
66
0
    __ENUMERATE_KEY_CODE(Comma, ",")                           \
67
0
    __ENUMERATE_KEY_CODE(Minus, "-")                           \
68
0
    __ENUMERATE_KEY_CODE(Period, ".")                          \
69
0
    __ENUMERATE_KEY_CODE(Slash, "/")                           \
70
0
    __ENUMERATE_KEY_CODE(0, "0")                               \
71
0
    __ENUMERATE_KEY_CODE(1, "1")                               \
72
0
    __ENUMERATE_KEY_CODE(2, "2")                               \
73
0
    __ENUMERATE_KEY_CODE(3, "3")                               \
74
0
    __ENUMERATE_KEY_CODE(4, "4")                               \
75
0
    __ENUMERATE_KEY_CODE(5, "5")                               \
76
0
    __ENUMERATE_KEY_CODE(6, "6")                               \
77
0
    __ENUMERATE_KEY_CODE(7, "7")                               \
78
0
    __ENUMERATE_KEY_CODE(8, "8")                               \
79
0
    __ENUMERATE_KEY_CODE(9, "9")                               \
80
0
    __ENUMERATE_KEY_CODE(Colon, ":")                           \
81
0
    __ENUMERATE_KEY_CODE(Semicolon, ";")                       \
82
0
    __ENUMERATE_KEY_CODE(LessThan, "<")                        \
83
0
    __ENUMERATE_KEY_CODE(Equal, "=")                           \
84
0
    __ENUMERATE_KEY_CODE(GreaterThan, ">")                     \
85
0
    __ENUMERATE_KEY_CODE(QuestionMark, "?")                    \
86
0
    __ENUMERATE_KEY_CODE(AtSign, "@")                          \
87
0
    __ENUMERATE_KEY_CODE(A, "A")                               \
88
0
    __ENUMERATE_KEY_CODE(B, "B")                               \
89
0
    __ENUMERATE_KEY_CODE(C, "C")                               \
90
0
    __ENUMERATE_KEY_CODE(D, "D")                               \
91
0
    __ENUMERATE_KEY_CODE(E, "E")                               \
92
0
    __ENUMERATE_KEY_CODE(F, "F")                               \
93
0
    __ENUMERATE_KEY_CODE(G, "G")                               \
94
0
    __ENUMERATE_KEY_CODE(H, "H")                               \
95
0
    __ENUMERATE_KEY_CODE(I, "I")                               \
96
0
    __ENUMERATE_KEY_CODE(J, "J")                               \
97
0
    __ENUMERATE_KEY_CODE(K, "K")                               \
98
0
    __ENUMERATE_KEY_CODE(L, "L")                               \
99
0
    __ENUMERATE_KEY_CODE(M, "M")                               \
100
0
    __ENUMERATE_KEY_CODE(N, "N")                               \
101
0
    __ENUMERATE_KEY_CODE(O, "O")                               \
102
0
    __ENUMERATE_KEY_CODE(P, "P")                               \
103
0
    __ENUMERATE_KEY_CODE(Q, "Q")                               \
104
0
    __ENUMERATE_KEY_CODE(R, "R")                               \
105
0
    __ENUMERATE_KEY_CODE(S, "S")                               \
106
0
    __ENUMERATE_KEY_CODE(T, "T")                               \
107
0
    __ENUMERATE_KEY_CODE(U, "U")                               \
108
0
    __ENUMERATE_KEY_CODE(V, "V")                               \
109
0
    __ENUMERATE_KEY_CODE(W, "W")                               \
110
0
    __ENUMERATE_KEY_CODE(X, "X")                               \
111
0
    __ENUMERATE_KEY_CODE(Y, "Y")                               \
112
0
    __ENUMERATE_KEY_CODE(Z, "Z")                               \
113
0
    __ENUMERATE_KEY_CODE(LeftBracket, "[")                     \
114
0
    __ENUMERATE_KEY_CODE(RightBracket, "]")                    \
115
0
    __ENUMERATE_KEY_CODE(Backslash, "\\")                      \
116
0
    __ENUMERATE_KEY_CODE(Circumflex, "^")                      \
117
0
    __ENUMERATE_KEY_CODE(Underscore, "_")                      \
118
0
    __ENUMERATE_KEY_CODE(LeftBrace, "{")                       \
119
0
    __ENUMERATE_KEY_CODE(RightBrace, "}")                      \
120
0
    __ENUMERATE_KEY_CODE(Pipe, "|")                            \
121
0
    __ENUMERATE_KEY_CODE(Tilde, "~")                           \
122
0
    __ENUMERATE_KEY_CODE(Backtick, "`")                        \
123
0
    __ENUMERATE_KEY_CODE(LeftSuper, "LeftSuper")               \
124
0
    __ENUMERATE_KEY_CODE(RightSuper, "RightSuper")             \
125
0
    __ENUMERATE_KEY_CODE(BrowserSearch, "BrowserSearch")       \
126
0
    __ENUMERATE_KEY_CODE(BrowserFavorites, "BrowserFavorites") \
127
0
    __ENUMERATE_KEY_CODE(BrowserHome, "BrowserHome")           \
128
0
    __ENUMERATE_KEY_CODE(PreviousTrack, "PreviousTrack")       \
129
0
    __ENUMERATE_KEY_CODE(BrowserBack, "BrowserBack")           \
130
0
    __ENUMERATE_KEY_CODE(BrowserForward, "BrowserForward")     \
131
0
    __ENUMERATE_KEY_CODE(BrowserRefresh, "BrowserRefresh")     \
132
0
    __ENUMERATE_KEY_CODE(BrowserStop, "BrowserStop")           \
133
0
    __ENUMERATE_KEY_CODE(VolumeDown, "VolumeDown")             \
134
0
    __ENUMERATE_KEY_CODE(VolumeUp, "VolumeUp")                 \
135
0
    __ENUMERATE_KEY_CODE(Wake, "Wake")                         \
136
0
    __ENUMERATE_KEY_CODE(Sleep, "Sleep")                       \
137
0
    __ENUMERATE_KEY_CODE(NextTrack, "NextTrack")               \
138
0
    __ENUMERATE_KEY_CODE(MediaSelect, "MediaSelect")           \
139
0
    __ENUMERATE_KEY_CODE(Email, "Email")                       \
140
0
    __ENUMERATE_KEY_CODE(MyComputer, "MyComputer")             \
141
0
    __ENUMERATE_KEY_CODE(Power, "Power")                       \
142
0
    __ENUMERATE_KEY_CODE(Stop, "Stop")                         \
143
0
    __ENUMERATE_KEY_CODE(LeftGUI, "LeftGUI")                   \
144
0
    __ENUMERATE_KEY_CODE(Mute, "Mute")                         \
145
0
    __ENUMERATE_KEY_CODE(RightGUI, "RightGUI")                 \
146
0
    __ENUMERATE_KEY_CODE(Calculator, "Calculator")             \
147
0
    __ENUMERATE_KEY_CODE(Apps, "Apps")                         \
148
0
    __ENUMERATE_KEY_CODE(PlayPause, "PlayPause")               \
149
0
    __ENUMERATE_KEY_CODE(Menu, "Menu")
150
151
enum KeyCode : u8 {
152
#define __ENUMERATE_KEY_CODE(name, ui_name) Key_##name,
153
    ENUMERATE_KEY_CODES
154
#undef __ENUMERATE_KEY_CODE
155
156
        Key_Shift
157
    = Key_LeftShift,
158
};
159
size_t const key_code_count = Key_Menu + 1;
160
161
enum KeyModifier {
162
    Mod_None = 0x00,
163
    Mod_Alt = (1 << 0),
164
    Mod_Ctrl = (1 << 1),
165
    Mod_Shift = (1 << 2),
166
    Mod_Super = (1 << 3),
167
    Mod_AltGr = (1 << 4),
168
    Mod_Keypad = (1 << 5),
169
    Mod_Mask = Mod_Alt | Mod_Ctrl | Mod_Shift | Mod_Super | Mod_AltGr | Mod_Keypad,
170
171
    Is_Press = 0x80,
172
173
#if defined(AK_OS_MACOS)
174
    Mod_PlatformCtrl = Mod_Super,
175
    Mod_PlatformWordJump = Mod_Alt,
176
#else
177
    Mod_PlatformCtrl = Mod_Ctrl,
178
    Mod_PlatformWordJump = Mod_Ctrl,
179
#endif
180
};
181
182
AK_ENUM_BITWISE_OPERATORS(KeyModifier);
183
184
struct KeyEvent {
185
    KeyCode key { Key_Invalid };
186
    u8 map_entry_index { 0 };
187
    u64 scancode { 0 };
188
    u32 code_point { 0 };
189
    u8 flags { 0 };
190
    bool caps_lock_on { false };
191
0
    bool alt() const { return flags & Mod_Alt; }
192
0
    bool ctrl() const { return flags & Mod_Ctrl; }
193
0
    bool shift() const { return flags & Mod_Shift; }
194
0
    bool super() const { return flags & Mod_Super; }
195
0
    bool altgr() const { return flags & Mod_AltGr; }
196
0
    bool keypad() const { return flags & Mod_Keypad; }
197
0
    unsigned modifiers() const { return flags & Mod_Mask; }
198
0
    bool is_press() const { return flags & Is_Press; }
199
};
200
201
inline char const* key_code_to_string(KeyCode key)
202
0
{
203
0
    switch (key) {
204
0
#define __ENUMERATE_KEY_CODE(name, ui_name) \
205
0
    case Key_##name:                        \
206
0
        return ui_name;
207
0
        ENUMERATE_KEY_CODES
208
0
#undef __ENUMERATE_KEY_CODE
209
0
    default:
210
0
        return nullptr;
211
0
    }
212
0
}
213
214
inline KeyCode code_point_to_key_code(u32 code_point)
215
0
{
216
0
    switch (code_point) {
217
0
#define MATCH_ALPHA(letter) \
218
0
    case #letter[0]:        \
219
0
    case #letter[0] + 32:   \
220
0
        return KeyCode::Key_##letter;
221
0
        MATCH_ALPHA(A)
222
0
        MATCH_ALPHA(B)
223
0
        MATCH_ALPHA(C)
224
0
        MATCH_ALPHA(D)
225
0
        MATCH_ALPHA(E)
226
0
        MATCH_ALPHA(F)
227
0
        MATCH_ALPHA(G)
228
0
        MATCH_ALPHA(H)
229
0
        MATCH_ALPHA(I)
230
0
        MATCH_ALPHA(J)
231
0
        MATCH_ALPHA(K)
232
0
        MATCH_ALPHA(L)
233
0
        MATCH_ALPHA(M)
234
0
        MATCH_ALPHA(N)
235
0
        MATCH_ALPHA(O)
236
0
        MATCH_ALPHA(P)
237
0
        MATCH_ALPHA(Q)
238
0
        MATCH_ALPHA(R)
239
0
        MATCH_ALPHA(S)
240
0
        MATCH_ALPHA(T)
241
0
        MATCH_ALPHA(U)
242
0
        MATCH_ALPHA(V)
243
0
        MATCH_ALPHA(W)
244
0
        MATCH_ALPHA(X)
245
0
        MATCH_ALPHA(Y)
246
0
        MATCH_ALPHA(Z)
247
0
#undef MATCH_ALPHA
248
249
0
#define MATCH_KEY(name, character) \
250
0
    case character:                \
251
0
        return KeyCode::Key_##name;
252
0
        MATCH_KEY(ExclamationPoint, '!')
253
0
        MATCH_KEY(DoubleQuote, '"')
254
0
        MATCH_KEY(Hashtag, '#')
255
0
        MATCH_KEY(Dollar, '$')
256
0
        MATCH_KEY(Percent, '%')
257
0
        MATCH_KEY(Ampersand, '&')
258
0
        MATCH_KEY(Apostrophe, '\'')
259
0
        MATCH_KEY(LeftParen, '(')
260
0
        MATCH_KEY(RightParen, ')')
261
0
        MATCH_KEY(Asterisk, '*')
262
0
        MATCH_KEY(Plus, '+')
263
0
        MATCH_KEY(Comma, ',')
264
0
        MATCH_KEY(Minus, '-')
265
0
        MATCH_KEY(Period, '.')
266
0
        MATCH_KEY(Slash, '/')
267
0
        MATCH_KEY(0, '0')
268
0
        MATCH_KEY(1, '1')
269
0
        MATCH_KEY(2, '2')
270
0
        MATCH_KEY(3, '3')
271
0
        MATCH_KEY(4, '4')
272
0
        MATCH_KEY(5, '5')
273
0
        MATCH_KEY(6, '6')
274
0
        MATCH_KEY(7, '7')
275
0
        MATCH_KEY(8, '8')
276
0
        MATCH_KEY(9, '9')
277
0
        MATCH_KEY(Colon, ':')
278
0
        MATCH_KEY(Semicolon, ';')
279
0
        MATCH_KEY(LessThan, '<')
280
0
        MATCH_KEY(Equal, '=')
281
0
        MATCH_KEY(GreaterThan, '>')
282
0
        MATCH_KEY(QuestionMark, '?')
283
0
        MATCH_KEY(AtSign, '@')
284
0
        MATCH_KEY(LeftBracket, '[')
285
0
        MATCH_KEY(RightBracket, ']')
286
0
        MATCH_KEY(Backslash, '\\')
287
0
        MATCH_KEY(Circumflex, '^')
288
0
        MATCH_KEY(Underscore, '_')
289
0
        MATCH_KEY(LeftBrace, '{')
290
0
        MATCH_KEY(RightBrace, '}')
291
0
        MATCH_KEY(Pipe, '|')
292
0
        MATCH_KEY(Tilde, '~')
293
0
        MATCH_KEY(Backtick, '`')
294
0
        MATCH_KEY(Space, ' ')
295
0
        MATCH_KEY(Tab, '\t')
296
0
        MATCH_KEY(Backspace, '\b')
297
0
#undef MATCH_KEY
298
299
0
    default:
300
0
        return KeyCode::Key_Invalid;
301
0
    }
302
0
}