eefc217ec60035a92c182da047c704d53c508da2
[framework/uifw/isf.git] / ism / src / scim_panel_agent.cpp
1 /** @file scim_panel.cpp
2  *  @brief Implementation of class PanelAgent.
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) 2005 James Su <suzhe@tsinghua.org.cn>
11  *
12  *
13  * This library is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU Lesser General Public
15  * License as published by the Free Software Foundation; either
16  * version 2 of the License, or (at your option) any later version.
17  *
18  * This library is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU Lesser General Public License for more details.
22  *
23  * You should have received a copy of the GNU Lesser General Public
24  * License along with this program; if not, write to the
25  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
26  * Boston, MA  02111-1307  USA
27  *
28  * $Id: scim_panel_agent.cpp,v 1.8.2.1 2006/01/09 14:32:18 suzhe Exp $
29  *
30  */
31
32 #define Uses_SCIM_TRANSACTION
33 #define Uses_SCIM_TRANS_COMMANDS
34 #define Uses_SCIM_PANEL_AGENT
35 #define Uses_SCIM_HELPER
36 #define Uses_SCIM_SOCKET
37 #define Uses_SCIM_EVENT
38 #define Uses_SCIM_CONFIG
39 #define Uses_SCIM_CONFIG_MODULE
40 #define Uses_SCIM_CONFIG_PATH
41 #define Uses_SCIM_UTILITY
42
43 #include <string.h>
44 #include <sys/types.h>
45 #include <unistd.h>
46 #include "scim_private.h"
47 #include "scim.h"
48 #include "scim_stl_map.h"
49
50
51 scim::CommonLookupTable g_isf_candidate_table;
52
53
54 namespace scim {
55
56 typedef Signal0<void>
57         PanelAgentSignalVoid;
58
59 typedef Signal1<void, int>
60         PanelAgentSignalInt;
61
62 typedef Signal1<void, const String &>
63         PanelAgentSignalString;
64
65 typedef Signal2<void, const String &, bool>
66         PanelAgentSignalStringBool;
67
68 typedef Signal2<void, String &, String &>
69         PanelAgentSignalString2;
70
71 typedef Signal2<void, int, const String &>
72         PanelAgentSignalIntString;
73
74 typedef Signal1<void, const PanelFactoryInfo &>
75         PanelAgentSignalFactoryInfo;
76
77 typedef Signal1<void, const std::vector <PanelFactoryInfo> &>
78         PanelAgentSignalFactoryInfoVector;
79
80 typedef Signal1<void, const LookupTable &>
81         PanelAgentSignalLookupTable;
82
83 typedef Signal1<void, const Property &>
84         PanelAgentSignalProperty;
85
86 typedef Signal1<void, const PropertyList &>
87         PanelAgentSignalPropertyList;
88
89 typedef Signal2<void, int, int>
90         PanelAgentSignalIntInt;
91
92 typedef Signal2<void, int &, int &>
93         PanelAgentSignalIntInt2;
94
95 typedef Signal3<void, int, int, int>
96         PanelAgentSignalIntIntInt;
97
98 typedef Signal2<void, int, const Property &>
99         PanelAgentSignalIntProperty;
100
101 typedef Signal2<void, int, const PropertyList &>
102         PanelAgentSignalIntPropertyList;
103
104 typedef Signal2<void, int, const HelperInfo &>
105         PanelAgentSignalIntHelperInfo;
106
107 typedef Signal2<void, const String &, const AttributeList &>
108         PanelAgentSignalAttributeString;
109
110 typedef Signal1<void, std::vector <String> &>
111         PanelAgentSignalStringVector;
112
113 typedef Signal1<bool, std::vector <String> &>
114         PanelAgentSignalBoolStringVector;
115
116 typedef Signal2<void, char *, std::vector <String> &>
117         PanelAgentSignalStrStringVector;
118
119 typedef Signal2<bool, const String &, ISE_INFO &>
120         PanelAgentSignalStringISEINFO;
121
122 typedef Signal1<void, const KeyEvent &>
123         PanelAgentSignalKeyEvent;
124
125 typedef Signal1<void, struct rectinfo &>
126         PanelAgentSignalRect;
127
128 enum ClientType {
129     UNKNOWN_CLIENT,
130     FRONTEND_CLIENT,
131     HELPER_CLIENT,
132     HELPER_ACT_CLIENT,
133     IMCONTROL_ACT_CLIENT,
134     IMCONTROL_CLIENT
135 };
136
137 struct ClientInfo {
138     uint32       key;
139     ClientType   type;
140 };
141
142 struct HelperClientStub {
143     int id;
144     int ref;
145
146     HelperClientStub (int i = 0, int r = 0) : id (i), ref (r) { }
147 };
148
149 struct IMControlStub {
150     std::vector<ISE_INFO> info;
151     std::vector<int> count;
152 };
153
154 static  int _id_count = -4;
155
156 #define DEFAULT_CONTEXT_VALUE 0xfff
157
158 #if SCIM_USE_STL_EXT_HASH_MAP
159 typedef __gnu_cxx::hash_map <int, ClientInfo, __gnu_cxx::hash <int> >       ClientRepository;
160 typedef __gnu_cxx::hash_map <int, HelperInfo, __gnu_cxx::hash <int> >       HelperInfoRepository;
161 typedef __gnu_cxx::hash_map <uint32, String, __gnu_cxx::hash <unsigned int> > ClientContextUUIDRepository;
162 typedef __gnu_cxx::hash_map <String, HelperClientStub, scim_hash_string>    HelperClientIndex;
163 typedef __gnu_cxx::hash_map <String, std::vector < std::pair <uint32, String> >, scim_hash_string>    StartHelperICIndex;
164 #elif SCIM_USE_STL_HASH_MAP
165 typedef std::hash_map <int, ClientInfo, std::hash <int> >                   ClientRepository;
166 typedef std::hash_map <int, HelperInfo, std::hash <int> >                   HelperInfoRepository;
167 typedef std::hash_map <uint32, String, std::hash <unsigned int> >           ClientContextUUIDRepository;
168 typedef std::hash_map <String, HelperClientStub, scim_hash_string>          HelperClientIndex;
169 typedef std::hash_map <String, std::vector < std::pair <uint32, String> >, scim_hash_string>          StartHelperICIndex;
170 #else
171 typedef std::map <int, ClientInfo>                                          ClientRepository;
172 typedef std::map <int, HelperInfo>                                          HelperInfoRepository;
173 typedef std::map <uint32, String>                                           ClientContextUUIDRepository;
174 typedef std::map <String, HelperClientStub>                                 HelperClientIndex;
175 typedef std::map <String, std::vector < std::pair <uint32, String> > >                                StartHelperICIndex;
176 #endif
177
178 typedef std::map <String, uint32>              UUIDCountRepository;
179 typedef std::map <String, enum HelperState>    UUIDStateRepository;
180 typedef std::map <String, int>                 StringIntRepository;
181 typedef std::map <int, struct IMControlStub>   IMControlRepository;
182 typedef std::map <int, int>                    IntIntRepository;
183
184 static uint32
185 get_helper_ic (int client, uint32 context)
186 {
187     return (uint32) (client & 0xFFFF) | ((context & 0x7FFF) << 16);
188 }
189
190 static void
191 get_imengine_client_context (uint32 helper_ic, int &client, uint32 &context)
192 {
193     client   = (int) (helper_ic & 0xFFFF);
194     context  = ((helper_ic >> 16) & 0x7FFF);
195 }
196
197 //==================================== PanelAgent ===========================
198 class PanelAgent::PanelAgentImpl
199 {
200     bool                                m_should_exit;
201     bool                                m_should_resident;
202
203     int                                 m_current_screen;
204
205     String                              m_config_name;
206     String                              m_display_name;
207
208     int                                 m_socket_timeout;
209     String                              m_socket_address;
210     SocketServer                        m_socket_server;
211
212     Transaction                         m_send_trans;
213     Transaction                         m_recv_trans;
214     Transaction                         m_nest_trans;
215
216     int                                 m_current_socket_client;
217     uint32                              m_current_client_context;
218     String                              m_current_context_uuid;
219     TOOLBAR_MODE_T                      m_current_toolbar_mode;
220     String                              m_current_factory_icon;
221     String                              m_current_helper_uuid;
222     String                              m_last_helper_uuid;
223     String                              m_current_ise_name;
224     uint32                              m_current_ise_style;
225     int                                 m_current_active_imcontrol_id;
226     int                                 m_pending_active_imcontrol_id;
227     IntIntRepository                    m_imcontrol_map;
228     DEFAULT_ISE_T                       m_default_ise;
229     bool                                m_should_shared_ise;
230     char *                              m_ise_settings;
231     size_t                              m_ise_settings_len;
232     bool                                m_ise_changing;
233     bool                                m_ise_exiting;
234
235     int                                 m_last_socket_client;
236     uint32                              m_last_client_context;
237     String                              m_last_context_uuid;
238
239     ClientRepository                    m_client_repository;
240     /*
241     * Each Helper ISE has two socket connect between PanelAgent and HelperAgent.
242     * m_helper_info_repository records the active connection.
243     * m_helper_active_info_repository records the passive connection.
244     */
245     HelperInfoRepository                m_helper_info_repository;
246     HelperInfoRepository                m_helper_active_info_repository;
247     HelperClientIndex                   m_helper_client_index;
248
249     /* when helper register, notify imcontrol client */
250     StringIntRepository                 m_ise_pending_repository;
251     IMControlRepository                 m_imcontrol_repository;
252
253     StartHelperICIndex                  m_start_helper_ic_index;
254
255     /* Keyboard ISE */
256     ClientContextUUIDRepository         m_client_context_uuids;
257
258     /* Helper ISE */
259     ClientContextUUIDRepository         m_client_context_helper;
260     UUIDCountRepository                 m_helper_uuid_count;
261     UUIDStateRepository                 m_helper_uuid_state;
262
263     HelperManager                       m_helper_manager;
264
265     PanelAgentSignalVoid                m_signal_reload_config;
266     PanelAgentSignalVoid                m_signal_turn_on;
267     PanelAgentSignalVoid                m_signal_turn_off;
268     PanelAgentSignalVoid                m_signal_show_panel;
269     PanelAgentSignalVoid                m_signal_hide_panel;
270     PanelAgentSignalInt                 m_signal_update_screen;
271     PanelAgentSignalIntIntInt           m_signal_update_spot_location;
272     PanelAgentSignalFactoryInfo         m_signal_update_factory_info;
273     PanelAgentSignalVoid                m_signal_start_default_ise;
274     PanelAgentSignalIntInt              m_signal_set_candidate_ui;
275     PanelAgentSignalIntInt2             m_signal_get_candidate_ui;
276     PanelAgentSignalIntInt              m_signal_set_candidate_position;
277     PanelAgentSignalRect                m_signal_get_candidate_rect;
278     PanelAgentSignalIntString           m_signal_set_keyboard_ise;
279     PanelAgentSignalString2             m_signal_get_keyboard_ise;
280     PanelAgentSignalString              m_signal_show_help;
281     PanelAgentSignalFactoryInfoVector   m_signal_show_factory_menu;
282     PanelAgentSignalVoid                m_signal_show_preedit_string;
283     PanelAgentSignalVoid                m_signal_show_aux_string;
284     PanelAgentSignalVoid                m_signal_show_lookup_table;
285     PanelAgentSignalVoid                m_signal_show_associate_table;
286     PanelAgentSignalVoid                m_signal_hide_preedit_string;
287     PanelAgentSignalVoid                m_signal_hide_aux_string;
288     PanelAgentSignalVoid                m_signal_hide_lookup_table;
289     PanelAgentSignalVoid                m_signal_hide_associate_table;
290     PanelAgentSignalAttributeString     m_signal_update_preedit_string;
291     PanelAgentSignalInt                 m_signal_update_preedit_caret;
292     PanelAgentSignalAttributeString     m_signal_update_aux_string;
293     PanelAgentSignalLookupTable         m_signal_update_lookup_table;
294     PanelAgentSignalLookupTable         m_signal_update_associate_table;
295     PanelAgentSignalPropertyList        m_signal_register_properties;
296     PanelAgentSignalProperty            m_signal_update_property;
297     PanelAgentSignalIntPropertyList     m_signal_register_helper_properties;
298     PanelAgentSignalIntProperty         m_signal_update_helper_property;
299     PanelAgentSignalIntHelperInfo       m_signal_register_helper;
300     PanelAgentSignalInt                 m_signal_remove_helper;
301     PanelAgentSignalStringBool          m_signal_set_active_ise_by_uuid;
302     PanelAgentSignalString              m_signal_set_active_ise_by_name;
303     PanelAgentSignalVoid                m_signal_focus_in;
304     PanelAgentSignalVoid                m_signal_focus_out;
305     PanelAgentSignalBoolStringVector    m_signal_get_ise_list;
306     PanelAgentSignalBoolStringVector    m_signal_get_keyboard_ise_list;
307     PanelAgentSignalInt                 m_signal_launch_helper_ise_list_selection;
308     PanelAgentSignalStringVector        m_signal_get_language_list;
309     PanelAgentSignalStringVector        m_signal_get_all_language;
310     PanelAgentSignalStrStringVector     m_signal_get_ise_language;
311     PanelAgentSignalString              m_signal_set_isf_language;
312     PanelAgentSignalStringISEINFO       m_signal_get_ise_info_by_uuid;
313     PanelAgentSignalStringISEINFO       m_signal_get_ise_info_by_name;
314     PanelAgentSignalKeyEvent            m_signal_send_key_event;
315
316     PanelAgentSignalInt                 m_signal_accept_connection;
317     PanelAgentSignalInt                 m_signal_close_connection;
318     PanelAgentSignalVoid                m_signal_exit;
319
320     PanelAgentSignalVoid                m_signal_transaction_start;
321     PanelAgentSignalVoid                m_signal_transaction_end;
322
323     PanelAgentSignalVoid                m_signal_lock;
324     PanelAgentSignalVoid                m_signal_unlock;
325
326 public:
327     PanelAgentImpl ()
328         : m_should_exit (false),
329           m_should_resident (false),
330           m_current_screen (0),
331           m_socket_timeout (scim_get_default_socket_timeout ()),
332           m_current_socket_client (-1), m_current_client_context (0),
333           m_current_toolbar_mode (TOOLBAR_KEYBOARD_MODE),
334           m_current_ise_style (0),
335           m_current_active_imcontrol_id (-1), m_pending_active_imcontrol_id (-1),
336           m_should_shared_ise (false),
337           m_ise_settings (NULL), m_ise_settings_len (0),
338           m_ise_changing (false), m_ise_exiting (false),
339           m_last_socket_client (-1), m_last_client_context (0)
340     {
341         m_current_ise_name = String (_("English/Keyboard"));
342         m_imcontrol_repository.clear ();
343         m_imcontrol_map.clear ();
344         m_socket_server.signal_connect_accept (slot (this, &PanelAgentImpl::socket_accept_callback));
345         m_socket_server.signal_connect_receive (slot (this, &PanelAgentImpl::socket_receive_callback));
346         m_socket_server.signal_connect_exception (slot (this, &PanelAgentImpl::socket_exception_callback));
347     }
348
349     bool initialize (const String &config, const String &display, bool resident)
350     {
351         m_config_name = config;
352         m_display_name = display;
353         m_should_resident = resident;
354
355         m_socket_address = scim_get_default_panel_socket_address (display);
356
357         m_socket_server.shutdown ();
358
359         return m_socket_server.create (SocketAddress (m_socket_address));
360     }
361
362     bool valid (void) const
363     {
364         return m_socket_server.valid ();
365     }
366
367 public:
368     bool run (void)
369     {
370         SCIM_DEBUG_MAIN (1) << "PanelAgent::run ()\n";
371
372         return m_socket_server.run ();
373     }
374
375     void stop (void)
376     {
377         SCIM_DEBUG_MAIN(1) << "PanelAgent::stop ()\n";
378
379         lock ();
380         m_should_exit = true;
381         unlock ();
382
383         SocketClient  client;
384
385         if (client.connect (SocketAddress (m_socket_address))) {
386             client.close ();
387         }
388     }
389
390     int get_helper_list (std::vector <HelperInfo> & helpers) const
391     {
392         SCIM_DEBUG_MAIN (1) << "PanelAgent::get_helper_list ()\n";
393
394         helpers.clear ();
395
396         m_helper_manager.get_helper_list ();
397         unsigned int num = m_helper_manager.number_of_helpers ();
398         HelperInfo info;
399
400         SCIM_DEBUG_MAIN (2) << "Found " << num << " Helper objects\n";
401
402         for (unsigned int i = 0; i < num; ++i) {
403             if (m_helper_manager.get_helper_info (i, info) && info.uuid.length ()
404                 && (info.option & SCIM_HELPER_STAND_ALONE))
405                 helpers.push_back (info);
406
407             SCIM_DEBUG_MAIN (3) << "Helper " << i << " : " << info.uuid << " : " << info.name << " : "
408                                 << ((info.option & SCIM_HELPER_STAND_ALONE) ? "SA " : "")
409                                 << ((info.option & SCIM_HELPER_AUTO_START) ? "AS " : "")
410                                 << ((info.option & SCIM_HELPER_AUTO_RESTART) ? "AR " : "") << "\n";
411         }
412
413         return (int)(helpers.size ());
414     }
415
416     TOOLBAR_MODE_T get_current_toolbar_mode () const
417     {
418         return m_current_toolbar_mode;
419     }
420
421     String get_current_ise_name () const
422     {
423         return m_current_ise_name;
424     }
425
426     String get_current_factory_icon () const
427     {
428         return m_current_factory_icon;
429     }
430
431     String get_current_helper_uuid () const
432     {
433         return m_current_helper_uuid;
434     }
435
436     String get_current_helper_name () const
437     {
438         std::vector<HelperInfo> helpers;
439
440         get_helper_list (helpers);
441
442         std::vector<HelperInfo>::iterator iter;
443
444         for (iter = helpers.begin (); iter != helpers.end (); iter++) {
445             if (iter->uuid == m_current_helper_uuid)
446                 return iter->name;
447         }
448
449         return String ("");
450     }
451
452     void set_current_ise_name (String &name)
453     {
454         m_current_ise_name = name;
455     }
456
457     void set_current_ise_style (uint32 &style)
458     {
459         m_current_ise_style = style;
460     }
461
462     void set_current_toolbar_mode (TOOLBAR_MODE_T mode)
463     {
464         m_current_toolbar_mode = mode;
465     }
466
467     void update_ise_name (String &name)
468     {
469         ClientRepository::iterator iter = m_client_repository.begin ();
470
471         for (; iter != m_client_repository.end (); iter++)
472         {
473             if (IMCONTROL_CLIENT == iter->second.type
474                 && iter->first == m_imcontrol_map[m_current_active_imcontrol_id])
475             {
476                 Socket client_socket (iter->first);
477                 Transaction trans;
478
479                 trans.clear ();
480                 trans.put_command (SCIM_TRANS_CMD_REQUEST);
481                 trans.put_command (ISM_TRANS_CMD_ISE_CHANGED);
482                 trans.put_data (name);
483
484                 trans.write_to_socket (client_socket);
485                 break;
486             }
487         }
488     }
489
490     void update_ise_style (uint32 &style)
491     {
492         ClientRepository::iterator iter = m_client_repository.begin ();
493
494         for (; iter != m_client_repository.end (); iter++)
495         {
496             if (IMCONTROL_CLIENT == iter->second.type &&
497                 iter->first == m_imcontrol_map[m_current_active_imcontrol_id])
498             {
499                 Socket client_socket (iter->first);
500                 Transaction trans;
501
502                 trans.clear ();
503                 trans.put_command (SCIM_TRANS_CMD_REQUEST);
504                 trans.put_command (ISM_TRANS_CMD_UPDATE_ISE_STYLE);
505                 trans.put_data (style);
506
507                 trans.write_to_socket (client_socket);
508                 break;
509             }
510         }
511     }
512
513     void set_current_factory_icon (String &icon)
514     {
515         m_current_factory_icon = icon;
516     }
517
518     bool move_preedit_caret (uint32 position)
519     {
520         SCIM_DEBUG_MAIN(1) << "PanelAgent::move_preedit_caret (" << position << ")\n";
521
522         int client;
523         uint32 context;
524
525         lock ();
526
527         get_focused_context (client, context);
528
529         if (client >= 0) {
530             Socket client_socket (client);
531             m_send_trans.clear ();
532             m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
533             m_send_trans.put_data ((uint32) context);
534             m_send_trans.put_command (SCIM_TRANS_CMD_MOVE_PREEDIT_CARET);
535             m_send_trans.put_data ((uint32) position);
536             m_send_trans.write_to_socket (client_socket);
537         }
538
539         unlock ();
540
541         return client >= 0;
542     }
543
544     bool request_help (void)
545     {
546         SCIM_DEBUG_MAIN(1) << "PanelAgent::request_help ()\n";
547
548         int client;
549         uint32 context;
550
551         lock ();
552
553         get_focused_context (client, context);
554
555         if (client >= 0) {
556             Socket client_socket (client);
557             m_send_trans.clear ();
558             m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
559             m_send_trans.put_data ((uint32) context);
560             m_send_trans.put_command (SCIM_TRANS_CMD_PANEL_REQUEST_HELP);
561             m_send_trans.write_to_socket (client_socket);
562         }
563
564         unlock ();
565
566         return client >= 0;
567     }
568
569     bool request_factory_menu (void)
570     {
571         SCIM_DEBUG_MAIN(1) << "PanelAgent::request_factory_menu ()\n";
572
573         int client;
574         uint32 context;
575
576         lock ();
577
578         get_focused_context (client, context);
579
580         if (client >= 0) {
581             Socket client_socket (client);
582             m_send_trans.clear ();
583             m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
584             m_send_trans.put_data ((uint32) context);
585             m_send_trans.put_command (SCIM_TRANS_CMD_PANEL_REQUEST_FACTORY_MENU);
586             m_send_trans.write_to_socket (client_socket);
587         }
588
589         unlock ();
590
591         return client >= 0;
592     }
593
594     bool reset_keyboard_ise (void)
595     {
596         SCIM_DEBUG_MAIN(1) << "PanelAgent::reset_keyboard_ise ()\n";
597         int    client = -1;
598         uint32 context = 0;
599
600         lock ();
601
602         get_focused_context (client, context);
603         if (client >= 0) {
604             Socket client_socket (client);
605             m_send_trans.clear ();
606             m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
607             m_send_trans.put_data ((uint32) context);
608             m_send_trans.put_command (ISM_TRANS_CMD_PANEL_REQUEST_RESET_ISE);
609             m_send_trans.write_to_socket (client_socket);
610         }
611
612         unlock ();
613
614         return client >= 0;
615     }
616
617     bool update_keyboard_ise_list (void)
618     {
619         SCIM_DEBUG_MAIN(1) << "PanelAgent::update_keyboard_ise_list ()\n";
620         int    client = -1;
621         uint32 context = 0;
622
623         lock ();
624
625         get_focused_context (client, context);
626         if (client >= 0) {
627             Socket client_socket (client);
628             m_send_trans.clear ();
629             m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
630             m_send_trans.put_data ((uint32) context);
631             m_send_trans.put_command (ISM_TRANS_CMD_PANEL_UPDATE_KEYBOARD_ISE);
632             m_send_trans.write_to_socket (client_socket);
633         }
634
635         unlock ();
636
637         return client >= 0;
638     }
639
640     bool change_factory (const String  &uuid)
641     {
642         SCIM_DEBUG_MAIN(1) << "PanelAgent::change_factory (" << uuid << ")\n";
643
644         int client;
645         uint32 context;
646
647         lock ();
648
649         get_focused_context (client, context);
650
651         if (client >= 0) {
652             Socket client_socket (client);
653             m_send_trans.clear ();
654             m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
655             m_send_trans.put_data ((uint32) context);
656             m_send_trans.put_command (SCIM_TRANS_CMD_PANEL_CHANGE_FACTORY);
657             m_send_trans.put_data (uuid);
658             m_send_trans.write_to_socket (client_socket);
659         }
660
661         unlock ();
662
663         return client >= 0;
664     }
665
666     bool candidate_more_window_show (void)
667     {
668         SCIM_DEBUG_MAIN(4) << __FUNCTION__ << "...\n";
669
670         if (TOOLBAR_HELPER_MODE == m_current_toolbar_mode)
671         {
672             HelperClientIndex::iterator it = m_helper_client_index.find (m_current_helper_uuid);
673
674             if (it != m_helper_client_index.end ())
675             {
676                 int    client;
677                 uint32 context;
678                 Socket client_socket (it->second.id);
679                 uint32 ctx;
680
681                 get_focused_context (client, context);
682                 ctx = get_helper_ic (client, context);
683
684                 m_send_trans.clear ();
685                 m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
686                 m_send_trans.put_data (ctx);
687                 m_send_trans.put_data (m_current_helper_uuid);
688                 m_send_trans.put_command (ISM_TRANS_CMD_CANDIDATE_MORE_WINDOW_SHOW);
689                 m_send_trans.write_to_socket (client_socket);
690
691                 return true;
692             }
693         }
694
695         return false;
696     }
697
698     bool candidate_more_window_hide (void)
699     {
700         SCIM_DEBUG_MAIN(4) << __FUNCTION__ << "...\n";
701
702         if (TOOLBAR_HELPER_MODE == m_current_toolbar_mode)
703         {
704             HelperClientIndex::iterator it = m_helper_client_index.find (m_current_helper_uuid);
705
706             if (it != m_helper_client_index.end ())
707             {
708                 int    client;
709                 uint32 context;
710                 Socket client_socket (it->second.id);
711                 uint32 ctx;
712
713                 get_focused_context (client, context);
714                 ctx = get_helper_ic (client, context);
715
716                 m_send_trans.clear ();
717                 m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
718                 m_send_trans.put_data (ctx);
719                 m_send_trans.put_data (m_current_helper_uuid);
720                 m_send_trans.put_command (ISM_TRANS_CMD_CANDIDATE_MORE_WINDOW_HIDE);
721                 m_send_trans.write_to_socket (client_socket);
722
723                 return true;
724             }
725         }
726
727         return false;
728     }
729
730     bool select_aux (uint32 item)
731     {
732         SCIM_DEBUG_MAIN(1) << "PanelAgent::select_aux (" << item << ")\n";
733
734         int client;
735         uint32 context;
736
737         lock ();
738
739         get_focused_context (client, context);
740
741         if (client >= 0) {
742             Socket client_socket (client);
743             m_send_trans.clear ();
744             m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
745             m_send_trans.put_data ((uint32) context);
746             m_send_trans.put_command (ISM_TRANS_CMD_SELECT_AUX);
747             m_send_trans.put_data ((uint32)item);
748             m_send_trans.write_to_socket (client_socket);
749         }
750
751         unlock ();
752
753         helper_select_aux (item);
754
755         return client >= 0;
756     }
757
758     bool select_candidate (uint32 item)
759     {
760         SCIM_DEBUG_MAIN(1) << "PanelAgent::select_candidate (" << item << ")\n";
761
762         int client;
763         uint32 context;
764
765         lock ();
766
767         get_focused_context (client, context);
768
769         if (client >= 0) {
770             Socket client_socket (client);
771             m_send_trans.clear ();
772             m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
773             m_send_trans.put_data ((uint32) context);
774             m_send_trans.put_command (SCIM_TRANS_CMD_SELECT_CANDIDATE);
775             m_send_trans.put_data ((uint32)item);
776             m_send_trans.write_to_socket (client_socket);
777         }
778
779         unlock ();
780
781         helper_select_candidate (item);
782
783         return client >= 0;
784     }
785
786     bool lookup_table_page_up (void)
787     {
788         SCIM_DEBUG_MAIN(1) << "PanelAgent::lookup_table_page_up ()\n";
789
790         int client;
791         uint32 context;
792
793         lock ();
794
795         get_focused_context (client, context);
796
797         if (client >= 0) {
798             Socket client_socket (client);
799             m_send_trans.clear ();
800             m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
801             m_send_trans.put_data ((uint32) context);
802             m_send_trans.put_command (SCIM_TRANS_CMD_LOOKUP_TABLE_PAGE_UP);
803             m_send_trans.write_to_socket (client_socket);
804         }
805
806         unlock ();
807
808         helper_lookup_table_page_up ();
809
810         return client >= 0;
811     }
812
813     bool lookup_table_page_down (void)
814     {
815         SCIM_DEBUG_MAIN(1) << "PanelAgent::lookup_table_page_down ()\n";
816
817         int client;
818         uint32 context;
819
820         lock ();
821
822         get_focused_context (client, context);
823
824         if (client >= 0) {
825             Socket client_socket (client);
826             m_send_trans.clear ();
827             m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
828             m_send_trans.put_data ((uint32) context);
829             m_send_trans.put_command (SCIM_TRANS_CMD_LOOKUP_TABLE_PAGE_DOWN);
830             m_send_trans.write_to_socket (client_socket);
831         }
832
833         unlock ();
834
835         helper_lookup_table_page_down ();
836
837         return client >= 0;
838     }
839
840     bool update_lookup_table_page_size (uint32 size)
841     {
842         SCIM_DEBUG_MAIN(1) << "PanelAgent::update_lookup_table_page_size (" << size << ")\n";
843
844         int client;
845         uint32 context;
846
847         lock ();
848
849         get_focused_context (client, context);
850
851         if (client >= 0) {
852             Socket client_socket (client);
853             m_send_trans.clear ();
854             m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
855             m_send_trans.put_data ((uint32) context);
856             m_send_trans.put_command (SCIM_TRANS_CMD_UPDATE_LOOKUP_TABLE_PAGE_SIZE);
857             m_send_trans.put_data (size);
858             m_send_trans.write_to_socket (client_socket);
859         }
860
861         unlock ();
862
863         helper_update_lookup_table_page_size (size);
864
865         return client >= 0;
866     }
867
868     bool select_associate (uint32 item)
869     {
870         SCIM_DEBUG_MAIN(1) << "PanelAgent::select_associate (" << item << ")\n";
871
872         int client;
873         uint32 context;
874
875         lock ();
876
877         get_focused_context (client, context);
878
879         if (client >= 0) {
880             Socket client_socket (client);
881             m_send_trans.clear ();
882             m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
883             m_send_trans.put_data ((uint32) context);
884             m_send_trans.put_command (ISM_TRANS_CMD_SELECT_ASSOCIATE);
885             m_send_trans.put_data ((uint32)item);
886             m_send_trans.write_to_socket (client_socket);
887         }
888
889         unlock ();
890
891         helper_select_associate (item);
892
893         return client >= 0;
894     }
895
896     bool associate_table_page_up (void)
897     {
898         SCIM_DEBUG_MAIN(1) << "PanelAgent::associate_table_page_up ()\n";
899
900         int client;
901         uint32 context;
902
903         lock ();
904
905         get_focused_context (client, context);
906
907         if (client >= 0) {
908             Socket client_socket (client);
909             m_send_trans.clear ();
910             m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
911             m_send_trans.put_data ((uint32) context);
912             m_send_trans.put_command (ISM_TRANS_CMD_ASSOCIATE_TABLE_PAGE_UP);
913             m_send_trans.write_to_socket (client_socket);
914         }
915
916         unlock ();
917
918         helper_associate_table_page_up ();
919
920         return client >= 0;
921     }
922
923     bool associate_table_page_down (void)
924     {
925         SCIM_DEBUG_MAIN(1) << "PanelAgent::associate_table_page_down ()\n";
926
927         int client;
928         uint32 context;
929
930         lock ();
931
932         get_focused_context (client, context);
933
934         if (client >= 0) {
935             Socket client_socket (client);
936             m_send_trans.clear ();
937             m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
938             m_send_trans.put_data ((uint32) context);
939             m_send_trans.put_command (ISM_TRANS_CMD_ASSOCIATE_TABLE_PAGE_DOWN);
940             m_send_trans.write_to_socket (client_socket);
941         }
942
943         unlock ();
944
945         helper_associate_table_page_down ();
946
947         return client >= 0;
948     }
949
950     bool update_associate_table_page_size (uint32 size)
951     {
952         SCIM_DEBUG_MAIN(1) << "PanelAgent::update_associate_table_page_size (" << size << ")\n";
953
954         int client;
955         uint32 context;
956
957         lock ();
958
959         get_focused_context (client, context);
960
961         if (client >= 0) {
962             Socket client_socket (client);
963             m_send_trans.clear ();
964             m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
965             m_send_trans.put_data ((uint32) context);
966             m_send_trans.put_command (ISM_TRANS_CMD_UPDATE_ASSOCIATE_TABLE_PAGE_SIZE);
967             m_send_trans.put_data (size);
968             m_send_trans.write_to_socket (client_socket);
969         }
970
971         unlock ();
972
973         helper_update_associate_table_page_size (size);
974
975         return client >= 0;
976     }
977
978     bool trigger_property (const String  &property)
979     {
980         SCIM_DEBUG_MAIN(1) << "PanelAgent::trigger_property (" << property << ")\n";
981
982         int client;
983         uint32 context;
984
985         lock ();
986
987         get_focused_context (client, context);
988
989         if (client >= 0) {
990             Socket client_socket (client);
991             m_send_trans.clear ();
992             m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
993             m_send_trans.put_data ((uint32) context);
994             m_send_trans.put_command (SCIM_TRANS_CMD_TRIGGER_PROPERTY);
995             m_send_trans.put_data (property);
996             m_send_trans.write_to_socket (client_socket);
997         }
998
999         unlock ();
1000
1001         return client >= 0;
1002     }
1003
1004     bool trigger_helper_property (int            client,
1005                                   const String  &property)
1006     {
1007         SCIM_DEBUG_MAIN(1) << "PanelAgent::trigger_helper_property (" << client << "," << property << ")\n";
1008
1009         lock ();
1010
1011         ClientInfo info = socket_get_client_info (client);
1012
1013         if (client >= 0 && info.type == HELPER_CLIENT) {
1014             int fe_client;
1015             uint32 fe_context;
1016             String fe_uuid;
1017
1018             fe_uuid = get_focused_context (fe_client, fe_context);
1019
1020             Socket client_socket (client);
1021             m_send_trans.clear ();
1022             m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
1023
1024             /* FIXME: We presume that client and context are both less than 65536.
1025              * Hopefully, it should be true in any UNIXs.
1026              * So it's ok to combine client and context into one uint32.*/
1027             m_send_trans.put_data (get_helper_ic (fe_client, fe_context));
1028             m_send_trans.put_data (fe_uuid);
1029             m_send_trans.put_command (SCIM_TRANS_CMD_TRIGGER_PROPERTY);
1030             m_send_trans.put_data (property);
1031             m_send_trans.write_to_socket (client_socket);
1032         }
1033
1034         unlock ();
1035
1036         return client >= 0 && info.type == HELPER_CLIENT;
1037     }
1038
1039     bool start_helper (const String  &uuid, int client, uint32 context)
1040     {
1041         SCIM_DEBUG_MAIN(1) << "PanelAgent::start_helper (" << uuid << ")\n";
1042         if (uuid.length () <= 0)
1043             return false;
1044
1045         lock ();
1046
1047         if (m_current_toolbar_mode != TOOLBAR_HELPER_MODE || m_current_helper_uuid.compare (uuid) != 0)
1048         {
1049             SCIM_DEBUG_MAIN(1) << uuid.c_str () <<  ".....enter run_helper ..............\n";
1050             m_helper_manager.run_helper (uuid, m_config_name, m_display_name);
1051         }
1052         m_current_helper_uuid = uuid;
1053 #ifdef ONE_HELPER_ISE_PROCESS
1054         if (client == -2)
1055             get_focused_context (client, context);
1056
1057         SCIM_DEBUG_MAIN(1) << "[start helper] client : " << client << " context : " << context << "\n";
1058         uint32 ctx = get_helper_ic (client, context);
1059
1060         /*HelperClientIndex::iterator it = m_helper_client_index.find (uuid);
1061         if (it == m_helper_client_index.end ())*/
1062         if (m_helper_uuid_count.find (uuid) == m_helper_uuid_count.end ())
1063         {
1064             m_client_context_helper[ctx] = uuid;
1065             m_current_helper_uuid        = uuid;
1066             m_helper_uuid_count[uuid]    = 1;
1067             m_helper_uuid_state[uuid]    = HELPER_HIDED;
1068
1069             m_helper_manager.run_helper (uuid, m_config_name, m_display_name);
1070             SCIM_DEBUG_MAIN(1) << "Start HelperISE " << uuid << " ...\n";
1071         }
1072         else
1073         {
1074             ClientContextUUIDRepository::iterator it2 = m_client_context_helper.find (ctx);
1075             if (it2 == m_client_context_helper.end ())
1076             {
1077                 m_client_context_helper[ctx] = uuid;
1078                 m_current_helper_uuid        = uuid;
1079                 m_helper_uuid_count[uuid]    = m_helper_uuid_count[uuid] + 1;
1080             }
1081
1082             if (m_current_active_imcontrol_id != -1
1083                 && m_ise_settings != NULL && m_ise_changing)
1084             {
1085                 show_helper (uuid, m_ise_settings, m_ise_settings_len);
1086                 m_ise_changing = false;
1087             }
1088
1089             SCIM_DEBUG_MAIN(1) << "Increment usage count of HelperISE " << uuid << " to "
1090                         << m_helper_uuid_count[uuid] << "\n";
1091         }
1092 #endif
1093         unlock ();
1094
1095         return true;
1096     }
1097
1098     bool stop_helper (const String &helper_uuid, int client, uint32 context)
1099     {
1100         String uuid = helper_uuid;
1101         SCIM_DEBUG_MAIN(1) << "PanelAgent::stop_helper (" << uuid << ")\n";
1102         if (uuid.length () <= 0)
1103             return false;
1104
1105         lock ();
1106
1107         uint32 ctx = get_helper_ic (client, context);
1108         HelperClientIndex::iterator it = m_helper_client_index.find (uuid);
1109         if (it != m_helper_client_index.end ())
1110         {
1111             Socket client_socket (it->second.id);
1112             m_send_trans.clear ();
1113             m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
1114             m_send_trans.put_data (ctx);
1115             m_send_trans.put_data (uuid);
1116
1117             m_ise_exiting = true;
1118             m_send_trans.put_command (SCIM_TRANS_CMD_EXIT);
1119             m_send_trans.write_to_socket (client_socket);
1120             SCIM_DEBUG_MAIN(1) << "Stop HelperISE " << uuid << " ...\n";
1121         }
1122 #ifdef ONE_HELPER_ISE_PROCESS
1123         if (client == -2)
1124             get_focused_context (client, context);
1125
1126         SCIM_DEBUG_MAIN(1) << "[stop helper] client : " << client << " context : " << context << "\n";
1127         uint32 ctx = get_helper_ic (client, context);
1128
1129         HelperClientIndex::iterator it = m_helper_client_index.find (uuid);
1130         /*if (it != m_helper_client_index.end ())*/
1131         if (m_helper_uuid_count.find (uuid) != m_helper_uuid_count.end ())
1132         {
1133             m_client_context_helper.erase (ctx);
1134
1135             uint32 count = m_helper_uuid_count[uuid];
1136             if (1 == count)
1137             {
1138                 m_helper_uuid_count.erase (uuid);
1139
1140                 if (it != m_helper_client_index.end ())
1141                 {
1142                     Socket client_socket (it->second.id);
1143                     m_send_trans.clear ();
1144                     m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
1145                     m_send_trans.put_data (ctx);
1146                     m_send_trans.put_data (uuid);
1147                     m_send_trans.put_command (SCIM_TRANS_CMD_EXIT);
1148                     m_send_trans.write_to_socket (client_socket);
1149                     SCIM_DEBUG_MAIN(1) << "Stop HelperISE " << uuid << " ...\n";
1150                 }
1151             }
1152             else
1153             {
1154                 m_helper_uuid_count[uuid] = count - 1;
1155                 SCIM_DEBUG_MAIN(1) << "Decrement usage count of HelperISE " << uuid
1156                         << " to " << m_helper_uuid_count[uuid] << "\n";
1157             }
1158         }
1159 #endif
1160         unlock ();
1161
1162         return true;
1163     }
1164
1165     void focus_out_helper (const String &uuid, int client, uint32 context)
1166     {
1167         HelperClientIndex::iterator it = m_helper_client_index.find (m_current_helper_uuid);
1168
1169         if (it != m_helper_client_index.end ())
1170         {
1171             Socket client_socket (it->second.id);
1172             uint32 ctx = get_helper_ic (client, context);
1173
1174             m_send_trans.clear ();
1175             m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
1176             m_send_trans.put_data (ctx);
1177             m_send_trans.put_data (uuid);
1178             m_send_trans.put_command (SCIM_TRANS_CMD_FOCUS_OUT);
1179             m_send_trans.write_to_socket (client_socket);
1180         }
1181     }
1182
1183     void focus_in_helper (const String &uuid, int client, uint32 context)
1184     {
1185         HelperClientIndex::iterator it = m_helper_client_index.find (m_current_helper_uuid);
1186
1187         if (it != m_helper_client_index.end ())
1188         {
1189             Socket client_socket (it->second.id);
1190             uint32 ctx = get_helper_ic (client, context);
1191
1192             m_send_trans.clear ();
1193             m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
1194             m_send_trans.put_data (ctx);
1195             m_send_trans.put_data (uuid);
1196             m_send_trans.put_command (SCIM_TRANS_CMD_FOCUS_IN);
1197             m_send_trans.write_to_socket (client_socket);
1198         }
1199     }
1200
1201     void show_helper (const String &uuid, char *data, size_t &len)
1202     {
1203         HelperClientIndex::iterator it = m_helper_client_index.find (m_current_helper_uuid);
1204
1205         if (it != m_helper_client_index.end ())
1206         {
1207             int client;
1208             uint32 context;
1209             Socket client_socket (it->second.id);
1210             uint32 ctx;
1211
1212             m_helper_uuid_state[uuid] = HELPER_SHOWED;
1213
1214             get_focused_context (client, context);
1215             ctx = get_helper_ic (client, context);
1216
1217             m_send_trans.clear ();
1218             m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
1219             m_send_trans.put_data (ctx);
1220             m_send_trans.put_data (uuid);
1221             m_send_trans.put_command (ISM_TRANS_CMD_SHOW_ISE);
1222             m_send_trans.put_data (data, len);
1223             m_send_trans.write_to_socket (client_socket);
1224         }
1225         return;
1226     }
1227
1228     void hide_helper (const String &uuid)
1229     {
1230         HelperClientIndex::iterator it = m_helper_client_index.find (m_current_helper_uuid);
1231
1232         if (it != m_helper_client_index.end ())
1233         {
1234             int client;
1235             uint32 context;
1236             Socket client_socket (it->second.id);
1237             uint32 ctx;
1238
1239             m_helper_uuid_state[uuid] = HELPER_HIDED;
1240
1241             get_focused_context (client, context);
1242             ctx = get_helper_ic (client, context);
1243
1244             m_send_trans.clear ();
1245             m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
1246             m_send_trans.put_data (ctx);
1247             m_send_trans.put_data (uuid);
1248             m_send_trans.put_command (ISM_TRANS_CMD_HIDE_ISE);
1249             m_send_trans.write_to_socket (client_socket);
1250         }
1251     }
1252
1253     bool set_helper_mode (const String &uuid, uint32 &mode)
1254     {
1255         HelperClientIndex::iterator it = m_helper_client_index.find (m_current_helper_uuid);
1256
1257         if (it != m_helper_client_index.end ())
1258         {
1259             int client;
1260             uint32 context;
1261             Socket client_socket (it->second.id);
1262             uint32 ctx;
1263
1264             get_focused_context (client, context);
1265             ctx = get_helper_ic (client, context);
1266
1267             m_send_trans.clear ();
1268             m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
1269             m_send_trans.put_data (ctx);
1270             m_send_trans.put_data (uuid);
1271             m_send_trans.put_command (ISM_TRANS_CMD_SET_ISE_MODE);
1272             m_send_trans.put_data (mode);
1273             m_send_trans.write_to_socket (client_socket);
1274             return true;
1275         }
1276
1277         return false;
1278     }
1279
1280     bool set_helper_language (const String &uuid, uint32 &language)
1281     {
1282         HelperClientIndex::iterator it = m_helper_client_index.find (m_current_helper_uuid);
1283
1284         if (it != m_helper_client_index.end ())
1285         {
1286             int client     = -1;
1287             uint32 context = 0;
1288             Socket client_socket (it->second.id);
1289             uint32 ctx;
1290
1291             get_focused_context (client, context);
1292             ctx = get_helper_ic (client, context);
1293
1294             m_send_trans.clear ();
1295             m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
1296             m_send_trans.put_data (ctx);
1297             m_send_trans.put_data (uuid);
1298             m_send_trans.put_command (ISM_TRANS_CMD_SET_ISE_LANGUAGE);
1299             m_send_trans.put_data (language);
1300             m_send_trans.write_to_socket (client_socket);
1301             return true;
1302         }
1303         return false;
1304     }
1305
1306     bool set_helper_imdata (const String &uuid, char *imdata, size_t &len)
1307     {
1308         HelperClientIndex::iterator it = m_helper_client_index.find (m_current_helper_uuid);
1309
1310         if (it != m_helper_client_index.end ())
1311         {
1312             int client     = -1;
1313             uint32 context = 0;
1314             Socket client_socket (it->second.id);
1315             uint32 ctx;
1316
1317             get_focused_context (client, context);
1318             ctx = get_helper_ic (client, context);
1319
1320             m_send_trans.clear ();
1321             m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
1322             m_send_trans.put_data (ctx);
1323             m_send_trans.put_data (uuid);
1324             m_send_trans.put_command (ISM_TRANS_CMD_SET_ISE_IMDATA);
1325             m_send_trans.put_data (imdata, len);
1326             m_send_trans.write_to_socket (client_socket);
1327             return true;
1328         }
1329         return false;
1330     }
1331
1332     bool set_helper_private_key (const String &uuid,
1333                                  uint32 layout_idx,
1334                                  uint32 key_idx,
1335                                  char *buf, size_t len1,
1336                                  char *value, size_t len2,
1337                                  bool is_image)
1338     {
1339         HelperClientIndex::iterator it = m_helper_client_index.find (m_current_helper_uuid);
1340
1341         if (it != m_helper_client_index.end ())
1342         {
1343             int client     = -1;
1344             uint32 context = 0;
1345             Socket client_socket (it->second.id);
1346             uint32 ctx;
1347
1348             get_focused_context (client, context);
1349             ctx = get_helper_ic (client, context);
1350
1351             m_send_trans.clear ();
1352             m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
1353             m_send_trans.put_data (ctx);
1354             m_send_trans.put_data (uuid);
1355             if (is_image)
1356                 m_send_trans.put_command (ISM_TRANS_CMD_SET_PRIVATE_KEY_BY_IMG);
1357             else
1358                 m_send_trans.put_command (ISM_TRANS_CMD_SET_PRIVATE_KEY);
1359             m_send_trans.put_data (layout_idx);
1360             m_send_trans.put_data (key_idx);
1361             m_send_trans.put_data (buf, len1);
1362             m_send_trans.put_data (value, len2);
1363             m_send_trans.write_to_socket (client_socket);
1364
1365             return true;
1366         }
1367
1368         return false;
1369     }
1370
1371     bool set_helper_disable_key (const String &uuid,
1372                                  uint32 layout_idx,
1373                                  uint32 key_idx,
1374                                  bool disabled)
1375     {
1376         HelperClientIndex::iterator it = m_helper_client_index.find (m_current_helper_uuid);
1377
1378         if (it != m_helper_client_index.end ())
1379         {
1380             int client     = -1;
1381             uint32 context = 0;
1382             Socket client_socket (it->second.id);
1383             uint32 ctx;
1384
1385             get_focused_context (client, context);
1386             ctx = get_helper_ic (client, context);
1387
1388             m_send_trans.clear ();
1389             m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
1390             m_send_trans.put_data (ctx);
1391             m_send_trans.put_data (uuid);
1392             m_send_trans.put_command (ISM_TRANS_CMD_SET_DISABLE_KEY);
1393             m_send_trans.put_data (layout_idx);
1394             m_send_trans.put_data (key_idx);
1395             m_send_trans.put_data (disabled);
1396             m_send_trans.write_to_socket (client_socket);
1397
1398             return true;
1399         }
1400
1401         return false;
1402     }
1403
1404     bool set_helper_layout (const String &uuid, uint32 &layout)
1405     {
1406         HelperClientIndex::iterator it = m_helper_client_index.find (m_current_helper_uuid);
1407
1408         if (it != m_helper_client_index.end ())
1409         {
1410             int client;
1411             uint32 context;
1412             Socket client_socket (it->second.id);
1413             uint32 ctx;
1414
1415             get_focused_context (client, context);
1416             ctx = get_helper_ic (client, context);
1417
1418             m_send_trans.clear ();
1419             m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
1420             m_send_trans.put_data (ctx);
1421             m_send_trans.put_data (uuid);
1422             m_send_trans.put_command (ISM_TRANS_CMD_SET_LAYOUT);
1423             m_send_trans.put_data (layout);
1424             m_send_trans.write_to_socket (client_socket);
1425             return true;
1426         }
1427
1428         return false;
1429     }
1430
1431     bool set_helper_caps_mode (const String &uuid, uint32 &mode)
1432     {
1433         HelperClientIndex::iterator it = m_helper_client_index.find (m_current_helper_uuid);
1434
1435         if (it != m_helper_client_index.end ())
1436         {
1437             int client;
1438             uint32 context;
1439             Socket client_socket (it->second.id);
1440             uint32 ctx;
1441
1442             get_focused_context (client, context);
1443             ctx = get_helper_ic (client, context);
1444
1445             m_send_trans.clear ();
1446             m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
1447             m_send_trans.put_data (ctx);
1448             m_send_trans.put_data (uuid);
1449             m_send_trans.put_command (ISM_TRANS_CMD_SET_CAPS_MODE);
1450             m_send_trans.put_data (mode);
1451             m_send_trans.write_to_socket (client_socket);
1452             return true;
1453         }
1454
1455         return false;
1456     }
1457
1458     void show_isf_panel (int client_id)
1459     {
1460         SCIM_DEBUG_MAIN(4) << "PanelAgent::show_isf_panel ()\n";
1461         Transaction trans;
1462         Socket client_socket (client_id);
1463
1464         m_signal_show_panel ();
1465     }
1466
1467     void hide_isf_panel (int client_id)
1468     {
1469         SCIM_DEBUG_MAIN(4) << "PanelAgent::hide_isf_panel ()\n";
1470         Transaction trans;
1471         Socket client_socket (client_id);
1472
1473         m_signal_hide_panel ();
1474     }
1475
1476     void show_ise_panel (int client_id)
1477     {
1478         SCIM_DEBUG_MAIN(4) << "PanelAgent::show_ise_panel ()\n";
1479         char   *data = NULL;
1480         size_t  len;
1481
1482         m_current_active_imcontrol_id = client_id;
1483
1484         if (m_recv_trans.get_data (&data, len))
1485         {
1486             if (TOOLBAR_HELPER_MODE == m_current_toolbar_mode)
1487                 show_helper (m_current_helper_uuid, data, len);
1488         }
1489
1490         if (data != NULL)
1491         {
1492             if (m_ise_settings != NULL)
1493                 delete [] m_ise_settings;
1494             m_ise_settings = data;
1495             m_ise_settings_len = len;
1496         }
1497     }
1498
1499     void hide_ise_panel (int client_id)
1500     {
1501         SCIM_DEBUG_MAIN(4) << "PanelAgent::hide_ise_panel ()\n";
1502         TOOLBAR_MODE_T mode;
1503
1504         mode = m_current_toolbar_mode;
1505
1506         if (client_id == m_current_active_imcontrol_id &&
1507             TOOLBAR_HELPER_MODE == mode)
1508         {
1509             hide_helper (m_current_helper_uuid);
1510         }
1511     }
1512
1513     void set_default_ise (const DEFAULT_ISE_T &ise)
1514     {
1515         m_default_ise.type = ise.type;
1516         m_default_ise.uuid = ise.uuid;
1517         m_default_ise.name = ise.name;
1518
1519         scim_global_config_write (String (SCIM_GLOBAL_CONFIG_DEFAULT_ISE_TYPE), (int)m_default_ise.type);
1520         scim_global_config_write (String (SCIM_GLOBAL_CONFIG_DEFAULT_ISE_UUID), m_default_ise.uuid);
1521         scim_global_config_write (String (SCIM_GLOBAL_CONFIG_DEFAULT_ISE_NAME), m_default_ise.name);
1522         scim_global_config_flush ();
1523     }
1524
1525     void set_should_shared_ise (const bool should_shared_ise)
1526     {
1527         m_should_shared_ise = should_shared_ise;
1528     }
1529
1530     bool get_helper_size (String &uuid, struct rectinfo &info)
1531     {
1532         HelperClientIndex::iterator it = m_helper_client_index.find (m_current_helper_uuid);
1533
1534         if (it != m_helper_client_index.end ()) {
1535             int    client;
1536             uint32 context;
1537             Socket client_socket (it->second.id);
1538             uint32 ctx;
1539             Transaction trans;
1540
1541             get_focused_context (client, context);
1542             ctx = get_helper_ic (client, context);
1543
1544             trans.clear ();
1545             trans.put_command (SCIM_TRANS_CMD_REPLY);
1546             trans.put_data (ctx);
1547             trans.put_data (uuid);
1548             trans.put_command (ISM_TRANS_CMD_GET_ACTIVE_ISE_SIZE);
1549
1550             if (trans.write_to_socket (client_socket)) {
1551                 int cmd;
1552
1553                 trans.clear ();
1554                 if (trans.read_from_socket (client_socket)
1555                     && trans.get_command(cmd) && cmd == SCIM_TRANS_CMD_REPLY
1556                     && trans.get_data (info.pos_x)
1557                     && trans.get_data (info.pos_y)
1558                     && trans.get_data (info.width)
1559                     && trans.get_data (info.height)) {
1560                     SCIM_DEBUG_MAIN (1) << "get_helper_size success\n";
1561                     return true;
1562                 } else {
1563                     std::cerr << "get_helper_size failed\n";
1564                     return false;
1565                 }
1566             }
1567         }
1568         return false;
1569     }
1570
1571     bool get_helper_imdata (String &uuid, char **imdata, size_t &len)
1572     {
1573         HelperClientIndex::iterator it = m_helper_client_index.find (m_current_helper_uuid);
1574
1575         if (it != m_helper_client_index.end ()) {
1576
1577             int    client;
1578             uint32 context;
1579             Socket client_socket (it->second.id);
1580             uint32 ctx;
1581             Transaction trans;
1582
1583             get_focused_context (client, context);
1584             ctx = get_helper_ic (client, context);
1585
1586             trans.clear ();
1587             trans.put_command (SCIM_TRANS_CMD_REPLY);
1588             trans.put_data (ctx);
1589             trans.put_data (uuid);
1590             trans.put_command (ISM_TRANS_CMD_GET_ISE_IMDATA);
1591
1592             int cmd;
1593             if (trans.write_to_socket (client_socket)
1594                 && trans.read_from_socket (client_socket)
1595                 && trans.get_command(cmd) && cmd == SCIM_TRANS_CMD_REPLY
1596                 && trans.get_data (imdata, len))
1597             {
1598                 SCIM_DEBUG_MAIN (1) << "get_helper_imdata success\n";
1599                 return true;
1600             }
1601             else
1602             {
1603                 std::cerr << "get_helper_imdata failed\n";
1604             }
1605         }
1606         return false;
1607     }
1608
1609     bool get_helper_layout (String &uuid, uint32 &layout)
1610     {
1611         HelperClientIndex::iterator it = m_helper_client_index.find (m_current_helper_uuid);
1612
1613         if (it != m_helper_client_index.end ()) {
1614
1615             int    client;
1616             uint32 context;
1617             Socket client_socket (it->second.id);
1618             uint32 ctx;
1619             Transaction trans;
1620
1621             get_focused_context (client, context);
1622             ctx = get_helper_ic (client, context);
1623
1624             trans.clear ();
1625             trans.put_command (SCIM_TRANS_CMD_REPLY);
1626             trans.put_data (ctx);
1627             trans.put_data (uuid);
1628             trans.put_command (ISM_TRANS_CMD_GET_LAYOUT);
1629
1630             int cmd;
1631             if (trans.write_to_socket (client_socket)
1632                 && trans.read_from_socket (client_socket)
1633                 && trans.get_command(cmd) && cmd == SCIM_TRANS_CMD_REPLY
1634                 && trans.get_data (layout))
1635             {
1636                 SCIM_DEBUG_MAIN (1) << "get_helper_layout success\n";
1637                 return true;
1638             }
1639             else
1640             {
1641                 std::cerr << "get_helper_layout failed\n";
1642             }
1643         }
1644         return false;
1645     }
1646
1647     bool get_helper_layout_list (String &uuid, std::vector<uint32> &list)
1648     {
1649         HelperClientIndex::iterator it = m_helper_client_index.find (uuid);
1650
1651         if (it != m_helper_client_index.end ()) {
1652
1653             int    client;
1654             uint32 context;
1655             Socket client_socket (it->second.id);
1656             uint32 ctx;
1657             Transaction trans;
1658
1659             get_focused_context (client, context);
1660             ctx = get_helper_ic (client, context);
1661
1662             trans.clear ();
1663             trans.put_command (SCIM_TRANS_CMD_REPLY);
1664             trans.put_data (ctx);
1665             trans.put_data (uuid);
1666             trans.put_command (ISM_TRANS_CMD_GET_LAYOUT_LIST);
1667
1668             int cmd;
1669             if (trans.write_to_socket (client_socket)
1670                 && trans.read_from_socket (client_socket, 500)
1671                 && trans.get_command(cmd) && cmd == SCIM_TRANS_CMD_REPLY
1672                 && trans.get_data (list))
1673             {
1674                 SCIM_DEBUG_MAIN (1) << "get_helper_layout_list success\n";
1675                 return true;
1676             }
1677             else
1678             {
1679                 std::cerr << "get_helper_layout_list failed\n";
1680             }
1681         }
1682         return false;
1683     }
1684
1685     void get_ise_size (int client_id)
1686     {
1687         SCIM_DEBUG_MAIN(4) << "PanelAgent::get_ise_size ()\n";
1688         struct rectinfo info;
1689         bool ret = false;
1690
1691         TOOLBAR_MODE_T mode;
1692
1693         mode = m_current_toolbar_mode;
1694
1695         if (TOOLBAR_HELPER_MODE == mode)
1696             ret = get_helper_size (m_current_helper_uuid, info);
1697
1698         Transaction trans;
1699         Socket client_socket (client_id);
1700
1701         trans.clear ();
1702         trans.put_command (SCIM_TRANS_CMD_REPLY);
1703
1704         if (ret)
1705         {
1706             trans.put_command (SCIM_TRANS_CMD_OK);
1707             trans.put_data (info.pos_x);
1708             trans.put_data (info.pos_y);
1709             trans.put_data (info.width);
1710             trans.put_data (info.height);
1711         }
1712         else
1713         {
1714             std::cerr << "get_ise_size failed\n";
1715             trans.put_command (SCIM_TRANS_CMD_FAIL);
1716         }
1717
1718         trans.write_to_socket (client_socket);
1719     }
1720
1721     void get_current_ise_rect (rectinfo &ise_rect)
1722     {
1723         SCIM_DEBUG_MAIN(4) << "PanelAgent::get_current_ise_rect ()\n";
1724         TOOLBAR_MODE_T mode = m_current_toolbar_mode;
1725         bool           ret  = false;
1726
1727         if (TOOLBAR_HELPER_MODE == mode)
1728             ret = get_helper_size (m_current_helper_uuid, ise_rect);
1729
1730         if (!ret)
1731         {
1732             ise_rect.pos_x  = 0;
1733             ise_rect.pos_y  = 0;
1734             ise_rect.width  = 0;
1735             ise_rect.height = 0;
1736         }
1737     }
1738
1739     void set_ise_mode (int client_id)
1740     {
1741         SCIM_DEBUG_MAIN(4) << "PanelAgent::set_ise_mode ()\n";
1742         uint32 mode;
1743
1744         if (m_recv_trans.get_data (mode))
1745         {
1746             if (TOOLBAR_HELPER_MODE == m_current_toolbar_mode)
1747                 set_helper_mode (m_current_helper_uuid, mode);
1748         }
1749     }
1750
1751     void set_ise_layout (int client_id)
1752     {
1753         SCIM_DEBUG_MAIN(4) << "PanelAgent::set_ise_layout ()\n";
1754         uint32 layout;
1755
1756         if (m_recv_trans.get_data (layout))
1757         {
1758             if (TOOLBAR_HELPER_MODE == m_current_toolbar_mode)
1759                 set_helper_layout (m_current_helper_uuid, layout);
1760         }
1761     }
1762
1763     void set_ise_language (int client_id)
1764     {
1765         SCIM_DEBUG_MAIN(4) << "PanelAgent::set_ise_language ()\n";
1766         uint32 language;
1767
1768         if (m_recv_trans.get_data (language))
1769         {
1770             if (TOOLBAR_HELPER_MODE == m_current_toolbar_mode)
1771                 set_helper_language (m_current_helper_uuid, language);
1772         }
1773     }
1774
1775     void set_isf_language (int client_id)
1776     {
1777         SCIM_DEBUG_MAIN(4) << "PanelAgent::set_isf_language ()\n";
1778         char   *buf = NULL;
1779         size_t  len;
1780
1781         if (m_recv_trans.get_data (&buf, len))
1782         {
1783             String lang (buf);
1784             m_signal_set_isf_language (lang);
1785         }
1786
1787         if (NULL != buf)
1788             delete[] buf;
1789     }
1790
1791     void set_ise_imdata (int client_id)
1792     {
1793         SCIM_DEBUG_MAIN(4) << "PanelAgent::set_ise_imdata ()\n";
1794         char   *imdata = NULL;
1795         size_t  len;
1796
1797         if (m_recv_trans.get_data (&imdata, len))
1798         {
1799             if (TOOLBAR_HELPER_MODE == m_current_toolbar_mode)
1800                 set_helper_imdata (m_current_helper_uuid, imdata, len);
1801         }
1802
1803         if (NULL != imdata)
1804             delete [] imdata;
1805     }
1806
1807     void get_ise_imdata (int client_id)
1808     {
1809         SCIM_DEBUG_MAIN(4) << "PanelAgent::get_ise_imdata ()\n";
1810         char   *imdata = NULL;
1811         size_t  len;
1812         bool    ret    = false;
1813
1814         TOOLBAR_MODE_T mode;
1815
1816         mode = m_current_toolbar_mode;
1817
1818         if (TOOLBAR_HELPER_MODE == mode)
1819         {
1820             ret = get_helper_imdata (m_current_helper_uuid, &imdata, len);
1821         }
1822
1823         Transaction trans;
1824         Socket client_socket (client_id);
1825
1826         trans.clear ();
1827         trans.put_command (SCIM_TRANS_CMD_REPLY);
1828         if (ret)
1829         {
1830             trans.put_command (SCIM_TRANS_CMD_OK);
1831             trans.put_data (imdata, len);
1832         }
1833         else
1834             trans.put_command (SCIM_TRANS_CMD_FAIL);
1835
1836         trans.write_to_socket (client_socket);
1837
1838         if (NULL != imdata)
1839             delete [] imdata;
1840     }
1841
1842     void get_ise_layout (int client_id)
1843     {
1844         SCIM_DEBUG_MAIN(4) << "PanelAgent::get_ise_layout ()\n";
1845         uint32 layout;
1846         bool   ret = false;
1847
1848         TOOLBAR_MODE_T mode = m_current_toolbar_mode;
1849
1850         if (TOOLBAR_HELPER_MODE == mode)
1851             ret = get_helper_layout (m_current_helper_uuid, layout);
1852
1853         Transaction trans;
1854         Socket client_socket (client_id);
1855
1856         trans.clear ();
1857         trans.put_command (SCIM_TRANS_CMD_REPLY);
1858         if (ret) {
1859             trans.put_command (SCIM_TRANS_CMD_OK);
1860             trans.put_data (layout);
1861         } else {
1862             trans.put_command (SCIM_TRANS_CMD_FAIL);
1863         }
1864
1865         trans.write_to_socket (client_socket);
1866     }
1867
1868     bool get_ise_layout_list (std::vector<uint32> &list)
1869     {
1870         bool ret = false;
1871
1872         TOOLBAR_MODE_T mode = m_current_toolbar_mode;
1873
1874         if (TOOLBAR_HELPER_MODE == mode)
1875             ret = get_helper_layout_list (m_current_helper_uuid, list);
1876
1877         return ret;
1878     }
1879
1880     void get_active_ise_name (int client_id)
1881     {
1882         SCIM_DEBUG_MAIN(4) << "PanelAgent::get_active_ise_name ()\n";
1883         Transaction trans;
1884         Socket client_socket (client_id);
1885         char *name = const_cast<char *> (m_current_ise_name.c_str ());
1886         size_t len = strlen (name) + 1;
1887
1888         trans.clear ();
1889         trans.put_command (SCIM_TRANS_CMD_REPLY);
1890         trans.put_command (SCIM_TRANS_CMD_OK);
1891         trans.put_data (name, len);
1892         trans.write_to_socket (client_socket);
1893     }
1894
1895     void get_ise_list (int client_id)
1896     {
1897         SCIM_DEBUG_MAIN(4) << "PanelAgent::get_ise_list ()\n";
1898         std::vector<String> strlist;
1899         m_signal_get_ise_list (strlist);
1900
1901         Transaction trans;
1902         Socket client_socket (client_id);
1903         char *buf = NULL;
1904         size_t len;
1905         uint32 num;
1906
1907         trans.clear ();
1908         trans.put_command (SCIM_TRANS_CMD_REPLY);
1909         trans.put_command (SCIM_TRANS_CMD_OK);
1910
1911         num = strlist.size ();
1912         trans.put_data (num);
1913         for (unsigned int i = 0; i < num; i++)
1914         {
1915             buf = const_cast<char *>(strlist[i].c_str ());
1916             len = strlen (buf) + 1;
1917             trans.put_data (buf, len);
1918         }
1919
1920         trans.write_to_socket (client_socket);
1921     }
1922
1923     void get_language_list (int client_id)
1924     {
1925         SCIM_DEBUG_MAIN(4) << "PanelAgent::get_language_list ()\n";
1926         std::vector<String> strlist;
1927
1928         m_signal_get_language_list (strlist);
1929
1930         Transaction trans;
1931         Socket client_socket (client_id);
1932         char *buf = NULL;
1933         size_t len;
1934         uint32 num;
1935
1936         trans.clear ();
1937         trans.put_command (SCIM_TRANS_CMD_REPLY);
1938         trans.put_command (SCIM_TRANS_CMD_OK);
1939
1940         num = strlist.size ();
1941         trans.put_data (num);
1942         for (unsigned int i = 0; i < num; i++)
1943         {
1944             buf = const_cast<char *>(strlist[i].c_str ());
1945             len = strlen (buf) + 1;
1946             trans.put_data (buf, len);
1947         }
1948
1949         trans.write_to_socket (client_socket);
1950     }
1951
1952     void get_all_language (int client_id)
1953     {
1954         SCIM_DEBUG_MAIN(4) << "PanelAgent::get_all_language ()\n";
1955         std::vector<String> strlist;
1956
1957         m_signal_get_all_language (strlist);
1958
1959         Transaction trans;
1960         Socket  client_socket (client_id);
1961         char   *buf = NULL;
1962         size_t  len;
1963         uint32  num;
1964
1965         trans.clear ();
1966         trans.put_command (SCIM_TRANS_CMD_REPLY);
1967         trans.put_command (SCIM_TRANS_CMD_OK);
1968
1969         num = strlist.size ();
1970         trans.put_data (num);
1971         for (unsigned int i = 0; i < num; i++)
1972         {
1973             buf = const_cast<char *>(strlist[i].c_str ());
1974             len = strlen (buf) + 1;
1975             trans.put_data (buf, len);
1976         }
1977
1978         trans.write_to_socket (client_socket);
1979     }
1980
1981     void get_ise_language (int client_id)
1982     {
1983         SCIM_DEBUG_MAIN(4) << "PanelAgent::get_ise_language ()\n";
1984         std::vector<String> strlist;
1985         char   *buf = NULL;
1986         size_t  len;
1987         Transaction trans;
1988         Socket client_socket (client_id);
1989
1990         if (!(m_recv_trans.get_data (&buf, len)))
1991         {
1992             trans.clear ();
1993             trans.put_command (SCIM_TRANS_CMD_REPLY);
1994             trans.put_command (SCIM_TRANS_CMD_FAIL);
1995             trans.write_to_socket (client_socket);
1996             if (NULL != buf)
1997                 delete[] buf;
1998             return;
1999         }
2000
2001         m_signal_get_ise_language (buf, strlist);
2002
2003         if (buf)
2004         {
2005             delete [] buf;
2006             buf = NULL;
2007         }
2008
2009         uint32 num;
2010
2011         trans.clear ();
2012         trans.put_command (SCIM_TRANS_CMD_REPLY);
2013         trans.put_command (SCIM_TRANS_CMD_OK);
2014
2015         num = strlist.size ();
2016         trans.put_data (num);
2017         for (unsigned int i = 0; i < num; i++)
2018         {
2019             buf = const_cast<char *>(strlist[i].c_str ());
2020             len = strlen (buf) + 1;
2021             trans.put_data (buf, len);
2022         }
2023
2024         trans.write_to_socket (client_socket);
2025     }
2026
2027     bool reset_ise_option (int client_id)
2028     {
2029         SCIM_DEBUG_MAIN(1) << "PanelAgent::resect_ise_option ()\n";
2030
2031         int    client = -1;
2032         uint32 context;
2033
2034         lock ();
2035
2036         ClientContextUUIDRepository::iterator it = m_client_context_uuids.begin ();
2037         if (it != m_client_context_uuids.end ()) {
2038             get_imengine_client_context (it->first, client, context);
2039         }
2040
2041         if (client >= 0) {
2042             Socket client_socket (client);
2043             m_send_trans.clear ();
2044             m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
2045             m_send_trans.put_data ((uint32) context);
2046             m_send_trans.put_command (ISM_TRANS_CMD_RESET_ISE_OPTION);
2047             m_send_trans.write_to_socket (client_socket);
2048         }
2049
2050         unlock ();
2051
2052         Transaction trans;
2053         trans.clear ();
2054         trans.put_command (SCIM_TRANS_CMD_REPLY);
2055         trans.put_command (SCIM_TRANS_CMD_OK);
2056         Socket client_socket (client_id);
2057         trans.write_to_socket (client_socket);
2058
2059         return client >= 0;
2060     }
2061
2062     bool find_active_ise_by_uuid (String uuid)
2063     {
2064         HelperInfoRepository::iterator iter = m_helper_info_repository.begin ();
2065         for (; iter != m_helper_info_repository.end (); iter++)
2066         {
2067             if (!uuid.compare (iter->second.uuid))
2068                 return true;
2069         }
2070
2071         return false;
2072     }
2073
2074     void set_active_ise_by_uuid (int client_id)
2075     {
2076         SCIM_DEBUG_MAIN(4) << "PanelAgent::set_active_ise_by_uuid ()\n";
2077         char   *buf = NULL;
2078         size_t  len;
2079         Transaction trans;
2080         Socket client_socket (client_id);
2081         m_current_active_imcontrol_id = client_id;
2082
2083         trans.clear ();
2084         trans.put_command (SCIM_TRANS_CMD_REPLY);
2085         if (!(m_recv_trans.get_data (&buf, len)))
2086         {
2087             trans.put_command (SCIM_TRANS_CMD_FAIL);
2088             trans.write_to_socket (client_socket);
2089             if (NULL != buf)
2090                 delete[] buf;
2091             return;
2092         }
2093
2094         String uuid (buf);
2095         ISE_INFO info;
2096
2097         if (!m_signal_get_ise_info_by_uuid (uuid, info))
2098         {
2099             trans.put_command (SCIM_TRANS_CMD_FAIL);
2100             trans.write_to_socket (client_socket);
2101             if (NULL != buf)
2102                 delete[] buf;
2103             return;
2104         }
2105
2106         if (info.type == TOOLBAR_KEYBOARD_MODE)
2107         {
2108             m_signal_set_active_ise_by_uuid (uuid, 1);
2109             trans.put_command (SCIM_TRANS_CMD_OK);
2110             trans.write_to_socket (client_socket);
2111             if (NULL != buf)
2112                 delete[] buf;
2113             return;
2114         }
2115         else if (info.option & ISM_ISE_HIDE_IN_CONTROL_PANEL)
2116         {
2117             int count = _id_count--;
2118             if (info.type == TOOLBAR_HELPER_MODE)
2119             {
2120                 m_current_toolbar_mode = TOOLBAR_HELPER_MODE;
2121                 if (uuid != m_current_helper_uuid)
2122                     m_last_helper_uuid = m_current_helper_uuid;
2123                 start_helper (uuid, count, DEFAULT_CONTEXT_VALUE);
2124                 IMControlRepository::iterator iter = m_imcontrol_repository.find (client_id);
2125                 if (iter == m_imcontrol_repository.end ())
2126                 {
2127                     struct IMControlStub stub;
2128                     stub.count.clear ();
2129                     stub.info.clear ();
2130                     stub.info.push_back (info);
2131                     stub.count.push_back (count);
2132                     m_imcontrol_repository[client_id] = stub;
2133                 }
2134                 else
2135                 {
2136                     iter->second.info.push_back (info);
2137                     iter->second.count.push_back (count);
2138                 }
2139             }
2140         }
2141         else
2142             m_signal_set_active_ise_by_uuid (uuid, 1);
2143
2144         if (find_active_ise_by_uuid (uuid))
2145         {
2146             trans.put_command (SCIM_TRANS_CMD_OK);
2147             trans.write_to_socket (client_socket);
2148         }
2149         else
2150             m_ise_pending_repository[uuid] = client_id;
2151
2152         if (NULL != buf)
2153             delete[] buf;
2154     }
2155
2156     bool find_active_ise_by_name (String name)
2157     {
2158         HelperInfoRepository::iterator iter = m_helper_info_repository.begin ();
2159         for (; iter != m_helper_info_repository.end (); iter++)
2160         {
2161             if (!name.compare (iter->second.name))
2162                 return true;
2163         }
2164
2165         return false;
2166     }
2167
2168     void set_active_ise_by_name (int client_id)
2169     {
2170         char   *buf = NULL;
2171         size_t  len;
2172         Transaction trans;
2173         Socket client_socket (client_id);
2174         m_current_active_imcontrol_id = client_id;
2175
2176         trans.clear ();
2177         trans.put_command (SCIM_TRANS_CMD_REPLY);
2178         if (!(m_recv_trans.get_data (&buf, len)))
2179         {
2180             trans.put_command (SCIM_TRANS_CMD_FAIL);
2181             trans.write_to_socket (client_socket);
2182             if (NULL != buf)
2183                 delete[] buf;
2184             return;
2185         }
2186
2187         String name (buf);
2188         ISE_INFO info;
2189
2190         if (!m_signal_get_ise_info_by_name (name, info))
2191         {
2192             trans.put_command (SCIM_TRANS_CMD_FAIL);
2193             trans.write_to_socket (client_socket);
2194             if (NULL != buf)
2195                 delete[] buf;
2196             return;
2197         }
2198
2199         if (info.type == TOOLBAR_KEYBOARD_MODE)
2200         {
2201             m_signal_set_keyboard_ise (ISM_TRANS_CMD_SET_KEYBOARD_ISE_BY_NAME, name);
2202             trans.put_command (SCIM_TRANS_CMD_OK);
2203             trans.write_to_socket (client_socket);
2204             if (NULL != buf)
2205                 delete[] buf;
2206             return;
2207         }
2208         else if (info.option & ISM_ISE_HIDE_IN_CONTROL_PANEL)
2209         {
2210             int count = _id_count--;
2211             if (info.type == TOOLBAR_HELPER_MODE)
2212             {
2213                 m_current_toolbar_mode = TOOLBAR_HELPER_MODE;
2214                 if (info.uuid != m_current_helper_uuid)
2215                     m_last_helper_uuid = m_current_helper_uuid;
2216                 start_helper (info.uuid, count, DEFAULT_CONTEXT_VALUE);
2217                 IMControlRepository::iterator iter = m_imcontrol_repository.find (client_id);
2218                 if (iter == m_imcontrol_repository.end ())
2219                 {
2220                     struct IMControlStub stub;
2221                     stub.count.clear ();
2222                     stub.info.clear ();
2223                     stub.info.push_back (info);
2224                     stub.count.push_back (count);
2225                     m_imcontrol_repository[client_id] = stub;
2226                 }
2227                 else
2228                 {
2229                     iter->second.info.push_back (info);
2230                     iter->second.count.push_back (count);
2231                 }
2232             }
2233         }
2234         else
2235             m_signal_set_active_ise_by_name (name);
2236
2237         if (find_active_ise_by_name (name))
2238         {
2239             trans.put_command (SCIM_TRANS_CMD_OK);
2240             trans.write_to_socket (client_socket);
2241         }
2242         else
2243             m_ise_pending_repository[name] = client_id;
2244
2245         if (NULL != buf)
2246             delete[] buf;
2247     }
2248
2249     void update_isf_control_status (const bool showed)
2250     {
2251         for (ClientRepository::iterator iter = m_client_repository.begin ();
2252              iter != m_client_repository.end (); ++iter)
2253         {
2254             if (IMCONTROL_CLIENT == iter->second.type
2255                 && iter->first == m_imcontrol_map[m_current_active_imcontrol_id])
2256             {
2257                 Socket client_socket (iter->first);
2258                 Transaction trans;
2259
2260                 trans.clear ();
2261                 trans.put_command (SCIM_TRANS_CMD_REQUEST);
2262                 if (showed)
2263                     trans.put_command (ISM_TRANS_CMD_ISF_CONTROL_SHOWED);
2264                 else
2265                     trans.put_command (ISM_TRANS_CMD_ISF_CONTROL_HIDED);
2266                 trans.write_to_socket (client_socket);
2267                 break;
2268             }
2269         }
2270         return;
2271     }
2272
2273     void set_ise_private_key (int client_id, bool is_image)
2274     {
2275         SCIM_DEBUG_MAIN(4) << "PanelAgent::set_ise_private_key ()\n";
2276         uint32 layout_idx, key_idx;
2277         char  *label = NULL, *value = NULL;
2278         size_t len1, len2;
2279
2280         if (m_recv_trans.get_data (layout_idx)
2281             && m_recv_trans.get_data (key_idx)
2282             && m_recv_trans.get_data (&label, len1)
2283             && m_recv_trans.get_data (&value, len2))
2284         {
2285             if (TOOLBAR_HELPER_MODE == m_current_toolbar_mode)
2286                 set_helper_private_key (m_current_helper_uuid,
2287                                         layout_idx,
2288                                         key_idx,
2289                                         label,
2290                                         len1,
2291                                         value,
2292                                         len2,
2293                                         is_image);
2294         }
2295
2296         if (NULL != label)
2297             delete[] label;
2298         if (NULL != value)
2299             delete[] value;
2300     }
2301
2302     void set_ise_disable_key (int client_id)
2303     {
2304         SCIM_DEBUG_MAIN(4) << "PanelAgent::set_ise_disable_key ()\n";
2305         uint32 layout_idx, key_idx, disabled;
2306
2307         if (m_recv_trans.get_data (layout_idx)
2308             && m_recv_trans.get_data (key_idx)
2309             && m_recv_trans.get_data (disabled))
2310         {
2311             if (TOOLBAR_HELPER_MODE == m_current_toolbar_mode)
2312                 set_helper_disable_key (m_current_helper_uuid,
2313                                         layout_idx,
2314                                         key_idx,
2315                                         disabled);
2316         }
2317     }
2318
2319     int get_active_ise_list (std::vector<String> &strlist)
2320     {
2321         strlist.clear ();
2322         m_helper_manager.get_active_ise_list (strlist);
2323         return (int)(strlist.size ());
2324     }
2325
2326     void reset_helper_context (const String &uuid)
2327     {
2328         HelperClientIndex::iterator it = m_helper_client_index.find (m_current_helper_uuid);
2329
2330         if (it != m_helper_client_index.end ())
2331         {
2332             int client;
2333             uint32 context;
2334             Socket client_socket (it->second.id);
2335             uint32 ctx;
2336
2337             get_focused_context (client, context);
2338             ctx = get_helper_ic (client, context);
2339
2340             m_send_trans.clear ();
2341             m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
2342             m_send_trans.put_data (ctx);
2343             m_send_trans.put_data (uuid);
2344             m_send_trans.put_command (ISM_TRANS_CMD_RESET_ISE_CONTEXT);
2345             m_send_trans.write_to_socket (client_socket);
2346         }
2347     }
2348
2349     void reset_ise_context (int client_id)
2350     {
2351         SCIM_DEBUG_MAIN(4) << "PanelAgent::reset_ise_context ()\n";
2352         TOOLBAR_MODE_T mode;
2353
2354         mode = m_current_toolbar_mode;
2355
2356         if (TOOLBAR_HELPER_MODE == mode)
2357         {
2358             reset_helper_context (m_current_helper_uuid);
2359         }
2360     }
2361
2362     bool set_helper_screen_direction (const String &uuid, uint32 &direction)
2363     {
2364         HelperClientIndex::iterator it = m_helper_client_index.find (m_current_helper_uuid);
2365
2366         if (it != m_helper_client_index.end ())
2367         {
2368             int client;
2369             uint32 context;
2370             Socket client_socket (it->second.id);
2371             uint32 ctx;
2372
2373             get_focused_context (client, context);
2374             ctx = get_helper_ic (client, context);
2375
2376             m_send_trans.clear ();
2377             m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
2378             m_send_trans.put_data (ctx);
2379             m_send_trans.put_data (uuid);
2380             m_send_trans.put_command (ISM_TRANS_CMD_SET_ISE_SCREEN_DIRECTION);
2381             m_send_trans.put_data (direction);
2382             m_send_trans.write_to_socket (client_socket);
2383             return true;
2384         }
2385
2386         return false;
2387     }
2388
2389     void set_ise_screen_direction (int client_id)
2390     {
2391         SCIM_DEBUG_MAIN(4) << "PanelAgent::set_ise_screen_direction ()\n";
2392         uint32 direction;
2393
2394         if (m_recv_trans.get_data (direction))
2395         {
2396             if (TOOLBAR_HELPER_MODE == m_current_toolbar_mode)
2397                 set_helper_screen_direction (m_current_helper_uuid, direction);
2398         }
2399     }
2400
2401     void set_ise_caps_mode (int client_id)
2402     {
2403         SCIM_DEBUG_MAIN(4) << "PanelAgent::set_ise_caps_mode ()\n";
2404         uint32 mode;
2405
2406         if (m_recv_trans.get_data (mode))
2407         {
2408             if (TOOLBAR_HELPER_MODE == m_current_toolbar_mode)
2409                 set_helper_caps_mode (m_current_helper_uuid, mode);
2410         }
2411     }
2412
2413     int send_display_name (String &name)
2414     {
2415         return m_helper_manager.send_display_name (name);
2416     }
2417
2418     bool reload_config (void)
2419     {
2420         SCIM_DEBUG_MAIN(1) << "PanelAgent::reload_config ()\n";
2421
2422         lock ();
2423
2424         m_send_trans.clear ();
2425         m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
2426         m_send_trans.put_command (SCIM_TRANS_CMD_RELOAD_CONFIG);
2427
2428         for (ClientRepository::iterator it = m_client_repository.begin ();
2429              it != m_client_repository.end (); ++it) {
2430
2431             if (it->second.type == IMCONTROL_ACT_CLIENT
2432                 || it->second.type == IMCONTROL_CLIENT
2433                 || it->second.type == HELPER_ACT_CLIENT)
2434                 continue;
2435
2436             Socket client_socket (it->first);
2437             m_send_trans.write_to_socket (client_socket);
2438         }
2439
2440         unlock ();
2441         return true;
2442     }
2443
2444     bool exit (void)
2445     {
2446         SCIM_DEBUG_MAIN(1) << "PanelAgent::exit ()\n";
2447
2448         lock ();
2449
2450         m_send_trans.clear ();
2451         m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
2452         m_send_trans.put_command (SCIM_TRANS_CMD_EXIT);
2453
2454         for (ClientRepository::iterator it = m_client_repository.begin ();
2455              it != m_client_repository.end (); ++it) {
2456             Socket client_socket (it->first);
2457             m_send_trans.write_to_socket (client_socket);
2458         }
2459
2460         unlock ();
2461
2462         stop ();
2463
2464         return true;
2465     }
2466
2467     bool filter_event (int fd)
2468     {
2469         SCIM_DEBUG_MAIN (1) << "PanelAgent::filter_event ()\n";
2470
2471         return m_socket_server.filter_event (fd);
2472     }
2473
2474     bool filter_exception_event (int fd)
2475     {
2476         SCIM_DEBUG_MAIN (1) << "PanelAgent::filter_exception_event ()\n";
2477
2478         return m_socket_server.filter_exception_event (fd);
2479     }
2480
2481     int get_server_id ()
2482     {
2483         SCIM_DEBUG_MAIN (1) << "PanelAgent::get_server_id ()\n";
2484
2485         return m_socket_server.get_id ();
2486     }
2487
2488     void set_ise_changing (bool changing)
2489     {
2490         SCIM_DEBUG_MAIN (1) << "PanelAgent::set_ise_changing ()\n";
2491         m_ise_changing = changing;
2492     }
2493
2494     void update_ise_list (std::vector<String> &strList)
2495     {
2496         /* send ise list to frontend */
2497         String dst_str = scim_combine_string_list (strList);
2498         m_helper_manager.send_ise_list (dst_str);
2499
2500         /* request PanelClient to update keyboard ise list */
2501         update_keyboard_ise_list ();
2502     }
2503
2504     Connection signal_connect_reload_config              (PanelAgentSlotVoid                *slot)
2505     {
2506         return m_signal_reload_config.connect (slot);
2507     }
2508
2509     Connection signal_connect_turn_on                    (PanelAgentSlotVoid                *slot)
2510     {
2511         return m_signal_turn_on.connect (slot);
2512     }
2513
2514     Connection signal_connect_turn_off                   (PanelAgentSlotVoid                *slot)
2515     {
2516         return m_signal_turn_off.connect (slot);
2517     }
2518
2519     Connection signal_connect_show_panel                 (PanelAgentSlotVoid                *slot)
2520     {
2521         return m_signal_show_panel.connect (slot);
2522     }
2523
2524     Connection signal_connect_hide_panel                 (PanelAgentSlotVoid                *slot)
2525     {
2526         return m_signal_hide_panel.connect (slot);
2527     }
2528
2529     Connection signal_connect_update_screen              (PanelAgentSlotInt                 *slot)
2530     {
2531         return m_signal_update_screen.connect (slot);
2532     }
2533
2534     Connection signal_connect_update_spot_location       (PanelAgentSlotIntIntInt           *slot)
2535     {
2536         return m_signal_update_spot_location.connect (slot);
2537     }
2538
2539     Connection signal_connect_update_factory_info        (PanelAgentSlotFactoryInfo         *slot)
2540     {
2541         return m_signal_update_factory_info.connect (slot);
2542     }
2543
2544     Connection signal_connect_start_default_ise          (PanelAgentSlotVoid                *slot)
2545     {
2546         return m_signal_start_default_ise.connect (slot);
2547     }
2548
2549     Connection signal_connect_set_candidate_ui           (PanelAgentSlotIntInt              *slot)
2550     {
2551         return m_signal_set_candidate_ui.connect (slot);
2552     }
2553
2554     Connection signal_connect_get_candidate_ui           (PanelAgentSlotIntInt2             *slot)
2555     {
2556         return m_signal_get_candidate_ui.connect (slot);
2557     }
2558
2559     Connection signal_connect_set_candidate_position     (PanelAgentSlotIntInt              *slot)
2560     {
2561         return m_signal_set_candidate_position.connect (slot);
2562     }
2563
2564     Connection signal_connect_get_candidate_rect         (PanelAgentSlotRect                *slot)
2565     {
2566         return m_signal_get_candidate_rect.connect (slot);
2567     }
2568
2569     Connection signal_connect_set_keyboard_ise           (PanelAgentSlotIntString           *slot)
2570     {
2571         return m_signal_set_keyboard_ise.connect (slot);
2572     }
2573
2574     Connection signal_connect_get_keyboard_ise           (PanelAgentSlotString2             *slot)
2575     {
2576         return m_signal_get_keyboard_ise.connect (slot);
2577     }
2578
2579     Connection signal_connect_show_help                  (PanelAgentSlotString              *slot)
2580     {
2581         return m_signal_show_help.connect (slot);
2582     }
2583
2584     Connection signal_connect_show_factory_menu          (PanelAgentSlotFactoryInfoVector   *slot)
2585     {
2586         return m_signal_show_factory_menu.connect (slot);
2587     }
2588
2589     Connection signal_connect_show_preedit_string        (PanelAgentSlotVoid                *slot)
2590     {
2591         return m_signal_show_preedit_string.connect (slot);
2592     }
2593
2594     Connection signal_connect_show_aux_string            (PanelAgentSlotVoid                *slot)
2595     {
2596         return m_signal_show_aux_string.connect (slot);
2597     }
2598
2599     Connection signal_connect_show_lookup_table          (PanelAgentSlotVoid                *slot)
2600     {
2601         return m_signal_show_lookup_table.connect (slot);
2602     }
2603
2604     Connection signal_connect_show_associate_table       (PanelAgentSlotVoid                *slot)
2605     {
2606         return m_signal_show_associate_table.connect (slot);
2607     }
2608
2609     Connection signal_connect_hide_preedit_string        (PanelAgentSlotVoid                *slot)
2610     {
2611         return m_signal_hide_preedit_string.connect (slot);
2612     }
2613
2614     Connection signal_connect_hide_aux_string            (PanelAgentSlotVoid                *slot)
2615     {
2616         return m_signal_hide_aux_string.connect (slot);
2617     }
2618
2619     Connection signal_connect_hide_lookup_table          (PanelAgentSlotVoid                *slot)
2620     {
2621         return m_signal_hide_lookup_table.connect (slot);
2622     }
2623
2624     Connection signal_connect_hide_associate_table       (PanelAgentSlotVoid                *slot)
2625     {
2626         return m_signal_hide_associate_table.connect (slot);
2627     }
2628
2629     Connection signal_connect_update_preedit_string      (PanelAgentSlotAttributeString     *slot)
2630     {
2631         return m_signal_update_preedit_string.connect (slot);
2632     }
2633
2634     Connection signal_connect_update_preedit_caret       (PanelAgentSlotInt                 *slot)
2635     {
2636         return m_signal_update_preedit_caret.connect (slot);
2637     }
2638
2639     Connection signal_connect_update_aux_string          (PanelAgentSlotAttributeString     *slot)
2640     {
2641         return m_signal_update_aux_string.connect (slot);
2642     }
2643
2644     Connection signal_connect_update_lookup_table        (PanelAgentSlotLookupTable         *slot)
2645     {
2646         return m_signal_update_lookup_table.connect (slot);
2647     }
2648
2649     Connection signal_connect_update_associate_table     (PanelAgentSlotLookupTable         *slot)
2650     {
2651         return m_signal_update_associate_table.connect (slot);
2652     }
2653
2654     Connection signal_connect_register_properties        (PanelAgentSlotPropertyList        *slot)
2655     {
2656         return m_signal_register_properties.connect (slot);
2657     }
2658
2659     Connection signal_connect_update_property            (PanelAgentSlotProperty            *slot)
2660     {
2661         return m_signal_update_property.connect (slot);
2662     }
2663
2664     Connection signal_connect_register_helper_properties (PanelAgentSlotIntPropertyList     *slot)
2665     {
2666         return m_signal_register_helper_properties.connect (slot);
2667     }
2668
2669     Connection signal_connect_update_helper_property     (PanelAgentSlotIntProperty         *slot)
2670     {
2671         return m_signal_update_helper_property.connect (slot);
2672     }
2673
2674     Connection signal_connect_register_helper            (PanelAgentSlotIntHelperInfo       *slot)
2675     {
2676         return m_signal_register_helper.connect (slot);
2677     }
2678
2679     Connection signal_connect_remove_helper              (PanelAgentSlotInt                 *slot)
2680     {
2681         return m_signal_remove_helper.connect (slot);
2682     }
2683
2684     Connection signal_connect_set_active_ise_by_uuid     (PanelAgentSlotStringBool          *slot)
2685     {
2686         return m_signal_set_active_ise_by_uuid.connect (slot);
2687     }
2688
2689     Connection signal_connect_set_active_ise_by_name     (PanelAgentSlotString                 *slot)
2690     {
2691         return m_signal_set_active_ise_by_name.connect (slot);
2692     }
2693
2694     Connection signal_connect_focus_in                   (PanelAgentSlotVoid                   *slot)
2695     {
2696         return m_signal_focus_in.connect (slot);
2697     }
2698
2699     Connection signal_connect_focus_out                  (PanelAgentSlotVoid                   *slot)
2700     {
2701         return m_signal_focus_out.connect (slot);
2702     }
2703
2704     Connection signal_connect_get_ise_list               (PanelAgentSlotBoolStringVector       *slot)
2705     {
2706         return m_signal_get_ise_list.connect (slot);
2707     }
2708
2709     Connection signal_connect_get_keyboard_ise_list      (PanelAgentSlotBoolStringVector       *slot)
2710     {
2711         return m_signal_get_keyboard_ise_list.connect (slot);
2712     }
2713     Connection signal_connect_launch_helper_ise_list_selection (PanelAgentSlotInt              *slot)
2714     {
2715         return m_signal_launch_helper_ise_list_selection.connect (slot);
2716     }
2717
2718     Connection signal_connect_get_language_list          (PanelAgentSlotStringVector           *slot)
2719     {
2720         return m_signal_get_language_list.connect (slot);
2721     }
2722
2723     Connection signal_connect_get_all_language           (PanelAgentSlotStringVector           *slot)
2724     {
2725         return m_signal_get_all_language.connect (slot);
2726     }
2727
2728     Connection signal_connect_get_ise_language           (PanelAgentSlotStrStringVector        *slot)
2729     {
2730         return m_signal_get_ise_language.connect (slot);
2731     }
2732
2733     Connection signal_connect_set_isf_language           (PanelAgentSlotString                 *slot)
2734     {
2735         return m_signal_set_isf_language.connect (slot);
2736     }
2737
2738     Connection signal_connect_get_ise_info_by_uuid       (PanelAgentSlotStringISEINFO          *slot)
2739     {
2740         return m_signal_get_ise_info_by_uuid.connect (slot);
2741     }
2742
2743     Connection signal_connect_get_ise_info_by_name       (PanelAgentSlotStringISEINFO          *slot)
2744     {
2745         return m_signal_get_ise_info_by_name.connect (slot);
2746     }
2747
2748     Connection signal_connect_send_key_event             (PanelAgentSlotKeyEvent               *slot)
2749     {
2750         return m_signal_send_key_event.connect (slot);
2751     }
2752
2753     Connection signal_connect_accept_connection          (PanelAgentSlotInt                    *slot)
2754     {
2755         return m_signal_accept_connection.connect (slot);
2756     }
2757
2758     Connection signal_connect_close_connection           (PanelAgentSlotInt                    *slot)
2759     {
2760         return m_signal_close_connection.connect (slot);
2761     }
2762
2763     Connection signal_connect_exit                       (PanelAgentSlotVoid                   *slot)
2764     {
2765         return m_signal_exit.connect (slot);
2766     }
2767
2768     Connection signal_connect_transaction_start          (PanelAgentSlotVoid                   *slot)
2769     {
2770         return m_signal_transaction_start.connect (slot);
2771     }
2772
2773     Connection signal_connect_transaction_end            (PanelAgentSlotVoid                   *slot)
2774     {
2775         return m_signal_transaction_end.connect (slot);
2776     }
2777
2778     Connection signal_connect_lock                       (PanelAgentSlotVoid                   *slot)
2779     {
2780         return m_signal_lock.connect (slot);
2781     }
2782
2783     Connection signal_connect_unlock                     (PanelAgentSlotVoid                   *slot)
2784     {
2785         return m_signal_unlock.connect (slot);
2786     }
2787
2788 private:
2789     bool socket_check_client_connection (const Socket &client)
2790     {
2791         SCIM_DEBUG_MAIN (3) << "PanelAgent::socket_check_client_connection (" << client.get_id () << ")\n";
2792
2793         unsigned char buf [sizeof(uint32)];
2794
2795         int nbytes = client.read_with_timeout (buf, sizeof(uint32), m_socket_timeout);
2796
2797         if (nbytes == sizeof (uint32))
2798             return true;
2799
2800         if (nbytes < 0) {
2801             SCIM_DEBUG_MAIN (4) << "Error occurred when reading socket: " << client.get_error_message () << ".\n";
2802         } else {
2803             SCIM_DEBUG_MAIN (4) << "Timeout when reading socket.\n";
2804         }
2805
2806         return false;
2807     }
2808
2809     void socket_accept_callback                 (SocketServer   *server,
2810                                                  const Socket   &client)
2811     {
2812         SCIM_DEBUG_MAIN (2) << "PanelAgent::socket_accept_callback (" << client.get_id () << ")\n";
2813
2814         lock ();
2815         if (m_should_exit) {
2816             SCIM_DEBUG_MAIN (3) << "Exit Socket Server Thread.\n";
2817             server->shutdown ();
2818         } else
2819             m_signal_accept_connection (client.get_id ());
2820         unlock ();
2821     }
2822
2823     void socket_receive_callback                (SocketServer   *server,
2824                                                  const Socket   &client)
2825     {
2826         int     client_id = client.get_id ();
2827         int     cmd     = 0;
2828         uint32  key     = 0;
2829         uint32  context = 0;
2830         String  uuid;
2831         bool    current = false;
2832         bool    last    = false;
2833
2834         ClientInfo client_info;
2835
2836         SCIM_DEBUG_MAIN (1) << "PanelAgent::socket_receive_callback (" << client_id << ")\n";
2837
2838         /* If the connection is closed then close this client. */
2839         if (!socket_check_client_connection (client)) {
2840             socket_close_connection (server, client);
2841             return;
2842         }
2843
2844         client_info = socket_get_client_info (client_id);
2845
2846         /* If it's a new client, then request to open the connection first. */
2847         if (client_info.type == UNKNOWN_CLIENT) {
2848             socket_open_connection (server, client);
2849             return;
2850         }
2851
2852         /* If can not read the transaction,
2853          * or the transaction is not started with SCIM_TRANS_CMD_REQUEST,
2854          * or the key is mismatch,
2855          * just return. */
2856         if (!m_recv_trans.read_from_socket (client, m_socket_timeout) ||
2857             !m_recv_trans.get_command (cmd) || cmd != SCIM_TRANS_CMD_REQUEST ||
2858             !m_recv_trans.get_data (key)    || key != (uint32) client_info.key)
2859             return;
2860
2861         if (client_info.type == FRONTEND_CLIENT) {
2862             if (m_recv_trans.get_data (context)) {
2863                 SCIM_DEBUG_MAIN (1) << "PanelAgent::FrontEnd Client, context = " << context << "\n";
2864                 socket_transaction_start();
2865                 while (m_recv_trans.get_command (cmd)) {
2866                     SCIM_DEBUG_MAIN (3) << "PanelAgent::cmd = " << cmd << "\n";
2867
2868                     if (cmd == SCIM_TRANS_CMD_PANEL_REGISTER_INPUT_CONTEXT) {
2869                         if (m_recv_trans.get_data (uuid)) {
2870                             SCIM_DEBUG_MAIN (2) << "PanelAgent::register_input_context (" << client_id << "," << "," << context << "," << uuid << ")\n";
2871                             uint32 ctx = get_helper_ic (client_id, context);
2872                             m_client_context_uuids [ctx] = uuid;
2873                         }
2874                         continue;
2875                     }
2876
2877                     if (cmd == ISM_TRANS_CMD_PANEL_START_DEFAULT_ISE) {
2878                         if ((m_default_ise.type == TOOLBAR_HELPER_MODE) && (m_default_ise.uuid.length () > 0))
2879                         {
2880                             m_current_toolbar_mode = TOOLBAR_HELPER_MODE;
2881                             start_helper (m_default_ise.uuid, client_id, context);
2882                         }
2883                         else if (m_default_ise.type == TOOLBAR_KEYBOARD_MODE)
2884                         {
2885                             m_current_toolbar_mode = TOOLBAR_KEYBOARD_MODE;
2886                         }
2887                         continue;
2888                     }
2889
2890                     if (cmd == SCIM_TRANS_CMD_PANEL_REMOVE_INPUT_CONTEXT) {
2891                         uint32 ctx = get_helper_ic (client_id, context);
2892                         m_client_context_uuids.erase (ctx);
2893 #ifdef ONE_HELPER_ISE_PROCESS
2894                         if (m_client_context_helper.find (ctx) != m_client_context_helper.end ())
2895                             stop_helper (m_client_context_helper[ctx], client_id, context);
2896 #endif
2897                         if (ctx == get_helper_ic (m_current_socket_client, m_current_client_context))
2898                         {
2899                             lock ();
2900                             m_current_socket_client  = m_last_socket_client;
2901                             m_current_client_context = m_last_client_context;
2902                             m_current_context_uuid   = m_last_context_uuid;
2903                             m_last_socket_client     = -1;
2904                             m_last_client_context    = 0;
2905                             m_last_context_uuid      = String ("");
2906                             if (m_current_socket_client == -1)
2907                             {
2908                                 unlock ();
2909                                 socket_update_control_panel ();
2910                             }
2911                             else
2912                                 unlock ();
2913                         }
2914                         else if (ctx == get_helper_ic (m_last_socket_client, m_last_client_context))
2915                         {
2916                             lock ();
2917                             m_last_socket_client  = -1;
2918                             m_last_client_context = 0;
2919                             m_last_context_uuid   = String ("");
2920                             unlock ();
2921                         }
2922                         continue;
2923                     }
2924
2925                     if (cmd == SCIM_TRANS_CMD_PANEL_RESET_INPUT_CONTEXT) {
2926                         socket_reset_input_context (client_id, context);
2927                         continue;
2928                     }
2929
2930                     if (cmd == SCIM_TRANS_CMD_FOCUS_IN) {
2931                         get_helper_ic (client_id, context);
2932                         m_signal_focus_in ();
2933                         if (TOOLBAR_HELPER_MODE == m_current_toolbar_mode)
2934                             focus_in_helper (m_current_helper_uuid, client_id, context);
2935 #ifdef ONE_HELPER_ISE_PROCESS
2936                         uint32 ctx = get_helper_ic (client_id, context);
2937                         ClientContextUUIDRepository::iterator it = m_client_context_helper.find (ctx);
2938                         if (it != m_client_context_helper.end ())
2939                         {
2940                             if (m_should_shared_ise)
2941                             {
2942                                 if (TOOLBAR_HELPER_MODE == m_current_toolbar_mode)
2943                                 {
2944                                     if (m_current_helper_uuid != it->second)
2945                                     {
2946                                         stop_helper (it->second, client_id, context);
2947                                         start_helper (m_current_helper_uuid, client_id, context);
2948                                     }
2949                                     focus_in_helper (m_current_helper_uuid, client_id, context);
2950                                 }
2951                                 else if (TOOLBAR_KEYBOARD_MODE == m_current_toolbar_mode)
2952                                     stop_helper (it->second, client_id, context);
2953                             }
2954                             else
2955                             {
2956                                 /* focus in the helper if the context is associated with some helper */
2957                                 m_current_toolbar_mode = TOOLBAR_HELPER_MODE;
2958                                 m_current_helper_uuid  = it->second;
2959                                 focus_in_helper (m_current_helper_uuid, client_id, context);
2960                             }
2961                         }
2962                         else
2963                         {
2964                             if (m_should_shared_ise)
2965                             {
2966                                 if (TOOLBAR_HELPER_MODE == m_current_toolbar_mode)
2967                                 {
2968                                     start_helper (m_current_helper_uuid, client_id, context);
2969                                     focus_in_helper (m_current_helper_uuid, client_id, context);
2970                                 }
2971                             }
2972                             else
2973                             {
2974                                 /* come here if the context is associated with some imengine */
2975                                 m_current_toolbar_mode = TOOLBAR_KEYBOARD_MODE;
2976                             }
2977                         }
2978 #endif
2979                         if (m_recv_trans.get_data (uuid)) {
2980                             SCIM_DEBUG_MAIN (2) << "PanelAgent::focus_in (" << client_id << "," << "," << context << "," << uuid << ")\n";
2981                             lock ();
2982                             if (m_current_socket_client >= 0) {
2983                                 m_last_socket_client  = m_current_socket_client;
2984                                 m_last_client_context = m_current_client_context;
2985                                 m_last_context_uuid   = m_current_context_uuid;
2986                             }
2987                             m_current_socket_client  = client_id;
2988                             m_current_client_context = context;
2989                             m_current_context_uuid   = uuid;
2990                             unlock ();
2991                         }
2992                         continue;
2993                     }
2994
2995                     if (cmd == ISM_TRANS_CMD_TURN_ON_LOG) {
2996                         socket_turn_on_log ();
2997                         continue;
2998                     }
2999
3000                     current = last = false;
3001                     uuid.clear ();
3002
3003                     /* Get the context uuid from the client context registration table. */
3004                     {
3005                         ClientContextUUIDRepository::iterator it = m_client_context_uuids.find (get_helper_ic (client_id, context));
3006                         if (it != m_client_context_uuids.end ())
3007                             uuid = it->second;
3008                     }
3009
3010                     if (m_current_socket_client == client_id && m_current_client_context == context) {
3011                         current = true;
3012                         if (!uuid.length ()) uuid = m_current_context_uuid;
3013                     } else if (m_last_socket_client == client_id && m_last_client_context == context) {
3014                         last = true;
3015                         if (!uuid.length ()) uuid = m_last_context_uuid;
3016                     }
3017
3018                     /* Skip to the next command and continue, if it's not current or last focused. */
3019                     if (!uuid.length ()) {
3020                         SCIM_DEBUG_MAIN (3) << "PanelAgent:: Couldn't find context uuid.\n";
3021                         while (m_recv_trans.get_data_type () != SCIM_TRANS_DATA_COMMAND && m_recv_trans.get_data_type () != SCIM_TRANS_DATA_UNKNOWN)
3022                             m_recv_trans.skip_data ();
3023                         continue;
3024                     }
3025
3026                     if (cmd == SCIM_TRANS_CMD_START_HELPER) {
3027                         socket_start_helper (client_id, context, uuid);
3028                         continue;
3029                     }
3030                     else if (cmd == SCIM_TRANS_CMD_SEND_HELPER_EVENT) {
3031                         socket_send_helper_event (client_id, context, uuid);
3032                         continue;
3033                     }
3034                     else if (cmd == SCIM_TRANS_CMD_STOP_HELPER) {
3035                         socket_stop_helper (client_id, context, uuid);
3036                         continue;
3037                     }
3038
3039                     /* If it's not focused, just continue. */
3040                     if ((!current && !last) || (last && m_current_socket_client >= 0)) {
3041                         SCIM_DEBUG_MAIN (3) << "PanelAgent::Not current focused.\n";
3042                         while (m_recv_trans.get_data_type () != SCIM_TRANS_DATA_COMMAND && m_recv_trans.get_data_type () != SCIM_TRANS_DATA_UNKNOWN)
3043                             m_recv_trans.skip_data ();
3044                         continue;
3045                     }
3046
3047                     /* Client must focus in before do any other things. */
3048                     if (cmd == SCIM_TRANS_CMD_PANEL_TURN_ON)
3049                         socket_turn_on ();
3050                     else if (cmd == SCIM_TRANS_CMD_PANEL_TURN_OFF)
3051                         socket_turn_off ();
3052                     else if (cmd == SCIM_TRANS_CMD_UPDATE_SCREEN)
3053                         socket_update_screen ();
3054                     else if (cmd == SCIM_TRANS_CMD_UPDATE_SPOT_LOCATION)
3055                         socket_update_spot_location ();
3056                     else if (cmd == ISM_TRANS_CMD_UPDATE_CURSOR_POSITION)
3057                         socket_update_cursor_position ();
3058                     else if (cmd == ISM_TRANS_CMD_UPDATE_SURROUNDING_TEXT)
3059                         socket_update_surrounding_text ();
3060                     else if (cmd == SCIM_TRANS_CMD_PANEL_UPDATE_FACTORY_INFO)
3061                         socket_update_factory_info ();
3062                     else if (cmd == SCIM_TRANS_CMD_SHOW_PREEDIT_STRING)
3063                         socket_show_preedit_string ();
3064                     else if (cmd == SCIM_TRANS_CMD_SHOW_AUX_STRING)
3065                         socket_show_aux_string ();
3066                     else if (cmd == SCIM_TRANS_CMD_SHOW_LOOKUP_TABLE)
3067                         socket_show_lookup_table ();
3068                     else if (cmd == ISM_TRANS_CMD_SHOW_ASSOCIATE_TABLE)
3069                         socket_show_associate_table ();
3070                     else if (cmd == SCIM_TRANS_CMD_HIDE_PREEDIT_STRING)
3071                         socket_hide_preedit_string ();
3072                     else if (cmd == SCIM_TRANS_CMD_HIDE_AUX_STRING)
3073                         socket_hide_aux_string ();
3074                     else if (cmd == SCIM_TRANS_CMD_HIDE_LOOKUP_TABLE)
3075                         socket_hide_lookup_table ();
3076                     else if (cmd == ISM_TRANS_CMD_HIDE_ASSOCIATE_TABLE)
3077                         socket_hide_associate_table ();
3078                     else if (cmd == SCIM_TRANS_CMD_UPDATE_PREEDIT_STRING)
3079                         socket_update_preedit_string ();
3080                     else if (cmd == SCIM_TRANS_CMD_UPDATE_PREEDIT_CARET)
3081                         socket_update_preedit_caret ();
3082                     else if (cmd == SCIM_TRANS_CMD_UPDATE_AUX_STRING)
3083                         socket_update_aux_string ();
3084                     else if (cmd == SCIM_TRANS_CMD_UPDATE_LOOKUP_TABLE)
3085                         socket_update_lookup_table ();
3086                     else if (cmd == ISM_TRANS_CMD_UPDATE_ASSOCIATE_TABLE)
3087                         socket_update_associate_table ();
3088                     else if (cmd == SCIM_TRANS_CMD_REGISTER_PROPERTIES)
3089                         socket_register_properties ();
3090                     else if (cmd == SCIM_TRANS_CMD_UPDATE_PROPERTY)
3091                         socket_update_property ();
3092                     else if (cmd == SCIM_TRANS_CMD_PANEL_SHOW_HELP)
3093                         socket_show_help ();
3094                     else if (cmd == SCIM_TRANS_CMD_PANEL_SHOW_FACTORY_MENU)
3095                         socket_show_factory_menu ();
3096                     else if (cmd == SCIM_TRANS_CMD_FOCUS_OUT) {
3097                         m_signal_focus_out ();
3098                         lock ();
3099                         TOOLBAR_MODE_T mode = m_current_toolbar_mode;
3100
3101                         if (TOOLBAR_HELPER_MODE == mode)
3102                             focus_out_helper (m_current_helper_uuid, client_id, context);
3103
3104                         if (m_current_socket_client >= 0) {
3105                             m_last_socket_client  = m_current_socket_client;
3106                             m_last_client_context = m_current_client_context;
3107                             m_last_context_uuid   = m_current_context_uuid;
3108                         }
3109                         m_current_socket_client  = -1;
3110                         m_current_client_context = 0;
3111                         m_current_context_uuid   = String ("");
3112                         unlock ();
3113                     }
3114                 }
3115                 socket_transaction_end ();
3116             }
3117         } else if (client_info.type == HELPER_CLIENT) {
3118             socket_transaction_start ();
3119             while (m_recv_trans.get_command (cmd)) {
3120                 if (cmd == SCIM_TRANS_CMD_PANEL_REGISTER_HELPER) {
3121                     socket_helper_register_helper (client_id);
3122                 }
3123             }
3124             socket_transaction_end ();
3125         }else if (client_info.type == HELPER_ACT_CLIENT) {
3126             socket_transaction_start ();
3127             while (m_recv_trans.get_command (cmd)) {
3128                 if (cmd == SCIM_TRANS_CMD_PANEL_REGISTER_ACTIVE_HELPER) {
3129                     socket_helper_register_helper_passive (client_id);
3130                 } else if (cmd == SCIM_TRANS_CMD_COMMIT_STRING) {
3131                     socket_helper_commit_string (client_id);
3132                 } else if (cmd == SCIM_TRANS_CMD_SHOW_PREEDIT_STRING) {
3133                     socket_helper_show_preedit_string (client_id);
3134                 } else if (cmd == SCIM_TRANS_CMD_SHOW_AUX_STRING) {
3135                     socket_show_aux_string ();
3136                 } else if (cmd == SCIM_TRANS_CMD_SHOW_LOOKUP_TABLE) {
3137                     socket_show_lookup_table ();
3138                 } else if (cmd == ISM_TRANS_CMD_SHOW_ASSOCIATE_TABLE) {
3139                     socket_show_associate_table ();
3140                 } else if (cmd == SCIM_TRANS_CMD_HIDE_PREEDIT_STRING) {
3141                     socket_helper_hide_preedit_string (client_id);
3142                 } else if (cmd == SCIM_TRANS_CMD_HIDE_AUX_STRING) {
3143                     socket_hide_aux_string ();
3144                 } else if (cmd == SCIM_TRANS_CMD_HIDE_LOOKUP_TABLE) {
3145                     socket_hide_lookup_table ();
3146                 } else if (cmd == ISM_TRANS_CMD_HIDE_ASSOCIATE_TABLE) {
3147                     socket_hide_associate_table ();
3148                 } else if (cmd == SCIM_TRANS_CMD_UPDATE_PREEDIT_STRING) {
3149                     socket_helper_update_preedit_string (client_id);
3150                 } else if (cmd == SCIM_TRANS_CMD_UPDATE_AUX_STRING) {
3151                     socket_update_aux_string ();
3152                 } else if (cmd == SCIM_TRANS_CMD_UPDATE_LOOKUP_TABLE) {
3153                     socket_update_lookup_table ();
3154                 } else if (cmd == ISM_TRANS_CMD_UPDATE_ASSOCIATE_TABLE) {
3155                     socket_update_associate_table ();
3156                 } else if (cmd == SCIM_TRANS_CMD_PROCESS_KEY_EVENT ||
3157                            cmd == SCIM_TRANS_CMD_PANEL_SEND_KEY_EVENT) {
3158                     socket_helper_send_key_event (client_id);
3159                 } else if (cmd == SCIM_TRANS_CMD_FORWARD_KEY_EVENT) {
3160                     socket_helper_forward_key_event (client_id);
3161                 } else if (cmd == SCIM_TRANS_CMD_PANEL_SEND_IMENGINE_EVENT) {
3162                     socket_helper_send_imengine_event (client_id);
3163                 } else if (cmd == SCIM_TRANS_CMD_REGISTER_PROPERTIES) {
3164                     socket_helper_register_properties (client_id);
3165                 } else if (cmd == SCIM_TRANS_CMD_UPDATE_PROPERTY) {
3166                     socket_helper_update_property (client_id);
3167                 } else if (cmd == SCIM_TRANS_CMD_RELOAD_CONFIG) {
3168                     reload_config ();
3169                     m_signal_reload_config ();
3170                 } else if (cmd == ISM_TRANS_CMD_ISE_PANEL_HIDED) {
3171                     socket_helper_update_state_hided (client_id);
3172                 } else if (cmd == ISM_TRANS_CMD_ISE_PANEL_SHOWED) {
3173                     socket_helper_update_state_showed (client_id);
3174                 } else if (cmd == ISM_TRANS_CMD_UPDATE_ISE_INPUT_CONTEXT) {
3175                     socket_helper_update_input_context (client_id);
3176                 } else if (cmd == ISM_TRANS_CMD_ISE_RESULT_TO_IMCONTROL) {
3177                     socket_helper_commit_ise_result_to_imcontrol (client_id);
3178                 } else if (cmd == ISM_TRANS_CMD_GET_KEYBOARD_ISE_LIST) {
3179                     socket_get_keyboard_ise_list ();
3180                 } else if (cmd == ISM_TRANS_CMD_SET_CANDIDATE_UI) {
3181                     socket_set_candidate_ui ();
3182                 } else if (cmd == ISM_TRANS_CMD_GET_CANDIDATE_UI) {
3183                     socket_get_candidate_ui ();
3184                 } else if (cmd == ISM_TRANS_CMD_SET_CANDIDATE_POSITION) {
3185                     socket_set_candidate_position ();
3186                 } else if (cmd == ISM_TRANS_CMD_HIDE_CANDIDATE) {
3187                     socket_hide_candidate ();
3188                 } else if (cmd == ISM_TRANS_CMD_GET_CANDIDATE_RECT) {
3189                     socket_get_candidate_rect ();
3190                 } else if (cmd == ISM_TRANS_CMD_SET_KEYBOARD_ISE_BY_NAME) {
3191                     socket_set_keyboard_ise (ISM_TRANS_CMD_SET_KEYBOARD_ISE_BY_NAME);
3192                 } else if (cmd == ISM_TRANS_CMD_SET_KEYBOARD_ISE_BY_UUID) {
3193                     socket_set_keyboard_ise (ISM_TRANS_CMD_SET_KEYBOARD_ISE_BY_UUID);
3194                 } else if (cmd == ISM_TRANS_CMD_GET_KEYBOARD_ISE) {
3195                     socket_get_keyboard_ise ();
3196                 } else if (cmd == ISM_TRANS_CMD_LAUNCH_HELPER_ISE_LIST_SELECTION) {
3197                     socket_helper_launch_helper_ise_list_selection ();
3198                 } else if (cmd == SCIM_TRANS_CMD_GET_SURROUNDING_TEXT) {
3199                     socket_helper_get_surrounding_text (client_id);
3200                 } else if (cmd == SCIM_TRANS_CMD_DELETE_SURROUNDING_TEXT) {
3201                     socket_helper_delete_surrounding_text (client_id);
3202                 }
3203             }
3204             socket_transaction_end ();
3205         }
3206         else if (client_info.type == IMCONTROL_ACT_CLIENT)
3207         {
3208             socket_transaction_start ();
3209
3210             while (m_recv_trans.get_command (cmd))
3211             {
3212                 if (cmd == ISM_TRANS_CMD_SHOW_ISF_CONTROL)
3213                     show_isf_panel (client_id);
3214                 else if (cmd == ISM_TRANS_CMD_HIDE_ISF_CONTROL)
3215                     hide_isf_panel (client_id);
3216                 else if (cmd == ISM_TRANS_CMD_SHOW_ISE_PANEL)
3217                     show_ise_panel (client_id);
3218                 else if (cmd == ISM_TRANS_CMD_HIDE_ISE_PANEL)
3219                     hide_ise_panel (client_id);
3220                 else if (cmd == ISM_TRANS_CMD_GET_ACTIVE_ISE_SIZE)
3221                     get_ise_size (client_id);
3222                 else if (cmd == ISM_TRANS_CMD_SET_ISE_MODE)
3223                     set_ise_mode (client_id);
3224                 else if (cmd == ISM_TRANS_CMD_SET_ISE_LANGUAGE)
3225                     set_ise_language (client_id);
3226                 else if (cmd == ISM_TRANS_CMD_SET_ISE_IMDATA)
3227                     set_ise_imdata (client_id);
3228                 else if (cmd == ISM_TRANS_CMD_GET_ISE_IMDATA)
3229                     get_ise_imdata (client_id);
3230                 else if (cmd == ISM_TRANS_CMD_GET_ACTIVE_ISE_NAME)
3231                     get_active_ise_name (client_id);
3232                 else if (cmd == ISM_TRANS_CMD_SET_ACTIVE_ISE_BY_NAME)
3233                     set_active_ise_by_name (client_id);
3234                 else if (cmd == ISM_TRANS_CMD_SET_ACTIVE_ISE_BY_UUID)
3235                     set_active_ise_by_uuid (client_id);
3236                 else if (cmd == ISM_TRANS_CMD_SET_PRIVATE_KEY)
3237                     set_ise_private_key (client_id, false);
3238                 else if (cmd == ISM_TRANS_CMD_SET_PRIVATE_KEY_BY_IMG)
3239                     set_ise_private_key (client_id, true);
3240                 else if (cmd == ISM_TRANS_CMD_SET_DISABLE_KEY)
3241                     set_ise_disable_key (client_id);
3242                 else if (cmd == ISM_TRANS_CMD_GET_LAYOUT)
3243                     get_ise_layout (client_id);
3244                 else if (cmd == ISM_TRANS_CMD_SET_LAYOUT)
3245                     set_ise_layout (client_id);
3246                 else if (cmd == ISM_TRANS_CMD_SET_CAPS_MODE)
3247                     set_ise_caps_mode (client_id);
3248                 else if (cmd == ISM_TRANS_CMD_GET_ISE_LIST)
3249                     get_ise_list (client_id);
3250                 else if (cmd == ISM_TRANS_CMD_RESET_ISE_OPTION)
3251                     reset_ise_option (client_id);
3252                 else if (cmd == ISM_TRANS_CMD_GET_LANGUAGE_LIST)
3253                     get_language_list (client_id);
3254                 else if (cmd == ISM_TRANS_CMD_GET_ALL_LANGUAGE_LIST)
3255                     get_all_language (client_id);
3256                 else if (cmd == ISM_TRANS_CMD_GET_ISE_LANGUAGE)
3257                     get_ise_language (client_id);
3258                 else if (cmd == ISM_TRANS_CMD_SET_ISF_LANGUAGE)
3259                     set_isf_language (client_id);
3260                 else if (cmd == ISM_TRANS_CMD_RESET_ISE_CONTEXT)
3261                     reset_ise_context (client_id);
3262                 else if (cmd == ISM_TRANS_CMD_SET_ISE_SCREEN_DIRECTION)
3263                     set_ise_screen_direction (client_id);
3264             }
3265
3266             socket_transaction_end ();
3267         }
3268     }
3269
3270     void socket_exception_callback              (SocketServer   *server,
3271                                                  const Socket   &client)
3272     {
3273         SCIM_DEBUG_MAIN (2) << "PanelAgent::socket_exception_callback (" << client.get_id () << ")\n";
3274
3275         socket_close_connection (server, client);
3276     }
3277
3278     bool socket_open_connection                 (SocketServer   *server,
3279                                                  const Socket   &client)
3280     {
3281         SCIM_DEBUG_MAIN (3) << "PanelAgent::socket_open_connection (" << client.get_id () << ")\n";
3282
3283         uint32 key;
3284         String type = scim_socket_accept_connection (key,
3285                                                      String ("Panel"),
3286                                                      String ("FrontEnd,Helper,Helper_Active,IMControl_Active,IMControl_Passive"),
3287                                                      client,
3288                                                      m_socket_timeout);
3289
3290         if (type.length ()) {
3291             ClientInfo info;
3292             info.key = key;
3293             info.type = ((type == "FrontEnd") ? FRONTEND_CLIENT :
3294                         ((type == "IMControl_Active") ? IMCONTROL_ACT_CLIENT :
3295                         ((type == "Helper_Active") ? HELPER_ACT_CLIENT :
3296                         ((type == "IMControl_Passive") ? IMCONTROL_CLIENT : HELPER_CLIENT))));
3297
3298             SCIM_DEBUG_MAIN (4) << "Add client to repository. Type=" << type << " key=" << key << "\n";
3299             lock ();
3300             m_client_repository [client.get_id ()] = info;
3301
3302             if (info.type == IMCONTROL_ACT_CLIENT)
3303             {
3304                 m_pending_active_imcontrol_id = client.get_id ();
3305             }
3306             else if (info.type == IMCONTROL_CLIENT)
3307             {
3308                 m_imcontrol_map [m_pending_active_imcontrol_id] = client.get_id();
3309                 m_pending_active_imcontrol_id = -1;
3310             }
3311
3312             const_cast<Socket &>(client).set_nonblock_mode ();
3313
3314             unlock ();
3315             return true;
3316         }
3317
3318         SCIM_DEBUG_MAIN (4) << "Close client connection " << client.get_id () << "\n";
3319         server->close_connection (client);
3320         return false;
3321     }
3322
3323     void socket_close_connection                (SocketServer   *server,
3324                                                  const Socket   &client)
3325     {
3326         SCIM_DEBUG_MAIN (3) << "PanelAgent::socket_close_connection (" << client.get_id () << ")\n";
3327
3328         lock ();
3329
3330         m_signal_close_connection (client.get_id ());
3331
3332         ClientInfo client_info = socket_get_client_info (client.get_id ());
3333
3334         m_client_repository.erase (client.get_id ());
3335
3336         server->close_connection (client);
3337
3338         /* Exit panel if there is no connected client anymore. */
3339         if (client_info.type != UNKNOWN_CLIENT && m_client_repository.size () == 0 && !m_should_resident) {
3340             SCIM_DEBUG_MAIN (4) << "Exit Socket Server Thread.\n";
3341             server->shutdown ();
3342             m_signal_exit.emit ();
3343         }
3344
3345         unlock ();
3346
3347         if (client_info.type == FRONTEND_CLIENT) {
3348             SCIM_DEBUG_MAIN(4) << "It's a FrontEnd client.\n";
3349             /* The focused client is closed. */
3350             if (m_current_socket_client == client.get_id ()) {
3351                 lock ();
3352                 m_current_socket_client = -1;
3353                 m_current_client_context = 0;
3354                 m_current_context_uuid = String ("");
3355                 unlock ();
3356
3357                 socket_transaction_start ();
3358                 socket_turn_off ();
3359                 socket_transaction_end ();
3360             }
3361
3362             if (m_last_socket_client == client.get_id ()) {
3363                 lock ();
3364                 m_last_socket_client = -1;
3365                 m_last_client_context = 0;
3366                 m_last_context_uuid = String ("");
3367                 unlock ();
3368             }
3369
3370             /* Erase all associated Client Context UUIDs. */
3371             std::vector <uint32> ctx_list;
3372             ClientContextUUIDRepository::iterator it = m_client_context_uuids.begin ();
3373             for (; it != m_client_context_uuids.end (); ++it) {
3374                 if ((it->first & 0xFFFF) == (client.get_id () & 0xFFFF))
3375                     ctx_list.push_back (it->first);
3376             }
3377
3378             for (size_t i = 0; i < ctx_list.size (); ++i)
3379                 m_client_context_uuids.erase (ctx_list [i]);
3380
3381             int client_id = client.get_id ();
3382
3383             /* Erase all helperise info associated with the client */
3384             ctx_list.clear ();
3385             it = m_client_context_helper.begin ();
3386             for (; it != m_client_context_helper.end (); ++it) {
3387                 if ((it->first & 0xFFFF) == (client_id & 0xFFFF)) {
3388                     ctx_list.push_back (it->first);
3389
3390                     /* similar to stop_helper except that it will not call get_focused_context() */
3391                     String uuid = it->second;
3392                     if (m_helper_uuid_count.find (uuid) != m_helper_uuid_count.end ()) {
3393                         uint32 count = m_helper_uuid_count[uuid];
3394                         if (1 == count) {
3395                             m_helper_uuid_count.erase (uuid);
3396
3397                             HelperClientIndex::iterator pise = m_helper_client_index.find (uuid);
3398                             if (pise != m_helper_client_index.end ())
3399                             {
3400                                 m_send_trans.clear ();
3401                                 m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
3402                                 m_send_trans.put_data (it->first);
3403                                 m_send_trans.put_data (uuid);
3404                                 m_send_trans.put_command (SCIM_TRANS_CMD_EXIT);
3405                                 m_send_trans.write_to_socket (pise->second.id);
3406                             }
3407                             SCIM_DEBUG_MAIN(1) << "Stop HelperISE " << uuid << " ...\n";
3408                         }
3409                         else
3410                         {
3411                             m_helper_uuid_count[uuid] = count - 1;
3412                             focus_out_helper (uuid, (it->first & 0xFFFF), ((it->first >> 16) & 0x7FFF));
3413                             SCIM_DEBUG_MAIN(1) << "Decrement usage count of HelperISE " << uuid
3414                                     << " to " << m_helper_uuid_count[uuid] << "\n";
3415                         }
3416                     }
3417                 }
3418             }
3419
3420             for (size_t i = 0; i < ctx_list.size (); ++i)
3421                  m_client_context_helper.erase (ctx_list [i]);
3422
3423             HelperInfoRepository::iterator iter = m_helper_info_repository.begin ();
3424             for (; iter != m_helper_info_repository.end (); iter++)
3425             {
3426                 if (!m_current_helper_uuid.compare (iter->second.uuid))
3427                     if (!(iter->second.option & ISM_ISE_HIDE_IN_CONTROL_PANEL))
3428                         socket_update_control_panel ();
3429             }
3430         } else if (client_info.type == HELPER_CLIENT) {
3431             SCIM_DEBUG_MAIN(4) << "It's a Helper client.\n";
3432
3433             lock ();
3434
3435             HelperInfoRepository::iterator hiit = m_helper_info_repository.find (client.get_id ());
3436
3437             if (hiit != m_helper_info_repository.end ()) {
3438                 bool restart = false;
3439                 String uuid = hiit->second.uuid;
3440
3441                 HelperClientIndex::iterator it = m_helper_client_index.find (uuid);
3442                 if ((hiit->second.option & SCIM_HELPER_AUTO_RESTART) &&
3443                     (it != m_helper_client_index.end () && it->second.ref > 0))
3444                     restart = true;
3445
3446                 m_helper_manager.stop_helper (hiit->second.name);
3447
3448                 m_helper_client_index.erase (uuid);
3449                 m_helper_info_repository.erase (hiit);
3450
3451                 if (restart && !m_ise_exiting)
3452                     m_helper_manager.run_helper (uuid, m_config_name, m_display_name);
3453             }
3454
3455             m_ise_exiting = false;
3456             unlock ();
3457
3458             socket_transaction_start ();
3459             m_signal_remove_helper (client.get_id ());
3460             socket_transaction_end ();
3461         } else if (client_info.type == HELPER_ACT_CLIENT) {
3462             SCIM_DEBUG_MAIN(4) << "It's a Helper passive client.\n";
3463
3464             lock ();
3465
3466             HelperInfoRepository::iterator hiit = m_helper_active_info_repository.find (client.get_id ());
3467             if (hiit != m_helper_active_info_repository.end ())
3468                 m_helper_active_info_repository.erase (hiit);
3469
3470             unlock ();
3471         } else if (client_info.type == IMCONTROL_ACT_CLIENT) {
3472             SCIM_DEBUG_MAIN(4) << "It's a IMCONTROL_ACT_CLIENT client.\n";
3473             int client_id = client.get_id ();
3474
3475             if (client_id == m_current_active_imcontrol_id
3476                 && TOOLBAR_HELPER_MODE == m_current_toolbar_mode)
3477                 hide_helper (m_current_helper_uuid);
3478
3479             IMControlRepository::iterator iter = m_imcontrol_repository.find (client_id);
3480             if (iter != m_imcontrol_repository.end ())
3481             {
3482                 int size = iter->second.info.size ();
3483                 int i = 0;
3484                 while (i < size) {
3485                     stop_helper ((iter->second.info)[i].uuid, (iter->second.count)[i], DEFAULT_CONTEXT_VALUE);
3486                     if ((iter->second.info)[i].option & ISM_ISE_HIDE_IN_CONTROL_PANEL)
3487                         m_current_helper_uuid = m_last_helper_uuid;
3488                     i++;
3489                 }
3490                 m_imcontrol_repository.erase (iter);
3491             }
3492
3493             IntIntRepository::iterator iter2 = m_imcontrol_map.find (client_id);
3494             if (iter2 != m_imcontrol_map.end ())
3495                 m_imcontrol_map.erase (iter2);
3496         }
3497     }
3498
3499     const ClientInfo & socket_get_client_info   (int client)
3500     {
3501         static ClientInfo null_client = { 0, UNKNOWN_CLIENT };
3502
3503         ClientRepository::iterator it = m_client_repository.find (client);
3504
3505         if (it != m_client_repository.end ())
3506             return it->second;
3507
3508         return null_client;
3509     }
3510
3511 private:
3512     void socket_turn_on                         (void)
3513     {
3514         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_turn_on ()\n";
3515
3516         m_signal_turn_on ();
3517     }
3518
3519     void socket_turn_off                        (void)
3520     {
3521         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_turn_off ()\n";
3522
3523         m_signal_turn_off ();
3524     }
3525
3526     void socket_update_screen                   (void)
3527     {
3528         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_update_screen ()\n";
3529
3530         uint32 num;
3531         if (m_recv_trans.get_data (num) && ((int) num) != m_current_screen) {
3532             SCIM_DEBUG_MAIN(4) << "New Screen number = " << num << "\n";
3533             m_signal_update_screen ((int) num);
3534             helper_all_update_screen ((int) num);
3535             m_current_screen = (num);
3536         }
3537     }
3538
3539     void socket_update_spot_location            (void)
3540     {
3541         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_update_spot_location ()\n";
3542
3543         uint32 x, y, top_y;
3544         if (m_recv_trans.get_data (x) && m_recv_trans.get_data (y) && m_recv_trans.get_data (top_y)) {
3545             SCIM_DEBUG_MAIN(4) << "New Spot location x=" << x << " y=" << y << "\n";
3546             m_signal_update_spot_location ((int)x, (int)y, (int)top_y);
3547             helper_all_update_spot_location ((int)x, (int)y);
3548         }
3549     }
3550
3551     void socket_update_cursor_position          (void)
3552     {
3553         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_update_cursor_position ()\n";
3554
3555         uint32 cursor_pos;
3556         if (m_recv_trans.get_data (cursor_pos)) {
3557             SCIM_DEBUG_MAIN(4) << "New cursor position pos=" << cursor_pos << "\n";
3558             helper_all_update_cursor_position ((int)cursor_pos);
3559         }
3560     }
3561
3562     void socket_update_surrounding_text         (void)
3563     {
3564         SCIM_DEBUG_MAIN(4) << __FUNCTION__ << "...\n";
3565
3566         String text;
3567         uint32 cursor;
3568         if (m_recv_trans.get_data (text) && m_recv_trans.get_data (cursor)) {
3569             HelperClientIndex::iterator it = m_helper_client_index.find (m_current_helper_uuid);
3570
3571             if (it != m_helper_client_index.end ())
3572             {
3573                 int    client;
3574                 uint32 context;
3575                 Socket client_socket (it->second.id);
3576                 uint32 ctx;
3577
3578                 lock ();
3579
3580                 get_focused_context (client, context);
3581                 ctx = get_helper_ic (client, context);
3582
3583                 m_send_trans.clear ();
3584                 m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
3585                 m_send_trans.put_data (ctx);
3586                 m_send_trans.put_data (m_current_helper_uuid);
3587                 m_send_trans.put_command (ISM_TRANS_CMD_UPDATE_SURROUNDING_TEXT);
3588                 m_send_trans.put_data (text);
3589                 m_send_trans.put_data (cursor);
3590                 m_send_trans.write_to_socket (client_socket);
3591
3592                 unlock ();
3593             }
3594         }
3595     }
3596
3597     void socket_update_factory_info             (void)
3598     {
3599         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_update_factory_info ()\n";
3600
3601         PanelFactoryInfo info;
3602         if (m_recv_trans.get_data (info.uuid) && m_recv_trans.get_data (info.name) &&
3603             m_recv_trans.get_data (info.lang) && m_recv_trans.get_data (info.icon)) {
3604             SCIM_DEBUG_MAIN(4) << "New Factory info uuid=" << info.uuid << " name=" << info.name << "\n";
3605             info.lang = scim_get_normalized_language (info.lang);
3606             m_signal_update_factory_info (info);
3607         }
3608     }
3609
3610     void socket_show_help                       (void)
3611     {
3612         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_show_help ()\n";
3613
3614         String help;
3615         if (m_recv_trans.get_data (help))
3616             m_signal_show_help (help);
3617     }
3618
3619     void socket_show_factory_menu               (void)
3620     {
3621         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_show_factory_menu ()\n";
3622
3623         PanelFactoryInfo info;
3624         std::vector <PanelFactoryInfo> vec;
3625
3626         while (m_recv_trans.get_data (info.uuid) && m_recv_trans.get_data (info.name) &&
3627                m_recv_trans.get_data (info.lang) && m_recv_trans.get_data (info.icon)) {
3628             info.lang = scim_get_normalized_language (info.lang);
3629             vec.push_back (info);
3630         }
3631
3632         if (vec.size ())
3633             m_signal_show_factory_menu (vec);
3634     }
3635
3636     void socket_turn_on_log                      (void)
3637     {
3638         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_turn_on_log ()\n";
3639
3640         uint32 isOn;
3641         if (m_recv_trans.get_data (isOn)) {
3642             if (isOn) {
3643                 DebugOutput::enable_debug (SCIM_DEBUG_AllMask);
3644                 DebugOutput::set_verbose_level (7);
3645             } else {
3646                 DebugOutput::disable_debug (SCIM_DEBUG_AllMask);
3647                 DebugOutput::set_verbose_level (0);
3648             }
3649
3650             int     focused_client;
3651             uint32  focused_context;
3652
3653             get_focused_context (focused_client, focused_context);
3654
3655             if (focused_client == -1 || focused_context == 0)
3656                 return;
3657
3658             if (TOOLBAR_HELPER_MODE == m_current_toolbar_mode)
3659             {
3660                 HelperClientIndex::iterator it = m_helper_client_index.find (m_current_helper_uuid);
3661
3662                 if (it != m_helper_client_index.end ())
3663                 {
3664                     Socket client_socket (it->second.id);
3665                     uint32 ctx;
3666
3667                     ctx = get_helper_ic (focused_client, focused_context);
3668
3669                     m_send_trans.clear ();
3670                     m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
3671                     m_send_trans.put_data (ctx);
3672                     m_send_trans.put_data (m_current_helper_uuid);
3673                     m_send_trans.put_command (ISM_TRANS_CMD_TURN_ON_LOG);
3674                     m_send_trans.put_data (isOn);
3675                     m_send_trans.write_to_socket (client_socket);
3676                 }
3677             }
3678
3679             ClientInfo client_info = socket_get_client_info (focused_client);
3680             if (client_info.type == FRONTEND_CLIENT) {
3681                 Socket socket_client (focused_client);
3682                 lock ();
3683                 m_send_trans.clear ();
3684                 m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
3685                 m_send_trans.put_data (focused_context);
3686                 m_send_trans.put_command (ISM_TRANS_CMD_TURN_ON_LOG);
3687                 m_send_trans.put_data (isOn);
3688                 m_send_trans.write_to_socket (socket_client);
3689                 unlock ();
3690             }
3691         }
3692     }
3693
3694     void socket_show_preedit_string             (void)
3695     {
3696         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_show_preedit_string ()\n";
3697         m_signal_show_preedit_string ();
3698     }
3699
3700     void socket_show_aux_string                 (void)
3701     {
3702         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_show_aux_string ()\n";
3703         m_signal_show_aux_string ();
3704     }
3705
3706     void socket_show_lookup_table               (void)
3707     {
3708         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_show_lookup_table ()\n";
3709         m_signal_show_lookup_table ();
3710     }
3711
3712     void socket_show_associate_table            (void)
3713     {
3714         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_show_associate_table ()\n";
3715         m_signal_show_associate_table ();
3716     }
3717
3718     void socket_hide_preedit_string             (void)
3719     {
3720         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_hide_preedit_string ()\n";
3721         m_signal_hide_preedit_string ();
3722     }
3723
3724     void socket_hide_aux_string                 (void)
3725     {
3726         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_hide_aux_string ()\n";
3727         m_signal_hide_aux_string ();
3728     }
3729
3730     void socket_hide_lookup_table               (void)
3731     {
3732         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_hide_lookup_table ()\n";
3733         m_signal_hide_lookup_table ();
3734     }
3735
3736     void socket_hide_associate_table            (void)
3737     {
3738         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_hide_associate_table ()\n";
3739         m_signal_hide_associate_table ();
3740     }
3741
3742     void socket_update_preedit_string           (void)
3743     {
3744         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_update_preedit_string ()\n";
3745
3746         String str;
3747         AttributeList attrs;
3748         if (m_recv_trans.get_data (str) && m_recv_trans.get_data (attrs))
3749             m_signal_update_preedit_string (str, attrs);
3750     }
3751
3752     void socket_update_preedit_caret            (void)
3753     {
3754         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_update_preedit_caret ()\n";
3755
3756         uint32 caret;
3757         if (m_recv_trans.get_data (caret))
3758             m_signal_update_preedit_caret ((int) caret);
3759     }
3760
3761     void socket_update_aux_string               (void)
3762     {
3763         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_update_aux_string ()\n";
3764
3765         String str;
3766         AttributeList attrs;
3767         if (m_recv_trans.get_data (str) && m_recv_trans.get_data (attrs))
3768             m_signal_update_aux_string (str, attrs);
3769     }
3770
3771     void socket_update_lookup_table             (void)
3772     {
3773         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_update_lookup_table ()\n";
3774
3775         lock ();
3776         if (m_recv_trans.get_data (g_isf_candidate_table))
3777         {
3778             unlock ();
3779             m_signal_update_lookup_table (g_isf_candidate_table);
3780         }
3781         else
3782         {
3783             unlock ();
3784         }
3785     }
3786
3787     void socket_update_associate_table          (void)
3788     {
3789         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_update_associate_table ()\n";
3790
3791         CommonLookupTable table;
3792         if (m_recv_trans.get_data (table))
3793             m_signal_update_associate_table (table);
3794     }
3795
3796     void socket_update_control_panel            (void)
3797     {
3798         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_update_control_panel ()\n";
3799         /* Check default ISE for no context app */
3800 #ifdef ONE_HELPER_ISE_PROCESS
3801         uint32 ctx = get_helper_ic (-1, 0);
3802         ClientContextUUIDRepository::iterator it = m_client_context_helper.find (ctx);
3803         if (it != m_client_context_helper.end ())
3804         {
3805             if (m_should_shared_ise)
3806             {
3807                 if (TOOLBAR_HELPER_MODE == m_current_toolbar_mode)
3808                 {
3809                     if (m_current_helper_uuid != it->second)
3810                     {
3811                         stop_helper (it->second, -1, 0);
3812                         start_helper (m_current_helper_uuid, -1, 0);
3813                     }
3814                 }
3815                 else if (TOOLBAR_KEYBOARD_MODE == m_current_toolbar_mode)
3816                     stop_helper (it->second, -1, 0);
3817             }
3818             else
3819             {
3820                 m_current_toolbar_mode = TOOLBAR_HELPER_MODE;
3821                 m_current_helper_uuid  = it->second;
3822             }
3823         }
3824         else
3825         {
3826             if (m_should_shared_ise)
3827             {
3828                 if (TOOLBAR_HELPER_MODE == m_current_toolbar_mode)
3829                     start_helper (m_current_helper_uuid, -1, 0);
3830             }
3831             else
3832             {
3833                 m_current_toolbar_mode = TOOLBAR_KEYBOARD_MODE;
3834             }
3835         }
3836
3837 #endif
3838         String name, uuid;
3839         m_signal_get_keyboard_ise (name, uuid);
3840
3841         PanelFactoryInfo info;
3842         if (name.length () > 0)
3843             info = PanelFactoryInfo (uuid, name, String (""), String (""));
3844         else
3845             info = PanelFactoryInfo (String (""), String (_("English/Keyboard")), String ("C"), String (SCIM_KEYBOARD_ICON_FILE));
3846         m_signal_update_factory_info (info);
3847     }
3848
3849     void socket_register_properties             (void)
3850     {
3851         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_register_properties ()\n";
3852
3853         PropertyList properties;
3854
3855         if (m_recv_trans.get_data (properties))
3856             m_signal_register_properties (properties);
3857     }
3858
3859     void socket_update_property                 (void)
3860     {
3861         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_update_property ()\n";
3862
3863         Property property;
3864         if (m_recv_trans.get_data (property))
3865             m_signal_update_property (property);
3866     }
3867
3868     void socket_get_keyboard_ise_list           (void)
3869     {
3870         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_get_keyboard_ise_list ()\n";
3871
3872         std::vector<String> list;
3873         list.clear ();
3874         m_signal_get_keyboard_ise_list (list);
3875
3876         String uuid;
3877         if (m_recv_trans.get_data (uuid))
3878         {
3879             HelperClientIndex::iterator it = m_helper_client_index.find (uuid);
3880             if (it != m_helper_client_index.end ())
3881             {
3882                 int    client;
3883                 uint32 context;
3884                 get_focused_context (client, context);
3885                 uint32 ctx = get_helper_ic (client, context);
3886                 Socket socket_client (it->second.id);
3887                 m_send_trans.clear ();
3888                 m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
3889                 m_send_trans.put_data (ctx);
3890                 m_send_trans.put_data (uuid);
3891                 m_send_trans.put_command (ISM_TRANS_CMD_UPDATE_KEYBOARD_ISE_LIST);
3892                 m_send_trans.put_data (list.size ());
3893                 for (unsigned int i = 0; i < list.size (); i++)
3894                     m_send_trans.put_data (list[i]);
3895                 m_send_trans.write_to_socket (socket_client);
3896             }
3897         }
3898     }
3899
3900     void socket_set_candidate_ui                (void)
3901     {
3902         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_set_candidate_ui ()\n";
3903
3904         uint32 style, mode;
3905         if (m_recv_trans.get_data (style) && m_recv_trans.get_data (mode))
3906         {
3907             m_signal_set_candidate_ui (style, mode);
3908         }
3909     }
3910
3911     void socket_get_candidate_ui                (void)
3912     {
3913         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_get_candidate_ui ()\n";
3914
3915         int style = 0, mode = 0;
3916         m_signal_get_candidate_ui (style, mode);
3917
3918         String uuid;
3919         if (m_recv_trans.get_data (uuid))
3920         {
3921             HelperClientIndex::iterator it = m_helper_client_index.find (uuid);
3922             if (it != m_helper_client_index.end ())
3923             {
3924                 int    client;
3925                 uint32 context;
3926                 get_focused_context (client, context);
3927                 uint32 ctx = get_helper_ic (client, context);
3928                 Socket socket_client (it->second.id);
3929                 m_send_trans.clear ();
3930                 m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
3931                 m_send_trans.put_data (ctx);
3932                 m_send_trans.put_data (uuid);
3933                 m_send_trans.put_command (ISM_TRANS_CMD_UPDATE_CANDIDATE_UI);
3934                 m_send_trans.put_data (style);
3935                 m_send_trans.put_data (mode);
3936                 m_send_trans.write_to_socket (socket_client);
3937             }
3938         }
3939     }
3940
3941     void socket_set_candidate_position          (void)
3942     {
3943         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_set_candidate_position ()\n";
3944
3945         uint32 left, top;
3946         if (m_recv_trans.get_data (left) && m_recv_trans.get_data (top))
3947         {
3948             m_signal_set_candidate_position (left, top);
3949         }
3950     }
3951
3952     void socket_hide_candidate                  (void)
3953     {
3954         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_hide_candidate ()\n";
3955
3956         m_signal_hide_preedit_string ();
3957         m_signal_hide_aux_string ();
3958         m_signal_hide_lookup_table ();
3959         m_signal_hide_associate_table ();
3960     }
3961
3962     void socket_get_candidate_rect              (void)
3963     {
3964         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_get_candidate_rect ()\n";
3965
3966         struct rectinfo info;
3967         info.pos_x  = 0;
3968         info.pos_y  = 0;
3969         info.width  = 0;
3970         info.height = 0;
3971         m_signal_get_candidate_rect (info);
3972
3973         String uuid;
3974         if (m_recv_trans.get_data (uuid))
3975         {
3976             HelperClientIndex::iterator it = m_helper_client_index.find (uuid);
3977             if (it != m_helper_client_index.end ())
3978             {
3979                 int    client;
3980                 uint32 context;
3981                 get_focused_context (client, context);
3982                 uint32 ctx = get_helper_ic (client, context);
3983                 Socket socket_client (it->second.id);
3984                 m_send_trans.clear ();
3985                 m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
3986                 m_send_trans.put_data (ctx);
3987                 m_send_trans.put_data (uuid);
3988                 m_send_trans.put_command (ISM_TRANS_CMD_UPDATE_CANDIDATE_RECT);
3989                 m_send_trans.put_data (info.pos_x);
3990                 m_send_trans.put_data (info.pos_y);
3991                 m_send_trans.put_data (info.width);
3992                 m_send_trans.put_data (info.height);
3993                 m_send_trans.write_to_socket (socket_client);
3994             }
3995         }
3996     }
3997
3998     void socket_set_keyboard_ise                (int type)
3999     {
4000         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_set_keyboard_ise ()\n";
4001
4002         String ise;
4003         if (m_recv_trans.get_data (ise))
4004             m_signal_set_keyboard_ise (type, ise);
4005     }
4006
4007     void socket_helper_launch_helper_ise_list_selection (void)
4008     {
4009         uint32 withUI;
4010         if (m_recv_trans.get_data (withUI))
4011             m_signal_launch_helper_ise_list_selection (withUI);
4012     }
4013
4014     void socket_get_keyboard_ise                (void)
4015     {
4016         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_get_keyboard_ise ()\n";
4017
4018         String ise_name, ise_uuid;
4019         int    client  = -1;
4020         uint32 context = 0;
4021         uint32 ctx     = 0;
4022
4023         get_focused_context (client, context);
4024         ctx = get_helper_ic (client, context);
4025
4026         if (m_client_context_uuids.find (ctx) != m_client_context_uuids.end ())
4027             ise_uuid = m_client_context_uuids[ctx];
4028         m_signal_get_keyboard_ise (ise_name, ise_uuid);
4029
4030         String uuid;
4031         if (m_recv_trans.get_data (uuid))
4032         {
4033             HelperClientIndex::iterator it = m_helper_client_index.find (uuid);
4034             if (it != m_helper_client_index.end ())
4035             {
4036                 int    client;
4037                 uint32 context;
4038                 get_focused_context (client, context);
4039                 uint32 ctx = get_helper_ic (client, context);
4040                 Socket socket_client (it->second.id);
4041                 m_send_trans.clear ();
4042                 m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
4043                 m_send_trans.put_data (ctx);
4044                 m_send_trans.put_data (uuid);
4045                 m_send_trans.put_command (ISM_TRANS_CMD_UPDATE_KEYBOARD_ISE);
4046                 m_send_trans.put_data (ise_name);
4047                 m_send_trans.put_data (ise_uuid);
4048                 m_send_trans.write_to_socket (socket_client);
4049             }
4050         }
4051     }
4052
4053     void socket_start_helper                    (int client, uint32 context, const String &ic_uuid)
4054     {
4055         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_start_helper ()\n";
4056
4057         String uuid;
4058         if (m_recv_trans.get_data (uuid) && uuid.length ()) {
4059             HelperClientIndex::iterator it = m_helper_client_index.find (uuid);
4060
4061             lock ();
4062
4063             uint32 ic = get_helper_ic (client, context);
4064
4065             SCIM_DEBUG_MAIN(5) << "Helper UUID =" << uuid << "  IC UUID =" << ic_uuid <<"\n";
4066
4067             if (it == m_helper_client_index.end ()) {
4068                 SCIM_DEBUG_MAIN(5) << "Run this Helper.\n";
4069                 m_start_helper_ic_index [uuid].push_back (std::make_pair (ic, ic_uuid));
4070                 m_helper_manager.run_helper (uuid, m_config_name, m_display_name);
4071             } else {
4072                 SCIM_DEBUG_MAIN(5) << "Increase the Reference count.\n";
4073                 Socket client_socket (it->second.id);
4074                 m_send_trans.clear ();
4075                 m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
4076                 m_send_trans.put_data (ic);
4077                 m_send_trans.put_data (ic_uuid);
4078                 m_send_trans.put_command (SCIM_TRANS_CMD_HELPER_ATTACH_INPUT_CONTEXT);
4079                 m_send_trans.write_to_socket (client_socket);
4080                 ++ it->second.ref;
4081             }
4082
4083             unlock ();
4084         }
4085     }
4086
4087     void socket_stop_helper                     (int client, uint32 context, const String &ic_uuid)
4088     {
4089         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_stop_helper ()\n";
4090
4091         String uuid;
4092         if (m_recv_trans.get_data (uuid) && uuid.length ()) {
4093             HelperClientIndex::iterator it = m_helper_client_index.find (uuid);
4094
4095             lock ();
4096
4097             uint32 ic = get_helper_ic (client, context);
4098
4099             SCIM_DEBUG_MAIN(5) << "Helper UUID =" << uuid << "  IC UUID =" << ic_uuid <<"\n";
4100
4101             if (it != m_helper_client_index.end ()) {
4102                 SCIM_DEBUG_MAIN(5) << "Decrase the Reference count.\n";
4103                 -- it->second.ref;
4104                 Socket client_socket (it->second.id);
4105                 m_send_trans.clear ();
4106                 m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
4107                 m_send_trans.put_data (ic);
4108                 m_send_trans.put_data (ic_uuid);
4109                 m_send_trans.put_command (SCIM_TRANS_CMD_HELPER_DETACH_INPUT_CONTEXT);
4110                 if (it->second.ref <= 0)
4111                     m_send_trans.put_command (SCIM_TRANS_CMD_EXIT);
4112                 m_send_trans.write_to_socket (client_socket);
4113             }
4114
4115             unlock ();
4116         }
4117     }
4118
4119     void socket_send_helper_event               (int client, uint32 context, const String &ic_uuid)
4120     {
4121         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_send_helper_event ()\n";
4122
4123         String uuid;
4124         if (m_recv_trans.get_data (uuid) && m_recv_trans.get_data (m_nest_trans) &&
4125             uuid.length () && m_nest_trans.valid ()) {
4126             HelperClientIndex::iterator it = m_helper_client_index.find (uuid);
4127             if (it != m_helper_client_index.end ()) {
4128                 Socket client_socket (it->second.id);
4129
4130                 lock ();
4131
4132                 m_send_trans.clear ();
4133                 m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
4134
4135                 /* FIXME: We presume that client and context are both less than 65536.
4136                  * Hopefully, it should be true in any UNIXs.
4137                  * So it's ok to combine client and context into one uint32. */
4138                 m_send_trans.put_data (get_helper_ic (client, context));
4139                 m_send_trans.put_data (ic_uuid);
4140                 m_send_trans.put_command (SCIM_TRANS_CMD_HELPER_PROCESS_IMENGINE_EVENT);
4141                 m_send_trans.put_data (m_nest_trans);
4142                 m_send_trans.write_to_socket (client_socket);
4143
4144                 unlock ();
4145             }
4146         }
4147     }
4148
4149     void socket_helper_register_properties      (int client)
4150     {
4151         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_helper_register_properties (" << client << ")\n";
4152
4153         PropertyList properties;
4154         if (m_recv_trans.get_data (properties))
4155             m_signal_register_helper_properties (client, properties);
4156     }
4157
4158     void socket_helper_update_property          (int client)
4159     {
4160         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_helper_update_property (" << client << ")\n";
4161
4162         Property property;
4163         if (m_recv_trans.get_data (property))
4164             m_signal_update_helper_property (client, property);
4165     }
4166
4167     void socket_helper_send_imengine_event      (int client)
4168     {
4169         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_helper_send_imengine_event (" << client << ")\n";
4170
4171         uint32 target_ic;
4172         String target_uuid;
4173
4174         HelperInfoRepository::iterator hiit = m_helper_active_info_repository.find (client);
4175
4176         if (m_recv_trans.get_data (target_ic)    &&
4177             m_recv_trans.get_data (target_uuid)  &&
4178             m_recv_trans.get_data (m_nest_trans) &&
4179             m_nest_trans.valid ()                &&
4180             hiit != m_helper_active_info_repository.end ()) {
4181
4182             int     target_client;
4183             uint32  target_context;
4184
4185             get_imengine_client_context (target_ic, target_client, target_context);
4186
4187             int     focused_client;
4188             uint32  focused_context;
4189             String  focused_uuid;
4190
4191             focused_uuid = get_focused_context (focused_client, focused_context);
4192
4193             if (target_ic == (uint32) (-1)) {
4194                 target_client  = focused_client;
4195                 target_context = focused_context;
4196             }
4197
4198             if (target_uuid.length () == 0)
4199                 target_uuid = focused_uuid;
4200
4201             ClientInfo  client_info = socket_get_client_info (target_client);
4202
4203             SCIM_DEBUG_MAIN(5) << "Target UUID = " << target_uuid << "  Focused UUId = " << focused_uuid << "\nTarget Client = " << target_client << "\n";
4204
4205             if (client_info.type == FRONTEND_CLIENT) {
4206                 Socket socket_client (target_client);
4207                 lock ();
4208                 m_send_trans.clear ();
4209                 m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
4210                 m_send_trans.put_data (target_context);
4211                 m_send_trans.put_command (SCIM_TRANS_CMD_PROCESS_HELPER_EVENT);
4212                 m_send_trans.put_data (target_uuid);
4213                 m_send_trans.put_data (hiit->second.uuid);
4214                 m_send_trans.put_data (m_nest_trans);
4215                 m_send_trans.write_to_socket (socket_client);
4216                 unlock ();
4217             }
4218         }
4219     }
4220
4221     void socket_helper_key_event_op (int client, int cmd)
4222     {
4223         uint32 target_ic;
4224         String target_uuid;
4225         KeyEvent key;
4226
4227         if (m_recv_trans.get_data (target_ic)    &&
4228             m_recv_trans.get_data (target_uuid)  &&
4229             m_recv_trans.get_data (key)          &&
4230             !key.empty ()) {
4231
4232             int     target_client;
4233             uint32  target_context;
4234
4235             get_imengine_client_context (target_ic, target_client, target_context);
4236
4237             int     focused_client;
4238             uint32  focused_context;
4239             String  focused_uuid;
4240
4241             focused_uuid = get_focused_context (focused_client, focused_context);
4242
4243             if (target_ic == (uint32) (-1)) {
4244                 target_client  = focused_client;
4245                 target_context = focused_context;
4246             }
4247
4248             if (target_uuid.length () == 0)
4249                 target_uuid = focused_uuid;
4250
4251             if (target_client == -1)
4252             {
4253                 /* FIXUP: monitor 'Invalid Window' error */
4254                 std::cerr << "focused target client is NULL" << "\n";
4255             }
4256             else if (target_client  == focused_client &&
4257                 target_context == focused_context &&
4258                 target_uuid    == focused_uuid)
4259             {
4260                 ClientInfo client_info = socket_get_client_info (target_client);
4261                 if (client_info.type == FRONTEND_CLIENT) {
4262                     Socket socket_client (target_client);
4263                     lock ();
4264                     m_send_trans.clear ();
4265                     m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
4266                     m_send_trans.put_data (target_context);
4267                     m_send_trans.put_command (cmd);
4268                     m_send_trans.put_data (key);
4269                     m_send_trans.write_to_socket (socket_client);
4270                     unlock ();
4271                 }
4272             }
4273         }
4274     }
4275
4276     void socket_helper_send_key_event (int client)
4277     {
4278         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_helper_send_key_event (" << client << ")\n";
4279         ISF_PROF_DEBUG("first message")
4280
4281         socket_helper_key_event_op (client, SCIM_TRANS_CMD_PROCESS_KEY_EVENT);
4282     }
4283
4284     void socket_helper_forward_key_event        (int client)
4285     {
4286         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_helper_forward_key_event (" << client << ")\n";
4287
4288         socket_helper_key_event_op (client, SCIM_TRANS_CMD_FORWARD_KEY_EVENT);
4289     }
4290
4291     void socket_helper_commit_string            (int client)
4292     {
4293         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_helper_commit_string (" << client << ")\n";
4294
4295         uint32 target_ic;
4296         String target_uuid;
4297         WideString wstr;
4298
4299         if (m_recv_trans.get_data (target_ic)    &&
4300             m_recv_trans.get_data (target_uuid)  &&
4301             m_recv_trans.get_data (wstr)         &&
4302             wstr.length ()) {
4303
4304             int     target_client;
4305             uint32  target_context;
4306
4307             get_imengine_client_context (target_ic, target_client, target_context);
4308
4309             int     focused_client;
4310             uint32  focused_context;
4311             String  focused_uuid;
4312
4313             focused_uuid = get_focused_context (focused_client, focused_context);
4314
4315             if (target_ic == (uint32) (-1)) {
4316                 target_client  = focused_client;
4317                 target_context = focused_context;
4318             }
4319
4320             if (target_uuid.length () == 0)
4321                 target_uuid = focused_uuid;
4322
4323             if (target_client  == focused_client &&
4324                 target_context == focused_context &&
4325                 target_uuid    == focused_uuid) {
4326                 ClientInfo client_info = socket_get_client_info (target_client);
4327                 if (client_info.type == FRONTEND_CLIENT) {
4328                     Socket socket_client (target_client);
4329                     lock ();
4330                     m_send_trans.clear ();
4331                     m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
4332                     m_send_trans.put_data (target_context);
4333                     m_send_trans.put_command (SCIM_TRANS_CMD_COMMIT_STRING);
4334                     m_send_trans.put_data (wstr);
4335                     m_send_trans.write_to_socket (socket_client);
4336                     unlock ();
4337                 }
4338             }
4339         }
4340     }
4341
4342     void socket_helper_get_surrounding_text     (int client)
4343     {
4344         SCIM_DEBUG_MAIN(4) << __FUNCTION__ << " (" << client << ")\n";
4345
4346         String uuid;
4347         uint32 maxlen_before;
4348         uint32 maxlen_after;
4349
4350         if (m_recv_trans.get_data (uuid) &&
4351             m_recv_trans.get_data (maxlen_before) &&
4352             m_recv_trans.get_data (maxlen_after)) {
4353
4354             int     focused_client;
4355             uint32  focused_context;
4356             String  focused_uuid;
4357
4358             focused_uuid = get_focused_context (focused_client, focused_context);
4359
4360             ClientInfo client_info = socket_get_client_info (focused_client);
4361             if (client_info.type == FRONTEND_CLIENT) {
4362                 Socket socket_client (focused_client);
4363                 lock ();
4364                 m_send_trans.clear ();
4365                 m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
4366                 m_send_trans.put_data (focused_context);
4367                 m_send_trans.put_command (SCIM_TRANS_CMD_GET_SURROUNDING_TEXT);
4368                 m_send_trans.put_data (maxlen_before);
4369                 m_send_trans.put_data (maxlen_after);
4370                 m_send_trans.write_to_socket (socket_client);
4371                 unlock ();
4372             }
4373         }
4374     }
4375
4376     void socket_helper_delete_surrounding_text  (int client)
4377     {
4378         SCIM_DEBUG_MAIN(4) << __FUNCTION__ << " (" << client << ")\n";
4379
4380         uint32 offset;
4381         uint32 len;
4382
4383         if (m_recv_trans.get_data (offset) && m_recv_trans.get_data (len)) {
4384
4385             int     focused_client;
4386             uint32  focused_context;
4387             String  focused_uuid;
4388
4389             focused_uuid = get_focused_context (focused_client, focused_context);
4390
4391             ClientInfo client_info = socket_get_client_info (focused_client);
4392             if (client_info.type == FRONTEND_CLIENT) {
4393                 Socket socket_client (focused_client);
4394                 lock ();
4395                 m_send_trans.clear ();
4396                 m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
4397                 m_send_trans.put_data (focused_context);
4398                 m_send_trans.put_command (SCIM_TRANS_CMD_DELETE_SURROUNDING_TEXT);
4399                 m_send_trans.put_data (offset);
4400                 m_send_trans.put_data (len);
4401                 m_send_trans.write_to_socket (socket_client);
4402                 unlock ();
4403             }
4404         }
4405     }
4406
4407     void socket_helper_show_preedit_string            (int client)
4408     {
4409         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_helper_show_preedit_string (" << client << ")\n";
4410
4411         uint32 target_ic;
4412         String target_uuid;
4413
4414         if (m_recv_trans.get_data (target_ic) && m_recv_trans.get_data (target_uuid)) {
4415             int     target_client;
4416             uint32  target_context;
4417
4418             get_imengine_client_context (target_ic, target_client, target_context);
4419
4420             int     focused_client;
4421             uint32  focused_context;
4422             String  focused_uuid;
4423
4424             focused_uuid = get_focused_context (focused_client, focused_context);
4425
4426             if (target_ic == (uint32) (-1)) {
4427                 target_client  = focused_client;
4428                 target_context = focused_context;
4429             }
4430
4431             if (target_uuid.length () == 0)
4432                 target_uuid = focused_uuid;
4433
4434             if (target_client  == focused_client &&
4435                 target_context == focused_context &&
4436                 target_uuid    == focused_uuid) {
4437                 ClientInfo client_info = socket_get_client_info (target_client);
4438                 if (client_info.type == FRONTEND_CLIENT) {
4439                     Socket socket_client (target_client);
4440                     lock ();
4441                     m_send_trans.clear ();
4442                     m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
4443                     m_send_trans.put_data (target_context);
4444                     m_send_trans.put_command (SCIM_TRANS_CMD_SHOW_PREEDIT_STRING);
4445                     m_send_trans.write_to_socket (socket_client);
4446                     unlock ();
4447                 }
4448             }
4449         }
4450     }
4451
4452     void socket_helper_hide_preedit_string            (int client)
4453     {
4454         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_helper_hide_preedit_string (" << client << ")\n";
4455
4456         uint32 target_ic;
4457         String target_uuid;
4458
4459         if (m_recv_trans.get_data (target_ic) && m_recv_trans.get_data (target_uuid)) {
4460             int     target_client;
4461             uint32  target_context;
4462
4463             get_imengine_client_context (target_ic, target_client, target_context);
4464
4465             int     focused_client;
4466             uint32  focused_context;
4467             String  focused_uuid;
4468
4469             focused_uuid = get_focused_context (focused_client, focused_context);
4470
4471             if (target_ic == (uint32) (-1)) {
4472                 target_client  = focused_client;
4473                 target_context = focused_context;
4474             }
4475
4476             if (target_uuid.length () == 0)
4477                 target_uuid = focused_uuid;
4478
4479             if (target_client  == focused_client &&
4480                 target_context == focused_context &&
4481                 target_uuid    == focused_uuid) {
4482                 ClientInfo client_info = socket_get_client_info (target_client);
4483                 if (client_info.type == FRONTEND_CLIENT) {
4484                     Socket socket_client (target_client);
4485                     lock ();
4486                     m_send_trans.clear ();
4487                     m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
4488                     m_send_trans.put_data (target_context);
4489                     m_send_trans.put_command (SCIM_TRANS_CMD_HIDE_PREEDIT_STRING);
4490                     m_send_trans.write_to_socket (socket_client);
4491                     unlock ();
4492                 }
4493             }
4494         }
4495     }
4496
4497     void socket_helper_update_preedit_string            (int client)
4498     {
4499         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_helper_update_preedit_string (" << client << ")\n";
4500
4501         uint32 target_ic;
4502         String target_uuid;
4503         WideString wstr;
4504         AttributeList attrs;
4505
4506         if (m_recv_trans.get_data (target_ic)    &&
4507             m_recv_trans.get_data (target_uuid)  &&
4508             m_recv_trans.get_data (wstr) && wstr.length () &&
4509             m_recv_trans.get_data (attrs)) {
4510
4511             int     target_client;
4512             uint32  target_context;
4513
4514             get_imengine_client_context (target_ic, target_client, target_context);
4515
4516             int     focused_client;
4517             uint32  focused_context;
4518             String  focused_uuid;
4519
4520             focused_uuid = get_focused_context (focused_client, focused_context);
4521
4522             if (target_ic == (uint32) (-1)) {
4523                 target_client  = focused_client;
4524                 target_context = focused_context;
4525             }
4526
4527             if (target_uuid.length () == 0)
4528                 target_uuid = focused_uuid;
4529
4530             if (target_client  == focused_client &&
4531                 target_context == focused_context &&
4532                 target_uuid    == focused_uuid) {
4533                 ClientInfo client_info = socket_get_client_info (target_client);
4534                 if (client_info.type == FRONTEND_CLIENT) {
4535                     Socket socket_client (target_client);
4536                     lock ();
4537                     m_send_trans.clear ();
4538                     m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
4539                     m_send_trans.put_data (target_context);
4540                     m_send_trans.put_command (SCIM_TRANS_CMD_UPDATE_PREEDIT_STRING);
4541                     m_send_trans.put_data (wstr);
4542                     m_send_trans.put_data (attrs);
4543                     m_send_trans.write_to_socket (socket_client);
4544                     unlock ();
4545                 }
4546             }
4547         }
4548     }
4549
4550
4551     void socket_helper_register_helper          (int client)
4552     {
4553         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_helper_register_helper (" << client << ")\n";
4554
4555         HelperInfo info;
4556
4557         bool result = false;
4558
4559         lock ();
4560
4561         Socket socket_client (client);
4562         m_send_trans.clear ();
4563         m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
4564
4565         if (m_recv_trans.get_data (info.uuid) &&
4566             m_recv_trans.get_data (info.name) &&
4567             m_recv_trans.get_data (info.icon) &&
4568             m_recv_trans.get_data (info.description) &&
4569             m_recv_trans.get_data (info.option) &&
4570             info.uuid.length () &&
4571             info.name.length ()) {
4572
4573             SCIM_DEBUG_MAIN(4) << "New Helper uuid=" << info.uuid << " name=" << info.name << "\n";
4574
4575             HelperClientIndex::iterator it = m_helper_client_index.find (info.uuid);
4576
4577             if (it == m_helper_client_index.end ()) {
4578                 m_helper_info_repository [client] = info;
4579                 m_helper_client_index [info.uuid] = HelperClientStub (client, 1);
4580                 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
4581
4582                 StartHelperICIndex::iterator icit = m_start_helper_ic_index.find (info.uuid);
4583
4584                 if (icit != m_start_helper_ic_index.end ()) {
4585                     m_send_trans.put_command (SCIM_TRANS_CMD_HELPER_ATTACH_INPUT_CONTEXT);
4586                     for (size_t i = 0; i < icit->second.size (); ++i) {
4587                         m_send_trans.put_data (icit->second [i].first);
4588                         m_send_trans.put_data (icit->second [i].second);
4589                     }
4590                     m_start_helper_ic_index.erase (icit);
4591                 }
4592
4593                 m_send_trans.put_command (SCIM_TRANS_CMD_UPDATE_SCREEN);
4594                 m_send_trans.put_data ((uint32)m_current_screen);
4595
4596                 result = true;
4597             } else {
4598                 m_send_trans.put_command (SCIM_TRANS_CMD_FAIL);
4599             }
4600         }
4601
4602         m_send_trans.write_to_socket (socket_client);
4603
4604         unlock ();
4605
4606         if (result)
4607             m_signal_register_helper (client, info);
4608     }
4609
4610     void socket_helper_register_helper_passive          (int client)
4611     {
4612         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_helper_register_helper_passive (" << client << ")\n";
4613
4614         HelperInfo info;
4615
4616         lock ();
4617
4618         if (m_recv_trans.get_data (info.uuid) &&
4619             m_recv_trans.get_data (info.name) &&
4620             m_recv_trans.get_data (info.icon) &&
4621             m_recv_trans.get_data (info.description) &&
4622             m_recv_trans.get_data (info.option) &&
4623             info.uuid.length () &&
4624             info.name.length ()) {
4625
4626             SCIM_DEBUG_MAIN(4) << "New Helper Passive uuid=" << info.uuid << " name=" << info.name << "\n";
4627
4628             HelperInfoRepository::iterator it = m_helper_active_info_repository.find (client);
4629             if (it == m_helper_active_info_repository.end ()) {
4630                 m_helper_active_info_repository[client] =  info;
4631             }
4632
4633             StringIntRepository::iterator iter = m_ise_pending_repository.find (info.uuid);
4634             if (iter != m_ise_pending_repository.end ())
4635             {
4636                 Transaction trans;
4637                 Socket client_socket (iter->second);
4638                 trans.clear ();
4639                 trans.put_command (SCIM_TRANS_CMD_REPLY);
4640                 trans.put_command (SCIM_TRANS_CMD_OK);
4641                 trans.write_to_socket (client_socket);
4642                 m_ise_pending_repository.erase (iter);
4643             }
4644
4645             iter = m_ise_pending_repository.find (info.name);
4646             if (iter != m_ise_pending_repository.end ())
4647             {
4648                 Transaction trans;
4649                 Socket client_socket (iter->second);
4650                 trans.clear ();
4651                 trans.put_command (SCIM_TRANS_CMD_REPLY);
4652                 trans.put_command (SCIM_TRANS_CMD_OK);
4653                 trans.write_to_socket (client_socket);
4654                 m_ise_pending_repository.erase (iter);
4655             }
4656
4657             if (m_current_active_imcontrol_id != -1 &&
4658                 m_ise_settings != NULL && m_ise_changing)
4659             {
4660                 show_helper (info.uuid, m_ise_settings, m_ise_settings_len);
4661                 m_ise_changing = false;
4662             }
4663         }
4664
4665         unlock ();
4666     }
4667
4668     void socket_helper_update_state_hided          (int client)
4669     {
4670         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_helper_update_state_hided (" << client << ")\n";
4671
4672         ClientRepository::iterator iter = m_client_repository.begin ();
4673
4674         for (; iter != m_client_repository.end (); iter++)
4675         {
4676             if (IMCONTROL_CLIENT == iter->second.type
4677                 && iter->first == m_imcontrol_map[m_current_active_imcontrol_id])
4678             {
4679                 Socket client_socket (iter->first);
4680                 Transaction trans;
4681
4682                 trans.clear ();
4683                 trans.put_command (SCIM_TRANS_CMD_REQUEST);
4684                 trans.put_command (ISM_TRANS_CMD_ISE_PANEL_HIDED);
4685
4686                 trans.write_to_socket (client_socket);
4687                 break;
4688             }
4689         }
4690     }
4691
4692     void socket_helper_update_state_showed          (int client)
4693     {
4694         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_helper_update_state_showed (" << client << ")\n";
4695
4696         ClientRepository::iterator iter = m_client_repository.begin ();
4697
4698         for (; iter != m_client_repository.end (); iter++)
4699         {
4700             if (IMCONTROL_CLIENT == iter->second.type &&
4701                 iter->first == m_imcontrol_map[m_current_active_imcontrol_id])
4702             {
4703                 Socket client_socket (iter->first);
4704                 Transaction trans;
4705
4706                 trans.clear ();
4707                 trans.put_command (SCIM_TRANS_CMD_REQUEST);
4708                 trans.put_command (ISM_TRANS_CMD_ISE_PANEL_SHOWED);
4709
4710                 trans.write_to_socket (client_socket);
4711                 break;
4712             }
4713         }
4714     }
4715
4716     void socket_helper_update_input_context          (int client)
4717     {
4718         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_helper_update_input_context (" << client << ")\n";
4719
4720         uint32 type;
4721         uint32 value;
4722
4723         if (m_recv_trans.get_data (type) && m_recv_trans.get_data (value))
4724         {
4725             ClientRepository::iterator iter = m_client_repository.begin ();
4726
4727             for (; iter != m_client_repository.end (); iter++)
4728             {
4729                 if (IMCONTROL_CLIENT == iter->second.type &&
4730                     iter->first == m_imcontrol_map[m_current_active_imcontrol_id])
4731                 {
4732                     Socket client_socket (iter->first);
4733                     Transaction trans;
4734
4735                     trans.clear ();
4736                     trans.put_command (SCIM_TRANS_CMD_REQUEST);
4737                     trans.put_command (ISM_TRANS_CMD_UPDATE_ISE_INPUT_CONTEXT);
4738                     trans.put_data (type);
4739                     trans.put_data (value);
4740
4741                     trans.write_to_socket (client_socket);
4742                     break;
4743                 }
4744             }
4745         }
4746     }
4747
4748     void socket_helper_commit_ise_result_to_imcontrol          (int client)
4749     {
4750         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_helper_commit_ise_result_to_imcontrol (" << client << ")\n";
4751
4752         char * buf = NULL;
4753         size_t len;
4754
4755         if (m_recv_trans.get_data (&buf, len))
4756         {
4757             ClientRepository::iterator iter = m_client_repository.begin ();
4758
4759             for (; iter != m_client_repository.end (); iter++)
4760             {
4761                 if (IMCONTROL_CLIENT == iter->second.type &&
4762                     iter->first == m_imcontrol_map[m_current_active_imcontrol_id])
4763                 {
4764                     Socket client_socket (iter->first);
4765                     Transaction trans;
4766
4767                     trans.clear ();
4768                     trans.put_command (SCIM_TRANS_CMD_REQUEST);
4769                     trans.put_command (ISM_TRANS_CMD_ISE_RESULT_TO_IMCONTROL);
4770                     trans.put_data (buf, len);
4771                     trans.write_to_socket (client_socket);
4772                     break;
4773                 }
4774             }
4775
4776             if (buf)
4777                 delete [] buf;
4778         }
4779     }
4780
4781     void socket_reset_helper_input_context (const String &uuid, int client, uint32 context)
4782     {
4783         HelperClientIndex::iterator it = m_helper_client_index.find (m_current_helper_uuid);
4784
4785         if (it != m_helper_client_index.end ())
4786         {
4787             Socket client_socket (it->second.id);
4788             uint32 ctx = get_helper_ic (client, context);
4789
4790             m_send_trans.clear ();
4791             m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
4792             m_send_trans.put_data (ctx);
4793             m_send_trans.put_data (uuid);
4794             m_send_trans.put_command (SCIM_TRANS_CMD_PANEL_RESET_INPUT_CONTEXT);
4795             m_send_trans.write_to_socket (client_socket);
4796         }
4797     }
4798
4799     void socket_reset_input_context (int client, uint32 context)
4800     {
4801         SCIM_DEBUG_MAIN(4) << "PanelAgent::socket_reset_input_context \n";
4802
4803         if (TOOLBAR_HELPER_MODE == m_current_toolbar_mode)
4804             socket_reset_helper_input_context (m_current_helper_uuid, client, context);
4805     }
4806
4807     bool helper_select_aux (uint32 item)
4808     {
4809         SCIM_DEBUG_MAIN(4) << "PanelAgent::helper_select_aux \n";
4810
4811         if (TOOLBAR_HELPER_MODE == m_current_toolbar_mode)
4812         {
4813             HelperClientIndex::iterator it = m_helper_client_index.find (m_current_helper_uuid);
4814
4815             if (it != m_helper_client_index.end ())
4816             {
4817                 int    client;
4818                 uint32 context;
4819                 Socket client_socket (it->second.id);
4820                 uint32 ctx;
4821
4822                 get_focused_context (client, context);
4823                 ctx = get_helper_ic (client, context);
4824
4825                 m_send_trans.clear ();
4826                 m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
4827                 m_send_trans.put_data (ctx);
4828                 m_send_trans.put_data (m_current_helper_uuid);
4829                 m_send_trans.put_command (ISM_TRANS_CMD_SELECT_AUX);
4830                 m_send_trans.put_data ((uint32)item);
4831                 m_send_trans.write_to_socket (client_socket);
4832
4833                 return true;
4834             }
4835         }
4836
4837         return false;
4838     }
4839
4840     bool helper_select_candidate (uint32 item)
4841     {
4842         SCIM_DEBUG_MAIN(4) << "PanelAgent::helper_select_candidate \n";
4843
4844         if (TOOLBAR_HELPER_MODE == m_current_toolbar_mode)
4845         {
4846             HelperClientIndex::iterator it = m_helper_client_index.find (m_current_helper_uuid);
4847
4848             if (it != m_helper_client_index.end ())
4849             {
4850                 int    client;
4851                 uint32 context;
4852                 Socket client_socket (it->second.id);
4853                 uint32 ctx;
4854
4855                 get_focused_context (client, context);
4856                 ctx = get_helper_ic (client, context);
4857
4858                 m_send_trans.clear ();
4859                 m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
4860                 m_send_trans.put_data (ctx);
4861                 m_send_trans.put_data (m_current_helper_uuid);
4862                 m_send_trans.put_command (SCIM_TRANS_CMD_SELECT_CANDIDATE);
4863                 m_send_trans.put_data ((uint32)item);
4864                 m_send_trans.write_to_socket (client_socket);
4865
4866                 return true;
4867             }
4868         }
4869
4870         return false;
4871     }
4872
4873     bool helper_lookup_table_page_up (void)
4874     {
4875         SCIM_DEBUG_MAIN(4) << "PanelAgent::helper_lookup_table_page_up \n";
4876
4877         if (TOOLBAR_HELPER_MODE == m_current_toolbar_mode)
4878         {
4879             HelperClientIndex::iterator it = m_helper_client_index.find (m_current_helper_uuid);
4880
4881             if (it != m_helper_client_index.end ())
4882             {
4883                 int    client;
4884                 uint32 context;
4885                 Socket client_socket (it->second.id);
4886                 uint32 ctx;
4887
4888                 get_focused_context (client, context);
4889                 ctx = get_helper_ic (client, context);
4890
4891                 m_send_trans.clear ();
4892                 m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
4893                 m_send_trans.put_data (ctx);
4894                 m_send_trans.put_data (m_current_helper_uuid);
4895                 m_send_trans.put_command (SCIM_TRANS_CMD_LOOKUP_TABLE_PAGE_UP);
4896                 m_send_trans.write_to_socket (client_socket);
4897
4898                 return true;
4899             }
4900         }
4901
4902         return false;
4903     }
4904
4905     bool helper_lookup_table_page_down (void)
4906     {
4907         SCIM_DEBUG_MAIN(4) << "PanelAgent::helper_lookup_table_page_down \n";
4908
4909         if (TOOLBAR_HELPER_MODE == m_current_toolbar_mode)
4910         {
4911             HelperClientIndex::iterator it = m_helper_client_index.find (m_current_helper_uuid);
4912
4913             if (it != m_helper_client_index.end ())
4914             {
4915                 int    client;
4916                 uint32 context;
4917                 Socket client_socket (it->second.id);
4918                 uint32 ctx;
4919
4920                 get_focused_context (client, context);
4921                 ctx = get_helper_ic (client, context);
4922
4923                 m_send_trans.clear ();
4924                 m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
4925                 m_send_trans.put_data (ctx);
4926                 m_send_trans.put_data (m_current_helper_uuid);
4927                 m_send_trans.put_command (SCIM_TRANS_CMD_LOOKUP_TABLE_PAGE_DOWN);
4928                 m_send_trans.write_to_socket (client_socket);
4929
4930                 return true;
4931             }
4932         }
4933
4934         return false;
4935     }
4936
4937     bool helper_update_lookup_table_page_size (uint32 size)
4938     {
4939         SCIM_DEBUG_MAIN(4) << "PanelAgent::helper_update_lookup_table_page_size \n";
4940
4941         if (TOOLBAR_HELPER_MODE == m_current_toolbar_mode)
4942         {
4943             HelperClientIndex::iterator it = m_helper_client_index.find (m_current_helper_uuid);
4944
4945             if (it != m_helper_client_index.end ())
4946             {
4947                 int    client;
4948                 uint32 context;
4949                 Socket client_socket (it->second.id);
4950                 uint32 ctx;
4951
4952                 get_focused_context (client, context);
4953                 ctx = get_helper_ic (client, context);
4954
4955                 m_send_trans.clear ();
4956                 m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
4957                 m_send_trans.put_data (ctx);
4958                 m_send_trans.put_data (m_current_helper_uuid);
4959                 m_send_trans.put_command (SCIM_TRANS_CMD_UPDATE_LOOKUP_TABLE_PAGE_SIZE);
4960                 m_send_trans.put_data (size);
4961                 m_send_trans.write_to_socket (client_socket);
4962
4963                 return true;
4964             }
4965         }
4966
4967         return false;
4968     }
4969
4970     bool helper_select_associate (uint32 item)
4971     {
4972         SCIM_DEBUG_MAIN(4) << "PanelAgent::helper_select_associate \n";
4973
4974         if (TOOLBAR_HELPER_MODE == m_current_toolbar_mode)
4975         {
4976             HelperClientIndex::iterator it = m_helper_client_index.find (m_current_helper_uuid);
4977
4978             if (it != m_helper_client_index.end ())
4979             {
4980                 int    client;
4981                 uint32 context;
4982                 Socket client_socket (it->second.id);
4983                 uint32 ctx;
4984
4985                 get_focused_context (client, context);
4986                 ctx = get_helper_ic (client, context);
4987
4988                 m_send_trans.clear ();
4989                 m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
4990                 m_send_trans.put_data (ctx);
4991                 m_send_trans.put_data (m_current_helper_uuid);
4992                 m_send_trans.put_command (ISM_TRANS_CMD_SELECT_ASSOCIATE);
4993                 m_send_trans.put_data ((uint32)item);
4994                 m_send_trans.write_to_socket (client_socket);
4995
4996                 return true;
4997             }
4998         }
4999
5000         return false;
5001     }
5002
5003     bool helper_associate_table_page_up (void)
5004     {
5005         SCIM_DEBUG_MAIN(4) << "PanelAgent::helper_associate_table_page_up \n";
5006
5007         if (TOOLBAR_HELPER_MODE == m_current_toolbar_mode)
5008         {
5009             HelperClientIndex::iterator it = m_helper_client_index.find (m_current_helper_uuid);
5010
5011             if (it != m_helper_client_index.end ())
5012             {
5013                 int    client;
5014                 uint32 context;
5015                 Socket client_socket (it->second.id);
5016                 uint32 ctx;
5017
5018                 get_focused_context (client, context);
5019                 ctx = get_helper_ic (client, context);
5020
5021                 m_send_trans.clear ();
5022                 m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
5023                 m_send_trans.put_data (ctx);
5024                 m_send_trans.put_data (m_current_helper_uuid);
5025                 m_send_trans.put_command (ISM_TRANS_CMD_ASSOCIATE_TABLE_PAGE_UP);
5026                 m_send_trans.write_to_socket (client_socket);
5027
5028                 return true;
5029             }
5030         }
5031
5032         return false;
5033     }
5034
5035     bool helper_associate_table_page_down (void)
5036     {
5037         SCIM_DEBUG_MAIN(4) << "PanelAgent::helper_associate_table_page_down \n";
5038
5039         if (TOOLBAR_HELPER_MODE == m_current_toolbar_mode)
5040         {
5041             HelperClientIndex::iterator it = m_helper_client_index.find (m_current_helper_uuid);
5042
5043             if (it != m_helper_client_index.end ())
5044             {
5045                 int    client;
5046                 uint32 context;
5047                 Socket client_socket (it->second.id);
5048                 uint32 ctx;
5049
5050                 get_focused_context (client, context);
5051                 ctx = get_helper_ic (client, context);
5052
5053                 m_send_trans.clear ();
5054                 m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
5055                 m_send_trans.put_data (ctx);
5056                 m_send_trans.put_data (m_current_helper_uuid);
5057                 m_send_trans.put_command (ISM_TRANS_CMD_ASSOCIATE_TABLE_PAGE_DOWN);
5058                 m_send_trans.write_to_socket (client_socket);
5059
5060                 return true;
5061             }
5062         }
5063
5064         return false;
5065     }
5066
5067     bool helper_update_associate_table_page_size (uint32         size)
5068     {
5069         SCIM_DEBUG_MAIN(4) << "PanelAgent::helper_update_associate_table_page_size \n";
5070
5071         if (TOOLBAR_HELPER_MODE == m_current_toolbar_mode)
5072         {
5073             HelperClientIndex::iterator it = m_helper_client_index.find (m_current_helper_uuid);
5074
5075             if (it != m_helper_client_index.end ())
5076             {
5077                 int    client;
5078                 uint32 context;
5079                 Socket client_socket (it->second.id);
5080                 uint32 ctx;
5081
5082                 get_focused_context (client, context);
5083                 ctx = get_helper_ic (client, context);
5084
5085                 m_send_trans.clear ();
5086                 m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
5087                 m_send_trans.put_data (ctx);
5088                 m_send_trans.put_data (m_current_helper_uuid);
5089                 m_send_trans.put_command (ISM_TRANS_CMD_UPDATE_ASSOCIATE_TABLE_PAGE_SIZE);
5090                 m_send_trans.put_data (size);
5091                 m_send_trans.write_to_socket (client_socket);
5092
5093                 return true;
5094             }
5095         }
5096
5097         return false;
5098     }
5099
5100     void helper_all_update_spot_location (int x, int y)
5101     {
5102         SCIM_DEBUG_MAIN (5) << "PanelAgent::helper_all_update_spot_location (" << x << "," << y << ")\n";
5103
5104         HelperInfoRepository::iterator hiit = m_helper_info_repository.begin ();
5105
5106         int    client;
5107         uint32 context;
5108         String uuid = get_focused_context (client, context);
5109
5110         lock ();
5111
5112         m_send_trans.clear ();
5113         m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
5114
5115         /* FIXME: We presume that client and context are both less than 65536.
5116          * Hopefully, it should be true in any UNIXs.
5117          * So it's ok to combine client and context into one uint32. */
5118         m_send_trans.put_data (get_helper_ic (client, context));
5119         m_send_trans.put_data (uuid);
5120         m_send_trans.put_command (SCIM_TRANS_CMD_UPDATE_SPOT_LOCATION);
5121         m_send_trans.put_data ((uint32) x);
5122         m_send_trans.put_data ((uint32) y);
5123
5124         for (; hiit != m_helper_info_repository.end (); ++ hiit) {
5125             if (hiit->second.option & SCIM_HELPER_NEED_SPOT_LOCATION_INFO) {
5126                 Socket client_socket (hiit->first);
5127                 m_send_trans.write_to_socket (client_socket);
5128             }
5129         }
5130
5131         unlock ();
5132     }
5133
5134     void helper_all_update_cursor_position      (int cursor_pos)
5135     {
5136         SCIM_DEBUG_MAIN (5) << "PanelAgent::helper_all_update_cursor_position (" << cursor_pos << ")\n";
5137
5138         HelperInfoRepository::iterator hiit = m_helper_info_repository.begin ();
5139
5140         int    client;
5141         uint32 context;
5142         String uuid = get_focused_context (client, context);
5143
5144         lock ();
5145
5146         m_send_trans.clear ();
5147         m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
5148         m_send_trans.put_data (get_helper_ic (client, context));
5149         m_send_trans.put_data (uuid);
5150         m_send_trans.put_command (ISM_TRANS_CMD_UPDATE_CURSOR_POSITION);
5151         m_send_trans.put_data ((uint32) cursor_pos);
5152
5153         for (; hiit != m_helper_info_repository.end (); ++ hiit) {
5154             Socket client_socket (hiit->first);
5155             m_send_trans.write_to_socket (client_socket);
5156         }
5157
5158         unlock ();
5159     }
5160
5161     void helper_all_update_screen               (int screen)
5162     {
5163         SCIM_DEBUG_MAIN (5) << "PanelAgent::helper_all_update_screen (" << screen << ")\n";
5164
5165         HelperInfoRepository::iterator hiit = m_helper_info_repository.begin ();
5166
5167         int    client;
5168         uint32 context;
5169         String uuid;
5170
5171         lock ();
5172
5173         uuid = get_focused_context (client, context);
5174
5175         m_send_trans.clear ();
5176         m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
5177
5178         /* FIXME: We presume that client and context are both less than 65536.
5179          * Hopefully, it should be true in any UNIXs.
5180          * So it's ok to combine client and context into one uint32. */
5181         m_send_trans.put_data (get_helper_ic (client, context));
5182         m_send_trans.put_data (uuid);
5183         m_send_trans.put_command (SCIM_TRANS_CMD_UPDATE_SCREEN);
5184         m_send_trans.put_data ((uint32) screen);
5185
5186         for (; hiit != m_helper_info_repository.end (); ++ hiit) {
5187             if (hiit->second.option & SCIM_HELPER_NEED_SCREEN_INFO) {
5188                 Socket client_socket (hiit->first);
5189                 m_send_trans.write_to_socket (client_socket);
5190             }
5191         }
5192
5193         unlock ();
5194     }
5195
5196     const String & get_focused_context (int &client, uint32 &context, bool force_last_context = false) const
5197     {
5198         if (m_current_socket_client >= 0) {
5199             client  = m_current_socket_client;
5200             context = m_current_client_context;
5201             return m_current_context_uuid;
5202         } else {
5203             client  = m_last_socket_client;
5204             context = m_last_client_context;
5205             return m_last_context_uuid;
5206         }
5207     }
5208
5209 private:
5210     void socket_transaction_start (void)
5211     {
5212         m_signal_transaction_start ();
5213     }
5214
5215     void socket_transaction_end (void)
5216     {
5217         m_signal_transaction_end ();
5218     }
5219
5220     void lock (void)
5221     {
5222         m_signal_lock ();
5223     }
5224     void unlock (void)
5225     {
5226         m_signal_unlock ();
5227     }
5228 };
5229
5230 PanelAgent::PanelAgent ()
5231     : m_impl (new PanelAgentImpl ())
5232 {
5233 }
5234
5235 PanelAgent::~PanelAgent ()
5236 {
5237     delete m_impl;
5238 }
5239
5240 bool
5241 PanelAgent::initialize (const String &config, const String &display, bool resident)
5242 {
5243     return m_impl->initialize (config, display, resident);
5244 }
5245
5246 bool
5247 PanelAgent::valid (void) const
5248 {
5249     return m_impl->valid ();
5250 }
5251
5252 bool
5253 PanelAgent::run (void)
5254 {
5255     return m_impl->run ();
5256 }
5257
5258 void
5259 PanelAgent::stop (void)
5260 {
5261     if (m_impl != NULL)
5262         m_impl->stop ();
5263 }
5264
5265 int
5266 PanelAgent::get_helper_list (std::vector <HelperInfo> & helpers) const
5267 {
5268     return m_impl->get_helper_list (helpers);
5269 }
5270
5271 void PanelAgent::hide_helper (const String &uuid)
5272 {
5273     m_impl->hide_helper (uuid);
5274 }
5275 TOOLBAR_MODE_T
5276 PanelAgent::get_current_toolbar_mode () const
5277 {
5278     return m_impl->get_current_toolbar_mode ();
5279 }
5280
5281 void
5282 PanelAgent::get_current_ise_rect (rectinfo &ise_rect)
5283 {
5284     m_impl->get_current_ise_rect (ise_rect);
5285 }
5286
5287 String
5288 PanelAgent::get_current_helper_uuid () const
5289 {
5290     return m_impl->get_current_helper_uuid ();
5291 }
5292
5293 String
5294 PanelAgent::get_current_helper_name () const
5295 {
5296     return m_impl->get_current_helper_name ();
5297 }
5298
5299 String
5300 PanelAgent::get_current_factory_icon () const
5301 {
5302     return m_impl->get_current_factory_icon ();
5303 }
5304
5305 String
5306 PanelAgent::get_current_ise_name () const
5307 {
5308     return m_impl->get_current_ise_name ();
5309 }
5310
5311 void
5312 PanelAgent::set_current_toolbar_mode (TOOLBAR_MODE_T mode)
5313 {
5314     m_impl->set_current_toolbar_mode (mode);
5315 }
5316
5317 void
5318 PanelAgent::set_current_ise_name (String &name)
5319 {
5320     m_impl->set_current_ise_name (name);
5321 }
5322
5323 void
5324 PanelAgent::set_current_ise_style (uint32 &style)
5325 {
5326     m_impl->set_current_ise_style (style);
5327 }
5328
5329 void
5330 PanelAgent::update_ise_name (String &name)
5331 {
5332     m_impl->update_ise_name (name);
5333 }
5334
5335 void
5336 PanelAgent::update_ise_style (uint32 &style)
5337 {
5338     m_impl->update_ise_style (style);
5339 }
5340
5341 void
5342 PanelAgent::set_current_factory_icon (String &icon)
5343 {
5344     m_impl->set_current_factory_icon (icon);
5345 }
5346
5347 bool
5348 PanelAgent::move_preedit_caret             (uint32         position)
5349 {
5350     return m_impl->move_preedit_caret (position);
5351 }
5352
5353 bool
5354 PanelAgent::request_help                   (void)
5355 {
5356     return m_impl->request_help ();
5357 }
5358
5359 bool
5360 PanelAgent::request_factory_menu           (void)
5361 {
5362     return m_impl->request_factory_menu ();
5363 }
5364
5365 bool
5366 PanelAgent::change_factory                 (const String  &uuid)
5367 {
5368     return m_impl->change_factory (uuid);
5369 }
5370
5371 bool
5372 PanelAgent::candidate_more_window_show     (void)
5373 {
5374     return m_impl->candidate_more_window_show ();
5375 }
5376
5377 bool
5378 PanelAgent::candidate_more_window_hide     (void)
5379 {
5380     return m_impl->candidate_more_window_hide ();
5381 }
5382
5383 bool
5384 PanelAgent::select_aux                     (uint32         item)
5385 {
5386     return m_impl->select_aux (item);
5387 }
5388
5389 bool
5390 PanelAgent::select_candidate               (uint32         item)
5391 {
5392     return m_impl->select_candidate (item);
5393 }
5394
5395 bool
5396 PanelAgent::lookup_table_page_up           (void)
5397 {
5398     return m_impl->lookup_table_page_up ();
5399 }
5400
5401 bool
5402 PanelAgent::lookup_table_page_down         (void)
5403 {
5404     return m_impl->lookup_table_page_down ();
5405 }
5406
5407 bool
5408 PanelAgent::update_lookup_table_page_size  (uint32         size)
5409 {
5410     return m_impl->update_lookup_table_page_size (size);
5411 }
5412
5413 bool
5414 PanelAgent::select_associate               (uint32         item)
5415 {
5416     return m_impl->select_associate (item);
5417 }
5418
5419 bool
5420 PanelAgent::associate_table_page_up        (void)
5421 {
5422     return m_impl->associate_table_page_up ();
5423 }
5424
5425 bool
5426 PanelAgent::associate_table_page_down      (void)
5427 {
5428     return m_impl->associate_table_page_down ();
5429 }
5430
5431 bool
5432 PanelAgent::update_associate_table_page_size (uint32         size)
5433 {
5434     return m_impl->update_associate_table_page_size (size);
5435 }
5436
5437 bool
5438 PanelAgent::trigger_property               (const String  &property)
5439 {
5440     return m_impl->trigger_property (property);
5441 }
5442
5443 bool
5444 PanelAgent::trigger_helper_property        (int            client,
5445                                             const String  &property)
5446 {
5447     return m_impl->trigger_helper_property (client, property);
5448 }
5449
5450 bool
5451 PanelAgent::start_helper                   (const String  &uuid)
5452 {
5453     return m_impl->start_helper (uuid, -2, 0);
5454 }
5455
5456 bool
5457 PanelAgent::stop_helper                    (const String  &uuid)
5458 {
5459     return m_impl->stop_helper (uuid, -2, 0);
5460 }
5461
5462 void
5463 PanelAgent::set_default_ise                (const DEFAULT_ISE_T  &ise)
5464 {
5465     m_impl->set_default_ise (ise);
5466 }
5467
5468 void
5469 PanelAgent::set_should_shared_ise          (const bool should_shared_ise)
5470 {
5471     m_impl->set_should_shared_ise (should_shared_ise);
5472 }
5473
5474 bool
5475 PanelAgent::reset_keyboard_ise             () const
5476 {
5477     return m_impl->reset_keyboard_ise ();
5478 }
5479
5480 int
5481 PanelAgent::get_active_ise_list            (std::vector<String> &strlist)
5482 {
5483     return m_impl->get_active_ise_list (strlist);
5484 }
5485
5486 void
5487 PanelAgent::update_isf_control_status      (const bool showed)
5488 {
5489    m_impl->update_isf_control_status (showed);
5490 }
5491
5492 int
5493 PanelAgent::send_display_name              (String &name)
5494 {
5495     return m_impl->send_display_name (name);
5496 }
5497
5498 bool
5499 PanelAgent::reload_config                  (void)
5500 {
5501     return m_impl->reload_config ();
5502 }
5503
5504 bool
5505 PanelAgent::exit                           (void)
5506 {
5507     return m_impl->exit ();
5508 }
5509
5510 bool
5511 PanelAgent::filter_event (int fd)
5512 {
5513     return m_impl->filter_event (fd);
5514 }
5515
5516 bool
5517 PanelAgent::filter_exception_event (int fd)
5518 {
5519     return m_impl->filter_exception_event (fd);
5520 }
5521
5522 int
5523 PanelAgent::get_server_id (void)
5524 {
5525     return m_impl->get_server_id ();
5526 }
5527
5528 void
5529 PanelAgent::update_ise_list (std::vector<String> &strList)
5530 {
5531     m_impl->update_ise_list (strList);
5532 }
5533
5534 void
5535 PanelAgent::set_ise_changing (bool changing)
5536 {
5537     m_impl->set_ise_changing (changing);
5538 }
5539
5540 Connection
5541 PanelAgent::signal_connect_reload_config              (PanelAgentSlotVoid                *slot)
5542 {
5543     return m_impl->signal_connect_reload_config (slot);
5544 }
5545
5546 Connection
5547 PanelAgent::signal_connect_turn_on                    (PanelAgentSlotVoid                *slot)
5548 {
5549     return m_impl->signal_connect_turn_on (slot);
5550 }
5551
5552 Connection
5553 PanelAgent::signal_connect_turn_off                   (PanelAgentSlotVoid                *slot)
5554 {
5555     return m_impl->signal_connect_turn_off (slot);
5556 }
5557
5558 Connection
5559 PanelAgent::signal_connect_show_panel                 (PanelAgentSlotVoid                *slot)
5560 {
5561     return m_impl->signal_connect_show_panel (slot);
5562 }
5563
5564 Connection
5565 PanelAgent::signal_connect_hide_panel                 (PanelAgentSlotVoid                *slot)
5566 {
5567     return m_impl->signal_connect_hide_panel (slot);
5568 }
5569
5570 Connection
5571 PanelAgent::signal_connect_update_screen              (PanelAgentSlotInt                 *slot)
5572 {
5573     return m_impl->signal_connect_update_screen (slot);
5574 }
5575
5576 Connection
5577 PanelAgent::signal_connect_update_spot_location       (PanelAgentSlotIntIntInt           *slot)
5578 {
5579     return m_impl->signal_connect_update_spot_location (slot);
5580 }
5581
5582 Connection
5583 PanelAgent::signal_connect_update_factory_info        (PanelAgentSlotFactoryInfo         *slot)
5584 {
5585     return m_impl->signal_connect_update_factory_info (slot);
5586 }
5587
5588 Connection
5589 PanelAgent::signal_connect_start_default_ise          (PanelAgentSlotVoid                *slot)
5590 {
5591     return m_impl->signal_connect_start_default_ise (slot);
5592 }
5593
5594 Connection
5595 PanelAgent::signal_connect_set_candidate_ui           (PanelAgentSlotIntInt              *slot)
5596 {
5597     return m_impl->signal_connect_set_candidate_ui (slot);
5598 }
5599
5600 Connection
5601 PanelAgent::signal_connect_get_candidate_ui           (PanelAgentSlotIntInt2             *slot)
5602 {
5603     return m_impl->signal_connect_get_candidate_ui (slot);
5604 }
5605
5606 Connection
5607 PanelAgent::signal_connect_set_candidate_position     (PanelAgentSlotIntInt              *slot)
5608 {
5609     return m_impl->signal_connect_set_candidate_position (slot);
5610 }
5611
5612 Connection
5613 PanelAgent::signal_connect_get_candidate_rect         (PanelAgentSlotRect                *slot)
5614 {
5615     return m_impl->signal_connect_get_candidate_rect (slot);
5616 }
5617
5618 Connection
5619 PanelAgent::signal_connect_set_keyboard_ise           (PanelAgentSlotIntString           *slot)
5620 {
5621     return m_impl->signal_connect_set_keyboard_ise (slot);
5622 }
5623
5624 Connection
5625 PanelAgent::signal_connect_get_keyboard_ise           (PanelAgentSlotString2             *slot)
5626 {
5627     return m_impl->signal_connect_get_keyboard_ise (slot);
5628 }
5629
5630 Connection
5631 PanelAgent::signal_connect_show_help                  (PanelAgentSlotString              *slot)
5632 {
5633     return m_impl->signal_connect_show_help (slot);
5634 }
5635
5636 Connection
5637 PanelAgent::signal_connect_show_factory_menu          (PanelAgentSlotFactoryInfoVector   *slot)
5638 {
5639     return m_impl->signal_connect_show_factory_menu (slot);
5640 }
5641
5642 Connection
5643 PanelAgent::signal_connect_show_preedit_string        (PanelAgentSlotVoid                *slot)
5644 {
5645     return m_impl->signal_connect_show_preedit_string (slot);
5646 }
5647
5648 Connection
5649 PanelAgent::signal_connect_show_aux_string            (PanelAgentSlotVoid                *slot)
5650 {
5651     return m_impl->signal_connect_show_aux_string (slot);
5652 }
5653
5654 Connection
5655 PanelAgent::signal_connect_show_lookup_table          (PanelAgentSlotVoid                *slot)
5656 {
5657     return m_impl->signal_connect_show_lookup_table (slot);
5658 }
5659
5660 Connection
5661 PanelAgent::signal_connect_show_associate_table       (PanelAgentSlotVoid                *slot)
5662 {
5663     return m_impl->signal_connect_show_associate_table (slot);
5664 }
5665
5666 Connection
5667 PanelAgent::signal_connect_hide_preedit_string        (PanelAgentSlotVoid                *slot)
5668 {
5669     return m_impl->signal_connect_hide_preedit_string (slot);
5670 }
5671
5672 Connection
5673 PanelAgent::signal_connect_hide_aux_string            (PanelAgentSlotVoid                *slot)
5674 {
5675     return m_impl->signal_connect_hide_aux_string (slot);
5676 }
5677
5678 Connection
5679 PanelAgent::signal_connect_hide_lookup_table          (PanelAgentSlotVoid                *slot)
5680 {
5681     return m_impl->signal_connect_hide_lookup_table (slot);
5682 }
5683
5684 Connection
5685 PanelAgent::signal_connect_hide_associate_table       (PanelAgentSlotVoid                *slot)
5686 {
5687     return m_impl->signal_connect_hide_associate_table (slot);
5688 }
5689
5690 Connection
5691 PanelAgent::signal_connect_update_preedit_string      (PanelAgentSlotAttributeString     *slot)
5692 {
5693     return m_impl->signal_connect_update_preedit_string (slot);
5694 }
5695
5696 Connection
5697 PanelAgent::signal_connect_update_preedit_caret       (PanelAgentSlotInt                 *slot)
5698 {
5699     return m_impl->signal_connect_update_preedit_caret (slot);
5700 }
5701
5702 Connection
5703 PanelAgent::signal_connect_update_aux_string          (PanelAgentSlotAttributeString     *slot)
5704 {
5705     return m_impl->signal_connect_update_aux_string (slot);
5706 }
5707
5708 Connection
5709 PanelAgent::signal_connect_update_lookup_table        (PanelAgentSlotLookupTable         *slot)
5710 {
5711     return m_impl->signal_connect_update_lookup_table (slot);
5712 }
5713
5714 Connection
5715 PanelAgent::signal_connect_update_associate_table     (PanelAgentSlotLookupTable         *slot)
5716 {
5717     return m_impl->signal_connect_update_associate_table (slot);
5718 }
5719
5720 Connection
5721 PanelAgent::signal_connect_register_properties        (PanelAgentSlotPropertyList        *slot)
5722 {
5723     return m_impl->signal_connect_register_properties (slot);
5724 }
5725
5726 Connection
5727 PanelAgent::signal_connect_update_property            (PanelAgentSlotProperty            *slot)
5728 {
5729     return m_impl->signal_connect_update_property (slot);
5730 }
5731
5732 Connection
5733 PanelAgent::signal_connect_register_helper_properties (PanelAgentSlotIntPropertyList     *slot)
5734 {
5735     return m_impl->signal_connect_register_helper_properties (slot);
5736 }
5737
5738 Connection
5739 PanelAgent::signal_connect_update_helper_property     (PanelAgentSlotIntProperty         *slot)
5740 {
5741     return m_impl->signal_connect_update_helper_property (slot);
5742 }
5743
5744 Connection
5745 PanelAgent::signal_connect_register_helper            (PanelAgentSlotIntHelperInfo       *slot)
5746 {
5747     return m_impl->signal_connect_register_helper (slot);
5748 }
5749
5750 Connection
5751 PanelAgent::signal_connect_remove_helper              (PanelAgentSlotInt                 *slot)
5752 {
5753     return m_impl->signal_connect_remove_helper (slot);
5754 }
5755
5756 Connection
5757 PanelAgent::signal_connect_set_active_ise_by_uuid     (PanelAgentSlotStringBool              *slot)
5758 {
5759     return m_impl->signal_connect_set_active_ise_by_uuid (slot);
5760 }
5761
5762 Connection
5763 PanelAgent::signal_connect_set_active_ise_by_name     (PanelAgentSlotString              *slot)
5764 {
5765     return m_impl->signal_connect_set_active_ise_by_name (slot);
5766 }
5767
5768 Connection
5769 PanelAgent::signal_connect_focus_in                   (PanelAgentSlotVoid                *slot)
5770 {
5771     return m_impl->signal_connect_focus_in (slot);
5772 }
5773
5774 Connection
5775 PanelAgent::signal_connect_focus_out                  (PanelAgentSlotVoid                *slot)
5776 {
5777     return m_impl->signal_connect_focus_out (slot);
5778 }
5779
5780 Connection
5781 PanelAgent::signal_connect_get_ise_list               (PanelAgentSlotBoolStringVector    *slot)
5782 {
5783     return m_impl->signal_connect_get_ise_list (slot);
5784 }
5785
5786 Connection
5787 PanelAgent::signal_connect_get_keyboard_ise_list      (PanelAgentSlotBoolStringVector    *slot)
5788 {
5789     return m_impl->signal_connect_get_keyboard_ise_list (slot);
5790 }
5791
5792 Connection
5793 PanelAgent::signal_connect_launch_helper_ise_list_selection(PanelAgentSlotInt * slot)
5794 {
5795     return m_impl->signal_connect_launch_helper_ise_list_selection (slot);
5796 }
5797
5798 Connection
5799 PanelAgent::signal_connect_get_language_list          (PanelAgentSlotStringVector        *slot)
5800 {
5801     return m_impl->signal_connect_get_language_list (slot);
5802 }
5803
5804 Connection
5805 PanelAgent::signal_connect_get_all_language           (PanelAgentSlotStringVector        *slot)
5806 {
5807     return m_impl->signal_connect_get_all_language (slot);
5808 }
5809
5810 Connection
5811 PanelAgent::signal_connect_get_ise_language           (PanelAgentSlotStrStringVector     *slot)
5812 {
5813     return m_impl->signal_connect_get_ise_language (slot);
5814 }
5815
5816 Connection
5817 PanelAgent::signal_connect_set_isf_language           (PanelAgentSlotString              *slot)
5818 {
5819     return m_impl->signal_connect_set_isf_language (slot);
5820 }
5821
5822 Connection
5823 PanelAgent::signal_connect_get_ise_info_by_uuid       (PanelAgentSlotStringISEINFO       *slot)
5824 {
5825     return m_impl->signal_connect_get_ise_info_by_uuid (slot);
5826 }
5827
5828 Connection
5829 PanelAgent::signal_connect_get_ise_info_by_name       (PanelAgentSlotStringISEINFO       *slot)
5830 {
5831     return m_impl->signal_connect_get_ise_info_by_name (slot);
5832 }
5833
5834 Connection
5835 PanelAgent::signal_connect_send_key_event             (PanelAgentSlotKeyEvent            *slot)
5836 {
5837     return m_impl->signal_connect_send_key_event (slot);
5838 }
5839
5840 Connection
5841 PanelAgent::signal_connect_accept_connection          (PanelAgentSlotInt                 *slot)
5842 {
5843     return m_impl->signal_connect_accept_connection (slot);
5844 }
5845
5846 Connection
5847 PanelAgent::signal_connect_close_connection           (PanelAgentSlotInt                 *slot)
5848 {
5849     return m_impl->signal_connect_close_connection (slot);
5850 }
5851
5852 Connection
5853 PanelAgent::signal_connect_exit                       (PanelAgentSlotVoid                *slot)
5854 {
5855     return m_impl->signal_connect_exit (slot);
5856 }
5857
5858 Connection
5859 PanelAgent::signal_connect_transaction_start          (PanelAgentSlotVoid                *slot)
5860 {
5861     return m_impl->signal_connect_transaction_start (slot);
5862 }
5863
5864 Connection
5865 PanelAgent::signal_connect_transaction_end            (PanelAgentSlotVoid                *slot)
5866 {
5867     return m_impl->signal_connect_transaction_end (slot);
5868 }
5869
5870 Connection
5871 PanelAgent::signal_connect_lock                       (PanelAgentSlotVoid                *slot)
5872 {
5873     return m_impl->signal_connect_lock (slot);
5874 }
5875
5876 Connection
5877 PanelAgent::signal_connect_unlock                     (PanelAgentSlotVoid                *slot)
5878 {
5879     return m_impl->signal_connect_unlock (slot);
5880 }
5881
5882 } /* namespace scim */
5883
5884 /*
5885 vi:ts=4:nowrap:ai:expandtab
5886 */
5887