Check keyboard mode before sending ise state variables
[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                 if (!m_impl->si.null ()) m_impl->si->update_cursor_position(subclass->get_cursor_pos_ref());
950             }
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             m_impl->signal_set_mode (this, subclass->get_mode_ref());
1062             break;
1063         }
1064         case ISM_TRANS_CMD_SET_ISE_LANGUAGE:
1065         {
1066             MessageItemSetISELanguage *subclass = static_cast<MessageItemSetISELanguage*>(message);
1067             m_impl->signal_set_language (this, subclass->get_language_ref());
1068             break;
1069         }
1070         case ISM_TRANS_CMD_SET_ISE_IMDATA:
1071         {
1072             MessageItemSetISEImData *subclass = static_cast<MessageItemSetISEImData*>(message);
1073             m_impl->signal_set_imdata (this, *(subclass->get_imdata_ptr()), subclass->get_len_ref());
1074             if (!m_impl->si.null ()) m_impl->si->set_imdata(*(subclass->get_imdata_ptr()),
1075                 subclass->get_len_ref());
1076             break;
1077         }
1078         case ISM_TRANS_CMD_GET_ISE_IMDATA:
1079         {
1080             char   *buf = NULL;
1081             size_t  len = 0;
1082
1083             m_impl->signal_get_imdata (this, &buf, len);
1084             LOGD ("send ise imdata len = %d", len);
1085             m_impl->send.clear ();
1086             m_impl->send.put_command (SCIM_TRANS_CMD_REPLY);
1087             m_impl->send.put_data (buf, len);
1088             m_impl->send.write_to_socket (m_impl->socket);
1089             if (NULL != buf)
1090                 delete[] buf;
1091             break;
1092         }
1093         case ISM_TRANS_CMD_GET_ISE_LANGUAGE_LOCALE:
1094         {
1095             MessageItemGetISELanguageLocale *subclass = static_cast<MessageItemGetISELanguageLocale*>(message);
1096             char *buf = NULL;
1097             m_impl->signal_get_language_locale (this, subclass->get_ic_ref(), &buf);
1098             m_impl->send.clear ();
1099             m_impl->send.put_command (SCIM_TRANS_CMD_REPLY);
1100             if (buf != NULL)
1101                 m_impl->send.put_data (buf, strlen (buf));
1102             m_impl->send.write_to_socket (m_impl->socket);
1103             if (NULL != buf)
1104                 delete[] buf;
1105             break;
1106         }
1107         case ISM_TRANS_CMD_SET_RETURN_KEY_TYPE:
1108         {
1109             MessageItemSetReturnKeyType *subclass = static_cast<MessageItemSetReturnKeyType*>(message);
1110             if (m_impl->ise_show_flag || m_impl->hw_keyboard_mode) {
1111                 m_impl->signal_set_return_key_type (this, subclass->get_type_ref());
1112             }
1113             break;
1114         }
1115         case ISM_TRANS_CMD_GET_RETURN_KEY_TYPE:
1116         {
1117             uint32 type = 0;
1118             m_impl->signal_get_return_key_type (this, type);
1119             m_impl->send.clear ();
1120             m_impl->send.put_command (SCIM_TRANS_CMD_REPLY);
1121             m_impl->send.put_data (type);
1122             m_impl->send.write_to_socket (m_impl->socket);
1123             break;
1124         }
1125         case ISM_TRANS_CMD_SET_RETURN_KEY_DISABLE:
1126         {
1127             MessageItemSetReturnKeyDisable *subclass = static_cast<MessageItemSetReturnKeyDisable*>(message);
1128             if (m_impl->ise_show_flag || m_impl->hw_keyboard_mode) {
1129                 m_impl->signal_set_return_key_disable (this, subclass->get_disabled_ref());
1130             }
1131             break;
1132         }
1133         case ISM_TRANS_CMD_GET_RETURN_KEY_DISABLE:
1134         {
1135             uint32 disabled = 0;
1136             m_impl->signal_get_return_key_type (this, disabled);
1137             m_impl->send.clear ();
1138             m_impl->send.put_command (SCIM_TRANS_CMD_REPLY);
1139             m_impl->send.put_data (disabled);
1140             m_impl->send.write_to_socket (m_impl->socket);
1141             break;
1142         }
1143         case SCIM_TRANS_CMD_PROCESS_KEY_EVENT:
1144         {
1145             MessageItemProcessKeyEvent *subclass = static_cast<MessageItemProcessKeyEvent*>(message);
1146             uint32 ret = 0;
1147             m_impl->signal_process_key_event(this, subclass->get_key_ref(), ret);
1148             if (ret == 0)
1149                 if (!m_impl->si.null ())
1150                 {
1151                     ret = m_impl->si->process_key_event (subclass->get_key_ref());
1152                     LOGD("imengine(%s) process key %d return %d", m_impl->si->get_factory_uuid().c_str(),
1153                         subclass->get_key_ref().code, ret);
1154                 }
1155             m_impl->process_key_event_done (subclass->get_key_ref(), ret, subclass->get_serial_ref());
1156             break;
1157         }
1158         case ISM_TRANS_CMD_SET_LAYOUT:
1159         {
1160             MessageItemSetLayout *subclass = static_cast<MessageItemSetLayout*>(message);
1161             m_impl->layout = subclass->get_layout_ref();
1162             if (m_impl->ise_show_flag || m_impl->hw_keyboard_mode) {
1163                 m_impl->signal_set_layout (this, subclass->get_layout_ref());
1164                 if (!m_impl->si.null ()) m_impl->si->set_layout(subclass->get_layout_ref());
1165             }
1166             break;
1167         }
1168         case ISM_TRANS_CMD_GET_LAYOUT:
1169         {
1170             uint32 layout = 0;
1171
1172             m_impl->signal_get_layout (this, layout);
1173             m_impl->send.clear ();
1174             m_impl->send.put_command (SCIM_TRANS_CMD_REPLY);
1175             m_impl->send.put_data (layout);
1176             m_impl->send.write_to_socket (m_impl->socket);
1177             break;
1178         }
1179         case ISM_TRANS_CMD_SET_INPUT_MODE:
1180         {
1181             MessageItemSetInputMode *subclass = static_cast<MessageItemSetInputMode*>(message);
1182             m_impl->signal_set_input_mode (this, subclass->get_input_mode_ref());
1183             break;
1184         }
1185         case ISM_TRANS_CMD_SET_CAPS_MODE:
1186         {
1187             MessageItemSetCapsMode *subclass = static_cast<MessageItemSetCapsMode*>(message);
1188             if (m_impl->ise_show_flag || m_impl->hw_keyboard_mode) {
1189                 m_impl->signal_set_caps_mode (this, subclass->get_mode_ref());
1190             }
1191             break;
1192         }
1193         case SCIM_TRANS_CMD_PANEL_RESET_INPUT_CONTEXT:
1194         {
1195             MessageItemPanelResetInputContext *subclass = static_cast<MessageItemPanelResetInputContext*>(message);
1196             m_impl->signal_reset_input_context (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1197             if (!m_impl->si.null ()) m_impl->si->reset();
1198             break;
1199         }
1200         case ISM_TRANS_CMD_UPDATE_CANDIDATE_UI:
1201         {
1202             MessageItemUpdateCandidateUI *subclass = static_cast<MessageItemUpdateCandidateUI*>(message);
1203             m_impl->signal_update_candidate_ui (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
1204                 subclass->get_style_ref(), subclass->get_mode_ref());
1205             break;
1206         }
1207         case ISM_TRANS_CMD_UPDATE_CANDIDATE_GEOMETRY:
1208         {
1209             MessageItemUpdateCandidateGeometry *subclass = static_cast<MessageItemUpdateCandidateGeometry*>(message);
1210             m_impl->signal_update_candidate_geometry (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
1211                 subclass->get_rectinfo_ref());
1212             break;
1213         }
1214         case ISM_TRANS_CMD_UPDATE_KEYBOARD_ISE:
1215         {
1216             MessageItemUpdateKeyboardISE *subclass = static_cast<MessageItemUpdateKeyboardISE*>(message);
1217             m_impl->signal_update_keyboard_ise (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
1218                 subclass->get_name_ref(), subclass->get_uuid_ref());
1219             break;
1220         }
1221         case ISM_TRANS_CMD_UPDATE_KEYBOARD_ISE_LIST:
1222         {
1223             MessageItemUpdateKeyboardISEList *subclass = static_cast<MessageItemUpdateKeyboardISEList*>(message);
1224             m_impl->signal_update_keyboard_ise_list (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
1225                 subclass->get_list_ref());
1226             break;
1227         }
1228         case ISM_TRANS_CMD_CANDIDATE_MORE_WINDOW_SHOW:
1229         {
1230             MessageItemCandidateMoreWindowShow *subclass = static_cast<MessageItemCandidateMoreWindowShow*>(message);
1231             m_impl->signal_candidate_more_window_show (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1232             if (!m_impl->si.null ()) m_impl->si->candidate_more_window_show();
1233             break;
1234         }
1235         case ISM_TRANS_CMD_CANDIDATE_MORE_WINDOW_HIDE:
1236         {
1237             MessageItemCandidateMoreWindowHide *subclass = static_cast<MessageItemCandidateMoreWindowHide*>(message);
1238             m_impl->signal_candidate_more_window_hide (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1239             if (!m_impl->si.null ()) m_impl->si->candidate_more_window_hide();
1240             break;
1241         }
1242         case ISM_TRANS_CMD_SELECT_AUX:
1243         {
1244             MessageItemSelectAux *subclass = static_cast<MessageItemSelectAux*>(message);
1245             m_impl->signal_select_aux (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
1246                 subclass->get_item_ref());
1247             if (!m_impl->si.null ()) m_impl->si->select_aux(subclass->get_item_ref());
1248             break;
1249         }
1250         case SCIM_TRANS_CMD_SELECT_CANDIDATE: //FIXME:remove if useless
1251         {
1252             MessageItemSelectCandidate *subclass = static_cast<MessageItemSelectCandidate*>(message);
1253             m_impl->signal_select_candidate (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
1254                 subclass->get_item_ref());
1255             if (!m_impl->si.null ()) m_impl->si->select_candidate(subclass->get_item_ref());
1256             break;
1257         }
1258         case SCIM_TRANS_CMD_LOOKUP_TABLE_PAGE_UP: //FIXME:remove if useless
1259         {
1260             MessageItemLookupTablePageUp *subclass = static_cast<MessageItemLookupTablePageUp*>(message);
1261             m_impl->signal_candidate_table_page_up (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1262             if (!m_impl->si.null ()) m_impl->si->lookup_table_page_up();
1263             break;
1264         }
1265         case SCIM_TRANS_CMD_LOOKUP_TABLE_PAGE_DOWN: //FIXME:remove if useless
1266         {
1267             MessageItemLookupTablePageDown *subclass = static_cast<MessageItemLookupTablePageDown*>(message);
1268             m_impl->signal_candidate_table_page_down (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1269             if (!m_impl->si.null ()) m_impl->si->lookup_table_page_down();
1270             break;
1271         }
1272         case SCIM_TRANS_CMD_UPDATE_LOOKUP_TABLE_PAGE_SIZE:
1273         {
1274             MessageItemUpdateLookupTablePageSize *subclass = static_cast<MessageItemUpdateLookupTablePageSize*>(message);
1275             m_impl->signal_update_candidate_table_page_size (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
1276                 subclass->get_size_ref());
1277             if (!m_impl->si.null ()) m_impl->si->update_lookup_table_page_size(subclass->get_size_ref());
1278             break;
1279         }
1280         case ISM_TRANS_CMD_CANDIDATE_SHOW: //FIXME:remove if useless
1281         {
1282             MessageItemCandidateShow *subclass = static_cast<MessageItemCandidateShow*>(message);
1283             m_impl->signal_candidate_show (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1284             break;
1285         }
1286         case ISM_TRANS_CMD_CANDIDATE_HIDE: //FIXME:remove if useless
1287         {
1288             MessageItemCandidateHide *subclass = static_cast<MessageItemCandidateHide*>(message);
1289             m_impl->signal_candidate_hide (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1290             break;
1291         }
1292         case ISM_TRANS_CMD_UPDATE_LOOKUP_TABLE: //FIXME:remove if useless
1293         {
1294             MessageItemUpdateLookupTable *subclass = static_cast<MessageItemUpdateLookupTable*>(message);
1295             m_impl->signal_update_lookup_table (this, subclass->get_candidate_table_ref());
1296             break;
1297         }
1298         case ISM_TRANS_CMD_UPDATE_CANDIDATE_ITEM_LAYOUT:
1299         {
1300             MessageItemUpdateCandidateItemLayout *subclass = static_cast<MessageItemUpdateCandidateItemLayout*>(message);
1301             m_impl->signal_update_candidate_item_layout (this, subclass->get_row_items_ref());
1302             if (!m_impl->si.null ()) m_impl->si->update_candidate_item_layout(subclass->get_row_items_ref());
1303             break;
1304         }
1305         case ISM_TRANS_CMD_SELECT_ASSOCIATE:
1306         {
1307             MessageItemSelectAssociate *subclass = static_cast<MessageItemSelectAssociate*>(message);
1308             m_impl->signal_select_associate (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
1309                 subclass->get_item_ref());
1310             break;
1311         }
1312         case ISM_TRANS_CMD_ASSOCIATE_TABLE_PAGE_UP:
1313         {
1314             MessageItemAssociateTablePageUp *subclass = static_cast<MessageItemAssociateTablePageUp*>(message);
1315             m_impl->signal_associate_table_page_up (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1316             break;
1317         }
1318         case ISM_TRANS_CMD_ASSOCIATE_TABLE_PAGE_DOWN:
1319         {
1320             MessageItemAssociateTablePageDown *subclass = static_cast<MessageItemAssociateTablePageDown*>(message);
1321             m_impl->signal_associate_table_page_down (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1322             break;
1323         }
1324         case ISM_TRANS_CMD_UPDATE_ASSOCIATE_TABLE_PAGE_SIZE:
1325         {
1326             MessageItemUpdateAssociateTablePageSize *subclass = static_cast<MessageItemUpdateAssociateTablePageSize*>(message);
1327             m_impl->signal_update_associate_table_page_size (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
1328                 subclass->get_size_ref());
1329             break;
1330         }
1331         case ISM_TRANS_CMD_RESET_ISE_CONTEXT:
1332         {
1333             MessageItemResetISEContext *subclass = static_cast<MessageItemResetISEContext*>(message);
1334             m_impl->signal_reset_ise_context (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1335             m_impl->signal_reset_input_context (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1336             if (!m_impl->si.null ()) m_impl->si->reset();
1337             break;
1338         }
1339         case ISM_TRANS_CMD_TURN_ON_LOG:
1340         {
1341             MessageItemTurnOnLog *subclass = static_cast<MessageItemTurnOnLog*>(message);
1342             m_impl->signal_turn_on_log (this, subclass->get_state_ref());
1343             break;
1344         }
1345         case ISM_TRANS_CMD_UPDATE_DISPLAYED_CANDIDATE:
1346         {
1347             MessageItemUpdateDisplayedCandidate *subclass = static_cast<MessageItemUpdateDisplayedCandidate*>(message);
1348             m_impl->signal_update_displayed_candidate_number (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
1349                 subclass->get_size_ref());
1350             if (!m_impl->si.null ()) m_impl->si->update_displayed_candidate_number(subclass->get_size_ref());
1351             break;
1352         }
1353         case ISM_TRANS_CMD_LONGPRESS_CANDIDATE:
1354         {
1355             MessageItemLongpressCandidate *subclass = static_cast<MessageItemLongpressCandidate*>(message);
1356             m_impl->signal_longpress_candidate (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
1357                 subclass->get_index_ref());
1358             if (!m_impl->si.null ()) m_impl->si->longpress_candidate(subclass->get_index_ref());
1359             break;
1360         }
1361         case ISM_TRANS_CMD_SET_INPUT_HINT:
1362         {
1363             MessageItemSetInputHint *subclass = static_cast<MessageItemSetInputHint*>(message);
1364             m_impl->signal_set_input_hint (this, subclass->get_input_hint_ref());
1365             if (!m_impl->si.null ()) m_impl->si->set_input_hint(subclass->get_input_hint_ref());
1366             break;
1367         }
1368         case ISM_TRANS_CMD_UPDATE_BIDI_DIRECTION:
1369         {
1370             MessageItemUpdateBidiDirection *subclass = static_cast<MessageItemUpdateBidiDirection*>(message);
1371             m_impl->signal_update_bidi_direction (this, subclass->get_bidi_direction());
1372             if (!m_impl->si.null ()) m_impl->si->update_bidi_direction(subclass->get_bidi_direction());
1373             break;
1374         }
1375         case ISM_TRANS_CMD_SHOW_ISE_OPTION_WINDOW:
1376         {
1377             MessageItemShowISEOptionWindow *subclass = static_cast<MessageItemShowISEOptionWindow*>(message);
1378             m_impl->signal_show_option_window (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1379             break;
1380         }
1381         case ISM_TRANS_CMD_RESUME_ISE_OPTION_WINDOW:
1382         {
1383             MessageItemResumeISEOptionWindow *subclass = static_cast<MessageItemResumeISEOptionWindow*>(message);
1384             m_impl->signal_resume_option_window (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1385             break;
1386         }
1387         case ISM_TRANS_CMD_CHECK_OPTION_WINDOW:
1388         {
1389             uint32 avail = 0;
1390             m_impl->signal_check_option_window (this, avail);
1391             m_impl->send.clear ();
1392             m_impl->send.put_command (SCIM_TRANS_CMD_REPLY);
1393             m_impl->send.put_data (avail);
1394             m_impl->send.write_to_socket (m_impl->socket);
1395             break;
1396         }
1397         case ISM_TRANS_CMD_PROCESS_INPUT_DEVICE_EVENT:
1398         {
1399             MessageItemProcessInputDeviceEvent *subclass = static_cast<MessageItemProcessInputDeviceEvent*>(message);
1400             uint32 ret = 0;
1401             m_impl->signal_process_input_device_event(this,
1402                 subclass->get_type_ref(), *(subclass->get_data_ptr()), subclass->get_len_ref(), ret);
1403             m_impl->send.clear();
1404             m_impl->send.put_command(SCIM_TRANS_CMD_REPLY);
1405             m_impl->send.put_data(ret);
1406             m_impl->send.write_to_socket(m_impl->socket);
1407             break;
1408         }
1409         case SCIM_TRANS_CMD_SET_AUTOCAPITAL_TYPE:
1410         {
1411             MessageItemSetAutocapitalType *subclass = static_cast<MessageItemSetAutocapitalType*>(message);
1412             if (!m_impl->si.null ()) m_impl->si->set_autocapital_type(subclass->get_auto_capital_type_ref());
1413             break;
1414         }
1415         case ISM_TRANS_CMD_SET_PREDICTION_ALLOW:
1416         {
1417             MessageItemSetPredictionAllow *subclass = static_cast<MessageItemSetPredictionAllow*>(message);
1418             if (!m_impl->si.null ()) m_impl->si->set_prediction_allow(subclass->get_prediction_allow_ref() == 0 ? false : true);
1419             break;
1420         }
1421         case ISM_TRANS_CMD_SET_KEYBOARD_MODE:
1422         {
1423             MessageItemSetKeyboardMode *subclass = static_cast<MessageItemSetKeyboardMode*>(message);
1424             if (subclass->get_mode_ref())
1425                 m_impl->hw_keyboard_mode = false;
1426             else
1427                 m_impl->hw_keyboard_mode = true;
1428             break;
1429         }
1430         default:
1431             break;
1432     }
1433     return true;
1434 }
1435
1436 /**
1437  * @brief Request SCIM to reload all configuration.
1438  *
1439  * This function should only by used by Setup Helper to request
1440  * scim's reloading the configuration.
1441  * Deprecated: reload config message only send by socketconfig client
1442  * using socketconfig::reload instead.
1443  */
1444 void
1445 HelperAgent::reload_config () const
1446 {
1447     LOGD ("send reload config message to isf");
1448     if (!m_impl->m_config.null())
1449         m_impl->m_config->reload();
1450 }
1451
1452 /**
1453  * @brief Register some properties into Panel.
1454  *
1455  * This function send the request to Panel to register a list
1456  * of Properties.
1457  *
1458  * @param properties The list of Properties to be registered into Panel.
1459  *
1460  * @sa scim::Property.
1461  */
1462 void
1463 HelperAgent::register_properties (const PropertyList &properties) const
1464 {
1465     LOGD ("");
1466     if (m_impl->socket_active.is_connected ()) {
1467         m_impl->send.clear ();
1468         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1469         m_impl->send.put_data (m_impl->magic_active);
1470         m_impl->send.put_command (SCIM_TRANS_CMD_REGISTER_PROPERTIES);
1471         m_impl->send.put_data (properties);
1472         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1473     }
1474 }
1475
1476 /**
1477  * @brief Update a registered property.
1478  *
1479  * @param property The property to be updated.
1480  */
1481 void
1482 HelperAgent::update_property (const Property &property) const
1483 {
1484     LOGD ("");
1485     if (m_impl->socket_active.is_connected ()) {
1486         m_impl->send.clear ();
1487         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1488         m_impl->send.put_data (m_impl->magic_active);
1489         m_impl->send.put_command (SCIM_TRANS_CMD_UPDATE_PROPERTY);
1490         m_impl->send.put_data (property);
1491         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1492     }
1493 }
1494
1495 /**
1496  * @brief Send a set of events to an IMEngineInstance.
1497  *
1498  * All events should be put into a Transaction.
1499  * And the events can only be received by one IMEngineInstance object.
1500  *
1501  * @param ic The handle of the Input Context to receive the events.
1502  * @param ic_uuid The UUID of the Input Context.
1503  * @param trans The Transaction object holds the events.
1504  */
1505 void
1506 HelperAgent::send_imengine_event (int                ic,
1507                                   const String      &ic_uuid,
1508                                   const Transaction &trans) const
1509 {
1510     LOGD ("");
1511 //remove if not necessary
1512 #if 0
1513     if (m_impl->socket_active.is_connected ()) {
1514         m_impl->send.clear ();
1515         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1516         m_impl->send.put_data (m_impl->magic_active);
1517         m_impl->send.put_command (SCIM_TRANS_CMD_PANEL_SEND_IMENGINE_EVENT);
1518         m_impl->send.put_data ((uint32)ic);
1519         m_impl->send.put_data (ic_uuid);
1520         m_impl->send.put_data (trans);
1521         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1522     }
1523 #endif
1524     if (!m_impl->si.null ()) m_impl->si->process_helper_event (ic_uuid, trans);
1525 }
1526
1527 /**
1528  * @brief Send a KeyEvent to an IMEngineInstance.
1529  *
1530  * @param ic The handle of the IMEngineInstance to receive the event.
1531  *        -1 means the currently focused IMEngineInstance.
1532  * @param ic_uuid The UUID of the IMEngineInstance. Empty means don't match.
1533  * @param key The KeyEvent to be sent.
1534  */
1535 void
1536 HelperAgent::send_key_event (int            ic,
1537                              const String   &ic_uuid,
1538                              const KeyEvent &key) const
1539 {
1540     LOGD ("");
1541
1542     //FIXME: remove shift_mode_off, shift_mode_on, shift_mode_lock from ISE side
1543     if (key.code == SHIFT_MODE_OFF ||
1544         key.code == SHIFT_MODE_ON ||
1545         key.code == SHIFT_MODE_LOCK ||
1546         key.code == SHIFT_MODE_ENABLE ||
1547         key.code == SHIFT_MODE_DISABLE) {
1548         LOGW("FIXME ignore shift codes");
1549         return;
1550     }
1551
1552     if (m_impl->socket_active.is_connected ()) {
1553         m_impl->send.clear ();
1554         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1555         m_impl->send.put_data (m_impl->magic_active);
1556         m_impl->send.put_command (SCIM_TRANS_CMD_PANEL_SEND_KEY_EVENT);
1557         if (ic == -1) {
1558             m_impl->send.put_data (m_impl->focused_ic);
1559         } else {
1560             m_impl->send.put_data ((uint32)ic);
1561         }
1562         m_impl->send.put_data (ic_uuid);
1563         m_impl->send.put_data (key);
1564         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1565     }
1566 }
1567
1568 /**
1569  * @brief Forward a KeyEvent to client application directly.
1570  *
1571  * @param ic The handle of the client Input Context to receive the event.
1572  *        -1 means the currently focused Input Context.
1573  * @param ic_uuid The UUID of the IMEngine used by the Input Context.
1574  *        Empty means don't match.
1575  * @param key The KeyEvent to be forwarded.
1576  */
1577 void
1578 HelperAgent::forward_key_event (int            ic,
1579                                 const String   &ic_uuid,
1580                                 const KeyEvent &key) const
1581 {
1582     LOGD ("");
1583     if (m_impl->socket_active.is_connected ()) {
1584         m_impl->send.clear ();
1585         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1586         m_impl->send.put_data (m_impl->magic_active);
1587         m_impl->send.put_command (SCIM_TRANS_CMD_FORWARD_KEY_EVENT);
1588         if (ic == -1) {
1589             m_impl->send.put_data (m_impl->focused_ic);
1590         } else {
1591             m_impl->send.put_data ((uint32)ic);
1592         }
1593         m_impl->send.put_data (ic_uuid);
1594         m_impl->send.put_data (key);
1595         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1596     }
1597 }
1598
1599 /**
1600  * @brief Commit a WideString to client application directly.
1601  *
1602  * @param ic The handle of the client Input Context to receive the WideString.
1603  *        -1 means the currently focused Input Context.
1604  * @param ic_uuid The UUID of the IMEngine used by the Input Context.
1605  *        Empty means don't match.
1606  * @param wstr The WideString to be committed.
1607  */
1608 void
1609 HelperAgent::commit_string (int               ic,
1610                             const String     &ic_uuid,
1611                             const WideString &wstr) const
1612 {
1613     LOGD ("");
1614     if (m_impl->socket_active.is_connected ()) {
1615         m_impl->send.clear ();
1616         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1617         m_impl->send.put_data (m_impl->magic_active);
1618         m_impl->send.put_command (SCIM_TRANS_CMD_COMMIT_STRING);
1619         if (ic == -1) {
1620             m_impl->send.put_data (m_impl->focused_ic);
1621         } else {
1622             m_impl->send.put_data ((uint32)ic);
1623         }
1624         m_impl->send.put_data (ic_uuid);
1625         m_impl->send.put_data (wstr);
1626         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1627     }
1628 }
1629
1630 void
1631 HelperAgent::commit_string (int               ic,
1632                             const String     &ic_uuid,
1633                             const  char      *buf,
1634                             int               buflen) const
1635 {
1636     LOGD ("");
1637     if (m_impl->socket_active.is_connected ()) {
1638         m_impl->send.clear ();
1639         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1640         m_impl->send.put_data (m_impl->magic_active);
1641         m_impl->send.put_command (SCIM_TRANS_CMD_COMMIT_STRING);
1642         if (ic == -1) {
1643             m_impl->send.put_data (m_impl->focused_ic);
1644         } else {
1645             m_impl->send.put_data ((uint32)ic);
1646         }
1647         m_impl->send.put_data (ic_uuid);
1648         m_impl->send.put_dataw (buf, buflen);
1649         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1650     }
1651 }
1652
1653 /**
1654  * @brief Request to show preedit string.
1655  *
1656  * @param ic The handle of the client Input Context to receive the request.
1657  *        -1 means the currently focused Input Context.
1658  * @param ic_uuid The UUID of the IMEngine used by the Input Context.
1659  *        Empty means don't match.
1660  */
1661 void
1662 HelperAgent::show_preedit_string (int               ic,
1663                                   const String     &ic_uuid) const
1664 {
1665     LOGD ("");
1666
1667     if (m_impl->socket_active.is_connected ()) {
1668         m_impl->send.clear ();
1669         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1670         m_impl->send.put_data (m_impl->magic_active);
1671         m_impl->send.put_command (SCIM_TRANS_CMD_SHOW_PREEDIT_STRING);
1672         m_impl->send.put_data ((uint32)ic);
1673         m_impl->send.put_data (ic_uuid);
1674         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1675     }
1676 }
1677
1678 /**
1679  * @brief Request to show aux string.
1680  */
1681 void
1682 HelperAgent::show_aux_string (void) const
1683 {
1684     LOGD ("");
1685
1686     if (m_impl->socket_active.is_connected ()) {
1687         m_impl->send.clear ();
1688         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1689         m_impl->send.put_data (m_impl->magic_active);
1690         m_impl->send.put_command (SCIM_TRANS_CMD_SHOW_AUX_STRING);
1691         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1692     }
1693 }
1694
1695 /**
1696  * @brief Request to show candidate string.
1697  */
1698 void
1699 HelperAgent::show_candidate_string (void) const
1700 {
1701     LOGD ("");
1702
1703     if (m_impl->socket_active.is_connected ()) {
1704         m_impl->send.clear ();
1705         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1706         m_impl->send.put_data (m_impl->magic_active);
1707         m_impl->send.put_command (SCIM_TRANS_CMD_SHOW_LOOKUP_TABLE);
1708         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1709     }
1710 }
1711
1712 /**
1713  * @brief Request to show associate string.
1714  */
1715 void
1716 HelperAgent::show_associate_string (void) const
1717 {
1718     LOGD ("");
1719     if (m_impl->socket_active.is_connected ()) {
1720         m_impl->send.clear ();
1721         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1722         m_impl->send.put_data (m_impl->magic_active);
1723         m_impl->send.put_command (ISM_TRANS_CMD_SHOW_ASSOCIATE_TABLE);
1724         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1725     }
1726 }
1727
1728 /**
1729  * @brief Request to hide preedit string.
1730  *
1731  * @param ic The handle of the client Input Context to receive the request.
1732  *        -1 means the currently focused Input Context.
1733  * @param ic_uuid The UUID of the IMEngine used by the Input Context.
1734  *        Empty means don't match.
1735  */
1736 void
1737 HelperAgent::hide_preedit_string (int               ic,
1738                                   const String     &ic_uuid) const
1739 {
1740     LOGD ("");
1741
1742     if (m_impl->socket_active.is_connected ()) {
1743         m_impl->send.clear ();
1744         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1745         m_impl->send.put_data (m_impl->magic_active);
1746         m_impl->send.put_command (SCIM_TRANS_CMD_HIDE_PREEDIT_STRING);
1747         m_impl->send.put_data ((uint32)ic);
1748         m_impl->send.put_data (ic_uuid);
1749         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1750     }
1751 }
1752
1753 /**
1754  * @brief Request to hide aux string.
1755  */
1756 void
1757 HelperAgent::hide_aux_string (void) const
1758 {
1759     LOGD ("");
1760     if (m_impl->socket_active.is_connected ()) {
1761         m_impl->send.clear ();
1762         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1763         m_impl->send.put_data (m_impl->magic_active);
1764         m_impl->send.put_command (SCIM_TRANS_CMD_HIDE_AUX_STRING);
1765         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1766     }
1767 }
1768
1769 /**
1770  * @brief Request to hide candidate string.
1771  */
1772 void
1773 HelperAgent::hide_candidate_string (void) const
1774 {
1775     LOGD ("");
1776     if (m_impl->socket_active.is_connected ()) {
1777         m_impl->send.clear ();
1778         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1779         m_impl->send.put_data (m_impl->magic_active);
1780         m_impl->send.put_command (SCIM_TRANS_CMD_HIDE_LOOKUP_TABLE);
1781         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1782     }
1783 }
1784
1785 /**
1786  * @brief Request to hide associate string.
1787  */
1788 void
1789 HelperAgent::hide_associate_string (void) const
1790 {
1791     LOGD ("");
1792     if (m_impl->socket_active.is_connected ()) {
1793         m_impl->send.clear ();
1794         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1795         m_impl->send.put_data (m_impl->magic_active);
1796         m_impl->send.put_command (ISM_TRANS_CMD_HIDE_ASSOCIATE_TABLE);
1797         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1798     }
1799 }
1800
1801 /**
1802  * @brief Update a new WideString for preedit.
1803  *
1804  * @param ic The handle of the client Input Context to receive the WideString.
1805  *        -1 means the currently focused Input Context.
1806  * @param ic_uuid The UUID of the IMEngine used by the Input Context.
1807  *        Empty means don't match.
1808  * @param str The WideString to be updated.
1809  * @param attrs The attribute list for preedit string.
1810  */
1811 void
1812 HelperAgent::update_preedit_string (int                  ic,
1813                                     const String        &ic_uuid,
1814                                     const WideString    &str,
1815                                     const AttributeList &attrs) const
1816 {
1817     LOGD ("");
1818     update_preedit_string (ic, ic_uuid, str, str, attrs, -1);
1819 }
1820
1821 void
1822 HelperAgent::update_preedit_string (int                  ic,
1823                                     const String        &ic_uuid,
1824                                     const char         *buf,
1825                                     int                 buflen,
1826                                     const AttributeList &attrs) const
1827 {
1828     LOGD ("");
1829     update_preedit_string (ic, ic_uuid, buf, buflen, attrs, -1);
1830 }
1831
1832 /**
1833  * @brief Update a new WideString for preedit.
1834  *
1835  * @param ic The handle of the client Input Context to receive the WideString.
1836  *        -1 means the currently focused Input Context.
1837  * @param ic_uuid The UUID of the IMEngine used by the Input Context.
1838  *        Empty means don't match.
1839  * @param str The WideString to be updated.
1840  * @param attrs The attribute list for preedit string.
1841  * @param caret The caret position in preedit string.
1842  */
1843 void
1844 HelperAgent::update_preedit_string (int                  ic,
1845                                     const String        &ic_uuid,
1846                                     const WideString    &wstr,
1847                                     const AttributeList &attrs,
1848                                     int            caret) const
1849 {
1850     LOGD ("");
1851     update_preedit_string (ic, ic_uuid, wstr, wstr, attrs, caret);
1852 }
1853
1854 void
1855 HelperAgent::update_preedit_string (int                 ic,
1856                                     const String       &ic_uuid,
1857                                     const char         *buf,
1858                                     int                 buflen,
1859                                     const AttributeList &attrs,
1860                                     int            caret) const
1861 {
1862     LOGD ("");
1863
1864     if (m_impl->socket_active.is_connected ()) {
1865         m_impl->send.clear ();
1866         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1867         m_impl->send.put_data (m_impl->magic_active);
1868         m_impl->send.put_command (SCIM_TRANS_CMD_UPDATE_PREEDIT_STRING);
1869         m_impl->send.put_data ((uint32)ic);
1870         m_impl->send.put_data (ic_uuid);
1871         m_impl->send.put_dataw (buf, buflen);
1872         m_impl->send.put_dataw (buf, buflen);
1873         m_impl->send.put_data (attrs);
1874         m_impl->send.put_data (caret);
1875         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1876     }
1877 }
1878
1879 void
1880 HelperAgent::update_preedit_string (int                  ic,
1881                                     const String        &ic_uuid,
1882                                     const WideString    &preedit,
1883                                     const WideString    &commit,
1884                                     const AttributeList &attrs,
1885                                     int                  caret) const
1886 {
1887     LOGD ("");
1888     if (m_impl->socket_active.is_connected ()) {
1889         m_impl->send.clear ();
1890         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1891         m_impl->send.put_data (m_impl->magic_active);
1892         m_impl->send.put_command (SCIM_TRANS_CMD_UPDATE_PREEDIT_STRING);
1893         m_impl->send.put_data ((uint32)ic);
1894         m_impl->send.put_data (ic_uuid);
1895         m_impl->send.put_data (preedit);
1896         m_impl->send.put_data (commit);
1897         m_impl->send.put_data (attrs);
1898         m_impl->send.put_data (caret);
1899         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1900     }
1901 }
1902
1903 /**
1904  * @brief Update the preedit caret position in the preedit string.
1905  *
1906  * @param caret - the new position of the preedit caret.
1907  */
1908 void
1909 HelperAgent::update_preedit_caret (int caret) const
1910 {
1911     LOGD ("");
1912
1913     if (m_impl->socket_active.is_connected ()) {
1914         m_impl->send.clear ();
1915         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1916         m_impl->send.put_data (m_impl->magic_active);
1917         m_impl->send.put_command (SCIM_TRANS_CMD_UPDATE_PREEDIT_CARET);
1918         m_impl->send.put_data ((uint32)caret);
1919         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1920     }
1921 }
1922
1923 /**
1924  * @brief Update a new string for aux.
1925  *
1926  * @param str The string to be updated.
1927  * @param attrs The attribute list for aux string.
1928  */
1929 void
1930 HelperAgent::update_aux_string (const String        &str,
1931                                 const AttributeList &attrs) const
1932 {
1933     LOGD ("");
1934     if (m_impl->socket_active.is_connected ()) {
1935         m_impl->send.clear ();
1936         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1937         m_impl->send.put_data (m_impl->magic_active);
1938         m_impl->send.put_command (SCIM_TRANS_CMD_UPDATE_AUX_STRING);
1939         m_impl->send.put_data (str);
1940         m_impl->send.put_data (attrs);
1941         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1942     }
1943 }
1944
1945 /**
1946  * @brief Request to update candidate.
1947  *
1948  * @param table The lookup table for candidate.
1949  */
1950 void
1951 HelperAgent::update_candidate_string (const LookupTable &table) const
1952 {
1953     LOGD ("");
1954     if (m_impl->socket_active.is_connected ()) {
1955         m_impl->send.clear ();
1956         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1957         m_impl->send.put_data (m_impl->magic_active);
1958         m_impl->send.put_command (SCIM_TRANS_CMD_UPDATE_LOOKUP_TABLE);
1959         m_impl->send.put_data (table);
1960         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1961     }
1962 }
1963
1964 /**
1965  * @brief Request to update associate.
1966  *
1967  * @param table The lookup table for associate.
1968  */
1969 void
1970 HelperAgent::update_associate_string (const LookupTable &table) const
1971 {
1972     LOGD ("");
1973     if (m_impl->socket_active.is_connected ()) {
1974         m_impl->send.clear ();
1975         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1976         m_impl->send.put_data (m_impl->magic_active);
1977         m_impl->send.put_command (ISM_TRANS_CMD_UPDATE_ASSOCIATE_TABLE);
1978         m_impl->send.put_data (table);
1979         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1980     }
1981 }
1982
1983 /**
1984  * @brief When the input context of ISE is changed,
1985  *         ISE can call this function to notify application
1986  *
1987  * @param type  type of event.
1988  * @param value value of event.
1989  */
1990 void
1991 HelperAgent::update_input_context (uint32 type, uint32 value) const
1992 {
1993     LOGD ("");
1994     if (m_impl->socket_active.is_connected ()) {
1995         m_impl->send.clear ();
1996         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1997         m_impl->send.put_data (m_impl->magic_active);
1998         m_impl->send.put_command (ISM_TRANS_CMD_UPDATE_ISE_INPUT_CONTEXT);
1999         m_impl->send.put_data (type);
2000         m_impl->send.put_data (value);
2001         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2002     }
2003 }
2004
2005 /**
2006  * @brief Request to get surrounding text asynchronously.
2007  *
2008  * @param uuid The helper ISE UUID.
2009  * @param maxlen_before The max length of before.
2010  * @param maxlen_after The max length of after.
2011  */
2012 void
2013 HelperAgent::get_surrounding_text (const String &uuid, int maxlen_before, int maxlen_after) const
2014 {
2015     LOGD ("");
2016     if (m_impl->socket_active.is_connected () && (m_impl->need_update_surrounding_text == 0)) {
2017         m_impl->send.clear ();
2018         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2019         m_impl->send.put_data (m_impl->magic_active);
2020         m_impl->send.put_command (SCIM_TRANS_CMD_GET_SURROUNDING_TEXT);
2021         m_impl->send.put_data (uuid);
2022         m_impl->send.put_data (maxlen_before);
2023         m_impl->send.put_data (maxlen_after);
2024         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2025     }
2026     m_impl->need_update_surrounding_text++;
2027 }
2028
2029 /**
2030  * @brief Request to get surrounding text synchronously.
2031  *
2032  * @param uuid The helper ISE UUID.
2033  * @param maxlen_before The max length of before.
2034  * @param maxlen_after The max length of after.
2035  * @param text The surrounding text.
2036  * @param cursor The cursor position.
2037  */
2038 void
2039 HelperAgent::get_surrounding_text (int maxlen_before, int maxlen_after, String &text, int &cursor)
2040 {
2041     LOGD ("");
2042
2043     if (!m_impl->socket_active.is_connected ())
2044         return;
2045
2046     m_impl->send.clear ();
2047     m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2048     m_impl->send.put_data (m_impl->magic_active);
2049     m_impl->send.put_command (SCIM_TRANS_CMD_GET_SURROUNDING_TEXT);
2050     m_impl->send.put_data ("");
2051     m_impl->send.put_data (maxlen_before);
2052     m_impl->send.put_data (maxlen_after);
2053     m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2054     if (m_impl->surrounding_text) {
2055         free (m_impl->surrounding_text);
2056         m_impl->surrounding_text = NULL;
2057     }
2058
2059     const int WAIT_FOR_SYNC_RESPONSE_TIMEOUT = 1000;
2060     /* Now we are waiting for the ISM_TRANS_CMD_UPDATE_SURROUNDING_TEXT message */
2061     if (wait_for_message(ISM_TRANS_CMD_UPDATE_SURROUNDING_TEXT, WAIT_FOR_SYNC_RESPONSE_TIMEOUT)) {
2062         MessageItem *message = message_queue.get_pending_message_by_cmd(ISM_TRANS_CMD_UPDATE_SURROUNDING_TEXT);
2063         handle_message(message);
2064         message_queue.remove_message(message);
2065
2066         if (m_impl->surrounding_text) {
2067             text = m_impl->surrounding_text;
2068             cursor = m_impl->cursor_pos;
2069         }
2070     }
2071
2072     if (m_impl->surrounding_text) {
2073         free (m_impl->surrounding_text);
2074         m_impl->surrounding_text = NULL;
2075     }
2076 }
2077
2078 /**
2079  * @brief Request to delete surrounding text.
2080  *
2081  * @param offset The offset for cursor position.
2082  * @param len The length for delete text.
2083  */
2084 void
2085 HelperAgent::delete_surrounding_text (int offset, int len) const
2086 {
2087     LOGD ("offset = %d, len = %d", offset, len);
2088
2089     if (m_impl->socket_active.is_connected ()) {
2090         m_impl->send.clear ();
2091         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2092         m_impl->send.put_data (m_impl->magic_active);
2093         m_impl->send.put_command (SCIM_TRANS_CMD_DELETE_SURROUNDING_TEXT);
2094         m_impl->send.put_data (offset);
2095         m_impl->send.put_data (len);
2096         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2097     }
2098 }
2099
2100 /**
2101  * @brief Request to get selection text asynchronously.
2102  *
2103  * @param uuid The helper ISE UUID.
2104  */
2105 void
2106 HelperAgent::get_selection (const String &uuid) const
2107 {
2108     LOGD ("");
2109     if (m_impl->socket_active.is_connected () && (m_impl->need_update_selection_text == 0)) {
2110         m_impl->send.clear ();
2111         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2112         m_impl->send.put_data (m_impl->magic_active);
2113         m_impl->send.put_command (SCIM_TRANS_CMD_GET_SELECTION);
2114         m_impl->send.put_data (uuid);
2115         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2116     }
2117     m_impl->need_update_selection_text++;
2118 }
2119
2120 /**
2121  * @brief Request to get selection text synchronously.
2122  *
2123  * @param text The selection text.
2124  */
2125 void
2126 HelperAgent::get_selection_text (String &text)
2127 {
2128     LOGD ("");
2129
2130     if (!m_impl->socket_active.is_connected ())
2131         return;
2132
2133     m_impl->send.clear ();
2134     m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2135     m_impl->send.put_data (m_impl->magic_active);
2136     m_impl->send.put_command (SCIM_TRANS_CMD_GET_SELECTION);
2137     m_impl->send.put_data ("");
2138     m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2139     if (m_impl->selection_text) {
2140         free (m_impl->selection_text);
2141         m_impl->selection_text = NULL;
2142     }
2143
2144     const int WAIT_FOR_SYNC_RESPONSE_TIMEOUT = 1000;
2145     /* Now we are waiting for the ISM_TRANS_CMD_UPDATE_SELECTION message */
2146     if (wait_for_message(ISM_TRANS_CMD_UPDATE_SELECTION, WAIT_FOR_SYNC_RESPONSE_TIMEOUT)) {
2147         MessageItem *message = message_queue.get_pending_message_by_cmd(ISM_TRANS_CMD_UPDATE_SELECTION);
2148         handle_message(message);
2149         message_queue.remove_message(message);
2150         if (m_impl->selection_text) {
2151             text = m_impl->selection_text;
2152         }
2153     }
2154
2155     if (m_impl->selection_text) {
2156         free (m_impl->selection_text);
2157         m_impl->selection_text = NULL;
2158     }
2159 }
2160
2161 /**
2162  * @brief Request to select text.
2163  *
2164  * @param start The start position in text.
2165  * @param end The end position in text.
2166  */
2167 void
2168 HelperAgent::set_selection (int start, int end) const
2169 {
2170     LOGD ("");
2171     if (m_impl->socket_active.is_connected ()) {
2172         m_impl->send.clear ();
2173         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2174         m_impl->send.put_data (m_impl->magic_active);
2175         m_impl->send.put_command (SCIM_TRANS_CMD_SET_SELECTION);
2176         m_impl->send.put_data (start);
2177         m_impl->send.put_data (end);
2178         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2179     }
2180 }
2181
2182 /**
2183  * @brief Send a private command to an application.
2184  *
2185  * @param command The private command sent from IME.
2186  */
2187 void
2188 HelperAgent::send_private_command (const String &command) const
2189 {
2190     LOGD ("");
2191     if (m_impl->socket_active.is_connected ()) {
2192         m_impl->send.clear ();
2193         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2194         m_impl->send.put_data (m_impl->magic_active);
2195         m_impl->send.put_command (SCIM_TRANS_CMD_SEND_PRIVATE_COMMAND);
2196         m_impl->send.put_data (command);
2197         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2198     }
2199 }
2200
2201 /**
2202  * @brief Request to get uuid list of all keyboard ISEs.
2203  *
2204  * @param uuid The helper ISE UUID.
2205  */
2206 void
2207 HelperAgent::get_keyboard_ise_list (const String &uuid) const
2208 {
2209     LOGD ("");
2210     if (m_impl->socket_active.is_connected ()) {
2211         m_impl->send.clear ();
2212         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2213         m_impl->send.put_data (m_impl->magic_active);
2214         m_impl->send.put_command (ISM_TRANS_CMD_GET_KEYBOARD_ISE_LIST);
2215         m_impl->send.put_data (uuid);
2216         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2217     }
2218 }
2219
2220 /**
2221  * @brief Set candidate position in screen.
2222  *
2223  * @param left The x position in screen.
2224  * @param top The y position in screen.
2225  */
2226 void
2227 HelperAgent::set_candidate_position (int left, int top) const
2228 {
2229     LOGD ("");
2230     if (m_impl->socket_active.is_connected ()) {
2231         m_impl->send.clear ();
2232         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2233         m_impl->send.put_data (m_impl->magic_active);
2234         m_impl->send.put_command (ISM_TRANS_CMD_SET_CANDIDATE_POSITION);
2235         m_impl->send.put_data (left);
2236         m_impl->send.put_data (top);
2237         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2238     }
2239 }
2240
2241 /**
2242  * @brief Set candidate style.
2243  *
2244  * @param portrait_line - the displayed line number for portrait mode.
2245  * @param mode          - candidate window mode.
2246  */
2247 void
2248 HelperAgent::set_candidate_style (ISF_CANDIDATE_PORTRAIT_LINE_T portrait_line,
2249                                   ISF_CANDIDATE_MODE_T          mode) const
2250 {
2251     LOGD ("");
2252     if (m_impl->socket_active.is_connected ()) {
2253         m_impl->send.clear ();
2254         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2255         m_impl->send.put_data (m_impl->magic_active);
2256         m_impl->send.put_command (ISM_TRANS_CMD_SET_CANDIDATE_UI);
2257         m_impl->send.put_data (portrait_line);
2258         m_impl->send.put_data (mode);
2259         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2260     }
2261 }
2262
2263 /**
2264  * @brief Request to hide candidate window.
2265  */
2266 void
2267 HelperAgent::candidate_hide (void) const
2268 {
2269     LOGD ("");
2270     if (m_impl->socket_active.is_connected ()) {
2271         m_impl->send.clear ();
2272         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2273         m_impl->send.put_data (m_impl->magic_active);
2274         m_impl->send.put_command (ISM_TRANS_CMD_HIDE_CANDIDATE);
2275         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2276     }
2277 }
2278
2279 /**
2280  * @brief Request to get candidate window size and position.
2281  *
2282  * @param uuid The helper ISE UUID.
2283  */
2284 void
2285 HelperAgent::get_candidate_window_geometry (const String &uuid) const
2286 {
2287     LOGD ("");
2288     if (m_impl->socket_active.is_connected ()) {
2289         m_impl->send.clear ();
2290         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2291         m_impl->send.put_data (m_impl->magic_active);
2292         m_impl->send.put_command (ISM_TRANS_CMD_GET_CANDIDATE_GEOMETRY);
2293         m_impl->send.put_data (uuid);
2294         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2295     }
2296 }
2297
2298 /**
2299  * @brief Set current keyboard ISE.
2300  *
2301  * @param uuid The keyboard ISE UUID.
2302  */
2303 void
2304 HelperAgent::set_keyboard_ise_by_uuid (const String &uuid) const
2305 {
2306     LOGD ("");
2307     ImeInfoDB imeInfo;
2308     IMEngineFactoryPointer factory;
2309     IMEngineModule *engine_module = NULL;
2310     static int instance_count = 1;
2311
2312     if ((!m_impl->si.null ()) && m_impl->si->get_factory_uuid () == uuid) {
2313         LOGD ("Already in UUID: %s\n", uuid.c_str());
2314         return;
2315     }
2316
2317     if (!m_impl->si.null()) {
2318         m_impl->si->focus_out();
2319         m_impl->si.reset();
2320     }
2321
2322     if (m_impl->m_config.null ()) {
2323         LOGW ("config is not working");
2324         return;
2325     }
2326
2327 #ifdef HAVE_PKGMGR_INFO
2328     int ret = 0;
2329     char *pkgid = NULL;
2330     pkgmgrinfo_appinfo_h handle;
2331     ret = pkgmgrinfo_appinfo_get_appinfo(uuid.c_str(), &handle);
2332     if (ret != PMINFO_R_OK) {
2333         LOGW("Retrieve app info failed : %s", uuid.c_str ());
2334         return;
2335     }
2336
2337     ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
2338     if (ret != PMINFO_R_OK) {
2339         LOGW("Retrieve pkgid failed : %s, %p", uuid.c_str(), handle);
2340         pkgmgrinfo_appinfo_destroy_appinfo(handle);
2341         return;
2342     }
2343
2344     imeInfo.module_name = pkgid;
2345     pkgmgrinfo_appinfo_destroy_appinfo(handle);
2346 #else
2347     if (isf_db_select_ime_info_by_appid(uuid.c_str(), &imeInfo) < 1) {
2348         LOGW("ime_info row is not available for %s", uuid.c_str());
2349         return;
2350     }
2351 #endif
2352
2353     engine_module = &m_impl->engine_module;
2354
2355     if (engine_module->valid() && imeInfo.module_name != engine_module->get_module_name()) {
2356         LOGD ("imengine module %s unloaded", engine_module->get_module_name().c_str());
2357         engine_module->unload();
2358     }
2359
2360     if (!engine_module->valid()) {
2361         if (engine_module->load (imeInfo.module_name, m_impl->m_config) == false) {
2362             LOGW ("load module %s failed", imeInfo.module_name.c_str());
2363             return;
2364         }
2365         LOGD ("imengine module %s loaded", imeInfo.module_name.c_str());
2366     }
2367
2368     for (size_t j = 0; j < engine_module->number_of_factories (); ++j) {
2369
2370         try {
2371             factory = engine_module->create_factory (j);
2372             if (factory.null () == false && factory->get_uuid () == uuid)
2373                 break;
2374         } catch (...) {
2375             factory.reset ();
2376             return;
2377         }
2378     }
2379
2380     if (factory.null()) {
2381         LOGW ("imengine uuid %s is not found", uuid.c_str());
2382         return;
2383     }
2384
2385     m_impl->si = factory->create_instance ("UTF-8", instance_count++);
2386     if (m_impl->si.null ()) {
2387         LOGE ("create_instance %s failed",uuid.c_str ());
2388         return;
2389     }
2390
2391     m_impl->attach_instance ();
2392     LOGD ("Require UUID: %s Current UUID: %s", uuid.c_str (), m_impl->si->get_factory_uuid ().c_str ());
2393     m_impl->si->set_layout (m_impl->layout);
2394     if(m_impl->focused_ic != (uint32)-1)
2395         m_impl->si->focus_in ();
2396 }
2397
2398 /**
2399  * @brief Request to get current keyboard ISE information.
2400  *
2401  * @param uuid The helper ISE UUID.
2402  */
2403 void
2404 HelperAgent::get_keyboard_ise (const String &uuid) const
2405 {
2406     LOGD ("");
2407     //FIXME: maybe useless
2408 #if 0
2409     if (m_impl->socket_active.is_connected ()) {
2410         m_impl->send.clear ();
2411         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2412         m_impl->send.put_data (m_impl->magic_active);
2413         m_impl->send.put_command (ISM_TRANS_CMD_GET_KEYBOARD_ISE);
2414         m_impl->send.put_data (uuid);
2415         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2416     }
2417 #endif
2418 }
2419
2420 /**
2421  * @brief Update ISE window geometry.
2422  *
2423  * @param x      The x position in screen.
2424  * @param y      The y position in screen.
2425  * @param width  The ISE window width.
2426  * @param height The ISE window height.
2427  */
2428 void
2429 HelperAgent::update_geometry (int x, int y, int width, int height) const
2430 {
2431     LOGD ("");
2432     if (m_impl->socket_active.is_connected ()) {
2433         m_impl->send.clear ();
2434         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2435         m_impl->send.put_data (m_impl->magic_active);
2436         m_impl->send.put_command (ISM_TRANS_CMD_UPDATE_ISE_GEOMETRY);
2437         m_impl->send.put_data (x);
2438         m_impl->send.put_data (y);
2439         m_impl->send.put_data (width);
2440         m_impl->send.put_data (height);
2441         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2442     }
2443 }
2444
2445 /**
2446  * @brief Request to expand candidate window.
2447  */
2448 void
2449 HelperAgent::expand_candidate (void) const
2450 {
2451     LOGD ("");
2452     if (m_impl->socket_active.is_connected ()) {
2453         m_impl->send.clear ();
2454         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2455         m_impl->send.put_data (m_impl->magic_active);
2456         m_impl->send.put_command (ISM_TRANS_CMD_EXPAND_CANDIDATE);
2457         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2458     }
2459 }
2460
2461 /**
2462  * @brief Request to contract candidate window.
2463  */
2464 void
2465 HelperAgent::contract_candidate (void) const
2466 {
2467     LOGD ("");
2468     if (m_impl->socket_active.is_connected ()) {
2469         m_impl->send.clear ();
2470         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2471         m_impl->send.put_data (m_impl->magic_active);
2472         m_impl->send.put_command (ISM_TRANS_CMD_CONTRACT_CANDIDATE);
2473         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2474     }
2475 }
2476
2477 /**
2478  * @brief Send selected candidate string index number.
2479  */
2480 void
2481 HelperAgent::select_candidate (int index) const
2482 {
2483     LOGD ("");
2484     if (!m_impl->si.null ())
2485         m_impl->si->select_candidate (index);
2486     //FIXME: maybe useless
2487 #if 0
2488
2489     if (m_impl->socket_active.is_connected ()) {
2490         m_impl->send.clear ();
2491         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2492         m_impl->send.put_data (m_impl->magic_active);
2493         m_impl->send.put_command (ISM_TRANS_CMD_SELECT_CANDIDATE);
2494         m_impl->send.put_data (index);
2495         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2496     }
2497 #endif
2498 }
2499
2500 /**
2501  * @brief Update our ISE is exiting.
2502  */
2503 void
2504 HelperAgent::update_ise_exit (void) const
2505 {
2506     LOGD ("");
2507     //FIXME: maybe useless
2508 #if 0
2509     if (m_impl->socket_active.is_connected ()) {
2510         m_impl->send.clear ();
2511         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2512         m_impl->send.put_data (m_impl->magic_active);
2513         m_impl->send.put_command (ISM_TRANS_CMD_UPDATE_ISE_EXIT);
2514         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2515     }
2516 #endif
2517 }
2518
2519 /**
2520  * @brief Request to reset keyboard ISE.
2521  */
2522 void
2523 HelperAgent::reset_keyboard_ise (void) const
2524 {
2525     LOGD ("");
2526 //FIXME: maybe useless
2527 #if 0
2528     if (m_impl->socket_active.is_connected ()) {
2529         m_impl->send.clear ();
2530         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2531         m_impl->send.put_data (m_impl->magic_active);
2532         m_impl->send.put_command (ISM_TRANS_CMD_PANEL_RESET_KEYBOARD_ISE);
2533         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2534     }
2535 #endif
2536     if (!m_impl->si.null ()) {
2537         m_impl->si->reset ();
2538     }
2539 }
2540
2541 /**
2542  * @brief Request to flush keyboard ISE.
2543  */
2544 void
2545 HelperAgent::flush_keyboard_ise (void) const
2546 {
2547     LOGD ("");
2548     if (!m_impl->si.null ()) {
2549         m_impl->si->flush ();
2550     }
2551 }
2552
2553 /**
2554  * @brief Request panel to hide ISE.
2555  */
2556 void
2557 HelperAgent::request_ise_hide (void) const
2558 {
2559     LOGD ("");
2560     if (m_impl->socket_active.is_connected ()) {
2561         m_impl->send.clear ();
2562         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2563         m_impl->send.put_data (m_impl->magic_active);
2564         m_impl->send.put_command (ISM_TRANS_CMD_REQUEST_ISE_HIDE);
2565         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2566     }
2567 }
2568
2569 /**
2570  * @brief Recapture
2571  */
2572 void
2573 HelperAgent::recapture_string (int                  ic,
2574                                const String        &ic_uuid,
2575                                int                  offset,
2576                                int                  len,
2577                                const WideString    &preedit_str,
2578                                const WideString    &commit_str,
2579                                const AttributeList &attrs) const
2580 {
2581     LOGD ("offset = %d, len = %d", offset, len);
2582
2583     if (m_impl->socket_active.is_connected ()) {
2584         m_impl->send.clear ();
2585         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2586         m_impl->send.put_data (m_impl->magic_active);
2587         m_impl->send.put_command (ISM_TRANS_CMD_RECAPTURE_STRING);
2588
2589         m_impl->send.put_data ((uint32)ic);
2590         m_impl->send.put_data (ic_uuid);
2591
2592         // Deleting surrounding text
2593         m_impl->send.put_data (offset);
2594         m_impl->send.put_data (len);
2595
2596         // Update preedit text
2597         m_impl->send.put_data (preedit_str);
2598
2599         // Commit
2600         m_impl->send.put_data (commit_str);
2601
2602         // preedit attributes
2603         m_impl->send.put_data (attrs);
2604
2605         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2606     }
2607 }
2608
2609 /**
2610  * @brief Connect a slot to Helper exit signal.
2611  *
2612  * This signal is used to let the Helper exit.
2613  *
2614  * The prototype of the slot is:
2615  *
2616  * void exit (const HelperAgent *agent, int ic, const String &ic_uuid);
2617  *
2618  * Parameters:
2619  * - agent    The pointer to the HelperAgent object which emits this signal.
2620  * - ic       An opaque handle of the currently focused input context.
2621  * - ic_uuid  The UUID of the IMEngineInstance associated with the focused input context.
2622  */
2623 Connection
2624 HelperAgent::signal_connect_exit (HelperAgentSlotVoid *slot)
2625 {
2626     return m_impl->signal_exit.connect (slot);
2627 }
2628
2629 /**
2630  * @brief Connect a slot to Helper attach input context signal.
2631  *
2632  * This signal is used to attach an input context to this helper.
2633  *
2634  * When an input context requst to start this helper, then this
2635  * signal will be emitted as soon as the helper is started.
2636  *
2637  * When an input context want to start an already started helper,
2638  * this signal will also be emitted.
2639  *
2640  * Helper can send some events back to the IMEngineInstance in this
2641  * signal-slot, to inform that it has been started sccessfully.
2642  *
2643  * The prototype of the slot is:
2644  *
2645  * void attach_input_context (const HelperAgent *agent, int ic, const String &ic_uuid);
2646  */
2647 Connection
2648 HelperAgent::signal_connect_attach_input_context (HelperAgentSlotVoid *slot)
2649 {
2650     return m_impl->signal_attach_input_context.connect (slot);
2651 }
2652
2653 /**
2654  * @brief Connect a slot to Helper detach input context signal.
2655  *
2656  * This signal is used to detach an input context from this helper.
2657  *
2658  * When an input context requst to stop this helper, then this
2659  * signal will be emitted.
2660  *
2661  * Helper shouldn't send any event back to the IMEngineInstance, because
2662  * the IMEngineInstance attached to the ic should have been destroyed.
2663  *
2664  * The prototype of the slot is:
2665  *
2666  * void detach_input_context (const HelperAgent *agent, int ic, const String &ic_uuid);
2667  */
2668 Connection
2669 HelperAgent::signal_connect_detach_input_context (HelperAgentSlotVoid *slot)
2670 {
2671     return m_impl->signal_detach_input_context.connect (slot);
2672 }
2673
2674 /**
2675  * @brief Connect a slot to Helper reload config signal.
2676  *
2677  * This signal is used to let the Helper reload configuration.
2678  *
2679  * The prototype of the slot is:
2680  *
2681  * void reload_config (const HelperAgent *agent, int ic, const String &ic_uuid);
2682  */
2683 Connection
2684 HelperAgent::signal_connect_reload_config (HelperAgentSlotVoid *slot)
2685 {
2686     return m_impl->signal_reload_config.connect (slot);
2687 }
2688
2689 /**
2690  * @brief Connect a slot to Helper update screen signal.
2691  *
2692  * This signal is used to let the Helper move its GUI to another screen.
2693  * It can only be emitted when SCIM_HELPER_NEED_SCREEN_INFO is set in HelperInfo.option.
2694  *
2695  * The prototype of the slot is:
2696  *
2697  * void update_screen (const HelperAgent *agent, int ic, const String &ic_uuid, int screen_number);
2698  */
2699 Connection
2700 HelperAgent::signal_connect_update_screen (HelperAgentSlotInt *slot)
2701 {
2702     return m_impl->signal_update_screen.connect (slot);
2703 }
2704
2705 /**
2706  * @brief Connect a slot to Helper update spot location signal.
2707  *
2708  * This signal is used to let the Helper move its GUI according to the current spot location.
2709  * It can only be emitted when SCIM_HELPER_NEED_SPOT_LOCATION_INFO is set in HelperInfo.option.
2710  *
2711  * The prototype of the slot is:
2712  * void update_spot_location (const HelperAgent *agent, int ic, const String &ic_uuid, int x, int y);
2713  */
2714 Connection
2715 HelperAgent::signal_connect_update_spot_location (HelperAgentSlotIntInt *slot)
2716 {
2717     return m_impl->signal_update_spot_location.connect (slot);
2718 }
2719
2720 /**
2721  * @brief Connect a slot to Helper update cursor position signal.
2722  *
2723  * This signal is used to let the Helper get the cursor position information.
2724  *
2725  * The prototype of the slot is:
2726  * void update_cursor_position (const HelperAgent *agent, int ic, const String &ic_uuid, int cursor_pos);
2727  */
2728 Connection
2729 HelperAgent::signal_connect_update_cursor_position (HelperAgentSlotInt *slot)
2730 {
2731     return m_impl->signal_update_cursor_position.connect (slot);
2732 }
2733
2734 /**
2735  * @brief Connect a slot to Helper update surrounding text signal.
2736  *
2737  * This signal is used to let the Helper get the surrounding text.
2738  *
2739  * The prototype of the slot is:
2740  * void update_surrounding_text (const HelperAgent *agent, int ic, const String &text, int cursor);
2741  */
2742 Connection
2743 HelperAgent::signal_connect_update_surrounding_text (HelperAgentSlotInt *slot)
2744 {
2745     return m_impl->signal_update_surrounding_text.connect (slot);
2746 }
2747
2748 /**
2749  * @brief Connect a slot to Helper update selection signal.
2750  *
2751  * This signal is used to let the Helper get the selection.
2752  *
2753  * The prototype of the slot is:
2754  * void update_selection (const HelperAgent *agent, int ic, const String &text);
2755  */
2756 Connection
2757 HelperAgent::signal_connect_update_selection (HelperAgentSlotVoid *slot)
2758 {
2759     return m_impl->signal_update_selection.connect (slot);
2760 }
2761
2762 /**
2763  * @brief Connect a slot to Helper trigger property signal.
2764  *
2765  * This signal is used to trigger a property registered by this Helper.
2766  * A property will be triggered when user clicks on it.
2767  *
2768  * The prototype of the slot is:
2769  * void trigger_property (const HelperAgent *agent, int ic, const String &ic_uuid, const String &property);
2770  */
2771 Connection
2772 HelperAgent::signal_connect_trigger_property (HelperAgentSlotString *slot)
2773 {
2774     return m_impl->signal_trigger_property.connect (slot);
2775 }
2776
2777 /**
2778  * @brief Connect a slot to Helper process imengine event signal.
2779  *
2780  * This signal is used to deliver the events sent from IMEngine to Helper.
2781  *
2782  * The prototype of the slot is:
2783  * void process_imengine_event (const HelperAgent *agent, int ic, const String &ic_uuid, const Transaction &transaction);
2784  */
2785 Connection
2786 HelperAgent::signal_connect_process_imengine_event (HelperAgentSlotTransaction *slot)
2787 {
2788     return m_impl->signal_process_imengine_event.connect (slot);
2789 }
2790
2791 /**
2792  * @brief Connect a slot to Helper focus out signal.
2793  *
2794  * This signal is used to do something when input context is focus out.
2795  *
2796  * The prototype of the slot is:
2797  * void focus_out (const HelperAgent *agent, int ic, const String &ic_uuid);
2798  */
2799 Connection
2800 HelperAgent::signal_connect_focus_out (HelperAgentSlotVoid *slot)
2801 {
2802     return m_impl->signal_focus_out.connect (slot);
2803 }
2804
2805 /**
2806  * @brief Connect a slot to Helper focus in signal.
2807  *
2808  * This signal is used to do something when input context is focus in.
2809  *
2810  * The prototype of the slot is:
2811  * void focus_in (const HelperAgent *agent, int ic, const String &ic_uuid);
2812  */
2813 Connection
2814 HelperAgent::signal_connect_focus_in (HelperAgentSlotVoid *slot)
2815 {
2816     return m_impl->signal_focus_in.connect (slot);
2817 }
2818
2819 /**
2820  * @brief Connect a slot to Helper show signal.
2821  *
2822  * This signal is used to show Helper ISE window.
2823  *
2824  * The prototype of the slot is:
2825  * void ise_show (const HelperAgent *agent, int ic, char *buf, size_t &len);
2826  */
2827 Connection
2828 HelperAgent::signal_connect_ise_show (HelperAgentSlotIntRawVoid *slot)
2829 {
2830     return m_impl->signal_ise_show.connect (slot);
2831 }
2832
2833 /**
2834  * @brief Connect a slot to Helper hide signal.
2835  *
2836  * This signal is used to hide Helper ISE window.
2837  *
2838  * The prototype of the slot is:
2839  * void ise_hide (const HelperAgent *agent, int ic, const String &ic_uuid);
2840  */
2841 Connection
2842 HelperAgent::signal_connect_ise_hide (HelperAgentSlotVoid *slot)
2843 {
2844     return m_impl->signal_ise_hide.connect (slot);
2845 }
2846
2847 /**
2848  * @brief Connect a slot to Helper get ISE window geometry signal.
2849  *
2850  * This signal is used to get Helper ISE window size and position.
2851  *
2852  * The prototype of the slot is:
2853  * void get_geometry (const HelperAgent *agent, struct rectinfo &info);
2854  */
2855 Connection
2856 HelperAgent::signal_connect_get_geometry (HelperAgentSlotSize *slot)
2857 {
2858     return m_impl->signal_get_geometry.connect (slot);
2859 }
2860
2861 /**
2862  * @brief Connect a slot to Helper set mode signal.
2863  *
2864  * This signal is used to set Helper ISE mode.
2865  *
2866  * The prototype of the slot is:
2867  * void set_mode (const HelperAgent *agent, uint32 &mode);
2868  */
2869 Connection
2870 HelperAgent::signal_connect_set_mode (HelperAgentSlotUintVoid *slot)
2871 {
2872     return m_impl->signal_set_mode.connect (slot);
2873 }
2874
2875 /**
2876  * @brief Connect a slot to Helper set language signal.
2877  *
2878  * This signal is used to set Helper ISE language.
2879  *
2880  * The prototype of the slot is:
2881  * void set_language (const HelperAgent *agent, uint32 &language);
2882  */
2883 Connection
2884 HelperAgent::signal_connect_set_language (HelperAgentSlotUintVoid *slot)
2885 {
2886     return m_impl->signal_set_language.connect (slot);
2887 }
2888
2889 /**
2890  * @brief Connect a slot to Helper set im data signal.
2891  *
2892  * This signal is used to send im data to Helper ISE.
2893  *
2894  * The prototype of the slot is:
2895  * void set_imdata (const HelperAgent *agent, char *buf, size_t &len);
2896  */
2897 Connection
2898 HelperAgent::signal_connect_set_imdata (HelperAgentSlotRawVoid *slot)
2899 {
2900     return m_impl->signal_set_imdata.connect (slot);
2901 }
2902
2903 /**
2904  * @brief Connect a slot to Helper get im data signal.
2905  *
2906  * This signal is used to get im data from Helper ISE.
2907  *
2908  * The prototype of the slot is:
2909  * void get_imdata (const HelperAgent *, char **buf, size_t &len);
2910  */
2911 Connection
2912 HelperAgent::signal_connect_get_imdata (HelperAgentSlotGetRawVoid *slot)
2913 {
2914     return m_impl->signal_get_imdata.connect (slot);
2915 }
2916
2917 /**
2918  * @brief Connect a slot to Helper get language locale signal.
2919  *
2920  * This signal is used to get language locale from Helper ISE.
2921  *
2922  * The prototype of the slot is:
2923  * void get_language_locale (const HelperAgent *, int ic, char **locale);
2924  */
2925 Connection
2926 HelperAgent::signal_connect_get_language_locale (HelperAgentSlotIntGetStringVoid *slot)
2927 {
2928     return m_impl->signal_get_language_locale.connect (slot);
2929 }
2930
2931 /**
2932  * @brief Connect a slot to Helper set return key type signal.
2933  *
2934  * This signal is used to send return key type to Helper ISE.
2935  *
2936  * The prototype of the slot is:
2937  * void set_return_key_type (const HelperAgent *agent, uint32 &type);
2938  */
2939 Connection
2940 HelperAgent::signal_connect_set_return_key_type (HelperAgentSlotUintVoid *slot)
2941 {
2942     return m_impl->signal_set_return_key_type.connect (slot);
2943 }
2944
2945 /**
2946  * @brief Connect a slot to Helper get return key type signal.
2947  *
2948  * This signal is used to get return key type from Helper ISE.
2949  *
2950  * The prototype of the slot is:
2951  * void get_return_key_type (const HelperAgent *agent, uint32 &type);
2952  */
2953 Connection
2954 HelperAgent::signal_connect_get_return_key_type (HelperAgentSlotUintVoid *slot)
2955 {
2956     return m_impl->signal_get_return_key_type.connect (slot);
2957 }
2958
2959 /**
2960  * @brief Connect a slot to Helper set return key disable signal.
2961  *
2962  * This signal is used to send return key disable to Helper ISE.
2963  *
2964  * The prototype of the slot is:
2965  * void set_return_key_disable (const HelperAgent *agent, uint32 &disabled);
2966  */
2967 Connection
2968 HelperAgent::signal_connect_set_return_key_disable (HelperAgentSlotUintVoid *slot)
2969 {
2970     return m_impl->signal_set_return_key_disable.connect (slot);
2971 }
2972
2973 /**
2974  * @brief Connect a slot to Helper process key event signal.
2975  *
2976  * This signal is used to send keyboard key event to Helper ISE.
2977  *
2978  * The prototype of the slot is:
2979  * void process_key_event (const HelperAgent *agent, KeyEvent &key, uint32 &ret);
2980  */
2981 Connection
2982 HelperAgent::signal_connect_process_key_event (HelperAgentSlotKeyEventUint *slot)
2983 {
2984     return m_impl->signal_process_key_event.connect (slot);
2985 }
2986
2987 /**
2988  * @brief Connect a slot to Helper get return key disable signal.
2989  *
2990  * This signal is used to get return key disable from Helper ISE.
2991  *
2992  * The prototype of the slot is:
2993  * void get_return_key_disable (const HelperAgent *agent, uint32 &disabled);
2994  */
2995 Connection
2996 HelperAgent::signal_connect_get_return_key_disable (HelperAgentSlotUintVoid *slot)
2997 {
2998     return m_impl->signal_get_return_key_disable.connect (slot);
2999 }
3000
3001 /**
3002  * @brief Connect a slot to Helper set layout signal.
3003  *
3004  * This signal is used to set Helper ISE layout.
3005  *
3006  * The prototype of the slot is:
3007  * void set_layout (const HelperAgent *agent, uint32 &layout);
3008  */
3009 Connection
3010 HelperAgent::signal_connect_set_layout (HelperAgentSlotUintVoid *slot)
3011 {
3012     return m_impl->signal_set_layout.connect (slot);
3013 }
3014
3015 /**
3016  * @brief Connect a slot to Helper get layout signal.
3017  *
3018  * This signal is used to get Helper ISE layout.
3019  *
3020  * The prototype of the slot is:
3021  * void get_layout (const HelperAgent *agent, uint32 &layout);
3022  */
3023 Connection
3024 HelperAgent::signal_connect_get_layout (HelperAgentSlotUintVoid *slot)
3025 {
3026     return m_impl->signal_get_layout.connect (slot);
3027 }
3028
3029 /**
3030  * @brief Connect a slot to Helper set input mode signal.
3031  *
3032  * This signal is used to set Helper ISE input mode.
3033  *
3034  * The prototype of the slot is:
3035  * void set_input_mode (const HelperAgent *agent, uint32 &input_mode);
3036  */
3037 Connection
3038 HelperAgent::signal_connect_set_input_mode (HelperAgentSlotUintVoid *slot)
3039 {
3040     return m_impl->signal_set_input_mode.connect (slot);
3041 }
3042
3043 /**
3044  * @brief Connect a slot to Helper set input hint signal.
3045  *
3046  * This signal is used to set Helper ISE input hint.
3047  *
3048  * The prototype of the slot is:
3049  * void set_input_hint (const HelperAgent *agent, uint32 &input_hint);
3050  */
3051 Connection
3052 HelperAgent::signal_connect_set_input_hint (HelperAgentSlotUintVoid *slot)
3053 {
3054     return m_impl->signal_set_input_hint.connect (slot);
3055 }
3056
3057 /**
3058  * @brief Connect a slot to Helper set BiDi direction signal.
3059  *
3060  * This signal is used to set Helper ISE BiDi direction.
3061  *
3062  * The prototype of the slot is:
3063  * void update_bidi_direction (const HelperAgent *agent, uint32 &bidi_direction);
3064  */
3065 Connection
3066 HelperAgent::signal_connect_update_bidi_direction (HelperAgentSlotUintVoid *slot)
3067 {
3068     return m_impl->signal_update_bidi_direction.connect (slot);
3069 }
3070
3071 /**
3072  * @brief Connect a slot to Helper set shift mode signal.
3073  *
3074  * This signal is used to set Helper shift mode.
3075  *
3076  * The prototype of the slot is:
3077  * void set_caps_mode (const HelperAgent *agent, uint32 &mode);
3078  */
3079 Connection
3080 HelperAgent::signal_connect_set_caps_mode (HelperAgentSlotUintVoid *slot)
3081 {
3082     return m_impl->signal_set_caps_mode.connect (slot);
3083 }
3084
3085 /**
3086  * @brief Connect a slot to Helper reset input context signal.
3087  *
3088  * This signal is used to reset Helper ISE input context.
3089  *
3090  * The prototype of the slot is:
3091  * void reset_input_context (const HelperAgent *agent, int ic, const String &uuid);
3092  */
3093 Connection
3094 HelperAgent::signal_connect_reset_input_context (HelperAgentSlotVoid *slot)
3095 {
3096     return m_impl->signal_reset_input_context.connect (slot);
3097 }
3098
3099 /**
3100  * @brief Connect a slot to Helper update candidate window geometry signal.
3101  *
3102  * This signal is used to get candidate window size and position.
3103  *
3104  * The prototype of the slot is:
3105  * void update_candidate_geometry (const HelperAgent *agent, int ic, const String &uuid, const rectinfo &info);
3106  */
3107 Connection
3108 HelperAgent::signal_connect_update_candidate_geometry (HelperAgentSlotRect *slot)
3109 {
3110     return m_impl->signal_update_candidate_geometry.connect (slot);
3111 }
3112
3113 /**
3114  * @brief Connect a slot to Helper update keyboard ISE signal.
3115  *
3116  * This signal is used to get current keyboard ISE name and uuid.
3117  *
3118  * The prototype of the slot is:
3119  * void update_keyboard_ise (const HelperAgent *agent, int ic, const String &uuid,
3120  *                           const String &ise_name, const String &ise_uuid);
3121  */
3122 Connection
3123 HelperAgent::signal_connect_update_keyboard_ise (HelperAgentSlotString2 *slot)
3124 {
3125     return m_impl->signal_update_keyboard_ise.connect (slot);
3126 }
3127
3128 /**
3129  * @brief Connect a slot to Helper update keyboard ISE list signal.
3130  *
3131  * This signal is used to get uuid list of all keyboard ISEs.
3132  *
3133  * The prototype of the slot is:
3134  * void update_keyboard_ise_list (const HelperAgent *agent, int ic, const String &uuid,
3135  *                                const std::vector<String> &ise_list);
3136  */
3137 Connection
3138 HelperAgent::signal_connect_update_keyboard_ise_list (HelperAgentSlotStringVector *slot)
3139 {
3140     return m_impl->signal_update_keyboard_ise_list.connect (slot);
3141 }
3142
3143 /**
3144  * @brief Connect a slot to Helper candidate more window show signal.
3145  *
3146  * This signal is used to do someting when candidate more window is showed.
3147  *
3148  * The prototype of the slot is:
3149  * void candidate_more_window_show (const HelperAgent *agent, int ic, const String &uuid);
3150  */
3151 Connection
3152 HelperAgent::signal_connect_candidate_more_window_show (HelperAgentSlotVoid *slot)
3153 {
3154     return m_impl->signal_candidate_more_window_show.connect (slot);
3155 }
3156
3157 /**
3158  * @brief Connect a slot to Helper candidate more window hide signal.
3159  *
3160  * This signal is used to do someting when candidate more window is hidden.
3161  *
3162  * The prototype of the slot is:
3163  * void candidate_more_window_hide (const HelperAgent *agent, int ic, const String &uuid);
3164  */
3165 Connection
3166 HelperAgent::signal_connect_candidate_more_window_hide (HelperAgentSlotVoid *slot)
3167 {
3168     return m_impl->signal_candidate_more_window_hide.connect (slot);
3169 }
3170
3171 /**
3172  * @brief Connect a slot to Helper candidate show signal.
3173  *
3174  * This signal is used to do candidate show.
3175  *
3176  * The prototype of the slot is:
3177  * void candidate_show (const HelperAgent *agent, int ic, const String &uuid);
3178  */
3179 Connection
3180 HelperAgent::signal_connect_candidate_show (HelperAgentSlotVoid *slot)
3181 {
3182     return m_impl->signal_candidate_show.connect (slot);
3183 }
3184
3185 /**
3186  * @brief Connect a slot to Helper candidate hide signal.
3187  *
3188  * This signal is used to do candidate hide.
3189  *
3190  * The prototype of the slot is:
3191  * void candidate_hide (const HelperAgent *agent, int ic, const String &uuid);
3192  */
3193 Connection
3194 HelperAgent::signal_connect_candidate_hide (HelperAgentSlotVoid *slot)
3195 {
3196     return m_impl->signal_candidate_hide.connect (slot);
3197 }
3198
3199 /**
3200  * @brief Connect a slot to Helper update lookup table signal.
3201  *
3202  * This signal is used to do someting when update lookup table.
3203  *
3204  * The prototype of the slot is:
3205  * void update_lookup_table (const HelperAgent *agent, int ic, const String &uuid ,LookupTable &table);
3206  */
3207 Connection
3208 HelperAgent::signal_connect_update_lookup_table (HelperAgentSlotLookupTable *slot)
3209 {
3210     return m_impl->signal_update_lookup_table.connect (slot);
3211 }
3212
3213 /**
3214  * @brief Connect a slot to Helper select aux signal.
3215  *
3216  * This signal is used to do something when aux is selected.
3217  *
3218  * The prototype of the slot is:
3219  * void select_aux (const HelperAgent *agent, int ic, const String &uuid, int index);
3220  */
3221 Connection
3222 HelperAgent::signal_connect_select_aux (HelperAgentSlotInt *slot)
3223 {
3224     return m_impl->signal_select_aux.connect (slot);
3225 }
3226
3227 /**
3228  * @brief Connect a slot to Helper select candidate signal.
3229  *
3230  * This signal is used to do something when candidate is selected.
3231  *
3232  * The prototype of the slot is:
3233  * void select_candidate (const HelperAgent *agent, int ic, const String &uuid, int index);
3234  */
3235 Connection
3236 HelperAgent::signal_connect_select_candidate (HelperAgentSlotInt *slot)
3237 {
3238     return m_impl->signal_select_candidate.connect (slot);
3239 }
3240
3241 /**
3242  * @brief Connect a slot to Helper candidate table page up signal.
3243  *
3244  * This signal is used to do something when candidate table is paged up.
3245  *
3246  * The prototype of the slot is:
3247  * void candidate_table_page_up (const HelperAgent *agent, int ic, const String &uuid);
3248  */
3249 Connection
3250 HelperAgent::signal_connect_candidate_table_page_up (HelperAgentSlotVoid *slot)
3251 {
3252     return m_impl->signal_candidate_table_page_up.connect (slot);
3253 }
3254
3255 /**
3256  * @brief Connect a slot to Helper candidate table page down signal.
3257  *
3258  * This signal is used to do something when candidate table is paged down.
3259  *
3260  * The prototype of the slot is:
3261  * void candidate_table_page_down (const HelperAgent *agent, int ic, const String &uuid);
3262  */
3263 Connection
3264 HelperAgent::signal_connect_candidate_table_page_down (HelperAgentSlotVoid *slot)
3265 {
3266     return m_impl->signal_candidate_table_page_down.connect (slot);
3267 }
3268
3269 /**
3270  * @brief Connect a slot to Helper update candidate table page size signal.
3271  *
3272  * This signal is used to do something when candidate table page size is changed.
3273  *
3274  * The prototype of the slot is:
3275  * void update_candidate_table_page_size (const HelperAgent *, int ic, const String &uuid, int page_size);
3276  */
3277 Connection
3278 HelperAgent::signal_connect_update_candidate_table_page_size (HelperAgentSlotInt *slot)
3279 {
3280     return m_impl->signal_update_candidate_table_page_size.connect (slot);
3281 }
3282
3283 /**
3284  * @brief Connect a slot to Helper update candidate item layout signal.
3285  *
3286  * The prototype of the slot is:
3287  * void update_candidate_item_layout (const HelperAgent *, const std::vector<uint32> &row_items);
3288  */
3289 Connection
3290 HelperAgent::signal_connect_update_candidate_item_layout (HelperAgentSlotUintVector *slot)
3291 {
3292     return m_impl->signal_update_candidate_item_layout.connect (slot);
3293 }
3294
3295 /**
3296  * @brief Connect a slot to Helper select associate signal.
3297  *
3298  * This signal is used to do something when associate is selected.
3299  *
3300  * The prototype of the slot is:
3301  * void select_associate (const HelperAgent *agent, int ic, const String &uuid, int index);
3302  */
3303 Connection
3304 HelperAgent::signal_connect_select_associate (HelperAgentSlotInt *slot)
3305 {
3306     return m_impl->signal_select_associate.connect (slot);
3307 }
3308
3309 /**
3310  * @brief Connect a slot to Helper associate table page up signal.
3311  *
3312  * This signal is used to do something when associate table is paged up.
3313  *
3314  * The prototype of the slot is:
3315  * void associate_table_page_up (const HelperAgent *agent, int ic, const String &uuid);
3316  */
3317 Connection
3318 HelperAgent::signal_connect_associate_table_page_up (HelperAgentSlotVoid *slot)
3319 {
3320     return m_impl->signal_associate_table_page_up.connect (slot);
3321 }
3322
3323 /**
3324  * @brief Connect a slot to Helper associate table page down signal.
3325  *
3326  * This signal is used to do something when associate table is paged down.
3327  *
3328  * The prototype of the slot is:
3329  * void associate_table_page_down (const HelperAgent *agent, int ic, const String &uuid);
3330  */
3331 Connection
3332 HelperAgent::signal_connect_associate_table_page_down (HelperAgentSlotVoid *slot)
3333 {
3334     return m_impl->signal_associate_table_page_down.connect (slot);
3335 }
3336
3337 /**
3338  * @brief Connect a slot to Helper update associate table page size signal.
3339  *
3340  * This signal is used to do something when associate table page size is changed.
3341  *
3342  * The prototype of the slot is:
3343  * void update_associate_table_page_size (const HelperAgent *, int ic, const String &uuid, int page_size);
3344  */
3345 Connection
3346 HelperAgent::signal_connect_update_associate_table_page_size (HelperAgentSlotInt *slot)
3347 {
3348     return m_impl->signal_update_associate_table_page_size.connect (slot);
3349 }
3350
3351 /**
3352  * @brief Connect a slot to Helper turn on log signal.
3353  *
3354  * This signal is used to turn on Helper ISE debug information.
3355  *
3356  * The prototype of the slot is:
3357  * void turn_on_log (const HelperAgent *agent, uint32 &on);
3358  */
3359 Connection
3360 HelperAgent::signal_connect_turn_on_log (HelperAgentSlotUintVoid *slot)
3361 {
3362     return m_impl->signal_turn_on_log.connect (slot);
3363 }
3364
3365 /**
3366  * @brief Connect a slot to Helper update displayed candidate number signal.
3367  *
3368  * This signal is used to inform helper ISE displayed candidate number.
3369  *
3370  * The prototype of the slot is:
3371  * void update_displayed_candidate_number (const HelperAgent *, int ic, const String &uuid, int number);
3372  */
3373 Connection
3374 HelperAgent::signal_connect_update_displayed_candidate_number (HelperAgentSlotInt *slot)
3375 {
3376     return m_impl->signal_update_displayed_candidate_number.connect (slot);
3377 }
3378
3379 /**
3380  * @brief Connect a slot to Helper longpress candidate signal.
3381  *
3382  * This signal is used to do something when candidate is longpress.
3383  *
3384  * The prototype of the slot is:
3385  * void longpress_candidate (const HelperAgent *agent, int ic, const String &uuid, int index);
3386  */
3387 Connection
3388 HelperAgent::signal_connect_longpress_candidate (HelperAgentSlotInt *slot)
3389 {
3390     return m_impl->signal_longpress_candidate.connect (slot);
3391 }
3392
3393 /**
3394  * @brief Connect a slot to Helper show option window.
3395  *
3396  * This signal is used to do request the ISE to show option window.
3397  *
3398  * The prototype of the slot is:
3399  * void show_option_window (const HelperAgent *agent, int ic, const String &uuid);
3400  */
3401 Connection
3402 HelperAgent::signal_connect_show_option_window (HelperAgentSlotVoid *slot)
3403 {
3404     return m_impl->signal_show_option_window.connect (slot);
3405 }
3406
3407 /**
3408  * @brief Connect a slot to Helper resume option window.
3409  *
3410  * This signal is used to do request the ISE to resume option window.
3411  *
3412  * The prototype of the slot is:
3413  * void resume_option_window (const HelperAgent *agent, int ic, const String &uuid);
3414  */
3415 Connection
3416 HelperAgent::signal_connect_resume_option_window (HelperAgentSlotVoid *slot)
3417 {
3418     return m_impl->signal_resume_option_window.connect (slot);
3419 }
3420
3421 /**
3422  * @brief Connect a slot to Helper check if the option is available.
3423  *
3424  * This signal is used to check if the option (setting) is available from Helper ISE.
3425  *
3426  * The prototype of the slot is:
3427  * void check_option_window (const HelperAgent *agent, uint32 &avail);
3428  */
3429 Connection
3430 HelperAgent::signal_connect_check_option_window (HelperAgentSlotUintVoid *slot)
3431 {
3432     return m_impl->signal_check_option_window.connect (slot);
3433 }
3434
3435 /**
3436  * @brief Connect a slot to Helper process unconventional input device event signal.
3437  *
3438  * This signal is used to send unconventional input device event to Helper ISE.
3439  *
3440  * The prototype of the slot is:
3441  * void process_input_device_event (const HelperAgent *, uint32 &type, char *data, size_t &size, uint32 &ret);
3442  */
3443 Connection
3444 HelperAgent::signal_connect_process_input_device_event (HelperAgentSlotUintCharSizeUint *slot)
3445 {
3446     return m_impl->signal_process_input_device_event.connect (slot);
3447 }
3448
3449 } /* namespace scim */
3450
3451 /*
3452 vi:ts=4:nowrap:ai:expandtab
3453 */
3454