Make sure the engine was not destroyed before real set the global
[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 <strings.h>
29 #include "ibusimpl.h"
30 #include "dbusimpl.h"
31 #include "server.h"
32 #include "connection.h"
33 #include "registry.h"
34 #include "factoryproxy.h"
35 #include "panelproxy.h"
36 #include "inputcontext.h"
37 #include "option.h"
38
39 enum {
40     LAST_SIGNAL,
41 };
42
43 enum {
44     PROP_0,
45 };
46
47 // static guint            _signals[LAST_SIGNAL] = { 0 };
48
49 /* functions prototype */
50 static void     bus_ibus_impl_destroy           (BusIBusImpl        *ibus);
51 static gboolean bus_ibus_impl_ibus_message      (BusIBusImpl        *ibus,
52                                                  BusConnection      *connection,
53                                                  IBusMessage        *message);
54 static void     bus_ibus_impl_add_factory       (BusIBusImpl        *ibus,
55                                                  BusFactoryProxy    *factory);
56 static void     bus_ibus_impl_set_trigger       (BusIBusImpl        *ibus,
57                                                  GValue             *value);
58 static void     bus_ibus_impl_set_preload_engines
59                                                 (BusIBusImpl        *ibus,
60                                                  GValue             *value);
61 static void     bus_ibus_impl_set_use_sys_layout
62                                                 (BusIBusImpl        *ibus,
63                                                  GValue             *value);
64 static void     bus_ibus_impl_set_embed_preedit_text
65                                                 (BusIBusImpl        *ibus,
66                                                  GValue             *value);
67
68 static void     bus_ibus_impl_set_use_global_engine
69                                                 (BusIBusImpl        *ibus,
70                                                  GValue             *value);
71 static void     bus_ibus_impl_set_global_engine (BusIBusImpl        *ibus,
72                                                  BusEngineProxy     *engine);
73
74 static void     bus_ibus_impl_registry_changed  (BusIBusImpl        *ibus);
75 static void     _factory_destroy_cb             (BusFactoryProxy    *factory,
76                                                  BusIBusImpl        *ibus);
77
78 G_DEFINE_TYPE(BusIBusImpl, bus_ibus_impl, IBUS_TYPE_SERVICE)
79
80 BusIBusImpl *
81 bus_ibus_impl_get_default (void)
82 {
83     static BusIBusImpl *ibus = NULL;
84
85     if (ibus == NULL) {
86         ibus = (BusIBusImpl *) g_object_new (BUS_TYPE_IBUS_IMPL,
87                                              "path", IBUS_PATH_IBUS,
88                                              NULL);
89         bus_dbus_impl_register_object (BUS_DEFAULT_DBUS,
90                                        (IBusService *)ibus);
91     }
92     return ibus;
93 }
94
95 static void
96 bus_ibus_impl_class_init (BusIBusImplClass *klass)
97 {
98     IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (klass);
99
100     ibus_object_class->destroy = (IBusObjectDestroyFunc) bus_ibus_impl_destroy;
101
102     IBUS_SERVICE_CLASS (klass)->ibus_message = (ServiceIBusMessageFunc) bus_ibus_impl_ibus_message;
103
104 }
105
106 static void
107 _panel_destroy_cb (BusPanelProxy *panel,
108                    BusIBusImpl   *ibus)
109 {
110     g_assert (BUS_IS_PANEL_PROXY (panel));
111     g_assert (BUS_IS_IBUS_IMPL (ibus));
112
113     g_return_if_fail (ibus->panel == panel);
114
115     ibus->panel = NULL;
116     g_object_unref (panel);
117 }
118
119 static void
120 bus_ibus_impl_set_hotkey (BusIBusImpl *ibus,
121                           GQuark       hotkey,
122                           GValue      *value)
123 {
124     g_assert (BUS_IS_IBUS_IMPL (ibus));
125
126     GValueArray *array;
127     gint i;
128
129     ibus_hotkey_profile_remove_hotkey_by_event (ibus->hotkey_profile, hotkey);
130
131     if (value == NULL) {
132         return;
133     }
134
135     g_return_if_fail (G_VALUE_TYPE (value) == G_TYPE_VALUE_ARRAY);
136     array = g_value_get_boxed (value);
137
138     for (i = 0; i < array->n_values; i++) {
139        GValue *str;
140
141        str = g_value_array_get_nth (array, i);
142        g_return_if_fail (G_VALUE_TYPE (str) == G_TYPE_STRING);
143
144        ibus_hotkey_profile_add_hotkey_from_string (ibus->hotkey_profile,
145                                                    g_value_get_string (str),
146                                                    hotkey);
147    }
148
149 }
150
151 static void
152 bus_ibus_impl_set_trigger (BusIBusImpl *ibus,
153                            GValue      *value)
154 {
155     GQuark hotkey = g_quark_from_static_string ("trigger");
156     bus_ibus_impl_set_hotkey (ibus, hotkey, value);
157     if (value == NULL) {
158         ibus_hotkey_profile_add_hotkey (ibus->hotkey_profile,
159                                         IBUS_space,
160                                         IBUS_CONTROL_MASK,
161                                         hotkey);
162     }
163 }
164
165 static void
166 bus_ibus_impl_set_next_engine (BusIBusImpl *ibus,
167                                GValue      *value)
168 {
169     GQuark hotkey = g_quark_from_static_string ("next-engine");
170     bus_ibus_impl_set_hotkey (ibus, hotkey, value);
171 }
172
173 static void
174 bus_ibus_impl_set_prev_engine (BusIBusImpl *ibus,
175                                GValue      *value)
176 {
177     GQuark hotkey = g_quark_from_static_string ("prev-engine");
178     bus_ibus_impl_set_hotkey (ibus, hotkey, value);
179 }
180
181 static void
182 bus_ibus_impl_set_preload_engines (BusIBusImpl *ibus,
183                                    GValue      *value)
184 {
185     GList *engine_list = NULL;
186
187     g_list_foreach (ibus->engine_list, (GFunc) g_object_unref, NULL);
188     g_list_free (ibus->engine_list);
189
190     if (value != NULL && G_VALUE_TYPE (value) == G_TYPE_VALUE_ARRAY) {
191         GValueArray *array;
192         gint i;
193
194         array = (GValueArray *) g_value_get_boxed (value);
195         for (i = 0; array && i < array->n_values; i++) {
196             const gchar *engine_name;
197             IBusEngineDesc *engine;
198
199             if (G_VALUE_TYPE (&array->values[i]) != G_TYPE_STRING)
200                 continue;
201
202             engine_name = g_value_get_string (&array->values[i]);
203
204             engine = bus_registry_find_engine_by_name (ibus->registry, engine_name);
205
206             if (engine == NULL || g_list_find (engine_list, engine) != NULL)
207                 continue;
208
209             engine_list = g_list_append (engine_list, engine);
210         }
211     }
212
213     g_list_foreach (engine_list, (GFunc) g_object_ref, NULL);
214     ibus->engine_list = engine_list;
215
216     if (ibus->engine_list) {
217         IBusComponent *component;
218
219         component = ibus_component_get_from_engine ((IBusEngineDesc *) ibus->engine_list->data);
220         if (component && !ibus_component_is_running (component)) {
221             ibus_component_start (component, g_verbose);
222         }
223     }
224 }
225
226 static void
227 bus_ibus_impl_set_use_sys_layout (BusIBusImpl *ibus,
228                                   GValue      *value)
229 {
230     if (value != NULL && G_VALUE_TYPE (value) == G_TYPE_BOOLEAN) {
231         ibus->use_sys_layout = g_value_get_boolean (value);
232     }
233 }
234
235 static void
236 bus_ibus_impl_set_embed_preedit_text (BusIBusImpl        *ibus,
237                                                              GValue             *value){
238     if (value != NULL && G_VALUE_TYPE (value) == G_TYPE_BOOLEAN) {
239         ibus->embed_preedit_text = g_value_get_boolean (value);
240     }
241
242 }
243
244 static void
245 bus_ibus_impl_set_use_global_engine (BusIBusImpl *ibus,
246                                      GValue      *value)
247 {
248     gboolean new_value;
249
250     if (value == NULL || G_VALUE_TYPE (value) != G_TYPE_BOOLEAN) {
251         return;
252     }
253
254     new_value = g_value_get_boolean (value);
255     if (ibus->use_global_engine == new_value) {
256         return;
257     }
258
259     if (new_value == TRUE) {
260         /* turn on use_global_engine option */
261         ibus->use_global_engine = TRUE;
262         if (ibus->focused_context != NULL)
263             bus_ibus_impl_set_global_engine (ibus, bus_input_context_get_engine (ibus->focused_context));
264     }
265     else {
266         /* turn off use_global_engine option */
267         bus_ibus_impl_set_global_engine (ibus, NULL);
268         ibus->use_global_engine = FALSE;
269     }
270 }
271
272 static gint
273 _engine_desc_cmp (IBusEngineDesc *desc1,
274                   IBusEngineDesc *desc2)
275 {
276     return - ((gint) desc1->rank) + ((gint) desc2->rank);
277 }
278
279 static void
280 bus_ibus_impl_set_default_preload_engines (BusIBusImpl *ibus)
281 {
282     g_assert (BUS_IS_IBUS_IMPL (ibus));
283
284     static gboolean done = FALSE;
285     GValue value = { 0 };
286     GList *engines, *list;
287     gchar *lang, *p;
288     GValueArray *array;
289
290     if (done || ibus->config == NULL) {
291         return;
292     }
293
294     if (ibus_config_get_value (ibus->config, "general", "preload_engines", &value)) {
295         done = TRUE;
296         g_value_unset (&value);
297         return;
298     }
299
300     done = TRUE;
301     lang = g_strdup (setlocale (LC_ALL, NULL));
302     p = index (lang, '.');
303     if (p) {
304         *p = '\0';
305     }
306
307     engines = bus_registry_get_engines_by_language (ibus->registry, lang);
308     if (engines == NULL) {
309         p = index (lang, '_');
310         if (p) {
311             *p = '\0';
312             engines = bus_registry_get_engines_by_language (ibus->registry, lang);
313         }
314     }
315     g_free (lang);
316
317     /* sort engines by rank */
318     engines = g_list_sort (engines, (GCompareFunc) _engine_desc_cmp);
319
320     g_value_init (&value, G_TYPE_VALUE_ARRAY);
321     array = g_value_array_new (5);
322     for (list = engines; list != NULL; list = list->next) {
323         IBusEngineDesc *desc;
324         GValue name = { 0 };
325         desc = (IBusEngineDesc *)list->data;
326
327         /* ignore engines with rank <== 0 */
328         if (desc->rank <= 0)
329             break;
330         g_value_init (&name, G_TYPE_STRING);
331         g_value_set_string (&name, desc->name);
332         g_value_array_append (array, &name);
333     }
334     g_value_take_boxed (&value, array);
335     ibus_config_set_value (ibus->config, "general", "preload_engines", &value);
336     g_value_unset (&value);
337     g_list_free (engines);
338 }
339
340 static void
341 bus_ibus_impl_reload_config (BusIBusImpl *ibus)
342 {
343     g_assert (BUS_IS_IBUS_IMPL (ibus));
344
345     gint i;
346     GValue value = { 0 };
347
348     const static struct {
349         gchar *section;
350         gchar *key;
351         void ( *func) (BusIBusImpl *, GValue *);
352     } entries [] = {
353         { "general/hotkey", "trigger", bus_ibus_impl_set_trigger },
354         { "general/hotkey", "next_engine", bus_ibus_impl_set_next_engine },
355         { "general/hotkey", "prev_engine", bus_ibus_impl_set_prev_engine },
356         { "general", "preload_engines", bus_ibus_impl_set_preload_engines },
357         { "general", "use_system_keyboard_layout", bus_ibus_impl_set_use_sys_layout },
358         { "general", "use_global_engine", bus_ibus_impl_set_use_global_engine },
359         { "general", "embed_preedit_text", bus_ibus_impl_set_embed_preedit_text },
360         { NULL, NULL, NULL },
361     };
362
363     for (i = 0; entries[i].section != NULL; i++) {
364         if (ibus->config != NULL &&
365             ibus_config_get_value (ibus->config,
366                                    entries[i].section,
367                                    entries[i].key,
368                                    &value)) {
369             entries[i].func (ibus, &value);
370             g_value_unset (&value);
371         }
372         else {
373             entries[i].func (ibus, NULL);
374         }
375     }
376 }
377
378 static void
379 _config_value_changed_cb (IBusConfig  *config,
380                           gchar       *section,
381                           gchar       *key,
382                           GValue      *value,
383                           BusIBusImpl *ibus)
384 {
385     g_assert (IBUS_IS_CONFIG (config));
386     g_assert (section);
387     g_assert (key);
388     g_assert (value);
389     g_assert (BUS_IS_IBUS_IMPL (ibus));
390
391     gint i;
392
393     const static struct {
394         gchar *section;
395         gchar *key;
396         void ( *func) (BusIBusImpl *, GValue *);
397     } entries [] = {
398         { "general/hotkey", "trigger",     bus_ibus_impl_set_trigger },
399         { "general/hotkey", "next_engine", bus_ibus_impl_set_next_engine },
400         { "general/hotkey", "prev_engine", bus_ibus_impl_set_prev_engine },
401         { "general", "preload_engines",    bus_ibus_impl_set_preload_engines },
402         { "general", "use_system_keyboard_layout", bus_ibus_impl_set_use_sys_layout },
403         { "general", "use_global_engine", bus_ibus_impl_set_use_global_engine },
404         { "general", "embed_preedit_text", bus_ibus_impl_set_embed_preedit_text },
405         { NULL, NULL, NULL },
406     };
407
408     for (i = 0; entries[i].section != NULL; i++) {
409         if (g_strcmp0 (entries[i].section, section) == 0 &&
410             g_strcmp0 (entries[i].key, key) == 0) {
411             entries[i].func (ibus, value);
412             break;
413         }
414     }
415 }
416
417 static void
418 _config_destroy_cb (IBusConfig  *config,
419                     BusIBusImpl *ibus)
420 {
421     g_assert (IBUS_IS_CONFIG (config));
422     g_assert (BUS_IS_IBUS_IMPL (ibus));
423
424     g_assert (ibus->config == config);
425
426     g_object_unref (ibus->config);
427     ibus->config = NULL;
428 }
429
430 static void
431 _registry_changed_cb (BusRegistry *registry,
432                       BusIBusImpl *ibus)
433 {
434     bus_ibus_impl_registry_changed (ibus);
435 }
436
437 static void
438 _dbus_name_owner_changed_cb (BusDBusImpl *dbus,
439                              const gchar *name,
440                              const gchar *old_name,
441                              const gchar *new_name,
442                              BusIBusImpl *ibus)
443 {
444     g_assert (BUS_IS_DBUS_IMPL (dbus));
445     g_assert (name != NULL);
446     g_assert (old_name != NULL);
447     g_assert (new_name != NULL);
448     g_assert (BUS_IS_IBUS_IMPL (ibus));
449
450     BusFactoryProxy *factory;
451
452     if (g_strcmp0 (name, IBUS_SERVICE_PANEL) == 0) {
453         if (g_strcmp0 (new_name, "") != 0) {
454             BusConnection *connection;
455
456             if (ibus->panel != NULL) {
457                 ibus_object_destroy (IBUS_OBJECT (ibus->panel));
458                 /* panel should be NULL after destroy */
459                 g_assert (ibus->panel == NULL);
460             }
461
462             connection = bus_dbus_impl_get_connection_by_name (BUS_DEFAULT_DBUS, new_name);
463             g_return_if_fail (connection != NULL);
464
465             ibus->panel = bus_panel_proxy_new (connection);
466             g_object_ref_sink (ibus->panel);
467
468             g_signal_connect (ibus->panel,
469                               "destroy",
470                               G_CALLBACK (_panel_destroy_cb),
471                               ibus);
472
473             if (ibus->focused_context != NULL) {
474                 bus_panel_proxy_focus_in (ibus->panel, ibus->focused_context);
475             }
476         }
477     }
478     else if (g_strcmp0 (name, IBUS_SERVICE_CONFIG) == 0) {
479         if (g_strcmp0 (new_name, "") != 0) {
480             BusConnection *connection;
481
482             if (ibus->config != NULL) {
483                 ibus_object_destroy (IBUS_OBJECT (ibus->config));
484                 /* config should be NULL */
485                 g_assert (ibus->config == NULL);
486             }
487
488             connection = bus_dbus_impl_get_connection_by_name (BUS_DEFAULT_DBUS, new_name);
489             g_return_if_fail (connection != NULL);
490
491             ibus->config = g_object_new (IBUS_TYPE_CONFIG,
492                                          "name", NULL,
493                                          "path", IBUS_PATH_CONFIG,
494                                          "connection", connection,
495                                          NULL);
496             g_object_ref_sink (ibus->config);
497
498             g_signal_connect (ibus->config,
499                               "value-changed",
500                               G_CALLBACK (_config_value_changed_cb),
501                               ibus);
502
503             g_signal_connect (ibus->config,
504                               "destroy",
505                               G_CALLBACK (_config_destroy_cb),
506                               ibus);
507
508             bus_ibus_impl_set_default_preload_engines (ibus);
509             bus_ibus_impl_reload_config (ibus);
510         }
511     }
512
513     factory = bus_registry_name_owner_changed (ibus->registry, name, old_name, new_name);
514
515     if (factory) {
516         bus_ibus_impl_add_factory (ibus, factory);
517     }
518 }
519
520 static void
521 bus_ibus_impl_init (BusIBusImpl *ibus)
522 {
523     ibus->factory_dict = g_hash_table_new_full (
524                             g_str_hash,
525                             g_str_equal,
526                             NULL,
527                             (GDestroyNotify) g_object_unref);
528
529     ibus->engine_list = NULL;
530     ibus->register_engine_list = NULL;
531     ibus->contexts = NULL;
532     ibus->focused_context = NULL;
533     ibus->panel = NULL;
534     ibus->config = NULL;
535
536     ibus->registry = bus_registry_new ();
537
538     g_signal_connect (ibus->registry,
539                       "changed",
540                       G_CALLBACK (_registry_changed_cb),
541                       ibus);
542 #ifdef G_THREADS_ENABLED
543     extern gint g_monitor_timeout;
544     if (g_monitor_timeout != 0) {
545         bus_registry_start_monitor_changes (ibus->registry);
546     }
547 #endif
548
549     ibus->hotkey_profile = ibus_hotkey_profile_new ();
550     ibus->keymap = ibus_keymap_get ("us");
551
552     ibus->use_sys_layout = FALSE;
553     ibus->embed_preedit_text = TRUE;
554     ibus->use_global_engine = TRUE;
555     ibus->global_engine_enabled = FALSE;
556     ibus->global_engine = NULL;
557
558     bus_ibus_impl_reload_config (ibus);
559
560     g_signal_connect (BUS_DEFAULT_DBUS,
561                       "name-owner-changed",
562                       G_CALLBACK (_dbus_name_owner_changed_cb),
563                       ibus);
564 }
565
566 static void
567 bus_ibus_impl_destroy (BusIBusImpl *ibus)
568 {
569     pid_t pid;
570     glong timeout;
571     gint status;
572     gboolean flag;
573
574     bus_registry_stop_all_components (ibus->registry);
575
576     pid = 0;
577     timeout = 0;
578     flag = FALSE;
579     while (1) {
580         while ((pid = waitpid (0, &status, WNOHANG)) > 0);
581
582         if (pid == -1) { /* all children finished */
583             break;
584         }
585         if (pid == 0) { /* no child status changed */
586             g_usleep (1000);
587             timeout += 1000;
588             if (timeout >= G_USEC_PER_SEC) {
589                 if (flag == FALSE) {
590                     gpointer old;
591                     old = signal (SIGTERM, SIG_IGN);
592                     kill (-getpid (), SIGTERM);
593                     signal (SIGTERM, old);
594                     flag = TRUE;
595                 }
596                 else {
597                     g_warning ("Not every child processes exited!");
598                     break;
599                 }
600             }
601         }
602     };
603
604     g_list_foreach (ibus->engine_list, (GFunc) g_object_unref, NULL);
605     g_list_free (ibus->engine_list);
606     ibus->engine_list = NULL;
607
608     g_list_foreach (ibus->register_engine_list, (GFunc) g_object_unref, NULL);
609     g_list_free (ibus->register_engine_list);
610     ibus->register_engine_list = NULL;
611
612     if (ibus->factory_dict != NULL) {
613         g_hash_table_destroy (ibus->factory_dict);
614         ibus->factory_dict = NULL;
615     }
616
617     if (ibus->hotkey_profile != NULL) {
618         g_object_unref (ibus->hotkey_profile);
619         ibus->hotkey_profile = NULL;
620     }
621
622     if (ibus->keymap != NULL) {
623         g_object_unref (ibus->keymap);
624         ibus->keymap = NULL;
625     }
626
627     if (ibus->global_engine) {
628         g_object_unref (ibus->global_engine);
629         ibus->global_engine = NULL;
630     }
631
632     bus_server_quit (BUS_DEFAULT_SERVER);
633     ibus_object_destroy ((IBusObject *) BUS_DEFAULT_SERVER);
634     IBUS_OBJECT_CLASS(bus_ibus_impl_parent_class)->destroy (IBUS_OBJECT (ibus));
635 }
636
637 /* introspectable interface */
638 static IBusMessage *
639 _ibus_introspect (BusIBusImpl     *ibus,
640                   IBusMessage     *message,
641                   BusConnection   *connection)
642 {
643     static const gchar *introspect =
644         DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE
645         "<node>\n"
646         "  <interface name=\"org.freedesktop.DBus.Introspectable\">\n"
647         "    <method name=\"Introspect\">\n"
648         "      <arg name=\"data\" direction=\"out\" type=\"s\"/>\n"
649         "    </method>\n"
650         "  </interface>\n"
651         "  <interface name=\"org.freedesktop.IBus\">\n"
652         "    <method name=\"GetAddress\">\n"
653         "      <arg name=\"address\" direction=\"out\" type=\"s\"/>\n"
654         "    </method>\n"
655         "    <method name=\"CreateInputContext\">\n"
656         "      <arg name=\"name\" direction=\"in\" type=\"s\"/>\n"
657         "      <arg name=\"context\" direction=\"out\" type=\"o\"/>\n"
658         "    </method>\n"
659         "    <method name=\"CurrentInputContext\">\n"
660         "      <arg name=\"name\" direction=\"out\" type=\"s\"/>\n"
661         "    </method>\n"
662         "    <method name=\"RegisterComponent\">\n"
663         "      <arg name=\"components\" direction=\"in\" type=\"v\"/>\n"
664         "    </method>\n"
665         "    <method name=\"ListEngines\">\n"
666         "      <arg name=\"engines\" direction=\"out\" type=\"av\"/>\n"
667         "    </method>\n"
668         "    <method name=\"ListActiveEngines\">\n"
669         "      <arg name=\"engines\" direction=\"out\" type=\"av\"/>\n"
670         "    </method>\n"
671         "    <method name=\"Exit\">\n"
672         "      <arg name=\"restart\" direction=\"in\" type=\"b\"/>\n"
673         "    </method>\n"
674         "    <method name=\"Ping\">\n"
675         "      <arg name=\"data\" direction=\"in\" type=\"v\"/>\n"
676         "      <arg name=\"data\" direction=\"out\" type=\"v\"/>\n"
677         "    </method>\n"
678         "    <signal name=\"RegistryChanged\">\n"
679         "    </signal>\n"
680         "  </interface>\n"
681         "</node>\n";
682
683     IBusMessage *reply_message;
684     reply_message = ibus_message_new_method_return (message);
685     ibus_message_append_args (reply_message,
686                               G_TYPE_STRING, &introspect,
687                               G_TYPE_INVALID);
688
689     return reply_message;
690 }
691
692
693
694 static IBusMessage *
695 _ibus_get_address (BusIBusImpl     *ibus,
696                    IBusMessage     *message,
697                    BusConnection   *connection)
698 {
699     const gchar *address;
700     IBusMessage *reply;
701
702     address = ibus_server_get_address (IBUS_SERVER (BUS_DEFAULT_SERVER));
703
704     reply = ibus_message_new_method_return (message);
705     ibus_message_append_args (reply,
706                               G_TYPE_STRING, &address,
707                               G_TYPE_INVALID);
708
709     return reply;
710 }
711
712 static BusEngineProxy *
713 bus_ibus_impl_create_engine (IBusEngineDesc *engine_desc)
714 {
715     IBusComponent *comp;
716     BusFactoryProxy *factory;
717     BusEngineProxy *engine;
718     GTimeVal t1, t2;
719
720     factory = bus_factory_proxy_get_from_engine (engine_desc);
721
722     if (factory == NULL) {
723         /* try to execute the engine */
724         comp = ibus_component_get_from_engine (engine_desc);
725         g_assert (comp);
726
727         if (!ibus_component_is_running (comp)) {
728             ibus_component_start (comp, g_verbose);
729             g_get_current_time (&t1);
730             while (1) {
731                 if (g_main_context_pending (NULL)) {
732                     g_main_context_iteration (NULL, FALSE);
733                     factory = bus_factory_proxy_get_from_engine (engine_desc);
734                     if (factory != NULL) {
735                         break;
736                     }
737                 }
738                 g_get_current_time (&t2);
739                 if (t2.tv_sec - t1.tv_sec >= 5)
740                     break;
741             }
742         }
743         else {
744             factory = bus_factory_proxy_get_from_engine (engine_desc);
745         }
746     }
747
748     if (factory == NULL) {
749         return NULL;
750     }
751
752     g_object_ref (factory);
753     engine = bus_factory_proxy_create_engine (factory, engine_desc);
754     g_object_unref (factory);
755
756     return engine;
757 }
758
759 static IBusEngineDesc *
760 _find_engine_desc_by_name(BusIBusImpl *ibus,
761                           gchar *engine_name)
762 {
763     IBusEngineDesc *engine_desc = NULL;
764     GList *p;
765
766     /* find engine in registered engine list */
767     for (p = ibus->register_engine_list; p != NULL; p = p->next) {
768         engine_desc = (IBusEngineDesc *)p->data;
769         if (g_strcmp0 (engine_desc->name, engine_name) == 0)
770             return engine_desc;
771     }
772
773     /* find engine in preload engine list */
774     for (p = ibus->engine_list; p != NULL; p = p->next) {
775         engine_desc = (IBusEngineDesc *)p->data;
776         if (g_strcmp0 (engine_desc->name, engine_name) == 0)
777             return engine_desc;
778     }
779
780     return NULL;
781 }
782
783 static void
784 _context_request_engine_cb (BusInputContext *context,
785                             gchar           *engine_name,
786                             BusIBusImpl     *ibus)
787 {
788     IBusEngineDesc *engine_desc = NULL;
789     BusEngineProxy *engine;
790
791     /* context should has focus before request an engine */
792     g_return_if_fail (bus_input_context_has_focus (context));
793
794     if (engine_name == NULL || engine_name[0] == '\0') {
795         /* request default engine */
796         if (ibus->register_engine_list) {
797             engine_desc = (IBusEngineDesc *)ibus->register_engine_list->data;
798         }
799         else if (ibus->engine_list) {
800             engine_desc = (IBusEngineDesc *)ibus->engine_list->data;
801         }
802     }
803     else {
804         /* request engine by name */
805         engine_desc = _find_engine_desc_by_name (ibus, engine_name);
806     }
807
808     if (engine_desc != NULL) {
809         engine = bus_ibus_impl_create_engine (engine_desc);
810         if (engine != NULL) {
811             bus_input_context_set_engine (context, engine);
812         }
813     }
814 }
815
816 static void
817 _context_request_next_engine_cb (BusInputContext *context,
818                                  BusIBusImpl     *ibus)
819 {
820     BusEngineProxy *engine;
821     IBusEngineDesc *desc;
822     IBusEngineDesc *next_desc = NULL;
823     GList *p;
824
825     engine = bus_input_context_get_engine (context);
826     if (engine == NULL) {
827         _context_request_engine_cb (context, NULL, ibus);
828         return;
829     }
830
831     desc = bus_engine_proxy_get_desc (engine);
832
833     p = g_list_find (ibus->register_engine_list, desc);
834     if (p != NULL) {
835         p = p->next;
836     }
837     if (p == NULL) {
838         p = g_list_find (ibus->engine_list, desc);
839         if (p != NULL) {
840             p = p->next;
841         }
842     }
843
844     if (p != NULL) {
845         next_desc = (IBusEngineDesc*) p->data;
846     }
847     else {
848         if (ibus->register_engine_list) {
849             next_desc = (IBusEngineDesc *)ibus->register_engine_list->data;
850         }
851         else if (ibus->engine_list) {
852             next_desc = (IBusEngineDesc *)ibus->engine_list->data;
853         }
854     }
855
856     if (next_desc != NULL) {
857         engine = bus_ibus_impl_create_engine (next_desc);
858         if (engine != NULL) {
859             bus_input_context_set_engine (context, engine);
860         }
861     }
862 }
863
864 static void
865 _context_request_prev_engine_cb (BusInputContext *context,
866                                  BusIBusImpl     *ibus)
867 {
868
869 }
870
871 static void
872 _global_engine_destroy_cb (BusEngineProxy *engine,
873                            BusIBusImpl    *ibus)
874 {
875     if (ibus->global_engine != engine) {
876         return;
877     }
878
879     g_signal_handlers_disconnect_by_func (ibus->global_engine,
880                 G_CALLBACK (_global_engine_destroy_cb), ibus);
881     g_object_unref (ibus->global_engine);
882     ibus->global_engine = NULL;
883 }
884
885 static void
886 bus_ibus_impl_set_global_engine (BusIBusImpl    *ibus,
887                                  BusEngineProxy *engine)
888 {
889     g_assert (ibus->use_global_engine == TRUE);
890
891     if (ibus->global_engine == engine) {
892         return;
893     }
894
895     if (ibus->global_engine) {
896         ibus_object_destroy ((IBusObject *)ibus->global_engine);
897         /* global_engine should be NULL */
898         g_assert (ibus->global_engine == NULL);
899     }
900
901     if (engine != NULL && !IBUS_OBJECT_DESTROYED (engine)) {
902         g_object_ref (engine);
903         ibus->global_engine = engine;
904         g_signal_connect (ibus->global_engine, "destroy",
905                 G_CALLBACK (_global_engine_destroy_cb), ibus);
906     }
907 }
908
909 static void
910 _context_engine_changed_cb (BusInputContext *context,
911                             BusIBusImpl     *ibus)
912 {
913     BusEngineProxy *engine;
914
915     if (context != ibus->focused_context ||
916         ibus->use_global_engine != TRUE) {
917         return;
918     }
919
920     engine = bus_input_context_get_engine (context);
921     bus_ibus_impl_set_global_engine (ibus, engine);
922 }
923
924 static void
925 _context_focus_out_cb (BusInputContext    *context,
926                        BusIBusImpl        *ibus)
927 {
928     g_assert (BUS_IS_IBUS_IMPL (ibus));
929     g_assert (BUS_IS_INPUT_CONTEXT (context));
930
931     /* Do noting if context does not support focus.
932      * Actually, the context should emit focus signals, if it does not support focus */
933     if ((bus_input_context_get_capabilities (context) & IBUS_CAP_FOCUS) == 0) {
934         return;
935     }
936
937     /* Do noting if it is not focused context. */
938     if (ibus->focused_context != context) {
939         return;
940     }
941
942     ibus->focused_context = NULL;
943
944     if (ibus->panel != NULL) {
945         bus_panel_proxy_focus_out (ibus->panel, context);
946     }
947
948     /* If the use_global_engine option is enabled,
949      * the global engine shoule be detached from the focused context. */
950     if (ibus->use_global_engine) {
951         bus_input_context_set_engine (context, NULL);
952     }
953
954     g_object_unref (context);
955 }
956
957 static void
958 _context_focus_in_cb (BusInputContext *context,
959                       BusIBusImpl     *ibus)
960 {
961     g_assert (BUS_IS_IBUS_IMPL (ibus));
962     g_assert (BUS_IS_INPUT_CONTEXT (context));
963
964     /* Do nothing if context does not support focus.
965      * The global engine shoule be detached from the focused context. */
966     if ((bus_input_context_get_capabilities (context) & IBUS_CAP_FOCUS) == 0) {
967         return;
968     }
969
970     /* Do nothing if it is focused context already. */
971     if (ibus->focused_context == context) {
972         return;
973     }
974
975     if (ibus->focused_context) {
976         /* focus out context */
977         bus_input_context_focus_out (ibus->focused_context);
978         g_assert (ibus->focused_context == NULL);
979     }
980
981     g_object_ref (context);
982     ibus->focused_context = context;
983
984     /* If the use_global_engine option is enabled, then we need:
985      * - Switch the context to use the global engine or save the context's
986      *   existing engine as global engine.
987      * - Set the context's enabled state according to the saved state.
988      * Note: we get this signal only if the context supports IBUS_CAP_FOCUS. */
989     if (ibus->use_global_engine) {
990         bus_input_context_set_engine (context, ibus->global_engine);
991         if (ibus->global_engine &&
992             bus_engine_proxy_is_enabled (ibus->global_engine)) {
993             bus_input_context_enable (context);
994         }
995     }
996
997     if (ibus->panel != NULL) {
998         bus_panel_proxy_focus_in (ibus->panel, ibus->focused_context);
999     }
1000 }
1001
1002 static void
1003 _context_destroy_cb (BusInputContext    *context,
1004                      BusIBusImpl        *ibus)
1005 {
1006     g_assert (BUS_IS_IBUS_IMPL (ibus));
1007     g_assert (BUS_IS_INPUT_CONTEXT (context));
1008
1009     if (context == ibus->focused_context) {
1010         /* focus out context */
1011         bus_input_context_focus_out (ibus->focused_context);
1012         g_assert (ibus->focused_context == NULL);
1013     }
1014
1015     ibus->contexts = g_list_remove (ibus->contexts, context);
1016     g_object_unref (context);
1017 }
1018
1019 static void
1020 _context_enabled_cb (BusInputContext    *context,
1021                      BusIBusImpl        *ibus)
1022 {
1023     if (ibus->focused_context == context && ibus->use_global_engine &&
1024         (bus_input_context_get_capabilities (context) & IBUS_CAP_FOCUS) != 0) {
1025         ibus->global_engine_enabled = TRUE;
1026     }
1027 }
1028
1029 static void
1030 _context_disabled_cb (BusInputContext    *context,
1031                       BusIBusImpl        *ibus)
1032 {
1033     if (ibus->focused_context == context && ibus->use_global_engine &&
1034         (bus_input_context_get_capabilities (context) & IBUS_CAP_FOCUS) != 0) {
1035         ibus->global_engine_enabled = FALSE;
1036     }
1037 }
1038
1039 static IBusMessage *
1040 _ibus_create_input_context (BusIBusImpl     *ibus,
1041                             IBusMessage     *message,
1042                             BusConnection   *connection)
1043 {
1044     g_assert (BUS_IS_IBUS_IMPL (ibus));
1045     g_assert (message != NULL);
1046     g_assert (BUS_IS_CONNECTION (connection));
1047
1048     gint i;
1049     gchar *client;
1050     IBusError *error;
1051     IBusMessage *reply;
1052     BusInputContext *context;
1053     const gchar *path;
1054
1055     if (!ibus_message_get_args (message,
1056                                 &error,
1057                                 G_TYPE_STRING, &client,
1058                                 G_TYPE_INVALID)) {
1059         reply = ibus_message_new_error (message,
1060                                         DBUS_ERROR_INVALID_ARGS,
1061                                         "Argument 1 of CreateInputContext should be an string");
1062         ibus_error_free (error);
1063         return reply;
1064     }
1065
1066     context = bus_input_context_new (connection, client);
1067     g_object_ref_sink (context);
1068     ibus->contexts = g_list_append (ibus->contexts, context);
1069
1070     static const struct {
1071         gchar *name;
1072         GCallback callback;
1073     } signals [] = {
1074         { "request-engine",      G_CALLBACK (_context_request_engine_cb) },
1075         { "request-next-engine", G_CALLBACK (_context_request_next_engine_cb) },
1076         { "request-prev-engine", G_CALLBACK (_context_request_prev_engine_cb) },
1077         { "engine-changed", G_CALLBACK (_context_engine_changed_cb) },
1078         { "focus-in",       G_CALLBACK (_context_focus_in_cb) },
1079         { "focus-out",      G_CALLBACK (_context_focus_out_cb) },
1080         { "destroy",        G_CALLBACK (_context_destroy_cb) },
1081         { "enabled",        G_CALLBACK (_context_enabled_cb) },
1082         { "disabled",       G_CALLBACK (_context_disabled_cb) },
1083     };
1084
1085     for (i = 0; i < G_N_ELEMENTS (signals); i++) {
1086         g_signal_connect (context,
1087                           signals[i].name,
1088                           signals[i].callback,
1089                           ibus);
1090     }
1091
1092     path = ibus_service_get_path ((IBusService *) context);
1093     reply = ibus_message_new_method_return (message);
1094     ibus_message_append_args (reply,
1095                               IBUS_TYPE_OBJECT_PATH, &path,
1096                               G_TYPE_INVALID);
1097
1098     bus_dbus_impl_register_object (BUS_DEFAULT_DBUS,
1099                                    (IBusService *)context);
1100     return reply;
1101 }
1102
1103 static IBusMessage *
1104 _ibus_current_input_context (BusIBusImpl     *ibus,
1105                             IBusMessage     *message,
1106                             BusConnection   *connection)
1107 {
1108     g_assert (BUS_IS_IBUS_IMPL (ibus));
1109     g_assert (message != NULL);
1110     g_assert (BUS_IS_CONNECTION (connection));
1111
1112     IBusMessage *reply;
1113     const gchar *path;
1114
1115     if (!ibus->focused_context)
1116     {
1117         reply = ibus_message_new_error (message,
1118                                         DBUS_ERROR_FAILED,
1119                                         "No input context focused");
1120         return reply;
1121     }
1122
1123     reply = ibus_message_new_method_return (message);
1124     path = ibus_service_get_path((IBusService *)ibus->focused_context);
1125     ibus_message_append_args (reply,
1126                               G_TYPE_STRING, &path,
1127                               G_TYPE_INVALID);
1128
1129     return reply;
1130 }
1131
1132 static void
1133 _factory_destroy_cb (BusFactoryProxy    *factory,
1134                      BusIBusImpl        *ibus)
1135 {
1136     g_assert (BUS_IS_IBUS_IMPL (ibus));
1137     g_assert (BUS_IS_FACTORY_PROXY (factory));
1138
1139     IBusComponent *component;
1140     GList *engines, *p;
1141
1142     ibus->factory_list = g_list_remove (ibus->factory_list, factory);
1143
1144     component = bus_factory_proxy_get_component (factory);
1145
1146     if (component != NULL) {
1147         p = engines = ibus_component_get_engines (component);
1148         for (; p != NULL; p = p->next) {
1149             if (g_list_find (ibus->register_engine_list, p->data)) {
1150                 ibus->register_engine_list = g_list_remove (ibus->register_engine_list, p->data);
1151                 g_object_unref (p->data);
1152             }
1153         }
1154         g_list_free (engines);
1155     }
1156
1157     g_object_unref (factory);
1158 }
1159
1160 static void
1161 bus_ibus_impl_add_factory (BusIBusImpl     *ibus,
1162                            BusFactoryProxy *factory)
1163 {
1164     g_assert (BUS_IS_IBUS_IMPL (ibus));
1165     g_assert (BUS_IS_FACTORY_PROXY (factory));
1166
1167     g_object_ref_sink (factory);
1168     ibus->factory_list = g_list_append (ibus->factory_list, factory);
1169
1170     g_signal_connect (factory, "destroy", G_CALLBACK (_factory_destroy_cb), ibus);
1171 }
1172
1173
1174 static IBusMessage *
1175 _ibus_register_component (BusIBusImpl     *ibus,
1176                           IBusMessage     *message,
1177                           BusConnection   *connection)
1178 {
1179     IBusMessage *reply;
1180     IBusError *error;
1181     gboolean retval;
1182     GList *engines;
1183     IBusComponent *component;
1184     BusFactoryProxy *factory;
1185
1186     retval = ibus_message_get_args (message, &error,
1187                                     IBUS_TYPE_COMPONENT, &component,
1188                                     G_TYPE_INVALID);
1189
1190     if (!retval) {
1191         reply = ibus_message_new_error_printf (message,
1192                                                DBUS_ERROR_INVALID_ARGS,
1193                                                "1st Argument must be IBusComponent: %s",
1194                                                error->message);
1195         ibus_error_free (error);
1196         return reply;
1197     }
1198
1199     g_object_ref_sink (component);
1200     factory = bus_factory_proxy_new (component, connection);
1201
1202     if (factory == NULL) {
1203         reply = ibus_message_new_error (message,
1204                                         DBUS_ERROR_FAILED,
1205                                         "Can not create factory");
1206         return reply;
1207     }
1208
1209     bus_ibus_impl_add_factory (ibus, factory);
1210
1211     engines = ibus_component_get_engines (component);
1212
1213     g_list_foreach (engines, (GFunc) g_object_ref, NULL);
1214     ibus->register_engine_list = g_list_concat (ibus->register_engine_list, engines);
1215     g_object_unref (component);
1216
1217     reply = ibus_message_new_method_return (message);
1218     return reply;
1219 }
1220
1221 static IBusMessage *
1222 _ibus_list_engines (BusIBusImpl   *ibus,
1223                     IBusMessage   *message,
1224                     BusConnection *connection)
1225 {
1226     IBusMessage *reply;
1227     IBusMessageIter iter, sub_iter;
1228     GList *engines, *p;
1229
1230     reply = ibus_message_new_method_return (message);
1231
1232     ibus_message_iter_init_append (reply, &iter);
1233     ibus_message_iter_open_container (&iter, IBUS_TYPE_ARRAY, "v", &sub_iter);
1234
1235     engines = bus_registry_get_engines (ibus->registry);
1236     for (p = engines; p != NULL; p = p->next) {
1237         ibus_message_iter_append (&sub_iter, IBUS_TYPE_ENGINE_DESC, &(p->data));
1238     }
1239     g_list_free (engines);
1240     ibus_message_iter_close_container (&iter, &sub_iter);
1241
1242     return reply;
1243 }
1244
1245 static IBusMessage *
1246 _ibus_list_active_engines (BusIBusImpl   *ibus,
1247                            IBusMessage   *message,
1248                            BusConnection *connection)
1249 {
1250     IBusMessage *reply;
1251     IBusMessageIter iter, sub_iter;
1252     GList *p;
1253
1254     reply = ibus_message_new_method_return (message);
1255
1256     ibus_message_iter_init_append (reply, &iter);
1257     ibus_message_iter_open_container (&iter, IBUS_TYPE_ARRAY, "v", &sub_iter);
1258
1259     for (p = ibus->engine_list; p != NULL; p = p->next) {
1260         ibus_message_iter_append (&sub_iter, IBUS_TYPE_ENGINE_DESC, &(p->data));
1261     }
1262
1263     for (p = ibus->register_engine_list; p != NULL; p = p->next) {
1264         ibus_message_iter_append (&sub_iter, IBUS_TYPE_ENGINE_DESC, &(p->data));
1265     }
1266     ibus_message_iter_close_container (&iter, &sub_iter);
1267
1268     return reply;
1269 }
1270
1271
1272 static IBusMessage *
1273 _ibus_exit (BusIBusImpl     *ibus,
1274             IBusMessage     *message,
1275             BusConnection   *connection)
1276 {
1277     IBusMessage *reply;
1278     IBusError *error;
1279     gboolean restart;
1280
1281     if (!ibus_message_get_args (message,
1282                                 &error,
1283                                 G_TYPE_BOOLEAN, &restart,
1284                                 G_TYPE_INVALID)) {
1285         reply = ibus_message_new_error (message,
1286                                         DBUS_ERROR_INVALID_ARGS,
1287                                         "Argument 1 of Exit should be an boolean");
1288         ibus_error_free (error);
1289         return reply;
1290     }
1291
1292     reply = ibus_message_new_method_return (message);
1293     ibus_connection_send ((IBusConnection *) connection, reply);
1294     ibus_connection_flush ((IBusConnection *) connection);
1295     ibus_message_unref (reply);
1296
1297     ibus_object_destroy ((IBusObject *) BUS_DEFAULT_SERVER);
1298
1299     if (!restart) {
1300         exit (0);
1301     }
1302     else {
1303         extern gchar **g_argv;
1304         gchar *exe;
1305         gint fd;
1306
1307         exe = g_strdup_printf ("/proc/%d/exe", getpid ());
1308         exe = g_file_read_link (exe, NULL);
1309
1310         if (exe == NULL)
1311             exe = BINDIR"/ibus-daemon";
1312
1313         /* close all fds except stdin, stdout, stderr */
1314         for (fd = 3; fd <= sysconf (_SC_OPEN_MAX); fd ++) {
1315             close (fd);
1316         }
1317
1318         execv (exe, g_argv);
1319         g_warning ("execv %s failed!", g_argv[0]);
1320         exit (-1);
1321     }
1322
1323     /* should not reach here */
1324     g_assert_not_reached ();
1325
1326     return NULL;
1327 }
1328
1329 static IBusMessage *
1330 _ibus_ping (BusIBusImpl     *ibus,
1331             IBusMessage     *message,
1332             BusConnection   *connection)
1333 {
1334     IBusMessage *reply;
1335     IBusMessageIter src, dst;
1336
1337     reply = ibus_message_new_method_return (message);
1338
1339     ibus_message_iter_init (message, &src);
1340     ibus_message_iter_init_append (reply, &dst);
1341
1342     ibus_message_iter_copy_data (&dst, &src);
1343
1344     return reply;
1345 }
1346
1347 static gboolean
1348 bus_ibus_impl_ibus_message (BusIBusImpl     *ibus,
1349                             BusConnection   *connection,
1350                             IBusMessage     *message)
1351 {
1352     g_assert (BUS_IS_IBUS_IMPL (ibus));
1353     g_assert (BUS_IS_CONNECTION (connection));
1354     g_assert (message != NULL);
1355
1356     gint i;
1357     IBusMessage *reply_message = NULL;
1358
1359     static const struct {
1360         const gchar *interface;
1361         const gchar *name;
1362         IBusMessage *(* handler) (BusIBusImpl *, IBusMessage *, BusConnection *);
1363     } handlers[] =  {
1364         /* Introspectable interface */
1365         { DBUS_INTERFACE_INTROSPECTABLE,
1366                                "Introspect",            _ibus_introspect },
1367         /* IBus interface */
1368         { IBUS_INTERFACE_IBUS, "GetAddress",            _ibus_get_address },
1369         { IBUS_INTERFACE_IBUS, "CreateInputContext",    _ibus_create_input_context },
1370         { IBUS_INTERFACE_IBUS, "CurrentInputContext",   _ibus_current_input_context },
1371         { IBUS_INTERFACE_IBUS, "RegisterComponent",     _ibus_register_component },
1372         { IBUS_INTERFACE_IBUS, "ListEngines",           _ibus_list_engines },
1373         { IBUS_INTERFACE_IBUS, "ListActiveEngines",     _ibus_list_active_engines },
1374         { IBUS_INTERFACE_IBUS, "Exit",                  _ibus_exit },
1375         { IBUS_INTERFACE_IBUS, "Ping",                  _ibus_ping },
1376     };
1377
1378     ibus_message_set_sender (message, bus_connection_get_unique_name (connection));
1379     ibus_message_set_destination (message, DBUS_SERVICE_DBUS);
1380
1381     if (ibus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL) {
1382         for (i = 0; i < G_N_ELEMENTS (handlers); i++) {
1383             if (ibus_message_is_method_call (message,
1384                                              handlers[i].interface,
1385                                              handlers[i].name)) {
1386
1387                 reply_message = handlers[i].handler (ibus, message, connection);
1388                 if (reply_message) {
1389
1390                     ibus_message_set_sender (reply_message, DBUS_SERVICE_DBUS);
1391                     ibus_message_set_destination (reply_message, bus_connection_get_unique_name (connection));
1392                     ibus_message_set_no_reply (reply_message, TRUE);
1393
1394                     ibus_connection_send ((IBusConnection *) connection, reply_message);
1395                     ibus_message_unref (reply_message);
1396                 }
1397
1398                 g_signal_stop_emission_by_name (ibus, "ibus-message");
1399                 return TRUE;
1400             }
1401         }
1402     }
1403
1404     return IBUS_SERVICE_CLASS(bus_ibus_impl_parent_class)->ibus_message (
1405                                     (IBusService *) ibus,
1406                                     (IBusConnection *) connection,
1407                                     message);
1408 }
1409
1410 BusFactoryProxy *
1411 bus_ibus_impl_lookup_factory (BusIBusImpl *ibus,
1412                               const gchar *path)
1413 {
1414     g_assert (BUS_IS_IBUS_IMPL (ibus));
1415
1416     BusFactoryProxy *factory;
1417
1418     factory = (BusFactoryProxy *) g_hash_table_lookup (ibus->factory_dict, path);
1419
1420     return factory;
1421 }
1422
1423 IBusHotkeyProfile *
1424 bus_ibus_impl_get_hotkey_profile (BusIBusImpl *ibus)
1425 {
1426     g_assert (BUS_IS_IBUS_IMPL (ibus));
1427
1428     return ibus->hotkey_profile;
1429 }
1430
1431 IBusKeymap *
1432 bus_ibus_impl_get_keymap (BusIBusImpl *ibus)
1433 {
1434
1435     g_assert (BUS_IS_IBUS_IMPL (ibus));
1436
1437     return ibus->keymap;
1438 }
1439
1440 BusRegistry *
1441 bus_ibus_impl_get_registry (BusIBusImpl *ibus)
1442 {
1443
1444     g_assert (BUS_IS_IBUS_IMPL (ibus));
1445
1446     return ibus->registry;
1447 }
1448
1449 static void
1450 bus_ibus_impl_registry_changed (BusIBusImpl *ibus)
1451 {
1452     g_assert (BUS_IS_IBUS_IMPL (ibus));
1453
1454     IBusMessage *message;
1455
1456     message = ibus_message_new_signal (IBUS_PATH_IBUS,
1457                                        IBUS_INTERFACE_IBUS,
1458                                        "RegistryChanged");
1459     ibus_message_append_args (message,
1460                               G_TYPE_INVALID);
1461     ibus_message_set_sender (message, IBUS_SERVICE_IBUS);
1462
1463     bus_dbus_impl_dispatch_message_by_rule (BUS_DEFAULT_DBUS, message, NULL);
1464
1465     ibus_message_unref (message);
1466
1467 }