#include <libwebsockets.h>
+#ifdef WAYLAND
+#include <Ecore_Wayland.h>
+#endif
+
#define WEBSOCKET_PORT 7681
#define RECVED_MESSAGE "recved"
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<ISE_MESSAGE>& 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)
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;
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<ISE_MESSAGE>& 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;
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;
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);
}
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[] = {
"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,
}
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 {