Revert "Add SocketConfigServer PanelAgent module"
[platform/core/uifw/isf.git] / ism / src / scim_helper.cpp
1 /** @file scim_helper.cpp
2  *  @brief Implementation of class HelperAgent.
3  */
4
5 /* ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. */
6
7 /*
8  * Smart Common Input Method
9  *
10  * Copyright (c) 2004-2005 James Su <suzhe@tsinghua.org.cn>
11  * Copyright (c) 2012-2015 Samsung Electronics Co., Ltd.
12  *
13  *
14  * This library is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU Lesser General Public
16  * License as published by the Free Software Foundation; either
17  * version 2 of the License, or (at your option) any later version.
18  *
19  * This library is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU Lesser General Public License for more details.
23  *
24  * You should have received a copy of the GNU Lesser General Public
25  * License along with this program; if not, write to the
26  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
27  * Boston, MA  02111-1307  USA
28  *
29  * Modifications by Samsung Electronics Co., Ltd.
30  * 1. Add new interface APIs for keyboard ISE
31  *    a. expand_candidate (), contract_candidate () and set_candidate_style ()
32  *    b. set_keyboard_ise_by_uuid () and reset_keyboard_ise ()
33  *    c. get_surrounding_text () and delete_surrounding_text ()
34  *    d. show_preedit_string (), hide_preedit_string (), update_preedit_string () and update_preedit_caret ()
35  *    e. show_candidate_string (), hide_candidate_string () and update_candidate_string ()
36  *
37  * $Id: scim_helper.cpp,v 1.13 2005/05/24 12:22:51 suzhe Exp $
38  *
39  */
40
41 #define Uses_SCIM_TRANSACTION
42 #define Uses_SCIM_TRANS_COMMANDS
43 #define Uses_SCIM_HELPER
44 #define Uses_SCIM_SOCKET
45 #define Uses_SCIM_EVENT
46 #define Uses_SCIM_BACKEND
47 #define Uses_SCIM_IMENGINE_MODULE
48
49 #include <string.h>
50 #include <unistd.h>
51 #include <sys/time.h>
52
53 #include "scim_private.h"
54 #include "scim.h"
55 #include <scim_panel_common.h>
56 #include "isf_query_utility.h"
57 #include <dlog.h>
58 #include "isf_debug.h"
59 #include "isf_message_queue.h"
60 #if HAVE_PKGMGR_INFO
61 #include <pkgmgr-info.h>
62 #endif // HAVE_PKGMGR_INFO
63
64 #ifdef LOG_TAG
65 # undef LOG_TAG
66 #endif
67 #define LOG_TAG             "SCIM_HELPER"
68
69
70 //FIXME: remove this definitions
71 #define SHIFT_MODE_OFF  0xffe1
72 #define SHIFT_MODE_ON   0xffe2
73 #define SHIFT_MODE_LOCK 0xffe6
74 #define SHIFT_MODE_ENABLE 0x9fe7
75 #define SHIFT_MODE_DISABLE 0x9fe8
76
77 namespace scim {
78
79 typedef Signal3<void, const HelperAgent *, int, const String &>
80         HelperAgentSignalVoid;
81
82 typedef Signal4<void, const HelperAgent *, int, const String &, const String &>
83         HelperAgentSignalString;
84
85 typedef Signal4<void, const HelperAgent *, int, const String &, const std::vector<String> &>
86         HelperAgentSignalStringVector;
87
88 typedef Signal5<void, const HelperAgent *, int, const String &, const String &, const String &>
89         HelperAgentSignalString2;
90
91 typedef Signal4<void, const HelperAgent *, int, const String &, int>
92         HelperAgentSignalInt;
93
94 typedef Signal5<void, const HelperAgent *, int, const String &, int, int>
95         HelperAgentSignalIntInt;
96
97 typedef Signal4<void, const HelperAgent *, int, const String &, const Transaction &>
98         HelperAgentSignalTransaction;
99
100 typedef Signal4<void, const HelperAgent *, int, const String &, const rectinfo &>
101         HelperAgentSignalRect;
102
103 typedef Signal2<void, const HelperAgent *, struct rectinfo &>
104         HelperAgentSignalSize;
105
106 typedef Signal2<void, const HelperAgent *, uint32 &>
107         HelperAgentSignalUintVoid;
108
109 typedef Signal3<void, const HelperAgent *, int, uint32 &>
110         HelperAgentSignalIntUint;
111
112 typedef Signal3 <void, const HelperAgent *, char *, size_t &>
113         HelperAgentSignalRawVoid;
114
115 typedef Signal3 <void, const HelperAgent *, char **, size_t &>
116         HelperAgentSignalGetRawVoid;
117
118 typedef Signal4 <void, const HelperAgent *, int, char *, size_t &>
119         HelperAgentSignalIntRawVoid;
120
121 typedef Signal3 <void, const HelperAgent *, int, char **>
122         HelperAgentSignalIntGetStringVoid;
123
124 typedef Signal2<void, const HelperAgent *, const std::vector<uint32> &>
125         HelperAgentSignalUintVector;
126
127 typedef Signal2<void, const HelperAgent *, LookupTable &>
128         HelperAgentSignalLookupTable;
129
130 typedef Signal3<void, const HelperAgent *, KeyEvent &, uint32 &>
131         HelperAgentSignalKeyEventUint;
132
133 typedef Signal5<void, const HelperAgent *, uint32 &, char *, size_t &, uint32 &>
134         HelperAgentSignalUintCharSizeUint;
135
136 class HelperAgent::HelperAgentImpl
137 {
138 public:
139     SocketClient socket;
140     SocketClient socket_active;
141     Transaction  recv;
142     Transaction  send;
143     uint32       magic;
144     uint32       magic_active;
145     int          timeout;
146     uint32       focused_ic;
147
148     HelperAgent* thiz;
149     IMEngineInstancePointer si;
150     ConfigPointer m_config;
151     IMEngineModule engine_module;
152
153     char* surrounding_text;
154     char* selection_text;
155     uint32 cursor_pos;
156     int need_update_surrounding_text;
157     int need_update_selection_text;
158     uint32 layout;
159
160     HelperAgentSignalVoid           signal_exit;
161     HelperAgentSignalVoid           signal_attach_input_context;
162     HelperAgentSignalVoid           signal_detach_input_context;
163     HelperAgentSignalVoid           signal_reload_config;
164     HelperAgentSignalInt            signal_update_screen;
165     HelperAgentSignalIntInt         signal_update_spot_location;
166     HelperAgentSignalInt            signal_update_cursor_position;
167     HelperAgentSignalInt            signal_update_surrounding_text;
168     HelperAgentSignalVoid           signal_update_selection;
169     HelperAgentSignalString         signal_trigger_property;
170     HelperAgentSignalTransaction    signal_process_imengine_event;
171     HelperAgentSignalVoid           signal_focus_out;
172     HelperAgentSignalVoid           signal_focus_in;
173     HelperAgentSignalIntRawVoid     signal_ise_show;
174     HelperAgentSignalVoid           signal_ise_hide;
175     HelperAgentSignalVoid           signal_candidate_show;
176     HelperAgentSignalVoid           signal_candidate_hide;
177     HelperAgentSignalSize           signal_get_geometry;
178     HelperAgentSignalUintVoid       signal_set_mode;
179     HelperAgentSignalUintVoid       signal_set_language;
180     HelperAgentSignalRawVoid        signal_set_imdata;
181     HelperAgentSignalGetRawVoid     signal_get_imdata;
182     HelperAgentSignalIntGetStringVoid   signal_get_language_locale;
183     HelperAgentSignalUintVoid           signal_set_return_key_type;
184     HelperAgentSignalUintVoid           signal_get_return_key_type;
185     HelperAgentSignalUintVoid           signal_set_return_key_disable;
186     HelperAgentSignalUintVoid           signal_get_return_key_disable;
187     HelperAgentSignalUintVoid           signal_set_layout;
188     HelperAgentSignalUintVoid           signal_get_layout;
189     HelperAgentSignalUintVoid           signal_set_caps_mode;
190     HelperAgentSignalVoid               signal_reset_input_context;
191     HelperAgentSignalIntInt             signal_update_candidate_ui;
192     HelperAgentSignalRect               signal_update_candidate_geometry;
193     HelperAgentSignalString2            signal_update_keyboard_ise;
194     HelperAgentSignalStringVector       signal_update_keyboard_ise_list;
195     HelperAgentSignalVoid               signal_candidate_more_window_show;
196     HelperAgentSignalVoid               signal_candidate_more_window_hide;
197     HelperAgentSignalLookupTable        signal_update_lookup_table;
198     HelperAgentSignalInt                signal_select_aux;
199     HelperAgentSignalInt                signal_select_candidate;
200     HelperAgentSignalVoid               signal_candidate_table_page_up;
201     HelperAgentSignalVoid               signal_candidate_table_page_down;
202     HelperAgentSignalInt                signal_update_candidate_table_page_size;
203     HelperAgentSignalUintVector         signal_update_candidate_item_layout;
204     HelperAgentSignalInt                signal_select_associate;
205     HelperAgentSignalVoid               signal_associate_table_page_up;
206     HelperAgentSignalVoid               signal_associate_table_page_down;
207     HelperAgentSignalInt                signal_update_associate_table_page_size;
208     HelperAgentSignalVoid               signal_reset_ise_context;
209     HelperAgentSignalUintVoid           signal_turn_on_log;
210     HelperAgentSignalInt                signal_update_displayed_candidate_number;
211     HelperAgentSignalInt                signal_longpress_candidate;
212     HelperAgentSignalKeyEventUint       signal_process_key_event;
213     HelperAgentSignalUintVoid           signal_set_input_mode;
214     HelperAgentSignalUintVoid           signal_set_input_hint;
215     HelperAgentSignalUintVoid           signal_update_bidi_direction;
216     HelperAgentSignalVoid               signal_show_option_window;
217     HelperAgentSignalUintVoid           signal_check_option_window;
218     HelperAgentSignalUintCharSizeUint   signal_process_input_device_event;
219
220 public:
221     HelperAgentImpl (HelperAgent* thiz) : focused_ic ((uint32) -1), thiz (thiz),
222         surrounding_text (NULL), selection_text (NULL), cursor_pos (0),
223         need_update_surrounding_text (0), need_update_selection_text (0),
224         layout (0) {
225     }
226
227     ~HelperAgentImpl () {
228         if (!si.null ()) {
229             si.reset ();
230         }
231
232         if (surrounding_text != NULL)
233             free (surrounding_text);
234
235         if (selection_text != NULL)
236             free (selection_text);
237
238         if (engine_module.valid ()) {
239             engine_module.unload ();
240         }
241     }
242
243     // Implementation of slot functions
244     void
245     slot_show_preedit_string (IMEngineInstanceBase *si)
246     {
247         LOGD ("");
248         thiz->show_preedit_string (focused_ic, "");
249     }
250
251     void
252     slot_show_aux_string (IMEngineInstanceBase *si)
253     {
254         LOGD ("");
255         thiz->show_aux_string ();
256     }
257
258     void
259     slot_show_lookup_table (IMEngineInstanceBase *si)
260     {
261         LOGD ("");
262         thiz->show_candidate_string ();
263     }
264
265     void
266     slot_hide_preedit_string (IMEngineInstanceBase *si)
267     {
268         LOGD ("");
269         thiz->hide_preedit_string (focused_ic, "");
270     }
271
272     void
273     slot_hide_aux_string (IMEngineInstanceBase *si)
274     {
275         LOGD ("");
276         thiz->hide_aux_string ();
277     }
278
279     void
280     slot_hide_lookup_table (IMEngineInstanceBase *si)
281     {
282         LOGD ("");
283         thiz->hide_candidate_string ();
284     }
285
286     void
287     slot_update_preedit_caret (IMEngineInstanceBase *si, int caret)
288     {
289         LOGD ("");
290         thiz->update_preedit_caret (caret);
291     }
292
293     void
294     slot_update_preedit_string (IMEngineInstanceBase *si,
295                                 const WideString & str,
296                                 const AttributeList & attrs,
297                                 int caret)
298     {
299         LOGD ("");
300         thiz->update_preedit_string (-1, "", str, attrs, caret);
301     }
302
303     void
304     slot_update_preedit_string_with_commit (IMEngineInstanceBase *si,
305                                             const WideString & preedit,
306                                             const WideString & commit,
307                                             const AttributeList & attrs,
308                                             int caret)
309     {
310         LOGD ("");
311         thiz->update_preedit_string (-1, "", preedit, commit, attrs, caret);
312     }
313
314     void
315     slot_update_aux_string (IMEngineInstanceBase *si,
316                             const WideString & str,
317                             const AttributeList & attrs)
318     {
319         LOGD ("");
320         thiz->update_aux_string (utf8_wcstombs(str), attrs);
321     }
322
323     void
324     slot_commit_string (IMEngineInstanceBase *si,
325                         const WideString & str)
326     {
327         LOGD ("");
328         thiz->commit_string (-1, "", str);
329     }
330
331     void
332     slot_forward_key_event (IMEngineInstanceBase *si,
333                             const KeyEvent & key)
334     {
335         LOGD ("");
336         thiz->forward_key_event (-1, "", key);
337     }
338
339     void
340     slot_update_lookup_table (IMEngineInstanceBase *si,
341                               const LookupTable & table)
342     {
343         LOGD ("");
344         thiz->update_candidate_string (table);
345     }
346
347     void
348     slot_register_properties (IMEngineInstanceBase *si,
349                               const PropertyList & properties)
350     {
351         LOGD ("");
352         thiz->register_properties (properties);
353     }
354
355     void
356     slot_update_property (IMEngineInstanceBase *si,
357                           const Property & property)
358     {
359         LOGD ("");
360         thiz->update_property (property);
361     }
362
363     void
364     slot_beep (IMEngineInstanceBase *si)
365     {
366         //FIXME
367         LOGD ("");
368     }
369
370     void
371     slot_start_helper (IMEngineInstanceBase *si,
372                        const String &helper_uuid)
373     {
374         LOGW ("deprecated function");
375     }
376
377     void
378     slot_stop_helper (IMEngineInstanceBase *si,
379                       const String &helper_uuid)
380     {
381         LOGW ("deprecated function");
382     }
383
384     void
385     slot_send_helper_event (IMEngineInstanceBase *si,
386                             const String      &helper_uuid,
387                             const Transaction &trans)
388     {
389         LOGD ("");
390         signal_process_imengine_event (thiz, focused_ic, helper_uuid, trans);
391     }
392
393     bool
394     slot_get_surrounding_text (IMEngineInstanceBase *si,
395                                WideString            &text,
396                                int                   &cursor,
397                                int                    maxlen_before,
398                                int                    maxlen_after)
399     {
400         LOGD ("");
401         String _text;
402         thiz->get_surrounding_text (maxlen_before, maxlen_after, _text, cursor);
403         text = utf8_mbstowcs(_text);
404         return true;
405     }
406
407     bool
408     slot_delete_surrounding_text (IMEngineInstanceBase *si,
409                                   int                   offset,
410                                   int                   len)
411     {
412         LOGD ("");
413
414         thiz->delete_surrounding_text (offset, len);
415         return true;
416     }
417
418     bool
419     slot_get_selection (IMEngineInstanceBase *si,
420                         WideString            &text)
421     {
422         LOGD ("");
423         String _text;
424         thiz->get_selection_text (_text);
425         text = utf8_mbstowcs (_text);
426         return true;
427     }
428
429     bool
430     slot_set_selection (IMEngineInstanceBase *si,
431                         int              start,
432                         int              end)
433     {
434         LOGD ("");
435         thiz->set_selection (start, end);
436         return true;
437     }
438
439     void
440     slot_expand_candidate (IMEngineInstanceBase *si)
441     {
442         LOGD ("");
443         thiz->expand_candidate ();
444     }
445
446     void
447     slot_contract_candidate (IMEngineInstanceBase *si)
448     {
449         LOGD ("");
450         thiz->contract_candidate ();
451     }
452
453     void
454     slot_set_candidate_style (IMEngineInstanceBase *si, ISF_CANDIDATE_PORTRAIT_LINE_T portrait_line, ISF_CANDIDATE_MODE_T mode)
455     {
456         LOGD ("");
457         thiz->set_candidate_style (portrait_line, mode);
458     }
459
460     void
461     slot_send_private_command (IMEngineInstanceBase *si,
462                                const String &command)
463     {
464         LOGD ("");
465         thiz->send_private_command (command);
466     }
467
468     void
469     attach_instance ()
470     {
471         si->signal_connect_show_preedit_string (
472             slot (this, &HelperAgent::HelperAgentImpl::slot_show_preedit_string));
473         si->signal_connect_show_aux_string (
474             slot (this, &HelperAgent::HelperAgentImpl::slot_show_aux_string));
475         si->signal_connect_show_lookup_table (
476             slot (this, &HelperAgent::HelperAgentImpl::slot_show_lookup_table));
477
478         si->signal_connect_hide_preedit_string (
479             slot (this, &HelperAgent::HelperAgentImpl::slot_hide_preedit_string));
480         si->signal_connect_hide_aux_string (
481             slot (this, &HelperAgent::HelperAgentImpl::slot_hide_aux_string));
482         si->signal_connect_hide_lookup_table (
483             slot (this, &HelperAgent::HelperAgentImpl::slot_hide_lookup_table));
484
485         si->signal_connect_update_preedit_caret (
486             slot (this, &HelperAgent::HelperAgentImpl::slot_update_preedit_caret));
487         si->signal_connect_update_preedit_string (
488             slot (this, &HelperAgent::HelperAgentImpl::slot_update_preedit_string));
489         si->signal_connect_update_preedit_string_with_commit (
490             slot (this, &HelperAgent::HelperAgentImpl::slot_update_preedit_string_with_commit));
491
492         si->signal_connect_update_aux_string (
493             slot (this, &HelperAgent::HelperAgentImpl::slot_update_aux_string));
494         si->signal_connect_update_lookup_table (
495             slot (this, &HelperAgent::HelperAgentImpl::slot_update_lookup_table));
496
497         si->signal_connect_commit_string (
498             slot (this, &HelperAgent::HelperAgentImpl::slot_commit_string));
499
500         si->signal_connect_forward_key_event (
501             slot (this, &HelperAgent::HelperAgentImpl::slot_forward_key_event));
502
503         si->signal_connect_register_properties (
504             slot (this, &HelperAgent::HelperAgentImpl::slot_register_properties));
505
506         si->signal_connect_update_property (
507             slot (this, &HelperAgent::HelperAgentImpl::slot_update_property));
508
509         si->signal_connect_beep (
510             slot (this, &HelperAgent::HelperAgentImpl::slot_beep));
511
512         si->signal_connect_start_helper (
513             slot (this, &HelperAgent::HelperAgentImpl::slot_start_helper));
514
515         si->signal_connect_stop_helper (
516             slot (this, &HelperAgent::HelperAgentImpl::slot_stop_helper));
517
518         si->signal_connect_send_helper_event (
519             slot (this, &HelperAgent::HelperAgentImpl::slot_send_helper_event));
520
521         si->signal_connect_get_surrounding_text (
522             slot (this, &HelperAgent::HelperAgentImpl::slot_get_surrounding_text));
523
524         si->signal_connect_delete_surrounding_text (
525             slot (this, &HelperAgent::HelperAgentImpl::slot_delete_surrounding_text));
526
527         si->signal_connect_get_selection (
528             slot (this, &HelperAgent::HelperAgentImpl::slot_get_selection));
529
530         si->signal_connect_set_selection (
531             slot (this, &HelperAgent::HelperAgentImpl::slot_set_selection));
532
533         si->signal_connect_expand_candidate (
534             slot (this, &HelperAgent::HelperAgentImpl::slot_expand_candidate));
535         si->signal_connect_contract_candidate (
536             slot (this, &HelperAgent::HelperAgentImpl::slot_contract_candidate));
537
538         si->signal_connect_set_candidate_style (
539             slot (this, &HelperAgent::HelperAgentImpl::slot_set_candidate_style));
540
541         si->signal_connect_send_private_command (
542             slot (this, &HelperAgent::HelperAgentImpl::slot_send_private_command));
543     }
544 public:
545     void process_key_event_done(KeyEvent &key, uint32 ret, uint32 serial) {
546         LOGD ("ret: %d, serial: %d", ret, serial);
547         if (socket_active.is_connected ()) {
548             send.clear ();
549             send.put_command (SCIM_TRANS_CMD_REQUEST);
550             send.put_data (magic_active);
551             send.put_command (ISM_TRANS_CMD_PROCESS_KEY_EVENT_DONE);
552             send.put_data (key);
553             send.put_data (ret);
554             send.put_data (serial);
555             send.write_to_socket (socket_active, magic_active);
556         }
557     }
558 private:
559     HelperAgentImpl () : magic (0), magic_active (0), timeout (-1), focused_ic ((uint32) -1) { }
560 };
561
562 static MessageQueue message_queue;
563
564 HelperAgent::HelperAgent ()
565     : m_impl (new HelperAgentImpl (this))
566 {
567     message_queue.create();
568 }
569
570 HelperAgent::~HelperAgent ()
571 {
572     message_queue.destroy();
573     delete m_impl;
574 }
575
576 /**
577  * @brief Open socket connection to the Panel.
578  *
579  * @param info The information of this Helper object.
580  * @param display The display which this Helper object should run on.
581  *
582  * @return The connection socket id. -1 means failed to create
583  *         the connection.
584  */
585 int
586 HelperAgent::open_connection (const HelperInfo &info,
587                               const String     &display)
588 {
589     if (m_impl->socket.is_connected ())
590         close_connection ();
591
592     SocketAddress address (scim_get_default_panel_socket_address (display));
593     int timeout = m_impl->timeout = scim_get_default_socket_timeout ();
594     uint32 magic;
595
596     if (!address.valid ())
597         return -1;
598
599     int i = 0;
600     std::cerr << " Connecting to PanelAgent server.";
601     ISF_LOG (" Connecting to PanelAgent server.\n");
602     while (!m_impl->socket.connect (address)) {
603         std::cerr << ".";
604         scim_usleep (100000);
605         if (++i == 200) {
606             std::cerr << "m_impl->socket.connect () is failed!!!\n";
607             ISF_LOG ("m_impl->socket.connect () is failed!!!\n");
608             return -1;
609         }
610     }
611     std::cerr << " Connected :" << i << "\n";
612     ISF_LOG ("  Connected :%d\n", i);
613     LOGD ("Connection to PanelAgent succeeded, %d\n", i);
614
615     /* Let's retry 10 times when failed */
616     int open_connection_retries = 0;
617     while (!scim_socket_open_connection (magic,
618                                       String ("Helper"),
619                                       String ("Panel"),
620                                       m_impl->socket,
621                                       timeout)) {
622         if (++open_connection_retries > 10) {
623             m_impl->socket.close ();
624             std::cerr << "scim_socket_open_connection () is failed!!!\n";
625             ISF_LOG ("scim_socket_open_connection () is failed!!!\n");
626             ISF_SAVE_LOG ("scim_socket_open_connection failed, %d\n", timeout);
627
628             return -1;
629         }
630
631         /* Retry after re-connecting the socket */
632         if (m_impl->socket.is_connected ())
633             close_connection ();
634
635         /* This time, just retry atmost 2 seconds */
636         i = 0;
637         while (!m_impl->socket.connect (address) && ++i < 10) {
638             scim_usleep (200000);
639         }
640
641     }
642
643     ISF_LOG ("scim_socket_open_connection () is successful.\n");
644     LOGD ("scim_socket_open_connection successful\n");
645
646     bool match = false;
647     std::vector<ImeInfoDB> ime_info_db;
648     isf_db_select_all_ime_info (ime_info_db);
649     for (i = 0; i < (int)ime_info_db.size (); i++) {
650         if (ime_info_db[i].appid.compare (info.uuid) == 0) {
651             match = true;
652             break;
653         }
654     }
655
656     m_impl->send.clear ();
657     m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
658     m_impl->send.put_data (magic);
659     m_impl->send.put_command (SCIM_TRANS_CMD_PANEL_REGISTER_HELPER);
660     m_impl->send.put_data (info.uuid);
661     m_impl->send.put_data (match? ime_info_db[i].label : info.name);
662     m_impl->send.put_data (match? ime_info_db[i].iconpath : info.icon);
663     m_impl->send.put_data (info.description);
664     m_impl->send.put_data (match? ime_info_db[i].options : info.option);
665
666     if (!m_impl->send.write_to_socket (m_impl->socket, magic)) {
667         m_impl->socket.close ();
668         return -1;
669     }
670
671     int cmd;
672     if (m_impl->recv.read_from_socket (m_impl->socket, timeout) &&
673         m_impl->recv.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY &&
674         m_impl->recv.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) {
675         m_impl->magic = magic;
676
677         while (m_impl->recv.get_command (cmd)) {
678             switch (cmd) {
679                 case SCIM_TRANS_CMD_HELPER_ATTACH_INPUT_CONTEXT:
680                 {
681                     uint32 ic;
682                     String ic_uuid;
683                     while (m_impl->recv.get_data (ic) && m_impl->recv.get_data (ic_uuid))
684                         m_impl->signal_attach_input_context (this, ic, ic_uuid);
685                     break;
686                 }
687                 case SCIM_TRANS_CMD_UPDATE_SCREEN:
688                 {
689                     uint32 screen;
690                     if (m_impl->recv.get_data (screen))
691                         m_impl->signal_update_screen (this, (uint32) -1, String (""), (int) screen);
692                     break;
693                 }
694                 default:
695                     break;
696             }
697         }
698     } else {
699         //FIXME: Attaching input context is needed for desktop environment
700         LOGW ("Attach input context and update screen failed");
701     }
702
703     ISF_SAVE_LOG ("Trying connect() with Helper_Active\n");
704
705     /* connect to the panel agent as the active helper client */
706     if (!m_impl->socket_active.connect (address)) return -1;
707     if (!scim_socket_open_connection (magic,
708                                       String ("Helper_Active"),
709                                       String ("Panel"),
710                                       m_impl->socket_active,
711                                       timeout)) {
712         m_impl->socket_active.close ();
713         ISF_SAVE_LOG ("Helper_Active scim_socket_open_connection() failed %d\n", timeout);
714         return -1;
715     }
716
717     m_impl->magic_active = magic;
718
719     m_impl->send.clear ();
720     m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
721     m_impl->send.put_data (magic);
722     m_impl->send.put_command (SCIM_TRANS_CMD_PANEL_REGISTER_ACTIVE_HELPER);
723     m_impl->send.put_data (info.uuid);
724     m_impl->send.put_data (match? ime_info_db[i].label : info.name);
725     m_impl->send.put_data (match? ime_info_db[i].iconpath : info.icon);
726     m_impl->send.put_data (info.description);
727     m_impl->send.put_data (match? ime_info_db[i].options : info.option);
728
729     if (!m_impl->send.write_to_socket (m_impl->socket_active, magic)) {
730         ISF_SAVE_LOG ("Helper_Active write_to_socket() failed\n");
731         m_impl->socket_active.close ();
732         return -1;
733     }
734     m_impl->m_config = ConfigBase::get (false, "socket");
735
736     return m_impl->socket.get_id ();
737 }
738
739 /**
740  * @brief Close the socket connection to Panel.
741  */
742 void
743 HelperAgent::close_connection ()
744 {
745     m_impl->socket.close ();
746     m_impl->socket_active.close ();
747     m_impl->send.clear ();
748     m_impl->recv.clear ();
749     m_impl->magic        = 0;
750     m_impl->magic_active = 0;
751     m_impl->timeout      = 0;
752 }
753
754 /**
755  * @brief Get the connection id previously returned by open_connection().
756  *
757  * @return the connection id
758  */
759 int
760 HelperAgent::get_connection_number () const
761 {
762     if (m_impl->socket.is_connected ())
763         return m_impl->socket.get_id ();
764     return -1;
765 }
766
767 /**
768  * @brief Check whether this HelperAgent has been connected to a Panel.
769  *
770  * Return true when it is connected to panel, otherwise return false.
771  */
772 bool
773 HelperAgent::is_connected () const
774 {
775     return m_impl->socket.is_connected ();
776 }
777
778 /**
779  * @brief Check if there are any events available to be processed.
780  *
781  * If it returns true then Helper object should call
782  * HelperAgent::filter_event() to process them.
783  *
784  * @return true if there are any events available.
785  */
786 bool
787 HelperAgent::has_pending_event () const
788 {
789     if (m_impl->socket.is_connected () && m_impl->socket.wait_for_data (0) > 0)
790         return true;
791
792     if (message_queue.has_pending_message())
793         return true;
794
795     return false;
796 }
797
798 /**
799  * @brief Process the pending events.
800  *
801  * This function will emit the corresponding signals according
802  * to the events.
803  *
804  * @return false if the connection is broken, otherwise return true.
805  */
806 bool
807 HelperAgent::filter_event ()
808 {
809     if (!m_impl->socket.is_connected () || !m_impl->recv.read_from_socket (m_impl->socket, m_impl->timeout))
810         return false;
811
812     message_queue.read_from_transaction(m_impl->recv);
813
814     while (message_queue.has_pending_message()) {
815         MessageItem *message = message_queue.get_pending_message();
816         handle_message(message);
817         message_queue.remove_message(message);
818     }
819
820     return true;
821 }
822
823
824 /**
825  * @brief Read messages from socket buffer, and see if there is a message with the given cmd.
826  *
827  * @return false if the connection is broken, or no message available with given cmd. Otherwise return true.
828  */
829 bool
830 HelperAgent::wait_for_message(int cmd, int timeout)
831 {
832     struct timeval t0 = { 0, 0 };
833     struct timeval t1 = { 0, 0 };
834
835     gettimeofday(&t0, NULL);
836     int etime = 0;
837
838     do {
839         if (!m_impl->socket.is_connected() || !m_impl->recv.read_from_socket(m_impl->socket, timeout))
840             return false;
841
842         message_queue.read_from_transaction(m_impl->recv);
843         if (message_queue.get_pending_message_by_cmd(cmd)) {
844             return true;
845         }
846
847         gettimeofday(&t1, NULL);
848         etime = ((t1.tv_sec * 1000000 + t1.tv_usec) - (t0.tv_sec * 1000000 + t0.tv_usec)) / 1000;
849
850         usleep(100 * 1000);
851     } while (etime < timeout);
852
853     return false;
854 }
855
856 /**
857  * @brief Process one message that is in our message queue.
858  *
859  * This function will emit the corresponding signals according
860  * to the events.
861  *
862  * @param message The message that needs to be handled.
863  *
864  * @return false if the connection is broken, otherwise return true.
865  */
866 bool
867 HelperAgent::handle_message (MessageItem *message)
868 {
869     if (!message)
870         return false;
871
872     int cmd = message->get_command_ref();
873     LOGD ("HelperAgent::cmd = %d\n", cmd);
874     switch (cmd) {
875         case SCIM_TRANS_CMD_EXIT:
876         {
877             MessageItemExit *subclass = static_cast<MessageItemExit*>(message);
878             ISF_SAVE_LOG ("Helper ISE received SCIM_TRANS_CMD_EXIT message\n");
879             m_impl->signal_exit(this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
880             break;
881         }
882         case SCIM_TRANS_CMD_RELOAD_CONFIG:
883         {
884             MessageItemReloadConfig *subclass = static_cast<MessageItemReloadConfig*>(message);
885             m_impl->signal_reload_config (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
886             if (!m_impl->m_config.null())
887                 m_impl->m_config->ConfigBase::reload();
888             break;
889         }
890         case SCIM_TRANS_CMD_UPDATE_SCREEN:
891         {
892             MessageItemUpdateScreen *subclass = static_cast<MessageItemUpdateScreen*>(message);
893             m_impl->signal_update_screen (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
894                 subclass->get_screen_ref());
895             break;
896         }
897         case SCIM_TRANS_CMD_UPDATE_SPOT_LOCATION:
898         {
899             MessageItemUpdateSpotLocation *subclass = static_cast<MessageItemUpdateSpotLocation*>(message);
900             m_impl->signal_update_spot_location (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
901                 subclass->get_x_ref(), subclass->get_y_ref());
902             break;
903         }
904         case ISM_TRANS_CMD_UPDATE_CURSOR_POSITION:
905         {
906             MessageItemUpdateCursorPosition *subclass = static_cast<MessageItemUpdateCursorPosition*>(message);
907             m_impl->cursor_pos = subclass->get_cursor_pos_ref();
908             LOGD ("update cursor position %d", subclass->get_cursor_pos_ref());
909             m_impl->signal_update_cursor_position (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
910                 subclass->get_cursor_pos_ref());
911             if (!m_impl->si.null ()) m_impl->si->update_cursor_position(subclass->get_cursor_pos_ref());
912             break;
913         }
914         case ISM_TRANS_CMD_UPDATE_SURROUNDING_TEXT:
915         {
916             MessageItemUpdateSurroundingText *subclass = static_cast<MessageItemUpdateSurroundingText*>(message);
917             if (m_impl->surrounding_text != NULL)
918                 free (m_impl->surrounding_text);
919             m_impl->surrounding_text = strdup (subclass->get_text_ref().c_str ());
920             m_impl->cursor_pos = subclass->get_cursor_ref();
921             LOGD ("surrounding text: %s, %d", m_impl->surrounding_text, subclass->get_cursor_ref());
922             while (m_impl->need_update_surrounding_text > 0) {
923                 m_impl->need_update_surrounding_text--;
924                 m_impl->signal_update_surrounding_text (this, subclass->get_ic_ref(),
925                     subclass->get_text_ref(), subclass->get_cursor_ref());
926             }
927             break;
928         }
929         case ISM_TRANS_CMD_UPDATE_SELECTION:
930         {
931             MessageItemUpdateSelection *subclass = static_cast<MessageItemUpdateSelection*>(message);
932             if (m_impl->selection_text != NULL)
933                 free (m_impl->selection_text);
934
935             m_impl->selection_text = strdup (subclass->get_text_ref().c_str ());
936             LOGD ("selection text: %s", m_impl->selection_text);
937
938             while (m_impl->need_update_selection_text > 0) {
939                 m_impl->need_update_selection_text--;
940                 m_impl->signal_update_selection (this, subclass->get_ic_ref(), subclass->get_text_ref());
941             }
942             break;
943         }
944         case SCIM_TRANS_CMD_TRIGGER_PROPERTY:
945         {
946             MessageItemTriggerProperty *subclass = static_cast<MessageItemTriggerProperty*>(message);
947             m_impl->signal_trigger_property (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
948                 subclass->get_property_ref());
949             if (!m_impl->si.null ()) m_impl->si->trigger_property(subclass->get_property_ref());
950             break;
951         }
952         case SCIM_TRANS_CMD_HELPER_PROCESS_IMENGINE_EVENT:
953         {
954             MessageItemHelperProcessImengineEvent *subclass = static_cast<MessageItemHelperProcessImengineEvent*>(message);
955             m_impl->signal_process_imengine_event (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
956                 subclass->get_transaction_ref());
957             break;
958         }
959         case SCIM_TRANS_CMD_HELPER_ATTACH_INPUT_CONTEXT:
960         {
961             MessageItemHelperAttachInputContext *subclass = static_cast<MessageItemHelperAttachInputContext*>(message);
962             m_impl->signal_attach_input_context (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
963             break;
964         }
965         case SCIM_TRANS_CMD_HELPER_DETACH_INPUT_CONTEXT:
966         {
967             MessageItemHelperDetachInputContext *subclass = static_cast<MessageItemHelperDetachInputContext*>(message);
968             m_impl->signal_detach_input_context (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
969             break;
970         }
971         case SCIM_TRANS_CMD_FOCUS_OUT:
972         {
973             MessageItemFocusOut *subclass = static_cast<MessageItemFocusOut*>(message);
974             m_impl->signal_focus_out (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
975             m_impl->focused_ic = (uint32) -1;
976             if (!m_impl->si.null ()) m_impl->si->focus_out();
977             break;
978         }
979         case SCIM_TRANS_CMD_FOCUS_IN:
980         {
981             MessageItemFocusIn *subclass = static_cast<MessageItemFocusIn*>(message);
982             m_impl->signal_focus_in (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
983             m_impl->focused_ic = subclass->get_ic_ref();
984             if (!m_impl->si.null ()) m_impl->si->focus_in();
985             break;
986         }
987         case ISM_TRANS_CMD_SHOW_ISE_PANEL:
988         {
989             MessageItemShowISEPanel *subclass = static_cast<MessageItemShowISEPanel*>(message);
990             LOGD ("Helper ISE received ISM_TRANS_CMD_SHOW_ISE_PANEL message\n");
991
992             m_impl->signal_ise_show (this, subclass->get_ic_ref(), *(subclass->get_data_ptr()),
993                 subclass->get_len_ref());
994             break;
995         }
996         case ISM_TRANS_CMD_HIDE_ISE_PANEL:
997         {
998             MessageItemHideISEPanel *subclass = static_cast<MessageItemHideISEPanel*>(message);
999             LOGD ("Helper ISE received ISM_TRANS_CMD_HIDE_ISE_PANEL message\n");
1000             m_impl->signal_ise_hide (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1001             break;
1002         }
1003         case ISM_TRANS_CMD_GET_ACTIVE_ISE_GEOMETRY:
1004         {
1005             struct rectinfo info = {0, 0, 0, 0};
1006             m_impl->signal_get_geometry (this, info);
1007             m_impl->send.clear ();
1008             m_impl->send.put_command (SCIM_TRANS_CMD_REPLY);
1009             m_impl->send.put_data (info.pos_x);
1010             m_impl->send.put_data (info.pos_y);
1011             m_impl->send.put_data (info.width);
1012             m_impl->send.put_data (info.height);
1013             m_impl->send.write_to_socket (m_impl->socket);
1014             break;
1015         }
1016         case ISM_TRANS_CMD_SET_ISE_MODE:
1017         {
1018             MessageItemSetISEMode *subclass = static_cast<MessageItemSetISEMode*>(message);
1019             m_impl->signal_set_mode (this, subclass->get_mode_ref());
1020             break;
1021         }
1022         case ISM_TRANS_CMD_SET_ISE_LANGUAGE:
1023         {
1024             MessageItemSetISELanguage *subclass = static_cast<MessageItemSetISELanguage*>(message);
1025             m_impl->signal_set_language (this, subclass->get_language_ref());
1026             break;
1027         }
1028         case ISM_TRANS_CMD_SET_ISE_IMDATA:
1029         {
1030             MessageItemSetISEImData *subclass = static_cast<MessageItemSetISEImData*>(message);
1031             m_impl->signal_set_imdata (this, *(subclass->get_imdata_ptr()), subclass->get_len_ref());
1032             if (!m_impl->si.null ()) m_impl->si->set_imdata(*(subclass->get_imdata_ptr()),
1033                 subclass->get_len_ref());
1034             break;
1035         }
1036         case ISM_TRANS_CMD_GET_ISE_IMDATA:
1037         {
1038             char   *buf = NULL;
1039             size_t  len = 0;
1040
1041             m_impl->signal_get_imdata (this, &buf, len);
1042             LOGD ("send ise imdata len = %d", len);
1043             m_impl->send.clear ();
1044             m_impl->send.put_command (SCIM_TRANS_CMD_REPLY);
1045             m_impl->send.put_data (buf, len);
1046             m_impl->send.write_to_socket (m_impl->socket);
1047             if (NULL != buf)
1048                 delete[] buf;
1049             break;
1050         }
1051         case ISM_TRANS_CMD_GET_ISE_LANGUAGE_LOCALE:
1052         {
1053             MessageItemGetISELanguageLocale *subclass = static_cast<MessageItemGetISELanguageLocale*>(message);
1054             char *buf = NULL;
1055             m_impl->signal_get_language_locale (this, subclass->get_ic_ref(), &buf);
1056             m_impl->send.clear ();
1057             m_impl->send.put_command (SCIM_TRANS_CMD_REPLY);
1058             if (buf != NULL)
1059                 m_impl->send.put_data (buf, strlen (buf));
1060             m_impl->send.write_to_socket (m_impl->socket);
1061             if (NULL != buf)
1062                 delete[] buf;
1063             break;
1064         }
1065         case ISM_TRANS_CMD_SET_RETURN_KEY_TYPE:
1066         {
1067             MessageItemSetReturnKeyType *subclass = static_cast<MessageItemSetReturnKeyType*>(message);
1068             m_impl->signal_set_return_key_type (this, subclass->get_type_ref());
1069             break;
1070         }
1071         case ISM_TRANS_CMD_GET_RETURN_KEY_TYPE:
1072         {
1073             uint32 type = 0;
1074             m_impl->signal_get_return_key_type (this, type);
1075             m_impl->send.clear ();
1076             m_impl->send.put_command (SCIM_TRANS_CMD_REPLY);
1077             m_impl->send.put_data (type);
1078             m_impl->send.write_to_socket (m_impl->socket);
1079             break;
1080         }
1081         case ISM_TRANS_CMD_SET_RETURN_KEY_DISABLE:
1082         {
1083             MessageItemSetReturnKeyDisable *subclass = static_cast<MessageItemSetReturnKeyDisable*>(message);
1084             m_impl->signal_set_return_key_disable (this, subclass->get_disabled_ref());
1085             break;
1086         }
1087         case ISM_TRANS_CMD_GET_RETURN_KEY_DISABLE:
1088         {
1089             uint32 disabled = 0;
1090             m_impl->signal_get_return_key_type (this, disabled);
1091             m_impl->send.clear ();
1092             m_impl->send.put_command (SCIM_TRANS_CMD_REPLY);
1093             m_impl->send.put_data (disabled);
1094             m_impl->send.write_to_socket (m_impl->socket);
1095             break;
1096         }
1097         case SCIM_TRANS_CMD_PROCESS_KEY_EVENT:
1098         {
1099             MessageItemProcessKeyEvent *subclass = static_cast<MessageItemProcessKeyEvent*>(message);
1100             uint32 ret = 0;
1101             m_impl->signal_process_key_event(this, subclass->get_key_ref(), ret);
1102             if (ret == 0)
1103                 if (!m_impl->si.null ())
1104                 {
1105                     ret = m_impl->si->process_key_event (subclass->get_key_ref());
1106                     LOGD("imengine(%s) process key %d return %d", m_impl->si->get_factory_uuid().c_str(),
1107                         subclass->get_key_ref().code, ret);
1108                 }
1109             m_impl->process_key_event_done (subclass->get_key_ref(), ret, subclass->get_serial_ref());
1110             break;
1111         }
1112         case ISM_TRANS_CMD_SET_LAYOUT:
1113         {
1114             MessageItemSetLayout *subclass = static_cast<MessageItemSetLayout*>(message);
1115             m_impl->layout = subclass->get_layout_ref();
1116             m_impl->signal_set_layout (this, subclass->get_layout_ref());
1117             if (!m_impl->si.null ()) m_impl->si->set_layout(subclass->get_layout_ref());
1118             break;
1119         }
1120         case ISM_TRANS_CMD_GET_LAYOUT:
1121         {
1122             uint32 layout = 0;
1123
1124             m_impl->signal_get_layout (this, layout);
1125             m_impl->send.clear ();
1126             m_impl->send.put_command (SCIM_TRANS_CMD_REPLY);
1127             m_impl->send.put_data (layout);
1128             m_impl->send.write_to_socket (m_impl->socket);
1129             break;
1130         }
1131         case ISM_TRANS_CMD_SET_INPUT_MODE:
1132         {
1133             MessageItemSetInputMode *subclass = static_cast<MessageItemSetInputMode*>(message);
1134             m_impl->signal_set_input_mode (this, subclass->get_input_mode_ref());
1135             break;
1136         }
1137         case ISM_TRANS_CMD_SET_CAPS_MODE:
1138         {
1139             MessageItemSetCapsMode *subclass = static_cast<MessageItemSetCapsMode*>(message);
1140             m_impl->signal_set_caps_mode (this, subclass->get_mode_ref());
1141             break;
1142         }
1143         case SCIM_TRANS_CMD_PANEL_RESET_INPUT_CONTEXT:
1144         {
1145             MessageItemPanelResetInputContext *subclass = static_cast<MessageItemPanelResetInputContext*>(message);
1146             m_impl->signal_reset_input_context (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1147             if (!m_impl->si.null ()) m_impl->si->reset();
1148             break;
1149         }
1150         case ISM_TRANS_CMD_UPDATE_CANDIDATE_UI:
1151         {
1152             MessageItemUpdateCandidateUI *subclass = static_cast<MessageItemUpdateCandidateUI*>(message);
1153             m_impl->signal_update_candidate_ui (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
1154                 subclass->get_style_ref(), subclass->get_mode_ref());
1155             break;
1156         }
1157         case ISM_TRANS_CMD_UPDATE_CANDIDATE_GEOMETRY:
1158         {
1159             MessageItemUpdateCandidateGeometry *subclass = static_cast<MessageItemUpdateCandidateGeometry*>(message);
1160             m_impl->signal_update_candidate_geometry (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
1161                 subclass->get_rectinfo_ref());
1162             break;
1163         }
1164         case ISM_TRANS_CMD_UPDATE_KEYBOARD_ISE:
1165         {
1166             MessageItemUpdateKeyboardISE *subclass = static_cast<MessageItemUpdateKeyboardISE*>(message);
1167             m_impl->signal_update_keyboard_ise (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
1168                 subclass->get_name_ref(), subclass->get_uuid_ref());
1169             break;
1170         }
1171         case ISM_TRANS_CMD_UPDATE_KEYBOARD_ISE_LIST:
1172         {
1173             MessageItemUpdateKeyboardISEList *subclass = static_cast<MessageItemUpdateKeyboardISEList*>(message);
1174             m_impl->signal_update_keyboard_ise_list (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
1175                 subclass->get_list_ref());
1176             break;
1177         }
1178         case ISM_TRANS_CMD_CANDIDATE_MORE_WINDOW_SHOW:
1179         {
1180             MessageItemCandidateMoreWindowShow *subclass = static_cast<MessageItemCandidateMoreWindowShow*>(message);
1181             m_impl->signal_candidate_more_window_show (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1182             if (!m_impl->si.null ()) m_impl->si->candidate_more_window_show();
1183             break;
1184         }
1185         case ISM_TRANS_CMD_CANDIDATE_MORE_WINDOW_HIDE:
1186         {
1187             MessageItemCandidateMoreWindowHide *subclass = static_cast<MessageItemCandidateMoreWindowHide*>(message);
1188             m_impl->signal_candidate_more_window_hide (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1189             if (!m_impl->si.null ()) m_impl->si->candidate_more_window_hide();
1190             break;
1191         }
1192         case ISM_TRANS_CMD_SELECT_AUX:
1193         {
1194             MessageItemSelectAux *subclass = static_cast<MessageItemSelectAux*>(message);
1195             m_impl->signal_select_aux (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
1196                 subclass->get_item_ref());
1197             if (!m_impl->si.null ()) m_impl->si->select_aux(subclass->get_item_ref());
1198             break;
1199         }
1200         case SCIM_TRANS_CMD_SELECT_CANDIDATE: //FIXME:remove if useless
1201         {
1202             MessageItemSelectCandidate *subclass = static_cast<MessageItemSelectCandidate*>(message);
1203             m_impl->signal_select_candidate (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
1204                 subclass->get_item_ref());
1205             if (!m_impl->si.null ()) m_impl->si->select_candidate(subclass->get_item_ref());
1206             break;
1207         }
1208         case SCIM_TRANS_CMD_LOOKUP_TABLE_PAGE_UP: //FIXME:remove if useless
1209         {
1210             MessageItemLookupTablePageUp *subclass = static_cast<MessageItemLookupTablePageUp*>(message);
1211             m_impl->signal_candidate_table_page_up (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1212             if (!m_impl->si.null ()) m_impl->si->lookup_table_page_up();
1213             break;
1214         }
1215         case SCIM_TRANS_CMD_LOOKUP_TABLE_PAGE_DOWN: //FIXME:remove if useless
1216         {
1217             MessageItemLookupTablePageDown *subclass = static_cast<MessageItemLookupTablePageDown*>(message);
1218             m_impl->signal_candidate_table_page_down (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1219             if (!m_impl->si.null ()) m_impl->si->lookup_table_page_down();
1220             break;
1221         }
1222         case SCIM_TRANS_CMD_UPDATE_LOOKUP_TABLE_PAGE_SIZE:
1223         {
1224             MessageItemUpdateLookupTablePageSize *subclass = static_cast<MessageItemUpdateLookupTablePageSize*>(message);
1225             m_impl->signal_update_candidate_table_page_size (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
1226                 subclass->get_size_ref());
1227             if (!m_impl->si.null ()) m_impl->si->update_lookup_table_page_size(subclass->get_size_ref());
1228             break;
1229         }
1230         case ISM_TRANS_CMD_CANDIDATE_SHOW: //FIXME:remove if useless
1231         {
1232             MessageItemCandidateShow *subclass = static_cast<MessageItemCandidateShow*>(message);
1233             m_impl->signal_candidate_show (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1234             break;
1235         }
1236         case ISM_TRANS_CMD_CANDIDATE_HIDE: //FIXME:remove if useless
1237         {
1238             MessageItemCandidateHide *subclass = static_cast<MessageItemCandidateHide*>(message);
1239             m_impl->signal_candidate_hide (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1240             break;
1241         }
1242         case ISM_TRANS_CMD_UPDATE_LOOKUP_TABLE: //FIXME:remove if useless
1243         {
1244             MessageItemUpdateLookupTable *subclass = static_cast<MessageItemUpdateLookupTable*>(message);
1245             m_impl->signal_update_lookup_table (this, subclass->get_candidate_table_ref());
1246             break;
1247         }
1248         case ISM_TRANS_CMD_UPDATE_CANDIDATE_ITEM_LAYOUT:
1249         {
1250             MessageItemUpdateCandidateItemLayout *subclass = static_cast<MessageItemUpdateCandidateItemLayout*>(message);
1251             m_impl->signal_update_candidate_item_layout (this, subclass->get_row_items_ref());
1252             if (!m_impl->si.null ()) m_impl->si->update_candidate_item_layout(subclass->get_row_items_ref());
1253             break;
1254         }
1255         case ISM_TRANS_CMD_SELECT_ASSOCIATE:
1256         {
1257             MessageItemSelectAssociate *subclass = static_cast<MessageItemSelectAssociate*>(message);
1258             m_impl->signal_select_associate (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
1259                 subclass->get_item_ref());
1260             break;
1261         }
1262         case ISM_TRANS_CMD_ASSOCIATE_TABLE_PAGE_UP:
1263         {
1264             MessageItemAssociateTablePageUp *subclass = static_cast<MessageItemAssociateTablePageUp*>(message);
1265             m_impl->signal_associate_table_page_up (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1266             break;
1267         }
1268         case ISM_TRANS_CMD_ASSOCIATE_TABLE_PAGE_DOWN:
1269         {
1270             MessageItemAssociateTablePageDown *subclass = static_cast<MessageItemAssociateTablePageDown*>(message);
1271             m_impl->signal_associate_table_page_down (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1272             break;
1273         }
1274         case ISM_TRANS_CMD_UPDATE_ASSOCIATE_TABLE_PAGE_SIZE:
1275         {
1276             MessageItemUpdateAssociateTablePageSize *subclass = static_cast<MessageItemUpdateAssociateTablePageSize*>(message);
1277             m_impl->signal_update_associate_table_page_size (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
1278                 subclass->get_size_ref());
1279             break;
1280         }
1281         case ISM_TRANS_CMD_RESET_ISE_CONTEXT:
1282         {
1283             MessageItemResetISEContext *subclass = static_cast<MessageItemResetISEContext*>(message);
1284             m_impl->signal_reset_ise_context (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1285             m_impl->signal_reset_input_context (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1286             if (!m_impl->si.null ()) m_impl->si->reset();
1287             break;
1288         }
1289         case ISM_TRANS_CMD_TURN_ON_LOG:
1290         {
1291             MessageItemTurnOnLog *subclass = static_cast<MessageItemTurnOnLog*>(message);
1292             m_impl->signal_turn_on_log (this, subclass->get_state_ref());
1293             break;
1294         }
1295         case ISM_TRANS_CMD_UPDATE_DISPLAYED_CANDIDATE:
1296         {
1297             MessageItemUpdateDisplayedCandidate *subclass = static_cast<MessageItemUpdateDisplayedCandidate*>(message);
1298             m_impl->signal_update_displayed_candidate_number (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
1299                 subclass->get_size_ref());
1300             if (!m_impl->si.null ()) m_impl->si->update_displayed_candidate_number(subclass->get_size_ref());
1301             break;
1302         }
1303         case ISM_TRANS_CMD_LONGPRESS_CANDIDATE:
1304         {
1305             MessageItemLongpressCandidate *subclass = static_cast<MessageItemLongpressCandidate*>(message);
1306             m_impl->signal_longpress_candidate (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
1307                 subclass->get_index_ref());
1308             if (!m_impl->si.null ()) m_impl->si->longpress_candidate(subclass->get_index_ref());
1309             break;
1310         }
1311         case ISM_TRANS_CMD_SET_INPUT_HINT:
1312         {
1313             MessageItemSetInputHint *subclass = static_cast<MessageItemSetInputHint*>(message);
1314             m_impl->signal_set_input_hint (this, subclass->get_input_hint_ref());
1315             if (!m_impl->si.null ()) m_impl->si->set_input_hint(subclass->get_input_hint_ref());
1316             break;
1317         }
1318         case ISM_TRANS_CMD_UPDATE_BIDI_DIRECTION:
1319         {
1320             MessageItemUpdateBidiDirection *subclass = static_cast<MessageItemUpdateBidiDirection*>(message);
1321             m_impl->signal_update_bidi_direction (this, subclass->get_bidi_direction());
1322             if (!m_impl->si.null ()) m_impl->si->update_bidi_direction(subclass->get_bidi_direction());
1323             break;
1324         }
1325         case ISM_TRANS_CMD_SHOW_ISE_OPTION_WINDOW:
1326         {
1327             MessageItemShowISEOptionWindow *subclass = static_cast<MessageItemShowISEOptionWindow*>(message);
1328             m_impl->signal_show_option_window (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1329             break;
1330         }
1331         case ISM_TRANS_CMD_CHECK_OPTION_WINDOW:
1332         {
1333             uint32 avail = 0;
1334             m_impl->signal_check_option_window (this, avail);
1335             m_impl->send.clear ();
1336             m_impl->send.put_command (SCIM_TRANS_CMD_REPLY);
1337             m_impl->send.put_data (avail);
1338             m_impl->send.write_to_socket (m_impl->socket);
1339             break;
1340         }
1341         case ISM_TRANS_CMD_PROCESS_INPUT_DEVICE_EVENT:
1342         {
1343             MessageItemProcessInputDeviceEvent *subclass = static_cast<MessageItemProcessInputDeviceEvent*>(message);
1344             uint32 ret = 0;
1345             m_impl->signal_process_input_device_event(this,
1346                 subclass->get_type_ref(), *(subclass->get_data_ptr()), subclass->get_len_ref(), ret);
1347             m_impl->send.clear();
1348             m_impl->send.put_command(SCIM_TRANS_CMD_REPLY);
1349             m_impl->send.put_data(ret);
1350             m_impl->send.write_to_socket(m_impl->socket);
1351             break;
1352         }
1353         case SCIM_TRANS_CMD_SET_AUTOCAPITAL_TYPE:
1354         {
1355             MessageItemSetAutocapitalType *subclass = static_cast<MessageItemSetAutocapitalType*>(message);
1356             if (!m_impl->si.null ()) m_impl->si->set_autocapital_type(subclass->get_auto_capital_type_ref());
1357             break;
1358         }
1359         default:
1360             break;
1361     }
1362     return true;
1363 }
1364
1365 /**
1366  * @brief Request SCIM to reload all configuration.
1367  *
1368  * This function should only by used by Setup Helper to request
1369  * scim's reloading the configuration.
1370  */
1371 void
1372 HelperAgent::reload_config () const
1373 {
1374     LOGD ("");
1375 #if 0 //reload config message only send by socketconfig client
1376     if (m_impl->socket_active.is_connected ()) {
1377         m_impl->send.clear ();
1378         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1379         m_impl->send.put_data (m_impl->magic_active);
1380         m_impl->send.put_command (SCIM_TRANS_CMD_RELOAD_CONFIG);
1381         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1382     }
1383 #endif
1384     if (!m_impl->m_config.null())
1385         m_impl->m_config->reload();
1386 }
1387
1388 /**
1389  * @brief Register some properties into Panel.
1390  *
1391  * This function send the request to Panel to register a list
1392  * of Properties.
1393  *
1394  * @param properties The list of Properties to be registered into Panel.
1395  *
1396  * @sa scim::Property.
1397  */
1398 void
1399 HelperAgent::register_properties (const PropertyList &properties) const
1400 {
1401     LOGD ("");
1402     if (m_impl->socket_active.is_connected ()) {
1403         m_impl->send.clear ();
1404         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1405         m_impl->send.put_data (m_impl->magic_active);
1406         m_impl->send.put_command (SCIM_TRANS_CMD_REGISTER_PROPERTIES);
1407         m_impl->send.put_data (properties);
1408         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1409     }
1410 }
1411
1412 /**
1413  * @brief Update a registered property.
1414  *
1415  * @param property The property to be updated.
1416  */
1417 void
1418 HelperAgent::update_property (const Property &property) const
1419 {
1420     LOGD ("");
1421     if (m_impl->socket_active.is_connected ()) {
1422         m_impl->send.clear ();
1423         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1424         m_impl->send.put_data (m_impl->magic_active);
1425         m_impl->send.put_command (SCIM_TRANS_CMD_UPDATE_PROPERTY);
1426         m_impl->send.put_data (property);
1427         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1428     }
1429 }
1430
1431 /**
1432  * @brief Send a set of events to an IMEngineInstance.
1433  *
1434  * All events should be put into a Transaction.
1435  * And the events can only be received by one IMEngineInstance object.
1436  *
1437  * @param ic The handle of the Input Context to receive the events.
1438  * @param ic_uuid The UUID of the Input Context.
1439  * @param trans The Transaction object holds the events.
1440  */
1441 void
1442 HelperAgent::send_imengine_event (int                ic,
1443                                   const String      &ic_uuid,
1444                                   const Transaction &trans) const
1445 {
1446     LOGD ("");
1447 //remove if not necessary
1448 #if 0
1449     if (m_impl->socket_active.is_connected ()) {
1450         m_impl->send.clear ();
1451         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1452         m_impl->send.put_data (m_impl->magic_active);
1453         m_impl->send.put_command (SCIM_TRANS_CMD_PANEL_SEND_IMENGINE_EVENT);
1454         m_impl->send.put_data ((uint32)ic);
1455         m_impl->send.put_data (ic_uuid);
1456         m_impl->send.put_data (trans);
1457         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1458     }
1459 #endif
1460     if (!m_impl->si.null ()) m_impl->si->process_helper_event (ic_uuid, trans);
1461 }
1462
1463 /**
1464  * @brief Send a KeyEvent to an IMEngineInstance.
1465  *
1466  * @param ic The handle of the IMEngineInstance to receive the event.
1467  *        -1 means the currently focused IMEngineInstance.
1468  * @param ic_uuid The UUID of the IMEngineInstance. Empty means don't match.
1469  * @param key The KeyEvent to be sent.
1470  */
1471 void
1472 HelperAgent::send_key_event (int            ic,
1473                              const String   &ic_uuid,
1474                              const KeyEvent &key) const
1475 {
1476     LOGD ("");
1477
1478     //FIXME: remove shift_mode_off, shift_mode_on, shift_mode_lock from ISE side
1479     if (key.code == SHIFT_MODE_OFF ||
1480         key.code == SHIFT_MODE_ON ||
1481         key.code == SHIFT_MODE_LOCK ||
1482         key.code == SHIFT_MODE_ENABLE ||
1483         key.code == SHIFT_MODE_DISABLE) {
1484         LOGW("FIXME ignore shift codes");
1485         return;
1486     }
1487
1488     bool ret = false;
1489
1490 #if ENABLE_GRAB_KEYBOARD
1491     if (!m_impl->si.null ()) {
1492 #else
1493     if (key.code <= 0x7F ||
1494         (key.code >= SCIM_KEY_BackSpace && key.code <= SCIM_KEY_Delete) ||
1495         (key.code >= SCIM_KEY_Home && key.code <= SCIM_KEY_Hyper_R)) {
1496         // ascii code and function keys
1497         ret = false;
1498     } else {
1499         ret = true;
1500     }
1501
1502     if (ret && (!m_impl->si.null ())) {
1503 #endif
1504         ret = m_impl->si->process_key_event (key);
1505         LOGD ("imengine(%s) process key %d return %d", m_impl->si->get_factory_uuid().c_str(), key.code, ret);
1506     }
1507
1508     if (ret == false && m_impl->socket_active.is_connected ()) {
1509         m_impl->send.clear ();
1510         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1511         m_impl->send.put_data (m_impl->magic_active);
1512         m_impl->send.put_command (SCIM_TRANS_CMD_PANEL_SEND_KEY_EVENT);
1513         if (ic == -1) {
1514             m_impl->send.put_data (m_impl->focused_ic);
1515         } else {
1516             m_impl->send.put_data ((uint32)ic);
1517         }
1518         m_impl->send.put_data (ic_uuid);
1519         m_impl->send.put_data (key);
1520         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1521     }
1522 }
1523
1524 /**
1525  * @brief Forward a KeyEvent to client application directly.
1526  *
1527  * @param ic The handle of the client Input Context to receive the event.
1528  *        -1 means the currently focused Input Context.
1529  * @param ic_uuid The UUID of the IMEngine used by the Input Context.
1530  *        Empty means don't match.
1531  * @param key The KeyEvent to be forwarded.
1532  */
1533 void
1534 HelperAgent::forward_key_event (int            ic,
1535                                 const String   &ic_uuid,
1536                                 const KeyEvent &key) const
1537 {
1538     LOGD ("");
1539     if (m_impl->socket_active.is_connected ()) {
1540         m_impl->send.clear ();
1541         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1542         m_impl->send.put_data (m_impl->magic_active);
1543         m_impl->send.put_command (SCIM_TRANS_CMD_FORWARD_KEY_EVENT);
1544         if (ic == -1) {
1545             m_impl->send.put_data (m_impl->focused_ic);
1546         } else {
1547             m_impl->send.put_data ((uint32)ic);
1548         }
1549         m_impl->send.put_data (ic_uuid);
1550         m_impl->send.put_data (key);
1551         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1552     }
1553 }
1554
1555 /**
1556  * @brief Commit a WideString to client application directly.
1557  *
1558  * @param ic The handle of the client Input Context to receive the WideString.
1559  *        -1 means the currently focused Input Context.
1560  * @param ic_uuid The UUID of the IMEngine used by the Input Context.
1561  *        Empty means don't match.
1562  * @param wstr The WideString to be committed.
1563  */
1564 void
1565 HelperAgent::commit_string (int               ic,
1566                             const String     &ic_uuid,
1567                             const WideString &wstr) const
1568 {
1569     LOGD ("");
1570     if (m_impl->socket_active.is_connected ()) {
1571         m_impl->send.clear ();
1572         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1573         m_impl->send.put_data (m_impl->magic_active);
1574         m_impl->send.put_command (SCIM_TRANS_CMD_COMMIT_STRING);
1575         if (ic == -1) {
1576             m_impl->send.put_data (m_impl->focused_ic);
1577         } else {
1578             m_impl->send.put_data ((uint32)ic);
1579         }
1580         m_impl->send.put_data (ic_uuid);
1581         m_impl->send.put_data (wstr);
1582         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1583     }
1584 }
1585
1586 void
1587 HelperAgent::commit_string (int               ic,
1588                             const String     &ic_uuid,
1589                             const  char      *buf,
1590                             int               buflen) const
1591 {
1592     LOGD ("");
1593     if (m_impl->socket_active.is_connected ()) {
1594         m_impl->send.clear ();
1595         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1596         m_impl->send.put_data (m_impl->magic_active);
1597         m_impl->send.put_command (SCIM_TRANS_CMD_COMMIT_STRING);
1598         if (ic == -1) {
1599             m_impl->send.put_data (m_impl->focused_ic);
1600         } else {
1601             m_impl->send.put_data ((uint32)ic);
1602         }
1603         m_impl->send.put_data (ic_uuid);
1604         m_impl->send.put_dataw (buf, buflen);
1605         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1606     }
1607 }
1608
1609 /**
1610  * @brief Request to show preedit string.
1611  *
1612  * @param ic The handle of the client Input Context to receive the request.
1613  *        -1 means the currently focused Input Context.
1614  * @param ic_uuid The UUID of the IMEngine used by the Input Context.
1615  *        Empty means don't match.
1616  */
1617 void
1618 HelperAgent::show_preedit_string (int               ic,
1619                                   const String     &ic_uuid) const
1620 {
1621     LOGD ("");
1622
1623     if (m_impl->socket_active.is_connected ()) {
1624         m_impl->send.clear ();
1625         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1626         m_impl->send.put_data (m_impl->magic_active);
1627         m_impl->send.put_command (SCIM_TRANS_CMD_SHOW_PREEDIT_STRING);
1628         m_impl->send.put_data ((uint32)ic);
1629         m_impl->send.put_data (ic_uuid);
1630         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1631     }
1632 }
1633
1634 /**
1635  * @brief Request to show aux string.
1636  */
1637 void
1638 HelperAgent::show_aux_string (void) const
1639 {
1640     LOGD ("");
1641
1642     if (m_impl->socket_active.is_connected ()) {
1643         m_impl->send.clear ();
1644         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1645         m_impl->send.put_data (m_impl->magic_active);
1646         m_impl->send.put_command (SCIM_TRANS_CMD_SHOW_AUX_STRING);
1647         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1648     }
1649 }
1650
1651 /**
1652  * @brief Request to show candidate string.
1653  */
1654 void
1655 HelperAgent::show_candidate_string (void) const
1656 {
1657     LOGD ("");
1658
1659     if (m_impl->socket_active.is_connected ()) {
1660         m_impl->send.clear ();
1661         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1662         m_impl->send.put_data (m_impl->magic_active);
1663         m_impl->send.put_command (SCIM_TRANS_CMD_SHOW_LOOKUP_TABLE);
1664         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1665     }
1666 }
1667
1668 /**
1669  * @brief Request to show associate string.
1670  */
1671 void
1672 HelperAgent::show_associate_string (void) const
1673 {
1674     LOGD ("");
1675     if (m_impl->socket_active.is_connected ()) {
1676         m_impl->send.clear ();
1677         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1678         m_impl->send.put_data (m_impl->magic_active);
1679         m_impl->send.put_command (ISM_TRANS_CMD_SHOW_ASSOCIATE_TABLE);
1680         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1681     }
1682 }
1683
1684 /**
1685  * @brief Request to hide preedit string.
1686  *
1687  * @param ic The handle of the client Input Context to receive the request.
1688  *        -1 means the currently focused Input Context.
1689  * @param ic_uuid The UUID of the IMEngine used by the Input Context.
1690  *        Empty means don't match.
1691  */
1692 void
1693 HelperAgent::hide_preedit_string (int               ic,
1694                                   const String     &ic_uuid) const
1695 {
1696     LOGD ("");
1697
1698     if (m_impl->socket_active.is_connected ()) {
1699         m_impl->send.clear ();
1700         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1701         m_impl->send.put_data (m_impl->magic_active);
1702         m_impl->send.put_command (SCIM_TRANS_CMD_HIDE_PREEDIT_STRING);
1703         m_impl->send.put_data ((uint32)ic);
1704         m_impl->send.put_data (ic_uuid);
1705         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1706     }
1707 }
1708
1709 /**
1710  * @brief Request to hide aux string.
1711  */
1712 void
1713 HelperAgent::hide_aux_string (void) const
1714 {
1715     LOGD ("");
1716     if (m_impl->socket_active.is_connected ()) {
1717         m_impl->send.clear ();
1718         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1719         m_impl->send.put_data (m_impl->magic_active);
1720         m_impl->send.put_command (SCIM_TRANS_CMD_HIDE_AUX_STRING);
1721         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1722     }
1723 }
1724
1725 /**
1726  * @brief Request to hide candidate string.
1727  */
1728 void
1729 HelperAgent::hide_candidate_string (void) const
1730 {
1731     LOGD ("");
1732     if (m_impl->socket_active.is_connected ()) {
1733         m_impl->send.clear ();
1734         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1735         m_impl->send.put_data (m_impl->magic_active);
1736         m_impl->send.put_command (SCIM_TRANS_CMD_HIDE_LOOKUP_TABLE);
1737         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1738     }
1739 }
1740
1741 /**
1742  * @brief Request to hide associate string.
1743  */
1744 void
1745 HelperAgent::hide_associate_string (void) const
1746 {
1747     LOGD ("");
1748     if (m_impl->socket_active.is_connected ()) {
1749         m_impl->send.clear ();
1750         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1751         m_impl->send.put_data (m_impl->magic_active);
1752         m_impl->send.put_command (ISM_TRANS_CMD_HIDE_ASSOCIATE_TABLE);
1753         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1754     }
1755 }
1756
1757 /**
1758  * @brief Update a new WideString for preedit.
1759  *
1760  * @param ic The handle of the client Input Context to receive the WideString.
1761  *        -1 means the currently focused Input Context.
1762  * @param ic_uuid The UUID of the IMEngine used by the Input Context.
1763  *        Empty means don't match.
1764  * @param str The WideString to be updated.
1765  * @param attrs The attribute list for preedit string.
1766  */
1767 void
1768 HelperAgent::update_preedit_string (int                  ic,
1769                                     const String        &ic_uuid,
1770                                     const WideString    &str,
1771                                     const AttributeList &attrs) const
1772 {
1773     LOGD ("");
1774     update_preedit_string (ic, ic_uuid, str, str, attrs, -1);
1775 }
1776
1777 void
1778 HelperAgent::update_preedit_string (int                  ic,
1779                                     const String        &ic_uuid,
1780                                     const char         *buf,
1781                                     int                 buflen,
1782                                     const AttributeList &attrs) const
1783 {
1784     LOGD ("");
1785     update_preedit_string (ic, ic_uuid, buf, buflen, attrs, -1);
1786 }
1787
1788 /**
1789  * @brief Update a new WideString for preedit.
1790  *
1791  * @param ic The handle of the client Input Context to receive the WideString.
1792  *        -1 means the currently focused Input Context.
1793  * @param ic_uuid The UUID of the IMEngine used by the Input Context.
1794  *        Empty means don't match.
1795  * @param str The WideString to be updated.
1796  * @param attrs The attribute list for preedit string.
1797  * @param caret The caret position in preedit string.
1798  */
1799 void
1800 HelperAgent::update_preedit_string (int                  ic,
1801                                     const String        &ic_uuid,
1802                                     const WideString    &wstr,
1803                                     const AttributeList &attrs,
1804                                     int            caret) const
1805 {
1806     LOGD ("");
1807     update_preedit_string (ic, ic_uuid, wstr, wstr, attrs, caret);
1808 }
1809
1810 void
1811 HelperAgent::update_preedit_string (int                 ic,
1812                                     const String       &ic_uuid,
1813                                     const char         *buf,
1814                                     int                 buflen,
1815                                     const AttributeList &attrs,
1816                                     int            caret) const
1817 {
1818     LOGD ("");
1819
1820     if (m_impl->socket_active.is_connected ()) {
1821         m_impl->send.clear ();
1822         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1823         m_impl->send.put_data (m_impl->magic_active);
1824         m_impl->send.put_command (SCIM_TRANS_CMD_UPDATE_PREEDIT_STRING);
1825         m_impl->send.put_data ((uint32)ic);
1826         m_impl->send.put_data (ic_uuid);
1827         m_impl->send.put_dataw (buf, buflen);
1828         m_impl->send.put_dataw (buf, buflen);
1829         m_impl->send.put_data (attrs);
1830         m_impl->send.put_data (caret);
1831         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1832     }
1833 }
1834
1835 void
1836 HelperAgent::update_preedit_string (int                  ic,
1837                                     const String        &ic_uuid,
1838                                     const WideString    &preedit,
1839                                     const WideString    &commit,
1840                                     const AttributeList &attrs,
1841                                     int                  caret) const
1842 {
1843     LOGD ("");
1844     if (m_impl->socket_active.is_connected ()) {
1845         m_impl->send.clear ();
1846         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1847         m_impl->send.put_data (m_impl->magic_active);
1848         m_impl->send.put_command (SCIM_TRANS_CMD_UPDATE_PREEDIT_STRING);
1849         m_impl->send.put_data ((uint32)ic);
1850         m_impl->send.put_data (ic_uuid);
1851         m_impl->send.put_data (preedit);
1852         m_impl->send.put_data (commit);
1853         m_impl->send.put_data (attrs);
1854         m_impl->send.put_data (caret);
1855         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1856     }
1857 }
1858
1859 /**
1860  * @brief Update the preedit caret position in the preedit string.
1861  *
1862  * @param caret - the new position of the preedit caret.
1863  */
1864 void
1865 HelperAgent::update_preedit_caret (int caret) const
1866 {
1867     LOGD ("");
1868
1869     if (m_impl->socket_active.is_connected ()) {
1870         m_impl->send.clear ();
1871         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1872         m_impl->send.put_data (m_impl->magic_active);
1873         m_impl->send.put_command (SCIM_TRANS_CMD_UPDATE_PREEDIT_CARET);
1874         m_impl->send.put_data ((uint32)caret);
1875         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1876     }
1877 }
1878
1879 /**
1880  * @brief Update a new string for aux.
1881  *
1882  * @param str The string to be updated.
1883  * @param attrs The attribute list for aux string.
1884  */
1885 void
1886 HelperAgent::update_aux_string (const String        &str,
1887                                 const AttributeList &attrs) const
1888 {
1889     LOGD ("");
1890     if (m_impl->socket_active.is_connected ()) {
1891         m_impl->send.clear ();
1892         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1893         m_impl->send.put_data (m_impl->magic_active);
1894         m_impl->send.put_command (SCIM_TRANS_CMD_UPDATE_AUX_STRING);
1895         m_impl->send.put_data (str);
1896         m_impl->send.put_data (attrs);
1897         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1898     }
1899 }
1900
1901 /**
1902  * @brief Request to update candidate.
1903  *
1904  * @param table The lookup table for candidate.
1905  */
1906 void
1907 HelperAgent::update_candidate_string (const LookupTable &table) const
1908 {
1909     LOGD ("");
1910     if (m_impl->socket_active.is_connected ()) {
1911         m_impl->send.clear ();
1912         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1913         m_impl->send.put_data (m_impl->magic_active);
1914         m_impl->send.put_command (SCIM_TRANS_CMD_UPDATE_LOOKUP_TABLE);
1915         m_impl->send.put_data (table);
1916         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1917     }
1918 }
1919
1920 /**
1921  * @brief Request to update associate.
1922  *
1923  * @param table The lookup table for associate.
1924  */
1925 void
1926 HelperAgent::update_associate_string (const LookupTable &table) const
1927 {
1928     LOGD ("");
1929     if (m_impl->socket_active.is_connected ()) {
1930         m_impl->send.clear ();
1931         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1932         m_impl->send.put_data (m_impl->magic_active);
1933         m_impl->send.put_command (ISM_TRANS_CMD_UPDATE_ASSOCIATE_TABLE);
1934         m_impl->send.put_data (table);
1935         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1936     }
1937 }
1938
1939 /**
1940  * @brief When the input context of ISE is changed,
1941  *         ISE can call this function to notify application
1942  *
1943  * @param type  type of event.
1944  * @param value value of event.
1945  */
1946 void
1947 HelperAgent::update_input_context (uint32 type, uint32 value) const
1948 {
1949     LOGD ("");
1950     if (m_impl->socket_active.is_connected ()) {
1951         m_impl->send.clear ();
1952         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1953         m_impl->send.put_data (m_impl->magic_active);
1954         m_impl->send.put_command (ISM_TRANS_CMD_UPDATE_ISE_INPUT_CONTEXT);
1955         m_impl->send.put_data (type);
1956         m_impl->send.put_data (value);
1957         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1958     }
1959 }
1960
1961 /**
1962  * @brief Request to get surrounding text asynchronously.
1963  *
1964  * @param uuid The helper ISE UUID.
1965  * @param maxlen_before The max length of before.
1966  * @param maxlen_after The max length of after.
1967  */
1968 void
1969 HelperAgent::get_surrounding_text (const String &uuid, int maxlen_before, int maxlen_after) const
1970 {
1971     LOGD ("");
1972     if (m_impl->socket_active.is_connected () && (m_impl->need_update_surrounding_text == 0)) {
1973         m_impl->send.clear ();
1974         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1975         m_impl->send.put_data (m_impl->magic_active);
1976         m_impl->send.put_command (SCIM_TRANS_CMD_GET_SURROUNDING_TEXT);
1977         m_impl->send.put_data (uuid);
1978         m_impl->send.put_data (maxlen_before);
1979         m_impl->send.put_data (maxlen_after);
1980         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1981     }
1982     m_impl->need_update_surrounding_text++;
1983 }
1984
1985 /**
1986  * @brief Request to get surrounding text synchronously.
1987  *
1988  * @param uuid The helper ISE UUID.
1989  * @param maxlen_before The max length of before.
1990  * @param maxlen_after The max length of after.
1991  * @param text The surrounding text.
1992  * @param cursor The cursor position.
1993  */
1994 void
1995 HelperAgent::get_surrounding_text (int maxlen_before, int maxlen_after, String &text, int &cursor)
1996 {
1997     LOGD ("");
1998 #ifdef _TV
1999     if (m_impl->socket_active.is_connected () && (m_impl->need_update_surrounding_text == 0)) {
2000         m_impl->send.clear ();
2001         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2002         m_impl->send.put_data (m_impl->magic_active);
2003         m_impl->send.put_command (SCIM_TRANS_CMD_GET_SURROUNDING_TEXT);
2004         m_impl->send.put_data ("");
2005         m_impl->send.put_data (maxlen_before);
2006         m_impl->send.put_data (maxlen_after);
2007         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2008     }
2009     m_impl->need_update_surrounding_text++;
2010 #else
2011     if (!m_impl->socket_active.is_connected ())
2012         return;
2013
2014     m_impl->send.clear ();
2015     m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2016     m_impl->send.put_data (m_impl->magic_active);
2017     m_impl->send.put_command (SCIM_TRANS_CMD_GET_SURROUNDING_TEXT);
2018     m_impl->send.put_data ("");
2019     m_impl->send.put_data (maxlen_before);
2020     m_impl->send.put_data (maxlen_after);
2021     m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2022     if (m_impl->surrounding_text) {
2023         free (m_impl->surrounding_text);
2024         m_impl->surrounding_text = NULL;
2025     }
2026
2027     const int WAIT_FOR_SYNC_RESPONSE_TIMEOUT = 1000;
2028     /* Now we are waiting for the ISM_TRANS_CMD_UPDATE_SURROUNDING_TEXT message */
2029     if (wait_for_message(ISM_TRANS_CMD_UPDATE_SURROUNDING_TEXT, WAIT_FOR_SYNC_RESPONSE_TIMEOUT)) {
2030         MessageItem *message = message_queue.get_pending_message_by_cmd(ISM_TRANS_CMD_UPDATE_SURROUNDING_TEXT);
2031         handle_message(message);
2032         message_queue.remove_message(message);
2033
2034         if (m_impl->surrounding_text) {
2035             text = m_impl->surrounding_text;
2036             cursor = m_impl->cursor_pos;
2037         }
2038     }
2039
2040     if (m_impl->surrounding_text) {
2041         free (m_impl->surrounding_text);
2042         m_impl->surrounding_text = NULL;
2043     }
2044 #endif
2045 }
2046
2047 /**
2048  * @brief Request to delete surrounding text.
2049  *
2050  * @param offset The offset for cursor position.
2051  * @param len The length for delete text.
2052  */
2053 void
2054 HelperAgent::delete_surrounding_text (int offset, int len) const
2055 {
2056     LOGD ("offset = %d, len = %d", offset, len);
2057
2058     if (m_impl->socket_active.is_connected ()) {
2059         m_impl->send.clear ();
2060         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2061         m_impl->send.put_data (m_impl->magic_active);
2062         m_impl->send.put_command (SCIM_TRANS_CMD_DELETE_SURROUNDING_TEXT);
2063         m_impl->send.put_data (offset);
2064         m_impl->send.put_data (len);
2065         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2066     }
2067 }
2068
2069 /**
2070  * @brief Request to get selection text asynchronously.
2071  *
2072  * @param uuid The helper ISE UUID.
2073  */
2074 void
2075 HelperAgent::get_selection (const String &uuid) const
2076 {
2077     LOGD ("");
2078     if (m_impl->socket_active.is_connected () && (m_impl->need_update_selection_text == 0)) {
2079         m_impl->send.clear ();
2080         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2081         m_impl->send.put_data (m_impl->magic_active);
2082         m_impl->send.put_command (SCIM_TRANS_CMD_GET_SELECTION);
2083         m_impl->send.put_data (uuid);
2084         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2085     }
2086     m_impl->need_update_selection_text++;
2087 }
2088
2089 /**
2090  * @brief Request to get selection text synchronously.
2091  *
2092  * @param text The selection text.
2093  */
2094 void
2095 HelperAgent::get_selection_text (String &text)
2096 {
2097     LOGD ("");
2098 #ifdef _TV
2099     if (m_impl->socket_active.is_connected () && (m_impl->need_update_selection_text == 0)) {
2100         m_impl->send.clear ();
2101         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2102         m_impl->send.put_data (m_impl->magic_active);
2103         m_impl->send.put_command (SCIM_TRANS_CMD_GET_SELECTION);
2104         m_impl->send.put_data ("");
2105         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2106     }
2107     m_impl->need_update_selection_text++;
2108 #else
2109     if (!m_impl->socket_active.is_connected ())
2110         return;
2111
2112     m_impl->send.clear ();
2113     m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2114     m_impl->send.put_data (m_impl->magic_active);
2115     m_impl->send.put_command (SCIM_TRANS_CMD_GET_SELECTION);
2116     m_impl->send.put_data ("");
2117     m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2118     if (m_impl->selection_text) {
2119         free (m_impl->selection_text);
2120         m_impl->selection_text = NULL;
2121     }
2122
2123     const int WAIT_FOR_SYNC_RESPONSE_TIMEOUT = 1000;
2124     /* Now we are waiting for the ISM_TRANS_CMD_UPDATE_SELECTION message */
2125     if (wait_for_message(ISM_TRANS_CMD_UPDATE_SELECTION, WAIT_FOR_SYNC_RESPONSE_TIMEOUT)) {
2126         MessageItem *message = message_queue.get_pending_message_by_cmd(ISM_TRANS_CMD_UPDATE_SELECTION);
2127         handle_message(message);
2128         message_queue.remove_message(message);
2129         if (m_impl->selection_text) {
2130             text = m_impl->selection_text;
2131         }
2132     }
2133
2134     if (m_impl->selection_text) {
2135         free (m_impl->selection_text);
2136         m_impl->selection_text = NULL;
2137     }
2138 #endif
2139 }
2140
2141 /**
2142  * @brief Request to select text.
2143  *
2144  * @param start The start position in text.
2145  * @param end The end position in text.
2146  */
2147 void
2148 HelperAgent::set_selection (int start, int end) const
2149 {
2150     LOGD ("");
2151     if (m_impl->socket_active.is_connected ()) {
2152         m_impl->send.clear ();
2153         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2154         m_impl->send.put_data (m_impl->magic_active);
2155         m_impl->send.put_command (SCIM_TRANS_CMD_SET_SELECTION);
2156         m_impl->send.put_data (start);
2157         m_impl->send.put_data (end);
2158         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2159     }
2160 }
2161
2162 /**
2163  * @brief Send a private command to an application.
2164  *
2165  * @param command The private command sent from IME.
2166  */
2167 void
2168 HelperAgent::send_private_command (const String &command) const
2169 {
2170     LOGD ("");
2171     if (m_impl->socket_active.is_connected ()) {
2172         m_impl->send.clear ();
2173         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2174         m_impl->send.put_data (m_impl->magic_active);
2175         m_impl->send.put_command (SCIM_TRANS_CMD_SEND_PRIVATE_COMMAND);
2176         m_impl->send.put_data (command);
2177         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2178     }
2179 }
2180
2181 /**
2182  * @brief Request to get uuid list of all keyboard ISEs.
2183  *
2184  * @param uuid The helper ISE UUID.
2185  */
2186 void
2187 HelperAgent::get_keyboard_ise_list (const String &uuid) const
2188 {
2189     LOGD ("");
2190     if (m_impl->socket_active.is_connected ()) {
2191         m_impl->send.clear ();
2192         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2193         m_impl->send.put_data (m_impl->magic_active);
2194         m_impl->send.put_command (ISM_TRANS_CMD_GET_KEYBOARD_ISE_LIST);
2195         m_impl->send.put_data (uuid);
2196         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2197     }
2198 }
2199
2200 /**
2201  * @brief Set candidate position in screen.
2202  *
2203  * @param left The x position in screen.
2204  * @param top The y position in screen.
2205  */
2206 void
2207 HelperAgent::set_candidate_position (int left, int top) const
2208 {
2209     LOGD ("");
2210     if (m_impl->socket_active.is_connected ()) {
2211         m_impl->send.clear ();
2212         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2213         m_impl->send.put_data (m_impl->magic_active);
2214         m_impl->send.put_command (ISM_TRANS_CMD_SET_CANDIDATE_POSITION);
2215         m_impl->send.put_data (left);
2216         m_impl->send.put_data (top);
2217         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2218     }
2219 }
2220
2221 /**
2222  * @brief Set candidate style.
2223  *
2224  * @param portrait_line - the displayed line number for portrait mode.
2225  * @param mode          - candidate window mode.
2226  */
2227 void
2228 HelperAgent::set_candidate_style (ISF_CANDIDATE_PORTRAIT_LINE_T portrait_line,
2229                                   ISF_CANDIDATE_MODE_T          mode) const
2230 {
2231     LOGD ("");
2232     if (m_impl->socket_active.is_connected ()) {
2233         m_impl->send.clear ();
2234         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2235         m_impl->send.put_data (m_impl->magic_active);
2236         m_impl->send.put_command (ISM_TRANS_CMD_SET_CANDIDATE_UI);
2237         m_impl->send.put_data (portrait_line);
2238         m_impl->send.put_data (mode);
2239         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2240     }
2241 }
2242
2243 /**
2244  * @brief Request to hide candidate window.
2245  */
2246 void
2247 HelperAgent::candidate_hide (void) const
2248 {
2249     LOGD ("");
2250     if (m_impl->socket_active.is_connected ()) {
2251         m_impl->send.clear ();
2252         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2253         m_impl->send.put_data (m_impl->magic_active);
2254         m_impl->send.put_command (ISM_TRANS_CMD_HIDE_CANDIDATE);
2255         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2256     }
2257 }
2258
2259 /**
2260  * @brief Request to get candidate window size and position.
2261  *
2262  * @param uuid The helper ISE UUID.
2263  */
2264 void
2265 HelperAgent::get_candidate_window_geometry (const String &uuid) const
2266 {
2267     LOGD ("");
2268     if (m_impl->socket_active.is_connected ()) {
2269         m_impl->send.clear ();
2270         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2271         m_impl->send.put_data (m_impl->magic_active);
2272         m_impl->send.put_command (ISM_TRANS_CMD_GET_CANDIDATE_GEOMETRY);
2273         m_impl->send.put_data (uuid);
2274         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2275     }
2276 }
2277
2278 /**
2279  * @brief Set current keyboard ISE.
2280  *
2281  * @param uuid The keyboard ISE UUID.
2282  */
2283 void
2284 HelperAgent::set_keyboard_ise_by_uuid (const String &uuid) const
2285 {
2286     LOGD ("");
2287     ImeInfoDB imeInfo;
2288     IMEngineFactoryPointer factory;
2289     IMEngineModule *engine_module = NULL;
2290     static int instance_count = 1;
2291
2292     if ((!m_impl->si.null ()) && m_impl->si->get_factory_uuid () == uuid) {
2293         LOGD ("Already in UUID: %s\n", uuid.c_str());
2294         return;
2295     }
2296
2297     if (!m_impl->si.null()) {
2298         m_impl->si->focus_out();
2299         m_impl->si.reset();
2300     }
2301
2302     if (m_impl->m_config.null ()) {
2303         LOGW ("config is not working");
2304         return;
2305     }
2306
2307 #if HAVE_PKGMGR_INFO
2308     int ret = 0;
2309     char *pkgid = NULL;
2310     pkgmgrinfo_appinfo_h handle;
2311     ret = pkgmgrinfo_appinfo_get_appinfo(uuid.c_str(), &handle);
2312     if (ret != PMINFO_R_OK) {
2313         LOGW("Retrieve app info failed : %s", uuid.c_str ());
2314         return;
2315     }
2316
2317     ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
2318     if (ret != PMINFO_R_OK) {
2319         LOGW("Retrieve pkgid failed : %s, %p", uuid.c_str(), handle);
2320         pkgmgrinfo_appinfo_destroy_appinfo(handle);
2321         return;
2322     }
2323
2324     imeInfo.module_name = pkgid;
2325     pkgmgrinfo_appinfo_destroy_appinfo(handle);
2326 #else
2327     if (isf_db_select_ime_info_by_appid(uuid.c_str(), &imeInfo) < 1) {
2328         LOGW("ime_info row is not available for %s", uuid.c_str());
2329         return;
2330     }
2331 #endif
2332
2333     engine_module = &m_impl->engine_module;
2334
2335     if (engine_module->valid() && imeInfo.module_name != engine_module->get_module_name()) {
2336         LOGD ("imengine module %s unloaded", engine_module->get_module_name().c_str());
2337         engine_module->unload();
2338     }
2339
2340     if (!engine_module->valid()) {
2341         if (engine_module->load (imeInfo.module_name, m_impl->m_config) == false) {
2342             LOGW ("load module %s failed", imeInfo.module_name.c_str());
2343             return;
2344         }
2345         LOGD ("imengine module %s loaded", imeInfo.module_name.c_str());
2346     }
2347
2348     for (size_t j = 0; j < engine_module->number_of_factories (); ++j) {
2349
2350         try {
2351             factory = engine_module->create_factory (j);
2352             if (factory.null () == false && factory->get_uuid () == uuid)
2353                 break;
2354         } catch (...) {
2355             factory.reset ();
2356             return;
2357         }
2358     }
2359
2360     if (factory.null()) {
2361         LOGW ("imengine uuid %s is not found", uuid.c_str());
2362         return;
2363     }
2364
2365     m_impl->si = factory->create_instance ("UTF-8", instance_count++);
2366     if (m_impl->si.null ()) {
2367         LOGE ("create_instance %s failed",uuid.c_str ());
2368         return;
2369     }
2370
2371     m_impl->attach_instance ();
2372     LOGD ("Require UUID: %s Current UUID: %s", uuid.c_str (), m_impl->si->get_factory_uuid ().c_str ());
2373     m_impl->si->set_layout (m_impl->layout);
2374     if(m_impl->focused_ic != (uint32)-1)
2375         m_impl->si->focus_in ();
2376 }
2377
2378 /**
2379  * @brief Request to get current keyboard ISE information.
2380  *
2381  * @param uuid The helper ISE UUID.
2382  */
2383 void
2384 HelperAgent::get_keyboard_ise (const String &uuid) const
2385 {
2386     LOGD ("");
2387     //FIXME: maybe useless
2388 #if 0
2389     if (m_impl->socket_active.is_connected ()) {
2390         m_impl->send.clear ();
2391         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2392         m_impl->send.put_data (m_impl->magic_active);
2393         m_impl->send.put_command (ISM_TRANS_CMD_GET_KEYBOARD_ISE);
2394         m_impl->send.put_data (uuid);
2395         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2396     }
2397 #endif
2398 }
2399
2400 /**
2401  * @brief Update ISE window geometry.
2402  *
2403  * @param x      The x position in screen.
2404  * @param y      The y position in screen.
2405  * @param width  The ISE window width.
2406  * @param height The ISE window height.
2407  */
2408 void
2409 HelperAgent::update_geometry (int x, int y, int width, int height) const
2410 {
2411     LOGD ("");
2412     if (m_impl->socket_active.is_connected ()) {
2413         m_impl->send.clear ();
2414         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2415         m_impl->send.put_data (m_impl->magic_active);
2416         m_impl->send.put_command (ISM_TRANS_CMD_UPDATE_ISE_GEOMETRY);
2417         m_impl->send.put_data (x);
2418         m_impl->send.put_data (y);
2419         m_impl->send.put_data (width);
2420         m_impl->send.put_data (height);
2421         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2422     }
2423 }
2424
2425 /**
2426  * @brief Request to expand candidate window.
2427  */
2428 void
2429 HelperAgent::expand_candidate (void) const
2430 {
2431     LOGD ("");
2432     if (m_impl->socket_active.is_connected ()) {
2433         m_impl->send.clear ();
2434         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2435         m_impl->send.put_data (m_impl->magic_active);
2436         m_impl->send.put_command (ISM_TRANS_CMD_EXPAND_CANDIDATE);
2437         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2438     }
2439 }
2440
2441 /**
2442  * @brief Request to contract candidate window.
2443  */
2444 void
2445 HelperAgent::contract_candidate (void) const
2446 {
2447     LOGD ("");
2448     if (m_impl->socket_active.is_connected ()) {
2449         m_impl->send.clear ();
2450         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2451         m_impl->send.put_data (m_impl->magic_active);
2452         m_impl->send.put_command (ISM_TRANS_CMD_CONTRACT_CANDIDATE);
2453         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2454     }
2455 }
2456
2457 /**
2458  * @brief Send selected candidate string index number.
2459  */
2460 void
2461 HelperAgent::select_candidate (int index) const
2462 {
2463     LOGD ("");
2464     if (!m_impl->si.null ())
2465         m_impl->si->select_candidate (index);
2466     //FIXME: maybe useless
2467 #if 0
2468
2469     if (m_impl->socket_active.is_connected ()) {
2470         m_impl->send.clear ();
2471         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2472         m_impl->send.put_data (m_impl->magic_active);
2473         m_impl->send.put_command (ISM_TRANS_CMD_SELECT_CANDIDATE);
2474         m_impl->send.put_data (index);
2475         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2476     }
2477 #endif
2478 }
2479
2480 /**
2481  * @brief Update our ISE is exiting.
2482  */
2483 void
2484 HelperAgent::update_ise_exit (void) const
2485 {
2486     LOGD ("");
2487     //FIXME: maybe useless
2488 #if 0
2489     if (m_impl->socket_active.is_connected ()) {
2490         m_impl->send.clear ();
2491         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2492         m_impl->send.put_data (m_impl->magic_active);
2493         m_impl->send.put_command (ISM_TRANS_CMD_UPDATE_ISE_EXIT);
2494         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2495     }
2496 #endif
2497 }
2498
2499 /**
2500  * @brief Request to reset keyboard ISE.
2501  */
2502 void
2503 HelperAgent::reset_keyboard_ise (void) const
2504 {
2505     LOGD ("");
2506 //FIXME: maybe useless
2507 #if 0
2508     if (m_impl->socket_active.is_connected ()) {
2509         m_impl->send.clear ();
2510         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2511         m_impl->send.put_data (m_impl->magic_active);
2512         m_impl->send.put_command (ISM_TRANS_CMD_PANEL_RESET_KEYBOARD_ISE);
2513         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2514     }
2515 #endif
2516     if (!m_impl->si.null ()) {
2517         m_impl->si->reset ();
2518     }
2519 }
2520
2521 /**
2522  * @brief Connect a slot to Helper exit signal.
2523  *
2524  * This signal is used to let the Helper exit.
2525  *
2526  * The prototype of the slot is:
2527  *
2528  * void exit (const HelperAgent *agent, int ic, const String &ic_uuid);
2529  *
2530  * Parameters:
2531  * - agent    The pointer to the HelperAgent object which emits this signal.
2532  * - ic       An opaque handle of the currently focused input context.
2533  * - ic_uuid  The UUID of the IMEngineInstance associated with the focused input context.
2534  */
2535 Connection
2536 HelperAgent::signal_connect_exit (HelperAgentSlotVoid *slot)
2537 {
2538     return m_impl->signal_exit.connect (slot);
2539 }
2540
2541 /**
2542  * @brief Connect a slot to Helper attach input context signal.
2543  *
2544  * This signal is used to attach an input context to this helper.
2545  *
2546  * When an input context requst to start this helper, then this
2547  * signal will be emitted as soon as the helper is started.
2548  *
2549  * When an input context want to start an already started helper,
2550  * this signal will also be emitted.
2551  *
2552  * Helper can send some events back to the IMEngineInstance in this
2553  * signal-slot, to inform that it has been started sccessfully.
2554  *
2555  * The prototype of the slot is:
2556  *
2557  * void attach_input_context (const HelperAgent *agent, int ic, const String &ic_uuid);
2558  */
2559 Connection
2560 HelperAgent::signal_connect_attach_input_context (HelperAgentSlotVoid *slot)
2561 {
2562     return m_impl->signal_attach_input_context.connect (slot);
2563 }
2564
2565 /**
2566  * @brief Connect a slot to Helper detach input context signal.
2567  *
2568  * This signal is used to detach an input context from this helper.
2569  *
2570  * When an input context requst to stop this helper, then this
2571  * signal will be emitted.
2572  *
2573  * Helper shouldn't send any event back to the IMEngineInstance, because
2574  * the IMEngineInstance attached to the ic should have been destroyed.
2575  *
2576  * The prototype of the slot is:
2577  *
2578  * void detach_input_context (const HelperAgent *agent, int ic, const String &ic_uuid);
2579  */
2580 Connection
2581 HelperAgent::signal_connect_detach_input_context (HelperAgentSlotVoid *slot)
2582 {
2583     return m_impl->signal_detach_input_context.connect (slot);
2584 }
2585
2586 /**
2587  * @brief Connect a slot to Helper reload config signal.
2588  *
2589  * This signal is used to let the Helper reload configuration.
2590  *
2591  * The prototype of the slot is:
2592  *
2593  * void reload_config (const HelperAgent *agent, int ic, const String &ic_uuid);
2594  */
2595 Connection
2596 HelperAgent::signal_connect_reload_config (HelperAgentSlotVoid *slot)
2597 {
2598     return m_impl->signal_reload_config.connect (slot);
2599 }
2600
2601 /**
2602  * @brief Connect a slot to Helper update screen signal.
2603  *
2604  * This signal is used to let the Helper move its GUI to another screen.
2605  * It can only be emitted when SCIM_HELPER_NEED_SCREEN_INFO is set in HelperInfo.option.
2606  *
2607  * The prototype of the slot is:
2608  *
2609  * void update_screen (const HelperAgent *agent, int ic, const String &ic_uuid, int screen_number);
2610  */
2611 Connection
2612 HelperAgent::signal_connect_update_screen (HelperAgentSlotInt *slot)
2613 {
2614     return m_impl->signal_update_screen.connect (slot);
2615 }
2616
2617 /**
2618  * @brief Connect a slot to Helper update spot location signal.
2619  *
2620  * This signal is used to let the Helper move its GUI according to the current spot location.
2621  * It can only be emitted when SCIM_HELPER_NEED_SPOT_LOCATION_INFO is set in HelperInfo.option.
2622  *
2623  * The prototype of the slot is:
2624  * void update_spot_location (const HelperAgent *agent, int ic, const String &ic_uuid, int x, int y);
2625  */
2626 Connection
2627 HelperAgent::signal_connect_update_spot_location (HelperAgentSlotIntInt *slot)
2628 {
2629     return m_impl->signal_update_spot_location.connect (slot);
2630 }
2631
2632 /**
2633  * @brief Connect a slot to Helper update cursor position signal.
2634  *
2635  * This signal is used to let the Helper get the cursor position information.
2636  *
2637  * The prototype of the slot is:
2638  * void update_cursor_position (const HelperAgent *agent, int ic, const String &ic_uuid, int cursor_pos);
2639  */
2640 Connection
2641 HelperAgent::signal_connect_update_cursor_position (HelperAgentSlotInt *slot)
2642 {
2643     return m_impl->signal_update_cursor_position.connect (slot);
2644 }
2645
2646 /**
2647  * @brief Connect a slot to Helper update surrounding text signal.
2648  *
2649  * This signal is used to let the Helper get the surrounding text.
2650  *
2651  * The prototype of the slot is:
2652  * void update_surrounding_text (const HelperAgent *agent, int ic, const String &text, int cursor);
2653  */
2654 Connection
2655 HelperAgent::signal_connect_update_surrounding_text (HelperAgentSlotInt *slot)
2656 {
2657     return m_impl->signal_update_surrounding_text.connect (slot);
2658 }
2659
2660 /**
2661  * @brief Connect a slot to Helper update selection signal.
2662  *
2663  * This signal is used to let the Helper get the selection.
2664  *
2665  * The prototype of the slot is:
2666  * void update_selection (const HelperAgent *agent, int ic, const String &text);
2667  */
2668 Connection
2669 HelperAgent::signal_connect_update_selection (HelperAgentSlotVoid *slot)
2670 {
2671     return m_impl->signal_update_selection.connect (slot);
2672 }
2673
2674 /**
2675  * @brief Connect a slot to Helper trigger property signal.
2676  *
2677  * This signal is used to trigger a property registered by this Helper.
2678  * A property will be triggered when user clicks on it.
2679  *
2680  * The prototype of the slot is:
2681  * void trigger_property (const HelperAgent *agent, int ic, const String &ic_uuid, const String &property);
2682  */
2683 Connection
2684 HelperAgent::signal_connect_trigger_property (HelperAgentSlotString *slot)
2685 {
2686     return m_impl->signal_trigger_property.connect (slot);
2687 }
2688
2689 /**
2690  * @brief Connect a slot to Helper process imengine event signal.
2691  *
2692  * This signal is used to deliver the events sent from IMEngine to Helper.
2693  *
2694  * The prototype of the slot is:
2695  * void process_imengine_event (const HelperAgent *agent, int ic, const String &ic_uuid, const Transaction &transaction);
2696  */
2697 Connection
2698 HelperAgent::signal_connect_process_imengine_event (HelperAgentSlotTransaction *slot)
2699 {
2700     return m_impl->signal_process_imengine_event.connect (slot);
2701 }
2702
2703 /**
2704  * @brief Connect a slot to Helper focus out signal.
2705  *
2706  * This signal is used to do something when input context is focus out.
2707  *
2708  * The prototype of the slot is:
2709  * void focus_out (const HelperAgent *agent, int ic, const String &ic_uuid);
2710  */
2711 Connection
2712 HelperAgent::signal_connect_focus_out (HelperAgentSlotVoid *slot)
2713 {
2714     return m_impl->signal_focus_out.connect (slot);
2715 }
2716
2717 /**
2718  * @brief Connect a slot to Helper focus in signal.
2719  *
2720  * This signal is used to do something when input context is focus in.
2721  *
2722  * The prototype of the slot is:
2723  * void focus_in (const HelperAgent *agent, int ic, const String &ic_uuid);
2724  */
2725 Connection
2726 HelperAgent::signal_connect_focus_in (HelperAgentSlotVoid *slot)
2727 {
2728     return m_impl->signal_focus_in.connect (slot);
2729 }
2730
2731 /**
2732  * @brief Connect a slot to Helper show signal.
2733  *
2734  * This signal is used to show Helper ISE window.
2735  *
2736  * The prototype of the slot is:
2737  * void ise_show (const HelperAgent *agent, int ic, char *buf, size_t &len);
2738  */
2739 Connection
2740 HelperAgent::signal_connect_ise_show (HelperAgentSlotIntRawVoid *slot)
2741 {
2742     return m_impl->signal_ise_show.connect (slot);
2743 }
2744
2745 /**
2746  * @brief Connect a slot to Helper hide signal.
2747  *
2748  * This signal is used to hide Helper ISE window.
2749  *
2750  * The prototype of the slot is:
2751  * void ise_hide (const HelperAgent *agent, int ic, const String &ic_uuid);
2752  */
2753 Connection
2754 HelperAgent::signal_connect_ise_hide (HelperAgentSlotVoid *slot)
2755 {
2756     return m_impl->signal_ise_hide.connect (slot);
2757 }
2758
2759 /**
2760  * @brief Connect a slot to Helper get ISE window geometry signal.
2761  *
2762  * This signal is used to get Helper ISE window size and position.
2763  *
2764  * The prototype of the slot is:
2765  * void get_geometry (const HelperAgent *agent, struct rectinfo &info);
2766  */
2767 Connection
2768 HelperAgent::signal_connect_get_geometry (HelperAgentSlotSize *slot)
2769 {
2770     return m_impl->signal_get_geometry.connect (slot);
2771 }
2772
2773 /**
2774  * @brief Connect a slot to Helper set mode signal.
2775  *
2776  * This signal is used to set Helper ISE mode.
2777  *
2778  * The prototype of the slot is:
2779  * void set_mode (const HelperAgent *agent, uint32 &mode);
2780  */
2781 Connection
2782 HelperAgent::signal_connect_set_mode (HelperAgentSlotUintVoid *slot)
2783 {
2784     return m_impl->signal_set_mode.connect (slot);
2785 }
2786
2787 /**
2788  * @brief Connect a slot to Helper set language signal.
2789  *
2790  * This signal is used to set Helper ISE language.
2791  *
2792  * The prototype of the slot is:
2793  * void set_language (const HelperAgent *agent, uint32 &language);
2794  */
2795 Connection
2796 HelperAgent::signal_connect_set_language (HelperAgentSlotUintVoid *slot)
2797 {
2798     return m_impl->signal_set_language.connect (slot);
2799 }
2800
2801 /**
2802  * @brief Connect a slot to Helper set im data signal.
2803  *
2804  * This signal is used to send im data to Helper ISE.
2805  *
2806  * The prototype of the slot is:
2807  * void set_imdata (const HelperAgent *agent, char *buf, size_t &len);
2808  */
2809 Connection
2810 HelperAgent::signal_connect_set_imdata (HelperAgentSlotRawVoid *slot)
2811 {
2812     return m_impl->signal_set_imdata.connect (slot);
2813 }
2814
2815 /**
2816  * @brief Connect a slot to Helper get im data signal.
2817  *
2818  * This signal is used to get im data from Helper ISE.
2819  *
2820  * The prototype of the slot is:
2821  * void get_imdata (const HelperAgent *, char **buf, size_t &len);
2822  */
2823 Connection
2824 HelperAgent::signal_connect_get_imdata (HelperAgentSlotGetRawVoid *slot)
2825 {
2826     return m_impl->signal_get_imdata.connect (slot);
2827 }
2828
2829 /**
2830  * @brief Connect a slot to Helper get language locale signal.
2831  *
2832  * This signal is used to get language locale from Helper ISE.
2833  *
2834  * The prototype of the slot is:
2835  * void get_language_locale (const HelperAgent *, int ic, char **locale);
2836  */
2837 Connection
2838 HelperAgent::signal_connect_get_language_locale (HelperAgentSlotIntGetStringVoid *slot)
2839 {
2840     return m_impl->signal_get_language_locale.connect (slot);
2841 }
2842
2843 /**
2844  * @brief Connect a slot to Helper set return key type signal.
2845  *
2846  * This signal is used to send return key type to Helper ISE.
2847  *
2848  * The prototype of the slot is:
2849  * void set_return_key_type (const HelperAgent *agent, uint32 &type);
2850  */
2851 Connection
2852 HelperAgent::signal_connect_set_return_key_type (HelperAgentSlotUintVoid *slot)
2853 {
2854     return m_impl->signal_set_return_key_type.connect (slot);
2855 }
2856
2857 /**
2858  * @brief Connect a slot to Helper get return key type signal.
2859  *
2860  * This signal is used to get return key type from Helper ISE.
2861  *
2862  * The prototype of the slot is:
2863  * void get_return_key_type (const HelperAgent *agent, uint32 &type);
2864  */
2865 Connection
2866 HelperAgent::signal_connect_get_return_key_type (HelperAgentSlotUintVoid *slot)
2867 {
2868     return m_impl->signal_get_return_key_type.connect (slot);
2869 }
2870
2871 /**
2872  * @brief Connect a slot to Helper set return key disable signal.
2873  *
2874  * This signal is used to send return key disable to Helper ISE.
2875  *
2876  * The prototype of the slot is:
2877  * void set_return_key_disable (const HelperAgent *agent, uint32 &disabled);
2878  */
2879 Connection
2880 HelperAgent::signal_connect_set_return_key_disable (HelperAgentSlotUintVoid *slot)
2881 {
2882     return m_impl->signal_set_return_key_disable.connect (slot);
2883 }
2884
2885 /**
2886  * @brief Connect a slot to Helper process key event signal.
2887  *
2888  * This signal is used to send keyboard key event to Helper ISE.
2889  *
2890  * The prototype of the slot is:
2891  * void process_key_event (const HelperAgent *agent, KeyEvent &key, uint32 &ret);
2892  */
2893 Connection
2894 HelperAgent::signal_connect_process_key_event (HelperAgentSlotKeyEventUint *slot)
2895 {
2896     return m_impl->signal_process_key_event.connect (slot);
2897 }
2898
2899 /**
2900  * @brief Connect a slot to Helper get return key disable signal.
2901  *
2902  * This signal is used to get return key disable from Helper ISE.
2903  *
2904  * The prototype of the slot is:
2905  * void get_return_key_disable (const HelperAgent *agent, uint32 &disabled);
2906  */
2907 Connection
2908 HelperAgent::signal_connect_get_return_key_disable (HelperAgentSlotUintVoid *slot)
2909 {
2910     return m_impl->signal_get_return_key_disable.connect (slot);
2911 }
2912
2913 /**
2914  * @brief Connect a slot to Helper set layout signal.
2915  *
2916  * This signal is used to set Helper ISE layout.
2917  *
2918  * The prototype of the slot is:
2919  * void set_layout (const HelperAgent *agent, uint32 &layout);
2920  */
2921 Connection
2922 HelperAgent::signal_connect_set_layout (HelperAgentSlotUintVoid *slot)
2923 {
2924     return m_impl->signal_set_layout.connect (slot);
2925 }
2926
2927 /**
2928  * @brief Connect a slot to Helper get layout signal.
2929  *
2930  * This signal is used to get Helper ISE layout.
2931  *
2932  * The prototype of the slot is:
2933  * void get_layout (const HelperAgent *agent, uint32 &layout);
2934  */
2935 Connection
2936 HelperAgent::signal_connect_get_layout (HelperAgentSlotUintVoid *slot)
2937 {
2938     return m_impl->signal_get_layout.connect (slot);
2939 }
2940
2941 /**
2942  * @brief Connect a slot to Helper set input mode signal.
2943  *
2944  * This signal is used to set Helper ISE input mode.
2945  *
2946  * The prototype of the slot is:
2947  * void set_input_mode (const HelperAgent *agent, uint32 &input_mode);
2948  */
2949 Connection
2950 HelperAgent::signal_connect_set_input_mode (HelperAgentSlotUintVoid *slot)
2951 {
2952     return m_impl->signal_set_input_mode.connect (slot);
2953 }
2954
2955 /**
2956  * @brief Connect a slot to Helper set input hint signal.
2957  *
2958  * This signal is used to set Helper ISE input hint.
2959  *
2960  * The prototype of the slot is:
2961  * void set_input_hint (const HelperAgent *agent, uint32 &input_hint);
2962  */
2963 Connection
2964 HelperAgent::signal_connect_set_input_hint (HelperAgentSlotUintVoid *slot)
2965 {
2966     return m_impl->signal_set_input_hint.connect (slot);
2967 }
2968
2969 /**
2970  * @brief Connect a slot to Helper set BiDi direction signal.
2971  *
2972  * This signal is used to set Helper ISE BiDi direction.
2973  *
2974  * The prototype of the slot is:
2975  * void update_bidi_direction (const HelperAgent *agent, uint32 &bidi_direction);
2976  */
2977 Connection
2978 HelperAgent::signal_connect_update_bidi_direction (HelperAgentSlotUintVoid *slot)
2979 {
2980     return m_impl->signal_update_bidi_direction.connect (slot);
2981 }
2982
2983 /**
2984  * @brief Connect a slot to Helper set shift mode signal.
2985  *
2986  * This signal is used to set Helper shift mode.
2987  *
2988  * The prototype of the slot is:
2989  * void set_caps_mode (const HelperAgent *agent, uint32 &mode);
2990  */
2991 Connection
2992 HelperAgent::signal_connect_set_caps_mode (HelperAgentSlotUintVoid *slot)
2993 {
2994     return m_impl->signal_set_caps_mode.connect (slot);
2995 }
2996
2997 /**
2998  * @brief Connect a slot to Helper reset input context signal.
2999  *
3000  * This signal is used to reset Helper ISE input context.
3001  *
3002  * The prototype of the slot is:
3003  * void reset_input_context (const HelperAgent *agent, int ic, const String &uuid);
3004  */
3005 Connection
3006 HelperAgent::signal_connect_reset_input_context (HelperAgentSlotVoid *slot)
3007 {
3008     return m_impl->signal_reset_input_context.connect (slot);
3009 }
3010
3011 /**
3012  * @brief Connect a slot to Helper update candidate window geometry signal.
3013  *
3014  * This signal is used to get candidate window size and position.
3015  *
3016  * The prototype of the slot is:
3017  * void update_candidate_geometry (const HelperAgent *agent, int ic, const String &uuid, const rectinfo &info);
3018  */
3019 Connection
3020 HelperAgent::signal_connect_update_candidate_geometry (HelperAgentSlotRect *slot)
3021 {
3022     return m_impl->signal_update_candidate_geometry.connect (slot);
3023 }
3024
3025 /**
3026  * @brief Connect a slot to Helper update keyboard ISE signal.
3027  *
3028  * This signal is used to get current keyboard ISE name and uuid.
3029  *
3030  * The prototype of the slot is:
3031  * void update_keyboard_ise (const HelperAgent *agent, int ic, const String &uuid,
3032  *                           const String &ise_name, const String &ise_uuid);
3033  */
3034 Connection
3035 HelperAgent::signal_connect_update_keyboard_ise (HelperAgentSlotString2 *slot)
3036 {
3037     return m_impl->signal_update_keyboard_ise.connect (slot);
3038 }
3039
3040 /**
3041  * @brief Connect a slot to Helper update keyboard ISE list signal.
3042  *
3043  * This signal is used to get uuid list of all keyboard ISEs.
3044  *
3045  * The prototype of the slot is:
3046  * void update_keyboard_ise_list (const HelperAgent *agent, int ic, const String &uuid,
3047  *                                const std::vector<String> &ise_list);
3048  */
3049 Connection
3050 HelperAgent::signal_connect_update_keyboard_ise_list (HelperAgentSlotStringVector *slot)
3051 {
3052     return m_impl->signal_update_keyboard_ise_list.connect (slot);
3053 }
3054
3055 /**
3056  * @brief Connect a slot to Helper candidate more window show signal.
3057  *
3058  * This signal is used to do someting when candidate more window is showed.
3059  *
3060  * The prototype of the slot is:
3061  * void candidate_more_window_show (const HelperAgent *agent, int ic, const String &uuid);
3062  */
3063 Connection
3064 HelperAgent::signal_connect_candidate_more_window_show (HelperAgentSlotVoid *slot)
3065 {
3066     return m_impl->signal_candidate_more_window_show.connect (slot);
3067 }
3068
3069 /**
3070  * @brief Connect a slot to Helper candidate more window hide signal.
3071  *
3072  * This signal is used to do someting when candidate more window is hidden.
3073  *
3074  * The prototype of the slot is:
3075  * void candidate_more_window_hide (const HelperAgent *agent, int ic, const String &uuid);
3076  */
3077 Connection
3078 HelperAgent::signal_connect_candidate_more_window_hide (HelperAgentSlotVoid *slot)
3079 {
3080     return m_impl->signal_candidate_more_window_hide.connect (slot);
3081 }
3082
3083 /**
3084  * @brief Connect a slot to Helper candidate show signal.
3085  *
3086  * This signal is used to do candidate show.
3087  *
3088  * The prototype of the slot is:
3089  * void candidate_show (const HelperAgent *agent, int ic, const String &uuid);
3090  */
3091 Connection
3092 HelperAgent::signal_connect_candidate_show (HelperAgentSlotVoid *slot)
3093 {
3094     return m_impl->signal_candidate_show.connect (slot);
3095 }
3096
3097 /**
3098  * @brief Connect a slot to Helper candidate hide signal.
3099  *
3100  * This signal is used to do candidate hide.
3101  *
3102  * The prototype of the slot is:
3103  * void candidate_hide (const HelperAgent *agent, int ic, const String &uuid);
3104  */
3105 Connection
3106 HelperAgent::signal_connect_candidate_hide (HelperAgentSlotVoid *slot)
3107 {
3108     return m_impl->signal_candidate_hide.connect (slot);
3109 }
3110
3111 /**
3112  * @brief Connect a slot to Helper update lookup table signal.
3113  *
3114  * This signal is used to do someting when update lookup table.
3115  *
3116  * The prototype of the slot is:
3117  * void update_lookup_table (const HelperAgent *agent, int ic, const String &uuid ,LookupTable &table);
3118  */
3119 Connection
3120 HelperAgent::signal_connect_update_lookup_table (HelperAgentSlotLookupTable *slot)
3121 {
3122     return m_impl->signal_update_lookup_table.connect (slot);
3123 }
3124
3125 /**
3126  * @brief Connect a slot to Helper select aux signal.
3127  *
3128  * This signal is used to do something when aux is selected.
3129  *
3130  * The prototype of the slot is:
3131  * void select_aux (const HelperAgent *agent, int ic, const String &uuid, int index);
3132  */
3133 Connection
3134 HelperAgent::signal_connect_select_aux (HelperAgentSlotInt *slot)
3135 {
3136     return m_impl->signal_select_aux.connect (slot);
3137 }
3138
3139 /**
3140  * @brief Connect a slot to Helper select candidate signal.
3141  *
3142  * This signal is used to do something when candidate is selected.
3143  *
3144  * The prototype of the slot is:
3145  * void select_candidate (const HelperAgent *agent, int ic, const String &uuid, int index);
3146  */
3147 Connection
3148 HelperAgent::signal_connect_select_candidate (HelperAgentSlotInt *slot)
3149 {
3150     return m_impl->signal_select_candidate.connect (slot);
3151 }
3152
3153 /**
3154  * @brief Connect a slot to Helper candidate table page up signal.
3155  *
3156  * This signal is used to do something when candidate table is paged up.
3157  *
3158  * The prototype of the slot is:
3159  * void candidate_table_page_up (const HelperAgent *agent, int ic, const String &uuid);
3160  */
3161 Connection
3162 HelperAgent::signal_connect_candidate_table_page_up (HelperAgentSlotVoid *slot)
3163 {
3164     return m_impl->signal_candidate_table_page_up.connect (slot);
3165 }
3166
3167 /**
3168  * @brief Connect a slot to Helper candidate table page down signal.
3169  *
3170  * This signal is used to do something when candidate table is paged down.
3171  *
3172  * The prototype of the slot is:
3173  * void candidate_table_page_down (const HelperAgent *agent, int ic, const String &uuid);
3174  */
3175 Connection
3176 HelperAgent::signal_connect_candidate_table_page_down (HelperAgentSlotVoid *slot)
3177 {
3178     return m_impl->signal_candidate_table_page_down.connect (slot);
3179 }
3180
3181 /**
3182  * @brief Connect a slot to Helper update candidate table page size signal.
3183  *
3184  * This signal is used to do something when candidate table page size is changed.
3185  *
3186  * The prototype of the slot is:
3187  * void update_candidate_table_page_size (const HelperAgent *, int ic, const String &uuid, int page_size);
3188  */
3189 Connection
3190 HelperAgent::signal_connect_update_candidate_table_page_size (HelperAgentSlotInt *slot)
3191 {
3192     return m_impl->signal_update_candidate_table_page_size.connect (slot);
3193 }
3194
3195 /**
3196  * @brief Connect a slot to Helper update candidate item layout signal.
3197  *
3198  * The prototype of the slot is:
3199  * void update_candidate_item_layout (const HelperAgent *, const std::vector<uint32> &row_items);
3200  */
3201 Connection
3202 HelperAgent::signal_connect_update_candidate_item_layout (HelperAgentSlotUintVector *slot)
3203 {
3204     return m_impl->signal_update_candidate_item_layout.connect (slot);
3205 }
3206
3207 /**
3208  * @brief Connect a slot to Helper select associate signal.
3209  *
3210  * This signal is used to do something when associate is selected.
3211  *
3212  * The prototype of the slot is:
3213  * void select_associate (const HelperAgent *agent, int ic, const String &uuid, int index);
3214  */
3215 Connection
3216 HelperAgent::signal_connect_select_associate (HelperAgentSlotInt *slot)
3217 {
3218     return m_impl->signal_select_associate.connect (slot);
3219 }
3220
3221 /**
3222  * @brief Connect a slot to Helper associate table page up signal.
3223  *
3224  * This signal is used to do something when associate table is paged up.
3225  *
3226  * The prototype of the slot is:
3227  * void associate_table_page_up (const HelperAgent *agent, int ic, const String &uuid);
3228  */
3229 Connection
3230 HelperAgent::signal_connect_associate_table_page_up (HelperAgentSlotVoid *slot)
3231 {
3232     return m_impl->signal_associate_table_page_up.connect (slot);
3233 }
3234
3235 /**
3236  * @brief Connect a slot to Helper associate table page down signal.
3237  *
3238  * This signal is used to do something when associate table is paged down.
3239  *
3240  * The prototype of the slot is:
3241  * void associate_table_page_down (const HelperAgent *agent, int ic, const String &uuid);
3242  */
3243 Connection
3244 HelperAgent::signal_connect_associate_table_page_down (HelperAgentSlotVoid *slot)
3245 {
3246     return m_impl->signal_associate_table_page_down.connect (slot);
3247 }
3248
3249 /**
3250  * @brief Connect a slot to Helper update associate table page size signal.
3251  *
3252  * This signal is used to do something when associate table page size is changed.
3253  *
3254  * The prototype of the slot is:
3255  * void update_associate_table_page_size (const HelperAgent *, int ic, const String &uuid, int page_size);
3256  */
3257 Connection
3258 HelperAgent::signal_connect_update_associate_table_page_size (HelperAgentSlotInt *slot)
3259 {
3260     return m_impl->signal_update_associate_table_page_size.connect (slot);
3261 }
3262
3263 /**
3264  * @brief Connect a slot to Helper turn on log signal.
3265  *
3266  * This signal is used to turn on Helper ISE debug information.
3267  *
3268  * The prototype of the slot is:
3269  * void turn_on_log (const HelperAgent *agent, uint32 &on);
3270  */
3271 Connection
3272 HelperAgent::signal_connect_turn_on_log (HelperAgentSlotUintVoid *slot)
3273 {
3274     return m_impl->signal_turn_on_log.connect (slot);
3275 }
3276
3277 /**
3278  * @brief Connect a slot to Helper update displayed candidate number signal.
3279  *
3280  * This signal is used to inform helper ISE displayed candidate number.
3281  *
3282  * The prototype of the slot is:
3283  * void update_displayed_candidate_number (const HelperAgent *, int ic, const String &uuid, int number);
3284  */
3285 Connection
3286 HelperAgent::signal_connect_update_displayed_candidate_number (HelperAgentSlotInt *slot)
3287 {
3288     return m_impl->signal_update_displayed_candidate_number.connect (slot);
3289 }
3290
3291 /**
3292  * @brief Connect a slot to Helper longpress candidate signal.
3293  *
3294  * This signal is used to do something when candidate is longpress.
3295  *
3296  * The prototype of the slot is:
3297  * void longpress_candidate (const HelperAgent *agent, int ic, const String &uuid, int index);
3298  */
3299 Connection
3300 HelperAgent::signal_connect_longpress_candidate (HelperAgentSlotInt *slot)
3301 {
3302     return m_impl->signal_longpress_candidate.connect (slot);
3303 }
3304
3305 /**
3306  * @brief Connect a slot to Helper show option window.
3307  *
3308  * This signal is used to do request the ISE to show option window.
3309  *
3310  * The prototype of the slot is:
3311  * void show_option_window (const HelperAgent *agent, int ic, const String &uuid);
3312  */
3313 Connection
3314 HelperAgent::signal_connect_show_option_window (HelperAgentSlotVoid *slot)
3315 {
3316     return m_impl->signal_show_option_window.connect (slot);
3317 }
3318
3319 /**
3320  * @brief Connect a slot to Helper check if the option is available.
3321  *
3322  * This signal is used to check if the option (setting) is available from Helper ISE.
3323  *
3324  * The prototype of the slot is:
3325  * void check_option_window (const HelperAgent *agent, uint32 &avail);
3326  */
3327 Connection
3328 HelperAgent::signal_connect_check_option_window (HelperAgentSlotUintVoid *slot)
3329 {
3330     return m_impl->signal_check_option_window.connect (slot);
3331 }
3332
3333 /**
3334  * @brief Connect a slot to Helper process unconventional input device event signal.
3335  *
3336  * This signal is used to send unconventional input device event to Helper ISE.
3337  *
3338  * The prototype of the slot is:
3339  * void process_input_device_event (const HelperAgent *, uint32 &type, char *data, size_t &size, uint32 &ret);
3340  */
3341 Connection
3342 HelperAgent::signal_connect_process_input_device_event (HelperAgentSlotUintCharSizeUint *slot)
3343 {
3344     return m_impl->signal_process_input_device_event.connect (slot);
3345 }
3346
3347 } /* namespace scim */
3348
3349 /*
3350 vi:ts=4:nowrap:ai:expandtab
3351 */
3352