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