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