Added MessageQueue concept for handling sync messages 07/81907/8
authorJi-hoon Lee <dalton.lee@samsung.com>
Wed, 27 Jul 2016 01:18:37 +0000 (10:18 +0900)
committerJihoon Kim <jihoon48.kim@samsung.com>
Wed, 3 Aug 2016 10:25:11 +0000 (03:25 -0700)
Change-Id: Ie47192e77e937107e5e6392301beaa4cfa8c3988

ism/src/Makefile.am
ism/src/isf_message_queue.h [new file with mode: 0644]
ism/src/scim_helper.cpp
ism/src/scim_helper.h

index 9d68c1a..f4e7677 100644 (file)
@@ -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 (file)
index 0000000..31b57d7
--- /dev/null
@@ -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 <dalton.lee@samsung.com>, Jihoon Kim <jihoon48.kim@samsung.com>
+ *
+ * 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 <string.h>
+#include <unistd.h>
+
+#include "scim_private.h"
+#include "scim.h"
+#include <scim_panel_common.h>
+#include "isf_query_utility.h"
+#include <dlog.h>
+#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<String>& get_list_ref() { return m_list; }
+protected:
+    std::vector<String> 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<uint32>& get_row_items_ref() { return m_row_items; }
+protected:
+    std::vector<uint32> 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 <typename T>
+inline T*
+alloc_message() /* We could use memory pool in the future for performance enhancement */
+{
+    return new T;
+}
+
+template <typename T>
+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<MessageItem>(*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<MessageItem>(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<MessageItemExit>();
+                    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<MessageItemReloadConfig>();
+                    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<MessageItemUpdateScreen>();
+                    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<MessageItemUpdateScreen>(message);
+                        }
+                    }
+                    break;
+                }
+                case SCIM_TRANS_CMD_UPDATE_SPOT_LOCATION:
+                {
+                    MessageItemUpdateSpotLocation *message = alloc_message<MessageItemUpdateSpotLocation>();
+                    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<MessageItemUpdateSpotLocation>(message);
+                        }
+                    }
+                    break;
+                }
+                case ISM_TRANS_CMD_UPDATE_CURSOR_POSITION:
+                {
+                    MessageItemUpdateCursorPosition *message = alloc_message<MessageItemUpdateCursorPosition>();
+                    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<MessageItemUpdateCursorPosition>(message);
+                        }
+                    }
+                    break;
+                }
+                case ISM_TRANS_CMD_UPDATE_SURROUNDING_TEXT:
+                {
+                    MessageItemUpdateSurroundingText *message = alloc_message<MessageItemUpdateSurroundingText>();
+                    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<MessageItemUpdateSurroundingText>(message);
+                        }
+                    }
+                    break;
+                }
+                case ISM_TRANS_CMD_UPDATE_SELECTION:
+                {
+                    MessageItemUpdateSelection *message = alloc_message<MessageItemUpdateSelection>();
+                    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<MessageItemUpdateSelection>(message);
+                        }
+                    }
+                    break;
+                }
+                case SCIM_TRANS_CMD_TRIGGER_PROPERTY:
+                {
+                    MessageItemTriggerProperty *message = alloc_message<MessageItemTriggerProperty>();
+                    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<MessageItemTriggerProperty>(message);
+                        }
+                    }
+                    break;
+                }
+                case SCIM_TRANS_CMD_HELPER_PROCESS_IMENGINE_EVENT:
+                {
+                    MessageItemHelperProcessImengineEvent *message = alloc_message<MessageItemHelperProcessImengineEvent>();
+                    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<MessageItemHelperProcessImengineEvent>(message);
+                        }
+                    }
+                    break;
+                }
+                case SCIM_TRANS_CMD_HELPER_ATTACH_INPUT_CONTEXT:
+                {
+                    MessageItemHelperAttachInputContext *message = alloc_message<MessageItemHelperAttachInputContext>();
+                    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<MessageItemHelperDetachInputContext>();
+                    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<MessageItemFocusOut>();
+                    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<MessageItemFocusIn>();
+                    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<MessageItemShowISEPanel>();
+                    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<MessageItemShowISEPanel>(message);
+                        }
+                    }
+                    break;
+                }
+                case ISM_TRANS_CMD_HIDE_ISE_PANEL:
+                {
+                    MessageItemHideISEPanel *message = alloc_message<MessageItemHideISEPanel>();
+                    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<MessageItemGetActiveISEGeometry>();
+                    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<MessageItemSetISEMode>();
+                    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<MessageItemSetISEMode>(message);
+                        }
+                    }
+                    break;
+                }
+                case ISM_TRANS_CMD_SET_ISE_LANGUAGE:
+                {
+                    MessageItemSetISELanguage *message = alloc_message<MessageItemSetISELanguage>();
+                    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<MessageItemSetISELanguage>(message);
+                        }
+                    }
+                    break;
+                }
+                case ISM_TRANS_CMD_SET_ISE_IMDATA:
+                {
+                    MessageItemSetISEImData *message = alloc_message<MessageItemSetISEImData>();
+                    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<MessageItemSetISEImData>(message);
+                        }
+                    }
+                    break;
+                }
+                case ISM_TRANS_CMD_GET_ISE_IMDATA:
+                {
+                    MessageItemGetISEImdata *message = alloc_message<MessageItemGetISEImdata>();
+                    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<MessageItemGetISELanguageLocale>();
+                    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<MessageItemSetReturnKeyType>();
+                    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<MessageItemGetReturnKeyType>();
+                    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<MessageItemSetReturnKeyDisable>();
+                    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<MessageItemSetReturnKeyDisable>(message);
+                        }
+                    }
+                    break;
+                }
+                case ISM_TRANS_CMD_GET_RETURN_KEY_DISABLE:
+                {
+                    MessageItemGetReturnKeyDisable *message = alloc_message<MessageItemGetReturnKeyDisable>();
+                    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<MessageItemProcessKeyEvent>();
+                    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<MessageItemProcessKeyEvent>(message);
+                        }
+                    }
+                    break;
+                }
+                case ISM_TRANS_CMD_SET_LAYOUT:
+                {
+                    MessageItemSetLayout *message = alloc_message<MessageItemSetLayout>();
+                    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<MessageItemSetLayout>(message);
+                        }
+                    }
+                    break;
+                }
+                case ISM_TRANS_CMD_GET_LAYOUT:
+                {
+                    MessageItemGetLayout *message = alloc_message<MessageItemGetLayout>();
+                    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<MessageItemSetInputMode>();
+                    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<MessageItemSetInputMode>(message);
+                        }
+                    }
+                    break;
+                }
+                case ISM_TRANS_CMD_SET_CAPS_MODE:
+                {
+                    MessageItemSetCapsMode *message = alloc_message<MessageItemSetCapsMode>();
+                    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<MessageItemSetCapsMode>(message);
+                        }
+                    }
+                    break;
+                }
+                case SCIM_TRANS_CMD_PANEL_RESET_INPUT_CONTEXT:
+                {
+                    MessageItemPanelResetInputContext *message = alloc_message<MessageItemPanelResetInputContext>();
+                    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<MessageItemUpdateCandidateUI>();
+                    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<MessageItemUpdateCandidateUI>(message);
+                        }
+                    }
+                    break;
+                }
+                case ISM_TRANS_CMD_UPDATE_CANDIDATE_GEOMETRY:
+                {
+                    MessageItemUpdateCandidateGeometry *message = alloc_message<MessageItemUpdateCandidateGeometry>();
+                    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<MessageItemUpdateCandidateGeometry>(message);
+                        }
+                    }
+                    break;
+                }
+                case ISM_TRANS_CMD_UPDATE_KEYBOARD_ISE:
+                {
+                    MessageItemUpdateKeyboardISE *message = alloc_message<MessageItemUpdateKeyboardISE>();
+                    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<MessageItemUpdateKeyboardISE>(message);
+                        }
+                    }
+                    break;
+                }
+                case ISM_TRANS_CMD_UPDATE_KEYBOARD_ISE_LIST:
+                {
+                    MessageItemUpdateKeyboardISEList *message = alloc_message<MessageItemUpdateKeyboardISEList>();
+                    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<MessageItemUpdateKeyboardISEList>(message);
+                        }
+                    }
+                    break;
+                }
+                case ISM_TRANS_CMD_CANDIDATE_MORE_WINDOW_SHOW:
+                {
+                    MessageItemCandidateMoreWindowShow *message = alloc_message<MessageItemCandidateMoreWindowShow>();
+                    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<MessageItemCandidateMoreWindowHide>();
+                    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<MessageItemSelectAux>();
+                    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<MessageItemSelectAux>(message);
+                        }
+                    }
+                    break;
+                }
+                case SCIM_TRANS_CMD_SELECT_CANDIDATE: //FIXME:remove if useless
+                {
+                    MessageItemSelectCandidate *message = alloc_message<MessageItemSelectCandidate>();
+                    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<MessageItemSelectCandidate>(message);
+                        }
+                    }
+                    break;
+                }
+                case SCIM_TRANS_CMD_LOOKUP_TABLE_PAGE_UP: //FIXME:remove if useless
+                {
+                    MessageItemLookupTablePageUp *message = alloc_message<MessageItemLookupTablePageUp>();
+                    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<MessageItemLookupTablePageDown>();
+                    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<MessageItemUpdateLookupTablePageSize>();
+                    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<MessageItemUpdateLookupTablePageSize>(message);
+                        }
+                    }
+                    break;
+                }
+                case ISM_TRANS_CMD_CANDIDATE_SHOW: //FIXME:remove if useless
+                {
+                    MessageItemCandidateShow *message = alloc_message<MessageItemCandidateShow>();
+                    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<MessageItemCandidateHide>();
+                    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<MessageItemUpdateLookupTable>();
+                    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<MessageItemUpdateLookupTable>(message);
+                        }
+                    }
+                    break;
+                }
+                case ISM_TRANS_CMD_UPDATE_CANDIDATE_ITEM_LAYOUT:
+                {
+                    MessageItemUpdateCandidateItemLayout *message = alloc_message<MessageItemUpdateCandidateItemLayout>();
+                    if (transaction.get_data(message->get_row_items_ref())) {
+                        m_list_messages.push_back(message);
+                    } else {
+                            LOGW("wrong format of transaction\n");
+                            dealloc_message<MessageItemUpdateCandidateItemLayout>(message);
+                    }
+                    break;
+                }
+                case ISM_TRANS_CMD_SELECT_ASSOCIATE:
+                {
+                    MessageItemSelectAssociate *message = alloc_message<MessageItemSelectAssociate>();
+                    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<MessageItemSelectAssociate>(message);
+                    }
+                    break;
+                }
+                case ISM_TRANS_CMD_ASSOCIATE_TABLE_PAGE_UP:
+                {
+                    MessageItemAssociateTablePageUp *message = alloc_message<MessageItemAssociateTablePageUp>();
+                    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<MessageItemAssociateTablePageDown>();
+                    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<MessageItemUpdateAssociateTablePageSize>();
+                    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<MessageItemUpdateAssociateTablePageSize>(message);
+                    }
+                    break;
+                }
+                case ISM_TRANS_CMD_RESET_ISE_CONTEXT:
+                {
+                    MessageItemResetISEContext *message = alloc_message<MessageItemResetISEContext>();
+                    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<MessageItemTurnOnLog>();
+                    if (transaction.get_data(message->get_state_ref())) {
+                        m_list_messages.push_back(message);
+                    } else {
+                        LOGW("wrong format of transaction\n");
+                        dealloc_message<MessageItemTurnOnLog>(message);
+                    }
+                    break;
+                }
+                case ISM_TRANS_CMD_UPDATE_DISPLAYED_CANDIDATE:
+                {
+                    MessageItemUpdateDisplayedCandidate *message = alloc_message<MessageItemUpdateDisplayedCandidate>();
+                    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<MessageItemUpdateDisplayedCandidate>(message);
+                    }
+                    break;
+                }
+                case ISM_TRANS_CMD_LONGPRESS_CANDIDATE:
+                {
+                    MessageItemLongpressCandidate *message = alloc_message<MessageItemLongpressCandidate>();
+                    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<MessageItemLongpressCandidate>(message);
+                        }
+                    }
+                    break;
+                }
+                case ISM_TRANS_CMD_SET_INPUT_HINT:
+                {
+                    MessageItemSetInputHint *message = alloc_message<MessageItemSetInputHint>();
+                    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<MessageItemSetInputHint>(message);
+                        }
+                    }
+                    break;
+                }
+                case ISM_TRANS_CMD_UPDATE_BIDI_DIRECTION:
+                {
+                    MessageItemUpdateBidiDirection *message = alloc_message<MessageItemUpdateBidiDirection>();
+                    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<MessageItemUpdateBidiDirection>(message);
+                        }
+                    }
+                    break;
+                }
+                case ISM_TRANS_CMD_SHOW_ISE_OPTION_WINDOW:
+                {
+                    MessageItemShowISEOptionWindow *message = alloc_message<MessageItemShowISEOptionWindow>();
+                    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<MessageItemCheckOptionWindow>();
+                    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<MessageItemProcessInputDeviceEvent>();
+                    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<MessageItemProcessInputDeviceEvent>(message);
+                        }
+                    }
+                    break;
+                }
+                case SCIM_TRANS_CMD_SET_AUTOCAPITAL_TYPE:
+                {
+                    MessageItemSetAutocapitalType *message = alloc_message<MessageItemSetAutocapitalType>();
+                    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<MessageItemSetAutocapitalType>(message);
+                        }
+                    }
+                    break;
+                }
+            }
+        }
+
+        return true;
+    }
+
+protected:
+    typedef std::list<MessageItem*> MESSAGE_LIST;
+    MESSAGE_LIST m_list_messages;
+};
+
+} /* namespace scim */
+
+#endif  /* __ISF_MESSAGE_H */
+
+/*
+vi:ts=4:expandtab:nowrap
+*/
index 83d19a7..27342ab 100644 (file)
@@ -48,6 +48,7 @@
 
 #include <string.h>
 #include <unistd.h>
