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