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