From 1b862baaa32f28f08cc5eef0ca6c027f8637398c Mon Sep 17 00:00:00 2001 From: bilsaboob Date: Mon, 28 Mar 2022 01:12:23 +0200 Subject: [PATCH] add support for VK key mapping --- examples/windows.c | 2 + include/GLFW/glfw3.h | 2 + src/win32_init.c | 136 +++++++++++++++++++++++++++++++++++++++++++ src/win32_platform.h | 1 + src/win32_window.c | 26 ++++++++- tests/events.c | 48 +++++++-------- 6 files changed, 188 insertions(+), 27 deletions(-) diff --git a/examples/windows.c b/examples/windows.c index 1589ffbf..c6603a00 100644 --- a/examples/windows.c +++ b/examples/windows.c @@ -37,6 +37,8 @@ int main(int argc, char** argv) const char* description; GLFWwindow* windows[4]; + printf("testing windows example: %s", "test"); + if (!glfwInit()) { glfwGetError(&description); diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 26875465..f98b6f71 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -442,6 +442,8 @@ extern "C" { #define GLFW_KEY_WORLD_1 161 /* non-US #1 */ #define GLFW_KEY_WORLD_2 162 /* non-US #2 */ +#define GLFW_KEY_VK 231 + /* Function keys */ #define GLFW_KEY_ESCAPE 256 #define GLFW_KEY_ENTER 257 diff --git a/src/win32_init.c b/src/win32_init.c index 64393e77..8bb6b29f 100644 --- a/src/win32_init.c +++ b/src/win32_init.c @@ -200,10 +200,12 @@ static void freeLibraries(void) static void createKeyTables(void) { int scancode; + int vk; memset(_glfw.win32.keycodes, -1, sizeof(_glfw.win32.keycodes)); memset(_glfw.win32.scancodes, -1, sizeof(_glfw.win32.scancodes)); + // map the keycodes by scancode _glfw.win32.keycodes[0x00B] = GLFW_KEY_0; _glfw.win32.keycodes[0x002] = GLFW_KEY_1; _glfw.win32.keycodes[0x003] = GLFW_KEY_2; @@ -297,6 +299,7 @@ static void createKeyTables(void) _glfw.win32.keycodes[0x038] = GLFW_KEY_LEFT_ALT; _glfw.win32.keycodes[0x01D] = GLFW_KEY_LEFT_CONTROL; _glfw.win32.keycodes[0x02A] = GLFW_KEY_LEFT_SHIFT; + _glfw.win32.keycodes[0x100] = GLFW_KEY_VK; _glfw.win32.keycodes[0x15B] = GLFW_KEY_LEFT_SUPER; _glfw.win32.keycodes[0x137] = GLFW_KEY_PRINT_SCREEN; _glfw.win32.keycodes[0x138] = GLFW_KEY_RIGHT_ALT; @@ -326,6 +329,139 @@ static void createKeyTables(void) _glfw.win32.keycodes[0x037] = GLFW_KEY_KP_MULTIPLY; _glfw.win32.keycodes[0x04A] = GLFW_KEY_KP_SUBTRACT; + + // init the virtual keys + for (vk = 0; vk < 256; vk++) + _glfw.win32.vkkeycodes[vk] = 0; + + // map the keycodes by scancode + _glfw.win32.vkkeycodes[0x30] = GLFW_KEY_0; + _glfw.win32.vkkeycodes[0x31] = GLFW_KEY_1; + _glfw.win32.vkkeycodes[0x32] = GLFW_KEY_2; + _glfw.win32.vkkeycodes[0x33] = GLFW_KEY_3; + _glfw.win32.vkkeycodes[0x34] = GLFW_KEY_4; + _glfw.win32.vkkeycodes[0x35] = GLFW_KEY_5; + _glfw.win32.vkkeycodes[0x36] = GLFW_KEY_6; + _glfw.win32.vkkeycodes[0x37] = GLFW_KEY_7; + _glfw.win32.vkkeycodes[0x38] = GLFW_KEY_8; + _glfw.win32.vkkeycodes[0x39] = GLFW_KEY_9; + _glfw.win32.vkkeycodes[0x41] = GLFW_KEY_A; + _glfw.win32.vkkeycodes[0x42] = GLFW_KEY_B; + _glfw.win32.vkkeycodes[0x43] = GLFW_KEY_C; + _glfw.win32.vkkeycodes[0x44] = GLFW_KEY_D; + _glfw.win32.vkkeycodes[0x45] = GLFW_KEY_E; + _glfw.win32.vkkeycodes[0x46] = GLFW_KEY_F; + _glfw.win32.vkkeycodes[0x47] = GLFW_KEY_G; + _glfw.win32.vkkeycodes[0x47] = GLFW_KEY_H; + _glfw.win32.vkkeycodes[0x49] = GLFW_KEY_I; + _glfw.win32.vkkeycodes[0x4A] = GLFW_KEY_J; + _glfw.win32.vkkeycodes[0x4B] = GLFW_KEY_K; + _glfw.win32.vkkeycodes[0x4C] = GLFW_KEY_L; + _glfw.win32.vkkeycodes[0x4D] = GLFW_KEY_M; + _glfw.win32.vkkeycodes[0x4E] = GLFW_KEY_N; + _glfw.win32.vkkeycodes[0x4F] = GLFW_KEY_O; + _glfw.win32.vkkeycodes[0x50] = GLFW_KEY_P; + _glfw.win32.vkkeycodes[0x51] = GLFW_KEY_Q; + _glfw.win32.vkkeycodes[0x52] = GLFW_KEY_R; + _glfw.win32.vkkeycodes[0x53] = GLFW_KEY_S; + _glfw.win32.vkkeycodes[0x54] = GLFW_KEY_T; + _glfw.win32.vkkeycodes[0x55] = GLFW_KEY_U; + _glfw.win32.vkkeycodes[0x56] = GLFW_KEY_V; + _glfw.win32.vkkeycodes[0x57] = GLFW_KEY_W; + _glfw.win32.vkkeycodes[0x58] = GLFW_KEY_X; + _glfw.win32.vkkeycodes[0x59] = GLFW_KEY_Y; + _glfw.win32.vkkeycodes[0x5A] = GLFW_KEY_Z; + + //_glfw.win32.vkkeycodes[] = GLFW_KEY_APOSTROPHE; + _glfw.win32.vkkeycodes[0xBF] = GLFW_KEY_BACKSLASH; + _glfw.win32.vkkeycodes[0xBC] = GLFW_KEY_COMMA; + //_glfw.win32.vkkeycodes[0x00D] = GLFW_KEY_EQUAL; + //_glfw.win32.vkkeycodes[0x029] = GLFW_KEY_GRAVE_ACCENT; + //_glfw.win32.vkkeycodes[0x01A] = GLFW_KEY_LEFT_BRACKET; + _glfw.win32.vkkeycodes[0xBB] = GLFW_KEY_KP_ADD; + _glfw.win32.vkkeycodes[0xBD] = GLFW_KEY_MINUS; + _glfw.win32.vkkeycodes[0xBE] = GLFW_KEY_PERIOD; + //_glfw.win32.vkkeycodes[0x01B] = GLFW_KEY_RIGHT_BRACKET; + //_glfw.win32.vkkeycodes[0x027] = GLFW_KEY_SEMICOLON; + //_glfw.win32.vkkeycodes[0x035] = GLFW_KEY_SLASH; + //_glfw.win32.vkkeycodes[0x056] = GLFW_KEY_WORLD_2; + + _glfw.win32.vkkeycodes[0x08] = GLFW_KEY_BACKSPACE; + _glfw.win32.vkkeycodes[0x2E] = GLFW_KEY_DELETE; + _glfw.win32.vkkeycodes[0x23] = GLFW_KEY_END; + _glfw.win32.vkkeycodes[0x0D] = GLFW_KEY_ENTER; + _glfw.win32.vkkeycodes[0x1B] = GLFW_KEY_ESCAPE; + _glfw.win32.vkkeycodes[0x24] = GLFW_KEY_HOME; + _glfw.win32.vkkeycodes[0x2D] = GLFW_KEY_INSERT; + _glfw.win32.vkkeycodes[0x10] = GLFW_KEY_LEFT_SHIFT; + _glfw.win32.vkkeycodes[0x11] = GLFW_KEY_LEFT_CONTROL; + _glfw.win32.vkkeycodes[0x12] = GLFW_KEY_MENU; + _glfw.win32.vkkeycodes[0x22] = GLFW_KEY_PAGE_DOWN; + _glfw.win32.vkkeycodes[0x21] = GLFW_KEY_PAGE_UP; + _glfw.win32.vkkeycodes[0x13] = GLFW_KEY_PAUSE; + _glfw.win32.vkkeycodes[0x20] = GLFW_KEY_SPACE; + _glfw.win32.vkkeycodes[0x09] = GLFW_KEY_TAB; + _glfw.win32.vkkeycodes[0x14] = GLFW_KEY_CAPS_LOCK; + _glfw.win32.vkkeycodes[0x90] = GLFW_KEY_NUM_LOCK; + _glfw.win32.vkkeycodes[0x91] = GLFW_KEY_SCROLL_LOCK; + _glfw.win32.vkkeycodes[0x70] = GLFW_KEY_F1; + _glfw.win32.vkkeycodes[0x71] = GLFW_KEY_F2; + _glfw.win32.vkkeycodes[0x72] = GLFW_KEY_F3; + _glfw.win32.vkkeycodes[0x73] = GLFW_KEY_F4; + _glfw.win32.vkkeycodes[0x74] = GLFW_KEY_F5; + _glfw.win32.vkkeycodes[0x75] = GLFW_KEY_F6; + _glfw.win32.vkkeycodes[0x76] = GLFW_KEY_F7; + _glfw.win32.vkkeycodes[0x77] = GLFW_KEY_F8; + _glfw.win32.vkkeycodes[0x78] = GLFW_KEY_F9; + _glfw.win32.vkkeycodes[0x79] = GLFW_KEY_F10; + _glfw.win32.vkkeycodes[0x7A] = GLFW_KEY_F11; + _glfw.win32.vkkeycodes[0x7B] = GLFW_KEY_F12; + _glfw.win32.vkkeycodes[0x7C] = GLFW_KEY_F13; + _glfw.win32.vkkeycodes[0x7D] = GLFW_KEY_F14; + _glfw.win32.vkkeycodes[0x7E] = GLFW_KEY_F15; + _glfw.win32.vkkeycodes[0x7F] = GLFW_KEY_F16; + _glfw.win32.vkkeycodes[0x80] = GLFW_KEY_F17; + _glfw.win32.vkkeycodes[0x81] = GLFW_KEY_F18; + _glfw.win32.vkkeycodes[0x82] = GLFW_KEY_F19; + _glfw.win32.vkkeycodes[0x83] = GLFW_KEY_F20; + _glfw.win32.vkkeycodes[0x84] = GLFW_KEY_F21; + _glfw.win32.vkkeycodes[0x85] = GLFW_KEY_F22; + _glfw.win32.vkkeycodes[0x86] = GLFW_KEY_F23; + _glfw.win32.vkkeycodes[0x87] = GLFW_KEY_F24; + _glfw.win32.vkkeycodes[0xA0] = GLFW_KEY_RIGHT_SHIFT; + _glfw.win32.vkkeycodes[0xA1] = GLFW_KEY_LEFT_SHIFT; + _glfw.win32.vkkeycodes[0xA2] = GLFW_KEY_LEFT_CONTROL; + _glfw.win32.vkkeycodes[0xA3] = GLFW_KEY_RIGHT_CONTROL; + _glfw.win32.vkkeycodes[0xA4] = GLFW_KEY_LEFT_ALT; + _glfw.win32.vkkeycodes[0xA5] = GLFW_KEY_RIGHT_ALT; + + _glfw.win32.vkkeycodes[0x5B] = GLFW_KEY_LEFT_SUPER; + _glfw.win32.vkkeycodes[0x2C] = GLFW_KEY_PRINT_SCREEN; + _glfw.win32.vkkeycodes[0x5C] = GLFW_KEY_RIGHT_SUPER; + + _glfw.win32.vkkeycodes[0x28] = GLFW_KEY_DOWN; + _glfw.win32.vkkeycodes[0x25] = GLFW_KEY_LEFT; + _glfw.win32.vkkeycodes[0x27] = GLFW_KEY_RIGHT; + _glfw.win32.vkkeycodes[0x26] = GLFW_KEY_UP; + + _glfw.win32.vkkeycodes[0x60] = GLFW_KEY_KP_0; + _glfw.win32.vkkeycodes[0x61] = GLFW_KEY_KP_1; + _glfw.win32.vkkeycodes[0x62] = GLFW_KEY_KP_2; + _glfw.win32.vkkeycodes[0x63] = GLFW_KEY_KP_3; + _glfw.win32.vkkeycodes[0x64] = GLFW_KEY_KP_4; + _glfw.win32.vkkeycodes[0x65] = GLFW_KEY_KP_5; + _glfw.win32.vkkeycodes[0x66] = GLFW_KEY_KP_6; + _glfw.win32.vkkeycodes[0x67] = GLFW_KEY_KP_7; + _glfw.win32.vkkeycodes[0x68] = GLFW_KEY_KP_8; + _glfw.win32.vkkeycodes[0x69] = GLFW_KEY_KP_9; + _glfw.win32.vkkeycodes[0x6B] = GLFW_KEY_KP_ADD; + _glfw.win32.vkkeycodes[0x6E] = GLFW_KEY_KP_DECIMAL; + _glfw.win32.vkkeycodes[0x6F] = GLFW_KEY_KP_DIVIDE; + //_glfw.win32.vkkeycodes[0x11C] = GLFW_KEY_KP_ENTER; + //_glfw.win32.vkkeycodes[0x059] = GLFW_KEY_KP_EQUAL; + _glfw.win32.vkkeycodes[0x6A] = GLFW_KEY_KP_MULTIPLY; + _glfw.win32.vkkeycodes[0x6D] = GLFW_KEY_KP_SUBTRACT; + for (scancode = 0; scancode < 512; scancode++) { if (_glfw.win32.keycodes[scancode] > 0) diff --git a/src/win32_platform.h b/src/win32_platform.h index 82b34bb9..18d0e99c 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -447,6 +447,7 @@ typedef struct _GLFWlibraryWin32 char* clipboardString; short int keycodes[512]; short int scancodes[GLFW_KEY_LAST + 1]; + short int vkkeycodes[256]; char keynames[GLFW_KEY_LAST + 1][5]; // Where to place the cursor when re-enabled double restoreCursorPosX, restoreCursorPosY; diff --git a/src/win32_window.c b/src/win32_window.c index 676640bf..06e39271 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -37,6 +37,8 @@ #include #include +#include + // Returns the window style for the specified window // static DWORD getWindowStyle(const _GLFWwindow* window) @@ -688,6 +690,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l case WM_UNICHAR: { + printf("char event: (lParam=%d, wParam=%d)\n", lParam, wParam); + if (wParam == UNICODE_NOCHAR) { // WM_UNICHAR is not sent by Windows, but is sent by some @@ -709,27 +713,41 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l const int action = (HIWORD(lParam) & KF_UP) ? GLFW_RELEASE : GLFW_PRESS; const int mods = getKeyMods(); + //printf("key event1: (lParam=%d, wParam=%d)\n", lParam, wParam); + scancode = (HIWORD(lParam) & (KF_EXTENDED | 0xff)); + //printf("key event2: (lParam=%d, wParam=%d, sc=%d)\n", lParam, wParam, scancode); if (!scancode) { // NOTE: Some synthetic key messages have a scancode of zero // HACK: Map the virtual key back to a usable scancode scancode = MapVirtualKeyW((UINT) wParam, MAPVK_VK_TO_VSC); + //printf("key event3: (lParam=%d, wParam=%d, sc=%d)\n", lParam, wParam, scancode); } + //printf("key event4: (lParam=%d, wParam=%d, sc=%d)\n", lParam, wParam, scancode); // HACK: Alt+PrtSc has a different scancode than just PrtSc - if (scancode == 0x54) + if (scancode == 0x54) { scancode = 0x137; + //printf("key event5: (lParam=%d, wParam=%d, sc=%d)\n", lParam, wParam, scancode); + } // HACK: Ctrl+Pause has a different scancode than just Pause - if (scancode == 0x146) + if (scancode == 0x146) { scancode = 0x45; + //printf("key event6: (lParam=%d, wParam=%d, sc=%d)\n", lParam, wParam, scancode); + } // HACK: CJK IME sets the extended bit for right Shift if (scancode == 0x136) scancode = 0x36; key = _glfw.win32.keycodes[scancode]; + if(key == GLFW_KEY_VK) { + key = _glfw.win32.vkkeycodes[wParam]; + } + + //printf("key event7: (lParam=%d, wParam=%d, key=%d, sc=%d)\n", lParam, wParam, key, scancode); // The Ctrl keys require special handling if (wParam == VK_CONTROL) @@ -790,8 +808,10 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l _glfwInputKey(window, key, scancode, GLFW_PRESS, mods); _glfwInputKey(window, key, scancode, GLFW_RELEASE, mods); } - else + else { + //printf("_glfwInputKey event: (lParam=%d, wParam=%d, key=%d)\n", lParam, wParam, key); _glfwInputKey(window, key, scancode, action, mods); + } break; } diff --git a/tests/events.c b/tests/events.c index 60d4fc89..d61e374d 100644 --- a/tests/events.c +++ b/tests/events.c @@ -290,36 +290,36 @@ static void error_callback(int error, const char* description) static void window_pos_callback(GLFWwindow* window, int x, int y) { Slot* slot = glfwGetWindowUserPointer(window); - printf("%08x to %i at %0.3f: Window position: %i %i\n", - counter++, slot->number, glfwGetTime(), x, y); + /*printf("%08x to %i at %0.3f: Window position: %i %i\n", + counter++, slot->number, glfwGetTime(), x, y);*/ } static void window_size_callback(GLFWwindow* window, int width, int height) { Slot* slot = glfwGetWindowUserPointer(window); - printf("%08x to %i at %0.3f: Window size: %i %i\n", - counter++, slot->number, glfwGetTime(), width, height); + /*printf("%08x to %i at %0.3f: Window size: %i %i\n", + counter++, slot->number, glfwGetTime(), width, height);*/ } static void framebuffer_size_callback(GLFWwindow* window, int width, int height) { Slot* slot = glfwGetWindowUserPointer(window); - printf("%08x to %i at %0.3f: Framebuffer size: %i %i\n", - counter++, slot->number, glfwGetTime(), width, height); + /*printf("%08x to %i at %0.3f: Framebuffer size: %i %i\n", + counter++, slot->number, glfwGetTime(), width, height);*/ } static void window_content_scale_callback(GLFWwindow* window, float xscale, float yscale) { Slot* slot = glfwGetWindowUserPointer(window); - printf("%08x to %i at %0.3f: Window content scale: %0.3f %0.3f\n", - counter++, slot->number, glfwGetTime(), xscale, yscale); + /*printf("%08x to %i at %0.3f: Window content scale: %0.3f %0.3f\n", + counter++, slot->number, glfwGetTime(), xscale, yscale);*/ } static void window_close_callback(GLFWwindow* window) { Slot* slot = glfwGetWindowUserPointer(window); - printf("%08x to %i at %0.3f: Window close\n", - counter++, slot->number, glfwGetTime()); + /*printf("%08x to %i at %0.3f: Window close\n", + counter++, slot->number, glfwGetTime());*/ if (!slot->closeable) { @@ -333,8 +333,8 @@ static void window_close_callback(GLFWwindow* window) static void window_refresh_callback(GLFWwindow* window) { Slot* slot = glfwGetWindowUserPointer(window); - printf("%08x to %i at %0.3f: Window refresh\n", - counter++, slot->number, glfwGetTime()); + /*printf("%08x to %i at %0.3f: Window refresh\n", + counter++, slot->number, glfwGetTime());*/ glfwMakeContextCurrent(window); glClear(GL_COLOR_BUFFER_BIT); @@ -352,49 +352,49 @@ static void window_focus_callback(GLFWwindow* window, int focused) static void window_iconify_callback(GLFWwindow* window, int iconified) { Slot* slot = glfwGetWindowUserPointer(window); - printf("%08x to %i at %0.3f: Window was %s\n", + /*printf("%08x to %i at %0.3f: Window was %s\n", counter++, slot->number, glfwGetTime(), - iconified ? "iconified" : "uniconified"); + iconified ? "iconified" : "uniconified");*/ } static void window_maximize_callback(GLFWwindow* window, int maximized) { Slot* slot = glfwGetWindowUserPointer(window); - printf("%08x to %i at %0.3f: Window was %s\n", + /*printf("%08x to %i at %0.3f: Window was %s\n", counter++, slot->number, glfwGetTime(), - maximized ? "maximized" : "unmaximized"); + maximized ? "maximized" : "unmaximized");*/ } static void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) { Slot* slot = glfwGetWindowUserPointer(window); - printf("%08x to %i at %0.3f: Mouse button %i (%s) (with%s) was %s\n", + /*printf("%08x to %i at %0.3f: Mouse button %i (%s) (with%s) was %s\n", counter++, slot->number, glfwGetTime(), button, get_button_name(button), get_mods_name(mods), - get_action_name(action)); + get_action_name(action));*/ } static void cursor_position_callback(GLFWwindow* window, double x, double y) { Slot* slot = glfwGetWindowUserPointer(window); - printf("%08x to %i at %0.3f: Cursor position: %f %f\n", - counter++, slot->number, glfwGetTime(), x, y); + /*printf("%08x to %i at %0.3f: Cursor position: %f %f\n", + counter++, slot->number, glfwGetTime(), x, y);*/ } static void cursor_enter_callback(GLFWwindow* window, int entered) { Slot* slot = glfwGetWindowUserPointer(window); - printf("%08x to %i at %0.3f: Cursor %s window\n", + /*printf("%08x to %i at %0.3f: Cursor %s window\n", counter++, slot->number, glfwGetTime(), - entered ? "entered" : "left"); + entered ? "entered" : "left");*/ } static void scroll_callback(GLFWwindow* window, double x, double y) { Slot* slot = glfwGetWindowUserPointer(window); - printf("%08x to %i at %0.3f: Scroll: %0.3f %0.3f\n", - counter++, slot->number, glfwGetTime(), x, y); + /*printf("%08x to %i at %0.3f: Scroll: %0.3f %0.3f\n", + counter++, slot->number, glfwGetTime(), x, y);*/ } static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)