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