From 8cb295fc5efc4898491dd89927e57a7c0c83cad4 Mon Sep 17 00:00:00 2001 From: Ji-hoon Lee Date: Wed, 27 Jul 2016 10:18:37 +0900 Subject: [PATCH] Added MessageQueue concept for handling sync messages Change-Id: Ie47192e77e937107e5e6392301beaa4cfa8c3988 --- ism/src/Makefile.am | 3 +- ism/src/isf_message_queue.h | 1562 +++++++++++++++++++++++++++++++++++++++++++ ism/src/scim_helper.cpp | 1164 +++++++++++++++----------------- ism/src/scim_helper.h | 20 + 4 files changed, 2140 insertions(+), 609 deletions(-) create mode 100644 ism/src/isf_message_queue.h diff --git a/ism/src/Makefile.am b/ism/src/Makefile.am index 9d68c1a..f4e7677 100644 --- a/ism/src/Makefile.am +++ b/ism/src/Makefile.am @@ -96,7 +96,8 @@ libsciminclude_HEADERS = scim.h \ isf_panel_agent_manager.h \ isf_info_manager.h \ isf_panel_agent_base.h \ - isf_panel_agent_module.h + isf_panel_agent_module.h \ + isf_message_queue.h noinst_LTLIBRARIES = libltdlc.la libprivilege_checker.la libisf_pkg.la diff --git a/ism/src/isf_message_queue.h b/ism/src/isf_message_queue.h new file mode 100644 index 0000000..31b57d7 --- /dev/null +++ b/ism/src/isf_message_queue.h @@ -0,0 +1,1562 @@ +/* + * ISF(Input Service Framework) + * + * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. + * Copyright (c) 2012-2016 Samsung Electronics Co., Ltd. + * + * Contact: Ji-hoon Lee , Jihoon Kim + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __ISF_MESSAGE_QUEUE_H +#define __ISF_MESSAGE_QUEUE_H + +#define Uses_SCIM_TRANSACTION +#define Uses_SCIM_TRANS_COMMANDS +#define Uses_SCIM_HELPER +#define Uses_SCIM_SOCKET +#define Uses_SCIM_EVENT +#define Uses_SCIM_BACKEND +#define Uses_SCIM_IMENGINE_MODULE + +#include +#include + +#include "scim_private.h" +#include "scim.h" +#include +#include "isf_query_utility.h" +#include +#include "isf_debug.h" + +#ifdef LOG_TAG +# undef LOG_TAG +#endif +#define LOG_TAG "ISF_MESSAGE_QUEUE" + +namespace scim { + +class MessageItem +{ +public: + MessageItem() : m_command(0) {} + virtual ~MessageItem() {} + + int& get_command_ref() { return m_command; } +protected: + int m_command; +}; + +class MessageItemHelper : public MessageItem +{ +public: + MessageItemHelper() : m_ic(0) {} + virtual ~MessageItemHelper() {} + + uint32& get_ic_ref() { return m_ic; } + String& get_ic_uuid_ref() { return m_ic_uuid; } +protected: + uint32 m_ic; + String m_ic_uuid; +}; + +/* SCIM_TRANS_CMD_EXIT */ +class MessageItemExit : public MessageItemHelper +{ +}; + +/* SCIM_TRANS_CMD_RELOAD_CONFIG */ +class MessageItemReloadConfig : public MessageItemHelper +{ +}; + +/* SCIM_TRANS_CMD_UPDATE_SCREEN */ +class MessageItemUpdateScreen : public MessageItemHelper +{ +public: + MessageItemUpdateScreen() : m_screen(0) {} + virtual ~MessageItemUpdateScreen() {} + + uint32& get_screen_ref() { return m_screen; } +protected: + uint32 m_screen; +}; + +/* SCIM_TRANS_CMD_UPDATE_SPOT_LOCATION */ +class MessageItemUpdateSpotLocation : public MessageItemHelper +{ +public: + MessageItemUpdateSpotLocation() : m_x(0), m_y(0) {} + virtual ~MessageItemUpdateSpotLocation() {} + + uint32& get_x_ref() { return m_x; } + uint32& get_y_ref() { return m_y; } + +protected: + uint32 m_x; + uint32 m_y; +}; + +/* ISM_TRANS_CMD_UPDATE_CURSOR_POSITION */ +class MessageItemUpdateCursorPosition : public MessageItemHelper +{ +public: + MessageItemUpdateCursorPosition() : m_cursor_pos(0) {} + virtual ~MessageItemUpdateCursorPosition() {} + + uint32& get_cursor_pos_ref() { return m_cursor_pos; } +protected: + uint32 m_cursor_pos; +}; + +/* ISM_TRANS_CMD_UPDATE_SURROUNDING_TEXT */ +class MessageItemUpdateSurroundingText : public MessageItemHelper +{ +public: + MessageItemUpdateSurroundingText() : m_cursor(0) {} + virtual ~MessageItemUpdateSurroundingText() {} + + String& get_text_ref() { return m_text; } + uint32& get_cursor_ref() { return m_cursor; } +protected: + String m_text; + uint32 m_cursor; +}; + +/* ISM_TRANS_CMD_UPDATE_SELECTION */ +class MessageItemUpdateSelection : public MessageItemHelper +{ +public: + MessageItemUpdateSelection() {} + virtual ~MessageItemUpdateSelection() {} + + String& get_text_ref() { return m_text; } +protected: + String m_text; + +}; + +/* SCIM_TRANS_CMD_TRIGGER_PROPERTY */ +class MessageItemTriggerProperty : public MessageItemHelper +{ +public: + MessageItemTriggerProperty() {} + virtual ~MessageItemTriggerProperty() {} + + String& get_property_ref() { return m_property; } +protected: + String m_property; + +}; + +/* SCIM_TRANS_CMD_HELPER_PROCESS_IMENGINE_EVENT */ +class MessageItemHelperProcessImengineEvent : public MessageItemHelper +{ +public: + MessageItemHelperProcessImengineEvent() {} + virtual ~MessageItemHelperProcessImengineEvent() {} + + Transaction& get_transaction_ref() { return m_trans; } +protected: + Transaction m_trans; +}; + +/* SCIM_TRANS_CMD_HELPER_ATTACH_INPUT_CONTEXT */ +class MessageItemHelperAttachInputContext : public MessageItemHelper +{ +}; + +/* SCIM_TRANS_CMD_HELPER_DETACH_INPUT_CONTEXT */ +class MessageItemHelperDetachInputContext : public MessageItemHelper +{ +}; + +/* SCIM_TRANS_CMD_FOCUS_OUT */ +class MessageItemFocusOut : public MessageItemHelper +{ +}; + +/* SCIM_TRANS_CMD_FOCUS_IN */ +class MessageItemFocusIn : public MessageItemHelper +{ +}; + +/* ISM_TRANS_CMD_SHOW_ISE_PANEL */ +class MessageItemShowISEPanel : public MessageItemHelper +{ +public: + MessageItemShowISEPanel() : m_data(NULL), m_len(0) {} + virtual ~MessageItemShowISEPanel() { if (m_data) delete[] m_data; m_data = NULL; } + + char** get_data_ptr() { return &m_data; } + size_t& get_len_ref() { return m_len; } +protected: + char* m_data; + size_t m_len; +}; + +/* ISM_TRANS_CMD_HIDE_ISE_PANEL */ +class MessageItemHideISEPanel : public MessageItemHelper +{ +}; + +// ISM_TRANS_CMD_GET_ACTIVE_ISE_GEOMETRY +class MessageItemGetActiveISEGeometry : public MessageItemHelper +{ +}; + +/* ISM_TRANS_CMD_SET_ISE_MODE */ +class MessageItemSetISEMode : public MessageItemHelper +{ +public: + MessageItemSetISEMode() : m_mode(0) {} + virtual ~MessageItemSetISEMode() {} + + uint32& get_mode_ref() { return m_mode; } +protected: + uint32 m_mode; +}; + +/* ISM_TRANS_CMD_SET_ISE_LANGUAGE */ +class MessageItemSetISELanguage : public MessageItemHelper +{ +public: + MessageItemSetISELanguage() : m_language(0) {} + virtual ~MessageItemSetISELanguage() {} + + uint32& get_language_ref() { return m_language; } +protected: + uint32 m_language; +}; + +/* ISM_TRANS_CMD_SET_ISE_IMDATA */ +class MessageItemSetISEImData : public MessageItemHelper +{ +public: + MessageItemSetISEImData() : m_imdata(NULL), m_len(0) {} + virtual ~MessageItemSetISEImData() { if (m_imdata) delete[] m_imdata; m_imdata = NULL; } + + char** get_imdata_ptr() { return &m_imdata; } + size_t& get_len_ref() { return m_len; } +protected: + char* m_imdata; + size_t m_len; +}; + +/* ISM_TRANS_CMD_GET_ISE_IMDATA */ +class MessageItemGetISEImdata : public MessageItemHelper +{ +}; + +/* ISM_TRANS_CMD_GET_ISE_LANGUAGE_LOCALE */ +class MessageItemGetISELanguageLocale : public MessageItemHelper +{ +}; + +/* ISM_TRANS_CMD_SET_RETURN_KEY_TYPE */ +class MessageItemSetReturnKeyType : public MessageItemHelper +{ +public: + MessageItemSetReturnKeyType() : m_type(0) {} + virtual ~MessageItemSetReturnKeyType() {} + + uint32& get_type_ref() { return m_type; } +protected: + uint32 m_type; +}; + +/* ISM_TRANS_CMD_GET_RETURN_KEY_TYPE */ +class MessageItemGetReturnKeyType : public MessageItemHelper +{ +public: + MessageItemGetReturnKeyType() : m_type(0) {} + virtual ~MessageItemGetReturnKeyType() {} + + uint32& get_type_ref() { return m_type; } +protected: + uint32 m_type; +}; + +/* ISM_TRANS_CMD_SET_RETURN_KEY_DISABLE */ +class MessageItemSetReturnKeyDisable : public MessageItemHelper +{ +public: + MessageItemSetReturnKeyDisable() : m_disabled(0) {} + virtual ~MessageItemSetReturnKeyDisable() {} + + uint32& get_disabled_ref() { return m_disabled; } +protected: + uint32 m_disabled; +}; + +/* ISM_TRANS_CMD_GET_RETURN_KEY_DISABLE */ +class MessageItemGetReturnKeyDisable : public MessageItemHelper +{ +public: + MessageItemGetReturnKeyDisable() : m_disabled(0) {} + virtual ~MessageItemGetReturnKeyDisable() {} + + uint32& get_disabled_ref() { return m_disabled; } +protected: + uint32 m_disabled; +}; + +/* SCIM_TRANS_CMD_PROCESS_KEY_EVENT */ +class MessageItemProcessKeyEvent : public MessageItemHelper +{ +public: + MessageItemProcessKeyEvent() : m_serial(0) {} + virtual ~MessageItemProcessKeyEvent() {} + + KeyEvent& get_key_ref() { return m_key; } + uint32& get_serial_ref() { return m_serial; } +protected: + KeyEvent m_key; + uint32 m_serial; +}; + +/* ISM_TRANS_CMD_SET_LAYOUT */ +class MessageItemSetLayout : public MessageItemHelper +{ +public: + MessageItemSetLayout() : m_layout(0) {} + virtual ~MessageItemSetLayout() {} + + uint32& get_layout_ref() { return m_layout; } +protected: + uint32 m_layout; +}; + +/* ISM_TRANS_CMD_GET_LAYOUT */ +class MessageItemGetLayout : public MessageItemHelper +{ +public: + MessageItemGetLayout() : m_layout(0) {} + virtual ~MessageItemGetLayout() {} + + uint32& get_layout_ref() { return m_layout; } +protected: + uint32 m_layout; +}; + +/* ISM_TRANS_CMD_SET_INPUT_MODE */ +class MessageItemSetInputMode : public MessageItemHelper +{ +public: + MessageItemSetInputMode() : m_input_mode(0) {} + virtual ~MessageItemSetInputMode() {} + + uint32& get_input_mode_ref() { return m_input_mode; } +protected: + uint32 m_input_mode; +}; + +/* ISM_TRANS_CMD_SET_CAPS_MODE */ +class MessageItemSetCapsMode : public MessageItemHelper +{ +public: + MessageItemSetCapsMode() : m_mode(0) {} + virtual ~MessageItemSetCapsMode() {} + + uint32& get_mode_ref() { return m_mode; } +protected: + uint32 m_mode; +}; + +/* SCIM_TRANS_CMD_PANEL_RESET_INPUT_CONTEXT */ +class MessageItemPanelResetInputContext : public MessageItemHelper +{ +}; + +/* ISM_TRANS_CMD_UPDATE_CANDIDATE_UI */ +class MessageItemUpdateCandidateUI : public MessageItemHelper +{ +public: + MessageItemUpdateCandidateUI() : m_style(0), m_mode(0) {} + virtual ~MessageItemUpdateCandidateUI() {} + + uint32& get_style_ref() { return m_style; } + uint32& get_mode_ref() { return m_mode; } +protected: + uint32 m_style; + uint32 m_mode; +}; + +/* ISM_TRANS_CMD_UPDATE_CANDIDATE_GEOMETRY */ +class MessageItemUpdateCandidateGeometry : public MessageItemHelper +{ +public: + MessageItemUpdateCandidateGeometry() {} + virtual ~MessageItemUpdateCandidateGeometry() {} + + struct rectinfo& get_rectinfo_ref() { return m_info; } +protected: + struct rectinfo m_info; +}; + +/* ISM_TRANS_CMD_UPDATE_KEYBOARD_ISE */ +class MessageItemUpdateKeyboardISE : public MessageItemHelper +{ +public: + MessageItemUpdateKeyboardISE() {} + virtual ~MessageItemUpdateKeyboardISE() {} + + String& get_name_ref() { return m_name; } + String& get_uuid_ref() { return m_uuid; } +protected: + String m_name; + String m_uuid; +}; + +/* ISM_TRANS_CMD_UPDATE_KEYBOARD_ISE_LIST */ +class MessageItemUpdateKeyboardISEList : public MessageItemHelper +{ +public: + MessageItemUpdateKeyboardISEList() {} + virtual ~MessageItemUpdateKeyboardISEList() {} + + std::vector& get_list_ref() { return m_list; } +protected: + std::vector m_list; +}; + +/* ISM_TRANS_CMD_CANDIDATE_MORE_WINDOW_SHOW */ +class MessageItemCandidateMoreWindowShow : public MessageItemHelper +{ +}; + +/* ISM_TRANS_CMD_CANDIDATE_MORE_WINDOW_HIDE */ +class MessageItemCandidateMoreWindowHide : public MessageItemHelper +{ +}; + +/* ISM_TRANS_CMD_SELECT_AUX */ +class MessageItemSelectAux : public MessageItemHelper +{ +public: + MessageItemSelectAux() : m_item(0) {} + virtual ~MessageItemSelectAux() {} + + uint32& get_item_ref() { return m_item; } +protected: + uint32 m_item; +}; + +/* SCIM_TRANS_CMD_SELECT_CANDIDATE */ +class MessageItemSelectCandidate : public MessageItemHelper +{ +public: + MessageItemSelectCandidate() : m_item(0) {} + virtual ~MessageItemSelectCandidate() {} + + uint32& get_item_ref() { return m_item; } +protected: + uint32 m_item; +}; + +/* SCIM_TRANS_CMD_LOOKUP_TABLE_PAGE_UP */ +class MessageItemLookupTablePageUp : public MessageItemHelper +{ +}; + +/* SCIM_TRANS_CMD_LOOKUP_TABLE_PAGE_DOWN */ +class MessageItemLookupTablePageDown : public MessageItemHelper +{ +}; + +/* SCIM_TRANS_CMD_UPDATE_LOOKUP_TABLE_PAGE_SIZE: */ +class MessageItemUpdateLookupTablePageSize : public MessageItemHelper +{ +public: + MessageItemUpdateLookupTablePageSize() : m_size(0) {} + virtual ~MessageItemUpdateLookupTablePageSize() {} + + uint32& get_size_ref() { return m_size; } +protected: + uint32 m_size; +}; + +/* ISM_TRANS_CMD_CANDIDATE_SHOW */ +class MessageItemCandidateShow : public MessageItemHelper +{ +}; + +/* ISM_TRANS_CMD_CANDIDATE_HIDE */ +class MessageItemCandidateHide : public MessageItemHelper +{ +}; + +/* ISM_TRANS_CMD_UPDATE_LOOKUP_TABLE */ +class MessageItemUpdateLookupTable : public MessageItemHelper +{ +public: + MessageItemUpdateLookupTable() {} + virtual ~MessageItemUpdateLookupTable() {} + + CommonLookupTable& get_candidate_table_ref() { return m_helper_candidate_table; } +protected: + CommonLookupTable m_helper_candidate_table; +}; + +/* ISM_TRANS_CMD_UPDATE_CANDIDATE_ITEM_LAYOUT */ +class MessageItemUpdateCandidateItemLayout : public MessageItemHelper +{ +public: + MessageItemUpdateCandidateItemLayout() {} + virtual ~MessageItemUpdateCandidateItemLayout() {} + + std::vector& get_row_items_ref() { return m_row_items; } +protected: + std::vector m_row_items; +}; + +/* ISM_TRANS_CMD_SELECT_ASSOCIATE: */ +class MessageItemSelectAssociate : public MessageItemHelper +{ +public: + MessageItemSelectAssociate() : m_item(0) {} + virtual ~MessageItemSelectAssociate() {} + + uint32& get_item_ref() { return m_item; } +protected: + uint32 m_item; +}; + +/* ISM_TRANS_CMD_ASSOCIATE_TABLE_PAGE_UP */ +class MessageItemAssociateTablePageUp : public MessageItemHelper +{ +}; + +/* ISM_TRANS_CMD_ASSOCIATE_TABLE_PAGE_DOWN */ +class MessageItemAssociateTablePageDown : public MessageItemHelper +{ +}; + +/* ISM_TRANS_CMD_UPDATE_ASSOCIATE_TABLE_PAGE_SIZE */ +class MessageItemUpdateAssociateTablePageSize : public MessageItemHelper +{ +public: + MessageItemUpdateAssociateTablePageSize() : m_size(0) {} + virtual ~MessageItemUpdateAssociateTablePageSize() {} + + uint32& get_size_ref() { return m_size; } +protected: + uint32 m_size; +}; + +/* ISM_TRANS_CMD_RESET_ISE_CONTEXT */ +class MessageItemResetISEContext : public MessageItemHelper +{ +}; + +/* ISM_TRANS_CMD_TURN_ON_LOG */ +class MessageItemTurnOnLog : public MessageItemHelper +{ +public: + MessageItemTurnOnLog() : m_state(0) {} + virtual ~MessageItemTurnOnLog() {} + + uint32& get_state_ref() { return m_state; } +protected: + uint32 m_state; +}; + +/* ISM_TRANS_CMD_UPDATE_DISPLAYED_CANDIDATE */ +class MessageItemUpdateDisplayedCandidate : public MessageItemHelper +{ +public: + MessageItemUpdateDisplayedCandidate() : m_size(0) {} + virtual ~MessageItemUpdateDisplayedCandidate() {} + + uint32& get_size_ref() { return m_size; } +protected: + uint32 m_size; +}; + +/* ISM_TRANS_CMD_LONGPRESS_CANDIDATE */ +class MessageItemLongpressCandidate : public MessageItemHelper +{ +public: + MessageItemLongpressCandidate() : m_index(0) {} + virtual ~MessageItemLongpressCandidate() {} + + uint32& get_index_ref() { return m_index; } +protected: + uint32 m_index; +}; + +/* ISM_TRANS_CMD_SET_INPUT_HINT */ +class MessageItemSetInputHint : public MessageItemHelper +{ +public: + MessageItemSetInputHint() : m_input_hint(0) {} + virtual ~MessageItemSetInputHint() {} + + uint32& get_input_hint_ref() { return m_input_hint; } +protected: + uint32 m_input_hint; +}; + +/* ISM_TRANS_CMD_UPDATE_BIDI_DIRECTION */ +class MessageItemUpdateBidiDirection : public MessageItemHelper +{ +public: + MessageItemUpdateBidiDirection() : m_bidi_direction(0) {} + virtual ~MessageItemUpdateBidiDirection() {} + + uint32& get_bidi_direction() { return m_bidi_direction; } +protected: + uint32 m_bidi_direction; +}; + +/* ISM_TRANS_CMD_SHOW_ISE_OPTION_WINDOW */ +class MessageItemShowISEOptionWindow : public MessageItemHelper +{ +}; + +/* ISM_TRANS_CMD_CHECK_OPTION_WINDOW */ +class MessageItemCheckOptionWindow : public MessageItemHelper +{ +public: + MessageItemCheckOptionWindow() : m_avail(0) {} + virtual ~MessageItemCheckOptionWindow() {} + + uint32& get_avail_ref() { return m_avail; } +protected: + uint32 m_avail; +}; + +/* ISM_TRANS_CMD_PROCESS_INPUT_DEVICE_EVENT */ +class MessageItemProcessInputDeviceEvent : public MessageItemHelper +{ +public: + MessageItemProcessInputDeviceEvent() : m_type(0), m_data(NULL), m_len(0) {} + virtual ~MessageItemProcessInputDeviceEvent() {} + + uint32& get_type_ref() { return m_type; } + char** get_data_ptr() { return &m_data; } + size_t& get_len_ref() { return m_len; } +protected: + uint32 m_type; + char* m_data; + size_t m_len; +}; + +/* SCIM_TRANS_CMD_SET_AUTOCAPITAL_TYPE */ +class MessageItemSetAutocapitalType : public MessageItemHelper +{ +public: + MessageItemSetAutocapitalType() : m_auto_capital_type(0) {} + virtual ~MessageItemSetAutocapitalType() {} + + uint32& get_auto_capital_type_ref() { return m_auto_capital_type; } +protected: + uint32 m_auto_capital_type; +}; + +template +inline T* +alloc_message() /* We could use memory pool in the future for performance enhancement */ +{ + return new T; +} + +template +inline void +dealloc_message(T* ptr) /* We could use memory pool in the future for performance enhancement */ +{ + if (ptr) delete ptr; +} + +class MessageQueue +{ +public: + MessageQueue() {} + virtual ~MessageQueue() { destroy(); } + + void create() + { + + } + void destroy() + { + for (MESSAGE_LIST::iterator iter = m_list_messages.begin(); + iter != m_list_messages.end(); advance(iter, 1)) { + /* Here we are using MessageItem type template deallocator, should be cautious when using memory pool */ + dealloc_message(*iter); + } + m_list_messages.clear(); + } + + bool has_pending_message() { + return (m_list_messages.size() > 0); + } + + MessageItem* get_pending_message() + { + MessageItem* ret = NULL; + if (!m_list_messages.empty()) { + ret = m_list_messages.front(); + } + return ret; + } + + MessageItem* get_pending_message_by_cmd(int cmd) + { + MessageItem* ret = NULL; + for (MESSAGE_LIST::iterator iter = m_list_messages.begin(); + !ret && iter != m_list_messages.end(); advance(iter, 1)) { + if ((*iter)->get_command_ref() == cmd) { + ret = (*iter); + } + } + return ret; + } + + void remove_message(MessageItem *message) + { + if (message) { + for (MESSAGE_LIST::iterator iter = m_list_messages.begin(); + iter != m_list_messages.end(); advance(iter, 1)) { + if ((*iter) == message) { + iter = m_list_messages.erase(iter); + } + } + /* Here we are using MessageItem type template deallocator, should be cautious when using memory pool */ + dealloc_message(message); + } + return; + } + + bool read_from_transaction(scim::Transaction &transaction) + { + int cmd; + + uint32 ic = (uint32)-1; + String ic_uuid; + + if (!transaction.get_command(cmd) || cmd != SCIM_TRANS_CMD_REPLY) { + LOGW("wrong format of transaction\n"); + return true; + } + + /* If there are ic and ic_uuid then read them. */ + if (!(transaction.get_data_type() == SCIM_TRANS_DATA_COMMAND) && + !(transaction.get_data(ic) && transaction.get_data(ic_uuid))) { + LOGW("wrong format of transaction\n"); + return true; + } + + while (transaction.get_command(cmd)) { + switch (cmd) { + case SCIM_TRANS_CMD_EXIT: + { + MessageItemExit *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + message->get_ic_ref() = ic; + message->get_ic_uuid_ref() = ic_uuid; + m_list_messages.push_back(message); + } + break; + } + case SCIM_TRANS_CMD_RELOAD_CONFIG: + { + MessageItemReloadConfig *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + message->get_ic_ref() = ic; + message->get_ic_uuid_ref() = ic_uuid; + m_list_messages.push_back(message); + } + break; + } + case SCIM_TRANS_CMD_UPDATE_SCREEN: + { + MessageItemUpdateScreen *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + if (transaction.get_data(message->get_screen_ref())) { + message->get_ic_ref() = ic; + message->get_ic_uuid_ref() = ic_uuid; + m_list_messages.push_back(message); + } else { + LOGW("wrong format of transaction\n"); + dealloc_message(message); + } + } + break; + } + case SCIM_TRANS_CMD_UPDATE_SPOT_LOCATION: + { + MessageItemUpdateSpotLocation *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + if (transaction.get_data(message->get_x_ref()) && transaction.get_data(message->get_y_ref())) { + message->get_ic_ref() = ic; + message->get_ic_uuid_ref() = ic_uuid; + m_list_messages.push_back(message); + } else { + LOGW("wrong format of transaction\n"); + dealloc_message(message); + } + } + break; + } + case ISM_TRANS_CMD_UPDATE_CURSOR_POSITION: + { + MessageItemUpdateCursorPosition *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + if (transaction.get_data(message->get_cursor_pos_ref())) { + message->get_ic_ref() = ic; + message->get_ic_uuid_ref() = ic_uuid; + m_list_messages.push_back(message); + } else { + LOGW("wrong format of transaction\n"); + dealloc_message(message); + } + } + break; + } + case ISM_TRANS_CMD_UPDATE_SURROUNDING_TEXT: + { + MessageItemUpdateSurroundingText *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + if (transaction.get_data(message->get_text_ref()) && + transaction.get_data(message->get_cursor_ref())) { + message->get_ic_ref() = ic; + m_list_messages.push_back(message); + } else { + LOGW("wrong format of transaction\n"); + dealloc_message(message); + } + } + break; + } + case ISM_TRANS_CMD_UPDATE_SELECTION: + { + MessageItemUpdateSelection *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + if (transaction.get_data(message->get_text_ref())) { + message->get_ic_ref() = ic; + m_list_messages.push_back(message); + } else { + LOGW("wrong format of transaction\n"); + dealloc_message(message); + } + } + break; + } + case SCIM_TRANS_CMD_TRIGGER_PROPERTY: + { + MessageItemTriggerProperty *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + if (transaction.get_data(message->get_property_ref())) { + m_list_messages.push_back(message); + } else { + LOGW("wrong format of transaction\n"); + dealloc_message(message); + } + } + break; + } + case SCIM_TRANS_CMD_HELPER_PROCESS_IMENGINE_EVENT: + { + MessageItemHelperProcessImengineEvent *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + if (transaction.get_data(message->get_transaction_ref())) { + message->get_ic_ref() = ic; + message->get_ic_uuid_ref() = ic_uuid; + m_list_messages.push_back(message); + } else { + LOGW("wrong format of transaction\n"); + dealloc_message(message); + } + } + break; + } + case SCIM_TRANS_CMD_HELPER_ATTACH_INPUT_CONTEXT: + { + MessageItemHelperAttachInputContext *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + message->get_ic_ref() = ic; + message->get_ic_uuid_ref() = ic_uuid; + m_list_messages.push_back(message); + } + break; + } + case SCIM_TRANS_CMD_HELPER_DETACH_INPUT_CONTEXT: + { + MessageItemHelperDetachInputContext *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + message->get_ic_ref() = ic; + message->get_ic_uuid_ref() = ic_uuid; + m_list_messages.push_back(message); + } + break; + } + case SCIM_TRANS_CMD_FOCUS_OUT: + { + MessageItemFocusOut *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + message->get_ic_ref() = ic; + message->get_ic_uuid_ref() = ic_uuid; + m_list_messages.push_back(message); + } + break; + } + case SCIM_TRANS_CMD_FOCUS_IN: + { + MessageItemFocusIn *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + message->get_ic_ref() = ic; + message->get_ic_uuid_ref() = ic_uuid; + m_list_messages.push_back(message); + } + break; + } + case ISM_TRANS_CMD_SHOW_ISE_PANEL: + { + MessageItemShowISEPanel *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + if (transaction.get_data(message->get_data_ptr(), message->get_len_ref())) { + message->get_ic_ref() = ic; + m_list_messages.push_back(message); + } else { + LOGW("wrong format of transaction\n"); + dealloc_message(message); + } + } + break; + } + case ISM_TRANS_CMD_HIDE_ISE_PANEL: + { + MessageItemHideISEPanel *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + message->get_ic_ref() = ic; + message->get_ic_uuid_ref() = ic_uuid; + m_list_messages.push_back(message); + } + break; + } + case ISM_TRANS_CMD_GET_ACTIVE_ISE_GEOMETRY: + { + MessageItemGetActiveISEGeometry *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + m_list_messages.push_back(message); + } + break; + } + case ISM_TRANS_CMD_SET_ISE_MODE: + { + MessageItemSetISEMode *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + if (transaction.get_data(message->get_mode_ref())) { + m_list_messages.push_back(message); + } else { + LOGW("wrong format of transaction\n"); + dealloc_message(message); + } + } + break; + } + case ISM_TRANS_CMD_SET_ISE_LANGUAGE: + { + MessageItemSetISELanguage *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + if (transaction.get_data(message->get_language_ref())) { + m_list_messages.push_back(message); + } else { + LOGW("wrong format of transaction\n"); + dealloc_message(message); + } + } + break; + } + case ISM_TRANS_CMD_SET_ISE_IMDATA: + { + MessageItemSetISEImData *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + if (transaction.get_data(message->get_imdata_ptr(), message->get_len_ref())) { + m_list_messages.push_back(message); + } else { + LOGW("wrong format of transaction\n"); + dealloc_message(message); + } + } + break; + } + case ISM_TRANS_CMD_GET_ISE_IMDATA: + { + MessageItemGetISEImdata *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + m_list_messages.push_back(message); + } + break; + } + case ISM_TRANS_CMD_GET_ISE_LANGUAGE_LOCALE: + { + MessageItemGetISELanguageLocale *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + m_list_messages.push_back(message); + } + break; + } + case ISM_TRANS_CMD_SET_RETURN_KEY_TYPE: + { + MessageItemSetReturnKeyType *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + if (transaction.get_data(message->get_type_ref())) { + m_list_messages.push_back(message); + } + } + break; + } + case ISM_TRANS_CMD_GET_RETURN_KEY_TYPE: + { + MessageItemGetReturnKeyType *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + m_list_messages.push_back(message); + } + break; + } + case ISM_TRANS_CMD_SET_RETURN_KEY_DISABLE: + { + MessageItemSetReturnKeyDisable *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + if (transaction.get_data(message->get_disabled_ref())) { + m_list_messages.push_back(message); + } else { + LOGW("wrong format of transaction\n"); + dealloc_message(message); + } + } + break; + } + case ISM_TRANS_CMD_GET_RETURN_KEY_DISABLE: + { + MessageItemGetReturnKeyDisable *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + m_list_messages.push_back(message); + } + break; + } + case SCIM_TRANS_CMD_PROCESS_KEY_EVENT: + { + MessageItemProcessKeyEvent *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + if (transaction.get_data(message->get_key_ref()) && + transaction.get_data(message->get_serial_ref())) { + m_list_messages.push_back(message); + } else { + LOGW("wrong format of transaction\n"); + dealloc_message(message); + } + } + break; + } + case ISM_TRANS_CMD_SET_LAYOUT: + { + MessageItemSetLayout *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + if (transaction.get_data(message->get_layout_ref())) { + m_list_messages.push_back(message); + } else { + LOGW("wrong format of transaction\n"); + dealloc_message(message); + } + } + break; + } + case ISM_TRANS_CMD_GET_LAYOUT: + { + MessageItemGetLayout *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + m_list_messages.push_back(message); + } + break; + } + case ISM_TRANS_CMD_SET_INPUT_MODE: + { + MessageItemSetInputMode *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + if (transaction.get_data(message->get_input_mode_ref())) { + m_list_messages.push_back(message); + } else { + LOGW("wrong format of transaction\n"); + dealloc_message(message); + } + } + break; + } + case ISM_TRANS_CMD_SET_CAPS_MODE: + { + MessageItemSetCapsMode *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + if (transaction.get_data(message->get_mode_ref())) { + m_list_messages.push_back(message); + } else { + LOGW("wrong format of transaction\n"); + dealloc_message(message); + } + } + break; + } + case SCIM_TRANS_CMD_PANEL_RESET_INPUT_CONTEXT: + { + MessageItemPanelResetInputContext *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + message->get_ic_ref() = ic; + message->get_ic_uuid_ref() = ic_uuid; + m_list_messages.push_back(message); + } + break; + } + case ISM_TRANS_CMD_UPDATE_CANDIDATE_UI: + { + MessageItemUpdateCandidateUI *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + if (transaction.get_data(message->get_style_ref()) && + transaction.get_data(message->get_mode_ref())) { + message->get_ic_ref() = ic; + message->get_ic_uuid_ref() = ic_uuid; + m_list_messages.push_back(message); + } else { + LOGW("wrong format of transaction\n"); + dealloc_message(message); + } + } + break; + } + case ISM_TRANS_CMD_UPDATE_CANDIDATE_GEOMETRY: + { + MessageItemUpdateCandidateGeometry *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + if (transaction.get_data(message->get_rectinfo_ref().pos_x) + && transaction.get_data(message->get_rectinfo_ref().pos_y) + && transaction.get_data(message->get_rectinfo_ref().width) + && transaction.get_data(message->get_rectinfo_ref().height)) { + message->get_ic_ref() = ic; + message->get_ic_uuid_ref() = ic_uuid; + m_list_messages.push_back(message); + } else { + LOGW("wrong format of transaction\n"); + dealloc_message(message); + } + } + break; + } + case ISM_TRANS_CMD_UPDATE_KEYBOARD_ISE: + { + MessageItemUpdateKeyboardISE *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + String name, uuid; + if (transaction.get_data(message->get_name_ref()) && + transaction.get_data(message->get_uuid_ref())) { + message->get_ic_ref() = ic; + message->get_ic_uuid_ref() = ic_uuid; + m_list_messages.push_back(message); + } else { + LOGW("wrong format of transaction\n"); + dealloc_message(message); + } + } + break; + } + case ISM_TRANS_CMD_UPDATE_KEYBOARD_ISE_LIST: + { + MessageItemUpdateKeyboardISEList *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + uint32 num; + String ise; + if (transaction.get_data(num)) { + for (unsigned int i = 0; i < num; i++) { + if (transaction.get_data(ise)) { + message->get_list_ref().push_back (ise); + } else { + message->get_list_ref().clear (); + break; + } + } + message->get_ic_ref() = ic; + message->get_ic_uuid_ref() = ic_uuid; + m_list_messages.push_back(message); + } else { + LOGW("wrong format of transaction\n"); + dealloc_message(message); + } + } + break; + } + case ISM_TRANS_CMD_CANDIDATE_MORE_WINDOW_SHOW: + { + MessageItemCandidateMoreWindowShow *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + message->get_ic_ref() = ic; + message->get_ic_uuid_ref() = ic_uuid; + m_list_messages.push_back(message); + } + break; + } + case ISM_TRANS_CMD_CANDIDATE_MORE_WINDOW_HIDE: + { + MessageItemCandidateMoreWindowHide *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + message->get_ic_ref() = ic; + message->get_ic_uuid_ref() = ic_uuid; + m_list_messages.push_back(message); + } + break; + } + case ISM_TRANS_CMD_SELECT_AUX: + { + MessageItemSelectAux *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + if (transaction.get_data(message->get_item_ref())) { + message->get_ic_ref() = ic; + message->get_ic_uuid_ref() = ic_uuid; + m_list_messages.push_back(message); + } else { + LOGW("wrong format of transaction\n"); + dealloc_message(message); + } + } + break; + } + case SCIM_TRANS_CMD_SELECT_CANDIDATE: //FIXME:remove if useless + { + MessageItemSelectCandidate *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + if (transaction.get_data(message->get_item_ref())) { + message->get_ic_ref() = ic; + message->get_ic_uuid_ref() = ic_uuid; + m_list_messages.push_back(message); + } else { + LOGW("wrong format of transaction\n"); + dealloc_message(message); + } + } + break; + } + case SCIM_TRANS_CMD_LOOKUP_TABLE_PAGE_UP: //FIXME:remove if useless + { + MessageItemLookupTablePageUp *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + message->get_ic_ref() = ic; + message->get_ic_uuid_ref() = ic_uuid; + m_list_messages.push_back(message); + } + break; + } + case SCIM_TRANS_CMD_LOOKUP_TABLE_PAGE_DOWN: //FIXME:remove if useless + { + MessageItemLookupTablePageDown *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + message->get_ic_ref() = ic; + message->get_ic_uuid_ref() = ic_uuid; + m_list_messages.push_back(message); + } + break; + } + case SCIM_TRANS_CMD_UPDATE_LOOKUP_TABLE_PAGE_SIZE: + { + MessageItemUpdateLookupTablePageSize *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + if (transaction.get_data(message->get_size_ref())) { + message->get_ic_ref() = ic; + message->get_ic_uuid_ref() = ic_uuid; + m_list_messages.push_back(message); + } else { + LOGW("wrong format of transaction\n"); + dealloc_message(message); + } + } + break; + } + case ISM_TRANS_CMD_CANDIDATE_SHOW: //FIXME:remove if useless + { + MessageItemCandidateShow *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + message->get_ic_ref() = ic; + message->get_ic_uuid_ref() = ic_uuid; + m_list_messages.push_back(message); + } + break; + } + case ISM_TRANS_CMD_CANDIDATE_HIDE: //FIXME:remove if useless + { + MessageItemCandidateHide *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + message->get_ic_ref() = ic; + message->get_ic_uuid_ref() = ic_uuid; + m_list_messages.push_back(message); + } + break; + } + case ISM_TRANS_CMD_UPDATE_LOOKUP_TABLE: //FIXME:remove if useless + { + MessageItemUpdateLookupTable *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + if (transaction.get_data(message->get_candidate_table_ref())) { + m_list_messages.push_back(message); + } else { + LOGW("wrong format of transaction\n"); + dealloc_message(message); + } + } + break; + } + case ISM_TRANS_CMD_UPDATE_CANDIDATE_ITEM_LAYOUT: + { + MessageItemUpdateCandidateItemLayout *message = alloc_message(); + if (transaction.get_data(message->get_row_items_ref())) { + m_list_messages.push_back(message); + } else { + LOGW("wrong format of transaction\n"); + dealloc_message(message); + } + break; + } + case ISM_TRANS_CMD_SELECT_ASSOCIATE: + { + MessageItemSelectAssociate *message = alloc_message(); + if (transaction.get_data(message->get_item_ref())) { + message->get_ic_ref() = ic; + message->get_ic_uuid_ref() = ic_uuid; + m_list_messages.push_back(message); + } else { + LOGW("wrong format of transaction\n"); + dealloc_message(message); + } + break; + } + case ISM_TRANS_CMD_ASSOCIATE_TABLE_PAGE_UP: + { + MessageItemAssociateTablePageUp *message = alloc_message(); + message->get_ic_ref() = ic; + message->get_ic_uuid_ref() = ic_uuid; + m_list_messages.push_back(message); + break; + } + case ISM_TRANS_CMD_ASSOCIATE_TABLE_PAGE_DOWN: + { + MessageItemAssociateTablePageDown *message = alloc_message(); + message->get_ic_ref() = ic; + message->get_ic_uuid_ref() = ic_uuid; + m_list_messages.push_back(message); + break; + } + case ISM_TRANS_CMD_UPDATE_ASSOCIATE_TABLE_PAGE_SIZE: + { + MessageItemUpdateAssociateTablePageSize *message = alloc_message(); + if (transaction.get_data(message->get_size_ref())) { + message->get_ic_ref() = ic; + message->get_ic_uuid_ref() = ic_uuid; + m_list_messages.push_back(message); + } else { + LOGW("wrong format of transaction\n"); + dealloc_message(message); + } + break; + } + case ISM_TRANS_CMD_RESET_ISE_CONTEXT: + { + MessageItemResetISEContext *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + message->get_ic_ref() = ic; + message->get_ic_uuid_ref() = ic_uuid; + m_list_messages.push_back(message); + } + break; + } + case ISM_TRANS_CMD_TURN_ON_LOG: + { + MessageItemTurnOnLog *message = alloc_message(); + if (transaction.get_data(message->get_state_ref())) { + m_list_messages.push_back(message); + } else { + LOGW("wrong format of transaction\n"); + dealloc_message(message); + } + break; + } + case ISM_TRANS_CMD_UPDATE_DISPLAYED_CANDIDATE: + { + MessageItemUpdateDisplayedCandidate *message = alloc_message(); + if (transaction.get_data(message->get_size_ref())) { + message->get_ic_ref() = ic; + message->get_ic_uuid_ref() = ic_uuid; + m_list_messages.push_back(message); + } else { + LOGW("wrong format of transaction\n"); + dealloc_message(message); + } + break; + } + case ISM_TRANS_CMD_LONGPRESS_CANDIDATE: + { + MessageItemLongpressCandidate *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + if (transaction.get_data(message->get_index_ref())) { + message->get_ic_ref() = ic; + message->get_ic_uuid_ref() = ic_uuid; + m_list_messages.push_back(message); + } else { + LOGW("wrong format of transaction\n"); + dealloc_message(message); + } + } + break; + } + case ISM_TRANS_CMD_SET_INPUT_HINT: + { + MessageItemSetInputHint *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + if (transaction.get_data(message->get_input_hint_ref())) { + m_list_messages.push_back(message); + } else { + LOGW("wrong format of transaction\n"); + dealloc_message(message); + } + } + break; + } + case ISM_TRANS_CMD_UPDATE_BIDI_DIRECTION: + { + MessageItemUpdateBidiDirection *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + if (transaction.get_data(message->get_bidi_direction())) { + m_list_messages.push_back(message); + } else { + LOGW("wrong format of transaction\n"); + dealloc_message(message); + } + } + break; + } + case ISM_TRANS_CMD_SHOW_ISE_OPTION_WINDOW: + { + MessageItemShowISEOptionWindow *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + message->get_ic_ref() = ic; + message->get_ic_uuid_ref() = ic_uuid; + m_list_messages.push_back(message); + } + break; + } + case ISM_TRANS_CMD_CHECK_OPTION_WINDOW: + { + MessageItemCheckOptionWindow *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + m_list_messages.push_back(message); + } + break; + } + case ISM_TRANS_CMD_PROCESS_INPUT_DEVICE_EVENT: + { + MessageItemProcessInputDeviceEvent *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + if (transaction.get_data(message->get_type_ref()) && + transaction.get_data(message->get_data_ptr(), message->get_len_ref())) { + m_list_messages.push_back(message); + } else { + LOGW("wrong format of transaction\n"); + dealloc_message(message); + } + } + break; + } + case SCIM_TRANS_CMD_SET_AUTOCAPITAL_TYPE: + { + MessageItemSetAutocapitalType *message = alloc_message(); + if (message) { + message->get_command_ref() = cmd; + if (transaction.get_data(message->get_auto_capital_type_ref())) { + m_list_messages.push_back(message); + } else { + LOGW("wrong format of transaction\n"); + dealloc_message(message); + } + } + break; + } + } + } + + return true; + } + +protected: + typedef std::list MESSAGE_LIST; + MESSAGE_LIST m_list_messages; +}; + +} /* namespace scim */ + +#endif /* __ISF_MESSAGE_H */ + +/* +vi:ts=4:expandtab:nowrap +*/ diff --git a/ism/src/scim_helper.cpp b/ism/src/scim_helper.cpp index 83d19a7..27342ab 100644 --- a/ism/src/scim_helper.cpp +++ b/ism/src/scim_helper.cpp @@ -48,6 +48,7 @@ #include #include +#include #include "scim_private.h" #include "scim.h" @@ -55,6 +56,7 @@ #include "isf_query_utility.h" #include #include "isf_debug.h" +#include "isf_message_queue.h" #ifdef LOG_TAG # undef LOG_TAG @@ -539,13 +541,17 @@ private: HelperAgentImpl () : magic (0), magic_active (0), timeout (-1), focused_ic ((uint32) -1) { } }; +static MessageQueue message_queue; + HelperAgent::HelperAgent () : m_impl (new HelperAgentImpl (this)) { + message_queue.create(); } HelperAgent::~HelperAgent () { + message_queue.destroy(); delete m_impl; } @@ -765,6 +771,9 @@ HelperAgent::has_pending_event () const if (m_impl->socket.is_connected () && m_impl->socket.wait_for_data (0) > 0) return true; + if (message_queue.has_pending_message()) + return true; + return false; } @@ -782,620 +791,558 @@ HelperAgent::filter_event () if (!m_impl->socket.is_connected () || !m_impl->recv.read_from_socket (m_impl->socket, m_impl->timeout)) return false; - int cmd; - - uint32 ic = (uint32) -1; - String ic_uuid; + message_queue.read_from_transaction(m_impl->recv); - if (!m_impl->recv.get_command (cmd) || cmd != SCIM_TRANS_CMD_REPLY) { - LOGW ("wrong format of transaction\n"); - return true; + while (message_queue.has_pending_message()) { + MessageItem *message = message_queue.get_pending_message(); + handle_message(message); + message_queue.remove_message(message); } - /* If there are ic and ic_uuid then read them. */ - if (!(m_impl->recv.get_data_type () == SCIM_TRANS_DATA_COMMAND) && - !(m_impl->recv.get_data (ic) && m_impl->recv.get_data (ic_uuid))) { - LOGW ("wrong format of transaction\n"); - return true; - } + return true; +} - while (m_impl->recv.get_command (cmd)) { - LOGD ("HelperAgent::cmd = %d\n", cmd); - switch (cmd) { - case SCIM_TRANS_CMD_EXIT: - ISF_SAVE_LOG ("Helper ISE received SCIM_TRANS_CMD_EXIT message\n"); - m_impl->signal_exit (this, ic, ic_uuid); - break; - case SCIM_TRANS_CMD_RELOAD_CONFIG: - m_impl->signal_reload_config (this, ic, ic_uuid); - if (!m_impl->m_config.null()) - m_impl->m_config->ConfigBase::reload(); - break; - case SCIM_TRANS_CMD_UPDATE_SCREEN: - { - uint32 screen; - if (m_impl->recv.get_data (screen)) - m_impl->signal_update_screen (this, ic, ic_uuid, (int) screen); - else - LOGW ("wrong format of transaction\n"); - break; - } - case SCIM_TRANS_CMD_UPDATE_SPOT_LOCATION: - { - uint32 x, y; - if (m_impl->recv.get_data (x) && m_impl->recv.get_data (y)) - m_impl->signal_update_spot_location (this, ic, ic_uuid, (int) x, (int) y); - else - LOGW ("wrong format of transaction\n"); - break; - } - case ISM_TRANS_CMD_UPDATE_CURSOR_POSITION: - { - uint32 cursor_pos; - if (m_impl->recv.get_data (cursor_pos)) { - m_impl->cursor_pos = cursor_pos; - LOGD ("update cursor position %d", cursor_pos); - m_impl->signal_update_cursor_position (this, ic, ic_uuid, (int) cursor_pos); - if (!m_impl->si.null ()) m_impl->si->update_cursor_position(cursor_pos); - } - else - LOGW ("wrong format of transaction\n"); - break; - } - case ISM_TRANS_CMD_UPDATE_SURROUNDING_TEXT: - { - String text; - uint32 cursor; - if (m_impl->recv.get_data (text) && m_impl->recv.get_data (cursor)) { - if (m_impl->surrounding_text != NULL) - free (m_impl->surrounding_text); - m_impl->surrounding_text = strdup (text.c_str ()); - m_impl->cursor_pos = cursor; - LOGD ("surrounding text: %s, %d", m_impl->surrounding_text, cursor); - while (m_impl->need_update_surrounding_text > 0) { - m_impl->need_update_surrounding_text--; - m_impl->signal_update_surrounding_text (this, ic, text, (int) cursor); - } - } - else - LOGW ("wrong format of transaction\n"); - break; - } - case ISM_TRANS_CMD_UPDATE_SELECTION: - { - String text; - if (m_impl->recv.get_data (text)) { - if (m_impl->selection_text != NULL) - free (m_impl->selection_text); - - m_impl->selection_text = strdup (text.c_str ()); - LOGD ("selection text: %s", m_impl->selection_text); - - while (m_impl->need_update_selection_text > 0) { - m_impl->need_update_selection_text--; - m_impl->signal_update_selection (this, ic, text); - } - } else - LOGW ("wrong format of transaction\n"); - break; - } - case SCIM_TRANS_CMD_TRIGGER_PROPERTY: - { - String property; - if (m_impl->recv.get_data (property)) { - m_impl->signal_trigger_property (this, ic, ic_uuid, property); - if (!m_impl->si.null ()) m_impl->si->trigger_property(property); - } - else - LOGW ("wrong format of transaction\n"); - break; - } - case SCIM_TRANS_CMD_HELPER_PROCESS_IMENGINE_EVENT: - { - Transaction trans; - if (m_impl->recv.get_data (trans)) - m_impl->signal_process_imengine_event (this, ic, ic_uuid, trans); - else - LOGW ("wrong format of transaction\n"); - break; - } - case SCIM_TRANS_CMD_HELPER_ATTACH_INPUT_CONTEXT: - m_impl->signal_attach_input_context (this, ic, ic_uuid); - break; - case SCIM_TRANS_CMD_HELPER_DETACH_INPUT_CONTEXT: - m_impl->signal_detach_input_context (this, ic, ic_uuid); - break; - case SCIM_TRANS_CMD_FOCUS_OUT: - { - m_impl->signal_focus_out (this, ic, ic_uuid); - m_impl->focused_ic = (uint32) -1; - if (!m_impl->si.null ()) m_impl->si->focus_out(); - break; - } - case SCIM_TRANS_CMD_FOCUS_IN: - { - m_impl->signal_focus_in (this, ic, ic_uuid); - m_impl->focused_ic = ic; - if (!m_impl->si.null ()) m_impl->si->focus_in(); - break; - } - case ISM_TRANS_CMD_SHOW_ISE_PANEL: - { - LOGD ("Helper ISE received ISM_TRANS_CMD_SHOW_ISE_PANEL message\n"); - - char *data = NULL; - size_t len; - if (m_impl->recv.get_data (&data, len)) - m_impl->signal_ise_show (this, ic, data, len); - else - LOGW ("wrong format of transaction\n"); - if (data) - delete [] data; - break; - } - case ISM_TRANS_CMD_HIDE_ISE_PANEL: - { - LOGD ("Helper ISE received ISM_TRANS_CMD_HIDE_ISE_PANEL message\n"); - m_impl->signal_ise_hide (this, ic, ic_uuid); - break; - } - case ISM_TRANS_CMD_GET_ACTIVE_ISE_GEOMETRY: - { - struct rectinfo info = {0, 0, 0, 0}; - m_impl->signal_get_geometry (this, info); - m_impl->send.clear (); - m_impl->send.put_command (SCIM_TRANS_CMD_REPLY); - m_impl->send.put_data (info.pos_x); - m_impl->send.put_data (info.pos_y); - m_impl->send.put_data (info.width); - m_impl->send.put_data (info.height); - m_impl->send.write_to_socket (m_impl->socket); - break; - } - case ISM_TRANS_CMD_SET_ISE_MODE: - { - uint32 mode; - if (m_impl->recv.get_data (mode)) - m_impl->signal_set_mode (this, mode); - else - LOGW ("wrong format of transaction\n"); - break; - } - case ISM_TRANS_CMD_SET_ISE_LANGUAGE: - { - uint32 language; - if (m_impl->recv.get_data (language)) - m_impl->signal_set_language (this, language); - else - LOGW ("wrong format of transaction\n"); - break; - } - case ISM_TRANS_CMD_SET_ISE_IMDATA: - { - char *imdata = NULL; - size_t len; - if (m_impl->recv.get_data (&imdata, len)) { - m_impl->signal_set_imdata (this, imdata, len); - if (!m_impl->si.null ()) m_impl->si->set_imdata(imdata, len); - } - else - LOGW ("wrong format of transaction\n"); - if (NULL != imdata) - delete[] imdata; - break; - } - case ISM_TRANS_CMD_GET_ISE_IMDATA: - { - char *buf = NULL; - size_t len = 0; - - m_impl->signal_get_imdata (this, &buf, len); - LOGD ("send ise imdata len = %d", len); - m_impl->send.clear (); - m_impl->send.put_command (SCIM_TRANS_CMD_REPLY); - m_impl->send.put_data (buf, len); - m_impl->send.write_to_socket (m_impl->socket); - if (NULL != buf) - delete[] buf; - break; - } - case ISM_TRANS_CMD_GET_ISE_LANGUAGE_LOCALE: - { - char *buf = NULL; - m_impl->signal_get_language_locale (this, ic, &buf); - m_impl->send.clear (); - m_impl->send.put_command (SCIM_TRANS_CMD_REPLY); - if (buf != NULL) - m_impl->send.put_data (buf, strlen (buf)); - m_impl->send.write_to_socket (m_impl->socket); - if (NULL != buf) - delete[] buf; - break; - } - case ISM_TRANS_CMD_SET_RETURN_KEY_TYPE: - { - uint32 type = 0; - if (m_impl->recv.get_data (type)) { - m_impl->signal_set_return_key_type (this, type); - } - break; - } - case ISM_TRANS_CMD_GET_RETURN_KEY_TYPE: - { - uint32 type = 0; - m_impl->signal_get_return_key_type (this, type); - m_impl->send.clear (); - m_impl->send.put_command (SCIM_TRANS_CMD_REPLY); - m_impl->send.put_data (type); - m_impl->send.write_to_socket (m_impl->socket); - break; - } - case ISM_TRANS_CMD_SET_RETURN_KEY_DISABLE: - { - uint32 disabled = 0; - if (m_impl->recv.get_data (disabled)) { - m_impl->signal_set_return_key_disable (this, disabled); - } - else - LOGW ("wrong format of transaction\n"); - break; - } - case ISM_TRANS_CMD_GET_RETURN_KEY_DISABLE: - { - uint32 disabled = 0; - m_impl->signal_get_return_key_type (this, disabled); - m_impl->send.clear (); - m_impl->send.put_command (SCIM_TRANS_CMD_REPLY); - m_impl->send.put_data (disabled); - m_impl->send.write_to_socket (m_impl->socket); - break; - } - case SCIM_TRANS_CMD_PROCESS_KEY_EVENT: - { - KeyEvent key; - uint32 ret = 0; - uint32 serial = 0; - if (m_impl->recv.get_data (key) && m_impl->recv.get_data (serial)) { - m_impl->signal_process_key_event(this, key, ret); - if (ret == 0) - if (!m_impl->si.null ()) - { - ret = m_impl->si->process_key_event (key); - LOGD("imengine(%s) process key %d return %d", m_impl->si->get_factory_uuid().c_str(), key.code, ret); - } - m_impl->process_key_event_done (key, ret, serial); - } - else - LOGW ("wrong format of transaction\n"); - break; - } - case ISM_TRANS_CMD_SET_LAYOUT: - { - uint32 layout; - - if (m_impl->recv.get_data (layout)) { - m_impl->layout = layout; - m_impl->signal_set_layout (this, layout); - if (!m_impl->si.null ()) m_impl->si->set_layout(layout); - } - else - LOGW ("wrong format of transaction\n"); - break; - } - case ISM_TRANS_CMD_GET_LAYOUT: - { - uint32 layout = 0; - - m_impl->signal_get_layout (this, layout); - m_impl->send.clear (); - m_impl->send.put_command (SCIM_TRANS_CMD_REPLY); - m_impl->send.put_data (layout); - m_impl->send.write_to_socket (m_impl->socket); - break; - } - case ISM_TRANS_CMD_SET_INPUT_MODE: - { - uint32 input_mode; - - if (m_impl->recv.get_data (input_mode)) - m_impl->signal_set_input_mode (this, input_mode); - else - LOGW ("wrong format of transaction\n"); - break; - } - case ISM_TRANS_CMD_SET_CAPS_MODE: - { - uint32 mode; - - if (m_impl->recv.get_data (mode)) - m_impl->signal_set_caps_mode (this, mode); - else - LOGW ("wrong format of transaction\n"); - break; - } - case SCIM_TRANS_CMD_PANEL_RESET_INPUT_CONTEXT: - { - m_impl->signal_reset_input_context (this, ic, ic_uuid); - if (!m_impl->si.null ()) m_impl->si->reset(); - break; - } - case ISM_TRANS_CMD_UPDATE_CANDIDATE_UI: - { - uint32 style, mode; - if (m_impl->recv.get_data (style) && m_impl->recv.get_data (mode)) - m_impl->signal_update_candidate_ui (this, ic, ic_uuid, style, mode); - else - LOGW ("wrong format of transaction\n"); - break; - } - case ISM_TRANS_CMD_UPDATE_CANDIDATE_GEOMETRY: - { - struct rectinfo info = {0, 0, 0, 0}; - if (m_impl->recv.get_data (info.pos_x) - && m_impl->recv.get_data (info.pos_y) - && m_impl->recv.get_data (info.width) - && m_impl->recv.get_data (info.height)) - m_impl->signal_update_candidate_geometry (this, ic, ic_uuid, info); - else - LOGW ("wrong format of transaction\n"); - break; - } - case ISM_TRANS_CMD_UPDATE_KEYBOARD_ISE: - { - String name, uuid; - if (m_impl->recv.get_data (name) && m_impl->recv.get_data (uuid)) - m_impl->signal_update_keyboard_ise (this, ic, ic_uuid, name, uuid); - else - LOGW ("wrong format of transaction\n"); - break; - } - case ISM_TRANS_CMD_UPDATE_KEYBOARD_ISE_LIST: - { - uint32 num; - String ise; - std::vector list; - if (m_impl->recv.get_data (num)) { - for (unsigned int i = 0; i < num; i++) { - if (m_impl->recv.get_data (ise)) { - list.push_back (ise); - } else { - list.clear (); - break; - } - } - m_impl->signal_update_keyboard_ise_list (this, ic, ic_uuid, list); - } - else - LOGW ("wrong format of transaction\n"); - break; - } - case ISM_TRANS_CMD_CANDIDATE_MORE_WINDOW_SHOW: - { - m_impl->signal_candidate_more_window_show (this, ic, ic_uuid); - if (!m_impl->si.null ()) m_impl->si->candidate_more_window_show(); - break; - } - case ISM_TRANS_CMD_CANDIDATE_MORE_WINDOW_HIDE: - { - m_impl->signal_candidate_more_window_hide (this, ic, ic_uuid); - if (!m_impl->si.null ()) m_impl->si->candidate_more_window_hide(); - break; - } - case ISM_TRANS_CMD_SELECT_AUX: - { - uint32 item; - if (m_impl->recv.get_data (item)) { - m_impl->signal_select_aux (this, ic, ic_uuid, item); - if (!m_impl->si.null ()) m_impl->si->select_aux(item); - } - else - LOGW ("wrong format of transaction\n"); - break; - } - case SCIM_TRANS_CMD_SELECT_CANDIDATE: //FIXME:remove if useless - { - uint32 item; - if (m_impl->recv.get_data (item)) - m_impl->signal_select_candidate (this, ic, ic_uuid, item); - else - LOGW ("wrong format of transaction\n"); - if (!m_impl->si.null ()) m_impl->si->select_candidate(item); - break; - } - case SCIM_TRANS_CMD_LOOKUP_TABLE_PAGE_UP: //FIXME:remove if useless - { - m_impl->signal_candidate_table_page_up (this, ic, ic_uuid); - if (!m_impl->si.null ()) m_impl->si->lookup_table_page_up(); - break; - } - case SCIM_TRANS_CMD_LOOKUP_TABLE_PAGE_DOWN: //FIXME:remove if useless - { - m_impl->signal_candidate_table_page_down (this, ic, ic_uuid); - if (!m_impl->si.null ()) m_impl->si->lookup_table_page_down(); - break; - } - case SCIM_TRANS_CMD_UPDATE_LOOKUP_TABLE_PAGE_SIZE: - { - uint32 size; - if (m_impl->recv.get_data (size)) { - m_impl->signal_update_candidate_table_page_size (this, ic, ic_uuid, size); - if (!m_impl->si.null ()) m_impl->si->update_lookup_table_page_size(size); - } - else - LOGW ("wrong format of transaction\n"); - break; - } - case ISM_TRANS_CMD_CANDIDATE_SHOW: //FIXME:remove if useless - { - m_impl->signal_candidate_show (this, ic, ic_uuid); - break; - } - case ISM_TRANS_CMD_CANDIDATE_HIDE: //FIXME:remove if useless - { - m_impl->signal_candidate_hide (this, ic, ic_uuid); - break; - } - case ISM_TRANS_CMD_UPDATE_LOOKUP_TABLE: //FIXME:remove if useless - { - CommonLookupTable helper_candidate_table; - if (m_impl->recv.get_data (helper_candidate_table)) - m_impl->signal_update_lookup_table (this, helper_candidate_table); - else - LOGW ("wrong format of transaction\n"); - break; - } - case ISM_TRANS_CMD_UPDATE_CANDIDATE_ITEM_LAYOUT: - { - std::vector row_items; - if (m_impl->recv.get_data (row_items)) { - m_impl->signal_update_candidate_item_layout (this, row_items); - if (!m_impl->si.null ()) m_impl->si->update_candidate_item_layout(row_items); - } - else - LOGW ("wrong format of transaction\n"); - break; - } - case ISM_TRANS_CMD_SELECT_ASSOCIATE: - { - uint32 item; - if (m_impl->recv.get_data (item)) - m_impl->signal_select_associate (this, ic, ic_uuid, item); - else - LOGW ("wrong format of transaction\n"); - break; - } - case ISM_TRANS_CMD_ASSOCIATE_TABLE_PAGE_UP: - { - m_impl->signal_associate_table_page_up (this, ic, ic_uuid); - break; - } - case ISM_TRANS_CMD_ASSOCIATE_TABLE_PAGE_DOWN: - { - m_impl->signal_associate_table_page_down (this, ic, ic_uuid); - break; - } - case ISM_TRANS_CMD_UPDATE_ASSOCIATE_TABLE_PAGE_SIZE: - { - uint32 size; - if (m_impl->recv.get_data (size)) - m_impl->signal_update_associate_table_page_size (this, ic, ic_uuid, size); - else - LOGW ("wrong format of transaction\n"); - break; - } - case ISM_TRANS_CMD_RESET_ISE_CONTEXT: - { - m_impl->signal_reset_ise_context (this, ic, ic_uuid); - m_impl->signal_reset_input_context (this, ic, ic_uuid); - if (!m_impl->si.null ()) m_impl->si->reset(); - m_impl->send.clear (); - m_impl->send.put_command (SCIM_TRANS_CMD_REPLY); - m_impl->send.write_to_socket (m_impl->socket); - break; - } - case ISM_TRANS_CMD_TURN_ON_LOG: - { - uint32 isOn; - if (m_impl->recv.get_data (isOn)) - m_impl->signal_turn_on_log (this, isOn); - else - LOGW ("wrong format of transaction\n"); - break; - } - case ISM_TRANS_CMD_UPDATE_DISPLAYED_CANDIDATE: - { - uint32 size; - if (m_impl->recv.get_data (size)) { - m_impl->signal_update_displayed_candidate_number (this, ic, ic_uuid, size); - if (!m_impl->si.null ()) m_impl->si->update_displayed_candidate_number(size); - } - else - LOGW ("wrong format of transaction\n"); - break; - } - case ISM_TRANS_CMD_LONGPRESS_CANDIDATE: - { - uint32 index; - if (m_impl->recv.get_data (index)) { - m_impl->signal_longpress_candidate (this, ic, ic_uuid, index); - if (!m_impl->si.null ()) m_impl->si->longpress_candidate(index); - } - else - LOGW ("wrong format of transaction\n"); - break; - } - case ISM_TRANS_CMD_SET_INPUT_HINT: - { - uint32 input_hint; +/** + * @brief Read messages from socket buffer, and see if there is a message with the given cmd. + * + * @return false if the connection is broken, or no message available with given cmd. Otherwise return true. + */ +bool +HelperAgent::wait_for_message(int cmd, int timeout) +{ + struct timeval t0 = { 0, 0 }; + struct timeval t1 = { 0, 0 }; - if (m_impl->recv.get_data (input_hint)) { - m_impl->signal_set_input_hint (this, input_hint); - if (!m_impl->si.null ()) m_impl->si->set_input_hint(input_hint); - } - else - LOGW ("wrong format of transaction\n"); - break; - } - case ISM_TRANS_CMD_UPDATE_BIDI_DIRECTION: - { - uint32 bidi_direction; + gettimeofday(&t0, NULL); + int etime = 0; - if (m_impl->recv.get_data (bidi_direction)) { - m_impl->signal_update_bidi_direction (this, bidi_direction); - if (!m_impl->si.null ()) m_impl->si->update_bidi_direction(bidi_direction); - } - else - LOGW ("wrong format of transaction\n"); - break; - } - case ISM_TRANS_CMD_SHOW_ISE_OPTION_WINDOW: - { - m_impl->signal_show_option_window (this, ic, ic_uuid); - break; - } - case ISM_TRANS_CMD_CHECK_OPTION_WINDOW: - { - uint32 avail = 0; - m_impl->signal_check_option_window (this, avail); - m_impl->send.clear (); - m_impl->send.put_command (SCIM_TRANS_CMD_REPLY); - m_impl->send.put_data (avail); - m_impl->send.write_to_socket (m_impl->socket); - break; + do { + if (!m_impl->socket.is_connected() || !m_impl->recv.read_from_socket(m_impl->socket, timeout)) + return false; + + message_queue.read_from_transaction(m_impl->recv); + if (message_queue.get_pending_message_by_cmd(cmd)) { + return true; + } + + gettimeofday(&t1, NULL); + etime = ((t1.tv_sec * 1000000 + t1.tv_usec) - (t0.tv_sec * 1000000 + t0.tv_usec)) / 1000; + + usleep(100 * 1000); + } while (etime < timeout); + + return false; +} + +/** + * @brief Process one message that is in our message queue. + * + * This function will emit the corresponding signals according + * to the events. + * + * @param message The message that needs to be handled. + * + * @return false if the connection is broken, otherwise return true. + */ +bool +HelperAgent::handle_message (MessageItem *message) +{ + if (!message) + return false; + + int cmd = message->get_command_ref(); + LOGD ("HelperAgent::cmd = %d\n", cmd); + switch (cmd) { + case SCIM_TRANS_CMD_EXIT: + { + MessageItemExit *subclass = static_cast(message); + ISF_SAVE_LOG ("Helper ISE received SCIM_TRANS_CMD_EXIT message\n"); + m_impl->signal_exit(this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref()); + break; + } + case SCIM_TRANS_CMD_RELOAD_CONFIG: + { + MessageItemReloadConfig *subclass = static_cast(message); + m_impl->signal_reload_config (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref()); + if (!m_impl->m_config.null()) + m_impl->m_config->ConfigBase::reload(); + break; + } + case SCIM_TRANS_CMD_UPDATE_SCREEN: + { + MessageItemUpdateScreen *subclass = static_cast(message); + m_impl->signal_update_screen (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(), + subclass->get_screen_ref()); + break; + } + case SCIM_TRANS_CMD_UPDATE_SPOT_LOCATION: + { + MessageItemUpdateSpotLocation *subclass = static_cast(message); + m_impl->signal_update_spot_location (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(), + subclass->get_x_ref(), subclass->get_y_ref()); + break; + } + case ISM_TRANS_CMD_UPDATE_CURSOR_POSITION: + { + MessageItemUpdateCursorPosition *subclass = static_cast(message); + m_impl->cursor_pos = subclass->get_cursor_pos_ref(); + LOGD ("update cursor position %d", subclass->get_cursor_pos_ref()); + m_impl->signal_update_cursor_position (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(), + subclass->get_cursor_pos_ref()); + if (!m_impl->si.null ()) m_impl->si->update_cursor_position(subclass->get_cursor_pos_ref()); + break; + } + case ISM_TRANS_CMD_UPDATE_SURROUNDING_TEXT: + { + MessageItemUpdateSurroundingText *subclass = static_cast(message); + if (m_impl->surrounding_text != NULL) + free (m_impl->surrounding_text); + m_impl->surrounding_text = strdup (subclass->get_text_ref().c_str ()); + m_impl->cursor_pos = subclass->get_cursor_ref(); + LOGD ("surrounding text: %s, %d", m_impl->surrounding_text, subclass->get_cursor_ref()); + while (m_impl->need_update_surrounding_text > 0) { + m_impl->need_update_surrounding_text--; + m_impl->signal_update_surrounding_text (this, subclass->get_ic_ref(), + subclass->get_text_ref(), subclass->get_cursor_ref()); } - case ISM_TRANS_CMD_PROCESS_INPUT_DEVICE_EVENT: - { - uint32 ret = 0; - uint32 type; - char *data = NULL; - size_t len; - if (m_impl->recv.get_data(type) && - m_impl->recv.get_data(&data, len)) { - m_impl->signal_process_input_device_event(this, type, data, len, ret); - } - else - LOGW("wrong format of transaction\n"); - m_impl->send.clear(); - m_impl->send.put_command(SCIM_TRANS_CMD_REPLY); - m_impl->send.put_data(ret); - m_impl->send.write_to_socket(m_impl->socket); - break; + break; + } + case ISM_TRANS_CMD_UPDATE_SELECTION: + { + MessageItemUpdateSelection *subclass = static_cast(message); + if (m_impl->selection_text != NULL) + free (m_impl->selection_text); + + m_impl->selection_text = strdup (subclass->get_text_ref().c_str ()); + LOGD ("selection text: %s", m_impl->selection_text); + + while (m_impl->need_update_selection_text > 0) { + m_impl->need_update_selection_text--; + m_impl->signal_update_selection (this, subclass->get_ic_ref(), subclass->get_text_ref()); } - case SCIM_TRANS_CMD_SET_AUTOCAPITAL_TYPE: - { - uint32 auto_capital_type; + break; + } + case SCIM_TRANS_CMD_TRIGGER_PROPERTY: + { + MessageItemTriggerProperty *subclass = static_cast(message); + m_impl->signal_trigger_property (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(), + subclass->get_property_ref()); + if (!m_impl->si.null ()) m_impl->si->trigger_property(subclass->get_property_ref()); + break; + } + case SCIM_TRANS_CMD_HELPER_PROCESS_IMENGINE_EVENT: + { + MessageItemHelperProcessImengineEvent *subclass = static_cast(message); + m_impl->signal_process_imengine_event (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(), + subclass->get_transaction_ref()); + break; + } + case SCIM_TRANS_CMD_HELPER_ATTACH_INPUT_CONTEXT: + { + MessageItemHelperAttachInputContext *subclass = static_cast(message); + m_impl->signal_attach_input_context (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref()); + break; + } + case SCIM_TRANS_CMD_HELPER_DETACH_INPUT_CONTEXT: + { + MessageItemHelperDetachInputContext *subclass = static_cast(message); + m_impl->signal_detach_input_context (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref()); + break; + } + case SCIM_TRANS_CMD_FOCUS_OUT: + { + MessageItemFocusOut *subclass = static_cast(message); + m_impl->signal_focus_out (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref()); + m_impl->focused_ic = (uint32) -1; + if (!m_impl->si.null ()) m_impl->si->focus_out(); + break; + } + case SCIM_TRANS_CMD_FOCUS_IN: + { + MessageItemFocusIn *subclass = static_cast(message); + m_impl->signal_focus_in (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref()); + m_impl->focused_ic = subclass->get_ic_ref(); + if (!m_impl->si.null ()) m_impl->si->focus_in(); + break; + } + case ISM_TRANS_CMD_SHOW_ISE_PANEL: + { + MessageItemShowISEPanel *subclass = static_cast(message); + LOGD ("Helper ISE received ISM_TRANS_CMD_SHOW_ISE_PANEL message\n"); - if (m_impl->recv.get_data (auto_capital_type)) { - if (!m_impl->si.null ()) m_impl->si->set_autocapital_type(auto_capital_type); + m_impl->signal_ise_show (this, subclass->get_ic_ref(), *(subclass->get_data_ptr()), + subclass->get_len_ref()); + break; + } + case ISM_TRANS_CMD_HIDE_ISE_PANEL: + { + MessageItemHideISEPanel *subclass = static_cast(message); + LOGD ("Helper ISE received ISM_TRANS_CMD_HIDE_ISE_PANEL message\n"); + m_impl->signal_ise_hide (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref()); + break; + } + case ISM_TRANS_CMD_GET_ACTIVE_ISE_GEOMETRY: + { + struct rectinfo info = {0, 0, 0, 0}; + m_impl->signal_get_geometry (this, info); + m_impl->send.clear (); + m_impl->send.put_command (SCIM_TRANS_CMD_REPLY); + m_impl->send.put_data (info.pos_x); + m_impl->send.put_data (info.pos_y); + m_impl->send.put_data (info.width); + m_impl->send.put_data (info.height); + m_impl->send.write_to_socket (m_impl->socket); + break; + } + case ISM_TRANS_CMD_SET_ISE_MODE: + { + MessageItemSetISEMode *subclass = static_cast(message); + m_impl->signal_set_mode (this, subclass->get_mode_ref()); + break; + } + case ISM_TRANS_CMD_SET_ISE_LANGUAGE: + { + MessageItemSetISELanguage *subclass = static_cast(message); + m_impl->signal_set_language (this, subclass->get_language_ref()); + break; + } + case ISM_TRANS_CMD_SET_ISE_IMDATA: + { + MessageItemSetISEImData *subclass = static_cast(message); + m_impl->signal_set_imdata (this, *(subclass->get_imdata_ptr()), subclass->get_len_ref()); + if (!m_impl->si.null ()) m_impl->si->set_imdata(*(subclass->get_imdata_ptr()), + subclass->get_len_ref()); + break; + } + case ISM_TRANS_CMD_GET_ISE_IMDATA: + { + char *buf = NULL; + size_t len = 0; + + m_impl->signal_get_imdata (this, &buf, len); + LOGD ("send ise imdata len = %d", len); + m_impl->send.clear (); + m_impl->send.put_command (SCIM_TRANS_CMD_REPLY); + m_impl->send.put_data (buf, len); + m_impl->send.write_to_socket (m_impl->socket); + if (NULL != buf) + delete[] buf; + break; + } + case ISM_TRANS_CMD_GET_ISE_LANGUAGE_LOCALE: + { + MessageItemGetISELanguageLocale *subclass = static_cast(message); + char *buf = NULL; + m_impl->signal_get_language_locale (this, subclass->get_ic_ref(), &buf); + m_impl->send.clear (); + m_impl->send.put_command (SCIM_TRANS_CMD_REPLY); + if (buf != NULL) + m_impl->send.put_data (buf, strlen (buf)); + m_impl->send.write_to_socket (m_impl->socket); + if (NULL != buf) + delete[] buf; + break; + } + case ISM_TRANS_CMD_SET_RETURN_KEY_TYPE: + { + MessageItemSetReturnKeyType *subclass = static_cast(message); + m_impl->signal_set_return_key_type (this, subclass->get_type_ref()); + break; + } + case ISM_TRANS_CMD_GET_RETURN_KEY_TYPE: + { + uint32 type = 0; + m_impl->signal_get_return_key_type (this, type); + m_impl->send.clear (); + m_impl->send.put_command (SCIM_TRANS_CMD_REPLY); + m_impl->send.put_data (type); + m_impl->send.write_to_socket (m_impl->socket); + break; + } + case ISM_TRANS_CMD_SET_RETURN_KEY_DISABLE: + { + MessageItemSetReturnKeyDisable *subclass = static_cast(message); + m_impl->signal_set_return_key_disable (this, subclass->get_disabled_ref()); + break; + } + case ISM_TRANS_CMD_GET_RETURN_KEY_DISABLE: + { + uint32 disabled = 0; + m_impl->signal_get_return_key_type (this, disabled); + m_impl->send.clear (); + m_impl->send.put_command (SCIM_TRANS_CMD_REPLY); + m_impl->send.put_data (disabled); + m_impl->send.write_to_socket (m_impl->socket); + break; + } + case SCIM_TRANS_CMD_PROCESS_KEY_EVENT: + { + MessageItemProcessKeyEvent *subclass = static_cast(message); + uint32 ret = 0; + m_impl->signal_process_key_event(this, subclass->get_key_ref(), ret); + if (ret == 0) + if (!m_impl->si.null ()) + { + ret = m_impl->si->process_key_event (subclass->get_key_ref()); + LOGD("imengine(%s) process key %d return %d", m_impl->si->get_factory_uuid().c_str(), + subclass->get_key_ref().code, ret); } - else - LOGW ("wrong format of transaction\n"); - break; - } - default: - break; + m_impl->process_key_event_done (subclass->get_key_ref(), ret, subclass->get_serial_ref()); + break; + } + case ISM_TRANS_CMD_SET_LAYOUT: + { + MessageItemSetLayout *subclass = static_cast(message); + m_impl->layout = subclass->get_layout_ref(); + m_impl->signal_set_layout (this, subclass->get_layout_ref()); + if (!m_impl->si.null ()) m_impl->si->set_layout(subclass->get_layout_ref()); + break; } + case ISM_TRANS_CMD_GET_LAYOUT: + { + uint32 layout = 0; + + m_impl->signal_get_layout (this, layout); + m_impl->send.clear (); + m_impl->send.put_command (SCIM_TRANS_CMD_REPLY); + m_impl->send.put_data (layout); + m_impl->send.write_to_socket (m_impl->socket); + break; + } + case ISM_TRANS_CMD_SET_INPUT_MODE: + { + MessageItemSetInputMode *subclass = static_cast(message); + m_impl->signal_set_input_mode (this, subclass->get_input_mode_ref()); + break; + } + case ISM_TRANS_CMD_SET_CAPS_MODE: + { + MessageItemSetCapsMode *subclass = static_cast(message); + m_impl->signal_set_caps_mode (this, subclass->get_mode_ref()); + break; + } + case SCIM_TRANS_CMD_PANEL_RESET_INPUT_CONTEXT: + { + MessageItemPanelResetInputContext *subclass = static_cast(message); + m_impl->signal_reset_input_context (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref()); + if (!m_impl->si.null ()) m_impl->si->reset(); + break; + } + case ISM_TRANS_CMD_UPDATE_CANDIDATE_UI: + { + MessageItemUpdateCandidateUI *subclass = static_cast(message); + m_impl->signal_update_candidate_ui (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(), + subclass->get_style_ref(), subclass->get_mode_ref()); + break; + } + case ISM_TRANS_CMD_UPDATE_CANDIDATE_GEOMETRY: + { + MessageItemUpdateCandidateGeometry *subclass = static_cast(message); + m_impl->signal_update_candidate_geometry (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(), + subclass->get_rectinfo_ref()); + break; + } + case ISM_TRANS_CMD_UPDATE_KEYBOARD_ISE: + { + MessageItemUpdateKeyboardISE *subclass = static_cast(message); + m_impl->signal_update_keyboard_ise (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(), + subclass->get_name_ref(), subclass->get_uuid_ref()); + break; + } + case ISM_TRANS_CMD_UPDATE_KEYBOARD_ISE_LIST: + { + MessageItemUpdateKeyboardISEList *subclass = static_cast(message); + m_impl->signal_update_keyboard_ise_list (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(), + subclass->get_list_ref()); + break; + } + case ISM_TRANS_CMD_CANDIDATE_MORE_WINDOW_SHOW: + { + MessageItemCandidateMoreWindowShow *subclass = static_cast(message); + m_impl->signal_candidate_more_window_show (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref()); + if (!m_impl->si.null ()) m_impl->si->candidate_more_window_show(); + break; + } + case ISM_TRANS_CMD_CANDIDATE_MORE_WINDOW_HIDE: + { + MessageItemCandidateMoreWindowHide *subclass = static_cast(message); + m_impl->signal_candidate_more_window_hide (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref()); + if (!m_impl->si.null ()) m_impl->si->candidate_more_window_hide(); + break; + } + case ISM_TRANS_CMD_SELECT_AUX: + { + MessageItemSelectAux *subclass = static_cast(message); + m_impl->signal_select_aux (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(), + subclass->get_item_ref()); + if (!m_impl->si.null ()) m_impl->si->select_aux(subclass->get_item_ref()); + break; + } + case SCIM_TRANS_CMD_SELECT_CANDIDATE: //FIXME:remove if useless + { + MessageItemSelectCandidate *subclass = static_cast(message); + m_impl->signal_select_candidate (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(), + subclass->get_item_ref()); + if (!m_impl->si.null ()) m_impl->si->select_candidate(subclass->get_item_ref()); + break; + } + case SCIM_TRANS_CMD_LOOKUP_TABLE_PAGE_UP: //FIXME:remove if useless + { + MessageItemLookupTablePageUp *subclass = static_cast(message); + m_impl->signal_candidate_table_page_up (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref()); + if (!m_impl->si.null ()) m_impl->si->lookup_table_page_up(); + break; + } + case SCIM_TRANS_CMD_LOOKUP_TABLE_PAGE_DOWN: //FIXME:remove if useless + { + MessageItemLookupTablePageDown *subclass = static_cast(message); + m_impl->signal_candidate_table_page_down (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref()); + if (!m_impl->si.null ()) m_impl->si->lookup_table_page_down(); + break; + } + case SCIM_TRANS_CMD_UPDATE_LOOKUP_TABLE_PAGE_SIZE: + { + MessageItemUpdateLookupTablePageSize *subclass = static_cast(message); + m_impl->signal_update_candidate_table_page_size (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(), + subclass->get_size_ref()); + if (!m_impl->si.null ()) m_impl->si->update_lookup_table_page_size(subclass->get_size_ref()); + break; + } + case ISM_TRANS_CMD_CANDIDATE_SHOW: //FIXME:remove if useless + { + MessageItemCandidateShow *subclass = static_cast(message); + m_impl->signal_candidate_show (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref()); + break; + } + case ISM_TRANS_CMD_CANDIDATE_HIDE: //FIXME:remove if useless + { + MessageItemCandidateHide *subclass = static_cast(message); + m_impl->signal_candidate_hide (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref()); + break; + } + case ISM_TRANS_CMD_UPDATE_LOOKUP_TABLE: //FIXME:remove if useless + { + MessageItemUpdateLookupTable *subclass = static_cast(message); + m_impl->signal_update_lookup_table (this, subclass->get_candidate_table_ref()); + break; + } + case ISM_TRANS_CMD_UPDATE_CANDIDATE_ITEM_LAYOUT: + { + MessageItemUpdateCandidateItemLayout *subclass = static_cast(message); + m_impl->signal_update_candidate_item_layout (this, subclass->get_row_items_ref()); + if (!m_impl->si.null ()) m_impl->si->update_candidate_item_layout(subclass->get_row_items_ref()); + break; + } + case ISM_TRANS_CMD_SELECT_ASSOCIATE: + { + MessageItemSelectAssociate *subclass = static_cast(message); + m_impl->signal_select_associate (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(), + subclass->get_item_ref()); + break; + } + case ISM_TRANS_CMD_ASSOCIATE_TABLE_PAGE_UP: + { + MessageItemAssociateTablePageUp *subclass = static_cast(message); + m_impl->signal_associate_table_page_up (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref()); + break; + } + case ISM_TRANS_CMD_ASSOCIATE_TABLE_PAGE_DOWN: + { + MessageItemAssociateTablePageDown *subclass = static_cast(message); + m_impl->signal_associate_table_page_down (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref()); + break; + } + case ISM_TRANS_CMD_UPDATE_ASSOCIATE_TABLE_PAGE_SIZE: + { + MessageItemUpdateAssociateTablePageSize *subclass = static_cast(message); + m_impl->signal_update_associate_table_page_size (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(), + subclass->get_size_ref()); + break; + } + case ISM_TRANS_CMD_RESET_ISE_CONTEXT: + { + MessageItemResetISEContext *subclass = static_cast(message); + m_impl->signal_reset_ise_context (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref()); + m_impl->signal_reset_input_context (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref()); + if (!m_impl->si.null ()) m_impl->si->reset(); + m_impl->send.clear (); + m_impl->send.put_command (SCIM_TRANS_CMD_REPLY); + m_impl->send.write_to_socket (m_impl->socket); + break; + } + case ISM_TRANS_CMD_TURN_ON_LOG: + { + MessageItemTurnOnLog *subclass = static_cast(message); + m_impl->signal_turn_on_log (this, subclass->get_state_ref()); + break; + } + case ISM_TRANS_CMD_UPDATE_DISPLAYED_CANDIDATE: + { + MessageItemUpdateDisplayedCandidate *subclass = static_cast(message); + m_impl->signal_update_displayed_candidate_number (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(), + subclass->get_size_ref()); + if (!m_impl->si.null ()) m_impl->si->update_displayed_candidate_number(subclass->get_size_ref()); + break; + } + case ISM_TRANS_CMD_LONGPRESS_CANDIDATE: + { + MessageItemLongpressCandidate *subclass = static_cast(message); + m_impl->signal_longpress_candidate (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(), + subclass->get_index_ref()); + if (!m_impl->si.null ()) m_impl->si->longpress_candidate(subclass->get_index_ref()); + break; + } + case ISM_TRANS_CMD_SET_INPUT_HINT: + { + MessageItemSetInputHint *subclass = static_cast(message); + m_impl->signal_set_input_hint (this, subclass->get_input_hint_ref()); + if (!m_impl->si.null ()) m_impl->si->set_input_hint(subclass->get_input_hint_ref()); + break; + } + case ISM_TRANS_CMD_UPDATE_BIDI_DIRECTION: + { + MessageItemUpdateBidiDirection *subclass = static_cast(message); + m_impl->signal_update_bidi_direction (this, subclass->get_bidi_direction()); + if (!m_impl->si.null ()) m_impl->si->update_bidi_direction(subclass->get_bidi_direction()); + break; + } + case ISM_TRANS_CMD_SHOW_ISE_OPTION_WINDOW: + { + MessageItemShowISEOptionWindow *subclass = static_cast(message); + m_impl->signal_show_option_window (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref()); + break; + } + case ISM_TRANS_CMD_CHECK_OPTION_WINDOW: + { + uint32 avail = 0; + m_impl->signal_check_option_window (this, avail); + m_impl->send.clear (); + m_impl->send.put_command (SCIM_TRANS_CMD_REPLY); + m_impl->send.put_data (avail); + m_impl->send.write_to_socket (m_impl->socket); + break; + } + case ISM_TRANS_CMD_PROCESS_INPUT_DEVICE_EVENT: + { + MessageItemProcessInputDeviceEvent *subclass = static_cast(message); + uint32 ret = 0; + m_impl->signal_process_input_device_event(this, + subclass->get_type_ref(), *(subclass->get_data_ptr()), subclass->get_len_ref(), ret); + m_impl->send.clear(); + m_impl->send.put_command(SCIM_TRANS_CMD_REPLY); + m_impl->send.put_data(ret); + m_impl->send.write_to_socket(m_impl->socket); + break; + } + case SCIM_TRANS_CMD_SET_AUTOCAPITAL_TYPE: + { + MessageItemSetAutocapitalType *subclass = static_cast(message); + if (!m_impl->si.null ()) m_impl->si->set_autocapital_type(subclass->get_auto_capital_type_ref()); + break; + } + default: + break; } return true; } @@ -2032,16 +1979,17 @@ HelperAgent::get_surrounding_text (int maxlen_before, int maxlen_after, String & m_impl->surrounding_text = NULL; } - for (int i = 0; i < 3; i++) { - filter_event (); - if (!m_impl->socket.is_connected ()) - break; + const int WAIT_FOR_SYNC_RESPONSE_TIMEOUT = 1000; + /* Now we are waiting for the ISM_TRANS_CMD_UPDATE_SURROUNDING_TEXT message */ + if (wait_for_message(ISM_TRANS_CMD_UPDATE_SURROUNDING_TEXT, WAIT_FOR_SYNC_RESPONSE_TIMEOUT)) { + MessageItem *message = message_queue.get_pending_message_by_cmd(ISM_TRANS_CMD_UPDATE_SURROUNDING_TEXT); + handle_message(message); + message_queue.remove_message(message); + if (m_impl->surrounding_text) { text = m_impl->surrounding_text; cursor = m_impl->cursor_pos; - break; } - //timeout } if (m_impl->surrounding_text) { diff --git a/ism/src/scim_helper.h b/ism/src/scim_helper.h index 334d3ba..b41260c 100644 --- a/ism/src/scim_helper.h +++ b/ism/src/scim_helper.h @@ -157,6 +157,7 @@ enum HelperState HELPER_INVALID_STATE }; +class MessageItem; class HelperAgent; typedef Slot3 @@ -299,6 +300,25 @@ public: bool filter_event (); /** + * @brief Read messages from socket buffer, and see if there is a message with the given cmd. + * + * @return false if the connection is broken, or no message available with given cmd. Otherwise return true. + */ + bool wait_for_message (int cmd, int timeout); + + /** + * @brief Process one message that is in our message queue. + * + * This function will emit the corresponding signals according + * to the events. + * + * @param message The message that needs to be handled. + * + * @return false if the connection is broken, otherwise return true. + */ + bool handle_message (MessageItem *message); + + /** * @brief Request SCIM to reload all configuration. * * This function should only by used by Setup Helper to request -- 2.7.4