diff options
Diffstat (limited to 'platform')
-rw-r--r-- | platform/linuxbsd/display_server_x11.cpp | 18 | ||||
-rw-r--r-- | platform/linuxbsd/display_server_x11.h | 1 | ||||
-rw-r--r-- | platform/linuxbsd/key_mapping_x11.cpp | 12 | ||||
-rw-r--r-- | platform/linuxbsd/key_mapping_x11.h | 1 | ||||
-rw-r--r-- | platform/osx/display_server_osx.h | 1 | ||||
-rw-r--r-- | platform/osx/display_server_osx.mm | 288 | ||||
-rw-r--r-- | platform/osx/os_osx.mm | 20 | ||||
-rw-r--r-- | platform/windows/display_server_windows.cpp | 36 | ||||
-rw-r--r-- | platform/windows/display_server_windows.h | 1 | ||||
-rw-r--r-- | platform/windows/key_mapping_windows.cpp | 10 | ||||
-rw-r--r-- | platform/windows/key_mapping_windows.h | 1 |
11 files changed, 250 insertions, 139 deletions
diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp index 66fcc8335d..f2cd336b39 100644 --- a/platform/linuxbsd/display_server_x11.cpp +++ b/platform/linuxbsd/display_server_x11.cpp @@ -2068,6 +2068,24 @@ String DisplayServerX11::keyboard_get_layout_name(int p_index) const { return ret; } +Key DisplayServerX11::keyboard_get_keycode_from_physical(Key p_keycode) const { + unsigned int modifiers = p_keycode & KEY_MODIFIER_MASK; + unsigned int keycode_no_mod = p_keycode & KEY_CODE_MASK; + unsigned int xkeycode = KeyMappingX11::get_xlibcode((Key)keycode_no_mod); + KeySym xkeysym = XkbKeycodeToKeysym(x11_display, xkeycode, 0, 0); + if (xkeysym >= 'a' && xkeysym <= 'z') { + xkeysym -= ('a' - 'A'); + } + + Key key = KeyMappingX11::get_keycode(xkeysym); + // If not found, fallback to QWERTY. + // This should match the behavior of the event pump + if (key == KEY_NONE) { + return p_keycode; + } + return (Key)(key | modifiers); +} + DisplayServerX11::Property DisplayServerX11::_read_property(Display *p_display, Window p_window, Atom p_property) { Atom actual_type = None; int actual_format = 0; diff --git a/platform/linuxbsd/display_server_x11.h b/platform/linuxbsd/display_server_x11.h index 052c6d6b7b..1887c7105b 100644 --- a/platform/linuxbsd/display_server_x11.h +++ b/platform/linuxbsd/display_server_x11.h @@ -372,6 +372,7 @@ public: virtual void keyboard_set_current_layout(int p_index) override; virtual String keyboard_get_layout_language(int p_index) const override; virtual String keyboard_get_layout_name(int p_index) const override; + virtual Key keyboard_get_keycode_from_physical(Key p_keycode) const override; virtual void process_events() override; diff --git a/platform/linuxbsd/key_mapping_x11.cpp b/platform/linuxbsd/key_mapping_x11.cpp index a1ef28234d..829feda40a 100644 --- a/platform/linuxbsd/key_mapping_x11.cpp +++ b/platform/linuxbsd/key_mapping_x11.cpp @@ -309,6 +309,18 @@ unsigned int KeyMappingX11::get_scancode(unsigned int p_code) { return keycode; } +unsigned int KeyMappingX11::get_xlibcode(unsigned int p_keysym) { + unsigned int code = 0; + for (int i = 0; _scancode_to_keycode[i].keysym != KEY_UNKNOWN; i++) { + if (_scancode_to_keycode[i].keysym == p_keysym) { + code = _scancode_to_keycode[i].keycode; + break; + } + } + + return code; +} + Key KeyMappingX11::get_keycode(KeySym p_keysym) { // kinda bruteforce.. could optimize. diff --git a/platform/linuxbsd/key_mapping_x11.h b/platform/linuxbsd/key_mapping_x11.h index 598db1c45a..d4f1554671 100644 --- a/platform/linuxbsd/key_mapping_x11.h +++ b/platform/linuxbsd/key_mapping_x11.h @@ -45,6 +45,7 @@ class KeyMappingX11 { public: static Key get_keycode(KeySym p_keysym); + static unsigned int get_xlibcode(unsigned int p_keysym); static unsigned int get_scancode(unsigned int p_code); static KeySym get_keysym(Key p_code); static unsigned int get_unicode_from_keysym(KeySym p_keysym); diff --git a/platform/osx/display_server_osx.h b/platform/osx/display_server_osx.h index 06b14f1c14..e8f2858489 100644 --- a/platform/osx/display_server_osx.h +++ b/platform/osx/display_server_osx.h @@ -305,6 +305,7 @@ public: virtual void keyboard_set_current_layout(int p_index) override; virtual String keyboard_get_layout_language(int p_index) const override; virtual String keyboard_get_layout_name(int p_index) const override; + virtual Key keyboard_get_keycode_from_physical(Key p_keycode) const override; virtual void process_events() override; virtual void force_process_and_drop_events() override; diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm index f037d75fbd..da6c45793a 100644 --- a/platform/osx/display_server_osx.mm +++ b/platform/osx/display_server_osx.mm @@ -930,146 +930,155 @@ static bool isNumpadKey(unsigned int key) { return false; } +// Keyboard symbol translation table +static const Key _osx_to_godot_table[128] = { + /* 00 */ KEY_A, + /* 01 */ KEY_S, + /* 02 */ KEY_D, + /* 03 */ KEY_F, + /* 04 */ KEY_H, + /* 05 */ KEY_G, + /* 06 */ KEY_Z, + /* 07 */ KEY_X, + /* 08 */ KEY_C, + /* 09 */ KEY_V, + /* 0a */ KEY_SECTION, /* ISO Section */ + /* 0b */ KEY_B, + /* 0c */ KEY_Q, + /* 0d */ KEY_W, + /* 0e */ KEY_E, + /* 0f */ KEY_R, + /* 10 */ KEY_Y, + /* 11 */ KEY_T, + /* 12 */ KEY_1, + /* 13 */ KEY_2, + /* 14 */ KEY_3, + /* 15 */ KEY_4, + /* 16 */ KEY_6, + /* 17 */ KEY_5, + /* 18 */ KEY_EQUAL, + /* 19 */ KEY_9, + /* 1a */ KEY_7, + /* 1b */ KEY_MINUS, + /* 1c */ KEY_8, + /* 1d */ KEY_0, + /* 1e */ KEY_BRACERIGHT, + /* 1f */ KEY_O, + /* 20 */ KEY_U, + /* 21 */ KEY_BRACELEFT, + /* 22 */ KEY_I, + /* 23 */ KEY_P, + /* 24 */ KEY_ENTER, + /* 25 */ KEY_L, + /* 26 */ KEY_J, + /* 27 */ KEY_APOSTROPHE, + /* 28 */ KEY_K, + /* 29 */ KEY_SEMICOLON, + /* 2a */ KEY_BACKSLASH, + /* 2b */ KEY_COMMA, + /* 2c */ KEY_SLASH, + /* 2d */ KEY_N, + /* 2e */ KEY_M, + /* 2f */ KEY_PERIOD, + /* 30 */ KEY_TAB, + /* 31 */ KEY_SPACE, + /* 32 */ KEY_QUOTELEFT, + /* 33 */ KEY_BACKSPACE, + /* 34 */ KEY_UNKNOWN, + /* 35 */ KEY_ESCAPE, + /* 36 */ KEY_META, + /* 37 */ KEY_META, + /* 38 */ KEY_SHIFT, + /* 39 */ KEY_CAPSLOCK, + /* 3a */ KEY_ALT, + /* 3b */ KEY_CTRL, + /* 3c */ KEY_SHIFT, + /* 3d */ KEY_ALT, + /* 3e */ KEY_CTRL, + /* 3f */ KEY_UNKNOWN, /* Function */ + /* 40 */ KEY_UNKNOWN, /* F17 */ + /* 41 */ KEY_KP_PERIOD, + /* 42 */ KEY_UNKNOWN, + /* 43 */ KEY_KP_MULTIPLY, + /* 44 */ KEY_UNKNOWN, + /* 45 */ KEY_KP_ADD, + /* 46 */ KEY_UNKNOWN, + /* 47 */ KEY_NUMLOCK, /* Really KeypadClear... */ + /* 48 */ KEY_VOLUMEUP, /* VolumeUp */ + /* 49 */ KEY_VOLUMEDOWN, /* VolumeDown */ + /* 4a */ KEY_VOLUMEMUTE, /* Mute */ + /* 4b */ KEY_KP_DIVIDE, + /* 4c */ KEY_KP_ENTER, + /* 4d */ KEY_UNKNOWN, + /* 4e */ KEY_KP_SUBTRACT, + /* 4f */ KEY_UNKNOWN, /* F18 */ + /* 50 */ KEY_UNKNOWN, /* F19 */ + /* 51 */ KEY_EQUAL, /* KeypadEqual */ + /* 52 */ KEY_KP_0, + /* 53 */ KEY_KP_1, + /* 54 */ KEY_KP_2, + /* 55 */ KEY_KP_3, + /* 56 */ KEY_KP_4, + /* 57 */ KEY_KP_5, + /* 58 */ KEY_KP_6, + /* 59 */ KEY_KP_7, + /* 5a */ KEY_UNKNOWN, /* F20 */ + /* 5b */ KEY_KP_8, + /* 5c */ KEY_KP_9, + /* 5d */ KEY_YEN, /* JIS Yen */ + /* 5e */ KEY_UNDERSCORE, /* JIS Underscore */ + /* 5f */ KEY_COMMA, /* JIS KeypadComma */ + /* 60 */ KEY_F5, + /* 61 */ KEY_F6, + /* 62 */ KEY_F7, + /* 63 */ KEY_F3, + /* 64 */ KEY_F8, + /* 65 */ KEY_F9, + /* 66 */ KEY_UNKNOWN, /* JIS Eisu */ + /* 67 */ KEY_F11, + /* 68 */ KEY_UNKNOWN, /* JIS Kana */ + /* 69 */ KEY_F13, + /* 6a */ KEY_F16, + /* 6b */ KEY_F14, + /* 6c */ KEY_UNKNOWN, + /* 6d */ KEY_F10, + /* 6e */ KEY_MENU, + /* 6f */ KEY_F12, + /* 70 */ KEY_UNKNOWN, + /* 71 */ KEY_F15, + /* 72 */ KEY_INSERT, /* Really Help... */ + /* 73 */ KEY_HOME, + /* 74 */ KEY_PAGEUP, + /* 75 */ KEY_DELETE, + /* 76 */ KEY_F4, + /* 77 */ KEY_END, + /* 78 */ KEY_F2, + /* 79 */ KEY_PAGEDOWN, + /* 7a */ KEY_F1, + /* 7b */ KEY_LEFT, + /* 7c */ KEY_RIGHT, + /* 7d */ KEY_DOWN, + /* 7e */ KEY_UP, + /* 7f */ KEY_UNKNOWN, +}; + // Translates a OS X keycode to a Godot keycode -// static Key translateKey(unsigned int key) { - // Keyboard symbol translation table - static const Key table[128] = { - /* 00 */ KEY_A, - /* 01 */ KEY_S, - /* 02 */ KEY_D, - /* 03 */ KEY_F, - /* 04 */ KEY_H, - /* 05 */ KEY_G, - /* 06 */ KEY_Z, - /* 07 */ KEY_X, - /* 08 */ KEY_C, - /* 09 */ KEY_V, - /* 0a */ KEY_SECTION, /* ISO Section */ - /* 0b */ KEY_B, - /* 0c */ KEY_Q, - /* 0d */ KEY_W, - /* 0e */ KEY_E, - /* 0f */ KEY_R, - /* 10 */ KEY_Y, - /* 11 */ KEY_T, - /* 12 */ KEY_1, - /* 13 */ KEY_2, - /* 14 */ KEY_3, - /* 15 */ KEY_4, - /* 16 */ KEY_6, - /* 17 */ KEY_5, - /* 18 */ KEY_EQUAL, - /* 19 */ KEY_9, - /* 1a */ KEY_7, - /* 1b */ KEY_MINUS, - /* 1c */ KEY_8, - /* 1d */ KEY_0, - /* 1e */ KEY_BRACERIGHT, - /* 1f */ KEY_O, - /* 20 */ KEY_U, - /* 21 */ KEY_BRACELEFT, - /* 22 */ KEY_I, - /* 23 */ KEY_P, - /* 24 */ KEY_ENTER, - /* 25 */ KEY_L, - /* 26 */ KEY_J, - /* 27 */ KEY_APOSTROPHE, - /* 28 */ KEY_K, - /* 29 */ KEY_SEMICOLON, - /* 2a */ KEY_BACKSLASH, - /* 2b */ KEY_COMMA, - /* 2c */ KEY_SLASH, - /* 2d */ KEY_N, - /* 2e */ KEY_M, - /* 2f */ KEY_PERIOD, - /* 30 */ KEY_TAB, - /* 31 */ KEY_SPACE, - /* 32 */ KEY_QUOTELEFT, - /* 33 */ KEY_BACKSPACE, - /* 34 */ KEY_UNKNOWN, - /* 35 */ KEY_ESCAPE, - /* 36 */ KEY_META, - /* 37 */ KEY_META, - /* 38 */ KEY_SHIFT, - /* 39 */ KEY_CAPSLOCK, - /* 3a */ KEY_ALT, - /* 3b */ KEY_CTRL, - /* 3c */ KEY_SHIFT, - /* 3d */ KEY_ALT, - /* 3e */ KEY_CTRL, - /* 3f */ KEY_UNKNOWN, /* Function */ - /* 40 */ KEY_UNKNOWN, /* F17 */ - /* 41 */ KEY_KP_PERIOD, - /* 42 */ KEY_UNKNOWN, - /* 43 */ KEY_KP_MULTIPLY, - /* 44 */ KEY_UNKNOWN, - /* 45 */ KEY_KP_ADD, - /* 46 */ KEY_UNKNOWN, - /* 47 */ KEY_NUMLOCK, /* Really KeypadClear... */ - /* 48 */ KEY_VOLUMEUP, /* VolumeUp */ - /* 49 */ KEY_VOLUMEDOWN, /* VolumeDown */ - /* 4a */ KEY_VOLUMEMUTE, /* Mute */ - /* 4b */ KEY_KP_DIVIDE, - /* 4c */ KEY_KP_ENTER, - /* 4d */ KEY_UNKNOWN, - /* 4e */ KEY_KP_SUBTRACT, - /* 4f */ KEY_UNKNOWN, /* F18 */ - /* 50 */ KEY_UNKNOWN, /* F19 */ - /* 51 */ KEY_EQUAL, /* KeypadEqual */ - /* 52 */ KEY_KP_0, - /* 53 */ KEY_KP_1, - /* 54 */ KEY_KP_2, - /* 55 */ KEY_KP_3, - /* 56 */ KEY_KP_4, - /* 57 */ KEY_KP_5, - /* 58 */ KEY_KP_6, - /* 59 */ KEY_KP_7, - /* 5a */ KEY_UNKNOWN, /* F20 */ - /* 5b */ KEY_KP_8, - /* 5c */ KEY_KP_9, - /* 5d */ KEY_YEN, /* JIS Yen */ - /* 5e */ KEY_UNDERSCORE, /* JIS Underscore */ - /* 5f */ KEY_COMMA, /* JIS KeypadComma */ - /* 60 */ KEY_F5, - /* 61 */ KEY_F6, - /* 62 */ KEY_F7, - /* 63 */ KEY_F3, - /* 64 */ KEY_F8, - /* 65 */ KEY_F9, - /* 66 */ KEY_UNKNOWN, /* JIS Eisu */ - /* 67 */ KEY_F11, - /* 68 */ KEY_UNKNOWN, /* JIS Kana */ - /* 69 */ KEY_F13, - /* 6a */ KEY_F16, - /* 6b */ KEY_F14, - /* 6c */ KEY_UNKNOWN, - /* 6d */ KEY_F10, - /* 6e */ KEY_MENU, - /* 6f */ KEY_F12, - /* 70 */ KEY_UNKNOWN, - /* 71 */ KEY_F15, - /* 72 */ KEY_INSERT, /* Really Help... */ - /* 73 */ KEY_HOME, - /* 74 */ KEY_PAGEUP, - /* 75 */ KEY_DELETE, - /* 76 */ KEY_F4, - /* 77 */ KEY_END, - /* 78 */ KEY_F2, - /* 79 */ KEY_PAGEDOWN, - /* 7a */ KEY_F1, - /* 7b */ KEY_LEFT, - /* 7c */ KEY_RIGHT, - /* 7d */ KEY_DOWN, - /* 7e */ KEY_UP, - /* 7f */ KEY_UNKNOWN, - }; - if (key >= 128) { return KEY_UNKNOWN; } - return table[key]; + return _osx_to_godot_table[key]; +} + +// Translates a Godot keycode back to a OSX keycode +static unsigned int unmapKey(Key key) { + for (int i = 0; i <= 126; i++) { + if (_osx_to_godot_table[i] == key) { + return i; + } + } + return 127; } struct _KeyCodeMap { @@ -3200,6 +3209,17 @@ String DisplayServerOSX::keyboard_get_layout_name(int p_index) const { return kbd_layouts[p_index].name; } +Key DisplayServerOSX::keyboard_get_keycode_from_physical(Key p_keycode) const { + if (p_keycode == KEY_PAUSE) { + return p_keycode; + } + + unsigned int modifiers = p_keycode & KEY_MODIFIER_MASK; + unsigned int keycode_no_mod = p_keycode & KEY_CODE_MASK; + unsigned int osx_keycode = unmapKey((Key)keycode_no_mod); + return (Key)(remapKey(osx_keycode, 0) | modifiers); +} + void DisplayServerOSX::_push_input(const Ref<InputEvent> &p_event) { Ref<InputEvent> ev = p_event; Input::get_singleton()->parse_input_event(ev); diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index 6ef1bdbd11..e9cb46ed21 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -314,17 +314,27 @@ String OS_OSX::get_name() const { return "macOS"; } +_FORCE_INLINE_ String _get_framework_executable(const String p_path) { + // Append framework executable name, or return as is if p_path is not a framework. + DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + if (da->dir_exists(p_path) && da->file_exists(p_path.plus_file(p_path.get_file().get_basename()))) { + return p_path.plus_file(p_path.get_file().get_basename()); + } else { + return p_path; + } +} + Error OS_OSX::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) { - String path = p_path; + String path = _get_framework_executable(p_path); if (!FileAccess::exists(path)) { - //this code exists so gdnative can load .dylib files from within the executable path - path = get_executable_path().get_base_dir().plus_file(p_path.get_file()); + // This code exists so gdnative can load .dylib files from within the executable path. + path = _get_framework_executable(get_executable_path().get_base_dir().plus_file(p_path.get_file())); } if (!FileAccess::exists(path)) { - //this code exists so gdnative can load .dylib files from a standard macOS location - path = get_executable_path().get_base_dir().plus_file("../Frameworks").plus_file(p_path.get_file()); + // This code exists so gdnative can load .dylib files from a standard macOS location. + path = _get_framework_executable(get_executable_path().get_base_dir().plus_file("../Frameworks").plus_file(p_path.get_file())); } p_library_handle = dlopen(path.utf8().get_data(), RTLD_NOW); diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index a4be108c65..3100c0bd27 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -1476,6 +1476,42 @@ String DisplayServerWindows::keyboard_get_layout_language(int p_index) const { return String::utf16((const char16_t *)buf).substr(0, 2); } +Key DisplayServerWindows::keyboard_get_keycode_from_physical(Key p_keycode) const { + unsigned int modifiers = p_keycode & KEY_MODIFIER_MASK; + Key keycode_no_mod = (Key)(p_keycode & KEY_CODE_MASK); + + if (keycode_no_mod == KEY_PRINT || + keycode_no_mod == KEY_KP_ADD || + keycode_no_mod == KEY_KP_5 || + (keycode_no_mod >= KEY_0 && keycode_no_mod <= KEY_9)) { + return p_keycode; + } + + unsigned int scancode = KeyMappingWindows::get_scancode(keycode_no_mod); + if (scancode == 0) { + return p_keycode; + } + + HKL current_layout = GetKeyboardLayout(0); + UINT vk = MapVirtualKeyEx(scancode, MAPVK_VSC_TO_VK, current_layout); + if (vk == 0) { + return p_keycode; + } + + UINT char_code = MapVirtualKeyEx(vk, MAPVK_VK_TO_CHAR, current_layout) & 0x7FFF; + // Unlike a similar Linux/BSD check which matches full Latin-1 range, + // we limit these to ASCII to fix some layouts, including Arabic ones + if (char_code >= 32 && char_code <= 127) { + // Godot uses 'braces' instead of 'brackets' + if (char_code == KEY_BRACKETLEFT || char_code == KEY_BRACKETRIGHT) { + char_code += 32; + } + return (Key)(char_code | modifiers); + } + + return (Key)(KeyMappingWindows::get_keysym(vk) | modifiers); +} + String _get_full_layout_name_from_registry(HKL p_layout) { String id = "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\" + String::num_int64((int64_t)p_layout, 16, false).lpad(8, "0"); String ret; diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h index c02a90c543..8b82288a40 100644 --- a/platform/windows/display_server_windows.h +++ b/platform/windows/display_server_windows.h @@ -543,6 +543,7 @@ public: virtual void keyboard_set_current_layout(int p_index) override; virtual String keyboard_get_layout_language(int p_index) const override; virtual String keyboard_get_layout_name(int p_index) const override; + virtual Key keyboard_get_keycode_from_physical(Key p_keycode) const override; virtual int tablet_get_driver_count() const override; virtual String tablet_get_driver_name(int p_driver) const override; diff --git a/platform/windows/key_mapping_windows.cpp b/platform/windows/key_mapping_windows.cpp index db99d6c122..8016d20470 100644 --- a/platform/windows/key_mapping_windows.cpp +++ b/platform/windows/key_mapping_windows.cpp @@ -345,6 +345,16 @@ unsigned int KeyMappingWindows::get_keysym(unsigned int p_code) { return KEY_UNKNOWN; } +unsigned int KeyMappingWindows::get_scancode(Key p_keycode) { + for (int i = 0; _scancode_to_keycode[i].keysym != KEY_UNKNOWN; i++) { + if (_scancode_to_keycode[i].keysym == p_keycode) { + return _scancode_to_keycode[i].keycode; + } + } + + return 0; +} + unsigned int KeyMappingWindows::get_scansym(unsigned int p_code, bool p_extended) { unsigned int keycode = KEY_UNKNOWN; for (int i = 0; _scancode_to_keycode[i].keysym != KEY_UNKNOWN; i++) { diff --git a/platform/windows/key_mapping_windows.h b/platform/windows/key_mapping_windows.h index fb07227014..f260666a3e 100644 --- a/platform/windows/key_mapping_windows.h +++ b/platform/windows/key_mapping_windows.h @@ -42,6 +42,7 @@ class KeyMappingWindows { public: static unsigned int get_keysym(unsigned int p_code); + static unsigned int get_scancode(Key p_keycode); static unsigned int get_scansym(unsigned int p_code, bool p_extended); static bool is_extended_key(unsigned int p_code); }; |