Separate process_key_event_with_keycode from process_key_event to prevent build error
[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
878     gettimeofday(&t0, NULL);
879     int etime = 0;
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         etime = ((t1.tv_sec * 1000000 + t1.tv_usec) - (t0.tv_sec * 1000000 + t0.tv_usec)) / 1000;
892     } while (etime < 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             m_impl->process_key_event_done (subclass->get_key_ref(), ret, subclass->get_serial_ref());
1180             break;
1181         }
1182         case ISM_TRANS_CMD_SET_LAYOUT:
1183         {
1184             MessageItemSetLayout *subclass = static_cast<MessageItemSetLayout*>(message);
1185             m_impl->layout = subclass->get_layout_ref();
1186             if (m_impl->ise_show_flag || m_impl->need_update_entry_metadata) {
1187                 m_impl->signal_set_layout (this, subclass->get_layout_ref());
1188             }
1189             if (!m_impl->si.null ()) m_impl->si->set_layout(subclass->get_layout_ref());
1190             break;
1191         }
1192         case ISM_TRANS_CMD_GET_LAYOUT:
1193         {
1194             uint32 layout = 0;
1195
1196             m_impl->signal_get_layout (this, layout);
1197             m_impl->send.clear ();
1198             m_impl->send.put_command (SCIM_TRANS_CMD_REPLY);
1199             m_impl->send.put_data (layout);
1200             m_impl->send.write_to_socket (m_impl->socket);
1201             break;
1202         }
1203         case ISM_TRANS_CMD_SET_INPUT_MODE:
1204         {
1205             MessageItemSetInputMode *subclass = static_cast<MessageItemSetInputMode*>(message);
1206             if (m_impl->ise_show_flag || m_impl->need_update_entry_metadata) {
1207                 m_impl->signal_set_input_mode (this, subclass->get_input_mode_ref());
1208             }
1209             break;
1210         }
1211         case ISM_TRANS_CMD_SET_CAPS_MODE:
1212         {
1213             MessageItemSetCapsMode *subclass = static_cast<MessageItemSetCapsMode*>(message);
1214             m_impl->signal_set_caps_mode (this, subclass->get_mode_ref());
1215             break;
1216         }
1217         case SCIM_TRANS_CMD_PANEL_RESET_INPUT_CONTEXT:
1218         {
1219             MessageItemPanelResetInputContext *subclass = static_cast<MessageItemPanelResetInputContext*>(message);
1220             m_impl->signal_reset_input_context (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1221             if (!m_impl->si.null ()) m_impl->si->reset();
1222             break;
1223         }
1224         case ISM_TRANS_CMD_UPDATE_CANDIDATE_UI:
1225         {
1226             MessageItemUpdateCandidateUI *subclass = static_cast<MessageItemUpdateCandidateUI*>(message);
1227             m_impl->signal_update_candidate_ui (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
1228                 subclass->get_style_ref(), subclass->get_mode_ref());
1229             break;
1230         }
1231         case ISM_TRANS_CMD_UPDATE_CANDIDATE_GEOMETRY:
1232         {
1233             MessageItemUpdateCandidateGeometry *subclass = static_cast<MessageItemUpdateCandidateGeometry*>(message);
1234             m_impl->signal_update_candidate_geometry (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
1235                 subclass->get_rectinfo_ref());
1236             break;
1237         }
1238         case ISM_TRANS_CMD_UPDATE_KEYBOARD_ISE:
1239         {
1240             MessageItemUpdateKeyboardISE *subclass = static_cast<MessageItemUpdateKeyboardISE*>(message);
1241             m_impl->signal_update_keyboard_ise (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
1242                 subclass->get_name_ref(), subclass->get_uuid_ref());
1243             break;
1244         }
1245         case ISM_TRANS_CMD_UPDATE_KEYBOARD_ISE_LIST:
1246         {
1247             MessageItemUpdateKeyboardISEList *subclass = static_cast<MessageItemUpdateKeyboardISEList*>(message);
1248             m_impl->signal_update_keyboard_ise_list (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
1249                 subclass->get_list_ref());
1250             break;
1251         }
1252         case ISM_TRANS_CMD_CANDIDATE_MORE_WINDOW_SHOW:
1253         {
1254             MessageItemCandidateMoreWindowShow *subclass = static_cast<MessageItemCandidateMoreWindowShow*>(message);
1255             m_impl->signal_candidate_more_window_show (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1256             if (!m_impl->si.null ()) m_impl->si->candidate_more_window_show();
1257             break;
1258         }
1259         case ISM_TRANS_CMD_CANDIDATE_MORE_WINDOW_HIDE:
1260         {
1261             MessageItemCandidateMoreWindowHide *subclass = static_cast<MessageItemCandidateMoreWindowHide*>(message);
1262             m_impl->signal_candidate_more_window_hide (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1263             if (!m_impl->si.null ()) m_impl->si->candidate_more_window_hide();
1264             break;
1265         }
1266         case ISM_TRANS_CMD_SELECT_AUX:
1267         {
1268             MessageItemSelectAux *subclass = static_cast<MessageItemSelectAux*>(message);
1269             m_impl->signal_select_aux (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
1270                 subclass->get_item_ref());
1271             if (!m_impl->si.null ()) m_impl->si->select_aux(subclass->get_item_ref());
1272             break;
1273         }
1274         case SCIM_TRANS_CMD_SELECT_CANDIDATE: //FIXME:remove if useless
1275         {
1276             MessageItemSelectCandidate *subclass = static_cast<MessageItemSelectCandidate*>(message);
1277             m_impl->signal_select_candidate (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
1278                 subclass->get_item_ref());
1279             if (!m_impl->si.null ()) m_impl->si->select_candidate(subclass->get_item_ref());
1280             break;
1281         }
1282         case SCIM_TRANS_CMD_LOOKUP_TABLE_PAGE_UP: //FIXME:remove if useless
1283         {
1284             MessageItemLookupTablePageUp *subclass = static_cast<MessageItemLookupTablePageUp*>(message);
1285             m_impl->signal_candidate_table_page_up (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1286             if (!m_impl->si.null ()) m_impl->si->lookup_table_page_up();
1287             break;
1288         }
1289         case SCIM_TRANS_CMD_LOOKUP_TABLE_PAGE_DOWN: //FIXME:remove if useless
1290         {
1291             MessageItemLookupTablePageDown *subclass = static_cast<MessageItemLookupTablePageDown*>(message);
1292             m_impl->signal_candidate_table_page_down (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1293             if (!m_impl->si.null ()) m_impl->si->lookup_table_page_down();
1294             break;
1295         }
1296         case SCIM_TRANS_CMD_UPDATE_LOOKUP_TABLE_PAGE_SIZE:
1297         {
1298             MessageItemUpdateLookupTablePageSize *subclass = static_cast<MessageItemUpdateLookupTablePageSize*>(message);
1299             m_impl->signal_update_candidate_table_page_size (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
1300                 subclass->get_size_ref());
1301             if (!m_impl->si.null ()) m_impl->si->update_lookup_table_page_size(subclass->get_size_ref());
1302             break;
1303         }
1304         case ISM_TRANS_CMD_CANDIDATE_SHOW: //FIXME:remove if useless
1305         {
1306             MessageItemCandidateShow *subclass = static_cast<MessageItemCandidateShow*>(message);
1307             m_impl->signal_candidate_show (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1308             break;
1309         }
1310         case ISM_TRANS_CMD_CANDIDATE_HIDE: //FIXME:remove if useless
1311         {
1312             MessageItemCandidateHide *subclass = static_cast<MessageItemCandidateHide*>(message);
1313             m_impl->signal_candidate_hide (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1314             break;
1315         }
1316         case ISM_TRANS_CMD_UPDATE_LOOKUP_TABLE: //FIXME:remove if useless
1317         {
1318             MessageItemUpdateLookupTable *subclass = static_cast<MessageItemUpdateLookupTable*>(message);
1319             m_impl->signal_update_lookup_table (this, subclass->get_candidate_table_ref());
1320             break;
1321         }
1322         case ISM_TRANS_CMD_UPDATE_CANDIDATE_ITEM_LAYOUT:
1323         {
1324             MessageItemUpdateCandidateItemLayout *subclass = static_cast<MessageItemUpdateCandidateItemLayout*>(message);
1325             m_impl->signal_update_candidate_item_layout (this, subclass->get_row_items_ref());
1326             if (!m_impl->si.null ()) m_impl->si->update_candidate_item_layout(subclass->get_row_items_ref());
1327             break;
1328         }
1329         case ISM_TRANS_CMD_SELECT_ASSOCIATE:
1330         {
1331             MessageItemSelectAssociate *subclass = static_cast<MessageItemSelectAssociate*>(message);
1332             m_impl->signal_select_associate (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
1333                 subclass->get_item_ref());
1334             break;
1335         }
1336         case ISM_TRANS_CMD_ASSOCIATE_TABLE_PAGE_UP:
1337         {
1338             MessageItemAssociateTablePageUp *subclass = static_cast<MessageItemAssociateTablePageUp*>(message);
1339             m_impl->signal_associate_table_page_up (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1340             break;
1341         }
1342         case ISM_TRANS_CMD_ASSOCIATE_TABLE_PAGE_DOWN:
1343         {
1344             MessageItemAssociateTablePageDown *subclass = static_cast<MessageItemAssociateTablePageDown*>(message);
1345             m_impl->signal_associate_table_page_down (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1346             break;
1347         }
1348         case ISM_TRANS_CMD_UPDATE_ASSOCIATE_TABLE_PAGE_SIZE:
1349         {
1350             MessageItemUpdateAssociateTablePageSize *subclass = static_cast<MessageItemUpdateAssociateTablePageSize*>(message);
1351             m_impl->signal_update_associate_table_page_size (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
1352                 subclass->get_size_ref());
1353             break;
1354         }
1355         case ISM_TRANS_CMD_RESET_ISE_CONTEXT:
1356         {
1357             MessageItemResetISEContext *subclass = static_cast<MessageItemResetISEContext*>(message);
1358             m_impl->signal_reset_ise_context (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1359             m_impl->signal_reset_input_context (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1360             if (!m_impl->si.null ()) m_impl->si->reset();
1361             break;
1362         }
1363         case ISM_TRANS_CMD_TURN_ON_LOG:
1364         {
1365             MessageItemTurnOnLog *subclass = static_cast<MessageItemTurnOnLog*>(message);
1366             m_impl->signal_turn_on_log (this, subclass->get_state_ref());
1367             break;
1368         }
1369         case ISM_TRANS_CMD_UPDATE_DISPLAYED_CANDIDATE:
1370         {
1371             MessageItemUpdateDisplayedCandidate *subclass = static_cast<MessageItemUpdateDisplayedCandidate*>(message);
1372             m_impl->signal_update_displayed_candidate_number (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
1373                 subclass->get_size_ref());
1374             if (!m_impl->si.null ()) m_impl->si->update_displayed_candidate_number(subclass->get_size_ref());
1375             break;
1376         }
1377         case ISM_TRANS_CMD_LONGPRESS_CANDIDATE:
1378         {
1379             MessageItemLongpressCandidate *subclass = static_cast<MessageItemLongpressCandidate*>(message);
1380             m_impl->signal_longpress_candidate (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref(),
1381                 subclass->get_index_ref());
1382             if (!m_impl->si.null ()) m_impl->si->longpress_candidate(subclass->get_index_ref());
1383             break;
1384         }
1385         case ISM_TRANS_CMD_SET_INPUT_HINT:
1386         {
1387             MessageItemSetInputHint *subclass = static_cast<MessageItemSetInputHint*>(message);
1388             if (m_impl->ise_show_flag || m_impl->need_update_entry_metadata) {
1389                 m_impl->signal_set_input_hint (this, subclass->get_input_hint_ref());
1390             }
1391             if (!m_impl->si.null ()) m_impl->si->set_input_hint(subclass->get_input_hint_ref());
1392             break;
1393         }
1394         case ISM_TRANS_CMD_UPDATE_BIDI_DIRECTION:
1395         {
1396             MessageItemUpdateBidiDirection *subclass = static_cast<MessageItemUpdateBidiDirection*>(message);
1397             m_impl->signal_update_bidi_direction (this, subclass->get_bidi_direction());
1398             if (!m_impl->si.null ()) m_impl->si->update_bidi_direction(subclass->get_bidi_direction());
1399             break;
1400         }
1401         case ISM_TRANS_CMD_SHOW_ISE_OPTION_WINDOW:
1402         {
1403             MessageItemShowISEOptionWindow *subclass = static_cast<MessageItemShowISEOptionWindow*>(message);
1404             m_impl->signal_show_option_window (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1405             break;
1406         }
1407         case ISM_TRANS_CMD_RESUME_ISE_OPTION_WINDOW:
1408         {
1409             MessageItemResumeISEOptionWindow *subclass = static_cast<MessageItemResumeISEOptionWindow*>(message);
1410             m_impl->signal_resume_option_window (this, subclass->get_ic_ref(), subclass->get_ic_uuid_ref());
1411             break;
1412         }
1413         case ISM_TRANS_CMD_CHECK_OPTION_WINDOW:
1414         {
1415             uint32 avail = 0;
1416             m_impl->signal_check_option_window (this, avail);
1417             m_impl->send.clear ();
1418             m_impl->send.put_command (SCIM_TRANS_CMD_REPLY);
1419             m_impl->send.put_data (avail);
1420             m_impl->send.write_to_socket (m_impl->socket);
1421             break;
1422         }
1423         case ISM_TRANS_CMD_PROCESS_INPUT_DEVICE_EVENT:
1424         {
1425             MessageItemProcessInputDeviceEvent *subclass = static_cast<MessageItemProcessInputDeviceEvent*>(message);
1426             uint32 ret = 0;
1427             unsigned int ecore_event_id = find_ecore_event_from_device_type((isf_device_type_e)(subclass->get_type_ref()));
1428             char *decoded = (char*)malloc(subclass->get_len_ref());
1429             size_t decoded_size = subclass->get_len_ref();
1430             if (decoded) {
1431                 if(device_buffer_decode((const char*)*(subclass->get_data_ptr()),
1432                     subclass->get_len_ref(), (char*)(decoded), &decoded_size)) {
1433                     m_impl->signal_process_input_device_event(this, ecore_event_id, decoded, decoded_size, ret);
1434                 }
1435                 free(decoded);
1436             }
1437             break;
1438         }
1439         case SCIM_TRANS_CMD_SET_AUTOCAPITAL_TYPE:
1440         {
1441             MessageItemSetAutocapitalType *subclass = static_cast<MessageItemSetAutocapitalType*>(message);
1442             if (!m_impl->si.null ()) m_impl->si->set_autocapital_type(subclass->get_auto_capital_type_ref());
1443             break;
1444         }
1445         case ISM_TRANS_CMD_SET_PREDICTION_ALLOW:
1446         {
1447             MessageItemSetPredictionAllow *subclass = static_cast<MessageItemSetPredictionAllow*>(message);
1448             if (!m_impl->si.null ()) m_impl->si->set_prediction_allow(subclass->get_prediction_allow_ref() == 0 ? false : true);
1449             break;
1450         }
1451         case ISM_TRANS_CMD_SET_KEYBOARD_MODE:
1452         {
1453             MessageItemSetKeyboardMode *subclass = static_cast<MessageItemSetKeyboardMode*>(message);
1454             if (subclass->get_mode_ref())
1455                 m_impl->need_update_entry_metadata = false;
1456             else
1457                 m_impl->need_update_entry_metadata = true;
1458             break;
1459         }
1460         case ISM_TRANS_CMD_SET_PREDICTION_HINT:
1461         {
1462             MessageItemSetPredictionHint *subclass = static_cast<MessageItemSetPredictionHint*>(message);
1463             m_impl->signal_set_prediction_hint (this, subclass->get_message_ref());
1464             break;
1465         }
1466         case ISM_TRANS_CMD_SET_MIME_TYPE:
1467         {
1468             MessageItemSetMimeType *subclass = static_cast<MessageItemSetMimeType*>(message);
1469             if (m_impl->ise_show_flag || m_impl->need_update_entry_metadata) {
1470                 m_impl->signal_set_mime_type (this, subclass->get_mime_type_ref());
1471             }
1472             break;
1473         }
1474         case ISM_TRANS_CMD_FINALIZE_CONTENT:
1475         {
1476             MessageItemFinalizeContent *subclass = static_cast<MessageItemFinalizeContent*>(message);
1477             if (m_impl) {
1478                 if (m_impl->finalized_text != NULL)
1479                     free(m_impl->finalized_text);
1480                 m_impl->finalized_text = strdup(subclass->get_text_ref().c_str());
1481                 m_impl->finalized_cursor_pos = subclass->get_cursor_pos_ref();
1482             }
1483             break;
1484         }
1485         case ISM_TRANS_CMD_SET_PREDICTION_HINT_DATA:
1486         {
1487             MessageItemSetPredictionHintData *subclass = static_cast<MessageItemSetPredictionHintData*>(message);
1488             m_impl->signal_set_prediction_hint_data (this, 0, subclass->get_key_ref(), subclass->get_value_ref());
1489             break;
1490         }
1491         case ISM_TRANS_CMD_SET_OPTIMIZATION_HINT:
1492         {
1493             MessageItemSetOptimizationHint *subclass = static_cast<MessageItemSetOptimizationHint*>(message);
1494             m_impl->signal_set_optimization_hint(this, subclass->get_hint_ref());
1495             break;
1496         }
1497         default:
1498             break;
1499     }
1500     return true;
1501 }
1502
1503 /**
1504  * @brief Request SCIM to reload all configuration.
1505  *
1506  * This function should only by used by Setup Helper to request
1507  * scim's reloading the configuration.
1508  * Deprecated: reload config message only send by socketconfig client
1509  * using socketconfig::reload instead.
1510  */
1511 void
1512 HelperAgent::reload_config () const
1513 {
1514     LOGD ("send reload config message to isf");
1515     if (!m_impl->m_config.null())
1516         m_impl->m_config->reload();
1517 }
1518
1519 /**
1520  * @brief Register some properties into Panel.
1521  *
1522  * This function send the request to Panel to register a list
1523  * of Properties.
1524  *
1525  * @param properties The list of Properties to be registered into Panel.
1526  *
1527  * @sa scim::Property.
1528  */
1529 void
1530 HelperAgent::register_properties (const PropertyList &properties) const
1531 {
1532     if (m_impl->socket_active.is_connected ()) {
1533         m_impl->send.clear ();
1534         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1535         m_impl->send.put_data (m_impl->magic_active);
1536         m_impl->send.put_command (SCIM_TRANS_CMD_REGISTER_PROPERTIES);
1537         m_impl->send.put_data (properties);
1538         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1539     }
1540 }
1541
1542 /**
1543  * @brief Update a registered property.
1544  *
1545  * @param property The property to be updated.
1546  */
1547 void
1548 HelperAgent::update_property (const Property &property) const
1549 {
1550     if (m_impl->socket_active.is_connected ()) {
1551         m_impl->send.clear ();
1552         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1553         m_impl->send.put_data (m_impl->magic_active);
1554         m_impl->send.put_command (SCIM_TRANS_CMD_UPDATE_PROPERTY);
1555         m_impl->send.put_data (property);
1556         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1557     }
1558 }
1559
1560 /**
1561  * @brief Send a set of events to an IMEngineInstance.
1562  *
1563  * All events should be put into a Transaction.
1564  * And the events can only be received by one IMEngineInstance object.
1565  *
1566  * @param ic The handle of the Input Context to receive the events.
1567  * @param ic_uuid The UUID of the Input Context.
1568  * @param trans The Transaction object holds the events.
1569  */
1570 void
1571 HelperAgent::send_imengine_event (int                ic,
1572                                   const String      &ic_uuid,
1573                                   const Transaction &trans) const
1574 {
1575 //remove if not necessary
1576 #if 0
1577     if (m_impl->socket_active.is_connected ()) {
1578         m_impl->send.clear ();
1579         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1580         m_impl->send.put_data (m_impl->magic_active);
1581         m_impl->send.put_command (SCIM_TRANS_CMD_PANEL_SEND_IMENGINE_EVENT);
1582         m_impl->send.put_data ((uint32)ic);
1583         m_impl->send.put_data (ic_uuid);
1584         m_impl->send.put_data (trans);
1585         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1586     }
1587 #endif
1588     if (!m_impl->si.null ()) m_impl->si->process_helper_event (ic_uuid, trans);
1589 }
1590
1591 /**
1592  * @brief Send a KeyEvent to an IMEngineInstance.
1593  *
1594  * @param ic The handle of the IMEngineInstance to receive the event.
1595  *        -1 means the currently focused IMEngineInstance.
1596  * @param ic_uuid The UUID of the IMEngineInstance. Empty means don't match.
1597  * @param key The KeyEvent to be sent.
1598  */
1599 void
1600 HelperAgent::send_key_event (int            ic,
1601                              const String   &ic_uuid,
1602                              const KeyEvent &key) const
1603 {
1604
1605     //FIXME: remove shift_mode_off, shift_mode_on, shift_mode_lock from ISE side
1606     if (key.code == SHIFT_MODE_OFF ||
1607         key.code == SHIFT_MODE_ON ||
1608         key.code == SHIFT_MODE_LOCK ||
1609         key.code == SHIFT_MODE_ENABLE ||
1610         key.code == SHIFT_MODE_DISABLE) {
1611         LOGW("FIXME ignore shift codes");
1612         return;
1613     }
1614
1615     if (m_impl->socket_active.is_connected ()) {
1616         m_impl->send.clear ();
1617         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1618         m_impl->send.put_data (m_impl->magic_active);
1619         m_impl->send.put_command (SCIM_TRANS_CMD_PANEL_SEND_KEY_EVENT);
1620         if (ic == -1) {
1621             m_impl->send.put_data (m_impl->focused_ic);
1622         } else {
1623             m_impl->send.put_data ((uint32)ic);
1624         }
1625         m_impl->send.put_data (ic_uuid);
1626         m_impl->send.put_data (key);
1627         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1628     }
1629 }
1630
1631 /**
1632  * @brief Forward a KeyEvent to client application directly.
1633  *
1634  * @param ic The handle of the client Input Context to receive the event.
1635  *        -1 means the currently focused Input Context.
1636  * @param ic_uuid The UUID of the IMEngine used by the Input Context.
1637  *        Empty means don't match.
1638  * @param key The KeyEvent to be forwarded.
1639  */
1640 void
1641 HelperAgent::forward_key_event (int            ic,
1642                                 const String   &ic_uuid,
1643                                 const KeyEvent &key) const
1644 {
1645     if (m_impl->socket_active.is_connected ()) {
1646         m_impl->send.clear ();
1647         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1648         m_impl->send.put_data (m_impl->magic_active);
1649         m_impl->send.put_command (SCIM_TRANS_CMD_FORWARD_KEY_EVENT);
1650         if (ic == -1) {
1651             m_impl->send.put_data (m_impl->focused_ic);
1652         } else {
1653             m_impl->send.put_data ((uint32)ic);
1654         }
1655         m_impl->send.put_data (ic_uuid);
1656         m_impl->send.put_data (key);
1657         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1658     }
1659 }
1660
1661 /**
1662  * @brief Commit a WideString to client application directly.
1663  *
1664  * @param ic The handle of the client Input Context to receive the WideString.
1665  *        -1 means the currently focused Input Context.
1666  * @param ic_uuid The UUID of the IMEngine used by the Input Context.
1667  *        Empty means don't match.
1668  * @param wstr The WideString to be committed.
1669  */
1670 void
1671 HelperAgent::commit_string (int               ic,
1672                             const String     &ic_uuid,
1673                             const WideString &wstr) const
1674 {
1675     if (m_impl->socket_active.is_connected ()) {
1676         m_impl->send.clear ();
1677         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1678         m_impl->send.put_data (m_impl->magic_active);
1679         m_impl->send.put_command (SCIM_TRANS_CMD_COMMIT_STRING);
1680         if (ic == -1) {
1681             m_impl->send.put_data (m_impl->focused_ic);
1682         } else {
1683             m_impl->send.put_data ((uint32)ic);
1684         }
1685         m_impl->send.put_data (ic_uuid);
1686         m_impl->send.put_data (wstr);
1687         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1688     }
1689 }
1690
1691 void
1692 HelperAgent::commit_string (int               ic,
1693                             const String     &ic_uuid,
1694                             const  char      *buf,
1695                             int               buflen) const
1696 {
1697     if (m_impl->socket_active.is_connected ()) {
1698         m_impl->send.clear ();
1699         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1700         m_impl->send.put_data (m_impl->magic_active);
1701         m_impl->send.put_command (SCIM_TRANS_CMD_COMMIT_STRING);
1702         if (ic == -1) {
1703             m_impl->send.put_data (m_impl->focused_ic);
1704         } else {
1705             m_impl->send.put_data ((uint32)ic);
1706         }
1707         m_impl->send.put_data (ic_uuid);
1708         m_impl->send.put_dataw (buf, buflen);
1709         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1710     }
1711 }
1712
1713 /**
1714  * @brief Request to show preedit string.
1715  *
1716  * @param ic The handle of the client Input Context to receive the request.
1717  *        -1 means the currently focused Input Context.
1718  * @param ic_uuid The UUID of the IMEngine used by the Input Context.
1719  *        Empty means don't match.
1720  */
1721 void
1722 HelperAgent::show_preedit_string (int               ic,
1723                                   const String     &ic_uuid) const
1724 {
1725
1726     if (m_impl->socket_active.is_connected ()) {
1727         m_impl->send.clear ();
1728         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1729         m_impl->send.put_data (m_impl->magic_active);
1730         m_impl->send.put_command (SCIM_TRANS_CMD_SHOW_PREEDIT_STRING);
1731         m_impl->send.put_data ((uint32)ic);
1732         m_impl->send.put_data (ic_uuid);
1733         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1734     }
1735 }
1736
1737 /**
1738  * @brief Request to show aux string.
1739  */
1740 void
1741 HelperAgent::show_aux_string (void) const
1742 {
1743
1744     if (m_impl->socket_active.is_connected ()) {
1745         m_impl->send.clear ();
1746         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1747         m_impl->send.put_data (m_impl->magic_active);
1748         m_impl->send.put_command (SCIM_TRANS_CMD_SHOW_AUX_STRING);
1749         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1750     }
1751 }
1752
1753 /**
1754  * @brief Request to show candidate string.
1755  */
1756 void
1757 HelperAgent::show_candidate_string (void) const
1758 {
1759
1760     if (m_impl->socket_active.is_connected ()) {
1761         m_impl->send.clear ();
1762         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1763         m_impl->send.put_data (m_impl->magic_active);
1764         m_impl->send.put_command (SCIM_TRANS_CMD_SHOW_LOOKUP_TABLE);
1765         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1766     }
1767 }
1768
1769 /**
1770  * @brief Request to show associate string.
1771  */
1772 void
1773 HelperAgent::show_associate_string (void) const
1774 {
1775     if (m_impl->socket_active.is_connected ()) {
1776         m_impl->send.clear ();
1777         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1778         m_impl->send.put_data (m_impl->magic_active);
1779         m_impl->send.put_command (ISM_TRANS_CMD_SHOW_ASSOCIATE_TABLE);
1780         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1781     }
1782 }
1783
1784 /**
1785  * @brief Request to hide preedit string.
1786  *
1787  * @param ic The handle of the client Input Context to receive the request.
1788  *        -1 means the currently focused Input Context.
1789  * @param ic_uuid The UUID of the IMEngine used by the Input Context.
1790  *        Empty means don't match.
1791  */
1792 void
1793 HelperAgent::hide_preedit_string (int               ic,
1794                                   const String     &ic_uuid) const
1795 {
1796
1797     if (m_impl->socket_active.is_connected ()) {
1798         m_impl->send.clear ();
1799         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1800         m_impl->send.put_data (m_impl->magic_active);
1801         m_impl->send.put_command (SCIM_TRANS_CMD_HIDE_PREEDIT_STRING);
1802         m_impl->send.put_data ((uint32)ic);
1803         m_impl->send.put_data (ic_uuid);
1804         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1805     }
1806 }
1807
1808 /**
1809  * @brief Request to hide aux string.
1810  */
1811 void
1812 HelperAgent::hide_aux_string (void) const
1813 {
1814     if (m_impl->socket_active.is_connected ()) {
1815         m_impl->send.clear ();
1816         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1817         m_impl->send.put_data (m_impl->magic_active);
1818         m_impl->send.put_command (SCIM_TRANS_CMD_HIDE_AUX_STRING);
1819         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1820     }
1821 }
1822
1823 /**
1824  * @brief Request to hide candidate string.
1825  */
1826 void
1827 HelperAgent::hide_candidate_string (void) const
1828 {
1829     if (m_impl->socket_active.is_connected ()) {
1830         m_impl->send.clear ();
1831         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1832         m_impl->send.put_data (m_impl->magic_active);
1833         m_impl->send.put_command (SCIM_TRANS_CMD_HIDE_LOOKUP_TABLE);
1834         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1835     }
1836 }
1837
1838 /**
1839  * @brief Request to hide associate string.
1840  */
1841 void
1842 HelperAgent::hide_associate_string (void) const
1843 {
1844     if (m_impl->socket_active.is_connected ()) {
1845         m_impl->send.clear ();
1846         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1847         m_impl->send.put_data (m_impl->magic_active);
1848         m_impl->send.put_command (ISM_TRANS_CMD_HIDE_ASSOCIATE_TABLE);
1849         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1850     }
1851 }
1852
1853 /**
1854  * @brief Update a new WideString for preedit.
1855  *
1856  * @param ic The handle of the client Input Context to receive the WideString.
1857  *        -1 means the currently focused Input Context.
1858  * @param ic_uuid The UUID of the IMEngine used by the Input Context.
1859  *        Empty means don't match.
1860  * @param str The WideString to be updated.
1861  * @param attrs The attribute list for preedit string.
1862  */
1863 void
1864 HelperAgent::update_preedit_string (int                  ic,
1865                                     const String        &ic_uuid,
1866                                     const WideString    &str,
1867                                     const AttributeList &attrs) const
1868 {
1869     update_preedit_string (ic, ic_uuid, str, str, attrs, -1);
1870 }
1871
1872 void
1873 HelperAgent::update_preedit_string (int                  ic,
1874                                     const String        &ic_uuid,
1875                                     const char         *buf,
1876                                     int                 buflen,
1877                                     const AttributeList &attrs) const
1878 {
1879     update_preedit_string (ic, ic_uuid, buf, buflen, attrs, -1);
1880 }
1881
1882 /**
1883  * @brief Update a new WideString for preedit.
1884  *
1885  * @param ic The handle of the client Input Context to receive the WideString.
1886  *        -1 means the currently focused Input Context.
1887  * @param ic_uuid The UUID of the IMEngine used by the Input Context.
1888  *        Empty means don't match.
1889  * @param str The WideString to be updated.
1890  * @param attrs The attribute list for preedit string.
1891  * @param caret The caret position in preedit string.
1892  */
1893 void
1894 HelperAgent::update_preedit_string (int                  ic,
1895                                     const String        &ic_uuid,
1896                                     const WideString    &wstr,
1897                                     const AttributeList &attrs,
1898                                     int            caret) const
1899 {
1900     update_preedit_string (ic, ic_uuid, wstr, wstr, attrs, caret);
1901 }
1902
1903 void
1904 HelperAgent::update_preedit_string (int                 ic,
1905                                     const String       &ic_uuid,
1906                                     const char         *buf,
1907                                     int                 buflen,
1908                                     const AttributeList &attrs,
1909                                     int            caret) const
1910 {
1911
1912     if (m_impl->socket_active.is_connected ()) {
1913         m_impl->send.clear ();
1914         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1915         m_impl->send.put_data (m_impl->magic_active);
1916         m_impl->send.put_command (SCIM_TRANS_CMD_UPDATE_PREEDIT_STRING);
1917         m_impl->send.put_data ((uint32)ic);
1918         m_impl->send.put_data (ic_uuid);
1919         m_impl->send.put_dataw (buf, buflen);
1920         m_impl->send.put_dataw (buf, buflen);
1921         m_impl->send.put_data (attrs);
1922         m_impl->send.put_data (caret);
1923         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1924     }
1925 }
1926
1927 void
1928 HelperAgent::update_preedit_string (int                  ic,
1929                                     const String        &ic_uuid,
1930                                     const WideString    &preedit,
1931                                     const WideString    &commit,
1932                                     const AttributeList &attrs,
1933                                     int                  caret) const
1934 {
1935     if (m_impl->socket_active.is_connected ()) {
1936         m_impl->send.clear ();
1937         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1938         m_impl->send.put_data (m_impl->magic_active);
1939         m_impl->send.put_command (SCIM_TRANS_CMD_UPDATE_PREEDIT_STRING);
1940         m_impl->send.put_data ((uint32)ic);
1941         m_impl->send.put_data (ic_uuid);
1942         m_impl->send.put_data (preedit);
1943         m_impl->send.put_data (commit);
1944         m_impl->send.put_data (attrs);
1945         m_impl->send.put_data (caret);
1946         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1947     }
1948 }
1949
1950 /**
1951  * @brief Update the preedit caret position in the preedit string.
1952  *
1953  * @param caret - the new position of the preedit caret.
1954  */
1955 void
1956 HelperAgent::update_preedit_caret (int caret) const
1957 {
1958
1959     if (m_impl->socket_active.is_connected ()) {
1960         m_impl->send.clear ();
1961         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1962         m_impl->send.put_data (m_impl->magic_active);
1963         m_impl->send.put_command (SCIM_TRANS_CMD_UPDATE_PREEDIT_CARET);
1964         m_impl->send.put_data ((uint32)caret);
1965         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1966     }
1967 }
1968
1969 /**
1970  * @brief Update a new string for aux.
1971  *
1972  * @param str The string to be updated.
1973  * @param attrs The attribute list for aux string.
1974  */
1975 void
1976 HelperAgent::update_aux_string (const String        &str,
1977                                 const AttributeList &attrs) const
1978 {
1979     if (m_impl->socket_active.is_connected ()) {
1980         m_impl->send.clear ();
1981         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
1982         m_impl->send.put_data (m_impl->magic_active);
1983         m_impl->send.put_command (SCIM_TRANS_CMD_UPDATE_AUX_STRING);
1984         m_impl->send.put_data (str);
1985         m_impl->send.put_data (attrs);
1986         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
1987     }
1988 }
1989
1990 /**
1991  * @brief Request to update candidate.
1992  *
1993  * @param table The lookup table for candidate.
1994  */
1995 void
1996 HelperAgent::update_candidate_string (const LookupTable &table) const
1997 {
1998     if (m_impl->socket_active.is_connected ()) {
1999         m_impl->send.clear ();
2000         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2001         m_impl->send.put_data (m_impl->magic_active);
2002         m_impl->send.put_command (SCIM_TRANS_CMD_UPDATE_LOOKUP_TABLE);
2003         m_impl->send.put_data (table);
2004         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2005     }
2006 }
2007
2008 /**
2009  * @brief Request to update associate.
2010  *
2011  * @param table The lookup table for associate.
2012  */
2013 void
2014 HelperAgent::update_associate_string (const LookupTable &table) const
2015 {
2016     if (m_impl->socket_active.is_connected ()) {
2017         m_impl->send.clear ();
2018         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2019         m_impl->send.put_data (m_impl->magic_active);
2020         m_impl->send.put_command (ISM_TRANS_CMD_UPDATE_ASSOCIATE_TABLE);
2021         m_impl->send.put_data (table);
2022         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2023     }
2024 }
2025
2026 /**
2027  * @brief When the input context of ISE is changed,
2028  *         ISE can call this function to notify application
2029  *
2030  * @param type  type of event.
2031  * @param value value of event.
2032  */
2033 void
2034 HelperAgent::update_input_context (uint32 type, uint32 value) const
2035 {
2036     if (type == ECORE_IMF_INPUT_PANEL_LANGUAGE_EVENT) {
2037         /* Update all state variables that could be queried by the client application */
2038         char *buf = NULL;
2039         m_impl->signal_get_language_locale(this, -1, &buf);
2040
2041         if (buf != NULL) {
2042             if (m_impl->socket_active.is_connected()) {
2043                 m_impl->send.clear();
2044                 m_impl->send.put_command(SCIM_TRANS_CMD_REQUEST);
2045                 m_impl->send.put_data(m_impl->magic_active);
2046                 m_impl->send.put_command(ISM_TRANS_CMD_UPDATE_ISE_LANGUAGE_LOCALE);
2047                 m_impl->send.put_data(buf, strlen(buf));
2048                 m_impl->send.write_to_socket(m_impl->socket_active, m_impl->magic_active);
2049             }
2050             free(buf);
2051             buf = NULL;
2052         }
2053     }
2054
2055     if (m_impl->socket_active.is_connected ()) {
2056         m_impl->send.clear ();
2057         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2058         m_impl->send.put_data (m_impl->magic_active);
2059         m_impl->send.put_command (ISM_TRANS_CMD_UPDATE_ISE_INPUT_CONTEXT);
2060         m_impl->send.put_data (type);
2061         m_impl->send.put_data (value);
2062         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2063     }
2064 }
2065
2066 /**
2067  * @brief Request to get surrounding text asynchronously.
2068  *
2069  * @param uuid The helper ISE UUID.
2070  * @param maxlen_before The max length of before.
2071  * @param maxlen_after The max length of after.
2072  */
2073 void
2074 HelperAgent::get_surrounding_text (const String &uuid, int maxlen_before, int maxlen_after) const
2075 {
2076     if (m_impl->socket_active.is_connected () && (m_impl->need_update_surrounding_text == 0)) {
2077         m_impl->send.clear ();
2078         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2079         m_impl->send.put_data (m_impl->magic_active);
2080         m_impl->send.put_command (SCIM_TRANS_CMD_GET_SURROUNDING_TEXT);
2081         m_impl->send.put_data (uuid);
2082         m_impl->send.put_data (maxlen_before);
2083         m_impl->send.put_data (maxlen_after);
2084         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2085     }
2086     m_impl->need_update_surrounding_text++;
2087 }
2088
2089 /**
2090  * @brief Request to get surrounding text synchronously.
2091  *
2092  * @param uuid The helper ISE UUID.
2093  * @param maxlen_before The max length of before.
2094  * @param maxlen_after The max length of after.
2095  * @param text The surrounding text.
2096  * @param cursor The cursor position.
2097  */
2098 void
2099 HelperAgent::get_surrounding_text (int maxlen_before, int maxlen_after, String &text, int &cursor)
2100 {
2101     if (!m_impl->socket_active.is_connected ())
2102         return;
2103
2104     if (!m_impl->ise_focus_flag) {
2105         if (m_impl->finalized_text) {
2106             String buffer = m_impl->finalized_text;
2107             cursor = m_impl->finalized_cursor_pos;
2108             int pos = cursor - maxlen_before;
2109             if (maxlen_before < 0) pos = 0;
2110             if (pos > (int)buffer.length()) pos = (int)buffer.length();
2111             if (pos < 0) pos = 0;
2112             size_t len = maxlen_after + (cursor - pos);
2113             if (maxlen_after < 0) len = String::npos;
2114             text = buffer.substr (pos, len);
2115         } else {
2116             text.clear ();
2117             cursor = 0;
2118         }
2119     } else {
2120         m_impl->send.clear();
2121         m_impl->send.put_command(SCIM_TRANS_CMD_REQUEST);
2122         m_impl->send.put_data(m_impl->magic_active);
2123         m_impl->send.put_command(SCIM_TRANS_CMD_GET_SURROUNDING_TEXT);
2124         m_impl->send.put_data("");
2125         m_impl->send.put_data(maxlen_before);
2126         m_impl->send.put_data(maxlen_after);
2127         m_impl->send.write_to_socket(m_impl->socket_active, m_impl->magic_active);
2128         if (m_impl->surrounding_text) {
2129             free(m_impl->surrounding_text);
2130             m_impl->surrounding_text = NULL;
2131         }
2132
2133         const int WAIT_FOR_SYNC_RESPONSE_TIMEOUT = 1000;
2134         /* Now we are waiting for the ISM_TRANS_CMD_UPDATE_SURROUNDING_TEXT message */
2135         if (wait_for_message(ISM_TRANS_CMD_UPDATE_SURROUNDING_TEXT, WAIT_FOR_SYNC_RESPONSE_TIMEOUT)) {
2136             MessageItem *message = message_queue.get_pending_message_by_cmd(ISM_TRANS_CMD_UPDATE_SURROUNDING_TEXT);
2137             handle_message(message);
2138             message_queue.remove_message(message);
2139
2140             if (m_impl->surrounding_text) {
2141                 text = m_impl->surrounding_text;
2142                 cursor = m_impl->cursor_pos;
2143             }
2144         }
2145
2146         if (m_impl->surrounding_text) {
2147             free(m_impl->surrounding_text);
2148             m_impl->surrounding_text = NULL;
2149         }
2150     }
2151 }
2152
2153 /**
2154  * @brief Request to delete surrounding text.
2155  *
2156  * @param offset The offset for cursor position.
2157  * @param len The length for delete text.
2158  */
2159 void
2160 HelperAgent::delete_surrounding_text (int offset, int len) const
2161 {
2162     LOGD ("offset = %d, len = %d", offset, len);
2163
2164     if (m_impl->socket_active.is_connected ()) {
2165         m_impl->send.clear ();
2166         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2167         m_impl->send.put_data (m_impl->magic_active);
2168         m_impl->send.put_command (SCIM_TRANS_CMD_DELETE_SURROUNDING_TEXT);
2169         m_impl->send.put_data (offset);
2170         m_impl->send.put_data (len);
2171         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2172     }
2173 }
2174
2175 /**
2176  * @brief Request to get selection text asynchronously.
2177  *
2178  * @param uuid The helper ISE UUID.
2179  */
2180 void
2181 HelperAgent::get_selection (const String &uuid) const
2182 {
2183     if (m_impl->socket_active.is_connected () && (m_impl->need_update_selection_text == 0)) {
2184         m_impl->send.clear ();
2185         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2186         m_impl->send.put_data (m_impl->magic_active);
2187         m_impl->send.put_command (SCIM_TRANS_CMD_GET_SELECTION);
2188         m_impl->send.put_data (uuid);
2189         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2190     }
2191     m_impl->need_update_selection_text++;
2192 }
2193
2194 /**
2195  * @brief Request to get selection text synchronously.
2196  *
2197  * @param text The selection text.
2198  */
2199 void
2200 HelperAgent::get_selection_text (String &text)
2201 {
2202
2203     if (!m_impl->socket_active.is_connected ())
2204         return;
2205
2206     m_impl->send.clear ();
2207     m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2208     m_impl->send.put_data (m_impl->magic_active);
2209     m_impl->send.put_command (SCIM_TRANS_CMD_GET_SELECTION);
2210     m_impl->send.put_data ("");
2211     m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2212     if (m_impl->selection_text) {
2213         free (m_impl->selection_text);
2214         m_impl->selection_text = NULL;
2215     }
2216
2217     const int WAIT_FOR_SYNC_RESPONSE_TIMEOUT = 1000;
2218     /* Now we are waiting for the ISM_TRANS_CMD_UPDATE_SELECTION message */
2219     if (wait_for_message(ISM_TRANS_CMD_UPDATE_SELECTION, WAIT_FOR_SYNC_RESPONSE_TIMEOUT)) {
2220         MessageItem *message = message_queue.get_pending_message_by_cmd(ISM_TRANS_CMD_UPDATE_SELECTION);
2221         handle_message(message);
2222         message_queue.remove_message(message);
2223         if (m_impl->selection_text) {
2224             text = m_impl->selection_text;
2225         }
2226     }
2227
2228     if (m_impl->selection_text) {
2229         free (m_impl->selection_text);
2230         m_impl->selection_text = NULL;
2231     }
2232 }
2233
2234 /**
2235  * @brief Request to select text.
2236  *
2237  * @param start The start position in text.
2238  * @param end The end position in text.
2239  */
2240 void
2241 HelperAgent::set_selection (int start, int end) const
2242 {
2243     if (m_impl->socket_active.is_connected ()) {
2244         m_impl->send.clear ();
2245         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2246         m_impl->send.put_data (m_impl->magic_active);
2247         m_impl->send.put_command (SCIM_TRANS_CMD_SET_SELECTION);
2248         m_impl->send.put_data (start);
2249         m_impl->send.put_data (end);
2250         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2251     }
2252 }
2253
2254 /**
2255  * @brief Send a private command to an application.
2256  *
2257  * @param command The private command sent from IME.
2258  */
2259 void
2260 HelperAgent::send_private_command (const String &command) const
2261 {
2262     if (m_impl->socket_active.is_connected ()) {
2263         m_impl->send.clear ();
2264         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2265         m_impl->send.put_data (m_impl->magic_active);
2266         m_impl->send.put_command (SCIM_TRANS_CMD_SEND_PRIVATE_COMMAND);
2267         m_impl->send.put_data (command);
2268         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2269     }
2270 }
2271
2272 /**
2273  * @brief Commit content to an application.
2274  *
2275  * @param content The content sent from IME.
2276  */
2277 void
2278 HelperAgent::commit_content (const String &content, const String &description, const String &mime_types) const
2279 {
2280     LOGD ("");
2281     if (m_impl->socket_active.is_connected ()) {
2282         m_impl->send.clear ();
2283         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2284         m_impl->send.put_data (m_impl->magic_active);
2285         m_impl->send.put_command (SCIM_TRANS_CMD_COMMIT_CONTENT);
2286         m_impl->send.put_data (content);
2287         m_impl->send.put_data (description);
2288         m_impl->send.put_data (mime_types);
2289         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2290     }
2291 }
2292
2293 /**
2294  * @brief Request to get uuid list of all keyboard ISEs.
2295  *
2296  * @param uuid The helper ISE UUID.
2297  */
2298 void
2299 HelperAgent::get_keyboard_ise_list (const String &uuid) const
2300 {
2301     if (m_impl->socket_active.is_connected ()) {
2302         m_impl->send.clear ();
2303         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2304         m_impl->send.put_data (m_impl->magic_active);
2305         m_impl->send.put_command (ISM_TRANS_CMD_GET_KEYBOARD_ISE_LIST);
2306         m_impl->send.put_data (uuid);
2307         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2308     }
2309 }
2310
2311 /**
2312  * @brief Set candidate position in screen.
2313  *
2314  * @param left The x position in screen.
2315  * @param top The y position in screen.
2316  */
2317 void
2318 HelperAgent::set_candidate_position (int left, int top) const
2319 {
2320     if (m_impl->socket_active.is_connected ()) {
2321         m_impl->send.clear ();
2322         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2323         m_impl->send.put_data (m_impl->magic_active);
2324         m_impl->send.put_command (ISM_TRANS_CMD_SET_CANDIDATE_POSITION);
2325         m_impl->send.put_data (left);
2326         m_impl->send.put_data (top);
2327         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2328     }
2329 }
2330
2331 /**
2332  * @brief Set candidate style.
2333  *
2334  * @param portrait_line - the displayed line number for portrait mode.
2335  * @param mode          - candidate window mode.
2336  */
2337 void
2338 HelperAgent::set_candidate_style (ISF_CANDIDATE_PORTRAIT_LINE_T portrait_line,
2339                                   ISF_CANDIDATE_MODE_T          mode) const
2340 {
2341     if (m_impl->socket_active.is_connected ()) {
2342         m_impl->send.clear ();
2343         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2344         m_impl->send.put_data (m_impl->magic_active);
2345         m_impl->send.put_command (ISM_TRANS_CMD_SET_CANDIDATE_UI);
2346         m_impl->send.put_data (portrait_line);
2347         m_impl->send.put_data (mode);
2348         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2349     }
2350 }
2351
2352 /**
2353  * @brief Request to hide candidate window.
2354  */
2355 void
2356 HelperAgent::candidate_hide (void) const
2357 {
2358     if (m_impl->socket_active.is_connected ()) {
2359         m_impl->send.clear ();
2360         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2361         m_impl->send.put_data (m_impl->magic_active);
2362         m_impl->send.put_command (ISM_TRANS_CMD_HIDE_CANDIDATE);
2363         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2364     }
2365 }
2366
2367 /**
2368  * @brief Request to get candidate window size and position.
2369  *
2370  * @param uuid The helper ISE UUID.
2371  */
2372 void
2373 HelperAgent::get_candidate_window_geometry (const String &uuid) const
2374 {
2375     if (m_impl->socket_active.is_connected ()) {
2376         m_impl->send.clear ();
2377         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2378         m_impl->send.put_data (m_impl->magic_active);
2379         m_impl->send.put_command (ISM_TRANS_CMD_GET_CANDIDATE_GEOMETRY);
2380         m_impl->send.put_data (uuid);
2381         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2382     }
2383 }
2384
2385 /**
2386  * @brief Set current keyboard ISE.
2387  *
2388  * @param uuid The keyboard ISE UUID.
2389  */
2390 void
2391 HelperAgent::set_keyboard_ise_by_uuid (const String &uuid) const
2392 {
2393     ImeInfoDB imeInfo;
2394     IMEngineFactoryPointer factory;
2395     IMEngineModule *engine_module = NULL;
2396     static int instance_count = 1;
2397
2398     if ((!m_impl->si.null ()) && m_impl->si->get_factory_uuid () == uuid) {
2399         ISF_SAVE_LOG ("Already in UUID: %s", uuid.c_str());
2400         return;
2401     }
2402
2403     if (!m_impl->si.null()) {
2404         m_impl->si->focus_out();
2405         m_impl->si.reset();
2406     }
2407
2408     if (m_impl->m_config.null ()) {
2409         ISF_SAVE_LOG ("config is not working");
2410         return;
2411     }
2412
2413 #ifdef HAVE_PKGMGR_INFO
2414     int ret = 0;
2415     char *pkgid = NULL;
2416     pkgmgrinfo_appinfo_h handle;
2417     ret = pkgmgrinfo_appinfo_get_appinfo(uuid.c_str(), &handle);
2418     if (ret != PMINFO_R_OK) {
2419         ISF_SAVE_LOG ("Retrieve app info failed : %s", uuid.c_str ());
2420         return;
2421     }
2422
2423     ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
2424     if (ret != PMINFO_R_OK) {
2425         ISF_SAVE_LOG ("Retrieve pkgid failed : %s, %p", uuid.c_str(), handle);
2426         pkgmgrinfo_appinfo_destroy_appinfo(handle);
2427         return;
2428     }
2429
2430     imeInfo.module_name = pkgid;
2431     pkgmgrinfo_appinfo_destroy_appinfo(handle);
2432 #else
2433     if (isf_db_select_ime_info_by_appid(uuid.c_str(), &imeInfo) < 1) {
2434         ISF_SAVE_LOG ("ime_info row is not available for %s", uuid.c_str());
2435         return;
2436     }
2437 #endif
2438
2439     engine_module = &m_impl->engine_module;
2440
2441     if (engine_module->valid() && imeInfo.module_name != engine_module->get_module_name()) {
2442         ISF_SAVE_LOG ("imengine module %s unloaded", engine_module->get_module_name().c_str());
2443         engine_module->unload();
2444     }
2445
2446     if (!engine_module->valid()) {
2447         if (engine_module->load (imeInfo.module_name, m_impl->m_config) == false) {
2448             ISF_SAVE_LOG ("load module %s failed", imeInfo.module_name.c_str());
2449             return;
2450         }
2451         ISF_SAVE_LOG ("imengine module %s loaded", imeInfo.module_name.c_str());
2452     }
2453
2454     for (size_t j = 0; j < engine_module->number_of_factories (); ++j) {
2455         try {
2456             factory = engine_module->create_factory (j);
2457             if (factory.null () == false && factory->get_uuid () == uuid)
2458                 break;
2459         } catch (...) {
2460             factory.reset ();
2461             return;
2462         }
2463     }
2464
2465     if (factory.null()) {
2466         ISF_SAVE_LOG ("imengine uuid %s is not found", uuid.c_str());
2467         return;
2468     }
2469
2470     m_impl->si = factory->create_instance ("UTF-8", instance_count++);
2471     if (m_impl->si.null ()) {
2472         ISF_SAVE_LOG ("create_instance %s failed", uuid.c_str ());
2473         return;
2474     }
2475
2476     m_impl->attach_instance ();
2477     ISF_SAVE_LOG ("Require UUID: %s Current UUID: %s", uuid.c_str (), m_impl->si->get_factory_uuid ().c_str ());
2478     m_impl->si->set_layout (m_impl->layout);
2479     if (m_impl->focused_ic != (uint32)-1)
2480         m_impl->si->focus_in ();
2481 }
2482
2483 /**
2484  * @brief Request to get current keyboard ISE information.
2485  *
2486  * @param uuid The helper ISE UUID.
2487  */
2488 void
2489 HelperAgent::get_keyboard_ise (const String &uuid) const
2490 {
2491     //FIXME: maybe useless
2492 #if 0
2493     if (m_impl->socket_active.is_connected ()) {
2494         m_impl->send.clear ();
2495         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2496         m_impl->send.put_data (m_impl->magic_active);
2497         m_impl->send.put_command (ISM_TRANS_CMD_GET_KEYBOARD_ISE);
2498         m_impl->send.put_data (uuid);
2499         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2500     }
2501 #endif
2502 }
2503
2504 /**
2505  * @brief Update ISE window geometry.
2506  *
2507  * @param x      The x position in screen.
2508  * @param y      The y position in screen.
2509  * @param width  The ISE window width.
2510  * @param height The ISE window height.
2511  */
2512 void
2513 HelperAgent::update_geometry (int x, int y, int width, int height) const
2514 {
2515     if (m_impl->socket_active.is_connected ()) {
2516         m_impl->send.clear ();
2517         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2518         m_impl->send.put_data (m_impl->magic_active);
2519         m_impl->send.put_command (ISM_TRANS_CMD_UPDATE_ISE_GEOMETRY);
2520         m_impl->send.put_data (x);
2521         m_impl->send.put_data (y);
2522         m_impl->send.put_data (width);
2523         m_impl->send.put_data (height);
2524         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2525     }
2526 }
2527
2528 /**
2529  * @brief Request to expand candidate window.
2530  */
2531 void
2532 HelperAgent::expand_candidate (void) const
2533 {
2534     if (m_impl->socket_active.is_connected ()) {
2535         m_impl->send.clear ();
2536         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2537         m_impl->send.put_data (m_impl->magic_active);
2538         m_impl->send.put_command (ISM_TRANS_CMD_EXPAND_CANDIDATE);
2539         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2540     }
2541 }
2542
2543 /**
2544  * @brief Request to contract candidate window.
2545  */
2546 void
2547 HelperAgent::contract_candidate (void) const
2548 {
2549     if (m_impl->socket_active.is_connected ()) {
2550         m_impl->send.clear ();
2551         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2552         m_impl->send.put_data (m_impl->magic_active);
2553         m_impl->send.put_command (ISM_TRANS_CMD_CONTRACT_CANDIDATE);
2554         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2555     }
2556 }
2557
2558 /**
2559  * @brief Send selected candidate string index number.
2560  */
2561 void
2562 HelperAgent::select_candidate (int index) const
2563 {
2564     if (!m_impl->si.null ())
2565         m_impl->si->select_candidate (index);
2566     //FIXME: maybe useless
2567 #if 0
2568
2569     if (m_impl->socket_active.is_connected ()) {
2570         m_impl->send.clear ();
2571         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2572         m_impl->send.put_data (m_impl->magic_active);
2573         m_impl->send.put_command (ISM_TRANS_CMD_SELECT_CANDIDATE);
2574         m_impl->send.put_data (index);
2575         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2576     }
2577 #endif
2578 }
2579
2580 /**
2581  * @brief Update our ISE is exiting.
2582  *
2583  * The IME must call this function before terminating IME itself in On-demand mode.
2584  * If this function isn't called, IME will automatically restart.
2585  * This function only works in On-demand mode.
2586  *
2587  */
2588 void
2589 HelperAgent::update_ise_exit (void) const
2590 {
2591     if (m_impl->socket_active.is_connected ()) {
2592         m_impl->send.clear ();
2593         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2594         m_impl->send.put_data (m_impl->magic_active);
2595         m_impl->send.put_command (ISM_TRANS_CMD_UPDATE_ISE_EXIT);
2596         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2597
2598         // The update_ise_exit must be delivered before del_client of isf_info_manager was called.
2599         sync();
2600     }
2601 }
2602
2603 /**
2604  * @brief Request to reset keyboard ISE.
2605  */
2606 void
2607 HelperAgent::reset_keyboard_ise (void) const
2608 {
2609 //FIXME: maybe useless
2610 #if 0
2611     if (m_impl->socket_active.is_connected ()) {
2612         m_impl->send.clear ();
2613         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2614         m_impl->send.put_data (m_impl->magic_active);
2615         m_impl->send.put_command (ISM_TRANS_CMD_PANEL_RESET_KEYBOARD_ISE);
2616         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2617     }
2618 #endif
2619     if (!m_impl->si.null ()) {
2620         m_impl->si->reset ();
2621     }
2622 }
2623
2624 /**
2625  * @brief Request to flush keyboard ISE.
2626  */
2627 void
2628 HelperAgent::flush_keyboard_ise (void) const
2629 {
2630     if (!m_impl->si.null ()) {
2631         m_impl->si->flush ();
2632     }
2633 }
2634
2635 /**
2636  * @brief Request panel to hide ISE.
2637  */
2638 void
2639 HelperAgent::request_ise_hide (void) const
2640 {
2641     if (m_impl->socket_active.is_connected ()) {
2642         m_impl->send.clear ();
2643         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2644         m_impl->send.put_data (m_impl->magic_active);
2645         m_impl->send.put_command (ISM_TRANS_CMD_REQUEST_ISE_HIDE);
2646         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2647     }
2648 }
2649
2650 /**
2651  * @brief Recapture
2652  */
2653 void
2654 HelperAgent::recapture_string (int                  ic,
2655                                const String        &ic_uuid,
2656                                int                  offset,
2657                                int                  len,
2658                                const WideString    &preedit_str,
2659                                const WideString    &commit_str,
2660                                const AttributeList &attrs) const
2661 {
2662     LOGD ("offset = %d, len = %d", offset, len);
2663
2664     if (m_impl->socket_active.is_connected ()) {
2665         m_impl->send.clear ();
2666         m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
2667         m_impl->send.put_data (m_impl->magic_active);
2668         m_impl->send.put_command (ISM_TRANS_CMD_RECAPTURE_STRING);
2669
2670         m_impl->send.put_data ((uint32)ic);
2671         m_impl->send.put_data (ic_uuid);
2672
2673         // Deleting surrounding text
2674         m_impl->send.put_data (offset);
2675         m_impl->send.put_data (len);
2676
2677         // Update preedit text
2678         m_impl->send.put_data (preedit_str);
2679
2680         // Commit
2681         m_impl->send.put_data (commit_str);
2682
2683         // preedit attributes
2684         m_impl->send.put_data (attrs);
2685
2686         m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
2687     }
2688 }
2689
2690 /**
2691  * @brief Connect a slot to Helper exit signal.
2692  *
2693  * This signal is used to let the Helper exit.
2694  *
2695  * The prototype of the slot is:
2696  *
2697  * void exit (const HelperAgent *agent, int ic, const String &ic_uuid);
2698  *
2699  * Parameters:
2700  * - agent    The pointer to the HelperAgent object which emits this signal.
2701  * - ic       An opaque handle of the currently focused input context.
2702  * - ic_uuid  The UUID of the IMEngineInstance associated with the focused input context.
2703  */
2704 Connection
2705 HelperAgent::signal_connect_exit (HelperAgentSlotVoid *slot)
2706 {
2707     return m_impl->signal_exit.connect (slot);
2708 }
2709
2710 /**
2711  * @brief Connect a slot to Helper attach input context signal.
2712  *
2713  * This signal is used to attach an input context to this helper.
2714  *
2715  * When an input context requst to start this helper, then this
2716  * signal will be emitted as soon as the helper is started.
2717  *
2718  * When an input context want to start an already started helper,
2719  * this signal will also be emitted.
2720  *
2721  * Helper can send some events back to the IMEngineInstance in this
2722  * signal-slot, to inform that it has been started sccessfully.
2723  *
2724  * The prototype of the slot is:
2725  *
2726  * void attach_input_context (const HelperAgent *agent, int ic, const String &ic_uuid);
2727  */
2728 Connection
2729 HelperAgent::signal_connect_attach_input_context (HelperAgentSlotVoid *slot)
2730 {
2731     return m_impl->signal_attach_input_context.connect (slot);
2732 }
2733
2734 /**
2735  * @brief Connect a slot to Helper detach input context signal.
2736  *
2737  * This signal is used to detach an input context from this helper.
2738  *
2739  * When an input context requst to stop this helper, then this
2740  * signal will be emitted.
2741  *
2742  * Helper shouldn't send any event back to the IMEngineInstance, because
2743  * the IMEngineInstance attached to the ic should have been destroyed.
2744  *
2745  * The prototype of the slot is:
2746  *
2747  * void detach_input_context (const HelperAgent *agent, int ic, const String &ic_uuid);
2748  */
2749 Connection
2750 HelperAgent::signal_connect_detach_input_context (HelperAgentSlotVoid *slot)
2751 {
2752     return m_impl->signal_detach_input_context.connect (slot);
2753 }
2754
2755 /**
2756  * @brief Connect a slot to Helper reload config signal.
2757  *
2758  * This signal is used to let the Helper reload configuration.
2759  *
2760  * The prototype of the slot is:
2761  *
2762  * void reload_config (const HelperAgent *agent, int ic, const String &ic_uuid);
2763  */
2764 Connection
2765 HelperAgent::signal_connect_reload_config (HelperAgentSlotVoid *slot)
2766 {
2767     return m_impl->signal_reload_config.connect (slot);
2768 }
2769
2770 /**
2771  * @brief Connect a slot to Helper update screen signal.
2772  *
2773  * This signal is used to let the Helper move its GUI to another screen.
2774  * It can only be emitted when SCIM_HELPER_NEED_SCREEN_INFO is set in HelperInfo.option.
2775  *
2776  * The prototype of the slot is:
2777  *
2778  * void update_screen (const HelperAgent *agent, int ic, const String &ic_uuid, int screen_number);
2779  */
2780 Connection
2781 HelperAgent::signal_connect_update_screen (HelperAgentSlotInt *slot)
2782 {
2783     return m_impl->signal_update_screen.connect (slot);
2784 }
2785
2786 /**
2787  * @brief Connect a slot to Helper update spot location signal.
2788  *
2789  * This signal is used to let the Helper move its GUI according to the current spot location.
2790  * It can only be emitted when SCIM_HELPER_NEED_SPOT_LOCATION_INFO is set in HelperInfo.option.
2791  *
2792  * The prototype of the slot is:
2793  * void update_spot_location (const HelperAgent *agent, int ic, const String &ic_uuid, int x, int y);
2794  */
2795 Connection
2796 HelperAgent::signal_connect_update_spot_location (HelperAgentSlotIntInt *slot)
2797 {
2798     return m_impl->signal_update_spot_location.connect (slot);
2799 }
2800
2801 /**
2802  * @brief Connect a slot to Helper update cursor position signal.
2803  *
2804  * This signal is used to let the Helper get the cursor position information.
2805  *
2806  * The prototype of the slot is:
2807  * void update_cursor_position (const HelperAgent *agent, int ic, const String &ic_uuid, int cursor_pos);
2808  */
2809 Connection
2810 HelperAgent::signal_connect_update_cursor_position (HelperAgentSlotInt *slot)
2811 {
2812     return m_impl->signal_update_cursor_position.connect (slot);
2813 }
2814
2815 /**
2816  * @brief Connect a slot to Helper update surrounding text signal.
2817  *
2818  * This signal is used to let the Helper get the surrounding text.
2819  *
2820  * The prototype of the slot is:
2821  * void update_surrounding_text (const HelperAgent *agent, int ic, const String &text, int cursor);
2822  */
2823 Connection
2824 HelperAgent::signal_connect_update_surrounding_text (HelperAgentSlotInt *slot)
2825 {
2826     return m_impl->signal_update_surrounding_text.connect (slot);
2827 }
2828
2829 /**
2830  * @brief Connect a slot to Helper update selection signal.
2831  *
2832  * This signal is used to let the Helper get the selection.
2833  *
2834  * The prototype of the slot is:
2835  * void update_selection (const HelperAgent *agent, int ic, const String &text);
2836  */
2837 Connection
2838 HelperAgent::signal_connect_update_selection (HelperAgentSlotVoid *slot)
2839 {
2840     return m_impl->signal_update_selection.connect (slot);
2841 }
2842
2843 /**
2844  * @brief Connect a slot to Helper trigger property signal.
2845  *
2846  * This signal is used to trigger a property registered by this Helper.
2847  * A property will be triggered when user clicks on it.
2848  *
2849  * The prototype of the slot is:
2850  * void trigger_property (const HelperAgent *agent, int ic, const String &ic_uuid, const String &property);
2851  */
2852 Connection
2853 HelperAgent::signal_connect_trigger_property (HelperAgentSlotString *slot)
2854 {
2855     return m_impl->signal_trigger_property.connect (slot);
2856 }
2857
2858 /**
2859  * @brief Connect a slot to Helper process imengine event signal.
2860  *
2861  * This signal is used to deliver the events sent from IMEngine to Helper.
2862  *
2863  * The prototype of the slot is:
2864  * void process_imengine_event (const HelperAgent *agent, int ic, const String &ic_uuid, const Transaction &transaction);
2865  */
2866 Connection
2867 HelperAgent::signal_connect_process_imengine_event (HelperAgentSlotTransaction *slot)
2868 {
2869     return m_impl->signal_process_imengine_event.connect (slot);
2870 }
2871
2872 /**
2873  * @brief Connect a slot to Helper focus out signal.
2874  *
2875  * This signal is used to do something when input context is focus out.
2876  *
2877  * The prototype of the slot is:
2878  * void focus_out (const HelperAgent *agent, int ic, const String &ic_uuid);
2879  */
2880 Connection
2881 HelperAgent::signal_connect_focus_out (HelperAgentSlotVoid *slot)
2882 {
2883     return m_impl->signal_focus_out.connect (slot);
2884 }
2885
2886 /**
2887  * @brief Connect a slot to Helper focus in signal.
2888  *
2889  * This signal is used to do something when input context is focus in.
2890  *
2891  * The prototype of the slot is:
2892  * void focus_in (const HelperAgent *agent, int ic, const String &ic_uuid);
2893  */
2894 Connection
2895 HelperAgent::signal_connect_focus_in (HelperAgentSlotVoid *slot)
2896 {
2897     return m_impl->signal_focus_in.connect (slot);
2898 }
2899
2900 /**
2901  * @brief Connect a slot to Helper show signal.
2902  *
2903  * This signal is used to show Helper ISE window.
2904  *
2905  * The prototype of the slot is:
2906  * void ise_show (const HelperAgent *agent, int ic, char *buf, size_t &len);
2907  */
2908 Connection
2909 HelperAgent::signal_connect_ise_show (HelperAgentSlotIntRawVoid *slot)
2910 {
2911     return m_impl->signal_ise_show.connect (slot);
2912 }
2913
2914 /**
2915  * @brief Connect a slot to Helper hide signal.
2916  *
2917  * This signal is used to hide Helper ISE window.
2918  *
2919  * The prototype of the slot is:
2920  * void ise_hide (const HelperAgent *agent, int ic, const String &ic_uuid);
2921  */
2922 Connection
2923 HelperAgent::signal_connect_ise_hide (HelperAgentSlotVoid *slot)
2924 {
2925     return m_impl->signal_ise_hide.connect (slot);
2926 }
2927
2928 /**
2929  * @brief Connect a slot to Helper get ISE window geometry signal.
2930  *
2931  * This signal is used to get Helper ISE window size and position.
2932  *
2933  * The prototype of the slot is:
2934  * void get_geometry (const HelperAgent *agent, struct rectinfo &info);
2935  */
2936 Connection
2937 HelperAgent::signal_connect_get_geometry (HelperAgentSlotSize *slot)
2938 {
2939     return m_impl->signal_get_geometry.connect (slot);
2940 }
2941
2942 /**
2943  * @brief Connect a slot to Helper set mode signal.
2944  *
2945  * This signal is used to set Helper ISE mode.
2946  *
2947  * The prototype of the slot is:
2948  * void set_mode (const HelperAgent *agent, uint32 &mode);
2949  */
2950 Connection
2951 HelperAgent::signal_connect_set_mode (HelperAgentSlotUintVoid *slot)
2952 {
2953     return m_impl->signal_set_mode.connect (slot);
2954 }
2955
2956 /**
2957  * @brief Connect a slot to Helper set language signal.
2958  *
2959  * This signal is used to set Helper ISE language.
2960  *
2961  * The prototype of the slot is:
2962  * void set_language (const HelperAgent *agent, uint32 &language);
2963  */
2964 Connection
2965 HelperAgent::signal_connect_set_language (HelperAgentSlotUintVoid *slot)
2966 {
2967     return m_impl->signal_set_language.connect (slot);
2968 }
2969
2970 /**
2971  * @brief Connect a slot to Helper set im data signal.
2972  *
2973  * This signal is used to send im data to Helper ISE.
2974  *
2975  * The prototype of the slot is:
2976  * void set_imdata (const HelperAgent *agent, char *buf, size_t &len);
2977  */
2978 Connection
2979 HelperAgent::signal_connect_set_imdata (HelperAgentSlotRawVoid *slot)
2980 {
2981     return m_impl->signal_set_imdata.connect (slot);
2982 }
2983
2984 /**
2985  * @brief Connect a slot to Helper get im data signal.
2986  *
2987  * This signal is used to get im data from Helper ISE.
2988  *
2989  * The prototype of the slot is:
2990  * void get_imdata (const HelperAgent *, char **buf, size_t &len);
2991  */
2992 Connection
2993 HelperAgent::signal_connect_get_imdata (HelperAgentSlotGetRawVoid *slot)
2994 {
2995     return m_impl->signal_get_imdata.connect (slot);
2996 }
2997
2998 /**
2999  * @brief Connect a slot to Helper get language locale signal.
3000  *
3001  * This signal is used to get language locale from Helper ISE.
3002  *
3003  * The prototype of the slot is:
3004  * void get_language_locale (const HelperAgent *, int ic, char **locale);
3005  */
3006 Connection
3007 HelperAgent::signal_connect_get_language_locale (HelperAgentSlotIntGetStringVoid *slot)
3008 {
3009     return m_impl->signal_get_language_locale.connect (slot);
3010 }
3011
3012 /**
3013  * @brief Connect a slot to Helper set return key type signal.
3014  *
3015  * This signal is used to send return key type to Helper ISE.
3016  *
3017  * The prototype of the slot is:
3018  * void set_return_key_type (const HelperAgent *agent, uint32 &type);
3019  */
3020 Connection
3021 HelperAgent::signal_connect_set_return_key_type (HelperAgentSlotUintVoid *slot)
3022 {
3023     return m_impl->signal_set_return_key_type.connect (slot);
3024 }
3025
3026 /**
3027  * @brief Connect a slot to Helper get return key type signal.
3028  *
3029  * This signal is used to get return key type from Helper ISE.
3030  *
3031  * The prototype of the slot is:
3032  * void get_return_key_type (const HelperAgent *agent, uint32 &type);
3033  */
3034 Connection
3035 HelperAgent::signal_connect_get_return_key_type (HelperAgentSlotUintVoid *slot)
3036 {
3037     return m_impl->signal_get_return_key_type.connect (slot);
3038 }
3039
3040 /**
3041  * @brief Connect a slot to Helper set return key disable signal.
3042  *
3043  * This signal is used to send return key disable to Helper ISE.
3044  *
3045  * The prototype of the slot is:
3046  * void set_return_key_disable (const HelperAgent *agent, uint32 &disabled);
3047  */
3048 Connection
3049 HelperAgent::signal_connect_set_return_key_disable (HelperAgentSlotUintVoid *slot)
3050 {
3051     return m_impl->signal_set_return_key_disable.connect (slot);
3052 }
3053
3054 /**
3055  * @brief Connect a slot to Helper process key event signal.
3056  *
3057  * This signal is used to send keyboard key event to Helper ISE.
3058  *
3059  * The prototype of the slot is:
3060  * void process_key_event (const HelperAgent *agent, KeyEvent &key, uint32 &ret);
3061  */
3062 Connection
3063 HelperAgent::signal_connect_process_key_event (HelperAgentSlotKeyEventUint *slot)
3064 {
3065     return m_impl->signal_process_key_event.connect (slot);
3066 }
3067
3068 /**
3069  * @brief Connect a slot to Helper process key event with keycode signal.
3070  *
3071  * This signal is used to send keyboard key event with keycode to Helper ISE.
3072  *
3073  * The prototype of the slot is:
3074  * void process_key_event_with_keycode (const HelperAgent *agent, KeyEvent &key, uint32 &ret, uint32 keycode);
3075  */
3076 Connection
3077 HelperAgent::signal_connect_process_key_event_with_keycode (HelperAgentSlotKeyEventUintUint *slot)
3078 {
3079     return m_impl->signal_process_key_event_with_keycode.connect (slot);
3080 }
3081
3082 /**
3083  * @brief Connect a slot to Helper get return key disable signal.
3084  *
3085  * This signal is used to get return key disable from Helper ISE.
3086  *
3087  * The prototype of the slot is:
3088  * void get_return_key_disable (const HelperAgent *agent, uint32 &disabled);
3089  */
3090 Connection
3091 HelperAgent::signal_connect_get_return_key_disable (HelperAgentSlotUintVoid *slot)
3092 {
3093     return m_impl->signal_get_return_key_disable.connect (slot);
3094 }
3095
3096 /**
3097  * @brief Connect a slot to Helper set layout signal.
3098  *
3099  * This signal is used to set Helper ISE layout.
3100  *
3101  * The prototype of the slot is:
3102  * void set_layout (const HelperAgent *agent, uint32 &layout);
3103  */
3104 Connection
3105 HelperAgent::signal_connect_set_layout (HelperAgentSlotUintVoid *slot)
3106 {
3107     return m_impl->signal_set_layout.connect (slot);
3108 }
3109
3110 /**
3111  * @brief Connect a slot to Helper get layout signal.
3112  *
3113  * This signal is used to get Helper ISE layout.
3114  *
3115  * The prototype of the slot is:
3116  * void get_layout (const HelperAgent *agent, uint32 &layout);
3117  */
3118 Connection
3119 HelperAgent::signal_connect_get_layout (HelperAgentSlotUintVoid *slot)
3120 {
3121     return m_impl->signal_get_layout.connect (slot);
3122 }
3123
3124 /**
3125  * @brief Connect a slot to Helper set input mode signal.
3126  *
3127  * This signal is used to set Helper ISE input mode.
3128  *
3129  * The prototype of the slot is:
3130  * void set_input_mode (const HelperAgent *agent, uint32 &input_mode);
3131  */
3132 Connection
3133 HelperAgent::signal_connect_set_input_mode (HelperAgentSlotUintVoid *slot)
3134 {
3135     return m_impl->signal_set_input_mode.connect (slot);
3136 }
3137
3138 /**
3139  * @brief Connect a slot to Helper set input hint signal.
3140  *
3141  * This signal is used to set Helper ISE input hint.
3142  *
3143  * The prototype of the slot is:
3144  * void set_input_hint (const HelperAgent *agent, uint32 &input_hint);
3145  */
3146 Connection
3147 HelperAgent::signal_connect_set_input_hint (HelperAgentSlotUintVoid *slot)
3148 {
3149     return m_impl->signal_set_input_hint.connect (slot);
3150 }
3151
3152 /**
3153  * @brief Connect a slot to Helper set BiDi direction signal.
3154  *
3155  * This signal is used to set Helper ISE BiDi direction.
3156  *
3157  * The prototype of the slot is:
3158  * void update_bidi_direction (const HelperAgent *agent, uint32 &bidi_direction);
3159  */
3160 Connection
3161 HelperAgent::signal_connect_update_bidi_direction (HelperAgentSlotUintVoid *slot)
3162 {
3163     return m_impl->signal_update_bidi_direction.connect (slot);
3164 }
3165
3166 /**
3167  * @brief Connect a slot to Helper set shift mode signal.
3168  *
3169  * This signal is used to set Helper shift mode.
3170  *
3171  * The prototype of the slot is:
3172  * void set_caps_mode (const HelperAgent *agent, uint32 &mode);
3173  */
3174 Connection
3175 HelperAgent::signal_connect_set_caps_mode (HelperAgentSlotUintVoid *slot)
3176 {
3177     return m_impl->signal_set_caps_mode.connect (slot);
3178 }
3179
3180 /**
3181  * @brief Connect a slot to Helper reset input context signal.
3182  *
3183  * This signal is used to reset Helper ISE input context.
3184  *
3185  * The prototype of the slot is:
3186  * void reset_input_context (const HelperAgent *agent, int ic, const String &uuid);
3187  */
3188 Connection
3189 HelperAgent::signal_connect_reset_input_context (HelperAgentSlotVoid *slot)
3190 {
3191     return m_impl->signal_reset_input_context.connect (slot);
3192 }
3193
3194 /**
3195  * @brief Connect a slot to Helper update candidate window geometry signal.
3196  *
3197  * This signal is used to get candidate window size and position.
3198  *
3199  * The prototype of the slot is:
3200  * void update_candidate_geometry (const HelperAgent *agent, int ic, const String &uuid, const rectinfo &info);
3201  */
3202 Connection
3203 HelperAgent::signal_connect_update_candidate_geometry (HelperAgentSlotRect *slot)
3204 {
3205     return m_impl->signal_update_candidate_geometry.connect (slot);
3206 }
3207
3208 /**
3209  * @brief Connect a slot to Helper update keyboard ISE signal.
3210  *
3211  * This signal is used to get current keyboard ISE name and uuid.
3212  *
3213  * The prototype of the slot is:
3214  * void update_keyboard_ise (const HelperAgent *agent, int ic, const String &uuid,
3215  *                           const String &ise_name, const String &ise_uuid);
3216  */
3217 Connection
3218 HelperAgent::signal_connect_update_keyboard_ise (HelperAgentSlotString2 *slot)
3219 {
3220     return m_impl->signal_update_keyboard_ise.connect (slot);
3221 }
3222
3223 /**
3224  * @brief Connect a slot to Helper update keyboard ISE list signal.
3225  *
3226  * This signal is used to get uuid list of all keyboard ISEs.
3227  *
3228  * The prototype of the slot is:
3229  * void update_keyboard_ise_list (const HelperAgent *agent, int ic, const String &uuid,
3230  *                                const std::vector<String> &ise_list);
3231  */
3232 Connection
3233 HelperAgent::signal_connect_update_keyboard_ise_list (HelperAgentSlotStringVector *slot)
3234 {
3235     return m_impl->signal_update_keyboard_ise_list.connect (slot);
3236 }
3237
3238 /**
3239  * @brief Connect a slot to Helper candidate more window show signal.
3240  *
3241  * This signal is used to do someting when candidate more window is showed.
3242  *
3243  * The prototype of the slot is:
3244  * void candidate_more_window_show (const HelperAgent *agent, int ic, const String &uuid);
3245  */
3246 Connection
3247 HelperAgent::signal_connect_candidate_more_window_show (HelperAgentSlotVoid *slot)
3248 {
3249     return m_impl->signal_candidate_more_window_show.connect (slot);
3250 }
3251
3252 /**
3253  * @brief Connect a slot to Helper candidate more window hide signal.
3254  *
3255  * This signal is used to do someting when candidate more window is hidden.
3256  *
3257  * The prototype of the slot is:
3258  * void candidate_more_window_hide (const HelperAgent *agent, int ic, const String &uuid);
3259  */
3260 Connection
3261 HelperAgent::signal_connect_candidate_more_window_hide (HelperAgentSlotVoid *slot)
3262 {
3263     return m_impl->signal_candidate_more_window_hide.connect (slot);
3264 }
3265
3266 /**
3267  * @brief Connect a slot to Helper candidate show signal.
3268  *
3269  * This signal is used to do candidate show.
3270  *
3271  * The prototype of the slot is:
3272  * void candidate_show (const HelperAgent *agent, int ic, const String &uuid);
3273  */
3274 Connection
3275 HelperAgent::signal_connect_candidate_show (HelperAgentSlotVoid *slot)
3276 {
3277     return m_impl->signal_candidate_show.connect (slot);
3278 }
3279
3280 /**
3281  * @brief Connect a slot to Helper candidate hide signal.
3282  *
3283  * This signal is used to do candidate hide.
3284  *
3285  * The prototype of the slot is:
3286  * void candidate_hide (const HelperAgent *agent, int ic, const String &uuid);
3287  */
3288 Connection
3289 HelperAgent::signal_connect_candidate_hide (HelperAgentSlotVoid *slot)
3290 {
3291     return m_impl->signal_candidate_hide.connect (slot);
3292 }
3293
3294 /**
3295  * @brief Connect a slot to Helper update lookup table signal.
3296  *
3297  * This signal is used to do someting when update lookup table.
3298  *
3299  * The prototype of the slot is:
3300  * void update_lookup_table (const HelperAgent *agent, int ic, const String &uuid ,LookupTable &table);
3301  */
3302 Connection
3303 HelperAgent::signal_connect_update_lookup_table (HelperAgentSlotLookupTable *slot)
3304 {
3305     return m_impl->signal_update_lookup_table.connect (slot);
3306 }
3307
3308 /**
3309  * @brief Connect a slot to Helper select aux signal.
3310  *
3311  * This signal is used to do something when aux is selected.
3312  *
3313  * The prototype of the slot is:
3314  * void select_aux (const HelperAgent *agent, int ic, const String &uuid, int index);
3315  */
3316 Connection
3317 HelperAgent::signal_connect_select_aux (HelperAgentSlotInt *slot)
3318 {
3319     return m_impl->signal_select_aux.connect (slot);
3320 }
3321
3322 /**
3323  * @brief Connect a slot to Helper select candidate signal.
3324  *
3325  * This signal is used to do something when candidate is selected.
3326  *
3327  * The prototype of the slot is:
3328  * void select_candidate (const HelperAgent *agent, int ic, const String &uuid, int index);
3329  */
3330 Connection
3331 HelperAgent::signal_connect_select_candidate (HelperAgentSlotInt *slot)
3332 {
3333     return m_impl->signal_select_candidate.connect (slot);
3334 }
3335
3336 /**
3337  * @brief Connect a slot to Helper candidate table page up signal.
3338  *
3339  * This signal is used to do something when candidate table is paged up.
3340  *
3341  * The prototype of the slot is:
3342  * void candidate_table_page_up (const HelperAgent *agent, int ic, const String &uuid);
3343  */
3344 Connection
3345 HelperAgent::signal_connect_candidate_table_page_up (HelperAgentSlotVoid *slot)
3346 {
3347     return m_impl->signal_candidate_table_page_up.connect (slot);
3348 }
3349
3350 /**
3351  * @brief Connect a slot to Helper candidate table page down signal.
3352  *
3353  * This signal is used to do something when candidate table is paged down.
3354  *
3355  * The prototype of the slot is:
3356  * void candidate_table_page_down (const HelperAgent *agent, int ic, const String &uuid);
3357  */
3358 Connection
3359 HelperAgent::signal_connect_candidate_table_page_down (HelperAgentSlotVoid *slot)
3360 {
3361     return m_impl->signal_candidate_table_page_down.connect (slot);
3362 }
3363
3364 /**
3365  * @brief Connect a slot to Helper update candidate table page size signal.
3366  *
3367  * This signal is used to do something when candidate table page size is changed.
3368  *
3369  * The prototype of the slot is:
3370  * void update_candidate_table_page_size (const HelperAgent *, int ic, const String &uuid, int page_size);
3371  */
3372 Connection
3373 HelperAgent::signal_connect_update_candidate_table_page_size (HelperAgentSlotInt *slot)
3374 {
3375     return m_impl->signal_update_candidate_table_page_size.connect (slot);
3376 }
3377
3378 /**
3379  * @brief Connect a slot to Helper update candidate item layout signal.
3380  *
3381  * The prototype of the slot is:
3382  * void update_candidate_item_layout (const HelperAgent *, const std::vector<uint32> &row_items);
3383  */
3384 Connection
3385 HelperAgent::signal_connect_update_candidate_item_layout (HelperAgentSlotUintVector *slot)
3386 {
3387     return m_impl->signal_update_candidate_item_layout.connect (slot);
3388 }
3389
3390 /**
3391  * @brief Connect a slot to Helper select associate signal.
3392  *
3393  * This signal is used to do something when associate is selected.
3394  *
3395  * The prototype of the slot is:
3396  * void select_associate (const HelperAgent *agent, int ic, const String &uuid, int index);
3397  */
3398 Connection
3399 HelperAgent::signal_connect_select_associate (HelperAgentSlotInt *slot)
3400 {
3401     return m_impl->signal_select_associate.connect (slot);
3402 }
3403
3404 /**
3405  * @brief Connect a slot to Helper associate table page up signal.
3406  *
3407  * This signal is used to do something when associate table is paged up.
3408  *
3409  * The prototype of the slot is:
3410  * void associate_table_page_up (const HelperAgent *agent, int ic, const String &uuid);
3411  */
3412 Connection
3413 HelperAgent::signal_connect_associate_table_page_up (HelperAgentSlotVoid *slot)
3414 {
3415     return m_impl->signal_associate_table_page_up.connect (slot);
3416 }
3417
3418 /**
3419  * @brief Connect a slot to Helper associate table page down signal.
3420  *
3421  * This signal is used to do something when associate table is paged down.
3422  *
3423  * The prototype of the slot is:
3424  * void associate_table_page_down (const HelperAgent *agent, int ic, const String &uuid);
3425  */
3426 Connection
3427 HelperAgent::signal_connect_associate_table_page_down (HelperAgentSlotVoid *slot)
3428 {
3429     return m_impl->signal_associate_table_page_down.connect (slot);
3430 }
3431
3432 /**
3433  * @brief Connect a slot to Helper update associate table page size signal.
3434  *
3435  * This signal is used to do something when associate table page size is changed.
3436  *
3437  * The prototype of the slot is:
3438  * void update_associate_table_page_size (const HelperAgent *, int ic, const String &uuid, int page_size);
3439  */
3440 Connection
3441 HelperAgent::signal_connect_update_associate_table_page_size (HelperAgentSlotInt *slot)
3442 {
3443     return m_impl->signal_update_associate_table_page_size.connect (slot);
3444 }
3445
3446 /**
3447  * @brief Connect a slot to Helper turn on log signal.
3448  *
3449  * This signal is used to turn on Helper ISE debug information.
3450  *
3451  * The prototype of the slot is:
3452  * void turn_on_log (const HelperAgent *agent, uint32 &on);
3453  */
3454 Connection
3455 HelperAgent::signal_connect_turn_on_log (HelperAgentSlotUintVoid *slot)
3456 {
3457     return m_impl->signal_turn_on_log.connect (slot);
3458 }
3459
3460 /**
3461  * @brief Connect a slot to Helper update displayed candidate number signal.
3462  *
3463  * This signal is used to inform helper ISE displayed candidate number.
3464  *
3465  * The prototype of the slot is:
3466  * void update_displayed_candidate_number (const HelperAgent *, int ic, const String &uuid, int number);
3467  */
3468 Connection
3469 HelperAgent::signal_connect_update_displayed_candidate_number (HelperAgentSlotInt *slot)
3470 {
3471     return m_impl->signal_update_displayed_candidate_number.connect (slot);
3472 }
3473
3474 /**
3475  * @brief Connect a slot to Helper longpress candidate signal.
3476  *
3477  * This signal is used to do something when candidate is longpress.
3478  *
3479  * The prototype of the slot is:
3480  * void longpress_candidate (const HelperAgent *agent, int ic, const String &uuid, int index);
3481  */
3482 Connection
3483 HelperAgent::signal_connect_longpress_candidate (HelperAgentSlotInt *slot)
3484 {
3485     return m_impl->signal_longpress_candidate.connect (slot);
3486 }
3487
3488 /**
3489  * @brief Connect a slot to Helper show option window.
3490  *
3491  * This signal is used to do request the ISE to show option window.
3492  *
3493  * The prototype of the slot is:
3494  * void show_option_window (const HelperAgent *agent, int ic, const String &uuid);
3495  */
3496 Connection
3497 HelperAgent::signal_connect_show_option_window (HelperAgentSlotVoid *slot)
3498 {
3499     return m_impl->signal_show_option_window.connect (slot);
3500 }
3501
3502 /**
3503  * @brief Connect a slot to Helper resume option window.
3504  *
3505  * This signal is used to do request the ISE to resume option window.
3506  *
3507  * The prototype of the slot is:
3508  * void resume_option_window (const HelperAgent *agent, int ic, const String &uuid);
3509  */
3510 Connection
3511 HelperAgent::signal_connect_resume_option_window (HelperAgentSlotVoid *slot)
3512 {
3513     return m_impl->signal_resume_option_window.connect (slot);
3514 }
3515
3516 /**
3517  * @brief Connect a slot to Helper check if the option is available.
3518  *
3519  * This signal is used to check if the option (setting) is available from Helper ISE.
3520  *
3521  * The prototype of the slot is:
3522  * void check_option_window (const HelperAgent *agent, uint32 &avail);
3523  */
3524 Connection
3525 HelperAgent::signal_connect_check_option_window (HelperAgentSlotUintVoid *slot)
3526 {
3527     return m_impl->signal_check_option_window.connect (slot);
3528 }
3529
3530 /**
3531  * @brief Connect a slot to Helper process unconventional input device event signal.
3532  *
3533  * This signal is used to send unconventional input device event to Helper ISE.
3534  *
3535  * The prototype of the slot is:
3536  * void process_input_device_event (const HelperAgent *, uint32 &type, char *data, size_t &size, uint32 &ret);
3537  */
3538 Connection
3539 HelperAgent::signal_connect_process_input_device_event (HelperAgentSlotUintCharSizeUint *slot)
3540 {
3541     return m_impl->signal_process_input_device_event.connect (slot);
3542 }
3543
3544 /**
3545  * @brief Connect a slot to Helper set prediction hint signal.
3546  *
3547  * This signal is used to send prediction hint to Helper ISE.
3548  *
3549  * The prototype of the slot is:
3550  * void set_prediction_hint (const HelperAgent *agent, char *prediction_hint);
3551  */
3552 Connection
3553 HelperAgent::signal_connect_set_prediction_hint (HelperAgentSlotStringVoid *slot)
3554 {
3555     return m_impl->signal_set_prediction_hint.connect (slot);
3556 }
3557
3558 /**
3559  * @brief Connect a slot to Helper set mime type signal.
3560  *
3561  * This signal is used to send mime type to Helper ISE.
3562  *
3563  * The prototype of the slot is:
3564  * void set_mime_type (const HelperAgent *agent, char *mime_type);
3565  */
3566 Connection
3567 HelperAgent::signal_connect_set_mime_type (HelperAgentSlotStringVoid *slot)
3568 {
3569     return m_impl->signal_set_mime_type.connect (slot);
3570 }
3571
3572 /**
3573  * @brief Connect a slot to Helper set prediction hint data signal.
3574  *
3575  * This signal is used to send prediction hint data to Helper ISE.
3576  *
3577  * The prototype of the slot is:
3578  * void set_prediction_hint_data (const HelperAgent *agent, char *key, char *value);
3579  */
3580 Connection
3581 HelperAgent::signal_connect_set_prediction_hint_data (HelperAgentSlotString *slot)
3582 {
3583     return m_impl->signal_set_prediction_hint_data.connect (slot);
3584 }
3585
3586 /**
3587  * @brief Connect a slot to Helper set optimization hint signal.
3588  *
3589  * This signal is used to send optimization hint to Helper ISE.
3590  *
3591  * The prototype of the slot is:
3592  * void set_optimization_hint (const HelperAgent *agent, uint32 &hint);
3593  */
3594 Connection
3595 HelperAgent::signal_connect_set_optimization_hint (HelperAgentSlotUintVoid *slot)
3596 {
3597     return m_impl->signal_set_optimization_hint.connect (slot);
3598 }
3599
3600 } /* namespace scim */
3601
3602 /*
3603 vi:ts=4:nowrap:ai:expandtab
3604 */
3605