/* * Copyright (c) 2018-2020, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #define ENUMERATE_KEY_CODES \ __ENUMERATE_KEY_CODE(Invalid, "Invalid") \ __ENUMERATE_KEY_CODE(Escape, "Escape") \ __ENUMERATE_KEY_CODE(Tab, "Tab") \ __ENUMERATE_KEY_CODE(Backspace, "Backspace") \ __ENUMERATE_KEY_CODE(Return, "Return") \ __ENUMERATE_KEY_CODE(Insert, "Insert") \ __ENUMERATE_KEY_CODE(Delete, "Delete") \ __ENUMERATE_KEY_CODE(PrintScreen, "PrintScreen") \ __ENUMERATE_KEY_CODE(SysRq, "SysRq") \ __ENUMERATE_KEY_CODE(Home, "Home") \ __ENUMERATE_KEY_CODE(End, "End") \ __ENUMERATE_KEY_CODE(Left, "Left") \ __ENUMERATE_KEY_CODE(Up, "Up") \ __ENUMERATE_KEY_CODE(Right, "Right") \ __ENUMERATE_KEY_CODE(Down, "Down") \ __ENUMERATE_KEY_CODE(PageUp, "PageUp") \ __ENUMERATE_KEY_CODE(PageDown, "PageDown") \ __ENUMERATE_KEY_CODE(LeftShift, "LeftShift") \ __ENUMERATE_KEY_CODE(RightShift, "RightShift") \ __ENUMERATE_KEY_CODE(Control, "Ctrl") \ __ENUMERATE_KEY_CODE(Alt, "Alt") \ __ENUMERATE_KEY_CODE(CapsLock, "CapsLock") \ __ENUMERATE_KEY_CODE(NumLock, "NumLock") \ __ENUMERATE_KEY_CODE(ScrollLock, "ScrollLock") \ __ENUMERATE_KEY_CODE(F1, "F1") \ __ENUMERATE_KEY_CODE(F2, "F2") \ __ENUMERATE_KEY_CODE(F3, "F3") \ __ENUMERATE_KEY_CODE(F4, "F4") \ __ENUMERATE_KEY_CODE(F5, "F5") \ __ENUMERATE_KEY_CODE(F6, "F6") \ __ENUMERATE_KEY_CODE(F7, "F7") \ __ENUMERATE_KEY_CODE(F8, "F8") \ __ENUMERATE_KEY_CODE(F9, "F9") \ __ENUMERATE_KEY_CODE(F10, "F10") \ __ENUMERATE_KEY_CODE(F11, "F11") \ __ENUMERATE_KEY_CODE(F12, "F12") \ __ENUMERATE_KEY_CODE(Space, "Space") \ __ENUMERATE_KEY_CODE(ExclamationPoint, "!") \ __ENUMERATE_KEY_CODE(DoubleQuote, "\"") \ __ENUMERATE_KEY_CODE(Hashtag, "#") \ __ENUMERATE_KEY_CODE(Dollar, "$") \ __ENUMERATE_KEY_CODE(Percent, "%") \ __ENUMERATE_KEY_CODE(Ampersand, "&") \ __ENUMERATE_KEY_CODE(Apostrophe, "'") \ __ENUMERATE_KEY_CODE(LeftParen, "(") \ __ENUMERATE_KEY_CODE(RightParen, ")") \ __ENUMERATE_KEY_CODE(Asterisk, "*") \ __ENUMERATE_KEY_CODE(Plus, "+") \ __ENUMERATE_KEY_CODE(Comma, ",") \ __ENUMERATE_KEY_CODE(Minus, "-") \ __ENUMERATE_KEY_CODE(Period, ".") \ __ENUMERATE_KEY_CODE(Slash, "/") \ __ENUMERATE_KEY_CODE(0, "0") \ __ENUMERATE_KEY_CODE(1, "1") \ __ENUMERATE_KEY_CODE(2, "2") \ __ENUMERATE_KEY_CODE(3, "3") \ __ENUMERATE_KEY_CODE(4, "4") \ __ENUMERATE_KEY_CODE(5, "5") \ __ENUMERATE_KEY_CODE(6, "6") \ __ENUMERATE_KEY_CODE(7, "7") \ __ENUMERATE_KEY_CODE(8, "8") \ __ENUMERATE_KEY_CODE(9, "9") \ __ENUMERATE_KEY_CODE(Colon, ":") \ __ENUMERATE_KEY_CODE(Semicolon, ";") \ __ENUMERATE_KEY_CODE(LessThan, "<") \ __ENUMERATE_KEY_CODE(Equal, "=") \ __ENUMERATE_KEY_CODE(GreaterThan, ">") \ __ENUMERATE_KEY_CODE(QuestionMark, "?") \ __ENUMERATE_KEY_CODE(AtSign, "@") \ __ENUMERATE_KEY_CODE(A, "A") \ __ENUMERATE_KEY_CODE(B, "B") \ __ENUMERATE_KEY_CODE(C, "C") \ __ENUMERATE_KEY_CODE(D, "D") \ __ENUMERATE_KEY_CODE(E, "E") \ __ENUMERATE_KEY_CODE(F, "F") \ __ENUMERATE_KEY_CODE(G, "G") \ __ENUMERATE_KEY_CODE(H, "H") \ __ENUMERATE_KEY_CODE(I, "I") \ __ENUMERATE_KEY_CODE(J, "J") \ __ENUMERATE_KEY_CODE(K, "K") \ __ENUMERATE_KEY_CODE(L, "L") \ __ENUMERATE_KEY_CODE(M, "M") \ __ENUMERATE_KEY_CODE(N, "N") \ __ENUMERATE_KEY_CODE(O, "O") \ __ENUMERATE_KEY_CODE(P, "P") \ __ENUMERATE_KEY_CODE(Q, "Q") \ __ENUMERATE_KEY_CODE(R, "R") \ __ENUMERATE_KEY_CODE(S, "S") \ __ENUMERATE_KEY_CODE(T, "T") \ __ENUMERATE_KEY_CODE(U, "U") \ __ENUMERATE_KEY_CODE(V, "V") \ __ENUMERATE_KEY_CODE(W, "W") \ __ENUMERATE_KEY_CODE(X, "X") \ __ENUMERATE_KEY_CODE(Y, "Y") \ __ENUMERATE_KEY_CODE(Z, "Z") \ __ENUMERATE_KEY_CODE(LeftBracket, "[") \ __ENUMERATE_KEY_CODE(RightBracket, "]") \ __ENUMERATE_KEY_CODE(Backslash, "\\") \ __ENUMERATE_KEY_CODE(Circumflex, "^") \ __ENUMERATE_KEY_CODE(Underscore, "_") \ __ENUMERATE_KEY_CODE(LeftBrace, "{") \ __ENUMERATE_KEY_CODE(RightBrace, "}") \ __ENUMERATE_KEY_CODE(Pipe, "|") \ __ENUMERATE_KEY_CODE(Tilde, "~") \ __ENUMERATE_KEY_CODE(Backtick, "`") \ __ENUMERATE_KEY_CODE(Super, "Super") \ __ENUMERATE_KEY_CODE(Menu, "Menu") enum KeyCode : u8 { #define __ENUMERATE_KEY_CODE(name, ui_name) Key_##name, ENUMERATE_KEY_CODES #undef __ENUMERATE_KEY_CODE Key_Shift = Key_LeftShift, }; int const key_code_count = Key_Menu; enum KeyModifier { Mod_None = 0x00, Mod_Alt = (1 << 0), Mod_Ctrl = (1 << 1), Mod_Shift = (1 << 2), Mod_Super = (1 << 3), Mod_AltGr = (1 << 4), Mod_Mask = Mod_Alt | Mod_Ctrl | Mod_Shift | Mod_Super | Mod_AltGr, Is_Press = 0x80, }; struct KeyEvent { KeyCode key { Key_Invalid }; u32 scancode { 0 }; u32 code_point { 0 }; u8 flags { 0 }; bool caps_lock_on { false }; bool e0_prefix { false }; bool alt() const { return flags & Mod_Alt; } bool ctrl() const { return flags & Mod_Ctrl; } bool shift() const { return flags & Mod_Shift; } bool super() const { return flags & Mod_Super; } bool altgr() const { return flags & Mod_AltGr; } unsigned modifiers() const { return flags & Mod_Mask; } bool is_press() const { return flags & Is_Press; } }; inline char const* key_code_to_string(KeyCode key) { switch (key) { #define __ENUMERATE_KEY_CODE(name, ui_name) \ case Key_##name: \ return ui_name; ENUMERATE_KEY_CODES #undef __ENUMERATE_KEY_CODE default: return nullptr; } } inline KeyCode code_point_to_key_code(u32 code_point) { switch (code_point) { #define MATCH_ALPHA(letter) \ case #letter[0]: \ case #letter[0] + 32: \ return KeyCode::Key_##letter; MATCH_ALPHA(A) MATCH_ALPHA(B) MATCH_ALPHA(C) MATCH_ALPHA(D) MATCH_ALPHA(E) MATCH_ALPHA(F) MATCH_ALPHA(G) MATCH_ALPHA(H) MATCH_ALPHA(I) MATCH_ALPHA(J) MATCH_ALPHA(K) MATCH_ALPHA(L) MATCH_ALPHA(M) MATCH_ALPHA(N) MATCH_ALPHA(O) MATCH_ALPHA(P) MATCH_ALPHA(Q) MATCH_ALPHA(R) MATCH_ALPHA(S) MATCH_ALPHA(T) MATCH_ALPHA(U) MATCH_ALPHA(V) MATCH_ALPHA(W) MATCH_ALPHA(X) MATCH_ALPHA(Y) MATCH_ALPHA(Z) #undef MATCH_ALPHA #define MATCH_KEY(name, character) \ case character: \ return KeyCode::Key_##name; MATCH_KEY(ExclamationPoint, '!') MATCH_KEY(DoubleQuote, '"') MATCH_KEY(Hashtag, '#') MATCH_KEY(Dollar, '$') MATCH_KEY(Percent, '%') MATCH_KEY(Ampersand, '&') MATCH_KEY(Apostrophe, '\'') MATCH_KEY(LeftParen, '(') MATCH_KEY(RightParen, ')') MATCH_KEY(Asterisk, '*') MATCH_KEY(Plus, '+') MATCH_KEY(Comma, ',') MATCH_KEY(Minus, '-') MATCH_KEY(Period, '.') MATCH_KEY(Slash, '/') MATCH_KEY(0, '0') MATCH_KEY(1, '1') MATCH_KEY(2, '2') MATCH_KEY(3, '3') MATCH_KEY(4, '4') MATCH_KEY(5, '5') MATCH_KEY(6, '6') MATCH_KEY(7, '7') MATCH_KEY(8, '8') MATCH_KEY(9, '9') MATCH_KEY(Colon, ':') MATCH_KEY(Semicolon, ';') MATCH_KEY(LessThan, '<') MATCH_KEY(Equal, '=') MATCH_KEY(GreaterThan, '>') MATCH_KEY(QuestionMark, '?') MATCH_KEY(AtSign, '@') MATCH_KEY(LeftBracket, '[') MATCH_KEY(RightBracket, ']') MATCH_KEY(Backslash, '\\') MATCH_KEY(Circumflex, '^') MATCH_KEY(Underscore, '_') MATCH_KEY(LeftBrace, '{') MATCH_KEY(RightBrace, '}') MATCH_KEY(Pipe, '|') MATCH_KEY(Tilde, '~') MATCH_KEY(Backtick, '`') MATCH_KEY(Space, ' ') MATCH_KEY(Tab, '\t') MATCH_KEY(Backspace, '\b') #undef MATCH_KEY default: return KeyCode::Key_Invalid; } }