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