+#include <sys/time.h>
 
 #include "scim_private.h"
 #include "scim.h"
@@ -55,6 +56,7 @@
 #include "isf_query_utility.h"
 #include <dlog.h>
 #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<String> 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<uint32> 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<MessageItemExit*>(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<MessageItemReloadConfig*>(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<MessageItemUpdateScreen*>(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<MessageItemUpdateSpotLocation*>(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<MessageItemUpdateCursorPosition*>(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<MessageItemUpdateSurroundingText*>(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<MessageItemUpdateSelection*>(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<MessageItemTriggerProperty*>(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<MessageItemHelperProcessImengineEvent*>(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<MessageItemHelperAttachInputContext*>(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<MessageItemHelperDetachInputContext*>(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<MessageItemFocusOut*>(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<MessageItemFocusIn*>(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<MessageItemShowISEPanel*>(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<MessageItemHideISEPanel*>(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<MessageItemSetISEMode*>(message);
+            m_impl->signal_set_mode (this, subclass->get_mode_ref());
+            break;
+        }
+        case ISM_TRANS_CMD_SET_ISE_LANGUAGE:
+        {
+            MessageItemSetISELanguage *subclass = static_cast<MessageItemSetISELanguage*>(message);
+            m_impl->signal_set_language (this, subclass->get_language_ref());
+            break;
+        }
+        case ISM_TRANS_CMD_SET_ISE_IMDATA:
+        {
+            MessageItemSetISEImData *subclass = static_cast<MessageItemSetISEImData*>(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<MessageItemGetISELanguageLocale*>(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<MessageItemSetReturnKeyType*>(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<MessageItemSetReturnKeyDisable*>(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<MessageItemProcessKeyEvent*>(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<MessageItemSetLayout*>(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<MessageItemSetInputMode*>(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<MessageItemSetCapsMode*>(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<MessageItemPanelResetInputContext*>(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<MessageItemUpdateCandidateUI*>(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<MessageItemUpdateCandidateGeometry*>(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<MessageItemUpdateKeyboardISE*>(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<MessageItemUpdateKeyboardISEList*>(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<MessageItemCandidateMoreWindowShow*>(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<MessageItemCandidateMoreWindowHide*>(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<MessageItemSelectAux*>(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<MessageItemSelectCandidate*>(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<MessageItemLookupTablePageUp*>(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<MessageItemLookupTablePageDown*>(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<MessageItemUpdateLookupTablePageSize*>(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<MessageItemCandidateShow*>(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<MessageItemCandidateHide*>(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<MessageItemUpdateLookupTable*>(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<MessageItemUpdateCandidateItemLayout*>(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<MessageItemSelectAssociate*>(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<MessageItemAssociateTablePageUp*>(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<MessageItemAssociateTablePageDown*>(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<MessageItemUpdateAssociateTablePageSize*>(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<MessageItemResetISEContext*>(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<MessageItemTurnOnLog*>(message);
+            m_impl->signal_turn_on_log (this, subclass->get_state_ref());
+            break;
+        }
+        case ISM_TRANS_CMD_UPDATE_DISPLAYED_CANDIDATE:
+        {
+            MessageItemUpdateDisplayedCandidate *subclass = static_cast<MessageItemUpdateDisplayedCandidate*>(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<MessageItemLongpressCandidate*>(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<MessageItemSetInputHint*>(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<MessageItemUpdateBidiDirection*>(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<MessageItemShowISEOptionWindow*>(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<MessageItemProcessInputDeviceEvent*>(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<MessageItemSetAutocapitalType*>(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) {
index 334d3ba..b41260c 100644 (file)
@@ -157,6 +157,7 @@ enum HelperState
     HELPER_INVALID_STATE
 };
 
+class MessageItem;
 class HelperAgent;
 
 typedef Slot3<void, const HelperAgent *, int, const String &>
@@ -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