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