diff options
author | RĂ©mi Verschelde <rverschelde@gmail.com> | 2020-03-01 23:00:42 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-01 23:00:42 +0100 |
commit | e2b66cacf78ae39b94df748e9740b98a1f011e77 (patch) | |
tree | 56d468d762c43879c20b342702e8fc999221e6c6 /platform | |
parent | 55396d6e06f8e4e355e9ab0595bdb7f27c1c36dd (diff) | |
parent | 1af06d3d4608b17c74caed951cd9579ccbba229d (diff) |
Merge pull request #18020 from bruvzg/input_fix_non_latin_and_add_hw_scancodes
Fix non-latin layout scancodes on Linux, adds access to physical scancodes.
Diffstat (limited to 'platform')
21 files changed, 402 insertions, 64 deletions
diff --git a/platform/android/java/lib/src/org/godotengine/godot/Godot.java b/platform/android/java/lib/src/org/godotengine/godot/Godot.java index 021214b627..ac1032dab6 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java +++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java @@ -990,8 +990,8 @@ public abstract class Godot extends Activity implements SensorEventListener, IDo int keyCode; if ((keyCode = cc[i]) != 0) { // Simulate key down and up... - GodotLib.key(0, keyCode, true); - GodotLib.key(0, keyCode, false); + GodotLib.key(0, 0, keyCode, true); + GodotLib.key(0, 0, keyCode, false); } } } diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java index e0b46673ba..9ee29d439c 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java @@ -136,7 +136,7 @@ public class GodotLib { /** * Forward regular key events from the main thread to the GL thread. */ - public static native void key(int p_scancode, int p_unicode_char, boolean p_pressed); + public static native void key(int p_keycode, int p_scancode, int p_unicode_char, boolean p_pressed); /** * Forward game device's key events from the main thread to the GL thread. diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java index b2b88088e8..e00ca86c41 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java @@ -98,11 +98,12 @@ public class GodotInputHandler implements InputDeviceListener { }); } } else { + final int scanCode = event.getScanCode(); final int chr = event.getUnicodeChar(0); queueEvent(new Runnable() { @Override public void run() { - GodotLib.key(keyCode, chr, false); + GodotLib.key(keyCode, scanCode, chr, false); } }); }; @@ -143,11 +144,12 @@ public class GodotInputHandler implements InputDeviceListener { }); } } else { + final int scanCode = event.getScanCode(); final int chr = event.getUnicodeChar(0); queueEvent(new Runnable() { @Override public void run() { - GodotLib.key(keyCode, chr, true); + GodotLib.key(keyCode, scanCode, chr, true); } }); }; diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java index 3a154f1bf3..8d9b5461a1 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java @@ -91,8 +91,8 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene @Override public void run() { for (int i = 0; i < count; ++i) { - GodotLib.key(KeyEvent.KEYCODE_DEL, 0, true); - GodotLib.key(KeyEvent.KEYCODE_DEL, 0, false); + GodotLib.key(KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL, 0, true); + GodotLib.key(KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL, 0, false); } } }); @@ -110,8 +110,8 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene @Override public void run() { for (int i = 0; i < count; ++i) { - GodotLib.key(0, newChars[i], true); - GodotLib.key(0, newChars[i], false); + GodotLib.key(0, 0, newChars[i], true); + GodotLib.key(0, 0, newChars[i], false); } } }); @@ -127,8 +127,8 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene public void run() { for (int i = 0; i < characters.length(); i++) { final int ch = characters.codePointAt(i); - GodotLib.key(0, ch, true); - GodotLib.key(0, ch, false); + GodotLib.key(0, 0, ch, true); + GodotLib.key(0, 0, ch, false); } } }); diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp index 900a452024..022d9700d5 100644 --- a/platform/android/java_godot_lib_jni.cpp +++ b/platform/android/java_godot_lib_jni.cpp @@ -1167,28 +1167,29 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyconnectionchanged( } } -JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jobject obj, jint p_scancode, jint p_unicode_char, jboolean p_pressed) { +JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jobject obj, jint p_keycode, jint p_scancode, jint p_unicode_char, jboolean p_pressed) { if (step == 0) return; Ref<InputEventKey> ievent; ievent.instance(); int val = p_unicode_char; - int scancode = android_get_keysym(p_scancode); - ievent->set_scancode(scancode); + int keycode = android_get_keysym(p_keycode); + int phy_keycode = android_get_keysym(p_scancode); + ievent->set_keycode(keycode); + ievent->set_physical_keycode(phy_keycode); ievent->set_unicode(val); ievent->set_pressed(p_pressed); if (val == '\n') { - ievent->set_scancode(KEY_ENTER); + ievent->set_keycode(KEY_ENTER); } else if (val == 61448) { - ievent->set_scancode(KEY_BACKSPACE); + ievent->set_keycode(KEY_BACKSPACE); ievent->set_unicode(KEY_BACKSPACE); } else if (val == 61453) { - ievent->set_scancode(KEY_ENTER); + ievent->set_keycode(KEY_ENTER); ievent->set_unicode(KEY_ENTER); - } else if (p_scancode == 4) { - + } else if (p_keycode == 4) { os_android->main_loop_request_go_back(); } diff --git a/platform/android/java_godot_lib_jni.h b/platform/android/java_godot_lib_jni.h index 71d4547f65..fdd84ab1ef 100644 --- a/platform/android/java_godot_lib_jni.h +++ b/platform/android/java_godot_lib_jni.h @@ -48,7 +48,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch(JNIEnv *env, jo JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_hover(JNIEnv *env, jobject obj, jint p_type, jint p_x, jint p_y); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_doubletap(JNIEnv *env, jobject obj, jint p_x, jint p_y); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_scroll(JNIEnv *env, jobject obj, jint p_x, jint p_y); -JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jobject obj, jint p_scancode, jint p_unicode_char, jboolean p_pressed); +JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jobject obj, jint p_keycode, jint p_scancode, jint p_unicode_char, jboolean p_pressed); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv *env, jobject obj, jint p_device, jint p_button, jboolean p_pressed); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyaxis(JNIEnv *env, jobject obj, jint p_device, jint p_axis, jfloat p_value); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyhat(JNIEnv *env, jobject obj, jint p_device, jint p_hat_x, jint p_hat_y); diff --git a/platform/haiku/haiku_direct_window.cpp b/platform/haiku/haiku_direct_window.cpp index 3c2b7f8d10..2d7efe6b61 100644 --- a/platform/haiku/haiku_direct_window.cpp +++ b/platform/haiku/haiku_direct_window.cpp @@ -273,7 +273,8 @@ void HaikuDirectWindow::HandleKeyboardEvent(BMessage *message) { event.instance(); GetKeyModifierState(event, modifiers); event->set_pressed(message->what == B_KEY_DOWN); - event->set_scancode(KeyMappingHaiku::get_keysym(raw_char, key)); + event->set_keycode(KeyMappingHaiku::get_keysym(raw_char, key)); + event->set_physical_keycode(KeyMappingHaiku::get_keysym(raw_char, key)); event->set_echo(message->HasInt32("be:key_repeat")); event->set_unicode(0); @@ -283,8 +284,9 @@ void HaikuDirectWindow::HandleKeyboardEvent(BMessage *message) { } //make it consistent across platforms. - if (event->get_scancode() == KEY_BACKTAB) { - event->set_scancode(KEY_TAB); + if (event->get_keycode() == KEY_BACKTAB) { + event->set_keycode(KEY_TAB); + event->set_physical_keycode(KEY_TAB); event->set_shift(true); } diff --git a/platform/iphone/os_iphone.cpp b/platform/iphone/os_iphone.cpp index db203ff2b3..8a50f5a28b 100644 --- a/platform/iphone/os_iphone.cpp +++ b/platform/iphone/os_iphone.cpp @@ -135,7 +135,6 @@ Error OSIPhone::initialize(const VideoMode &p_desired, int p_video_driver, int p RasterizerRD::make_current(); #endif - visual_server = memnew(VisualServerRaster); // FIXME: Reimplement threaded rendering if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) { @@ -212,7 +211,8 @@ void OSIPhone::key(uint32_t p_key, bool p_pressed) { ev.instance(); ev->set_echo(false); ev->set_pressed(p_pressed); - ev->set_scancode(p_key); + ev->set_keycode(p_key); + ev->set_physical_keycode(p_key); ev->set_unicode(p_key); queue_event(ev); }; diff --git a/platform/javascript/dom_keys.inc b/platform/javascript/dom_keys.inc index 25e88f99d1..fd9df765d2 100644 --- a/platform/javascript/dom_keys.inc +++ b/platform/javascript/dom_keys.inc @@ -218,7 +218,7 @@ #define DOM_VK_PA1 0xFD #define DOM_VK_WIN_OEM_CLEAR 0xFE -int dom2godot_scancode(int dom_keycode) { +int dom2godot_keycode(int dom_keycode) { if (DOM_VK_0 <= dom_keycode && dom_keycode <= DOM_VK_Z) { // ASCII intersection diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp index 5acdc5f602..299c469bf4 100644 --- a/platform/javascript/os_javascript.cpp +++ b/platform/javascript/os_javascript.cpp @@ -250,7 +250,8 @@ static Ref<InputEventKey> setup_key_event(const EmscriptenKeyboardEvent *emscrip ev.instance(); ev->set_echo(emscripten_event->repeat); dom2godot_mod(emscripten_event, ev); - ev->set_scancode(dom2godot_scancode(emscripten_event->keyCode)); + ev->set_keycode(dom2godot_keycode(emscripten_event->keyCode)); + ev->set_physical_keycode(dom2godot_keycode(emscripten_event->keyCode)); String unicode = String::utf8(emscripten_event->key); // Check if empty or multi-character (e.g. `CapsLock`). @@ -270,7 +271,7 @@ EM_BOOL OS_JavaScript::keydown_callback(int p_event_type, const EmscriptenKeyboa OS_JavaScript *os = get_singleton(); Ref<InputEventKey> ev = setup_key_event(p_event); ev->set_pressed(true); - if (ev->get_unicode() == 0 && keycode_has_unicode(ev->get_scancode())) { + if (ev->get_unicode() == 0 && keycode_has_unicode(ev->get_keycode())) { // Defer to keypress event for legacy unicode retrieval. os->deferred_key_event = ev; // Do not suppress keypress event. @@ -295,7 +296,7 @@ EM_BOOL OS_JavaScript::keyup_callback(int p_event_type, const EmscriptenKeyboard Ref<InputEventKey> ev = setup_key_event(p_event); ev->set_pressed(false); get_singleton()->input->parse_input_event(ev); - return ev->get_scancode() != KEY_UNKNOWN && ev->get_scancode() != 0; + return ev->get_keycode() != KEY_UNKNOWN && ev->get_keycode() != 0; } // Mouse diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h index 75a56bd82c..3140d9bac4 100644 --- a/platform/osx/os_osx.h +++ b/platform/osx/os_osx.h @@ -69,7 +69,8 @@ public: bool pressed; bool echo; bool raw; - uint32_t scancode; + uint32_t keycode; + uint32_t physical_keycode; uint32_t unicode; }; diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index f2e5f9369c..952360c6aa 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -157,7 +157,8 @@ static NSCursor *cursorFromSelector(SEL selector, SEL fallback = nil) { get_key_modifier_state([event modifierFlags], k); k->set_pressed(true); - k->set_scancode(KEY_PERIOD); + k->set_keycode(KEY_PERIOD); + k->set_physical_keycode(KEY_PERIOD); k->set_echo([event isARepeat]); OS_OSX::singleton->push_input(k); @@ -635,7 +636,8 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; ke.pressed = true; ke.echo = false; ke.raw = false; // IME input event - ke.scancode = 0; + ke.keycode = 0; + ke.physical_keycode = 0; ke.unicode = codepoint; push_to_key_event_buffer(ke); @@ -1158,7 +1160,8 @@ static int remapKey(unsigned int key, unsigned int state) { ke.osx_state = [event modifierFlags]; ke.pressed = true; ke.echo = [event isARepeat]; - ke.scancode = remapKey([event keyCode], [event modifierFlags]); + ke.keycode = remapKey([event keyCode], [event modifierFlags]); + ke.physical_keycode = translateKey([event keyCode]); ke.raw = true; ke.unicode = [characters characterAtIndex:i]; @@ -1170,7 +1173,8 @@ static int remapKey(unsigned int key, unsigned int state) { ke.osx_state = [event modifierFlags]; ke.pressed = true; ke.echo = [event isARepeat]; - ke.scancode = remapKey([event keyCode], [event modifierFlags]); + ke.keycode = remapKey([event keyCode], [event modifierFlags]); + ke.physical_keycode = translateKey([event keyCode]); ke.raw = false; ke.unicode = 0; @@ -1228,7 +1232,8 @@ static int remapKey(unsigned int key, unsigned int state) { } ke.osx_state = mod; - ke.scancode = remapKey(key, mod); + ke.keycode = remapKey(key, mod); + ke.physical_keycode = translateKey(key); ke.unicode = 0; push_to_key_event_buffer(ke); @@ -1250,7 +1255,8 @@ static int remapKey(unsigned int key, unsigned int state) { ke.osx_state = [event modifierFlags]; ke.pressed = false; ke.echo = [event isARepeat]; - ke.scancode = remapKey([event keyCode], [event modifierFlags]); + ke.keycode = remapKey([event keyCode], [event modifierFlags]); + ke.physical_keycode = translateKey([event keyCode]); ke.raw = true; ke.unicode = [characters characterAtIndex:i]; @@ -1262,7 +1268,8 @@ static int remapKey(unsigned int key, unsigned int state) { ke.osx_state = [event modifierFlags]; ke.pressed = false; ke.echo = [event isARepeat]; - ke.scancode = remapKey([event keyCode], [event modifierFlags]); + ke.keycode = remapKey([event keyCode], [event modifierFlags]); + ke.physical_keycode = translateKey([event keyCode]); ke.raw = true; ke.unicode = 0; @@ -2845,32 +2852,35 @@ void OS_OSX::process_key_events() { get_key_modifier_state(ke.osx_state, k); k->set_pressed(ke.pressed); k->set_echo(ke.echo); - k->set_scancode(ke.scancode); + k->set_keycode(ke.keycode); + k->set_physical_keycode(ke.physical_keycode); k->set_unicode(ke.unicode); push_input(k); } else { // IME input - if ((i == 0 && ke.scancode == 0) || (i > 0 && key_event_buffer[i - 1].scancode == 0)) { + if ((i == 0 && ke.keycode == 0) || (i > 0 && key_event_buffer[i - 1].keycode == 0)) { k.instance(); get_key_modifier_state(ke.osx_state, k); k->set_pressed(ke.pressed); k->set_echo(ke.echo); - k->set_scancode(0); + k->set_keycode(0); + k->set_physical_keycode(0); k->set_unicode(ke.unicode); push_input(k); } - if (ke.scancode != 0) { + if (ke.keycode != 0) { k.instance(); get_key_modifier_state(ke.osx_state, k); k->set_pressed(ke.pressed); k->set_echo(ke.echo); - k->set_scancode(ke.scancode); + k->set_keycode(ke.keycode); + k->set_physical_keycode(ke.physical_keycode); - if (i + 1 < key_event_pos && key_event_buffer[i + 1].scancode == 0) { + if (i + 1 < key_event_pos && key_event_buffer[i + 1].keycode == 0) { k->set_unicode(key_event_buffer[i + 1].unicode); } diff --git a/platform/uwp/app.cpp b/platform/uwp/app.cpp index a47fe96c1b..ccb4b43373 100644 --- a/platform/uwp/app.cpp +++ b/platform/uwp/app.cpp @@ -410,14 +410,16 @@ void App::key_event(Windows::UI::Core::CoreWindow ^ sender, bool p_pressed, Wind ke.type = OS_UWP::KeyEvent::MessageType::KEY_EVENT_MESSAGE; ke.unicode = 0; - ke.scancode = KeyMappingWindows::get_keysym((unsigned int)key_args->VirtualKey); + ke.keycode = KeyMappingWindows::get_keysym((unsigned int)key_args->VirtualKey); + ke.physical_keycode = KeyMappingWindows::get_scansym((unsigned int)key_args->KeyStatus.ScanCode); ke.echo = (!p_pressed && !key_args->KeyStatus.IsKeyReleased) || (p_pressed && key_args->KeyStatus.WasKeyDown); } else { ke.type = OS_UWP::KeyEvent::MessageType::CHAR_EVENT_MESSAGE; ke.unicode = char_args->KeyCode; - ke.scancode = 0; + ke.keycode = 0; + ke.physical_keycode = 0; ke.echo = (!p_pressed && !char_args->KeyStatus.IsKeyReleased) || (p_pressed && char_args->KeyStatus.WasKeyDown); } diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp index 1e63d50263..97c8dafe65 100644 --- a/platform/uwp/os_uwp.cpp +++ b/platform/uwp/os_uwp.cpp @@ -605,7 +605,8 @@ void OS_UWP::process_key_events() { key_event->set_shift(kev.shift); key_event->set_control(kev.control); key_event->set_echo(kev.echo); - key_event->set_scancode(kev.scancode); + key_event->set_keycode(kev.keycode); + key_event->set_physical_keycode(kev.physical_keycode); key_event->set_unicode(kev.unicode); key_event->set_pressed(kev.pressed); diff --git a/platform/uwp/os_uwp.h b/platform/uwp/os_uwp.h index 32b899c0da..ac6e0f3dd5 100644 --- a/platform/uwp/os_uwp.h +++ b/platform/uwp/os_uwp.h @@ -61,7 +61,8 @@ public: bool alt, shift, control; MessageType type; bool pressed; - unsigned int scancode; + unsigned int keycode; + unsigned int physical_keycode; unsigned int unicode; bool echo; CorePhysicalKeyStatus status; diff --git a/platform/windows/key_mapping_windows.cpp b/platform/windows/key_mapping_windows.cpp index c76b31ca9c..da63e92622 100644 --- a/platform/windows/key_mapping_windows.cpp +++ b/platform/windows/key_mapping_windows.cpp @@ -238,6 +238,104 @@ VK_PA1 (0xFD) VK_OEM_CLEAR (0xFE) */ +static _WinTranslatePair _scancode_to_keycode[] = { + + { KEY_ESCAPE, 0x01 }, + { KEY_1, 0x02 }, + { KEY_2, 0x03 }, + { KEY_3, 0x04 }, + { KEY_4, 0x05 }, + { KEY_5, 0x06 }, + { KEY_6, 0x07 }, + { KEY_7, 0x08 }, + { KEY_8, 0x09 }, + { KEY_9, 0x0A }, + { KEY_0, 0x0B }, + { KEY_MINUS, 0x0C }, + { KEY_EQUAL, 0x0D }, + { KEY_BACKSPACE, 0x0E }, + { KEY_TAB, 0x0F }, + { KEY_Q, 0x10 }, + { KEY_W, 0x11 }, + { KEY_E, 0x12 }, + { KEY_R, 0x13 }, + { KEY_T, 0x14 }, + { KEY_Y, 0x15 }, + { KEY_U, 0x16 }, + { KEY_I, 0x17 }, + { KEY_O, 0x18 }, + { KEY_P, 0x19 }, + { KEY_BRACELEFT, 0x1A }, + { KEY_BRACERIGHT, 0x1B }, + { KEY_ENTER, 0x1C }, + { KEY_CONTROL, 0x1D }, + { KEY_A, 0x1E }, + { KEY_S, 0x1F }, + { KEY_D, 0x20 }, + { KEY_F, 0x21 }, + { KEY_G, 0x22 }, + { KEY_H, 0x23 }, + { KEY_J, 0x24 }, + { KEY_K, 0x25 }, + { KEY_L, 0x26 }, + { KEY_SEMICOLON, 0x27 }, + { KEY_APOSTROPHE, 0x28 }, + { KEY_QUOTELEFT, 0x29 }, + { KEY_SHIFT, 0x2A }, + { KEY_BACKSLASH, 0x2B }, + { KEY_Z, 0x2C }, + { KEY_X, 0x2D }, + { KEY_C, 0x2E }, + { KEY_V, 0x2F }, + { KEY_B, 0x30 }, + { KEY_N, 0x31 }, + { KEY_M, 0x32 }, + { KEY_COMMA, 0x33 }, + { KEY_PERIOD, 0x34 }, + { KEY_SLASH, 0x35 }, + { KEY_SHIFT, 0x36 }, + { KEY_PRINT, 0x37 }, + { KEY_ALT, 0x38 }, + { KEY_SPACE, 0x39 }, + { KEY_CAPSLOCK, 0x3A }, + { KEY_F1, 0x3B }, + { KEY_F2, 0x3C }, + { KEY_F3, 0x3D }, + { KEY_F4, 0x3E }, + { KEY_F5, 0x3F }, + { KEY_F6, 0x40 }, + { KEY_F7, 0x41 }, + { KEY_F8, 0x42 }, + { KEY_F9, 0x43 }, + { KEY_F10, 0x44 }, + { KEY_NUMLOCK, 0x45 }, + { KEY_SCROLLLOCK, 0x46 }, + { KEY_HOME, 0x47 }, + { KEY_UP, 0x48 }, + { KEY_PAGEUP, 0x49 }, + { KEY_KP_SUBTRACT, 0x4A }, + { KEY_LEFT, 0x4B }, + { KEY_KP_5, 0x4C }, + { KEY_RIGHT, 0x4D }, + { KEY_KP_ADD, 0x4E }, + { KEY_END, 0x4F }, + { KEY_DOWN, 0x50 }, + { KEY_PAGEDOWN, 0x51 }, + { KEY_INSERT, 0x52 }, + { KEY_DELETE, 0x53 }, + //{ KEY_???, 0x56 }, //NON US BACKSLASH + { KEY_F11, 0x57 }, + { KEY_F12, 0x58 }, + { KEY_META, 0x5B }, + { KEY_META, 0x5C }, + { KEY_MENU, 0x5D }, + { KEY_F13, 0x64 }, + { KEY_F14, 0x65 }, + { KEY_F15, 0x66 }, + { KEY_F16, 0x67 }, + { KEY_UNKNOWN, 0 } +}; + unsigned int KeyMappingWindows::get_keysym(unsigned int p_code) { for (int i = 0; _vk_to_keycode[i].keysym != KEY_UNKNOWN; i++) { @@ -251,3 +349,69 @@ unsigned int KeyMappingWindows::get_keysym(unsigned int p_code) { return KEY_UNKNOWN; } + +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++) { + + if (_scancode_to_keycode[i].keycode == p_code) { + keycode = _scancode_to_keycode[i].keysym; + break; + } + } + + if (p_extended) { + switch (keycode) { + case KEY_ENTER: { + keycode = KEY_KP_ENTER; + } break; + case KEY_SLASH: { + keycode = KEY_KP_DIVIDE; + } break; + case KEY_CAPSLOCK: { + keycode = KEY_KP_ADD; + } break; + } + } else { + switch (keycode) { + case KEY_NUMLOCK: { + keycode = KEY_PAUSE; + } break; + case KEY_HOME: { + keycode = KEY_KP_7; + } break; + case KEY_UP: { + keycode = KEY_KP_8; + } break; + case KEY_PAGEUP: { + keycode = KEY_KP_9; + } break; + case KEY_LEFT: { + keycode = KEY_KP_4; + } break; + case KEY_RIGHT: { + keycode = KEY_KP_6; + } break; + case KEY_END: { + keycode = KEY_KP_1; + } break; + case KEY_DOWN: { + keycode = KEY_KP_2; + } break; + case KEY_PAGEDOWN: { + keycode = KEY_KP_3; + } break; + case KEY_INSERT: { + keycode = KEY_KP_0; + } break; + case KEY_DELETE: { + keycode = KEY_KP_PERIOD; + } break; + case KEY_PRINT: { + keycode = KEY_KP_MULTIPLY; + } break; + } + } + + return keycode; +} diff --git a/platform/windows/key_mapping_windows.h b/platform/windows/key_mapping_windows.h index 0f9bdecde1..3361ad397f 100644 --- a/platform/windows/key_mapping_windows.h +++ b/platform/windows/key_mapping_windows.h @@ -43,6 +43,7 @@ class KeyMappingWindows { public: static unsigned int get_keysym(unsigned int p_code); + static unsigned int get_scansym(unsigned int p_code, bool p_extended); }; #endif // KEY_MAPPING_WINDOWS_H diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 2b414dd5bf..7f4392c624 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -1133,7 +1133,8 @@ void OS_Windows::process_key_events() { k->set_control(ke.control); k->set_metakey(ke.meta); k->set_pressed(true); - k->set_scancode(KeyMappingWindows::get_keysym(ke.wParam)); + k->set_keycode(KeyMappingWindows::get_keysym(ke.wParam)); + k->set_physical_keycode(KeyMappingWindows::get_scansym((ke.lParam >> 16) & 0xFF, ke.lParam & (1 << 24))); k->set_unicode(ke.wParam); if (k->get_unicode() && gr_mem) { k->set_alt(false); @@ -1163,11 +1164,13 @@ void OS_Windows::process_key_events() { if ((ke.lParam & (1 << 24)) && (ke.wParam == VK_RETURN)) { // Special case for Numpad Enter key - k->set_scancode(KEY_KP_ENTER); + k->set_keycode(KEY_KP_ENTER); } else { - k->set_scancode(KeyMappingWindows::get_keysym(ke.wParam)); + k->set_keycode(KeyMappingWindows::get_keysym(ke.wParam)); } + k->set_physical_keycode(KeyMappingWindows::get_scansym((ke.lParam >> 16) & 0xFF, ke.lParam & (1 << 24))); + if (i + 1 < key_event_pos && key_event_buffer[i + 1].uMsg == WM_CHAR) { k->set_unicode(key_event_buffer[i + 1].wParam); } diff --git a/platform/x11/key_mapping_x11.cpp b/platform/x11/key_mapping_x11.cpp index 54e1e1d357..78bd2b71a0 100644 --- a/platform/x11/key_mapping_x11.cpp +++ b/platform/x11/key_mapping_x11.cpp @@ -180,6 +180,140 @@ static _XTranslatePair _xkeysym_to_keycode[] = { { 0, 0 } }; +struct _TranslatePair { + + unsigned int keysym; + unsigned int keycode; +}; + +static _TranslatePair _scancode_to_keycode[] = { + + { KEY_ESCAPE, 0x09 }, + { KEY_1, 0x0A }, + { KEY_2, 0x0B }, + { KEY_3, 0x0C }, + { KEY_4, 0x0D }, + { KEY_5, 0x0E }, + { KEY_6, 0x0F }, + { KEY_7, 0x10 }, + { KEY_8, 0x11 }, + { KEY_9, 0x12 }, + { KEY_0, 0x13 }, + { KEY_MINUS, 0x14 }, + { KEY_EQUAL, 0x15 }, + { KEY_BACKSPACE, 0x16 }, + { KEY_TAB, 0x17 }, + { KEY_Q, 0x18 }, + { KEY_W, 0x19 }, + { KEY_E, 0x1A }, + { KEY_R, 0x1B }, + { KEY_T, 0x1C }, + { KEY_Y, 0x1D }, + { KEY_U, 0x1E }, + { KEY_I, 0x1F }, + { KEY_O, 0x20 }, + { KEY_P, 0x21 }, + { KEY_BRACELEFT, 0x22 }, + { KEY_BRACERIGHT, 0x23 }, + { KEY_ENTER, 0x24 }, + { KEY_CONTROL, 0x25 }, + { KEY_A, 0x26 }, + { KEY_S, 0x27 }, + { KEY_D, 0x28 }, + { KEY_F, 0x29 }, + { KEY_G, 0x2A }, + { KEY_H, 0x2B }, + { KEY_J, 0x2C }, + { KEY_K, 0x2D }, + { KEY_L, 0x2E }, + { KEY_SEMICOLON, 0x2F }, + { KEY_APOSTROPHE, 0x30 }, + { KEY_QUOTELEFT, 0x31 }, + { KEY_SHIFT, 0x32 }, + { KEY_BACKSLASH, 0x33 }, + { KEY_Z, 0x34 }, + { KEY_X, 0x35 }, + { KEY_C, 0x36 }, + { KEY_V, 0x37 }, + { KEY_B, 0x38 }, + { KEY_N, 0x39 }, + { KEY_M, 0x3A }, + { KEY_COMMA, 0x3B }, + { KEY_PERIOD, 0x3C }, + { KEY_SLASH, 0x3D }, + { KEY_SHIFT, 0x3E }, + { KEY_KP_MULTIPLY, 0x3F }, + { KEY_ALT, 0x40 }, + { KEY_SPACE, 0x41 }, + { KEY_CAPSLOCK, 0x42 }, + { KEY_F1, 0x43 }, + { KEY_F2, 0x44 }, + { KEY_F3, 0x45 }, + { KEY_F4, 0x46 }, + { KEY_F5, 0x47 }, + { KEY_F6, 0x48 }, + { KEY_F7, 0x49 }, + { KEY_F8, 0x4A }, + { KEY_F9, 0x4B }, + { KEY_F10, 0x4C }, + { KEY_NUMLOCK, 0x4D }, + { KEY_SCROLLLOCK, 0x4E }, + { KEY_KP_7, 0x4F }, + { KEY_KP_8, 0x50 }, + { KEY_KP_9, 0x51 }, + { KEY_KP_SUBTRACT, 0x52 }, + { KEY_KP_4, 0x53 }, + { KEY_KP_5, 0x54 }, + { KEY_KP_6, 0x55 }, + { KEY_KP_ADD, 0x56 }, + { KEY_KP_1, 0x57 }, + { KEY_KP_2, 0x58 }, + { KEY_KP_3, 0x59 }, + { KEY_KP_0, 0x5A }, + { KEY_KP_PERIOD, 0x5B }, + //{ KEY_???, 0x5E }, //NON US BACKSLASH + { KEY_F11, 0x5F }, + { KEY_F12, 0x60 }, + { KEY_KP_ENTER, 0x68 }, + { KEY_CONTROL, 0x69 }, + { KEY_KP_DIVIDE, 0x6A }, + { KEY_PRINT, 0x6B }, + { KEY_ALT, 0x6C }, + { KEY_ENTER, 0x6D }, + { KEY_HOME, 0x6E }, + { KEY_UP, 0x6F }, + { KEY_PAGEUP, 0x70 }, + { KEY_LEFT, 0x71 }, + { KEY_RIGHT, 0x72 }, + { KEY_END, 0x73 }, + { KEY_DOWN, 0x74 }, + { KEY_PAGEDOWN, 0x75 }, + { KEY_INSERT, 0x76 }, + { KEY_DELETE, 0x77 }, + { KEY_VOLUMEMUTE, 0x79 }, + { KEY_VOLUMEDOWN, 0x7A }, + { KEY_VOLUMEUP, 0x7B }, + { KEY_PAUSE, 0x7F }, + { KEY_SUPER_L, 0x85 }, + { KEY_SUPER_R, 0x86 }, + { KEY_MENU, 0x87 }, + { KEY_UNKNOWN, 0 } +}; + +unsigned int KeyMappingX11::get_scancode(unsigned int p_code) { + + unsigned int keycode = KEY_UNKNOWN; + for (int i = 0; _scancode_to_keycode[i].keysym != KEY_UNKNOWN; i++) { + + if (_scancode_to_keycode[i].keycode == p_code) { + keycode = _scancode_to_keycode[i].keysym; + break; + } + } + + return keycode; +} + unsigned int KeyMappingX11::get_keycode(KeySym p_keysym) { // kinda bruteforce.. could optimize. diff --git a/platform/x11/key_mapping_x11.h b/platform/x11/key_mapping_x11.h index e99bf1694b..10db43bcc4 100644 --- a/platform/x11/key_mapping_x11.h +++ b/platform/x11/key_mapping_x11.h @@ -45,6 +45,7 @@ class KeyMappingX11 { public: static unsigned int get_keycode(KeySym p_keysym); + static unsigned int get_scancode(unsigned int p_code); static KeySym get_keysym(unsigned int p_code); static unsigned int get_unicode_from_keysym(KeySym p_keysym); static KeySym get_keysym_from_unicode(unsigned int p_unicode); diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 36e9681f5f..c74981fd55 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -1888,6 +1888,8 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) { if (status == XLookupChars) { bool keypress = xkeyevent->type == KeyPress; unsigned int keycode = KeyMappingX11::get_keycode(keysym_keycode); + unsigned int physical_keycode = KeyMappingX11::get_scancode(xkeyevent->keycode); + if (keycode >= 'a' && keycode <= 'z') keycode -= 'a' - 'A'; @@ -1896,23 +1898,29 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) { for (int i = 0; i < tmp.length(); i++) { Ref<InputEventKey> k; k.instance(); - if (keycode == 0 && tmp[i] == 0) { + if (physical_keycode == 0 && keycode == 0 && tmp[i] == 0) { continue; } + if (keycode == 0) + keycode = physical_keycode; + get_key_modifier_state(xkeyevent->state, k); k->set_unicode(tmp[i]); k->set_pressed(keypress); - k->set_scancode(keycode); + k->set_keycode(keycode); + + k->set_physical_keycode(physical_keycode); k->set_echo(false); - if (k->get_scancode() == KEY_BACKTAB) { + if (k->get_keycode() == KEY_BACKTAB) { //make it consistent across platforms. - k->set_scancode(KEY_TAB); + k->set_keycode(KEY_TAB); + k->set_physical_keycode(KEY_TAB); k->set_shift(true); } @@ -1942,6 +1950,7 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) { // keysym, so it works in all platforms the same. unsigned int keycode = KeyMappingX11::get_keycode(keysym_keycode); + unsigned int physical_keycode = KeyMappingX11::get_scancode(xkeyevent->keycode); /* Phase 3, obtain a unicode character from the keysym */ @@ -1961,9 +1970,12 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) { bool keypress = xkeyevent->type == KeyPress; - if (keycode == 0 && unicode == 0) + if (physical_keycode == 0 && keycode == 0 && unicode == 0) return; + if (keycode == 0) + keycode = physical_keycode; + /* Phase 5, determine modifier mask */ // No problems here, except I had no way to @@ -2025,37 +2037,39 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) { if (keycode >= 'a' && keycode <= 'z') keycode -= 'a' - 'A'; - k->set_scancode(keycode); + k->set_keycode(keycode); + k->set_physical_keycode(physical_keycode); k->set_unicode(unicode); k->set_echo(p_echo); - if (k->get_scancode() == KEY_BACKTAB) { + if (k->get_keycode() == KEY_BACKTAB) { //make it consistent across platforms. - k->set_scancode(KEY_TAB); + k->set_keycode(KEY_TAB); + k->set_physical_keycode(KEY_TAB); k->set_shift(true); } //don't set mod state if modifier keys are released by themselves //else event.is_action() will not work correctly here if (!k->is_pressed()) { - if (k->get_scancode() == KEY_SHIFT) + if (k->get_keycode() == KEY_SHIFT) k->set_shift(false); - else if (k->get_scancode() == KEY_CONTROL) + else if (k->get_keycode() == KEY_CONTROL) k->set_control(false); - else if (k->get_scancode() == KEY_ALT) + else if (k->get_keycode() == KEY_ALT) k->set_alt(false); - else if (k->get_scancode() == KEY_META) + else if (k->get_keycode() == KEY_META) k->set_metakey(false); } - bool last_is_pressed = Input::get_singleton()->is_key_pressed(k->get_scancode()); + bool last_is_pressed = Input::get_singleton()->is_key_pressed(k->get_keycode()); if (k->is_pressed()) { if (last_is_pressed) { k->set_echo(true); } } - //printf("key: %x\n",k->get_scancode()); + //printf("key: %x\n",k->get_keycode()); input->accumulate_input_event(k); } |