9c26674039b173ef992b5300c7ac3d5cfacf1df6
[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 (pos < 0) pos = 0;
2061             int len = maxlen_after + (cursor - pos);
2062             if (len < 0) len = INT_MAX;
2063             text = buffer.substr (pos, len);
2064         } else {
2065             text.clear ();
2066             cursor = 0;
2067         }
2068     } else {
2069         m_impl->send.clear();
2070         m_impl->send.put_command(SCIM_TRANS_CMD_REQUEST);
2071         m_impl->send.put_data(m_impl->magic_active);
2072         m_impl->send.put_command(SCIM_TRANS_CMD_GET_SURROUNDING_TEXT);
2073         m_impl->send.put_data("");
2074         m_impl->send.put_data(maxlen_before);
2075         m_impl->send.put_data(maxlen_after);
2076         m_impl->send.write_to_socket(m_impl->socket_active, m_impl->magic_active);
2077         if (m_impl->surrounding_text) {
2078             free(m_impl->surrounding_text);
2079             m_impl->surrounding_text = NULL;
2080         }
2081
2082         const int WAIT_FOR_SYNC_RESPONSE_TIMEOUT = 1000;
2083         /* Now we are waiting for the ISM_TRANS_CMD_UPDATE_SURROUNDING_TEXT message */
2084         if (wait_for_message(ISM_TRANS_CMD_UPDATE_SURROUNDING_TEXT, WAIT_FOR_SYNC_RESPONSE_TIMEOUT)) {
2085             MessageItem *message = message_queue.get_pending_message_by_cmd(ISM_TRANS_CMD_UPDATE_SURROUNDING_TEXT);
2086             handle_message(message);
2087             message_queue.remove_message(message);
2088
2089             if (m_impl->surrounding_text) {
2090                 text = m_impl->surrounding_text;
2091                 cursor = m_impl->cursor_pos;
2092             }
2093         }
2094
2095         if (m_impl->surrounding_text) {
2096             free(m_impl->surrounding_text);
2097             m_impl->surrounding_text = NULL;
2098         }
2099     }
2100 }
2101
2102 /**
2103  * @brief Request to delete surrounding text.
2104  *
2105  * @param offset The offset for cursor position.
2106  * @param len The length for delete text.
2107  */
2108 void
2109 HelperAgent::delete_surrounding_text (int offset, int len) const
2110 {
2111     LOGD ("offset = %d, len = %d", offset, len);
2112
2113     if (m_impl->socket_active.is_connected ()) {
2114         m_impl->send.clear ();
2115         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2116         m_impl->send.put_data (m_impl->magic_active);
2117         m_impl->send.put_command (SCIM_TRANS_CMD_DELETE_SURROUNDING_TEXT);
2118         m_impl->send.put_data (offset);
2119         m_impl->send.put_data (len);
2120         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2121     }
2122 }
2123
2124 /**
2125  * @brief Request to get selection text asynchronously.
2126  *
2127  * @param uuid The helper ISE UUID.
2128  */
2129 void
2130 HelperAgent::get_selection (const String &uuid) const
2131 {
2132     if (m_impl->socket_active.is_connected () && (m_impl->need_update_selection_text == 0)) {
2133         m_impl->send.clear ();
2134         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2135         m_impl->send.put_data (m_impl->magic_active);
2136         m_impl->send.put_command (SCIM_TRANS_CMD_GET_SELECTION);
2137         m_impl->send.put_data (uuid);
2138         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2139     }
2140     m_impl->need_update_selection_text++;
2141 }
2142
2143 /**
2144  * @brief Request to get selection text synchronously.
2145  *
2146  * @param text The selection text.
2147  */
2148 void
2149 HelperAgent::get_selection_text (String &text)
2150 {
2151
2152     if (!m_impl->socket_active.is_connected ())
2153         return;
2154
2155     m_impl->send.clear ();
2156     m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2157     m_impl->send.put_data (m_impl->magic_active);
2158     m_impl->send.put_command (SCIM_TRANS_CMD_GET_SELECTION);
2159     m_impl->send.put_data ("");
2160     m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2161     if (m_impl->selection_text) {
2162         free (m_impl->selection_text);
2163         m_impl->selection_text = NULL;
2164     }
2165
2166     const int WAIT_FOR_SYNC_RESPONSE_TIMEOUT = 1000;
2167     /* Now we are waiting for the ISM_TRANS_CMD_UPDATE_SELECTION message */
2168     if (wait_for_message(ISM_TRANS_CMD_UPDATE_SELECTION, WAIT_FOR_SYNC_RESPONSE_TIMEOUT)) {
2169         MessageItem *message = message_queue.get_pending_message_by_cmd(ISM_TRANS_CMD_UPDATE_SELECTION);
2170         handle_message(message);
2171         message_queue.remove_message(message);
2172         if (m_impl->selection_text) {
2173             text = m_impl->selection_text;
2174         }
2175     }
2176
2177     if (m_impl->selection_text) {
2178         free (m_impl->selection_text);
2179         m_impl->selection_text = NULL;
2180     }
2181 }
2182
2183 /**
2184  * @brief Request to select text.
2185  *
2186  * @param start The start position in text.
2187  * @param end The end position in text.
2188  */
2189 void
2190 HelperAgent::set_selection (int start, int end) const
2191 {
2192     if (m_impl->socket_active.is_connected ()) {
2193         m_impl->send.clear ();
2194         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2195         m_impl->send.put_data (m_impl->magic_active);
2196         m_impl->send.put_command (SCIM_TRANS_CMD_SET_SELECTION);
2197         m_impl->send.put_data (start);
2198         m_impl->send.put_data (end);
2199         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2200     }
2201 }
2202
2203 /**
2204  * @brief Send a private command to an application.
2205  *
2206  * @param command The private command sent from IME.
2207  */
2208 void
2209 HelperAgent::send_private_command (const String &command) const
2210 {
2211     if (m_impl->socket_active.is_connected ()) {
2212         m_impl->send.clear ();
2213         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2214         m_impl->send.put_data (m_impl->magic_active);
2215         m_impl->send.put_command (SCIM_TRANS_CMD_SEND_PRIVATE_COMMAND);
2216         m_impl->send.put_data (command);
2217         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2218     }
2219 }
2220
2221 /**
2222  * @brief Commit content to an application.
2223  *
2224  * @param content The content sent from IME.
2225  */
2226 void
2227 HelperAgent::commit_content (const String &content, const String &description, const String &mime_types) const
2228 {
2229     LOGD ("");
2230     if (m_impl->socket_active.is_connected ()) {
2231         m_impl->send.clear ();
2232         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2233         m_impl->send.put_data (m_impl->magic_active);
2234         m_impl->send.put_command (SCIM_TRANS_CMD_COMMIT_CONTENT);
2235         m_impl->send.put_data (content);
2236         m_impl->send.put_data (description);
2237         m_impl->send.put_data (mime_types);
2238         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2239     }
2240 }
2241
2242 /**
2243  * @brief Request to get uuid list of all keyboard ISEs.
2244  *
2245  * @param uuid The helper ISE UUID.
2246  */
2247 void
2248 HelperAgent::get_keyboard_ise_list (const String &uuid) const
2249 {
2250     if (m_impl->socket_active.is_connected ()) {
2251         m_impl->send.clear ();
2252         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2253         m_impl->send.put_data (m_impl->magic_active);
2254         m_impl->send.put_command (ISM_TRANS_CMD_GET_KEYBOARD_ISE_LIST);
2255         m_impl->send.put_data (uuid);
2256         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2257     }
2258 }
2259
2260 /**
2261  * @brief Set candidate position in screen.
2262  *
2263  * @param left The x position in screen.
2264  * @param top The y position in screen.
2265  */
2266 void
2267 HelperAgent::set_candidate_position (int left, int top) const
2268 {
2269     if (m_impl->socket_active.is_connected ()) {
2270         m_impl->send.clear ();
2271         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2272         m_impl->send.put_data (m_impl->magic_active);
2273         m_impl->send.put_command (ISM_TRANS_CMD_SET_CANDIDATE_POSITION);
2274         m_impl->send.put_data (left);
2275         m_impl->send.put_data (top);
2276         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2277     }
2278 }
2279
2280 /**
2281  * @brief Set candidate style.
2282  *
2283  * @param portrait_line - the displayed line number for portrait mode.
2284  * @param mode          - candidate window mode.
2285  */
2286 void
2287 HelperAgent::set_candidate_style (ISF_CANDIDATE_PORTRAIT_LINE_T portrait_line,
2288                                   ISF_CANDIDATE_MODE_T          mode) const
2289 {
2290     if (m_impl->socket_active.is_connected ()) {
2291         m_impl->send.clear ();
2292         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2293         m_impl->send.put_data (m_impl->magic_active);
2294         m_impl->send.put_command (ISM_TRANS_CMD_SET_CANDIDATE_UI);
2295         m_impl->send.put_data (portrait_line);
2296         m_impl->send.put_data (mode);
2297         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2298     }
2299 }
2300
2301 /**
2302  * @brief Request to hide candidate window.
2303  */
2304 void
2305 HelperAgent::candidate_hide (void) const
2306 {
2307     if (m_impl->socket_active.is_connected ()) {
2308         m_impl->send.clear ();
2309         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2310         m_impl->send.put_data (m_impl->magic_active);
2311         m_impl->send.put_command (ISM_TRANS_CMD_HIDE_CANDIDATE);
2312         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2313     }
2314 }
2315
2316 /**
2317  * @brief Request to get candidate window size and position.
2318  *
2319  * @param uuid The helper ISE UUID.
2320  */
2321 void
2322 HelperAgent::get_candidate_window_geometry (const String &uuid) const
2323 {
2324     if (m_impl->socket_active.is_connected ()) {
2325         m_impl->send.clear ();
2326         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2327         m_impl->send.put_data (m_impl->magic_active);
2328         m_impl->send.put_command (ISM_TRANS_CMD_GET_CANDIDATE_GEOMETRY);
2329         m_impl->send.put_data (uuid);
2330         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2331     }
2332 }
2333
2334 /**
2335  * @brief Set current keyboard ISE.
2336  *
2337  * @param uuid The keyboard ISE UUID.
2338  */
2339 void
2340 HelperAgent::set_keyboard_ise_by_uuid (const String &uuid) const
2341 {
2342     ImeInfoDB imeInfo;
2343     IMEngineFactoryPointer factory;
2344     IMEngineModule *engine_module = NULL;
2345     static int instance_count = 1;
2346
2347     if ((!m_impl->si.null ()) && m_impl->si->get_factory_uuid () == uuid) {
2348         ISF_SAVE_LOG ("Already in UUID: %s", uuid.c_str());
2349         return;
2350     }
2351
2352     if (!m_impl->si.null()) {
2353         m_impl->si->focus_out();
2354         m_impl->si.reset();
2355     }
2356
2357     if (m_impl->m_config.null ()) {
2358         ISF_SAVE_LOG ("config is not working");
2359         return;
2360     }
2361
2362 #ifdef HAVE_PKGMGR_INFO
2363     int ret = 0;
2364     char *pkgid = NULL;
2365     pkgmgrinfo_appinfo_h handle;
2366     ret = pkgmgrinfo_appinfo_get_appinfo(uuid.c_str(), &handle);
2367     if (ret != PMINFO_R_OK) {
2368         ISF_SAVE_LOG ("Retrieve app info failed : %s", uuid.c_str ());
2369         return;
2370     }
2371
2372     ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
2373     if (ret != PMINFO_R_OK) {
2374         ISF_SAVE_LOG ("Retrieve pkgid failed : %s, %p", uuid.c_str(), handle);
2375         pkgmgrinfo_appinfo_destroy_appinfo(handle);
2376         return;
2377     }
2378
2379     imeInfo.module_name = pkgid;
2380     pkgmgrinfo_appinfo_destroy_appinfo(handle);
2381 #else
2382     if (isf_db_select_ime_info_by_appid(uuid.c_str(), &imeInfo) < 1) {
2383         ISF_SAVE_LOG ("ime_info row is not available for %s", uuid.c_str());
2384         return;
2385     }
2386 #endif
2387
2388     engine_module = &m_impl->engine_module;
2389
2390     if (engine_module->valid() && imeInfo.module_name != engine_module->get_module_name()) {
2391         ISF_SAVE_LOG ("imengine module %s unloaded", engine_module->get_module_name().c_str());
2392         engine_module->unload();
2393     }
2394
2395     if (!engine_module->valid()) {
2396         if (engine_module->load (imeInfo.module_name, m_impl->m_config) == false) {
2397             ISF_SAVE_LOG ("load module %s failed", imeInfo.module_name.c_str());
2398             return;
2399         }
2400         ISF_SAVE_LOG ("imengine module %s loaded", imeInfo.module_name.c_str());
2401     }
2402
2403     for (size_t j = 0; j < engine_module->number_of_factories (); ++j) {
2404         try {
2405             factory = engine_module->create_factory (j);
2406             if (factory.null () == false && factory->get_uuid () == uuid)
2407                 break;
2408         } catch (...) {
2409             factory.reset ();
2410             return;
2411         }
2412     }
2413
2414     if (factory.null()) {
2415         ISF_SAVE_LOG ("imengine uuid %s is not found", uuid.c_str());
2416         return;
2417     }
2418
2419     m_impl->si = factory->create_instance ("UTF-8", instance_count++);
2420     if (m_impl->si.null ()) {
2421         ISF_SAVE_LOG ("create_instance %s failed", uuid.c_str ());
2422         return;
2423     }
2424
2425     m_impl->attach_instance ();
2426     ISF_SAVE_LOG ("Require UUID: %s Current UUID: %s", uuid.c_str (), m_impl->si->get_factory_uuid ().c_str ());
2427     m_impl->si->set_layout (m_impl->layout);
2428     if (m_impl->focused_ic != (uint32)-1)
2429         m_impl->si->focus_in ();
2430 }
2431
2432 /**
2433  * @brief Request to get current keyboard ISE information.
2434  *
2435  * @param uuid The helper ISE UUID.
2436  */
2437 void
2438 HelperAgent::get_keyboard_ise (const String &uuid) const
2439 {
2440     //FIXME: maybe useless
2441 #if 0
2442     if (m_impl->socket_active.is_connected ()) {
2443         m_impl->send.clear ();
2444         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2445         m_impl->send.put_data (m_impl->magic_active);
2446         m_impl->send.put_command (ISM_TRANS_CMD_GET_KEYBOARD_ISE);
2447         m_impl->send.put_data (uuid);
2448         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2449     }
2450 #endif
2451 }
2452
2453 /**
2454  * @brief Update ISE window geometry.
2455  *
2456  * @param x      The x position in screen.
2457  * @param y      The y position in screen.
2458  * @param width  The ISE window width.
2459  * @param height The ISE window height.
2460  */
2461 void
2462 HelperAgent::update_geometry (int x, int y, int width, int height) const
2463 {
2464     if (m_impl->socket_active.is_connected ()) {
2465         m_impl->send.clear ();
2466         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2467         m_impl->send.put_data (m_impl->magic_active);
2468         m_impl->send.put_command (ISM_TRANS_CMD_UPDATE_ISE_GEOMETRY);
2469         m_impl->send.put_data (x);
2470         m_impl->send.put_data (y);
2471         m_impl->send.put_data (width);
2472         m_impl->send.put_data (height);
2473         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2474     }
2475 }
2476
2477 /**
2478  * @brief Request to expand candidate window.
2479  */
2480 void
2481 HelperAgent::expand_candidate (void) const
2482 {
2483     if (m_impl->socket_active.is_connected ()) {
2484         m_impl->send.clear ();
2485         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2486         m_impl->send.put_data (m_impl->magic_active);
2487         m_impl->send.put_command (ISM_TRANS_CMD_EXPAND_CANDIDATE);
2488         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2489     }
2490 }
2491
2492 /**
2493  * @brief Request to contract candidate window.
2494  */
2495 void
2496 HelperAgent::contract_candidate (void) const
2497 {
2498     if (m_impl->socket_active.is_connected ()) {
2499         m_impl->send.clear ();
2500         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2501         m_impl->send.put_data (m_impl->magic_active);
2502         m_impl->send.put_command (ISM_TRANS_CMD_CONTRACT_CANDIDATE);
2503         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2504     }
2505 }
2506
2507 /**
2508  * @brief Send selected candidate string index number.
2509  */
2510 void
2511 HelperAgent::select_candidate (int index) const
2512 {
2513     if (!m_impl->si.null ())
2514         m_impl->si->select_candidate (index);
2515     //FIXME: maybe useless
2516 #if 0
2517
2518     if (m_impl->socket_active.is_connected ()) {
2519         m_impl->send.clear ();
2520         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2521         m_impl->send.put_data (m_impl->magic_active);
2522         m_impl->send.put_command (ISM_TRANS_CMD_SELECT_CANDIDATE);
2523         m_impl->send.put_data (index);
2524         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2525     }
2526 #endif
2527 }
2528
2529 /**
2530  * @brief Update our ISE is exiting.
2531  */
2532 void
2533 HelperAgent::update_ise_exit (void) const
2534 {
2535     //FIXME: maybe useless
2536 #if 0
2537     if (m_impl->socket_active.is_connected ()) {
2538         m_impl->send.clear ();
2539         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2540         m_impl->send.put_data (m_impl->magic_active);
2541         m_impl->send.put_command (ISM_TRANS_CMD_UPDATE_ISE_EXIT);
2542         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2543     }
2544 #endif
2545 }
2546
2547 /**
2548  * @brief Request to reset keyboard ISE.
2549  */
2550 void
2551 HelperAgent::reset_keyboard_ise (void) const
2552 {
2553 //FIXME: maybe useless
2554 #if 0
2555     if (m_impl->socket_active.is_connected ()) {
2556         m_impl->send.clear ();
2557         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2558         m_impl->send.put_data (m_impl->magic_active);
2559         m_impl->send.put_command (ISM_TRANS_CMD_PANEL_RESET_KEYBOARD_ISE);
2560         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2561     }
2562 #endif
2563     if (!m_impl->si.null ()) {
2564         m_impl->si->reset ();
2565     }
2566 }
2567
2568 /**
2569  * @brief Request to flush keyboard ISE.
2570  */
2571 void
2572 HelperAgent::flush_keyboard_ise (void) const
2573 {
2574     if (!m_impl->si.null ()) {
2575         m_impl->si->flush ();
2576     }
2577 }
2578
2579 /**
2580  * @brief Request panel to hide ISE.
2581  */
2582 void
2583 HelperAgent::request_ise_hide (void) const
2584 {
2585     if (m_impl->socket_active.is_connected ()) {
2586         m_impl->send.clear ();
2587         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2588         m_impl->send.put_data (m_impl->magic_active);
2589         m_impl->send.put_command (ISM_TRANS_CMD_REQUEST_ISE_HIDE);
2590         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2591     }
2592 }
2593
2594 /**
2595  * @brief Recapture
2596  */
2597 void
2598 HelperAgent::recapture_string (int                  ic,
2599                                const String        &ic_uuid,
2600                                int                  offset,
2601                                int                  len,
2602                                const WideString    &preedit_str,
2603                                const WideString    &commit_str,
2604                                const AttributeList &attrs) const
2605 {
2606     LOGD ("offset = %d, len = %d", offset, len);
2607
2608     if (m_impl->socket_active.is_connected ()) {
2609         m_impl->send.clear ();
2610         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2611         m_impl->send.put_data (m_impl->magic_active);
2612         m_impl->send.put_command (ISM_TRANS_CMD_RECAPTURE_STRING);
2613
2614         m_impl->send.put_data ((uint32)ic);
2615         m_impl->send.put_data (ic_uuid);
2616
2617         // Deleting surrounding text
2618         m_impl->send.put_data (offset);
2619         m_impl->send.put_data (len);
2620
2621         // Update preedit text
2622         m_impl->send.put_data (preedit_str);
2623
2624         // Commit
2625         m_impl->send.put_data (commit_str);
2626
2627         // preedit attributes
2628         m_impl->send.put_data (attrs);
2629
2630         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2631     }
2632 }
2633
2634 /**
2635  * @brief Connect a slot to Helper exit signal.
2636  *
2637  * This signal is used to let the Helper exit.
2638  *
2639  * The prototype of the slot is:
2640  *
2641  * void exit (const HelperAgent *agent, int ic, const String &ic_uuid);
2642  *
2643  * Parameters:
2644  * - agent    The pointer to the HelperAgent object which emits this signal.
2645  * - ic       An opaque handle of the currently focused input context.
2646  * - ic_uuid  The UUID of the IMEngineInstance associated with the focused input context.
2647  */
2648 Connection
2649 HelperAgent::signal_connect_exit (HelperAgentSlotVoid *slot)
2650 {
2651     return m_impl->signal_exit.connect (slot);
2652 }
2653
2654 /**
2655  * @brief Connect a slot to Helper attach input context signal.
2656  *
2657  * This signal is used to attach an input context to this helper.
2658  *
2659  * When an input context requst to start this helper, then this
2660  * signal will be emitted as soon as the helper is started.
2661  *
2662  * When an input context want to start an already started helper,
2663  * this signal will also be emitted.
2664  *
2665  * Helper can send some events back to the IMEngineInstance in this
2666  * signal-slot, to inform that it has been started sccessfully.
2667  *
2668  * The prototype of the slot is:
2669  *
2670  * void attach_input_context (const HelperAgent *agent, int ic, const String &ic_uuid);
2671  */
2672 Connection
2673 HelperAgent::signal_connect_attach_input_context (HelperAgentSlotVoid *slot)
2674 {
2675     return m_impl->signal_attach_input_context.connect (slot);
2676 }
2677
2678 /**
2679  * @brief Connect a slot to Helper detach input context signal.
2680  *
2681  * This signal is used to detach an input context from this helper.
2682  *
2683  * When an input context requst to stop this helper, then this
2684  * signal will be emitted.
2685  *
2686  * Helper shouldn't send any event back to the IMEngineInstance, because
2687  * the IMEngineInstance attached to the ic should have been destroyed.
2688  *
2689  * The prototype of the slot is:
2690  *
2691  * void detach_input_context (const HelperAgent *agent, int ic, const String &ic_uuid);
2692  */
2693 Connection
2694 HelperAgent::signal_connect_detach_input_context (HelperAgentSlotVoid *slot)
2695 {
2696     return m_impl->signal_detach_input_context.connect (slot);
2697 }
2698
2699 /**
2700  * @brief Connect a slot to Helper reload config signal.
2701  *
2702  * This signal is used to let the Helper reload configuration.
2703  *
2704  * The prototype of the slot is:
2705  *
2706  * void reload_config (const HelperAgent *agent, int ic, const String &ic_uuid);
2707  */
2708 Connection
2709 HelperAgent::signal_connect_reload_config (HelperAgentSlotVoid *slot)
2710 {
2711     return m_impl->signal_reload_config.connect (slot);
2712 }
2713
2714 /**
2715  * @brief Connect a slot to Helper update screen signal.
2716  *
2717  * This signal is used to let the Helper move its GUI to another screen.
2718  * It can only be emitted when SCIM_HELPER_NEED_SCREEN_INFO is set in HelperInfo.option.
2719  *
2720  * The prototype of the slot is:
2721  *
2722  * void update_screen (const HelperAgent *agent, int ic, const String &ic_uuid, int screen_number);
2723  */
2724 Connection
2725 HelperAgent::signal_connect_update_screen (HelperAgentSlotInt *slot)
2726 {
2727     return m_impl->signal_update_screen.connect (slot);
2728 }
2729
2730 /**
2731  * @brief Connect a slot to Helper update spot location signal.
2732  *
2733  * This signal is used to let the Helper move its GUI according to the current spot location.
2734  * It can only be emitted when SCIM_HELPER_NEED_SPOT_LOCATION_INFO is set in HelperInfo.option.
2735  *
2736  * The prototype of the slot is:
2737  * void update_spot_location (const HelperAgent *agent, int ic, const String &ic_uuid, int x, int y);
2738  */
2739 Connection
2740 HelperAgent::signal_connect_update_spot_location (HelperAgentSlotIntInt *slot)
2741 {
2742     return m_impl->signal_update_spot_location.connect (slot);
2743 }
2744
2745 /**
2746  * @brief Connect a slot to Helper update cursor position signal.
2747  *
2748  * This signal is used to let the Helper get the cursor position information.
2749  *
2750  * The prototype of the slot is:
2751  * void update_cursor_position (const HelperAgent *agent, int ic, const String &ic_uuid, int cursor_pos);
2752  */
2753 Connection
2754 HelperAgent::signal_connect_update_cursor_position (HelperAgentSlotInt *slot)
2755 {
2756     return m_impl->signal_update_cursor_position.connect (slot);
2757 }
2758
2759 /**
2760  * @brief Connect a slot to Helper update surrounding text signal.
2761  *
2762  * This signal is used to let the Helper get the surrounding text.
2763  *
2764  * The prototype of the slot is:
2765  * void update_surrounding_text (const HelperAgent *agent, int ic, const String &text, int cursor);
2766  */
2767 Connection
2768 HelperAgent::signal_connect_update_surrounding_text (HelperAgentSlotInt *slot)
2769 {
2770     return m_impl->signal_update_surrounding_text.connect (slot);
2771 }
2772
2773 /**
2774  * @brief Connect a slot to Helper update selection signal.
2775  *
2776  * This signal is used to let the Helper get the selection.
2777  *
2778  * The prototype of the slot is:
2779  * void update_selection (const HelperAgent *agent, int ic, const String &text);
2780  */
2781 Connection
2782 HelperAgent::signal_connect_update_selection (HelperAgentSlotVoid *slot)
2783 {
2784     return m_impl->signal_update_selection.connect (slot);
2785 }
2786
2787 /**
2788  * @brief Connect a slot to Helper trigger property signal.
2789  *
2790  * This signal is used to trigger a property registered by this Helper.
2791  * A property will be triggered when user clicks on it.
2792  *
2793  * The prototype of the slot is:
2794  * void trigger_property (const HelperAgent *agent, int ic, const String &ic_uuid, const String &property);
2795  */
2796 Connection
2797 HelperAgent::signal_connect_trigger_property (HelperAgentSlotString *slot)
2798 {
2799     return m_impl->signal_trigger_property.connect (slot);
2800 }
2801
2802 /**
2803  * @brief Connect a slot to Helper process imengine event signal.
2804  *
2805  * This signal is used to deliver the events sent from IMEngine to Helper.
2806  *
2807  * The prototype of the slot is:
2808  * void process_imengine_event (const HelperAgent *agent, int ic, const String &ic_uuid, const Transaction &transaction);
2809  */
2810 Connection
2811 HelperAgent::signal_connect_process_imengine_event (HelperAgentSlotTransaction *slot)
2812 {
2813     return m_impl->signal_process_imengine_event.connect (slot);
2814 }
2815
2816 /**
2817  * @brief Connect a slot to Helper focus out signal.
2818  *
2819  * This signal is used to do something when input context is focus out.
2820  *
2821  * The prototype of the slot is:
2822  * void focus_out (const HelperAgent *agent, int ic, const String &ic_uuid);
2823  */
2824 Connection
2825 HelperAgent::signal_connect_focus_out (HelperAgentSlotVoid *slot)
2826 {
2827     return m_impl->signal_focus_out.connect (slot);
2828 }
2829
2830 /**
2831  * @brief Connect a slot to Helper focus in signal.
2832  *
2833  * This signal is used to do something when input context is focus in.
2834  *
2835  * The prototype of the slot is:
2836  * void focus_in (const HelperAgent *agent, int ic, const String &ic_uuid);
2837  */
2838 Connection
2839 HelperAgent::signal_connect_focus_in (HelperAgentSlotVoid *slot)
2840 {
2841     return m_impl->signal_focus_in.connect (slot);
2842 }
2843
2844 /**
2845  * @brief Connect a slot to Helper show signal.
2846  *
2847  * This signal is used to show Helper ISE window.
2848  *
2849  * The prototype of the slot is:
2850  * void ise_show (const HelperAgent *agent, int ic, char *buf, size_t &len);
2851  */
2852 Connection
2853 HelperAgent::signal_connect_ise_show (HelperAgentSlotIntRawVoid *slot)
2854 {
2855     return m_impl->signal_ise_show.connect (slot);
2856 }
2857
2858 /**
2859  * @brief Connect a slot to Helper hide signal.
2860  *
2861  * This signal is used to hide Helper ISE window.
2862  *
2863  * The prototype of the slot is:
2864  * void ise_hide (const HelperAgent *agent, int ic, const String &ic_uuid);
2865  */
2866 Connection
2867 HelperAgent::signal_connect_ise_hide (HelperAgentSlotVoid *slot)
2868 {
2869     return m_impl->signal_ise_hide.connect (slot);
2870 }
2871
2872 /**
2873  * @brief Connect a slot to Helper get ISE window geometry signal.
2874  *
2875  * This signal is used to get Helper ISE window size and position.
2876  *
2877  * The prototype of the slot is:
2878  * void get_geometry (const HelperAgent *agent, struct rectinfo &info);
2879  */
2880 Connection
2881 HelperAgent::signal_connect_get_geometry (HelperAgentSlotSize *slot)
2882 {
2883     return m_impl->signal_get_geometry.connect (slot);
2884 }
2885
2886 /**
2887  * @brief Connect a slot to Helper set mode signal.
2888  *
2889  * This signal is used to set Helper ISE mode.
2890  *
2891  * The prototype of the slot is:
2892  * void set_mode (const HelperAgent *agent, uint32 &mode);
2893  */
2894 Connection
2895 HelperAgent::signal_connect_set_mode (HelperAgentSlotUintVoid *slot)
2896 {
2897     return m_impl->signal_set_mode.connect (slot);
2898 }
2899
2900 /**
2901  * @brief Connect a slot to Helper set language signal.
2902  *
2903  * This signal is used to set Helper ISE language.
2904  *
2905  * The prototype of the slot is:
2906  * void set_language (const HelperAgent *agent, uint32 &language);
2907  */
2908 Connection
2909 HelperAgent::signal_connect_set_language (HelperAgentSlotUintVoid *slot)
2910 {
2911     return m_impl->signal_set_language.connect (slot);
2912 }
2913
2914 /**
2915  * @brief Connect a slot to Helper set im data signal.
2916  *
2917  * This signal is used to send im data to Helper ISE.
2918  *
2919  * The prototype of the slot is:
2920  * void set_imdata (const HelperAgent *agent, char *buf, size_t &len);
2921  */
2922 Connection
2923 HelperAgent::signal_connect_set_imdata (HelperAgentSlotRawVoid *slot)
2924 {
2925     return m_impl->signal_set_imdata.connect (slot);
2926 }
2927
2928 /**
2929  * @brief Connect a slot to Helper get im data signal.
2930  *
2931  * This signal is used to get im data from Helper ISE.
2932  *
2933  * The prototype of the slot is:
2934  * void get_imdata (const HelperAgent *, char **buf, size_t &len);
2935  */
2936 Connection
2937 HelperAgent::signal_connect_get_imdata (HelperAgentSlotGetRawVoid *slot)
2938 {
2939     return m_impl->signal_get_imdata.connect (slot);
2940 }
2941
2942 /**
2943  * @brief Connect a slot to Helper get language locale signal.
2944  *
2945  * This signal is used to get language locale from Helper ISE.
2946  *
2947  * The prototype of the slot is:
2948  * void get_language_locale (const HelperAgent *, int ic, char **locale);
2949  */
2950 Connection
2951 HelperAgent::signal_connect_get_language_locale (HelperAgentSlotIntGetStringVoid *slot)
2952 {
2953     return m_impl->signal_get_language_locale.connect (slot);
2954 }
2955
2956 /**
2957  * @brief Connect a slot to Helper set return key type signal.
2958  *
2959  * This signal is used to send return key type to Helper ISE.
2960  *
2961  * The prototype of the slot is:
2962  * void set_return_key_type (const HelperAgent *agent, uint32 &type);
2963  */
2964 Connection
2965 HelperAgent::signal_connect_set_return_key_type (HelperAgentSlotUintVoid *slot)
2966 {
2967     return m_impl->signal_set_return_key_type.connect (slot);
2968 }
2969
2970 /**
2971  * @brief Connect a slot to Helper get return key type signal.
2972  *
2973  * This signal is used to get return key type from Helper ISE.
2974  *
2975  * The prototype of the slot is:
2976  * void get_return_key_type (const HelperAgent *agent, uint32 &type);
2977  */
2978 Connection
2979 HelperAgent::signal_connect_get_return_key_type (HelperAgentSlotUintVoid *slot)
2980 {
2981     return m_impl->signal_get_return_key_type.connect (slot);
2982 }
2983
2984 /**
2985  * @brief Connect a slot to Helper set return key disable signal.
2986  *
2987  * This signal is used to send return key disable to Helper ISE.
2988  *
2989  * The prototype of the slot is:
2990  * void set_return_key_disable (const HelperAgent *agent, uint32 &disabled);
2991  */
2992 Connection
2993 HelperAgent::signal_connect_set_return_key_disable (HelperAgentSlotUintVoid *slot)
2994 {
2995     return m_impl->signal_set_return_key_disable.connect (slot);
2996 }
2997
2998 /**
2999  * @brief Connect a slot to Helper process key event signal.
3000  *
3001  * This signal is used to send keyboard key event to Helper ISE.
3002  *
3003  * The prototype of the slot is:
3004  * void process_key_event (const HelperAgent *agent, KeyEvent &key, uint32 &ret);
3005  */
3006 Connection
3007 HelperAgent::signal_connect_process_key_event (HelperAgentSlotKeyEventUint *slot)
3008 {
3009     return m_impl->signal_process_key_event.connect (slot);
3010 }
3011
3012 /**
3013  * @brief Connect a slot to Helper get return key disable signal.
3014  *
3015  * This signal is used to get return key disable from Helper ISE.
3016  *
3017  * The prototype of the slot is:
3018  * void get_return_key_disable (const HelperAgent *agent, uint32 &disabled);
3019  */
3020 Connection
3021 HelperAgent::signal_connect_get_return_key_disable (HelperAgentSlotUintVoid *slot)
3022 {
3023     return m_impl->signal_get_return_key_disable.connect (slot);
3024 }
3025
3026 /**
3027  * @brief Connect a slot to Helper set layout signal.
3028  *
3029  * This signal is used to set Helper ISE layout.
3030  *
3031  * The prototype of the slot is:
3032  * void set_layout (const HelperAgent *agent, uint32 &layout);
3033  */
3034 Connection
3035 HelperAgent::signal_connect_set_layout (HelperAgentSlotUintVoid *slot)
3036 {
3037     return m_impl->signal_set_layout.connect (slot);
3038 }
3039
3040 /**
3041  * @brief Connect a slot to Helper get layout signal.
3042  *
3043  * This signal is used to get Helper ISE layout.
3044  *
3045  * The prototype of the slot is:
3046  * void get_layout (const HelperAgent *agent, uint32 &layout);
3047  */
3048 Connection
3049 HelperAgent::signal_connect_get_layout (HelperAgentSlotUintVoid *slot)
3050 {
3051     return m_impl->signal_get_layout.connect (slot);
3052 }
3053
3054 /**
3055  * @brief Connect a slot to Helper set input mode signal.
3056  *
3057  * This signal is used to set Helper ISE input mode.
3058  *
3059  * The prototype of the slot is:
3060  * void set_input_mode (const HelperAgent *agent, uint32 &input_mode);
3061  */
3062 Connection
3063 HelperAgent::signal_connect_set_input_mode (HelperAgentSlotUintVoid *slot)
3064 {
3065     return m_impl->signal_set_input_mode.connect (slot);
3066 }
3067
3068 /**
3069  * @brief Connect a slot to Helper set input hint signal.
3070  *
3071  * This signal is used to set Helper ISE input hint.
3072  *
3073  * The prototype of the slot is:
3074  * void set_input_hint (const HelperAgent *agent, uint32 &input_hint);
3075  */
3076 Connection
3077 HelperAgent::signal_connect_set_input_hint (HelperAgentSlotUintVoid *slot)
3078 {
3079     return m_impl->signal_set_input_hint.connect (slot);
3080 }
3081
3082 /**
3083  * @brief Connect a slot to Helper set BiDi direction signal.
3084  *
3085  * This signal is used to set Helper ISE BiDi direction.
3086  *
3087  * The prototype of the slot is:
3088  * void update_bidi_direction (const HelperAgent *agent, uint32 &bidi_direction);
3089  */
3090 Connection
3091 HelperAgent::signal_connect_update_bidi_direction (HelperAgentSlotUintVoid *slot)
3092 {
3093     return m_impl->signal_update_bidi_direction.connect (slot);
3094 }
3095
3096 /**
3097  * @brief Connect a slot to Helper set shift mode signal.
3098  *
3099  * This signal is used to set Helper shift mode.
3100  *
3101  * The prototype of the slot is:
3102  * void set_caps_mode (const HelperAgent *agent, uint32 &mode);
3103  */
3104 Connection
3105 HelperAgent::signal_connect_set_caps_mode (HelperAgentSlotUintVoid *slot)
3106 {
3107     return m_impl->signal_set_caps_mode.connect (slot);
3108 }
3109
3110 /**
3111  * @brief Connect a slot to Helper reset input context signal.
3112  *
3113  * This signal is used to reset Helper ISE input context.
3114  *
3115  * The prototype of the slot is:
3116  * void reset_input_context (const HelperAgent *agent, int ic, const String &uuid);
3117  */
3118 Connection
3119 HelperAgent::signal_connect_reset_input_context (HelperAgentSlotVoid *slot)
3120 {
3121     return m_impl->signal_reset_input_context.connect (slot);
3122 }
3123
3124 /**
3125  * @brief Connect a slot to Helper update candidate window geometry signal.
3126  *
3127  * This signal is used to get candidate window size and position.
3128  *
3129  * The prototype of the slot is:
3130  * void update_candidate_geometry (const HelperAgent *agent, int ic, const String &uuid, const rectinfo &info);
3131  */
3132 Connection
3133 HelperAgent::signal_connect_update_candidate_geometry (HelperAgentSlotRect *slot)
3134 {
3135     return m_impl->signal_update_candidate_geometry.connect (slot);
3136 }
3137
3138 /**
3139  * @brief Connect a slot to Helper update keyboard ISE signal.
3140  *
3141  * This signal is used to get current keyboard ISE name and uuid.
3142  *
3143  * The prototype of the slot is:
3144  * void update_keyboard_ise (const HelperAgent *agent, int ic, const String &uuid,
3145  *                           const String &ise_name, const String &ise_uuid);
3146  */
3147 Connection
3148 HelperAgent::signal_connect_update_keyboard_ise (HelperAgentSlotString2 *slot)
3149 {
3150     return m_impl->signal_update_keyboard_ise.connect (slot);
3151 }
3152
3153 /**
3154  * @brief Connect a slot to Helper update keyboard ISE list signal.
3155  *
3156  * This signal is used to get uuid list of all keyboard ISEs.
3157  *
3158  * The prototype of the slot is:
3159  * void update_keyboard_ise_list (const HelperAgent *agent, int ic, const String &uuid,
3160  *                                const std::vector<String> &ise_list);
3161  */
3162 Connection
3163 HelperAgent::signal_connect_update_keyboard_ise_list (HelperAgentSlotStringVector *slot)
3164 {
3165     return m_impl->signal_update_keyboard_ise_list.connect (slot);
3166 }
3167
3168 /**
3169  * @brief Connect a slot to Helper candidate more window show signal.
3170  *
3171  * This signal is used to do someting when candidate more window is showed.
3172  *
3173  * The prototype of the slot is:
3174  * void candidate_more_window_show (const HelperAgent *agent, int ic, const String &uuid);
3175  */
3176 Connection
3177 HelperAgent::signal_connect_candidate_more_window_show (HelperAgentSlotVoid *slot)
3178 {
3179     return m_impl->signal_candidate_more_window_show.connect (slot);
3180 }
3181
3182 /**
3183  * @brief Connect a slot to Helper candidate more window hide signal.
3184  *
3185  * This signal is used to do someting when candidate more window is hidden.
3186  *
3187  * The prototype of the slot is:
3188  * void candidate_more_window_hide (const HelperAgent *agent, int ic, const String &uuid);
3189  */
3190 Connection
3191 HelperAgent::signal_connect_candidate_more_window_hide (HelperAgentSlotVoid *slot)
3192 {
3193     return m_impl->signal_candidate_more_window_hide.connect (slot);
3194 }
3195
3196 /**
3197  * @brief Connect a slot to Helper candidate show signal.
3198  *
3199  * This signal is used to do candidate show.
3200  *
3201  * The prototype of the slot is:
3202  * void candidate_show (const HelperAgent *agent, int ic, const String &uuid);
3203  */
3204 Connection
3205 HelperAgent::signal_connect_candidate_show (HelperAgentSlotVoid *slot)
3206 {
3207     return m_impl->signal_candidate_show.connect (slot);
3208 }
3209
3210 /**
3211  * @brief Connect a slot to Helper candidate hide signal.
3212  *
3213  * This signal is used to do candidate hide.
3214  *
3215  * The prototype of the slot is:
3216  * void candidate_hide (const HelperAgent *agent, int ic, const String &uuid);
3217  */
3218 Connection
3219 HelperAgent::signal_connect_candidate_hide (HelperAgentSlotVoid *slot)
3220 {
3221     return m_impl->signal_candidate_hide.connect (slot);
3222 }
3223
3224 /**
3225  * @brief Connect a slot to Helper update lookup table signal.
3226  *
3227  * This signal is used to do someting when update lookup table.
3228  *
3229  * The prototype of the slot is:
3230  * void update_lookup_table (const HelperAgent *agent, int ic, const String &uuid ,LookupTable &table);
3231  */
3232 Connection
3233 HelperAgent::signal_connect_update_lookup_table (HelperAgentSlotLookupTable *slot)
3234 {
3235     return m_impl->signal_update_lookup_table.connect (slot);
3236 }
3237
3238 /**
3239  * @brief Connect a slot to Helper select aux signal.
3240  *
3241  * This signal is used to do something when aux is selected.
3242  *
3243  * The prototype of the slot is:
3244  * void select_aux (const HelperAgent *agent, int ic, const String &uuid, int index);
3245  */
3246 Connection
3247 HelperAgent::signal_connect_select_aux (HelperAgentSlotInt *slot)
3248 {
3249     return m_impl->signal_select_aux.connect (slot);
3250 }
3251
3252 /**
3253  * @brief Connect a slot to Helper select candidate signal.
3254  *
3255  * This signal is used to do something when candidate is selected.
3256  *
3257  * The prototype of the slot is:
3258  * void select_candidate (const HelperAgent *agent, int ic, const String &uuid, int index);
3259  */
3260 Connection
3261 HelperAgent::signal_connect_select_candidate (HelperAgentSlotInt *slot)
3262 {
3263     return m_impl->signal_select_candidate.connect (slot);
3264 }
3265
3266 /**
3267  * @brief Connect a slot to Helper candidate table page up signal.
3268  *
3269  * This signal is used to do something when candidate table is paged up.
3270  *
3271  * The prototype of the slot is:
3272  * void candidate_table_page_up (const HelperAgent *agent, int ic, const String &uuid);
3273  */
3274 Connection
3275 HelperAgent::signal_connect_candidate_table_page_up (HelperAgentSlotVoid *slot)
3276 {
3277     return m_impl->signal_candidate_table_page_up.connect (slot);
3278 }
3279
3280 /**
3281  * @brief Connect a slot to Helper candidate table page down signal.
3282  *
3283  * This signal is used to do something when candidate table is paged down.
3284  *
3285  * The prototype of the slot is:
3286  * void candidate_table_page_down (const HelperAgent *agent, int ic, const String &uuid);
3287  */
3288 Connection
3289 HelperAgent::signal_connect_candidate_table_page_down (HelperAgentSlotVoid *slot)
3290 {
3291     return m_impl->signal_candidate_table_page_down.connect (slot);
3292 }
3293
3294 /**
3295  * @brief Connect a slot to Helper update candidate table page size signal.
3296  *
3297  * This signal is used to do something when candidate table page size is changed.
3298  *
3299  * The prototype of the slot is:
3300  * void update_candidate_table_page_size (const HelperAgent *, int ic, const String &uuid, int page_size);
3301  */
3302 Connection
3303 HelperAgent::signal_connect_update_candidate_table_page_size (HelperAgentSlotInt *slot)
3304 {
3305     return m_impl->signal_update_candidate_table_page_size.connect (slot);
3306 }
3307
3308 /**
3309  * @brief Connect a slot to Helper update candidate item layout signal.
3310  *
3311  * The prototype of the slot is:
3312  * void update_candidate_item_layout (const HelperAgent *, const std::vector<uint32> &row_items);
3313  */
3314 Connection
3315 HelperAgent::signal_connect_update_candidate_item_layout (HelperAgentSlotUintVector *slot)
3316 {
3317     return m_impl->signal_update_candidate_item_layout.connect (slot);
3318 }
3319
3320 /**
3321  * @brief Connect a slot to Helper select associate signal.
3322  *
3323  * This signal is used to do something when associate is selected.
3324  *
3325  * The prototype of the slot is:
3326  * void select_associate (const HelperAgent *agent, int ic, const String &uuid, int index);
3327  */
3328 Connection
3329 HelperAgent::signal_connect_select_associate (HelperAgentSlotInt *slot)
3330 {
3331     return m_impl->signal_select_associate.connect (slot);
3332 }
3333
3334 /**
3335  * @brief Connect a slot to Helper associate table page up signal.
3336  *
3337  * This signal is used to do something when associate table is paged up.
3338  *
3339  * The prototype of the slot is:
3340  * void associate_table_page_up (const HelperAgent *agent, int ic, const String &uuid);
3341  */
3342 Connection
3343 HelperAgent::signal_connect_associate_table_page_up (HelperAgentSlotVoid *slot)
3344 {
3345     return m_impl->signal_associate_table_page_up.connect (slot);
3346 }
3347
3348 /**
3349  * @brief Connect a slot to Helper associate table page down signal.
3350  *
3351  * This signal is used to do something when associate table is paged down.
3352  *
3353  * The prototype of the slot is:
3354  * void associate_table_page_down (const HelperAgent *agent, int ic, const String &uuid);
3355  */
3356 Connection
3357 HelperAgent::signal_connect_associate_table_page_down (HelperAgentSlotVoid *slot)
3358 {
3359     return m_impl->signal_associate_table_page_down.connect (slot);
3360 }
3361
3362 /**
3363  * @brief Connect a slot to Helper update associate table page size signal.
3364  *
3365  * This signal is used to do something when associate table page size is changed.
3366  *
3367  * The prototype of the slot is:
3368  * void update_associate_table_page_size (const HelperAgent *, int ic, const String &uuid, int page_size);
3369  */
3370 Connection
3371 HelperAgent::signal_connect_update_associate_table_page_size (HelperAgentSlotInt *slot)
3372 {
3373     return m_impl->signal_update_associate_table_page_size.connect (slot);
3374 }
3375
3376 /**
3377  * @brief Connect a slot to Helper turn on log signal.
3378  *
3379  * This signal is used to turn on Helper ISE debug information.
3380  *
3381  * The prototype of the slot is:
3382  * void turn_on_log (const HelperAgent *agent, uint32 &on);
3383  */
3384 Connection
3385 HelperAgent::signal_connect_turn_on_log (HelperAgentSlotUintVoid *slot)
3386 {
3387     return m_impl->signal_turn_on_log.connect (slot);
3388 }
3389
3390 /**
3391  * @brief Connect a slot to Helper update displayed candidate number signal.
3392  *
3393  * This signal is used to inform helper ISE displayed candidate number.
3394  *
3395  * The prototype of the slot is:
3396  * void update_displayed_candidate_number (const HelperAgent *, int ic, const String &uuid, int number);
3397  */
3398 Connection
3399 HelperAgent::signal_connect_update_displayed_candidate_number (HelperAgentSlotInt *slot)
3400 {
3401     return m_impl->signal_update_displayed_candidate_number.connect (slot);
3402 }
3403
3404 /**
3405  * @brief Connect a slot to Helper longpress candidate signal.
3406  *
3407  * This signal is used to do something when candidate is longpress.
3408  *
3409  * The prototype of the slot is:
3410  * void longpress_candidate (const HelperAgent *agent, int ic, const String &uuid, int index);
3411  */
3412 Connection
3413 HelperAgent::signal_connect_longpress_candidate (HelperAgentSlotInt *slot)
3414 {
3415     return m_impl->signal_longpress_candidate.connect (slot);
3416 }
3417
3418 /**
3419  * @brief Connect a slot to Helper show option window.
3420  *
3421  * This signal is used to do request the ISE to show option window.
3422  *
3423  * The prototype of the slot is:
3424  * void show_option_window (const HelperAgent *agent, int ic, const String &uuid);
3425  */
3426 Connection
3427 HelperAgent::signal_connect_show_option_window (HelperAgentSlotVoid *slot)
3428 {
3429     return m_impl->signal_show_option_window.connect (slot);
3430 }
3431
3432 /**
3433  * @brief Connect a slot to Helper resume option window.
3434  *
3435  * This signal is used to do request the ISE to resume option window.
3436  *
3437  * The prototype of the slot is:
3438  * void resume_option_window (const HelperAgent *agent, int ic, const String &uuid);
3439  */
3440 Connection
3441 HelperAgent::signal_connect_resume_option_window (HelperAgentSlotVoid *slot)
3442 {
3443     return m_impl->signal_resume_option_window.connect (slot);
3444 }
3445
3446 /**
3447  * @brief Connect a slot to Helper check if the option is available.
3448  *
3449  * This signal is used to check if the option (setting) is available from Helper ISE.
3450  *
3451  * The prototype of the slot is:
3452  * void check_option_window (const HelperAgent *agent, uint32 &avail);
3453  */
3454 Connection
3455 HelperAgent::signal_connect_check_option_window (HelperAgentSlotUintVoid *slot)
3456 {
3457     return m_impl->signal_check_option_window.connect (slot);
3458 }
3459
3460 /**
3461  * @brief Connect a slot to Helper process unconventional input device event signal.
3462  *
3463  * This signal is used to send unconventional input device event to Helper ISE.
3464  *
3465  * The prototype of the slot is:
3466  * void process_input_device_event (const HelperAgent *, uint32 &type, char *data, size_t &size, uint32 &ret);
3467  */
3468 Connection
3469 HelperAgent::signal_connect_process_input_device_event (HelperAgentSlotUintCharSizeUint *slot)
3470 {
3471     return m_impl->signal_process_input_device_event.connect (slot);
3472 }
3473
3474 /**
3475  * @brief Connect a slot to Helper set prediction hint signal.
3476  *
3477  * This signal is used to send prediction hint to Helper ISE.
3478  *
3479  * The prototype of the slot is:
3480  * void set_prediction_hint (const HelperAgent *agent, char *prediction_hint);
3481  */
3482 Connection
3483 HelperAgent::signal_connect_set_prediction_hint (HelperAgentSlotStringVoid *slot)
3484 {
3485     return m_impl->signal_set_prediction_hint.connect (slot);
3486 }
3487
3488 /**
3489  * @brief Connect a slot to Helper set mime type signal.
3490  *
3491  * This signal is used to send mime type to Helper ISE.
3492  *
3493  * The prototype of the slot is:
3494  * void set_mime_type (const HelperAgent *agent, char *mime_type);
3495  */
3496 Connection
3497 HelperAgent::signal_connect_set_mime_type (HelperAgentSlotStringVoid *slot)
3498 {
3499     return m_impl->signal_set_mime_type.connect (slot);
3500 }
3501
3502 } /* namespace scim */
3503
3504 /*
3505 vi:ts=4:nowrap:ai:expandtab
3506 */
3507