/* * This source file is part of RmlUi, the HTML/CSS Interface Middleware * * For the latest information, see http://github.com/mikke89/RmlUi * * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd * Copyright (c) 2019 The RmlUi Team, and contributors * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * */ #include #include #include #include #include #include static int GetKeyModifierState(); static void InitialiseKeymap(); static const int KEYMAP_SIZE = 256; static Rml::Core::Input::KeyIdentifier key_identifier_map[KEYMAP_SIZE]; bool InputWin32::Initialise() { InitialiseKeymap(); return true; } void InputWin32::Shutdown() { } void InputWin32::ProcessWindowsEvent(UINT message, WPARAM w_param, LPARAM l_param) { if (context == nullptr) return; // Process all mouse and keyboard events switch (message) { case WM_LBUTTONDOWN: context->ProcessMouseButtonDown(0, GetKeyModifierState()); break; case WM_LBUTTONUP: context->ProcessMouseButtonUp(0, GetKeyModifierState()); break; case WM_RBUTTONDOWN: context->ProcessMouseButtonDown(1, GetKeyModifierState()); break; case WM_RBUTTONUP: context->ProcessMouseButtonUp(1, GetKeyModifierState()); break; case WM_MBUTTONDOWN: context->ProcessMouseButtonDown(2, GetKeyModifierState()); break; case WM_MBUTTONUP: context->ProcessMouseButtonUp(2, GetKeyModifierState()); break; case WM_MOUSEMOVE: context->ProcessMouseMove(LOWORD(l_param), HIWORD(l_param), GetKeyModifierState()); break; case WM_MOUSEWHEEL: context->ProcessMouseWheel(static_cast((short) HIWORD(w_param)) / static_cast(-WHEEL_DELTA), GetKeyModifierState()); break; case WM_KEYDOWN: { Rml::Core::Input::KeyIdentifier key_identifier = key_identifier_map[w_param]; int key_modifier_state = GetKeyModifierState(); // Check for F8 to toggle the debugger. if (key_identifier == Rml::Core::Input::KI_F8) { Rml::Debugger::SetVisible(!Rml::Debugger::IsVisible()); break; } context->ProcessKeyDown(key_identifier, key_modifier_state); } break; case WM_CHAR: { static char16_t first_u16_code_unit = 0; char16_t c = (char16_t)w_param; Rml::Core::CodePoint code_point = (Rml::Core::CodePoint)c; // Windows sends two-wide characters as two messages. if (c >= 0xD800 && c < 0xDC00) { // First 16-bit code unit of a two-wide character. first_u16_code_unit = c; } else { if (c >= 0xDC00 && c < 0xE000 && first_u16_code_unit != 0) { // Second 16-bit code unit of a two-wide character. Rml::Core::String utf8 = Rml::Core::StringUtilities::ToUTF8({ first_u16_code_unit, c }); code_point = Rml::Core::StringUtilities::ToCodePoint(utf8.data()); } else if (c == '\r') { // Windows sends new-lines as carriage returns, convert to endlines. code_point = (Rml::Core::CodePoint)'\n'; } first_u16_code_unit = 0; // Only send through printable characters. if ((char32_t)code_point >= 32 || code_point == (Rml::Core::CodePoint)'\n') context->ProcessTextInput(code_point); } } break; case WM_KEYUP: context->ProcessKeyUp(key_identifier_map[w_param], GetKeyModifierState()); break; } } static int GetKeyModifierState() { int key_modifier_state = 0; // Query the state of all modifier keys if (GetKeyState(VK_CAPITAL) & 1) { key_modifier_state |= Rml::Core::Input::KM_CAPSLOCK; } if (HIWORD(GetKeyState(VK_SHIFT)) & 1) { key_modifier_state |= Rml::Core::Input::KM_SHIFT; } if (GetKeyState(VK_NUMLOCK) & 1) { key_modifier_state |= Rml::Core::Input::KM_NUMLOCK; } if (HIWORD(GetKeyState(VK_CONTROL)) & 1) { key_modifier_state |= Rml::Core::Input::KM_CTRL; } if (HIWORD(GetKeyState(VK_MENU)) & 1) { key_modifier_state |= Rml::Core::Input::KM_ALT; } return key_modifier_state; } // These are defined in winuser.h of MinGW 64 but are missing from MinGW 32 // Visual Studio has them by default #if defined(__MINGW32__) && !defined(__MINGW64__) #define VK_OEM_NEC_EQUAL 0x92 #define VK_OEM_FJ_JISHO 0x92 #define VK_OEM_FJ_MASSHOU 0x93 #define VK_OEM_FJ_TOUROKU 0x94 #define VK_OEM_FJ_LOYA 0x95 #define VK_OEM_FJ_ROYA 0x96 #define VK_OEM_AX 0xE1 #define VK_ICO_HELP 0xE3 #define VK_ICO_00 0xE4 #define VK_ICO_CLEAR 0xE6 #endif // !defined(__MINGW32__) || defined(__MINGW64__) static void InitialiseKeymap() { // Initialise the key map with default values. memset(key_identifier_map, 0, sizeof(key_identifier_map)); // Assign individual values. key_identifier_map['A'] = Rml::Core::Input::KI_A; key_identifier_map['B'] = Rml::Core::Input::KI_B; key_identifier_map['C'] = Rml::Core::Input::KI_C; key_identifier_map['D'] = Rml::Core::Input::KI_D; key_identifier_map['E'] = Rml::Core::Input::KI_E; key_identifier_map['F'] = Rml::Core::Input::KI_F; key_identifier_map['G'] = Rml::Core::Input::KI_G; key_identifier_map['H'] = Rml::Core::Input::KI_H; key_identifier_map['I'] = Rml::Core::Input::KI_I; key_identifier_map['J'] = Rml::Core::Input::KI_J; key_identifier_map['K'] = Rml::Core::Input::KI_K; key_identifier_map['L'] = Rml::Core::Input::KI_L; key_identifier_map['M'] = Rml::Core::Input::KI_M; key_identifier_map['N'] = Rml::Core::Input::KI_N; key_identifier_map['O'] = Rml::Core::Input::KI_O; key_identifier_map['P'] = Rml::Core::Input::KI_P; key_identifier_map['Q'] = Rml::Core::Input::KI_Q; key_identifier_map['R'] = Rml::Core::Input::KI_R; key_identifier_map['S'] = Rml::Core::Input::KI_S; key_identifier_map['T'] = Rml::Core::Input::KI_T; key_identifier_map['U'] = Rml::Core::Input::KI_U; key_identifier_map['V'] = Rml::Core::Input::KI_V; key_identifier_map['W'] = Rml::Core::Input::KI_W; key_identifier_map['X'] = Rml::Core::Input::KI_X; key_identifier_map['Y'] = Rml::Core::Input::KI_Y; key_identifier_map['Z'] = Rml::Core::Input::KI_Z; key_identifier_map['0'] = Rml::Core::Input::KI_0; key_identifier_map['1'] = Rml::Core::Input::KI_1; key_identifier_map['2'] = Rml::Core::Input::KI_2; key_identifier_map['3'] = Rml::Core::Input::KI_3; key_identifier_map['4'] = Rml::Core::Input::KI_4; key_identifier_map['5'] = Rml::Core::Input::KI_5; key_identifier_map['6'] = Rml::Core::Input::KI_6; key_identifier_map['7'] = Rml::Core::Input::KI_7; key_identifier_map['8'] = Rml::Core::Input::KI_8; key_identifier_map['9'] = Rml::Core::Input::KI_9; key_identifier_map[VK_BACK] = Rml::Core::Input::KI_BACK; key_identifier_map[VK_TAB] = Rml::Core::Input::KI_TAB; key_identifier_map[VK_CLEAR] = Rml::Core::Input::KI_CLEAR; key_identifier_map[VK_RETURN] = Rml::Core::Input::KI_RETURN; key_identifier_map[VK_PAUSE] = Rml::Core::Input::KI_PAUSE; key_identifier_map[VK_CAPITAL] = Rml::Core::Input::KI_CAPITAL; key_identifier_map[VK_KANA] = Rml::Core::Input::KI_KANA; key_identifier_map[VK_HANGUL] = Rml::Core::Input::KI_HANGUL; key_identifier_map[VK_JUNJA] = Rml::Core::Input::KI_JUNJA; key_identifier_map[VK_FINAL] = Rml::Core::Input::KI_FINAL; key_identifier_map[VK_HANJA] = Rml::Core::Input::KI_HANJA; key_identifier_map[VK_KANJI] = Rml::Core::Input::KI_KANJI; key_identifier_map[VK_ESCAPE] = Rml::Core::Input::KI_ESCAPE; key_identifier_map[VK_CONVERT] = Rml::Core::Input::KI_CONVERT; key_identifier_map[VK_NONCONVERT] = Rml::Core::Input::KI_NONCONVERT; key_identifier_map[VK_ACCEPT] = Rml::Core::Input::KI_ACCEPT; key_identifier_map[VK_MODECHANGE] = Rml::Core::Input::KI_MODECHANGE; key_identifier_map[VK_SPACE] = Rml::Core::Input::KI_SPACE; key_identifier_map[VK_PRIOR] = Rml::Core::Input::KI_PRIOR; key_identifier_map[VK_NEXT] = Rml::Core::Input::KI_NEXT; key_identifier_map[VK_END] = Rml::Core::Input::KI_END; key_identifier_map[VK_HOME] = Rml::Core::Input::KI_HOME; key_identifier_map[VK_LEFT] = Rml::Core::Input::KI_LEFT; key_identifier_map[VK_UP] = Rml::Core::Input::KI_UP; key_identifier_map[VK_RIGHT] = Rml::Core::Input::KI_RIGHT; key_identifier_map[VK_DOWN] = Rml::Core::Input::KI_DOWN; key_identifier_map[VK_SELECT] = Rml::Core::Input::KI_SELECT; key_identifier_map[VK_PRINT] = Rml::Core::Input::KI_PRINT; key_identifier_map[VK_EXECUTE] = Rml::Core::Input::KI_EXECUTE; key_identifier_map[VK_SNAPSHOT] = Rml::Core::Input::KI_SNAPSHOT; key_identifier_map[VK_INSERT] = Rml::Core::Input::KI_INSERT; key_identifier_map[VK_DELETE] = Rml::Core::Input::KI_DELETE; key_identifier_map[VK_HELP] = Rml::Core::Input::KI_HELP; key_identifier_map[VK_LWIN] = Rml::Core::Input::KI_LWIN; key_identifier_map[VK_RWIN] = Rml::Core::Input::KI_RWIN; key_identifier_map[VK_APPS] = Rml::Core::Input::KI_APPS; key_identifier_map[VK_SLEEP] = Rml::Core::Input::KI_SLEEP; key_identifier_map[VK_NUMPAD0] = Rml::Core::Input::KI_NUMPAD0; key_identifier_map[VK_NUMPAD1] = Rml::Core::Input::KI_NUMPAD1; key_identifier_map[VK_NUMPAD2] = Rml::Core::Input::KI_NUMPAD2; key_identifier_map[VK_NUMPAD3] = Rml::Core::Input::KI_NUMPAD3; key_identifier_map[VK_NUMPAD4] = Rml::Core::Input::KI_NUMPAD4; key_identifier_map[VK_NUMPAD5] = Rml::Core::Input::KI_NUMPAD5; key_identifier_map[VK_NUMPAD6] = Rml::Core::Input::KI_NUMPAD6; key_identifier_map[VK_NUMPAD7] = Rml::Core::Input::KI_NUMPAD7; key_identifier_map[VK_NUMPAD8] = Rml::Core::Input::KI_NUMPAD8; key_identifier_map[VK_NUMPAD9] = Rml::Core::Input::KI_NUMPAD9; key_identifier_map[VK_MULTIPLY] = Rml::Core::Input::KI_MULTIPLY; key_identifier_map[VK_ADD] = Rml::Core::Input::KI_ADD; key_identifier_map[VK_SEPARATOR] = Rml::Core::Input::KI_SEPARATOR; key_identifier_map[VK_SUBTRACT] = Rml::Core::Input::KI_SUBTRACT; key_identifier_map[VK_DECIMAL] = Rml::Core::Input::KI_DECIMAL; key_identifier_map[VK_DIVIDE] = Rml::Core::Input::KI_DIVIDE; key_identifier_map[VK_F1] = Rml::Core::Input::KI_F1; key_identifier_map[VK_F2] = Rml::Core::Input::KI_F2; key_identifier_map[VK_F3] = Rml::Core::Input::KI_F3; key_identifier_map[VK_F4] = Rml::Core::Input::KI_F4; key_identifier_map[VK_F5] = Rml::Core::Input::KI_F5; key_identifier_map[VK_F6] = Rml::Core::Input::KI_F6; key_identifier_map[VK_F7] = Rml::Core::Input::KI_F7; key_identifier_map[VK_F8] = Rml::Core::Input::KI_F8; key_identifier_map[VK_F9] = Rml::Core::Input::KI_F9; key_identifier_map[VK_F10] = Rml::Core::Input::KI_F10; key_identifier_map[VK_F11] = Rml::Core::Input::KI_F11; key_identifier_map[VK_F12] = Rml::Core::Input::KI_F12; key_identifier_map[VK_F13] = Rml::Core::Input::KI_F13; key_identifier_map[VK_F14] = Rml::Core::Input::KI_F14; key_identifier_map[VK_F15] = Rml::Core::Input::KI_F15; key_identifier_map[VK_F16] = Rml::Core::Input::KI_F16; key_identifier_map[VK_F17] = Rml::Core::Input::KI_F17; key_identifier_map[VK_F18] = Rml::Core::Input::KI_F18; key_identifier_map[VK_F19] = Rml::Core::Input::KI_F19; key_identifier_map[VK_F20] = Rml::Core::Input::KI_F20; key_identifier_map[VK_F21] = Rml::Core::Input::KI_F21; key_identifier_map[VK_F22] = Rml::Core::Input::KI_F22; key_identifier_map[VK_F23] = Rml::Core::Input::KI_F23; key_identifier_map[VK_F24] = Rml::Core::Input::KI_F24; key_identifier_map[VK_NUMLOCK] = Rml::Core::Input::KI_NUMLOCK; key_identifier_map[VK_SCROLL] = Rml::Core::Input::KI_SCROLL; key_identifier_map[VK_OEM_NEC_EQUAL] = Rml::Core::Input::KI_OEM_NEC_EQUAL; key_identifier_map[VK_OEM_FJ_JISHO] = Rml::Core::Input::KI_OEM_FJ_JISHO; key_identifier_map[VK_OEM_FJ_MASSHOU] = Rml::Core::Input::KI_OEM_FJ_MASSHOU; key_identifier_map[VK_OEM_FJ_TOUROKU] = Rml::Core::Input::KI_OEM_FJ_TOUROKU; key_identifier_map[VK_OEM_FJ_LOYA] = Rml::Core::Input::KI_OEM_FJ_LOYA; key_identifier_map[VK_OEM_FJ_ROYA] = Rml::Core::Input::KI_OEM_FJ_ROYA; key_identifier_map[VK_SHIFT] = Rml::Core::Input::KI_LSHIFT; key_identifier_map[VK_CONTROL] = Rml::Core::Input::KI_LCONTROL; key_identifier_map[VK_MENU] = Rml::Core::Input::KI_LMENU; key_identifier_map[VK_BROWSER_BACK] = Rml::Core::Input::KI_BROWSER_BACK; key_identifier_map[VK_BROWSER_FORWARD] = Rml::Core::Input::KI_BROWSER_FORWARD; key_identifier_map[VK_BROWSER_REFRESH] = Rml::Core::Input::KI_BROWSER_REFRESH; key_identifier_map[VK_BROWSER_STOP] = Rml::Core::Input::KI_BROWSER_STOP; key_identifier_map[VK_BROWSER_SEARCH] = Rml::Core::Input::KI_BROWSER_SEARCH; key_identifier_map[VK_BROWSER_FAVORITES] = Rml::Core::Input::KI_BROWSER_FAVORITES; key_identifier_map[VK_BROWSER_HOME] = Rml::Core::Input::KI_BROWSER_HOME; key_identifier_map[VK_VOLUME_MUTE] = Rml::Core::Input::KI_VOLUME_MUTE; key_identifier_map[VK_VOLUME_DOWN] = Rml::Core::Input::KI_VOLUME_DOWN; key_identifier_map[VK_VOLUME_UP] = Rml::Core::Input::KI_VOLUME_UP; key_identifier_map[VK_MEDIA_NEXT_TRACK] = Rml::Core::Input::KI_MEDIA_NEXT_TRACK; key_identifier_map[VK_MEDIA_PREV_TRACK] = Rml::Core::Input::KI_MEDIA_PREV_TRACK; key_identifier_map[VK_MEDIA_STOP] = Rml::Core::Input::KI_MEDIA_STOP; key_identifier_map[VK_MEDIA_PLAY_PAUSE] = Rml::Core::Input::KI_MEDIA_PLAY_PAUSE; key_identifier_map[VK_LAUNCH_MAIL] = Rml::Core::Input::KI_LAUNCH_MAIL; key_identifier_map[VK_LAUNCH_MEDIA_SELECT] = Rml::Core::Input::KI_LAUNCH_MEDIA_SELECT; key_identifier_map[VK_LAUNCH_APP1] = Rml::Core::Input::KI_LAUNCH_APP1; key_identifier_map[VK_LAUNCH_APP2] = Rml::Core::Input::KI_LAUNCH_APP2; key_identifier_map[VK_OEM_1] = Rml::Core::Input::KI_OEM_1; key_identifier_map[VK_OEM_PLUS] = Rml::Core::Input::KI_OEM_PLUS; key_identifier_map[VK_OEM_COMMA] = Rml::Core::Input::KI_OEM_COMMA; key_identifier_map[VK_OEM_MINUS] = Rml::Core::Input::KI_OEM_MINUS; key_identifier_map[VK_OEM_PERIOD] = Rml::Core::Input::KI_OEM_PERIOD; key_identifier_map[VK_OEM_2] = Rml::Core::Input::KI_OEM_2; key_identifier_map[VK_OEM_3] = Rml::Core::Input::KI_OEM_3; key_identifier_map[VK_OEM_4] = Rml::Core::Input::KI_OEM_4; key_identifier_map[VK_OEM_5] = Rml::Core::Input::KI_OEM_5; key_identifier_map[VK_OEM_6] = Rml::Core::Input::KI_OEM_6; key_identifier_map[VK_OEM_7] = Rml::Core::Input::KI_OEM_7; key_identifier_map[VK_OEM_8] = Rml::Core::Input::KI_OEM_8; key_identifier_map[VK_OEM_AX] = Rml::Core::Input::KI_OEM_AX; key_identifier_map[VK_OEM_102] = Rml::Core::Input::KI_OEM_102; key_identifier_map[VK_ICO_HELP] = Rml::Core::Input::KI_ICO_HELP; key_identifier_map[VK_ICO_00] = Rml::Core::Input::KI_ICO_00; key_identifier_map[VK_PROCESSKEY] = Rml::Core::Input::KI_PROCESSKEY; key_identifier_map[VK_ICO_CLEAR] = Rml::Core::Input::KI_ICO_CLEAR; key_identifier_map[VK_ATTN] = Rml::Core::Input::KI_ATTN; key_identifier_map[VK_CRSEL] = Rml::Core::Input::KI_CRSEL; key_identifier_map[VK_EXSEL] = Rml::Core::Input::KI_EXSEL; key_identifier_map[VK_EREOF] = Rml::Core::Input::KI_EREOF; key_identifier_map[VK_PLAY] = Rml::Core::Input::KI_PLAY; key_identifier_map[VK_ZOOM] = Rml::Core::Input::KI_ZOOM; key_identifier_map[VK_PA1] = Rml::Core::Input::KI_PA1; key_identifier_map[VK_OEM_CLEAR] = Rml::Core::Input::KI_OEM_CLEAR; }