Fix build errors
[platform/upstream/ibus.git] / bus / ibusimpl.c
1 /* vim:set et sts=4: */
2 /* ibus - The Input Bus
3  * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
4  * Copyright (C) 2008-2010 Red Hat, Inc.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 #include <unistd.h>
23 #include <sys/types.h>
24 #include <sys/wait.h>
25 #include <signal.h>
26 #include <stdlib.h>
27 #include <locale.h>
28 #include <string.h>
29 #include <strings.h>
30 #include <dbus/dbus.h>
31 #include "ibusimpl.h"
32 #include "dbusimpl.h"
33 #include "server.h"
34 #include "connection.h"
35 #include "registry.h"
36 #include "factoryproxy.h"
37 #include "panelproxy.h"
38 #include "inputcontext.h"
39 #include "option.h"
40
41 enum {
42     LAST_SIGNAL,
43 };
44
45 enum {
46     PROP_0,
47 };
48
49 // static guint            _signals[LAST_SIGNAL] = { 0 };
50
51 /* functions prototype */
52 static void     bus_ibus_impl_destroy           (BusIBusImpl        *ibus);
53 static gboolean bus_ibus_impl_ibus_message      (BusIBusImpl        *ibus,
54                                                  BusConnection      *connection,
55                                                  IBusMessage        *message);
56 static void     bus_ibus_impl_add_factory       (BusIBusImpl        *ibus,
57                                                  BusFactoryProxy    *factory);
58 static void     bus_ibus_impl_set_trigger       (BusIBusImpl        *ibus,
59                                                  GValue             *value);
60 static void     bus_ibus_impl_set_next_engine_in_menu
61                                                 (BusIBusImpl        *ibus,
62                                                  GValue             *value);
63 static void     bus_ibus_impl_set_previous_engine
64                                                 (BusIBusImpl        *ibus,
65                                                  GValue             *value);
66
67 static void     bus_ibus_impl_set_preload_engines
68                                                 (BusIBusImpl        *ibus,
69                                                  GValue             *value);
70 static void     bus_ibus_impl_set_use_sys_layout
71                                                 (BusIBusImpl        *ibus,
72                                                  GValue             *value);
73 static void     bus_ibus_impl_set_embed_preedit_text
74                                                 (BusIBusImpl        *ibus,
75                                                  GValue             *value);
76 static void     bus_ibus_impl_set_enable_by_default
77                                                 (BusIBusImpl        *ibus,
78                                                  GValue             *value);
79
80 static void     bus_ibus_impl_set_use_global_engine
81                                                 (BusIBusImpl        *ibus,
82                                                  GValue             *value);
83 static void     bus_ibus_impl_set_global_engine (BusIBusImpl        *ibus,
84                                                  BusEngineProxy     *engine);
85
86 static void     bus_ibus_impl_registry_changed  (BusIBusImpl        *ibus);
87 static void     bus_ibus_impl_global_engine_changed
88                                                 (BusIBusImpl        *ibus);
89
90 static void     _factory_destroy_cb             (BusFactoryProxy    *factory,
91                                                  BusIBusImpl        *ibus);
92
93 static void     bus_ibus_impl_set_context_engine(BusIBusImpl        *ibus,
94                                                  BusInputContext    *context,
95                                                  BusEngineProxy     *engine);
96
97 static gchar   *bus_ibus_impl_load_global_engine_name_from_config
98                                                 (BusIBusImpl        *ibus);
99 static void     bus_ibus_impl_save_global_engine_name_to_config
100                                                 (BusIBusImpl        *ibus);
101
102 static gchar   *bus_ibus_impl_load_global_previous_engine_name_from_config
103                                                 (BusIBusImpl        *ibus);
104 static void     bus_ibus_impl_save_global_previous_engine_name_to_config
105                                                 (BusIBusImpl        *ibus);
106
107 G_DEFINE_TYPE(BusIBusImpl, bus_ibus_impl, IBUS_TYPE_SERVICE)
108
109 BusIBusImpl *
110 bus_ibus_impl_get_default (void)
111 {
112     static BusIBusImpl *ibus = NULL;
113
114     if (ibus == NULL) {
115         ibus = (BusIBusImpl *) g_object_new (BUS_TYPE_IBUS_IMPL,
116                                              "path", IBUS_PATH_IBUS,
117                                              NULL);
118         bus_dbus_impl_register_object (BUS_DEFAULT_DBUS,
119                                        (IBusService *)ibus);
120     }
121     return ibus;
122 }
123
124 static void
125 bus_ibus_impl_class_init (BusIBusImplClass *klass)
126 {
127     IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (klass);
128
129     ibus_object_class->destroy = (IBusObjectDestroyFunc) bus_ibus_impl_destroy;
130
131     IBUS_SERVICE_CLASS (klass)->ibus_message = (ServiceIBusMessageFunc) bus_ibus_impl_ibus_message;
132
133 }
134
135 static void
136 _panel_destroy_cb (BusPanelProxy *panel,
137                    BusIBusImpl   *ibus)
138 {
139     g_assert (BUS_IS_PANEL_PROXY (panel));
140     g_assert (BUS_IS_IBUS_IMPL (ibus));
141
142     g_return_if_fail (ibus->panel == panel);
143
144     ibus->panel = NULL;
145     g_object_unref (panel);
146 }
147
148 static void
149 bus_ibus_impl_set_hotkey (BusIBusImpl *ibus,
150                           GQuark       hotkey,
151                           GValue      *value)
152 {
153     g_assert (BUS_IS_IBUS_IMPL (ibus));
154
155     GValueArray *array;
156     gint i;
157
158     ibus_hotkey_profile_remove_hotkey_by_event (ibus->hotkey_profile, hotkey);
159
160     if (value == NULL) {
161         return;
162     }
163
164     g_return_if_fail (G_VALUE_TYPE (value) == G_TYPE_VALUE_ARRAY);
165     array = g_value_get_boxed (value);
166
167     for (i = 0; i < array->n_values; i++) {
168        GValue *str;
169
170        str = g_value_array_get_nth (array, i);
171        g_return_if_fail (G_VALUE_TYPE (str) == G_TYPE_STRING);
172
173        ibus_hotkey_profile_add_hotkey_from_string (ibus->hotkey_profile,
174                                                    g_value_get_string (str),
175                                                    hotkey);
176    }
177
178 }
179
180 static void
181 bus_ibus_impl_set_trigger (BusIBusImpl *ibus,
182                            GValue      *value)
183 {
184     GQuark hotkey = g_quark_from_static_string ("trigger");
185     bus_ibus_impl_set_hotkey (ibus, hotkey, value);
186     if (value == NULL) {
187         ibus_hotkey_profile_add_hotkey (ibus->hotkey_profile,
188                                         IBUS_space,
189                                         IBUS_CONTROL_MASK,
190                                         hotkey);
191     }
192 }
193
194 static void
195 bus_ibus_impl_set_next_engine_in_menu (BusIBusImpl *ibus,
196                                        GValue      *value)
197 {
198     GQuark hotkey = g_quark_from_static_string ("next-engine-in-menu");
199     bus_ibus_impl_set_hotkey (ibus, hotkey, value);
200 }
201
202 static void
203 bus_ibus_impl_set_previous_engine (BusIBusImpl *ibus,
204                                    GValue      *value)
205 {
206     GQuark hotkey = g_quark_from_static_string ("previous-engine");
207     bus_ibus_impl_set_hotkey (ibus, hotkey, value);
208 }
209
210 static void
211 bus_ibus_impl_set_preload_engines (BusIBusImpl *ibus,
212                                    GValue      *value)
213 {
214     GList *engine_list = NULL;
215
216     g_list_foreach (ibus->engine_list, (GFunc) g_object_unref, NULL);
217     g_list_free (ibus->engine_list);
218
219     if (value != NULL && G_VALUE_TYPE (value) == G_TYPE_VALUE_ARRAY) {
220         GValueArray *array;
221         gint i;
222
223         array = (GValueArray *) g_value_get_boxed (value);
224         for (i = 0; array && i < array->n_values; i++) {
225             const gchar *engine_name;
226             IBusEngineDesc *engine;
227
228             if (G_VALUE_TYPE (&array->values[i]) != G_TYPE_STRING)
229                 continue;
230
231             engine_name = g_value_get_string (&array->values[i]);
232
233             engine = bus_registry_find_engine_by_name (ibus->registry, engine_name);
234
235             if (engine == NULL || g_list_find (engine_list, engine) != NULL)
236                 continue;
237
238             engine_list = g_list_append (engine_list, engine);
239         }
240     }
241
242     g_list_foreach (engine_list, (GFunc) g_object_ref, NULL);
243     ibus->engine_list = engine_list;
244
245     if (ibus->engine_list) {
246         IBusComponent *component;
247
248         component = ibus_component_get_from_engine ((IBusEngineDesc *) ibus->engine_list->data);
249         if (component && !ibus_component_is_running (component)) {
250             ibus_component_start (component, g_verbose);
251         }
252     }
253 }
254
255 static void
256 bus_ibus_impl_set_use_sys_layout (BusIBusImpl *ibus,
257                                   GValue      *value)
258 {
259     if (value != NULL && G_VALUE_TYPE (value) == G_TYPE_BOOLEAN) {
260         ibus->use_sys_layout = g_value_get_boolean (value);
261     }
262 }
263
264 static void
265 bus_ibus_impl_set_embed_preedit_text (BusIBusImpl *ibus,
266                                       GValue      *value)
267 {
268     if (value != NULL && G_VALUE_TYPE (value) == G_TYPE_BOOLEAN) {
269         ibus->embed_preedit_text = g_value_get_boolean (value);
270     }
271 }
272
273 static void
274 bus_ibus_impl_set_enable_by_default (BusIBusImpl *ibus,
275                                      GValue      *value)
276 {
277     if (value != NULL && G_VALUE_TYPE (value) == G_TYPE_BOOLEAN) {
278         ibus->enable_by_default = g_value_get_boolean (value);
279     }
280 }
281
282 static void
283 bus_ibus_impl_set_use_global_engine (BusIBusImpl *ibus,
284                                      GValue      *value)
285 {
286     gboolean new_value;
287
288     if (value == NULL || G_VALUE_TYPE (value) != G_TYPE_BOOLEAN) {
289         return;
290     }
291
292     new_value = g_value_get_boolean (value);
293     if (ibus->use_global_engine == new_value) {
294         return;
295     }
296
297     if (new_value == TRUE) {
298         BusEngineProxy *engine;
299         /* turn on use_global_engine option */
300         ibus->use_global_engine = TRUE;
301         engine = ibus->focused_context != NULL ?
302                     bus_input_context_get_engine (ibus->focused_context) : NULL;
303         if (engine) {
304             bus_ibus_impl_set_global_engine (ibus, engine);
305         }
306     }
307     else {
308         /* turn off use_global_engine option */
309         bus_ibus_impl_set_global_engine (ibus, NULL);
310         ibus->use_global_engine = FALSE;
311
312         g_free (ibus->global_previous_engine_name);
313     }
314 }
315
316 static gint
317 _engine_desc_cmp (IBusEngineDesc *desc1,
318                   IBusEngineDesc *desc2)
319 {
320     return - ((gint) desc1->rank) + ((gint) desc2->rank);
321 }
322
323 static void
324 bus_ibus_impl_set_default_preload_engines (BusIBusImpl *ibus)
325 {
326     g_assert (BUS_IS_IBUS_IMPL (ibus));
327
328     static gboolean done = FALSE;
329     GValue value = { 0 };
330     GList *engines, *list;
331     gchar *lang, *p;
332     GValueArray *array;
333
334     if (done || ibus->config == NULL) {
335         return;
336     }
337
338     if (ibus_config_get_value (ibus->config, "general", "preload_engines", &value)) {
339         done = TRUE;
340         g_value_unset (&value);
341         return;
342     }
343
344     done = TRUE;
345     lang = g_strdup (setlocale (LC_ALL, NULL));
346     p = index (lang, '.');
347     if (p) {
348         *p = '\0';
349     }
350
351     engines = bus_registry_get_engines_by_language (ibus->registry, lang);
352     if (engines == NULL) {
353         p = index (lang, '_');
354         if (p) {
355             *p = '\0';
356             engines = bus_registry_get_engines_by_language (ibus->registry, lang);
357         }
358     }
359     g_free (lang);
360
361     /* sort engines by rank */
362     engines = g_list_sort (engines, (GCompareFunc) _engine_desc_cmp);
363
364     g_value_init (&value, G_TYPE_VALUE_ARRAY);
365     array = g_value_array_new (5);
366     for (list = engines; list != NULL; list = list->next) {
367         IBusEngineDesc *desc;
368         GValue name = { 0 };
369         desc = (IBusEngineDesc *)list->data;
370
371         /* ignore engines with rank <== 0 */
372         if (desc->rank <= 0)
373             break;
374         g_value_init (&name, G_TYPE_STRING);
375         g_value_set_string (&name, desc->name);
376         g_value_array_append (array, &name);
377     }
378     g_value_take_boxed (&value, array);
379     ibus_config_set_value (ibus->config, "general", "preload_engines", &value);
380     g_value_unset (&value);
381     g_list_free (engines);
382 }
383
384 static void
385 bus_ibus_impl_reload_config (BusIBusImpl *ibus)
386 {
387     g_assert (BUS_IS_IBUS_IMPL (ibus));
388
389     gint i;
390     GValue value = { 0 };
391
392     const static struct {
393         gchar *section;
394         gchar *key;
395         void ( *func) (BusIBusImpl *, GValue *);
396     } entries [] = {
397         { "general/hotkey", "trigger", bus_ibus_impl_set_trigger },
398         /* Only for backward compatibility, shall be removed later. */
399         { "general/hotkey", "next_engine", bus_ibus_impl_set_next_engine_in_menu },
400         { "general/hotkey", "next_engine_in_menu", bus_ibus_impl_set_next_engine_in_menu },
401         /* Only for backward compatibility, shall be removed later. */
402         { "general/hotkey", "prev_engine", bus_ibus_impl_set_previous_engine },
403         { "general/hotkey", "previous_engine", bus_ibus_impl_set_previous_engine },
404         { "general", "preload_engines", bus_ibus_impl_set_preload_engines },
405         { "general", "use_system_keyboard_layout", bus_ibus_impl_set_use_sys_layout },
406         { "general", "use_global_engine", bus_ibus_impl_set_use_global_engine },
407         { "general", "embed_preedit_text", bus_ibus_impl_set_embed_preedit_text },
408         { "general", "enable_by_default", bus_ibus_impl_set_enable_by_default },
409     };
410
411     for (i = 0; i < G_N_ELEMENTS (entries); i++) {
412         if (ibus->config != NULL &&
413             ibus_config_get_value (ibus->config,
414                                    entries[i].section,
415                                    entries[i].key,
416                                    &value)) {
417             entries[i].func (ibus, &value);
418             g_value_unset (&value);
419         }
420         else {
421             entries[i].func (ibus, NULL);
422         }
423     }
424 }
425
426 static void
427 _config_value_changed_cb (IBusConfig  *config,
428                           gchar       *section,
429                           gchar       *key,
430                           GValue      *value,
431                           BusIBusImpl *ibus)
432 {
433     g_assert (IBUS_IS_CONFIG (config));
434     g_assert (section);
435     g_assert (key);
436     g_assert (value);
437     g_assert (BUS_IS_IBUS_IMPL (ibus));
438
439     gint i;
440
441     const static struct {
442         gchar *section;
443         gchar *key;
444         void ( *func) (BusIBusImpl *, GValue *);
445     } entries [] = {
446         { "general/hotkey", "trigger", bus_ibus_impl_set_trigger },
447         /* Only for backward compatibility, shall be removed later. */
448         { "general/hotkey", "next_engine", bus_ibus_impl_set_next_engine_in_menu },
449         { "general/hotkey", "next_engine_in_menu", bus_ibus_impl_set_next_engine_in_menu },
450         /* Only for backward compatibility, shall be removed later. */
451         { "general/hotkey", "prev_engine", bus_ibus_impl_set_previous_engine },
452         { "general/hotkey", "previous_engine", bus_ibus_impl_set_previous_engine },
453         { "general", "preload_engines",    bus_ibus_impl_set_preload_engines },
454         { "general", "use_system_keyboard_layout", bus_ibus_impl_set_use_sys_layout },
455         { "general", "use_global_engine", bus_ibus_impl_set_use_global_engine },
456         { "general", "embed_preedit_text", bus_ibus_impl_set_embed_preedit_text },
457         { "general", "enable_by_default", bus_ibus_impl_set_enable_by_default },
458     };
459
460     for (i = 0; i < G_N_ELEMENTS (entries); i++) {
461         if (g_strcmp0 (entries[i].section, section) == 0 &&
462             g_strcmp0 (entries[i].key, key) == 0) {
463             entries[i].func (ibus, value);
464             break;
465         }
466     }
467 }
468
469 static void
470 _config_destroy_cb (IBusConfig  *config,
471                     BusIBusImpl *ibus)
472 {
473     g_assert (IBUS_IS_CONFIG (config));
474     g_assert (BUS_IS_IBUS_IMPL (ibus));
475
476     g_assert (ibus->config == config);
477
478     g_object_unref (ibus->config);
479     ibus->config = NULL;
480 }
481
482 static void
483 _registry_changed_cb (BusRegistry *registry,
484                       BusIBusImpl *ibus)
485 {
486     bus_ibus_impl_registry_changed (ibus);
487 }
488
489 static void
490 _dbus_name_owner_changed_cb (BusDBusImpl *dbus,
491                              const gchar *name,
492                              const gchar *old_name,
493                              const gchar *new_name,
494                              BusIBusImpl *ibus)
495 {
496     g_assert (BUS_IS_DBUS_IMPL (dbus));
497     g_assert (name != NULL);
498     g_assert (old_name != NULL);
499     g_assert (new_name != NULL);
500     g_assert (BUS_IS_IBUS_IMPL (ibus));
501
502     BusFactoryProxy *factory;
503
504     if (g_strcmp0 (name, IBUS_SERVICE_PANEL) == 0) {
505         if (g_strcmp0 (new_name, "") != 0) {
506             BusConnection *connection;
507
508             if (ibus->panel != NULL) {
509                 ibus_object_destroy (IBUS_OBJECT (ibus->panel));
510                 /* panel should be NULL after destroy */
511                 g_assert (ibus->panel == NULL);
512             }
513
514             connection = bus_dbus_impl_get_connection_by_name (BUS_DEFAULT_DBUS, new_name);
515             g_return_if_fail (connection != NULL);
516
517             ibus->panel = bus_panel_proxy_new (connection);
518             g_object_ref_sink (ibus->panel);
519
520             g_signal_connect (ibus->panel,
521                               "destroy",
522                               G_CALLBACK (_panel_destroy_cb),
523                               ibus);
524
525             if (ibus->focused_context != NULL) {
526                 bus_panel_proxy_focus_in (ibus->panel, ibus->focused_context);
527             }
528         }
529     }
530     else if (g_strcmp0 (name, IBUS_SERVICE_CONFIG) == 0) {
531         if (g_strcmp0 (new_name, "") != 0) {
532             BusConnection *connection;
533
534             if (ibus->config != NULL) {
535                 ibus_object_destroy (IBUS_OBJECT (ibus->config));
536                 /* config should be NULL */
537                 g_assert (ibus->config == NULL);
538             }
539
540             connection = bus_dbus_impl_get_connection_by_name (BUS_DEFAULT_DBUS, new_name);
541             g_return_if_fail (connection != NULL);
542
543             ibus->config = g_object_new (IBUS_TYPE_CONFIG,
544                                          "name", NULL,
545                                          "path", IBUS_PATH_CONFIG,
546                                          "connection", connection,
547                                          NULL);
548             g_object_ref_sink (ibus->config);
549
550             g_signal_connect (ibus->config,
551                               "value-changed",
552                               G_CALLBACK (_config_value_changed_cb),
553                               ibus);
554
555             g_signal_connect (ibus->config,
556                               "destroy",
557                               G_CALLBACK (_config_destroy_cb),
558                               ibus);
559
560             bus_ibus_impl_set_default_preload_engines (ibus);
561             bus_ibus_impl_reload_config (ibus);
562         }
563     }
564
565     factory = bus_registry_name_owner_changed (ibus->registry, name, old_name, new_name);
566
567     if (factory) {
568         bus_ibus_impl_add_factory (ibus, factory);
569     }
570 }
571
572 static void
573 bus_ibus_impl_init (BusIBusImpl *ibus)
574 {
575     ibus->factory_dict = g_hash_table_new_full (
576                             g_str_hash,
577                             g_str_equal,
578                             NULL,
579                             (GDestroyNotify) g_object_unref);
580
581     ibus->engine_list = NULL;
582     ibus->register_engine_list = NULL;
583     ibus->contexts = NULL;
584     ibus->focused_context = NULL;
585     ibus->panel = NULL;
586     ibus->config = NULL;
587
588     ibus->registry = bus_registry_new ();
589
590     g_signal_connect (ibus->registry,
591                       "changed",
592                       G_CALLBACK (_registry_changed_cb),
593                       ibus);
594 #ifdef G_THREADS_ENABLED
595     extern gint g_monitor_timeout;
596     if (g_monitor_timeout != 0) {
597         bus_registry_start_monitor_changes (ibus->registry);
598     }
599 #endif
600
601     ibus->hotkey_profile = ibus_hotkey_profile_new ();
602     ibus->keymap = ibus_keymap_get ("us");
603
604     ibus->use_sys_layout = FALSE;
605     ibus->embed_preedit_text = TRUE;
606     ibus->enable_by_default = FALSE;
607     ibus->use_global_engine = FALSE;
608     ibus->global_engine = NULL;
609     ibus->global_previous_engine_name = NULL;
610
611     bus_ibus_impl_reload_config (ibus);
612
613     g_signal_connect (BUS_DEFAULT_DBUS,
614                       "name-owner-changed",
615                       G_CALLBACK (_dbus_name_owner_changed_cb),
616                       ibus);
617 }
618
619 static void
620 bus_ibus_impl_destroy (BusIBusImpl *ibus)
621 {
622     pid_t pid;
623     glong timeout;
624     gint status;
625     gboolean flag;
626
627     bus_registry_stop_all_components (ibus->registry);
628
629     pid = 0;
630     timeout = 0;
631     flag = FALSE;
632     while (1) {
633         while ((pid = waitpid (0, &status, WNOHANG)) > 0);
634
635         if (pid == -1) { /* all children finished */
636             break;
637         }
638         if (pid == 0) { /* no child status changed */
639             g_usleep (1000);
640             timeout += 1000;
641             if (timeout >= G_USEC_PER_SEC) {
642                 if (flag == FALSE) {
643                     gpointer old;
644                     old = signal (SIGTERM, SIG_IGN);
645                     kill (-getpid (), SIGTERM);
646                     signal (SIGTERM, old);
647                     flag = TRUE;
648                 }
649                 else {
650                     g_warning ("Not every child processes exited!");
651                     break;
652                 }
653             }
654         }
655     };
656
657     g_list_foreach (ibus->engine_list, (GFunc) g_object_unref, NULL);
658     g_list_free (ibus->engine_list);
659     ibus->engine_list = NULL;
660
661     g_list_foreach (ibus->register_engine_list, (GFunc) g_object_unref, NULL);
662     g_list_free (ibus->register_engine_list);
663     ibus->register_engine_list = NULL;
664
665     if (ibus->factory_dict != NULL) {
666         g_hash_table_destroy (ibus->factory_dict);
667         ibus->factory_dict = NULL;
668     }
669
670     if (ibus->hotkey_profile != NULL) {
671         g_object_unref (ibus->hotkey_profile);
672         ibus->hotkey_profile = NULL;
673     }
674
675     if (ibus->keymap != NULL) {
676         g_object_unref (ibus->keymap);
677         ibus->keymap = NULL;
678     }
679
680     if (ibus->global_engine) {
681         g_object_unref (ibus->global_engine);
682         ibus->global_engine = NULL;
683     }
684
685     g_free (ibus->global_previous_engine_name);
686
687     bus_server_quit (BUS_DEFAULT_SERVER);
688     ibus_object_destroy ((IBusObject *) BUS_DEFAULT_SERVER);
689     IBUS_OBJECT_CLASS(bus_ibus_impl_parent_class)->destroy (IBUS_OBJECT (ibus));
690 }
691
692 /* introspectable interface */
693 static IBusMessage *
694 _ibus_introspect (BusIBusImpl     *ibus,
695                   IBusMessage     *message,
696                   BusConnection   *connection)
697 {
698     static const gchar *introspect =
699         DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE
700         "<node>\n"
701         "  <interface name=\"org.freedesktop.DBus.Introspectable\">\n"
702         "    <method name=\"Introspect\">\n"
703         "      <arg name=\"data\" direction=\"out\" type=\"s\"/>\n"
704         "    </method>\n"
705         "  </interface>\n"
706         "  <interface name=\"org.freedesktop.IBus\">\n"
707         "    <method name=\"GetAddress\">\n"
708         "      <arg name=\"address\" direction=\"out\" type=\"s\"/>\n"
709         "    </method>\n"
710         "    <method name=\"CreateInputContext\">\n"
711         "      <arg name=\"name\" direction=\"in\" type=\"s\"/>\n"
712         "      <arg name=\"context\" direction=\"out\" type=\"o\"/>\n"
713         "    </method>\n"
714         "    <method name=\"CurrentInputContext\">\n"
715         "      <arg name=\"name\" direction=\"out\" type=\"s\"/>\n"
716         "    </method>\n"
717         "    <method name=\"RegisterComponent\">\n"
718         "      <arg name=\"components\" direction=\"in\" type=\"v\"/>\n"
719         "    </method>\n"
720         "    <method name=\"ListEngines\">\n"
721         "      <arg name=\"engines\" direction=\"out\" type=\"av\"/>\n"
722         "    </method>\n"
723         "    <method name=\"ListActiveEngines\">\n"
724         "      <arg name=\"engines\" direction=\"out\" type=\"av\"/>\n"
725         "    </method>\n"
726         "    <method name=\"Exit\">\n"
727         "      <arg name=\"restart\" direction=\"in\" type=\"b\"/>\n"
728         "    </method>\n"
729         "    <method name=\"Ping\">\n"
730         "      <arg name=\"data\" direction=\"in\" type=\"v\"/>\n"
731         "      <arg name=\"data\" direction=\"out\" type=\"v\"/>\n"
732         "    </method>\n"
733         "    <method name=\"GetUseSysLayout\">\n"
734         "      <arg name=\"enable\" direction=\"out\" type=\"b\"/>\n"
735         "    </method>\n"
736         "    <method name=\"GetUseGlobalEngine\">\n"
737         "      <arg name=\"enable\" direction=\"out\" type=\"b\"/>\n"
738         "    </method>\n"
739         "    <method name=\"GetGlobalEngine\">\n"
740         "      <arg name=\"desc\" direction=\"out\" type=\"v\"/>\n"
741         "    </method>\n"
742         "    <method name=\"SetGlobalEngine\">\n"
743         "      <arg name=\"name\" direction=\"in\" type=\"s\"/>\n"
744         "    </method>\n"
745         "    <method name=\"IsGlobalEngineEnabled\">\n"
746         "      <arg name=\"enable\" direction=\"out\" type=\"b\"/>\n"
747         "    </method>\n"
748         "    <signal name=\"RegistryChanged\">\n"
749         "    </signal>\n"
750         "    <signal name=\"GlobalEngineChanged\">\n"
751         "    </signal>\n"
752         "  </interface>\n"
753         "</node>\n";
754
755     IBusMessage *reply_message;
756     reply_message = ibus_message_new_method_return (message);
757     ibus_message_append_args (reply_message,
758                               G_TYPE_STRING, &introspect,
759                               G_TYPE_INVALID);
760
761     return reply_message;
762 }
763
764
765
766 static IBusMessage *
767 _ibus_get_address (BusIBusImpl     *ibus,
768                    IBusMessage     *message,
769                    BusConnection   *connection)
770 {
771     const gchar *address;
772     IBusMessage *reply;
773
774     address = ibus_server_get_address (IBUS_SERVER (BUS_DEFAULT_SERVER));
775
776     reply = ibus_message_new_method_return (message);
777     ibus_message_append_args (reply,
778                               G_TYPE_STRING, &address,
779                               G_TYPE_INVALID);
780
781     return reply;
782 }
783
784 static BusEngineProxy *
785 bus_ibus_impl_create_engine (IBusEngineDesc *engine_desc)
786 {
787     IBusComponent *comp;
788     BusFactoryProxy *factory;
789     BusEngineProxy *engine;
790     GTimeVal t1, t2;
791
792     factory = bus_factory_proxy_get_from_engine (engine_desc);
793
794     if (factory == NULL) {
795         /* try to execute the engine */
796         comp = ibus_component_get_from_engine (engine_desc);
797         g_assert (comp);
798
799         if (!ibus_component_is_running (comp)) {
800             ibus_component_start (comp, g_verbose);
801             g_get_current_time (&t1);
802             while (1) {
803                 if (g_main_context_pending (NULL)) {
804                     g_main_context_iteration (NULL, FALSE);
805                     factory = bus_factory_proxy_get_from_engine (engine_desc);
806                     if (factory != NULL) {
807                         break;
808                     }
809                 }
810                 g_get_current_time (&t2);
811                 if (t2.tv_sec - t1.tv_sec >= 5)
812                     break;
813             }
814         }
815         else {
816             factory = bus_factory_proxy_get_from_engine (engine_desc);
817         }
818     }
819
820     if (factory == NULL) {
821         return NULL;
822     }
823
824     g_object_ref (factory);
825     engine = bus_factory_proxy_create_engine (factory, engine_desc);
826     g_object_unref (factory);
827
828     return engine;
829 }
830
831 static IBusEngineDesc *
832 _find_engine_desc_by_name(BusIBusImpl *ibus,
833                           gchar *engine_name)
834 {
835     IBusEngineDesc *engine_desc = NULL;
836     GList *p;
837
838     /* find engine in registered engine list */
839     for (p = ibus->register_engine_list; p != NULL; p = p->next) {
840         engine_desc = (IBusEngineDesc *)p->data;
841         if (g_strcmp0 (engine_desc->name, engine_name) == 0)
842             return engine_desc;
843     }
844
845     /* find engine in preload engine list */
846     for (p = ibus->engine_list; p != NULL; p = p->next) {
847         engine_desc = (IBusEngineDesc *)p->data;
848         if (g_strcmp0 (engine_desc->name, engine_name) == 0)
849             return engine_desc;
850     }
851
852     return NULL;
853 }
854
855 static void
856 _context_request_engine_cb (BusInputContext *context,
857                             gchar           *engine_name,
858                             BusIBusImpl     *ibus)
859 {
860     IBusEngineDesc *engine_desc = NULL;
861     BusEngineProxy *engine;
862
863     /* context should has focus before request an engine */
864     g_return_if_fail (bus_input_context_has_focus (context));
865
866     if (engine_name == NULL || engine_name[0] == '\0') {
867         /* Use global engine if possible. */
868         if (ibus->use_global_engine) {
869             if (ibus->global_engine) {
870                 bus_ibus_impl_set_context_engine (ibus, context, ibus->global_engine);
871                 return;
872             }
873             else {
874                 engine_name = bus_ibus_impl_load_global_engine_name_from_config (ibus);
875                 if (engine_name) {
876                     engine_desc = _find_engine_desc_by_name (ibus, engine_name);
877                     g_free (engine_name);
878                 }
879             }
880         }
881         /* request default engine */
882         if (!engine_desc) {
883             if (ibus->register_engine_list) {
884                 engine_desc = (IBusEngineDesc *)ibus->register_engine_list->data;
885             }
886             else if (ibus->engine_list) {
887                 engine_desc = (IBusEngineDesc *)ibus->engine_list->data;
888             }
889          }
890     }
891     else {
892         /* request engine by name */
893         engine_desc = _find_engine_desc_by_name (ibus, engine_name);
894     }
895
896     if (engine_desc != NULL) {
897         engine = bus_ibus_impl_create_engine (engine_desc);
898         if (engine != NULL) {
899             bus_ibus_impl_set_context_engine (ibus, context, engine);
900         }
901     }
902 }
903
904 static void
905 bus_ibus_impl_context_request_next_engine_in_menu (BusIBusImpl     *ibus,
906                                                    BusInputContext *context)
907 {
908     BusEngineProxy *engine;
909     IBusEngineDesc *desc;
910     IBusEngineDesc *next_desc = NULL;
911     GList *p;
912
913     engine = bus_input_context_get_engine (context);
914     if (engine == NULL) {
915         _context_request_engine_cb (context, NULL, ibus);
916         return;
917     }
918
919     desc = bus_engine_proxy_get_desc (engine);
920
921     p = g_list_find (ibus->register_engine_list, desc);
922     if (p != NULL) {
923         p = p->next;
924     }
925     if (p == NULL) {
926         p = g_list_find (ibus->engine_list, desc);
927         if (p != NULL) {
928             p = p->next;
929         }
930     }
931
932     if (p != NULL) {
933         next_desc = (IBusEngineDesc*) p->data;
934     }
935     else {
936         if (ibus->register_engine_list) {
937             next_desc = (IBusEngineDesc *)ibus->register_engine_list->data;
938         }
939         else if (ibus->engine_list) {
940             next_desc = (IBusEngineDesc *)ibus->engine_list->data;
941         }
942     }
943
944     if (next_desc != NULL) {
945         engine = bus_ibus_impl_create_engine (next_desc);
946         if (engine != NULL) {
947             bus_ibus_impl_set_context_engine (ibus, context, engine);
948         }
949     }
950 }
951
952 static void
953 bus_ibus_impl_context_request_previous_engine (BusIBusImpl     *ibus,
954                                                BusInputContext *context)
955 {
956     gchar *engine_name = NULL;
957     if (!ibus->use_global_engine) {
958         engine_name = (gchar *) g_object_get_data (G_OBJECT (context), "previous-engine-name");
959     }
960     else {
961         if (!ibus->global_previous_engine_name) {
962             ibus->global_previous_engine_name = bus_ibus_impl_load_global_previous_engine_name_from_config (ibus);
963         }
964         engine_name = ibus->global_previous_engine_name;
965     }
966
967     _context_request_engine_cb (context, engine_name, ibus);
968 }
969
970 static void
971 _global_engine_destroy_cb (BusEngineProxy *engine,
972                            BusIBusImpl    *ibus)
973 {
974     if (ibus->global_engine != engine) {
975         return;
976     }
977
978     g_signal_handlers_disconnect_by_func (ibus->global_engine,
979                 G_CALLBACK (_global_engine_destroy_cb), ibus);
980     g_object_unref (ibus->global_engine);
981     ibus->global_engine = NULL;
982 }
983
984 static void
985 bus_ibus_impl_set_global_engine (BusIBusImpl    *ibus,
986                                  BusEngineProxy *engine)
987 {
988     g_assert (ibus->use_global_engine == TRUE);
989
990     if (ibus->global_engine == engine) {
991         return;
992     }
993
994     g_free (ibus->global_previous_engine_name);
995     ibus->global_previous_engine_name = NULL;
996     if (ibus->global_engine) {
997         /* Save the current global engine's name as previous engine. */
998         ibus->global_previous_engine_name = g_strdup (bus_engine_proxy_get_desc (ibus->global_engine)->name);
999
1000         ibus_object_destroy ((IBusObject *)ibus->global_engine);
1001         /* global_engine should be NULL */
1002         g_assert (ibus->global_engine == NULL);
1003     }
1004
1005     if (engine != NULL && !IBUS_OBJECT_DESTROYED (engine)) {
1006         g_object_ref (engine);
1007         ibus->global_engine = engine;
1008         g_signal_connect (ibus->global_engine, "destroy",
1009                 G_CALLBACK (_global_engine_destroy_cb), ibus);
1010     }
1011
1012     bus_ibus_impl_save_global_engine_name_to_config (ibus);
1013     bus_ibus_impl_save_global_previous_engine_name_to_config (ibus);
1014     bus_ibus_impl_global_engine_changed (ibus);
1015 }
1016
1017 static void
1018 bus_ibus_impl_set_context_engine (BusIBusImpl     *ibus,
1019                                   BusInputContext *context,
1020                                   BusEngineProxy  *engine) {
1021   g_object_set_data (G_OBJECT (context), "previous-engine-name", NULL);
1022
1023   /* If use_global_engine is disabled, then we need to save the previous engine
1024    * of each input context. */
1025   if (!ibus->use_global_engine) {
1026       BusEngineProxy *previous_engine = bus_input_context_get_engine (context);
1027       if (previous_engine) {
1028           g_object_set_data_full (G_OBJECT (context), "previous-engine-name",
1029                                   g_strdup (bus_engine_proxy_get_desc (previous_engine)->name),
1030                                   g_free);
1031       }
1032   }
1033
1034   bus_input_context_set_engine (context, engine);
1035 }
1036
1037 static void
1038 _context_engine_changed_cb (BusInputContext *context,
1039                             BusIBusImpl     *ibus)
1040 {
1041     BusEngineProxy *engine;
1042
1043     if (context != ibus->focused_context || !ibus->use_global_engine) {
1044         return;
1045     }
1046
1047     engine = bus_input_context_get_engine (context);
1048     if (engine != NULL) {
1049         /* only set global engine if engine is not NULL */
1050         bus_ibus_impl_set_global_engine (ibus, engine);
1051     }
1052 }
1053
1054 static void
1055 _context_focus_out_cb (BusInputContext    *context,
1056                        BusIBusImpl        *ibus)
1057 {
1058     g_assert (BUS_IS_IBUS_IMPL (ibus));
1059     g_assert (BUS_IS_INPUT_CONTEXT (context));
1060
1061     /* Do noting if context does not support focus.
1062      * Actually, the context should emit focus signals, if it does not support focus */
1063     if ((bus_input_context_get_capabilities (context) & IBUS_CAP_FOCUS) == 0) {
1064         return;
1065     }
1066
1067     /* Do noting if it is not focused context. */
1068     if (ibus->focused_context != context) {
1069         return;
1070     }
1071
1072     ibus->focused_context = NULL;
1073
1074     if (ibus->panel != NULL) {
1075         bus_panel_proxy_focus_out (ibus->panel, context);
1076     }
1077
1078     /* If the use_global_engine option is enabled,
1079      * the global engine shoule be detached from the focused context. */
1080     if (ibus->use_global_engine) {
1081         bus_ibus_impl_set_context_engine (ibus, context, NULL);
1082     }
1083
1084     g_object_unref (context);
1085 }
1086
1087 static void
1088 _context_focus_in_cb (BusInputContext *context,
1089                       BusIBusImpl     *ibus)
1090 {
1091     g_assert (BUS_IS_IBUS_IMPL (ibus));
1092     g_assert (BUS_IS_INPUT_CONTEXT (context));
1093
1094     /* Do nothing if context does not support focus.
1095      * The global engine shoule be detached from the focused context. */
1096     if ((bus_input_context_get_capabilities (context) & IBUS_CAP_FOCUS) == 0) {
1097         return;
1098     }
1099
1100     /* Do nothing if it is focused context already. */
1101     if (ibus->focused_context == context) {
1102         return;
1103     }
1104
1105     if (ibus->focused_context) {
1106         /* focus out context */
1107         bus_input_context_focus_out (ibus->focused_context);
1108         g_assert (ibus->focused_context == NULL);
1109     }
1110
1111     /* If the use_global_engine option is enabled, then we need:
1112      * - Switch the context to use the global engine or save the context's
1113      *   existing engine as global engine.
1114      * - Set the context's enabled state according to the saved state.
1115      * Note: we get this signal only if the context supports IBUS_CAP_FOCUS. */
1116     if (ibus->use_global_engine) {
1117         if (!ibus->global_engine) {
1118             bus_ibus_impl_set_global_engine (ibus, bus_input_context_get_engine (context));
1119         }
1120         else {
1121             bus_ibus_impl_set_context_engine (ibus, context, ibus->global_engine);
1122             if (ibus->global_engine && bus_engine_proxy_is_enabled (ibus->global_engine)) {
1123                 bus_input_context_enable (context);
1124             }
1125         }
1126     }
1127
1128     if (ibus->panel != NULL) {
1129         bus_panel_proxy_focus_in (ibus->panel, context);
1130     }
1131
1132     g_object_ref (context);
1133     ibus->focused_context = context;
1134 }
1135
1136 static void
1137 _context_destroy_cb (BusInputContext    *context,
1138                      BusIBusImpl        *ibus)
1139 {
1140     g_assert (BUS_IS_IBUS_IMPL (ibus));
1141     g_assert (BUS_IS_INPUT_CONTEXT (context));
1142
1143     if (context == ibus->focused_context) {
1144         /* focus out context */
1145         bus_input_context_focus_out (ibus->focused_context);
1146         g_assert (ibus->focused_context == NULL);
1147     }
1148
1149     ibus->contexts = g_list_remove (ibus->contexts, context);
1150     g_object_unref (context);
1151 }
1152
1153 #if 0
1154 static void
1155 _context_enabled_cb (BusInputContext    *context,
1156                      BusIBusImpl        *ibus)
1157 {
1158 }
1159
1160 static void
1161 _context_disabled_cb (BusInputContext    *context,
1162                       BusIBusImpl        *ibus)
1163 {
1164 }
1165 #endif
1166
1167 static IBusMessage *
1168 _ibus_create_input_context (BusIBusImpl     *ibus,
1169                             IBusMessage     *message,
1170                             BusConnection   *connection)
1171 {
1172     g_assert (BUS_IS_IBUS_IMPL (ibus));
1173     g_assert (message != NULL);
1174     g_assert (BUS_IS_CONNECTION (connection));
1175
1176     gint i;
1177     gchar *client;
1178     IBusError *error;
1179     IBusMessage *reply;
1180     BusInputContext *context;
1181     const gchar *path;
1182
1183     if (!ibus_message_get_args (message,
1184                                 &error,
1185                                 G_TYPE_STRING, &client,
1186                                 G_TYPE_INVALID)) {
1187         reply = ibus_message_new_error (message,
1188                                         DBUS_ERROR_INVALID_ARGS,
1189                                         "Argument 1 of CreateInputContext should be an string");
1190         ibus_error_free (error);
1191         return reply;
1192     }
1193
1194     context = bus_input_context_new (connection, client);
1195     g_object_ref_sink (context);
1196     ibus->contexts = g_list_append (ibus->contexts, context);
1197
1198     static const struct {
1199         gchar *name;
1200         GCallback callback;
1201     } signals [] = {
1202         { "request-engine",      G_CALLBACK (_context_request_engine_cb) },
1203         { "engine-changed", G_CALLBACK (_context_engine_changed_cb) },
1204         { "focus-in",       G_CALLBACK (_context_focus_in_cb) },
1205         { "focus-out",      G_CALLBACK (_context_focus_out_cb) },
1206         { "destroy",        G_CALLBACK (_context_destroy_cb) },
1207     #if 0
1208         { "enabled",        G_CALLBACK (_context_enabled_cb) },
1209         { "disabled",       G_CALLBACK (_context_disabled_cb) },
1210     #endif
1211     };
1212
1213     for (i = 0; i < G_N_ELEMENTS (signals); i++) {
1214         g_signal_connect (context,
1215                           signals[i].name,
1216                           signals[i].callback,
1217                           ibus);
1218     }
1219
1220     if (ibus->enable_by_default) {
1221         bus_input_context_enable (context);
1222     }
1223
1224     path = ibus_service_get_path ((IBusService *) context);
1225     reply = ibus_message_new_method_return (message);
1226     ibus_message_append_args (reply,
1227                               IBUS_TYPE_OBJECT_PATH, &path,
1228                               G_TYPE_INVALID);
1229
1230     bus_dbus_impl_register_object (BUS_DEFAULT_DBUS,
1231                                    (IBusService *)context);
1232     return reply;
1233 }
1234
1235 static IBusMessage *
1236 _ibus_current_input_context (BusIBusImpl     *ibus,
1237                             IBusMessage     *message,
1238                             BusConnection   *connection)
1239 {
1240     g_assert (BUS_IS_IBUS_IMPL (ibus));
1241     g_assert (message != NULL);
1242     g_assert (BUS_IS_CONNECTION (connection));
1243
1244     IBusMessage *reply;
1245     const gchar *path;
1246
1247     if (!ibus->focused_context)
1248     {
1249         reply = ibus_message_new_error (message,
1250                                         DBUS_ERROR_FAILED,
1251                                         "No input context focused");
1252         return reply;
1253     }
1254
1255     reply = ibus_message_new_method_return (message);
1256     path = ibus_service_get_path((IBusService *)ibus->focused_context);
1257     ibus_message_append_args (reply,
1258                               G_TYPE_STRING, &path,
1259                               G_TYPE_INVALID);
1260
1261     return reply;
1262 }
1263
1264 static void
1265 _factory_destroy_cb (BusFactoryProxy    *factory,
1266                      BusIBusImpl        *ibus)
1267 {
1268     g_assert (BUS_IS_IBUS_IMPL (ibus));
1269     g_assert (BUS_IS_FACTORY_PROXY (factory));
1270
1271     IBusComponent *component;
1272     GList *engines, *p;
1273
1274     ibus->factory_list = g_list_remove (ibus->factory_list, factory);
1275
1276     component = bus_factory_proxy_get_component (factory);
1277
1278     if (component != NULL) {
1279         p = engines = ibus_component_get_engines (component);
1280         for (; p != NULL; p = p->next) {
1281             if (g_list_find (ibus->register_engine_list, p->data)) {
1282                 ibus->register_engine_list = g_list_remove (ibus->register_engine_list, p->data);
1283                 g_object_unref (p->data);
1284             }
1285         }
1286         g_list_free (engines);
1287     }
1288
1289     g_object_unref (factory);
1290 }
1291
1292 static void
1293 bus_ibus_impl_add_factory (BusIBusImpl     *ibus,
1294                            BusFactoryProxy *factory)
1295 {
1296     g_assert (BUS_IS_IBUS_IMPL (ibus));
1297     g_assert (BUS_IS_FACTORY_PROXY (factory));
1298
1299     g_object_ref_sink (factory);
1300     ibus->factory_list = g_list_append (ibus->factory_list, factory);
1301
1302     g_signal_connect (factory, "destroy", G_CALLBACK (_factory_destroy_cb), ibus);
1303 }
1304
1305
1306 static IBusMessage *
1307 _ibus_register_component (BusIBusImpl     *ibus,
1308                           IBusMessage     *message,
1309                           BusConnection   *connection)
1310 {
1311     IBusMessage *reply;
1312     IBusError *error;
1313     gboolean retval;
1314     GList *engines;
1315     IBusComponent *component;
1316     BusFactoryProxy *factory;
1317
1318     retval = ibus_message_get_args (message, &error,
1319                                     IBUS_TYPE_COMPONENT, &component,
1320                                     G_TYPE_INVALID);
1321
1322     if (!retval) {
1323         reply = ibus_message_new_error_printf (message,
1324                                                DBUS_ERROR_INVALID_ARGS,
1325                                                "1st Argument must be IBusComponent: %s",
1326                                                error->message);
1327         ibus_error_free (error);
1328         return reply;
1329     }
1330
1331     g_object_ref_sink (component);
1332     factory = bus_factory_proxy_new (component, connection);
1333
1334     if (factory == NULL) {
1335         reply = ibus_message_new_error (message,
1336                                         DBUS_ERROR_FAILED,
1337                                         "Can not create factory");
1338         return reply;
1339     }
1340
1341     bus_ibus_impl_add_factory (ibus, factory);
1342
1343     engines = ibus_component_get_engines (component);
1344
1345     g_list_foreach (engines, (GFunc) g_object_ref, NULL);
1346     ibus->register_engine_list = g_list_concat (ibus->register_engine_list, engines);
1347     g_object_unref (component);
1348
1349     reply = ibus_message_new_method_return (message);
1350     return reply;
1351 }
1352
1353 static IBusMessage *
1354 _ibus_list_engines (BusIBusImpl   *ibus,
1355                     IBusMessage   *message,
1356                     BusConnection *connection)
1357 {
1358     IBusMessage *reply;
1359     IBusMessageIter iter, sub_iter;
1360     GList *engines, *p;
1361
1362     reply = ibus_message_new_method_return (message);
1363
1364     ibus_message_iter_init_append (reply, &iter);
1365     ibus_message_iter_open_container (&iter, IBUS_TYPE_ARRAY, "v", &sub_iter);
1366
1367     engines = bus_registry_get_engines (ibus->registry);
1368     for (p = engines; p != NULL; p = p->next) {
1369         ibus_message_iter_append (&sub_iter, IBUS_TYPE_ENGINE_DESC, &(p->data));
1370     }
1371     g_list_free (engines);
1372     ibus_message_iter_close_container (&iter, &sub_iter);
1373
1374     return reply;
1375 }
1376
1377 static IBusMessage *
1378 _ibus_list_active_engines (BusIBusImpl   *ibus,
1379                            IBusMessage   *message,
1380                            BusConnection *connection)
1381 {
1382     IBusMessage *reply;
1383     IBusMessageIter iter, sub_iter;
1384     GList *p;
1385
1386     reply = ibus_message_new_method_return (message);
1387
1388     ibus_message_iter_init_append (reply, &iter);
1389     ibus_message_iter_open_container (&iter, IBUS_TYPE_ARRAY, "v", &sub_iter);
1390
1391     for (p = ibus->engine_list; p != NULL; p = p->next) {
1392         ibus_message_iter_append (&sub_iter, IBUS_TYPE_ENGINE_DESC, &(p->data));
1393     }
1394
1395     for (p = ibus->register_engine_list; p != NULL; p = p->next) {
1396         ibus_message_iter_append (&sub_iter, IBUS_TYPE_ENGINE_DESC, &(p->data));
1397     }
1398     ibus_message_iter_close_container (&iter, &sub_iter);
1399
1400     return reply;
1401 }
1402
1403
1404 static IBusMessage *
1405 _ibus_exit (BusIBusImpl     *ibus,
1406             IBusMessage     *message,
1407             BusConnection   *connection)
1408 {
1409     IBusMessage *reply;
1410     IBusError *error;
1411     gboolean restart;
1412
1413     if (!ibus_message_get_args (message,
1414                                 &error,
1415                                 G_TYPE_BOOLEAN, &restart,
1416                                 G_TYPE_INVALID)) {
1417         reply = ibus_message_new_error (message,
1418                                         DBUS_ERROR_INVALID_ARGS,
1419                                         "Argument 1 of Exit should be an boolean");
1420         ibus_error_free (error);
1421         return reply;
1422     }
1423
1424     reply = ibus_message_new_method_return (message);
1425     ibus_connection_send ((IBusConnection *) connection, reply);
1426     ibus_connection_flush ((IBusConnection *) connection);
1427     ibus_message_unref (reply);
1428
1429     ibus_object_destroy ((IBusObject *) BUS_DEFAULT_SERVER);
1430
1431     if (!restart) {
1432         exit (0);
1433     }
1434     else {
1435         extern gchar **g_argv;
1436         gchar *exe;
1437         gint fd;
1438
1439         exe = g_strdup_printf ("/proc/%d/exe", getpid ());
1440         exe = g_file_read_link (exe, NULL);
1441
1442         if (exe == NULL)
1443             exe = BINDIR"/ibus-daemon";
1444
1445         /* close all fds except stdin, stdout, stderr */
1446         for (fd = 3; fd <= sysconf (_SC_OPEN_MAX); fd ++) {
1447             close (fd);
1448         }
1449
1450         execv (exe, g_argv);
1451
1452         /* If the server binary is replaced while the server is running,
1453          * "readlink /proc/[pid]/exe" might return a path with " (deleted)"
1454          * suffix. */
1455         const gchar suffix[] = " (deleted)";
1456         if (g_str_has_suffix (exe, suffix)) {
1457             exe [strlen (exe) - sizeof (suffix) + 1] = '\0';
1458             execv (exe, g_argv);
1459         }
1460         g_warning ("execv %s failed!", g_argv[0]);
1461         exit (-1);
1462     }
1463
1464     /* should not reach here */
1465     g_assert_not_reached ();
1466
1467     return NULL;
1468 }
1469
1470 static IBusMessage *
1471 _ibus_ping (BusIBusImpl     *ibus,
1472             IBusMessage     *message,
1473             BusConnection   *connection)
1474 {
1475     IBusMessage *reply;
1476     IBusMessageIter src, dst;
1477
1478     reply = ibus_message_new_method_return (message);
1479
1480     ibus_message_iter_init (message, &src);
1481     ibus_message_iter_init_append (reply, &dst);
1482
1483     ibus_message_iter_copy_data (&dst, &src);
1484
1485     return reply;
1486 }
1487
1488 static IBusMessage *
1489 _ibus_get_use_sys_layout (BusIBusImpl     *ibus,
1490                           IBusMessage     *message,
1491                           BusConnection   *connection)
1492 {
1493     IBusMessage *reply;
1494
1495     reply = ibus_message_new_method_return (message);
1496     ibus_message_append_args (reply,
1497             G_TYPE_BOOLEAN, &ibus->use_sys_layout,
1498             G_TYPE_INVALID);
1499
1500     return reply;
1501 }
1502
1503 static IBusMessage *
1504 _ibus_get_use_global_engine (BusIBusImpl     *ibus,
1505                              IBusMessage     *message,
1506                              BusConnection   *connection)
1507 {
1508     IBusMessage *reply;
1509
1510     reply = ibus_message_new_method_return (message);
1511     ibus_message_append_args (reply,
1512             G_TYPE_BOOLEAN, &ibus->use_global_engine,
1513             G_TYPE_INVALID);
1514
1515     return reply;
1516 }
1517
1518 static IBusMessage *
1519 _ibus_get_global_engine (BusIBusImpl     *ibus,
1520                          IBusMessage     *message,
1521                          BusConnection   *connection)
1522 {
1523     IBusMessage *reply;
1524
1525     if (ibus->use_global_engine && ibus->global_engine) {
1526         IBusEngineDesc *desc = bus_engine_proxy_get_desc (ibus->global_engine);
1527         if (desc != NULL) {
1528             reply = ibus_message_new_method_return (message);
1529             ibus_message_append_args (reply,
1530                                       IBUS_TYPE_ENGINE_DESC, &desc,
1531                                       G_TYPE_INVALID);
1532             return reply;
1533         }
1534     }
1535
1536     reply = ibus_message_new_error (message, DBUS_ERROR_FAILED,
1537                                     "No global engine.");
1538     return reply;
1539 }
1540
1541 static IBusMessage *
1542 _ibus_set_global_engine (BusIBusImpl     *ibus,
1543                          IBusMessage     *message,
1544                          BusConnection   *connection)
1545 {
1546     gboolean retval;
1547     IBusMessage *reply;
1548     IBusError *error;
1549     gchar *new_engine_name;
1550     gchar *old_engine_name;
1551
1552     if (!ibus->use_global_engine) {
1553         reply = ibus_message_new_error (message, DBUS_ERROR_FAILED,
1554                                         "Global engine feature is disable.");
1555         return reply;
1556     }
1557
1558     retval = ibus_message_get_args (message,
1559                                     &error,
1560                                     G_TYPE_STRING, &new_engine_name,
1561                                     G_TYPE_INVALID);
1562     if (!retval) {
1563         reply = ibus_message_new_error (message,
1564                                         error->name,
1565                                         error->message);
1566         ibus_error_free (error);
1567         return reply;
1568     }
1569
1570     reply = ibus_message_new_method_return (message);
1571     old_engine_name = NULL;
1572
1573     if (ibus->global_engine) {
1574         old_engine_name = bus_engine_proxy_get_desc (ibus->global_engine)->name;
1575     }
1576
1577     if (g_strcmp0 (new_engine_name, old_engine_name) == 0) {
1578         /* If the user requested the same global engine, then we just enable the
1579          * original one. */
1580         if (ibus->focused_context) {
1581             bus_input_context_enable (ibus->focused_context);
1582         }
1583         else if (ibus->global_engine) {
1584             bus_engine_proxy_enable (ibus->global_engine);
1585         }
1586         return reply;
1587     }
1588
1589     /* If there is a focused input context, then we just change the engine of
1590      * the focused context, which will then change the global engine
1591      * automatically. Otherwise, we need to change the global engine directly.
1592      */
1593     if (ibus->focused_context) {
1594         _context_request_engine_cb (ibus->focused_context, new_engine_name, ibus);
1595     }
1596     else {
1597         IBusEngineDesc *engine_desc = _find_engine_desc_by_name (ibus, new_engine_name);
1598         if (engine_desc != NULL) {
1599             BusEngineProxy *new_engine = bus_ibus_impl_create_engine (engine_desc);
1600             if (new_engine != NULL) {
1601                 /* Enable the global engine by default, because the user
1602                  * selected it explicitly. */
1603                 bus_engine_proxy_enable (new_engine);
1604
1605                 /* Assume the ownership of the new global engine. Normally it's
1606                  * done by the input context. But as we need to change the global
1607                  * engine directly, so we need to do it here. */
1608                 g_object_ref_sink (new_engine);
1609                 bus_ibus_impl_set_global_engine (ibus, new_engine);
1610
1611                 /* The global engine should already be referenced. */
1612                 g_object_unref (new_engine);
1613             }
1614         }
1615     }
1616
1617     return reply;
1618 }
1619
1620 static IBusMessage *
1621 _ibus_is_global_engine_enabled (BusIBusImpl     *ibus,
1622                                 IBusMessage     *message,
1623                                 BusConnection   *connection)
1624 {
1625     IBusMessage *reply;
1626     gboolean enabled = (ibus->use_global_engine && ibus->global_engine &&
1627                         bus_engine_proxy_is_enabled (ibus->global_engine));
1628
1629     reply = ibus_message_new_method_return (message);
1630     ibus_message_append_args (reply,
1631                               G_TYPE_BOOLEAN, &enabled,
1632                               G_TYPE_INVALID);
1633     return reply;
1634 }
1635
1636
1637 static gboolean
1638 bus_ibus_impl_ibus_message (BusIBusImpl     *ibus,
1639                             BusConnection   *connection,
1640                             IBusMessage     *message)
1641 {
1642     g_assert (BUS_IS_IBUS_IMPL (ibus));
1643     g_assert (BUS_IS_CONNECTION (connection));
1644     g_assert (message != NULL);
1645
1646     gint i;
1647     IBusMessage *reply_message = NULL;
1648
1649     static const struct {
1650         const gchar *interface;
1651         const gchar *name;
1652         IBusMessage *(* handler) (BusIBusImpl *, IBusMessage *, BusConnection *);
1653     } handlers[] =  {
1654         /* Introspectable interface */
1655         { DBUS_INTERFACE_INTROSPECTABLE,
1656                                "Introspect",            _ibus_introspect },
1657         /* IBus interface */
1658         { IBUS_INTERFACE_IBUS, "GetAddress",            _ibus_get_address },
1659         { IBUS_INTERFACE_IBUS, "CreateInputContext",    _ibus_create_input_context },
1660         { IBUS_INTERFACE_IBUS, "CurrentInputContext",   _ibus_current_input_context },
1661         { IBUS_INTERFACE_IBUS, "RegisterComponent",     _ibus_register_component },
1662         { IBUS_INTERFACE_IBUS, "ListEngines",           _ibus_list_engines },
1663         { IBUS_INTERFACE_IBUS, "ListActiveEngines",     _ibus_list_active_engines },
1664         { IBUS_INTERFACE_IBUS, "Exit",                  _ibus_exit },
1665         { IBUS_INTERFACE_IBUS, "Ping",                  _ibus_ping },
1666         { IBUS_INTERFACE_IBUS, "GetUseSysLayout",       _ibus_get_use_sys_layout },
1667         { IBUS_INTERFACE_IBUS, "GetUseGlobalEngine",    _ibus_get_use_global_engine },
1668         { IBUS_INTERFACE_IBUS, "GetGlobalEngine",       _ibus_get_global_engine },
1669         { IBUS_INTERFACE_IBUS, "SetGlobalEngine",       _ibus_set_global_engine },
1670         { IBUS_INTERFACE_IBUS, "IsGlobalEngineEnabled", _ibus_is_global_engine_enabled },
1671     };
1672
1673     ibus_message_set_sender (message, bus_connection_get_unique_name (connection));
1674     ibus_message_set_destination (message, DBUS_SERVICE_DBUS);
1675
1676     if (ibus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL) {
1677         for (i = 0; i < G_N_ELEMENTS (handlers); i++) {
1678             if (ibus_message_is_method_call (message,
1679                                              handlers[i].interface,
1680                                              handlers[i].name)) {
1681
1682                 reply_message = handlers[i].handler (ibus, message, connection);
1683                 if (reply_message) {
1684
1685                     ibus_message_set_sender (reply_message, DBUS_SERVICE_DBUS);
1686                     ibus_message_set_destination (reply_message, bus_connection_get_unique_name (connection));
1687                     ibus_message_set_no_reply (reply_message, TRUE);
1688
1689                     ibus_connection_send ((IBusConnection *) connection, reply_message);
1690                     ibus_message_unref (reply_message);
1691                 }
1692
1693                 g_signal_stop_emission_by_name (ibus, "ibus-message");
1694                 return TRUE;
1695             }
1696         }
1697     }
1698
1699     return IBUS_SERVICE_CLASS(bus_ibus_impl_parent_class)->ibus_message (
1700                                     (IBusService *) ibus,
1701                                     (IBusConnection *) connection,
1702                                     message);
1703 }
1704
1705 BusFactoryProxy *
1706 bus_ibus_impl_lookup_factory (BusIBusImpl *ibus,
1707                               const gchar *path)
1708 {
1709     g_assert (BUS_IS_IBUS_IMPL (ibus));
1710
1711     BusFactoryProxy *factory;
1712
1713     factory = (BusFactoryProxy *) g_hash_table_lookup (ibus->factory_dict, path);
1714
1715     return factory;
1716 }
1717
1718 IBusHotkeyProfile *
1719 bus_ibus_impl_get_hotkey_profile (BusIBusImpl *ibus)
1720 {
1721     g_assert (BUS_IS_IBUS_IMPL (ibus));
1722
1723     return ibus->hotkey_profile;
1724 }
1725
1726 IBusKeymap *
1727 bus_ibus_impl_get_keymap (BusIBusImpl *ibus)
1728 {
1729
1730     g_assert (BUS_IS_IBUS_IMPL (ibus));
1731
1732     return ibus->keymap;
1733 }
1734
1735 BusRegistry *
1736 bus_ibus_impl_get_registry (BusIBusImpl *ibus)
1737 {
1738
1739     g_assert (BUS_IS_IBUS_IMPL (ibus));
1740
1741     return ibus->registry;
1742 }
1743
1744 static void
1745 bus_ibus_impl_registry_changed (BusIBusImpl *ibus)
1746 {
1747     g_assert (BUS_IS_IBUS_IMPL (ibus));
1748
1749     IBusMessage *message;
1750
1751     message = ibus_message_new_signal (IBUS_PATH_IBUS,
1752                                        IBUS_INTERFACE_IBUS,
1753                                        "RegistryChanged");
1754     ibus_message_append_args (message,
1755                               G_TYPE_INVALID);
1756     ibus_message_set_sender (message, IBUS_SERVICE_IBUS);
1757
1758     bus_dbus_impl_dispatch_message_by_rule (BUS_DEFAULT_DBUS, message, NULL);
1759
1760     ibus_message_unref (message);
1761
1762 }
1763
1764 static void
1765 bus_ibus_impl_global_engine_changed (BusIBusImpl *ibus)
1766 {
1767     g_assert (BUS_IS_IBUS_IMPL (ibus));
1768
1769     IBusMessage *message;
1770
1771     message = ibus_message_new_signal (IBUS_PATH_IBUS,
1772                                        IBUS_INTERFACE_IBUS,
1773                                        "GlobalEngineChanged");
1774     ibus_message_append_args (message,
1775                               G_TYPE_INVALID);
1776     ibus_message_set_sender (message, IBUS_SERVICE_IBUS);
1777
1778     bus_dbus_impl_dispatch_message_by_rule (BUS_DEFAULT_DBUS, message, NULL);
1779
1780     ibus_message_unref (message);
1781 }
1782
1783 gboolean
1784 bus_ibus_impl_filter_keyboard_shortcuts (BusIBusImpl     *ibus,
1785                                          BusInputContext *context,
1786                                          guint           keyval,
1787                                          guint           modifiers,
1788                                          guint           prev_keyval,
1789                                          guint           prev_modifiers)
1790 {
1791     static GQuark trigger = 0;
1792     static GQuark next = 0;
1793     static GQuark previous = 0;
1794
1795     if (trigger == 0) {
1796         trigger = g_quark_from_static_string ("trigger");
1797         next = g_quark_from_static_string ("next-engine-in-menu");
1798         previous = g_quark_from_static_string ("previous-engine");
1799     }
1800
1801     GQuark event = ibus_hotkey_profile_filter_key_event (ibus->hotkey_profile,
1802                                                          keyval,
1803                                                          modifiers,
1804                                                          prev_keyval,
1805                                                          prev_modifiers,
1806                                                          0);
1807
1808     if (event == trigger) {
1809         gboolean enabled = bus_input_context_is_enabled (context);
1810         if (enabled) {
1811             bus_input_context_disable (context);
1812         }
1813         else {
1814             bus_input_context_enable (context);
1815         }
1816         return (enabled != bus_input_context_is_enabled (context));
1817     }
1818     if (event == next) {
1819         if (bus_input_context_is_enabled(context)) {
1820             bus_ibus_impl_context_request_next_engine_in_menu (ibus, context);
1821         }
1822         else {
1823             bus_input_context_enable (context);
1824         }
1825         return TRUE;
1826     }
1827     if (event == previous) {
1828         if (bus_input_context_is_enabled(context)) {
1829             bus_ibus_impl_context_request_previous_engine (ibus, context);
1830         }
1831         else {
1832             bus_input_context_enable (context);
1833         }
1834         return TRUE;
1835     }
1836     return FALSE;
1837 }
1838
1839 static gchar*
1840 bus_ibus_impl_load_global_engine_name_from_config (BusIBusImpl *ibus)
1841 {
1842     GValue value = { 0 };
1843     gchar *global_engine_name = NULL;
1844
1845     g_assert (IBUS_IS_CONFIG (ibus->config));
1846
1847     if (ibus_config_get_value (ibus->config, "general", "global_engine", &value) &&
1848         G_VALUE_TYPE (&value) == G_TYPE_STRING) {
1849         global_engine_name = g_value_dup_string (&value);
1850         g_value_unset (&value);
1851     }
1852
1853     return global_engine_name;
1854 }
1855
1856 static void
1857 bus_ibus_impl_save_global_engine_name_to_config (BusIBusImpl *ibus)
1858 {
1859     g_assert (IBUS_IS_CONFIG (ibus->config));
1860
1861     if (ibus->use_global_engine && ibus->global_engine) {
1862         GValue value = { 0 };
1863         g_value_init (&value, G_TYPE_STRING);
1864         g_value_set_static_string (&value, bus_engine_proxy_get_desc (ibus->global_engine)->name);
1865
1866         ibus_config_set_value (ibus->config, "general", "global_engine", &value);
1867         g_value_unset (&value);
1868     }
1869 }
1870
1871 static gchar*
1872 bus_ibus_impl_load_global_previous_engine_name_from_config (BusIBusImpl *ibus)
1873 {
1874     GValue value = { 0 };
1875     gchar *global_previous_engine_name = NULL;
1876
1877     g_assert (IBUS_IS_CONFIG (ibus->config));
1878
1879     if (ibus_config_get_value (ibus->config, "general", "global_previous_engine", &value) &&
1880         G_VALUE_TYPE (&value) == G_TYPE_STRING) {
1881         global_previous_engine_name = g_value_dup_string (&value);
1882         g_value_unset (&value);
1883     }
1884
1885     return global_previous_engine_name;
1886 }
1887
1888 static void
1889 bus_ibus_impl_save_global_previous_engine_name_to_config (BusIBusImpl *ibus)
1890 {
1891     g_assert (IBUS_IS_CONFIG (ibus->config));
1892
1893     if (ibus->use_global_engine && ibus->global_previous_engine_name) {
1894         GValue value = { 0 };
1895         g_value_init (&value, G_TYPE_STRING);
1896         g_value_set_static_string (&value, ibus->global_previous_engine_name);
1897
1898         ibus_config_set_value (ibus->config, "general", "global_previous_engine", &value);
1899         g_value_unset (&value);
1900     }
1901 }