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