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