From 0e9eefb7d4d3d3b10558ade0fea5ea9656a7cace Mon Sep 17 00:00:00 2001 From: eska Date: Sat, 16 Apr 2016 00:19:02 +0200 Subject: Reimplement key input events in Emscripten export Scancodes work, but unicode values are now completely broken in some browser/OS combinations. --- platform/javascript/os_javascript.cpp | 68 ++++++++++++++++++++++++++++++----- 1 file changed, 60 insertions(+), 8 deletions(-) (limited to 'platform/javascript/os_javascript.cpp') diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp index 413d88ee2..b60e5164b 100644 --- a/platform/javascript/os_javascript.cpp +++ b/platform/javascript/os_javascript.cpp @@ -38,6 +38,7 @@ #include "core/globals.h" #include "emscripten.h" +#include "dom_keys.h" int OS_JavaScript::get_video_driver_count() const { @@ -76,6 +77,49 @@ void OS_JavaScript::set_opengl_extensions(const char* p_gl_extensions) { gl_extensions=p_gl_extensions; } +static InputEvent _setup_key_event(const EmscriptenKeyboardEvent *emscripten_event) { + + InputEvent ev; + ev.type = InputEvent::KEY; + ev.key.echo = emscripten_event->repeat; + ev.key.mod.alt = emscripten_event->altKey; + ev.key.mod.shift = emscripten_event->shiftKey; + ev.key.mod.control = emscripten_event->ctrlKey; + ev.key.mod.meta = emscripten_event->metaKey; + ev.key.scancode = dom2godot_scancode(emscripten_event->keyCode); + + String unicode = String::utf8(emscripten_event->key); + if (unicode.length()!=1) { + unicode = String::utf8(emscripten_event->charValue); + } + if (unicode.length()==1) { + ev.key.unicode=unicode[0]; + } + + return ev; +} + +static EM_BOOL _keydown_callback(int event_type, const EmscriptenKeyboardEvent *key_event, void *user_data) { + + ERR_FAIL_COND_V(event_type!=EMSCRIPTEN_EVENT_KEYDOWN, false); + + InputEvent ev = _setup_key_event(key_event); + ev.key.pressed = true; + static_cast(user_data)->push_input(ev); + return ev.key.scancode!=KEY_UNKNOWN && ev.key.scancode!=0; +} + +static EM_BOOL _keyup_callback(int event_type, const EmscriptenKeyboardEvent *key_event, void *user_data) { + + ERR_FAIL_COND_V(event_type!=EMSCRIPTEN_EVENT_KEYUP, false); + + InputEvent ev = _setup_key_event(key_event); + ev.key.pressed = false; + static_cast(user_data)->push_input(ev); + return ev.key.scancode!=KEY_UNKNOWN && ev.key.scancode!=0; + +} + static EM_BOOL joy_callback_func(int p_type, const EmscriptenGamepadEvent *p_event, void *p_user) { OS_JavaScript *os = (OS_JavaScript*) OS::get_singleton(); if (os) { @@ -150,8 +194,22 @@ void OS_JavaScript::initialize(const VideoMode& p_desired,int p_video_driver,int input = memnew( InputDefault ); - emscripten_set_gamepadconnected_callback(NULL, true, &joy_callback_func); - emscripten_set_gamepaddisconnected_callback(NULL, true, &joy_callback_func); + EMSCRIPTEN_RESULT result = emscripten_set_keydown_callback(NULL, this , true, &_keydown_callback); + if (result!=EMSCRIPTEN_RESULT_SUCCESS) { + ERR_PRINTS( "Error while setting Emscripten keydown callback: Code " + itos(result) ); + } + result = emscripten_set_keyup_callback(NULL, this, true, &_keyup_callback); + if (result!=EMSCRIPTEN_RESULT_SUCCESS) { + ERR_PRINTS( "Error while setting Emscripten keyup callback: Code " + itos(result) ); + } + result = emscripten_set_gamepadconnected_callback(NULL, true, &joy_callback_func); + if (result!=EMSCRIPTEN_RESULT_SUCCESS) { + ERR_PRINTS( "Error while setting Emscripten gamepadconnected callback: Code " + itos(result) ); + } + result = emscripten_set_gamepaddisconnected_callback(NULL, true, &joy_callback_func); + if (result!=EMSCRIPTEN_RESULT_SUCCESS) { + ERR_PRINTS( "Error while setting Emscripten gamepaddisconnected callback: Code " + itos(result) ); + } } void OS_JavaScript::set_main_loop( MainLoop * p_main_loop ) { @@ -692,12 +750,6 @@ OS_JavaScript::OS_JavaScript(GFXInitFunc p_gfx_init_func,void*p_gfx_init_ud, Ope FileAccessUnix::close_notification_func=_close_notification_funcs; time_to_save_sync=-1; - - for (int i = 0; i < 256; i++) { - key_pressed[i] = false; - if (i < 121) - skey_pressed[i] = false; - } } OS_JavaScript::~OS_JavaScript() { -- cgit v1.2.3-70-g09d2 From 45b90f16ca080c601e6bf7038979eabb6b7eaa3e Mon Sep 17 00:00:00 2001 From: eska Date: Tue, 19 Apr 2016 14:15:20 +0200 Subject: Add fallback to legacy KeyboardEvent in web export Fallback to KeyboardEvent property `charCode` is absence of both `key` and `char` for retrieval of unicode value. --- platform/javascript/os_javascript.cpp | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'platform/javascript/os_javascript.cpp') diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp index b60e5164b..2e42e7999 100644 --- a/platform/javascript/os_javascript.cpp +++ b/platform/javascript/os_javascript.cpp @@ -99,14 +99,30 @@ static InputEvent _setup_key_event(const EmscriptenKeyboardEvent *emscripten_eve return ev; } +static InputEvent deferred_key_event; + static EM_BOOL _keydown_callback(int event_type, const EmscriptenKeyboardEvent *key_event, void *user_data) { ERR_FAIL_COND_V(event_type!=EMSCRIPTEN_EVENT_KEYDOWN, false); InputEvent ev = _setup_key_event(key_event); ev.key.pressed = true; + if (ev.key.unicode==0 && keycode_has_unicode(ev.key.scancode)) { + // defer to keypress event for legacy unicode retrieval + deferred_key_event = ev; + return false; // do not suppress keypress event + } static_cast(user_data)->push_input(ev); - return ev.key.scancode!=KEY_UNKNOWN && ev.key.scancode!=0; + return true; +} + +static EM_BOOL _keypress_callback(int event_type, const EmscriptenKeyboardEvent *key_event, void *user_data) { + + ERR_FAIL_COND_V(event_type!=EMSCRIPTEN_EVENT_KEYPRESS, false); + + deferred_key_event.key.unicode = key_event->charCode; + static_cast(user_data)->push_input(deferred_key_event); + return true; } static EM_BOOL _keyup_callback(int event_type, const EmscriptenKeyboardEvent *key_event, void *user_data) { @@ -198,6 +214,10 @@ void OS_JavaScript::initialize(const VideoMode& p_desired,int p_video_driver,int if (result!=EMSCRIPTEN_RESULT_SUCCESS) { ERR_PRINTS( "Error while setting Emscripten keydown callback: Code " + itos(result) ); } + result = emscripten_set_keypress_callback(NULL, this, true, &_keypress_callback); + if (result!=EMSCRIPTEN_RESULT_SUCCESS) { + ERR_PRINTS( "Error while setting Emscripten keypress callback: Code " + itos(result) ); + } result = emscripten_set_keyup_callback(NULL, this, true, &_keyup_callback); if (result!=EMSCRIPTEN_RESULT_SUCCESS) { ERR_PRINTS( "Error while setting Emscripten keyup callback: Code " + itos(result) ); -- cgit v1.2.3-70-g09d2