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