Backport: Allow for mapping scancodes to current layout
Co-authored-by: Frixuu <kontakt@lukasz.xyz>
This commit is contained in:
parent
9c04c75e7d
commit
b4ec1c5817
15 changed files with 255 additions and 135 deletions
|
@ -572,6 +572,10 @@ String _OS::keyboard_get_layout_name(int p_index) const {
|
||||||
return OS::get_singleton()->keyboard_get_layout_name(p_index);
|
return OS::get_singleton()->keyboard_get_layout_name(p_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t _OS::keyboard_get_scancode_from_physical(uint32_t p_scancode) const {
|
||||||
|
return OS::get_singleton()->keyboard_get_scancode_from_physical(p_scancode);
|
||||||
|
}
|
||||||
|
|
||||||
String _OS::get_model_name() const {
|
String _OS::get_model_name() const {
|
||||||
return OS::get_singleton()->get_model_name();
|
return OS::get_singleton()->get_model_name();
|
||||||
}
|
}
|
||||||
|
@ -1354,6 +1358,7 @@ void _OS::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("keyboard_set_current_layout", "index"), &_OS::keyboard_set_current_layout);
|
ClassDB::bind_method(D_METHOD("keyboard_set_current_layout", "index"), &_OS::keyboard_set_current_layout);
|
||||||
ClassDB::bind_method(D_METHOD("keyboard_get_layout_language", "index"), &_OS::keyboard_get_layout_language);
|
ClassDB::bind_method(D_METHOD("keyboard_get_layout_language", "index"), &_OS::keyboard_get_layout_language);
|
||||||
ClassDB::bind_method(D_METHOD("keyboard_get_layout_name", "index"), &_OS::keyboard_get_layout_name);
|
ClassDB::bind_method(D_METHOD("keyboard_get_layout_name", "index"), &_OS::keyboard_get_layout_name);
|
||||||
|
ClassDB::bind_method(D_METHOD("keyboard_get_scancode_from_physical", "scancode"), &_OS::keyboard_get_scancode_from_physical);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("can_draw"), &_OS::can_draw);
|
ClassDB::bind_method(D_METHOD("can_draw"), &_OS::can_draw);
|
||||||
ClassDB::bind_method(D_METHOD("is_userfs_persistent"), &_OS::is_userfs_persistent);
|
ClassDB::bind_method(D_METHOD("is_userfs_persistent"), &_OS::is_userfs_persistent);
|
||||||
|
|
|
@ -263,6 +263,7 @@ public:
|
||||||
void keyboard_set_current_layout(int p_index);
|
void keyboard_set_current_layout(int p_index);
|
||||||
String keyboard_get_layout_language(int p_index) const;
|
String keyboard_get_layout_language(int p_index) const;
|
||||||
String keyboard_get_layout_name(int p_index) const;
|
String keyboard_get_layout_name(int p_index) const;
|
||||||
|
uint32_t keyboard_get_scancode_from_physical(uint32_t p_scancode) const;
|
||||||
|
|
||||||
String get_model_name() const;
|
String get_model_name() const;
|
||||||
|
|
||||||
|
|
|
@ -215,6 +215,10 @@ int OS::get_virtual_keyboard_height() const {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t OS::keyboard_get_scancode_from_physical(uint32_t p_scancode) const {
|
||||||
|
return p_scancode;
|
||||||
|
}
|
||||||
|
|
||||||
void OS::set_cursor_shape(CursorShape p_shape) {
|
void OS::set_cursor_shape(CursorShape p_shape) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -411,6 +411,7 @@ public:
|
||||||
|
|
||||||
// returns height of the currently shown virtual keyboard (0 if keyboard is hidden)
|
// returns height of the currently shown virtual keyboard (0 if keyboard is hidden)
|
||||||
virtual int get_virtual_keyboard_height() const;
|
virtual int get_virtual_keyboard_height() const;
|
||||||
|
virtual uint32_t keyboard_get_scancode_from_physical(uint32_t p_scancode) const;
|
||||||
|
|
||||||
virtual void set_cursor_shape(CursorShape p_shape);
|
virtual void set_cursor_shape(CursorShape p_shape);
|
||||||
virtual CursorShape get_cursor_shape() const;
|
virtual CursorShape get_cursor_shape() const;
|
||||||
|
|
|
@ -709,6 +709,14 @@
|
||||||
[b]Note:[/b] This method is implemented on Linux, macOS and Windows.
|
[b]Note:[/b] This method is implemented on Linux, macOS and Windows.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="keyboard_get_scancode_from_physical" qualifiers="const">
|
||||||
|
<return type="int" />
|
||||||
|
<argument index="0" name="scancode" type="int" />
|
||||||
|
<description>
|
||||||
|
Converts a physical (US QWERTY) [code]scancode[/code] to one in the active keyboard layout.
|
||||||
|
[b]Note:[/b] This method is implemented on Linux, macOS and Windows.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="keyboard_set_current_layout">
|
<method name="keyboard_set_current_layout">
|
||||||
<return type="void" />
|
<return type="void" />
|
||||||
<argument index="0" name="index" type="int" />
|
<argument index="0" name="index" type="int" />
|
||||||
|
|
|
@ -263,6 +263,7 @@ public:
|
||||||
virtual void keyboard_set_current_layout(int p_index);
|
virtual void keyboard_set_current_layout(int p_index);
|
||||||
virtual String keyboard_get_layout_language(int p_index) const;
|
virtual String keyboard_get_layout_language(int p_index) const;
|
||||||
virtual String keyboard_get_layout_name(int p_index) const;
|
virtual String keyboard_get_layout_name(int p_index) const;
|
||||||
|
virtual uint32_t keyboard_get_scancode_from_physical(uint32_t p_scancode) const;
|
||||||
|
|
||||||
virtual void move_window_to_foreground();
|
virtual void move_window_to_foreground();
|
||||||
|
|
||||||
|
|
|
@ -932,145 +932,154 @@ static bool isNumpadKey(unsigned int key) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Translates a OS X keycode to a Godot keycode
|
// Keyboard symbol translation table
|
||||||
//
|
static const unsigned int _osx_to_godot_table[128] = {
|
||||||
static int translateKey(unsigned int key) {
|
/* 00 */ KEY_A,
|
||||||
// Keyboard symbol translation table
|
/* 01 */ KEY_S,
|
||||||
static const unsigned int table[128] = {
|
/* 02 */ KEY_D,
|
||||||
/* 00 */ KEY_A,
|
/* 03 */ KEY_F,
|
||||||
/* 01 */ KEY_S,
|
/* 04 */ KEY_H,
|
||||||
/* 02 */ KEY_D,
|
/* 05 */ KEY_G,
|
||||||
/* 03 */ KEY_F,
|
/* 06 */ KEY_Z,
|
||||||
/* 04 */ KEY_H,
|
/* 07 */ KEY_X,
|
||||||
/* 05 */ KEY_G,
|
/* 08 */ KEY_C,
|
||||||
/* 06 */ KEY_Z,
|
/* 09 */ KEY_V,
|
||||||
/* 07 */ KEY_X,
|
/* 0a */ KEY_SECTION, /* ISO Section */
|
||||||
/* 08 */ KEY_C,
|
/* 0b */ KEY_B,
|
||||||
/* 09 */ KEY_V,
|
/* 0c */ KEY_Q,
|
||||||
/* 0a */ KEY_SECTION, /* ISO Section */
|
/* 0d */ KEY_W,
|
||||||
/* 0b */ KEY_B,
|
/* 0e */ KEY_E,
|
||||||
/* 0c */ KEY_Q,
|
/* 0f */ KEY_R,
|
||||||
/* 0d */ KEY_W,
|
/* 10 */ KEY_Y,
|
||||||
/* 0e */ KEY_E,
|
/* 11 */ KEY_T,
|
||||||
/* 0f */ KEY_R,
|
/* 12 */ KEY_1,
|
||||||
/* 10 */ KEY_Y,
|
/* 13 */ KEY_2,
|
||||||
/* 11 */ KEY_T,
|
/* 14 */ KEY_3,
|
||||||
/* 12 */ KEY_1,
|
/* 15 */ KEY_4,
|
||||||
/* 13 */ KEY_2,
|
/* 16 */ KEY_6,
|
||||||
/* 14 */ KEY_3,
|
/* 17 */ KEY_5,
|
||||||
/* 15 */ KEY_4,
|
/* 18 */ KEY_EQUAL,
|
||||||
/* 16 */ KEY_6,
|
/* 19 */ KEY_9,
|
||||||
/* 17 */ KEY_5,
|
/* 1a */ KEY_7,
|
||||||
/* 18 */ KEY_EQUAL,
|
/* 1b */ KEY_MINUS,
|
||||||
/* 19 */ KEY_9,
|
/* 1c */ KEY_8,
|
||||||
/* 1a */ KEY_7,
|
/* 1d */ KEY_0,
|
||||||
/* 1b */ KEY_MINUS,
|
/* 1e */ KEY_BRACERIGHT,
|
||||||
/* 1c */ KEY_8,
|
/* 1f */ KEY_O,
|
||||||
/* 1d */ KEY_0,
|
/* 20 */ KEY_U,
|
||||||
/* 1e */ KEY_BRACERIGHT,
|
/* 21 */ KEY_BRACELEFT,
|
||||||
/* 1f */ KEY_O,
|
/* 22 */ KEY_I,
|
||||||
/* 20 */ KEY_U,
|
/* 23 */ KEY_P,
|
||||||
/* 21 */ KEY_BRACELEFT,
|
/* 24 */ KEY_ENTER,
|
||||||
/* 22 */ KEY_I,
|
/* 25 */ KEY_L,
|
||||||
/* 23 */ KEY_P,
|
/* 26 */ KEY_J,
|
||||||
/* 24 */ KEY_ENTER,
|
/* 27 */ KEY_APOSTROPHE,
|
||||||
/* 25 */ KEY_L,
|
/* 28 */ KEY_K,
|
||||||
/* 26 */ KEY_J,
|
/* 29 */ KEY_SEMICOLON,
|
||||||
/* 27 */ KEY_APOSTROPHE,
|
/* 2a */ KEY_BACKSLASH,
|
||||||
/* 28 */ KEY_K,
|
/* 2b */ KEY_COMMA,
|
||||||
/* 29 */ KEY_SEMICOLON,
|
/* 2c */ KEY_SLASH,
|
||||||
/* 2a */ KEY_BACKSLASH,
|
/* 2d */ KEY_N,
|
||||||
/* 2b */ KEY_COMMA,
|
/* 2e */ KEY_M,
|
||||||
/* 2c */ KEY_SLASH,
|
/* 2f */ KEY_PERIOD,
|
||||||
/* 2d */ KEY_N,
|
/* 30 */ KEY_TAB,
|
||||||
/* 2e */ KEY_M,
|
/* 31 */ KEY_SPACE,
|
||||||
/* 2f */ KEY_PERIOD,
|
/* 32 */ KEY_QUOTELEFT,
|
||||||
/* 30 */ KEY_TAB,
|
/* 33 */ KEY_BACKSPACE,
|
||||||
/* 31 */ KEY_SPACE,
|
/* 34 */ KEY_UNKNOWN,
|
||||||
/* 32 */ KEY_QUOTELEFT,
|
/* 35 */ KEY_ESCAPE,
|
||||||
/* 33 */ KEY_BACKSPACE,
|
/* 36 */ KEY_META,
|
||||||
/* 34 */ KEY_UNKNOWN,
|
/* 37 */ KEY_META,
|
||||||
/* 35 */ KEY_ESCAPE,
|
/* 38 */ KEY_SHIFT,
|
||||||
/* 36 */ KEY_META,
|
/* 39 */ KEY_CAPSLOCK,
|
||||||
/* 37 */ KEY_META,
|
/* 3a */ KEY_ALT,
|
||||||
/* 38 */ KEY_SHIFT,
|
/* 3b */ KEY_CONTROL,
|
||||||
/* 39 */ KEY_CAPSLOCK,
|
/* 3c */ KEY_SHIFT,
|
||||||
/* 3a */ KEY_ALT,
|
/* 3d */ KEY_ALT,
|
||||||
/* 3b */ KEY_CONTROL,
|
/* 3e */ KEY_CONTROL,
|
||||||
/* 3c */ KEY_SHIFT,
|
/* 3f */ KEY_UNKNOWN, /* Function */
|
||||||
/* 3d */ KEY_ALT,
|
/* 40 */ KEY_UNKNOWN, /* F17 */
|
||||||
/* 3e */ KEY_CONTROL,
|
/* 41 */ KEY_KP_PERIOD,
|
||||||
/* 3f */ KEY_UNKNOWN, /* Function */
|
/* 42 */ KEY_UNKNOWN,
|
||||||
/* 40 */ KEY_UNKNOWN, /* F17 */
|
/* 43 */ KEY_KP_MULTIPLY,
|
||||||
/* 41 */ KEY_KP_PERIOD,
|
/* 44 */ KEY_UNKNOWN,
|
||||||
/* 42 */ KEY_UNKNOWN,
|
/* 45 */ KEY_KP_ADD,
|
||||||
/* 43 */ KEY_KP_MULTIPLY,
|
/* 46 */ KEY_UNKNOWN,
|
||||||
/* 44 */ KEY_UNKNOWN,
|
/* 47 */ KEY_NUMLOCK, /* Really KeypadClear... */
|
||||||
/* 45 */ KEY_KP_ADD,
|
/* 48 */ KEY_VOLUMEUP, /* VolumeUp */
|
||||||
/* 46 */ KEY_UNKNOWN,
|
/* 49 */ KEY_VOLUMEDOWN, /* VolumeDown */
|
||||||
/* 47 */ KEY_NUMLOCK, /* Really KeypadClear... */
|
/* 4a */ KEY_VOLUMEMUTE, /* Mute */
|
||||||
/* 48 */ KEY_VOLUMEUP, /* VolumeUp */
|
/* 4b */ KEY_KP_DIVIDE,
|
||||||
/* 49 */ KEY_VOLUMEDOWN, /* VolumeDown */
|
/* 4c */ KEY_KP_ENTER,
|
||||||
/* 4a */ KEY_VOLUMEMUTE, /* Mute */
|
/* 4d */ KEY_UNKNOWN,
|
||||||
/* 4b */ KEY_KP_DIVIDE,
|
/* 4e */ KEY_KP_SUBTRACT,
|
||||||
/* 4c */ KEY_KP_ENTER,
|
/* 4f */ KEY_UNKNOWN, /* F18 */
|
||||||
/* 4d */ KEY_UNKNOWN,
|
/* 50 */ KEY_UNKNOWN, /* F19 */
|
||||||
/* 4e */ KEY_KP_SUBTRACT,
|
/* 51 */ KEY_EQUAL, /* KeypadEqual */
|
||||||
/* 4f */ KEY_UNKNOWN, /* F18 */
|
/* 52 */ KEY_KP_0,
|
||||||
/* 50 */ KEY_UNKNOWN, /* F19 */
|
/* 53 */ KEY_KP_1,
|
||||||
/* 51 */ KEY_EQUAL, /* KeypadEqual */
|
/* 54 */ KEY_KP_2,
|
||||||
/* 52 */ KEY_KP_0,
|
/* 55 */ KEY_KP_3,
|
||||||
/* 53 */ KEY_KP_1,
|
/* 56 */ KEY_KP_4,
|
||||||
/* 54 */ KEY_KP_2,
|
/* 57 */ KEY_KP_5,
|
||||||
/* 55 */ KEY_KP_3,
|
/* 58 */ KEY_KP_6,
|
||||||
/* 56 */ KEY_KP_4,
|
/* 59 */ KEY_KP_7,
|
||||||
/* 57 */ KEY_KP_5,
|
/* 5a */ KEY_UNKNOWN, /* F20 */
|
||||||
/* 58 */ KEY_KP_6,
|
/* 5b */ KEY_KP_8,
|
||||||
/* 59 */ KEY_KP_7,
|
/* 5c */ KEY_KP_9,
|
||||||
/* 5a */ KEY_UNKNOWN, /* F20 */
|
/* 5d */ KEY_YEN, /* JIS Yen */
|
||||||
/* 5b */ KEY_KP_8,
|
/* 5e */ KEY_UNDERSCORE, /* JIS Underscore */
|
||||||
/* 5c */ KEY_KP_9,
|
/* 5f */ KEY_COMMA, /* JIS KeypadComma */
|
||||||
/* 5d */ KEY_YEN, /* JIS Yen */
|
/* 60 */ KEY_F5,
|
||||||
/* 5e */ KEY_UNDERSCORE, /* JIS Underscore */
|
/* 61 */ KEY_F6,
|
||||||
/* 5f */ KEY_COMMA, /* JIS KeypadComma */
|
/* 62 */ KEY_F7,
|
||||||
/* 60 */ KEY_F5,
|
/* 63 */ KEY_F3,
|
||||||
/* 61 */ KEY_F6,
|
/* 64 */ KEY_F8,
|
||||||
/* 62 */ KEY_F7,
|
/* 65 */ KEY_F9,
|
||||||
/* 63 */ KEY_F3,
|
/* 66 */ KEY_UNKNOWN, /* JIS Eisu */
|
||||||
/* 64 */ KEY_F8,
|
/* 67 */ KEY_F11,
|
||||||
/* 65 */ KEY_F9,
|
/* 68 */ KEY_UNKNOWN, /* JIS Kana */
|
||||||
/* 66 */ KEY_UNKNOWN, /* JIS Eisu */
|
/* 69 */ KEY_F13,
|
||||||
/* 67 */ KEY_F11,
|
/* 6a */ KEY_F16,
|
||||||
/* 68 */ KEY_UNKNOWN, /* JIS Kana */
|
/* 6b */ KEY_F14,
|
||||||
/* 69 */ KEY_F13,
|
/* 6c */ KEY_UNKNOWN,
|
||||||
/* 6a */ KEY_F16,
|
/* 6d */ KEY_F10,
|
||||||
/* 6b */ KEY_F14,
|
/* 6e */ KEY_MENU,
|
||||||
/* 6c */ KEY_UNKNOWN,
|
/* 6f */ KEY_F12,
|
||||||
/* 6d */ KEY_F10,
|
/* 70 */ KEY_UNKNOWN,
|
||||||
/* 6e */ KEY_MENU,
|
/* 71 */ KEY_F15,
|
||||||
/* 6f */ KEY_F12,
|
/* 72 */ KEY_INSERT, /* Really Help... */
|
||||||
/* 70 */ KEY_UNKNOWN,
|
/* 73 */ KEY_HOME,
|
||||||
/* 71 */ KEY_F15,
|
/* 74 */ KEY_PAGEUP,
|
||||||
/* 72 */ KEY_INSERT, /* Really Help... */
|
/* 75 */ KEY_DELETE,
|
||||||
/* 73 */ KEY_HOME,
|
/* 76 */ KEY_F4,
|
||||||
/* 74 */ KEY_PAGEUP,
|
/* 77 */ KEY_END,
|
||||||
/* 75 */ KEY_DELETE,
|
/* 78 */ KEY_F2,
|
||||||
/* 76 */ KEY_F4,
|
/* 79 */ KEY_PAGEDOWN,
|
||||||
/* 77 */ KEY_END,
|
/* 7a */ KEY_F1,
|
||||||
/* 78 */ KEY_F2,
|
/* 7b */ KEY_LEFT,
|
||||||
/* 79 */ KEY_PAGEDOWN,
|
/* 7c */ KEY_RIGHT,
|
||||||
/* 7a */ KEY_F1,
|
/* 7d */ KEY_DOWN,
|
||||||
/* 7b */ KEY_LEFT,
|
/* 7e */ KEY_UP,
|
||||||
/* 7c */ KEY_RIGHT,
|
/* 7f */ KEY_UNKNOWN,
|
||||||
/* 7d */ KEY_DOWN,
|
};
|
||||||
/* 7e */ KEY_UP,
|
|
||||||
/* 7f */ KEY_UNKNOWN,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
// Translates a OS X keycode to a Godot keycode
|
||||||
|
static int translateKey(unsigned int key) {
|
||||||
if (key >= 128)
|
if (key >= 128)
|
||||||
return KEY_UNKNOWN;
|
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(int key) {
|
||||||
|
for (int i = 0; i <= 126; i++) {
|
||||||
|
if (_osx_to_godot_table[i] == key) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 127;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct _KeyCodeMap {
|
struct _KeyCodeMap {
|
||||||
|
@ -3207,6 +3216,17 @@ String OS_OSX::keyboard_get_layout_name(int p_index) const {
|
||||||
return kbd_layouts[p_index].name;
|
return kbd_layouts[p_index].name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t OS_OSX::keyboard_get_scancode_from_physical(uint32_t p_scancode) const {
|
||||||
|
if (p_scancode == KEY_PAUSE) {
|
||||||
|
return p_scancode;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int modifiers = p_scancode & KEY_MODIFIER_MASK;
|
||||||
|
unsigned int scancode_no_mod = p_scancode & KEY_CODE_MASK;
|
||||||
|
unsigned int osx_scancode = unmapKey((uint32_t)scancode_no_mod);
|
||||||
|
return (uint32_t)(remapKey(osx_scancode, 0) | modifiers);
|
||||||
|
}
|
||||||
|
|
||||||
void OS_OSX::process_events() {
|
void OS_OSX::process_events() {
|
||||||
while (true) {
|
while (true) {
|
||||||
NSEvent *event = [NSApp
|
NSEvent *event = [NSApp
|
||||||
|
|
|
@ -347,6 +347,16 @@ unsigned int KeyMappingWindows::get_keysym(unsigned int p_code) {
|
||||||
return KEY_UNKNOWN;
|
return KEY_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int KeyMappingWindows::get_scancode(unsigned int 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 KeyMappingWindows::get_scansym(unsigned int p_code, bool p_extended) {
|
||||||
unsigned int keycode = KEY_UNKNOWN;
|
unsigned int keycode = KEY_UNKNOWN;
|
||||||
for (int i = 0; _scancode_to_keycode[i].keysym != KEY_UNKNOWN; i++) {
|
for (int i = 0; _scancode_to_keycode[i].keysym != KEY_UNKNOWN; i++) {
|
||||||
|
|
|
@ -42,6 +42,7 @@ class KeyMappingWindows {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static unsigned int get_keysym(unsigned int p_code);
|
static unsigned int get_keysym(unsigned int p_code);
|
||||||
|
static unsigned int get_scancode(unsigned int p_keycode);
|
||||||
static unsigned int get_scansym(unsigned int p_code, bool p_extended);
|
static unsigned int get_scansym(unsigned int p_code, bool p_extended);
|
||||||
static bool is_extended_key(unsigned int p_code);
|
static bool is_extended_key(unsigned int p_code);
|
||||||
};
|
};
|
||||||
|
|
|
@ -3307,6 +3307,42 @@ String OS_Windows::keyboard_get_layout_language(int p_index) const {
|
||||||
return String(buf).substr(0, 2);
|
return String(buf).substr(0, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t OS_Windows::keyboard_get_scancode_from_physical(uint32_t p_scancode) const {
|
||||||
|
unsigned int modifiers = p_scancode & KEY_MODIFIER_MASK;
|
||||||
|
uint32_t scancode_no_mod = (uint32_t)(p_scancode & KEY_CODE_MASK);
|
||||||
|
|
||||||
|
if (scancode_no_mod == KEY_PRINT ||
|
||||||
|
scancode_no_mod == KEY_KP_ADD ||
|
||||||
|
scancode_no_mod == KEY_KP_5 ||
|
||||||
|
(scancode_no_mod >= KEY_0 && scancode_no_mod <= KEY_9)) {
|
||||||
|
return p_scancode;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int scancode = KeyMappingWindows::get_scancode(scancode_no_mod);
|
||||||
|
if (scancode == 0) {
|
||||||
|
return p_scancode;
|
||||||
|
}
|
||||||
|
|
||||||
|
HKL current_layout = GetKeyboardLayout(0);
|
||||||
|
UINT vk = MapVirtualKeyEx(scancode, MAPVK_VSC_TO_VK, current_layout);
|
||||||
|
if (vk == 0) {
|
||||||
|
return p_scancode;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 (uint32_t)(char_code | modifiers);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (uint32_t)(KeyMappingWindows::get_keysym(vk) | modifiers);
|
||||||
|
}
|
||||||
|
|
||||||
String _get_full_layout_name_from_registry(HKL p_layout) {
|
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 id = "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\" + String::num_int64((int64_t)p_layout, 16, false).lpad(8, "0");
|
||||||
String ret;
|
String ret;
|
||||||
|
|
|
@ -532,6 +532,7 @@ public:
|
||||||
virtual void keyboard_set_current_layout(int p_index);
|
virtual void keyboard_set_current_layout(int p_index);
|
||||||
virtual String keyboard_get_layout_language(int p_index) const;
|
virtual String keyboard_get_layout_language(int p_index) const;
|
||||||
virtual String keyboard_get_layout_name(int p_index) const;
|
virtual String keyboard_get_layout_name(int p_index) const;
|
||||||
|
virtual uint32_t keyboard_get_scancode_from_physical(uint32_t p_scancode) const;
|
||||||
|
|
||||||
virtual void enable_for_stealing_focus(ProcessID pid);
|
virtual void enable_for_stealing_focus(ProcessID pid);
|
||||||
virtual void move_window_to_foreground();
|
virtual void move_window_to_foreground();
|
||||||
|
|
|
@ -310,6 +310,18 @@ unsigned int KeyMappingX11::get_scancode(unsigned int p_code) {
|
||||||
return keycode;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int KeyMappingX11::get_keycode(KeySym p_keysym) {
|
unsigned int KeyMappingX11::get_keycode(KeySym p_keysym) {
|
||||||
// kinda bruteforce.. could optimize.
|
// kinda bruteforce.. could optimize.
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,7 @@ class KeyMappingX11 {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static unsigned int get_keycode(KeySym p_keysym);
|
static unsigned int get_keycode(KeySym p_keysym);
|
||||||
|
static unsigned int get_xlibcode(unsigned int p_keysym);
|
||||||
static unsigned int get_scancode(unsigned int p_code);
|
static unsigned int get_scancode(unsigned int p_code);
|
||||||
static KeySym get_keysym(unsigned int p_code);
|
static KeySym get_keysym(unsigned int p_code);
|
||||||
static unsigned int get_unicode_from_keysym(KeySym p_keysym);
|
static unsigned int get_unicode_from_keysym(KeySym p_keysym);
|
||||||
|
|
|
@ -4100,6 +4100,24 @@ String OS_X11::keyboard_get_layout_name(int p_index) const {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t OS_X11::keyboard_get_scancode_from_physical(uint32_t p_scancode) const {
|
||||||
|
unsigned int modifiers = p_scancode & KEY_MODIFIER_MASK;
|
||||||
|
unsigned int scancode_no_mod = p_scancode & KEY_CODE_MASK;
|
||||||
|
unsigned int xkeycode = KeyMappingX11::get_xlibcode((uint32_t)scancode_no_mod);
|
||||||
|
KeySym xkeysym = XkbKeycodeToKeysym(x11_display, xkeycode, 0, 0);
|
||||||
|
if (xkeysym >= 'a' && xkeysym <= 'z') {
|
||||||
|
xkeysym -= ('a' - 'A');
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t key = KeyMappingX11::get_keycode(xkeysym);
|
||||||
|
// If not found, fallback to QWERTY.
|
||||||
|
// This should match the behavior of the event pump
|
||||||
|
if (key == 0) {
|
||||||
|
return p_scancode;
|
||||||
|
}
|
||||||
|
return (uint32_t)(key | modifiers);
|
||||||
|
}
|
||||||
|
|
||||||
void OS_X11::update_real_mouse_position() {
|
void OS_X11::update_real_mouse_position() {
|
||||||
Window root_return, child_return;
|
Window root_return, child_return;
|
||||||
int root_x, root_y, win_x, win_y;
|
int root_x, root_y, win_x, win_y;
|
||||||
|
|
|
@ -361,6 +361,7 @@ public:
|
||||||
virtual void keyboard_set_current_layout(int p_index);
|
virtual void keyboard_set_current_layout(int p_index);
|
||||||
virtual String keyboard_get_layout_language(int p_index) const;
|
virtual String keyboard_get_layout_language(int p_index) const;
|
||||||
virtual String keyboard_get_layout_name(int p_index) const;
|
virtual String keyboard_get_layout_name(int p_index) const;
|
||||||
|
virtual uint32_t keyboard_get_scancode_from_physical(uint32_t p_scancode) const;
|
||||||
|
|
||||||
void update_real_mouse_position();
|
void update_real_mouse_position();
|
||||||
OS_X11();
|
OS_X11();
|
||||||
|
|
Loading…
Reference in a new issue