From 19927ec41ee80cda003adfee058e41c6e1c3adbb Mon Sep 17 00:00:00 2001 From: Ji-hoon Lee Date: Tue, 9 Jan 2018 18:20:59 +0900 Subject: [PATCH 01/16] EFL 1.20 migration Change-Id: I800cfaf2e693e542e79b6997af7d3dbd489f93a1 Disable graphic acceleration temporarily Change-Id: If3f25dd2292ba297052486e9c8cd912d8f015933 Signed-off-by: Jihoon Kim Revert "Disable graphic acceleration temporarily" This reverts commit f81d2f87b60931eb510f8c320557fd9c6cc4d10b. Change-Id: Ifdb21d098d891db333e87e4b3657881ace121a18 --- CMakeLists.txt | 2 +- packaging/libscl-core.spec | 2 +- src/sclcoreui-efl.cpp | 42 +++++++++++++++++++++++++++--------------- 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d85bafa..2fe6e33 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,7 +39,7 @@ SET(PKGS_CHECK_MODULES IF (with_wayland) ADD_DEFINITIONS("-DWAYLAND") - SET(PKGS_CHECK_MODULES ${PKGS_CHECK_MODULES} ecore-wayland wayland-client input-method-client) + SET(PKGS_CHECK_MODULES ${PKGS_CHECK_MODULES} ecore-wl2 wayland-client input-method-client) ELSE (with_wayland) SET(PKGS_CHECK_MODULES ${PKGS_CHECK_MODULES} ecore-x x11) ENDIF(with_wayland) diff --git a/packaging/libscl-core.spec b/packaging/libscl-core.spec index 0f1fa23..ad9d7b7 100644 --- a/packaging/libscl-core.spec +++ b/packaging/libscl-core.spec @@ -19,7 +19,7 @@ BuildRequires: pkgconfig(vconf) BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(isf) %if %{with wayland} -BuildRequires: pkgconfig(ecore-wayland) +BuildRequires: pkgconfig(ecore-wl2) BuildRequires: pkgconfig(wayland-client) BuildRequires: pkgconfig(input-method-client) %else diff --git a/src/sclcoreui-efl.cpp b/src/sclcoreui-efl.cpp index 8a15194..15ce472 100644 --- a/src/sclcoreui-efl.cpp +++ b/src/sclcoreui-efl.cpp @@ -27,7 +27,8 @@ #include #include #ifdef WAYLAND -#include +#define EFL_BETA_API_SUPPORT +#include #include #else #include @@ -46,7 +47,7 @@ static struct appcore_ops ops; struct WaylandKeyboard { Ecore_Evas *ee; - Ecore_Wl_Window *wl_win; + Ecore_Wl2_Window *wl_win; struct wl_surface *surface; struct wl_input_panel *ip; @@ -126,10 +127,11 @@ void CSCLCoreUIEFL::set_keyboard_size_hints(SclSize portrait, SclSize landscape) Evas_Object *main_window = NATIVE_WINDOW_CAST(m_main_window); #ifdef WAYLAND - ecore_wl_window_rotation_geometry_set(elm_win_wl_window_get(main_window), 0, 0, 0, portrait.width, portrait.height); - ecore_wl_window_rotation_geometry_set(elm_win_wl_window_get(main_window), 90, 0, 0, landscape.height, landscape.width); - ecore_wl_window_rotation_geometry_set(elm_win_wl_window_get(main_window), 180, 0, 0, portrait.width, portrait.height); - ecore_wl_window_rotation_geometry_set(elm_win_wl_window_get(main_window), 270, 0, 0, landscape.height, landscape.width); + Ecore_Wl2_Window *wl_window = (Ecore_Wl2_Window *)elm_win_wl_window_get(main_window); + ecore_wl2_window_rotation_geometry_set(wl_window, 0, 0, 0, portrait.width, portrait.height); + ecore_wl2_window_rotation_geometry_set(wl_window, 90, 0, 0, landscape.height, landscape.width); + ecore_wl2_window_rotation_geometry_set(wl_window, 180, 0, 0, portrait.width, portrait.height); + ecore_wl2_window_rotation_geometry_set(wl_window, 270, 0, 0, landscape.height, landscape.width); #else /* ecore_x_e_window_rotation_geometry_set(elm_win_xwindow_get(main_window), 0, 0, 0, portrait.width, portrait.height); @@ -334,17 +336,21 @@ static void signal_handler(int sig) { static bool _wayland_setup(struct WaylandKeyboard *wlkb, Evas_Object *main_window) { - Eina_Inlist *globals; + Eina_Iterator *globals; struct wl_registry *registry; - Ecore_Wl_Global *global; + Ecore_Wl2_Global *global; + Ecore_Wl2_Display *ewd; - if (!(registry = ecore_wl_registry_get())) + if (!(ewd = ecore_wl2_connected_display_get(NULL))) return false; - if (!(globals = ecore_wl_globals_get())) + if (!(registry = ecore_wl2_display_registry_get(ewd))) return false; - EINA_INLIST_FOREACH(globals, global) + if (!(globals = ecore_wl2_display_globals_get(ewd))) + return false; + + EINA_ITERATOR_FOREACH(globals, global) { if (strcmp(global->interface, "wl_input_panel") == 0) wlkb->ip = (wl_input_panel *)wl_registry_bind(registry, global->id, &wl_input_panel_interface, 1); @@ -370,19 +376,25 @@ _wayland_setup(struct WaylandKeyboard *wlkb, Evas_Object *main_window) /* Set input panel surface */ LOGD("Setting up input panel\n"); - wlkb->wl_win = ecore_evas_wayland_window_get(wlkb->ee); + wlkb->wl_win = ecore_evas_wayland2_window_get(wlkb->ee); if (!wlkb->wl_win) { LOGW("Couldn't get wayland window\n"); return false; } - ecore_wl_window_type_set(wlkb->wl_win, ECORE_WL_WINDOW_TYPE_NONE); - wlkb->surface = ecore_wl_window_surface_create(wlkb->wl_win); - if (!wlkb->surface) { + ecore_wl2_window_type_set(wlkb->wl_win, ECORE_WL2_WINDOW_TYPE_NONE); + Ecore_Wl2_Surface *surface = ecore_wl2_surface_create(wlkb->wl_win, EINA_TRUE); + if (!surface) { LOGW("Couldn't create surface\n"); return false; } + wlkb->surface = ecore_wl2_window_surface_get(wlkb->wl_win); + if (!wlkb->surface) { + LOGW("Couldn't get surface\n"); + return false; + } + wlkb->ips = wl_input_panel_get_input_panel_surface(wlkb->ip, wlkb->surface); if (!wlkb->ips) { LOGW("Couldn't get input panel surface\n"); -- 2.7.4 From 1e9043207224d1bbbefa5d6698bc639e4f09a2df Mon Sep 17 00:00:00 2001 From: Ji-hoon Lee Date: Mon, 19 Mar 2018 17:53:48 +0900 Subject: [PATCH 02/16] Update package version to 0.6.4 Change-Id: Ib0cfce02fd2cf6421123e69ecf64e4a6d614b8f2 --- packaging/libscl-core.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libscl-core.spec b/packaging/libscl-core.spec index ad9d7b7..050c983 100644 --- a/packaging/libscl-core.spec +++ b/packaging/libscl-core.spec @@ -8,7 +8,7 @@ Name: libscl-core Summary: A library for developing software keyboards -Version: 0.6.3 +Version: 0.6.4 Release: 1 Group: Graphics & UI Framework/Input License: Apache-2.0 -- 2.7.4 From 32df1232e34fc8c451f42c5e6ce532b950b8f623 Mon Sep 17 00:00:00 2001 From: Ji-hoon Lee Date: Wed, 9 Aug 2017 21:39:46 +0900 Subject: [PATCH 03/16] Handle the case WebIME reloads and losts init information Change-Id: I41ce3723ba0572c46c98ac5158a49cdeda1afecd --- src/legacy_support/websocket.cpp | 58 ++++++++++++++++++++++++++++++++++------ src/legacy_support/websocket.h | 4 +++ 2 files changed, 54 insertions(+), 8 deletions(-) diff --git a/src/legacy_support/websocket.cpp b/src/legacy_support/websocket.cpp index 4fecacc..f3946d6 100644 --- a/src/legacy_support/websocket.cpp +++ b/src/legacy_support/websocket.cpp @@ -75,6 +75,8 @@ static int callback_http(struct lws *wsi, struct per_session_data__keyboard { int session_id; int valid; + int need_init; + int initialized; }; static int callback_keyboard(struct lws *wsi, @@ -115,6 +117,8 @@ static int callback_keyboard(struct lws *wsi, pss->session_id = ++last_session_id; LOGD("LWS_CALLBACK_ESTABLISHED : %p %d", g_ws_server_context, pss->session_id); pss->valid = false; + pss->need_init = false; + pss->initialized = false; if (g_ws_server_context) { lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]); } @@ -126,19 +130,46 @@ static int callback_keyboard(struct lws *wsi, case LWS_CALLBACK_SERVER_WRITEABLE: if (agent) { + /* Ignore valid check since the magic key is not used anymore */ + if (!pss->valid) pss->valid = true; + /* We allow data tranmission only if this client is guaranteed to be valid */ if (pss->valid) { pthread_mutex_lock(&g_ws_server_mutex); std::queue& messages = agent->get_send_message_queue(); - /* One write allowed per one writable callback */ - if (messages.size() > 0) { - ISE_MESSAGE &message = messages.front(); + + if (pss->need_init && !pss->initialized) { + ISE_MESSAGE message; + message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_PLAIN]; + message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_INIT]; std::string str = CISEMessageSerializer::serialize(message); - LOGD("SEND_WEBSOCKET_MESSAGE : %s", str.c_str()); + LOGD("SEND_WEBSOCKET_MESSAGE : %d %s", pss->session_id, str.c_str()); n = snprintf((char *)p, bufsize, "%s", str.c_str()); /* too small for partial */ n = lws_write(wsi, p, n, LWS_WRITE_TEXT); - messages.pop(); + pss->need_init = false; + pss->initialized = true; + } else { + /* One write allowed per one writable callback */ + if (messages.size() > 0) { + ISE_MESSAGE &message = messages.front(); + bool drop = false; + if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_INIT]) == 0) { + if (pss->initialized) { + drop = true; + } else { + pss->initialized = true; + } + } + if (!drop) { + std::string str = CISEMessageSerializer::serialize(message); + LOGD("SEND_WEBSOCKET_MESSAGE : %d %s", pss->session_id, str.c_str()); + n = snprintf((char *)p, bufsize, "%s", str.c_str()); + /* too small for partial */ + n = lws_write(wsi, p, n, LWS_WRITE_TEXT); + } + messages.pop(); + } } if (messages.size() > 0) { ecore_pipe_write(agent->get_message_pipe(), MESSAGE_LEFT, strlen(MESSAGE_LEFT)); @@ -146,7 +177,7 @@ static int callback_keyboard(struct lws *wsi, pthread_mutex_unlock(&g_ws_server_mutex); if (n < 0) { - LOGE("ERROR %d writing to di socket\n", n); + LOGE("ERROR %d writing to di socket %d", n, pss->session_id); return -1; } @@ -154,7 +185,7 @@ static int callback_keyboard(struct lws *wsi, lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]); } } else { - LOGD("Rejecting data transmission since client is not valid"); + LOGD("Rejecting data transmission since client is not valid : %d", pss->session_id); } } break; @@ -175,8 +206,16 @@ static int callback_keyboard(struct lws *wsi, } */ pss->valid = true; + + if (agent->initalized()) { + pss->need_init = true; + lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]); + } } + /* Ignore valid check since the magic key is not used anymore */ + if (!pss->valid) pss->valid = true; + if (pss->valid) { pthread_mutex_lock(&g_ws_server_mutex); std::queue& messages = agent->get_recv_message_queue(); @@ -192,7 +231,7 @@ static int callback_keyboard(struct lws *wsi, pthread_mutex_unlock(&g_ws_query_mutex); } } else { - LOGD("Ignoring data received since client is not valid"); + LOGD("Ignoring data received since client is not valid %d", pss->session_id); } } @@ -233,6 +272,7 @@ CWebHelperAgentWebSocket::CWebHelperAgentWebSocket() } m_current_instance = this; m_message_pipe = NULL; + m_initialized = false; } CWebHelperAgentWebSocket::~CWebHelperAgentWebSocket() @@ -318,6 +358,8 @@ bool CWebHelperAgentWebSocket::init() on_init(); + m_initialized = true; + return ret; } diff --git a/src/legacy_support/websocket.h b/src/legacy_support/websocket.h index 98483cb..d032ed9 100644 --- a/src/legacy_support/websocket.h +++ b/src/legacy_support/websocket.h @@ -205,6 +205,8 @@ public: bool init(); bool exit(); + bool initalized() { return m_initialized; } + void signal(int sig); void on_init(); @@ -258,6 +260,8 @@ protected: std::queue m_recv_message_queue; Ecore_Pipe *m_message_pipe; + + bool m_initialized; }; #endif // _WEB_HELPER_AGENT_WEBSOCKET_H_ -- 2.7.4 From f11d05b6eb2520c14daf9155088e9a1247551fee Mon Sep 17 00:00:00 2001 From: Ji-hoon Lee Date: Wed, 9 Aug 2017 22:29:08 +0900 Subject: [PATCH 04/16] Add connection test client that checks libwebsocket server is alive Change-Id: I3597d74988c98b5fb0154ed02106ad677f091ae0 --- src/legacy_support/websocket.cpp | 93 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 87 insertions(+), 6 deletions(-) diff --git a/src/legacy_support/websocket.cpp b/src/legacy_support/websocket.cpp index f3946d6..8d13e4d 100644 --- a/src/legacy_support/websocket.cpp +++ b/src/legacy_support/websocket.cpp @@ -35,6 +35,8 @@ #include +#define WEBSOCKET_PORT 7681 + #define RECVED_MESSAGE "recved" #define MESSAGE_LEFT "left" @@ -99,6 +101,82 @@ static struct lws_protocols protocols[] = { { NULL, NULL, 0, 0 } }; + +static int callback_client(struct lws *wsi, + enum lws_callback_reasons reason, + void *user, void *in, size_t len) +{ + switch (reason) { + case LWS_CALLBACK_CLIENT_ESTABLISHED: + LOGD("[ClientTest] Connection established"); + break; + + case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: + LOGD("[ClientTest] Connection error"); + break; + + case LWS_CALLBACK_CLOSED: + LOGD("[ClientTest] Connection closed"); + break; + + default: + break; + } + + return 0; +} + +int test_client_connection(void) +{ + struct lws_context *context = NULL; + struct lws_context_creation_info context_info; + struct lws_client_connect_info connect_info; + struct lws *wsi = NULL; + + memset(&context_info, 0, sizeof context_info); + memset(&connect_info, 0, sizeof(connect_info)); + + const int protocols_num = sizeof(protocols) / sizeof(lws_protocols); + static struct lws_protocols client_protocols[protocols_num]; + + memcpy(&client_protocols, protocols, sizeof(protocols)); + for (int loop = 0; loop < protocols_num - 1; loop++) { + client_protocols[loop].callback = callback_client; + } + + context_info.port = CONTEXT_PORT_NO_LISTEN; + context_info.protocols = protocols; + context_info.gid = -1; + context_info.uid = -1; + + context = lws_create_context(&context_info); + LOGD("[ClientTest] create_context : %p", context); + if (context == NULL) { + return -1; + } + + connect_info.address = "localhost"; + connect_info.port = WEBSOCKET_PORT; + connect_info.path = "/"; + connect_info.context = context; + connect_info.ssl_connection = 0; + connect_info.host = connect_info.address; + connect_info.origin = connect_info.address; + connect_info.ietf_version_or_minus_one = -1; + connect_info.protocol = "keyboard-protocol"; + + wsi = lws_client_connect_via_info(&connect_info); + LOGD("[ClientTest] wsi created : %p", wsi); + + if (wsi) { + lws_service(context, 50); + } + + lws_context_destroy(context); + + return 0; +} + static int callback_keyboard(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) @@ -143,7 +221,7 @@ static int callback_keyboard(struct lws *wsi, message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_PLAIN]; message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_INIT]; std::string str = CISEMessageSerializer::serialize(message); - LOGD("SEND_WEBSOCKET_MESSAGE : %d %s", pss->session_id, str.c_str()); + SECURE_LOGD("SEND_WEBSOCKET_MESSAGE : %d %s", pss->session_id, str.c_str()); n = snprintf((char *)p, bufsize, "%s", str.c_str()); /* too small for partial */ n = lws_write(wsi, p, n, LWS_WRITE_TEXT); @@ -163,7 +241,7 @@ static int callback_keyboard(struct lws *wsi, } if (!drop) { std::string str = CISEMessageSerializer::serialize(message); - LOGD("SEND_WEBSOCKET_MESSAGE : %d %s", pss->session_id, str.c_str()); + SECURE_LOGD("SEND_WEBSOCKET_MESSAGE : %d %s", pss->session_id, str.c_str()); n = snprintf((char *)p, bufsize, "%s", str.c_str()); /* too small for partial */ n = lws_write(wsi, p, n, LWS_WRITE_TEXT); @@ -178,7 +256,6 @@ static int callback_keyboard(struct lws *wsi, if (n < 0) { LOGE("ERROR %d writing to di socket %d", n, pss->session_id); - return -1; } if (messages.size() > 0) { @@ -312,7 +389,7 @@ bool CWebHelperAgentWebSocket::init() struct lws_context_creation_info info; memset(&info, 0, sizeof info); - info.port = 7681; + info.port = WEBSOCKET_PORT; int log_level = LLL_ERR | LLL_WARN | LLL_DEBUG; lws_set_log_level(log_level, log_func); @@ -333,13 +410,13 @@ bool CWebHelperAgentWebSocket::init() m_message_pipe = ecore_pipe_add(message_pipe_handler, NULL); /* Let's retry creating server context for a certain number of times */ - const int max_retry_num = 10; + const int max_retry_num = 30; int retry_num = 0; do { g_ws_server_context = lws_create_context(&info); LOGD("libwebsocket context : %p", g_ws_server_context); - sleep(1); + usleep(100 * 1000); } while (g_ws_server_context == NULL && retry_num++ < max_retry_num); pthread_mutex_init(&g_ws_server_mutex, NULL); @@ -353,6 +430,7 @@ bool CWebHelperAgentWebSocket::init() ret = false; } } else { + LOGE("Failed creating server context : %p", g_ws_server_context); ret = false; } @@ -360,6 +438,8 @@ bool CWebHelperAgentWebSocket::init() m_initialized = true; + test_client_connection(); + return ret; } @@ -384,6 +464,7 @@ bool CWebHelperAgentWebSocket::exit() pthread_mutex_destroy(&g_ws_server_mutex); if (g_ws_server_context) { + lws_cancel_service(g_ws_server_context); lws_context_destroy(g_ws_server_context); g_ws_server_context = NULL; } -- 2.7.4 From c4c806b6369de6426c16fabe9998653cb35a1f5f Mon Sep 17 00:00:00 2001 From: Ji-hoon Lee Date: Thu, 17 Aug 2017 20:16:50 +0900 Subject: [PATCH 05/16] Add timer to process accumulated partial messages Change-Id: I1547763eb9a32d5c05d6eaad0d18971f83dd1b2d --- src/legacy_support/websocket.cpp | 135 ++++++++++++++++++++++++++++----------- src/legacy_support/websocket.h | 28 +++++++- src/sclconnection-isf.cpp | 1 + 3 files changed, 125 insertions(+), 39 deletions(-) diff --git a/src/legacy_support/websocket.cpp b/src/legacy_support/websocket.cpp index 8d13e4d..6f5dee2 100644 --- a/src/legacy_support/websocket.cpp +++ b/src/legacy_support/websocket.cpp @@ -35,6 +35,10 @@ #include +#ifdef WAYLAND +#include +#endif + #define WEBSOCKET_PORT 7681 #define RECVED_MESSAGE "recved" @@ -177,6 +181,67 @@ int test_client_connection(void) return 0; } +static Ecore_Timer *g_flush_server_recv_buffer_timer = NULL; +static std::string server_recv_buffer; +static Eina_Bool flush_server_recv_buffer_func(void *user) +{ + LOGD(""); + CWebHelperAgentWebSocket *agent = CWebHelperAgentWebSocket::get_current_instance(); + struct per_session_data__keyboard *pss = (struct per_session_data__keyboard *)user; + + if (g_flush_server_recv_buffer_timer) + ecore_timer_del(g_flush_server_recv_buffer_timer); + g_flush_server_recv_buffer_timer = NULL; + + if (!agent || !pss) return ECORE_CALLBACK_CANCEL; + + pthread_mutex_lock(&g_ws_server_mutex); + ISE_MESSAGE message = CISEMessageSerializer::deserialize(server_recv_buffer); + server_recv_buffer.clear(); + pthread_mutex_unlock(&g_ws_server_mutex); + + if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_LOGIN]) == 0) { + /* + if (message.values.at(0).compare(CMagicKeyManager::get_magic_key()) == 0) { + LOGD("LOGIN successful, validating client"); + pss->valid = true; + } else { + LOGD("LOGIN failed, invalidating client"); + pss->valid = false; + } + */ + pss->valid = true; + + if (agent->initalized()) { + pss->need_init = true; + ecore_pipe_write(agent->get_message_pipe(), MESSAGE_LEFT, strlen(MESSAGE_LEFT)); + } + } + + /* Ignore valid check since the magic key is not used anymore */ + if (!pss->valid) pss->valid = true; + + if (pss->valid) { + pthread_mutex_lock(&g_ws_server_mutex); + std::queue& messages = agent->get_recv_message_queue(); + messages.push(message); + pthread_mutex_unlock(&g_ws_server_mutex); + + ecore_pipe_write(agent->get_message_pipe(), RECVED_MESSAGE, strlen(RECVED_MESSAGE)); + + /* If we received reply message, let's send signal to wake up our main thread */ + if (message.type.compare(ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_REPLY]) == 0) { + pthread_mutex_lock(&g_ws_query_mutex); + pthread_cond_signal(&g_ws_query_condition); + pthread_mutex_unlock(&g_ws_query_mutex); + } + } else { + LOGD("Ignoring data received since client is not valid %d", pss->session_id); + } + + return ECORE_CALLBACK_CANCEL; +} + static int callback_keyboard(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) @@ -198,7 +263,7 @@ static int callback_keyboard(struct lws *wsi, pss->need_init = false; pss->initialized = false; if (g_ws_server_context) { - lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]); + ecore_pipe_write(agent->get_message_pipe(), MESSAGE_LEFT, strlen(MESSAGE_LEFT)); } break; @@ -269,47 +334,20 @@ static int callback_keyboard(struct lws *wsi, case LWS_CALLBACK_RECEIVE: if (in) { - std::string str = (const char *)in; - ISE_MESSAGE message = CISEMessageSerializer::deserialize(str); - - if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_LOGIN]) == 0) { - /* - if (message.values.at(0).compare(CMagicKeyManager::get_magic_key()) == 0) { - LOGD("LOGIN successful, validating client"); - pss->valid = true; - } else { - LOGD("LOGIN failed, invalidating client"); - pss->valid = false; - } - */ - pss->valid = true; + if (g_flush_server_recv_buffer_timer) + ecore_timer_del(g_flush_server_recv_buffer_timer); - if (agent->initalized()) { - pss->need_init = true; - lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]); - } + std::string str = (const char *)in; + if (CISEMessageSerializer::valid(str)) { + LOGD("A valid new message received, flush previous buffer"); + flush_server_recv_buffer_func((void*)pss); } - /* Ignore valid check since the magic key is not used anymore */ - if (!pss->valid) pss->valid = true; + pthread_mutex_lock(&g_ws_server_mutex); + server_recv_buffer += str; + pthread_mutex_unlock(&g_ws_server_mutex); - if (pss->valid) { - pthread_mutex_lock(&g_ws_server_mutex); - std::queue& messages = agent->get_recv_message_queue(); - messages.push(message); - pthread_mutex_unlock(&g_ws_server_mutex); - - ecore_pipe_write(agent->get_message_pipe(), RECVED_MESSAGE, strlen(RECVED_MESSAGE)); - - /* If we received reply message, let's send signal to wake up our main thread */ - if (message.type.compare(ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_REPLY]) == 0) { - pthread_mutex_lock(&g_ws_query_mutex); - pthread_cond_signal(&g_ws_query_condition); - pthread_mutex_unlock(&g_ws_query_mutex); - } - } else { - LOGD("Ignoring data received since client is not valid %d", pss->session_id); - } + g_flush_server_recv_buffer_timer = ecore_timer_add(0.05, flush_server_recv_buffer_func, (void*)pss); } break; @@ -445,6 +483,10 @@ bool CWebHelperAgentWebSocket::init() bool CWebHelperAgentWebSocket::exit() { + if (g_flush_server_recv_buffer_timer) + ecore_timer_del(g_flush_server_recv_buffer_timer); + g_flush_server_recv_buffer_timer = NULL; + on_exit(); g_ws_server_exit = true; @@ -1119,6 +1161,23 @@ void CWebHelperAgentWebSocket::handle_recved_message(ISE_MESSAGE &message) LOGD("ISE_MESSAGE_COMMAND_SET_KEYBOARD_SIZES : %d %d %d %d", portrait_width, portrait_height, landscape_width, landscape_height); + +#ifdef WAYLAND + /* Since the full screen IME makes the client application fully obscured, + * when it hides the client receives resume command and try to show IME again. + * So here we are adjusting the height value when the requested keyboard size + * is the same with the screen size, as a workaround */ + int scr_w = 0, scr_h = 0; + ecore_wl_sync(); + ecore_wl_screen_size_get(&scr_w, &scr_h); + if (scr_w == portrait_width && scr_h == portrait_height) { + portrait_height -= 1; + } + if (scr_h == landscape_width && scr_w == landscape_height) { + landscape_height -= 1; + } +#endif + set_keyboard_sizes( portrait_width, portrait_height, landscape_width, landscape_height); } diff --git a/src/legacy_support/websocket.h b/src/legacy_support/websocket.h index d032ed9..8693608 100644 --- a/src/legacy_support/websocket.h +++ b/src/legacy_support/websocket.h @@ -33,6 +33,8 @@ typedef enum { ISE_MESSAGE_TYPE_PLAIN, ISE_MESSAGE_TYPE_QUERY, ISE_MESSAGE_TYPE_REPLY, + + ISE_MESSAGE_TYPES_NUM, } ISE_MESSAGE_TYPES; const std::string ISE_MESSAGE_TYPE_STRINGS[] = { @@ -91,7 +93,7 @@ const std::string ISE_MESSAGE_COMMAND_STRINGS[] = { "set_rotation", // ISE_MESSAGE_COMMAND_SET_ROTATION, "update_cursor_position", // ISE_MESSAGE_COMMAND_UPDATE_CURSOR_POSITION, "update_surrounding_text", // ISE_MESSAGE_COMMAND_UPDATE_SURROUNDING_TEXT, - "update_selection", // ISE_MESSAGE_COMMAND_UPDATE_SURROUNDING_TEXT, + "update_selection", // ISE_MESSAGE_COMMAND_UPDATE_SELECTION "set_language", // ISE_MESSAGE_COMMAND_SET_LANGUAGE, "set_imdata", // ISE_MESSAGE_COMMAND_SET_IMDATA, "get_imdata", // ISE_MESSAGE_COMMAND_GET_IMDATA, @@ -195,6 +197,30 @@ public: } return ret; } + + static bool valid(std::string str) + { + int loop; + + bool valid_type = false; + bool valid_command = false; + + ISE_MESSAGE message; + message = deserialize(str); + + for (loop = 0;!valid_type && loop < ISE_MESSAGE_TYPES_NUM;loop++) { + if (message.type.compare(ISE_MESSAGE_TYPE_STRINGS[loop]) == 0) { + valid_type = true; + } + } + for (loop = 0;!valid_command && loop < ISE_MESSAGE_COMMANDS_NUM;loop++) { + if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[loop]) == 0) { + valid_command = true; + } + } + + return (valid_type && valid_command); + } }; class CWebHelperAgentWebSocket : public CWebHelperAgent { diff --git a/src/sclconnection-isf.cpp b/src/sclconnection-isf.cpp index dae093b..8b4bd63 100644 --- a/src/sclconnection-isf.cpp +++ b/src/sclconnection-isf.cpp @@ -196,6 +196,7 @@ static void slot_ise_show(const scim::HelperAgent *agent, int ic, char *buf, siz #ifdef WEBSOCKET g_websocket.on_set_layout(ise_context.layout); + g_websocket.on_update_cursor_position(ic, ise_context.cursor_pos); g_websocket.on_show(ic); #endif } -- 2.7.4 From 967fd49e41d3e9319b8583662eeb36417ad3508e Mon Sep 17 00:00:00 2001 From: Ji-hoon Lee Date: Tue, 10 Apr 2018 14:13:44 +0900 Subject: [PATCH 06/16] Apply EFL 1.20 upgrade Change-Id: Icafcba8df9e04bb1d3283cb0de869b3cafe917cb --- src/legacy_support/websocket.cpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/legacy_support/websocket.cpp b/src/legacy_support/websocket.cpp index 6f5dee2..ada9e47 100644 --- a/src/legacy_support/websocket.cpp +++ b/src/legacy_support/websocket.cpp @@ -36,7 +36,8 @@ #include #ifdef WAYLAND -#include +#define EFL_BETA_API_SUPPORT +#include #endif #define WEBSOCKET_PORT 7681 @@ -1168,13 +1169,17 @@ void CWebHelperAgentWebSocket::handle_recved_message(ISE_MESSAGE &message) * So here we are adjusting the height value when the requested keyboard size * is the same with the screen size, as a workaround */ int scr_w = 0, scr_h = 0; - ecore_wl_sync(); - ecore_wl_screen_size_get(&scr_w, &scr_h); - if (scr_w == portrait_width && scr_h == portrait_height) { - portrait_height -= 1; - } - if (scr_h == landscape_width && scr_w == landscape_height) { - landscape_height -= 1; + ecore_wl2_sync(); + Ecore_Wl2_Display *ewd = NULL; + if ((ewd = ecore_wl2_connected_display_get(NULL))) { + ecore_wl2_display_screen_size_get(ewd, &scr_w, &scr_h); + + if (scr_w == portrait_width && scr_h == portrait_height) { + portrait_height -= 1; + } + if (scr_h == landscape_width && scr_w == landscape_height) { + landscape_height -= 1; + } } #endif -- 2.7.4 From c5ae13d7a69e6f3d9fd457f303aec607296f21fb Mon Sep 17 00:00:00 2001 From: Ji-hoon Lee Date: Tue, 10 Apr 2018 14:28:29 +0900 Subject: [PATCH 07/16] Update package version to 0.6.5 Change-Id: I841c78ea3f44e3c15e1ebd4708bed5eccab6df48 --- packaging/libscl-core.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libscl-core.spec b/packaging/libscl-core.spec index 050c983..b196024 100644 --- a/packaging/libscl-core.spec +++ b/packaging/libscl-core.spec @@ -8,7 +8,7 @@ Name: libscl-core Summary: A library for developing software keyboards -Version: 0.6.4 +Version: 0.6.5 Release: 1 Group: Graphics & UI Framework/Input License: Apache-2.0 -- 2.7.4 From fe96ad1b0aa6de7b1bcbca00674200e3dec06d0a Mon Sep 17 00:00:00 2001 From: Ji-hoon Lee Date: Mon, 4 Jun 2018 19:45:43 +0900 Subject: [PATCH 08/16] Add optimization_hint for ISEs Change-Id: I246170372e1d54dc410c233e4297e6da8cf21461 --- src/sclconnection-isf.cpp | 12 ++++++++++++ src/sclcorecallback.h | 1 + src/sclcoreui.h | 6 ++++++ 3 files changed, 19 insertions(+) diff --git a/src/sclconnection-isf.cpp b/src/sclconnection-isf.cpp index 8b4bd63..c115b22 100644 --- a/src/sclconnection-isf.cpp +++ b/src/sclconnection-isf.cpp @@ -670,6 +670,17 @@ static void slot_set_prediction_hint_data(const scim::HelperAgent *agent, int ic } } +static void slot_set_optimization_hint(const scim::HelperAgent *agent, scim::uint32 &hint) { + CSCLCoreImpl *impl = CSCLCoreImpl::get_instance(); + if (impl) { + ISCLCoreEventCallback *callback = impl->get_core_event_callback(); + if (callback) { + SECURE_LOGD("hint : %d\n", hint); + callback->on_set_optimization_hint(hint); + } + } +} + /* Internal input handler function */ Eina_Bool input_handler(void *data, Ecore_Fd_Handler *fd_handler) { @@ -764,6 +775,7 @@ sclboolean CSCLConnectionISF::init() m_helper_agent.signal_connect_set_prediction_hint(scim::slot(slot_set_prediction_hint)); m_helper_agent.signal_connect_set_mime_type(scim::slot(slot_set_mime_type)); m_helper_agent.signal_connect_set_prediction_hint_data(scim::slot(slot_set_prediction_hint_data)); + m_helper_agent.signal_connect_set_optimization_hint(scim::slot(slot_set_optimization_hint)); m_initialized = TRUE; } diff --git a/src/sclcorecallback.h b/src/sclcorecallback.h index 118e841..c34e83e 100644 --- a/src/sclcorecallback.h +++ b/src/sclcorecallback.h @@ -92,6 +92,7 @@ struct ISCLCoreEventCallback { virtual void on_set_prediction_hint(const sclchar *prediction_hint) {} virtual void on_set_mime_type(const sclchar *mime_type) {} virtual void on_set_prediction_hint_data(const sclchar *key, const sclchar *value) {} + virtual void on_set_optimization_hint(sclu32 hint) {} ISCLCoreEventCallback() { /* Current callback interface version is 1.1 */ diff --git a/src/sclcoreui.h b/src/sclcoreui.h index 9511c30..57cc030 100644 --- a/src/sclcoreui.h +++ b/src/sclcoreui.h @@ -35,6 +35,12 @@ enum KEYBOARD_UI_STATE KEYBOARD_UI_STATE_WILL_SHOW, }; +enum KEYBOARD_OPTMIZATION_HINT +{ + KEYBOARD_OPTIMIZATION_HINT_NONE = 0, + KEYBOARD_OPTIMIZATION_HINT_SHOW_PREPARE, +}; + /** * @brief The base class that provides features for a soft-keyboard * -- 2.7.4 From 0abe5a66646ab076a0d93d49ee30fcdd3daa76f3 Mon Sep 17 00:00:00 2001 From: Jihoon Kim Date: Thu, 21 Jun 2018 08:42:47 +0900 Subject: [PATCH 09/16] Update package version to 0.6.6 Change-Id: I4c85ebcfddbc444b8daae162ab054e4896bd845b Signed-off-by: Jihoon Kim --- packaging/libscl-core.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libscl-core.spec b/packaging/libscl-core.spec index b196024..50221a4 100644 --- a/packaging/libscl-core.spec +++ b/packaging/libscl-core.spec @@ -8,7 +8,7 @@ Name: libscl-core Summary: A library for developing software keyboards -Version: 0.6.5 +Version: 0.6.6 Release: 1 Group: Graphics & UI Framework/Input License: Apache-2.0 -- 2.7.4 From 6f35bafe156b3ff701db91275cc890242582be73 Mon Sep 17 00:00:00 2001 From: Ji-hoon Lee Date: Wed, 4 Jul 2018 09:52:41 +0900 Subject: [PATCH 10/16] Make sure key events are processed before subsequent commit messages Change-Id: I4c4f5d663d26439b5b342b00043292696a7778d3 (cherry picked from commit a51d21ce5f14df49fac89ff16ccf51dead2f3697) --- src/legacy_support/websocket.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/legacy_support/websocket.cpp b/src/legacy_support/websocket.cpp index ada9e47..4bc9f87 100644 --- a/src/legacy_support/websocket.cpp +++ b/src/legacy_support/websocket.cpp @@ -1111,6 +1111,7 @@ bool CWebHelperAgentWebSocket::process_recved_messages_until_reply_found(std::st void CWebHelperAgentWebSocket::handle_recved_message(ISE_MESSAGE &message) { + static bool _key_event_processing = false; if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_LOG]) == 0) { std::string str = ""; for (unsigned int loop = 0;loop < message.values.size();loop++) { @@ -1121,8 +1122,6 @@ void CWebHelperAgentWebSocket::handle_recved_message(ISE_MESSAGE &message) } log(str.c_str()); } else if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_COMMIT_STRING]) == 0) { - send_key_event(0xff6b, 0); // Temporarily reset keyboard engine - std::string str = ""; for (unsigned int loop = 0;loop < message.values.size();loop++) { str += message.values.at(loop).c_str(); @@ -1130,6 +1129,13 @@ void CWebHelperAgentWebSocket::handle_recved_message(ISE_MESSAGE &message) str += " "; } } + if (_key_event_processing) { + struct timeval tv; + tv.tv_sec = 0; + tv.tv_usec = 50000; + select(0, NULL, NULL, NULL, &tv); + _key_event_processing = false; + } commit_string(str.c_str()); } else if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_UPDATE_PREEDIT_STRING]) == 0) { std::string str = ""; @@ -1142,7 +1148,8 @@ void CWebHelperAgentWebSocket::handle_recved_message(ISE_MESSAGE &message) update_preedit_string(str.c_str()); } else if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_SEND_KEY_EVENT]) == 0) { if (message.values.size() == 1) { - send_key_event(atoi(message.values.at(0).c_str()), 0); + forward_key_event(atoi(message.values.at(0).c_str())); + _key_event_processing = true; } } else if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_SET_KEYBOARD_SIZES]) == 0) { LOGD("ISE_MESSAGE_COMMAND_SET_KEYBOARD_SIZES"); -- 2.7.4 From 487ce2fe0f0f24618b7cb713f88c57dfa2012707 Mon Sep 17 00:00:00 2001 From: Ji-hoon Lee Date: Fri, 13 Jul 2018 16:08:19 +0900 Subject: [PATCH 11/16] Update package version to 0.6.7 Change-Id: I01f4dc3407545a9cd41dc71fa94162188333bc9c --- packaging/libscl-core.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libscl-core.spec b/packaging/libscl-core.spec index 50221a4..9e8eff5 100644 --- a/packaging/libscl-core.spec +++ b/packaging/libscl-core.spec @@ -8,7 +8,7 @@ Name: libscl-core Summary: A library for developing software keyboards -Version: 0.6.6 +Version: 0.6.7 Release: 1 Group: Graphics & UI Framework/Input License: Apache-2.0 -- 2.7.4 From e396b8dff16c77a5471cff8899d814cf0df16942 Mon Sep 17 00:00:00 2001 From: Jihoon Kim Date: Thu, 22 Nov 2018 18:35:07 +0900 Subject: [PATCH 12/16] Fix i18n issue in IME Change-Id: I24eb5dcaba083600c4c37c4de182b19d5097ada6 Signed-off-by: Jihoon Kim --- src/sclcoreui-efl.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/sclcoreui-efl.cpp b/src/sclcoreui-efl.cpp index 15ce472..e084b35 100644 --- a/src/sclcoreui-efl.cpp +++ b/src/sclcoreui-efl.cpp @@ -165,6 +165,12 @@ static int language_changed_cb(void *event_info, void* data) } LOGD("current language is %s\n", clang); + setenv("LC_ALL", clang, 1); + char *r = setlocale(LC_ALL, ""); + if (r == NULL) { + setlocale(LC_ALL, "en_US.UTF-8"); + } + CSCLCoreImpl *impl = CSCLCoreImpl::get_instance(); if (impl) { ISCLCoreEventCallback *callback = impl->get_core_event_callback(); -- 2.7.4 From 41d97b3240daf1592ef9e8d6dfaea0669218272b Mon Sep 17 00:00:00 2001 From: Jihoon Kim Date: Thu, 22 Nov 2018 18:35:32 +0900 Subject: [PATCH 13/16] Update package version to 0.6.8 Change-Id: I78e17949ad5b1067e67b0f841d2ca05042a75465 Signed-off-by: Jihoon Kim --- packaging/libscl-core.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libscl-core.spec b/packaging/libscl-core.spec index 9e8eff5..9d4a14f 100644 --- a/packaging/libscl-core.spec +++ b/packaging/libscl-core.spec @@ -8,7 +8,7 @@ Name: libscl-core Summary: A library for developing software keyboards -Version: 0.6.7 +Version: 0.6.8 Release: 1 Group: Graphics & UI Framework/Input License: Apache-2.0 -- 2.7.4 From a775c4936ffded637c0ffe06c585e2bfb866c6e8 Mon Sep 17 00:00:00 2001 From: Ji-hoon Lee Date: Fri, 7 Dec 2018 16:27:49 +0900 Subject: [PATCH 14/16] Fix mismatch between log format and actual parameter Change-Id: I9b6ead8cf534ee8bfcec5445a668e96e827e4e8a --- src/sclconnection-isf.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sclconnection-isf.cpp b/src/sclconnection-isf.cpp index c115b22..8b3cfbe 100644 --- a/src/sclconnection-isf.cpp +++ b/src/sclconnection-isf.cpp @@ -183,7 +183,8 @@ static void slot_ise_show(const scim::HelperAgent *agent, int ic, char *buf, siz if (len > (sizeof(Ise_Context) + ise_context.imdata_size)) callback->on_set_mime_type(buf + sizeof(ise_context) + ise_context.imdata_size); } else { - LOGD("\n-=-= WARNING - buf %p len %d size %d \n", buf, len, sizeof(ise_context)); + LOGD("\n-=-= WARNING - buf %p len %lu size %lu \n", + buf, (long unsigned int)len, (long unsigned int)sizeof(ise_context)); } CSCLCoreUI* ui = impl->get_core_ui(); if (ui) { -- 2.7.4 From e64de133904fb4ee4bef30112242f9d3ff6609be Mon Sep 17 00:00:00 2001 From: Ji-hoon Lee Date: Fri, 7 Dec 2018 16:41:35 +0900 Subject: [PATCH 15/16] Use %z format string for printing size_t types Change-Id: Ie1b3e0d0505ff1fb89ca5f4c25c04a236a391ff3 --- src/sclconnection-isf.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sclconnection-isf.cpp b/src/sclconnection-isf.cpp index 8b3cfbe..ca1a86c 100644 --- a/src/sclconnection-isf.cpp +++ b/src/sclconnection-isf.cpp @@ -183,8 +183,7 @@ static void slot_ise_show(const scim::HelperAgent *agent, int ic, char *buf, siz if (len > (sizeof(Ise_Context) + ise_context.imdata_size)) callback->on_set_mime_type(buf + sizeof(ise_context) + ise_context.imdata_size); } else { - LOGD("\n-=-= WARNING - buf %p len %lu size %lu \n", - buf, (long unsigned int)len, (long unsigned int)sizeof(ise_context)); + LOGD("\n-=-= WARNING - buf %p len %zu size %zu\n", buf, len, sizeof(ise_context)); } CSCLCoreUI* ui = impl->get_core_ui(); if (ui) { -- 2.7.4 From 4621e9cc5ac764a7858a37e4da84dc3d1516fe4b Mon Sep 17 00:00:00 2001 From: Ji-hoon Lee Date: Fri, 7 Dec 2018 16:28:04 +0900 Subject: [PATCH 16/16] Update package version to 0.6.9 Change-Id: Icd5c86ef6322b10724987fc7ccca4868ec5d90d6 --- packaging/libscl-core.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libscl-core.spec b/packaging/libscl-core.spec index 9d4a14f..2568044 100644 --- a/packaging/libscl-core.spec +++ b/packaging/libscl-core.spec @@ -8,7 +8,7 @@ Name: libscl-core Summary: A library for developing software keyboards -Version: 0.6.8 +Version: 0.6.9 Release: 1 Group: Graphics & UI Framework/Input License: Apache-2.0 -- 2.7.4