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