91180204d0d969cbcd68c15f4ccfd325f1902aaf
[platform/upstream/ibus.git] / src / ibusbus.c
1 /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
2 /* vim:set et sts=4: */
3 /* ibus - The Input Bus
4  * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
5  * Copyright (C) 2008-2010 Red Hat, Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #include "ibusbus.h"
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <unistd.h>
27 #include <glib/gstdio.h>
28 #include <gio/gio.h>
29 #include "ibusmarshalers.h"
30 #include "ibusinternal.h"
31 #include "ibusshare.h"
32 #include "ibusenginedesc.h"
33 #include "ibusserializable.h"
34 #include "ibusconfig.h"
35
36 #define IBUS_BUS_GET_PRIVATE(o)  \
37    (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_BUS, IBusBusPrivate))
38
39 enum {
40     CONNECTED,
41     DISCONNECTED,
42     GLOBAL_ENGINE_CHANGED,
43     NAME_OWNER_CHANGED,
44     LAST_SIGNAL,
45 };
46
47 enum {
48     PROP_0 = 0,
49     PROP_CONNECT_ASYNC,
50 };
51
52 /* IBusBusPriv */
53 struct _IBusBusPrivate {
54     GFileMonitor *monitor;
55     GDBusConnection *connection;
56     gboolean watch_dbus_signal;
57     guint watch_dbus_signal_id;
58     gboolean watch_ibus_signal;
59     guint watch_ibus_signal_id;
60     IBusConfig *config;
61     gchar *unique_name;
62     gboolean connect_async;
63     gchar *bus_address;
64     GCancellable *cancellable;
65 };
66
67 static guint    bus_signals[LAST_SIGNAL] = { 0 };
68
69 static IBusBus *_bus = NULL;
70
71 /* functions prototype */
72 static GObject  *ibus_bus_constructor           (GType                   type,
73                                                  guint                   n_params,
74                                                  GObjectConstructParam  *params);
75 static void      ibus_bus_destroy               (IBusObject             *object);
76 static void      ibus_bus_watch_dbus_signal     (IBusBus                *bus);
77 static void      ibus_bus_unwatch_dbus_signal   (IBusBus                *bus);
78 static void      ibus_bus_watch_ibus_signal     (IBusBus                *bus);
79 static void      ibus_bus_unwatch_ibus_signal   (IBusBus                *bus);
80 static GVariant *ibus_bus_call_sync             (IBusBus                *bus,
81                                                  const gchar            *service,
82                                                  const gchar            *path,
83                                                  const gchar            *interface,
84                                                  const gchar            *member,
85                                                  GVariant               *parameters,
86                                                  const GVariantType     *reply_type);
87 static void      ibus_bus_call_async             (IBusBus                *bus,
88                                                   const gchar            *service,
89                                                   const gchar            *path,
90                                                   const gchar            *interface,
91                                                   const gchar            *member,
92                                                   GVariant               *parameters,
93                                                   const GVariantType     *reply_type,
94                                                   gpointer                source_tag,
95                                                   gint                    timeout_msec,
96                                                   GCancellable           *cancellable,
97                                                   GAsyncReadyCallback     callback,
98                                                   gpointer                user_data);
99 static void      ibus_bus_set_property           (IBusBus                *bus,
100                                                   guint                   prop_id,
101                                                   const GValue           *value,
102                                                   GParamSpec             *pspec);
103 static void      ibus_bus_get_property           (IBusBus                *bus,
104                                                   guint                   prop_id,
105                                                   GValue                 *value,
106                                                   GParamSpec             *pspec);
107
108 static void     ibus_bus_close_connection        (IBusBus                *bus);
109
110 G_DEFINE_TYPE (IBusBus, ibus_bus, IBUS_TYPE_OBJECT)
111
112 static void
113 ibus_bus_class_init (IBusBusClass *class)
114 {
115     GObjectClass *gobject_class = G_OBJECT_CLASS (class);
116     IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (class);
117
118     gobject_class->constructor = ibus_bus_constructor;
119     gobject_class->set_property = (GObjectSetPropertyFunc) ibus_bus_set_property;
120     gobject_class->get_property = (GObjectGetPropertyFunc) ibus_bus_get_property;
121     ibus_object_class->destroy = ibus_bus_destroy;
122
123     /* install properties */
124     /**
125      * IBusBus:connect-async:
126      *
127      * Whether the #IBusBus object should connect asynchronously to the bus.
128      *
129      */
130     g_object_class_install_property (gobject_class,
131                                      PROP_CONNECT_ASYNC,
132                                      g_param_spec_boolean ("connect-async",
133                                                            "Connect Async",
134                                                            "Connect asynchronously to the bus",
135                                                            FALSE,
136                                                            G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
137
138     /* install signals */
139     /**
140      * IBusBus::connected:
141      * @bus: The #IBusBus object which recevied the signal
142      *
143      * Emitted when #IBusBus is connected to ibus-daemon.
144      *
145      */
146     bus_signals[CONNECTED] =
147         g_signal_new (I_("connected"),
148             G_TYPE_FROM_CLASS (class),
149             G_SIGNAL_RUN_LAST,
150             0,
151             NULL, NULL,
152             _ibus_marshal_VOID__VOID,
153             G_TYPE_NONE,
154             0);
155
156     /**
157      * IBusBus::disconnected:
158      * @bus: The #IBusBus object which recevied the signal
159      *
160      * Emitted when #IBusBus is disconnected from ibus-daemon.
161      *
162      */
163     bus_signals[DISCONNECTED] =
164         g_signal_new (I_("disconnected"),
165             G_TYPE_FROM_CLASS (class),
166             G_SIGNAL_RUN_LAST,
167             0,
168             NULL, NULL,
169             _ibus_marshal_VOID__VOID,
170             G_TYPE_NONE,
171             0);
172
173     /**
174      * IBusBus::global-engine-changed:
175      * @bus: The #IBusBus object which recevied the signal
176      * @name: The name of the new global engine.
177      *
178      * Emitted when global engine is changed.
179      *
180      */
181     bus_signals[GLOBAL_ENGINE_CHANGED] =
182         g_signal_new (I_("global-engine-changed"),
183             G_TYPE_FROM_CLASS (class),
184             G_SIGNAL_RUN_LAST,
185             0,
186             NULL, NULL,
187             _ibus_marshal_VOID__STRING,
188             G_TYPE_NONE,
189             1,
190             G_TYPE_STRING);
191
192     /**
193      * IBusBus::name-owner-changed:
194      * @bus: The #IBusBus object which recevied the signal
195      * @name: The name which ower is changed.
196      * @old_owner: The unique bus name of the old owner.
197      * @new_owner: The unique bus name of the new owner.
198      *
199      * Emitted when D-Bus name owner is changed.
200      *
201      */
202     bus_signals[NAME_OWNER_CHANGED] =
203         g_signal_new (I_("name-owner-changed"),
204             G_TYPE_FROM_CLASS (class),
205             G_SIGNAL_RUN_LAST,
206             0,
207             NULL, NULL,
208             _ibus_marshal_VOID__STRING_STRING_STRING,
209             G_TYPE_NONE,
210             3,
211             G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
212
213     g_type_class_add_private (class, sizeof (IBusBusPrivate));
214 }
215
216 static void
217 _connection_dbus_signal_cb (GDBusConnection *connection,
218                             const gchar *sender_name,
219                             const gchar *object_path,
220                             const gchar *interface_name,
221                             const gchar *signal_name,
222                             GVariant *parameters,
223                             gpointer user_data)
224 {
225     g_return_if_fail (user_data != NULL);
226     g_return_if_fail (IBUS_IS_BUS (user_data));
227
228     if (g_strcmp0 (signal_name, "NameOwnerChanged") == 0) {
229         gchar *name = NULL;
230         gchar *old_owner = NULL;
231         gchar *new_owner = NULL;
232         g_variant_get (parameters, "(&s&s&s)", &name, &old_owner, &new_owner);
233         g_signal_emit (IBUS_BUS (user_data),
234                        bus_signals[NAME_OWNER_CHANGED], 0,
235                        name, old_owner, new_owner);
236     }
237     /* FIXME handle other D-Bus signals if needed */
238 }
239
240 static void
241 _connection_ibus_signal_cb (GDBusConnection *connection,
242                             const gchar *sender_name,
243                             const gchar *object_path,
244                             const gchar *interface_name,
245                             const gchar *signal_name,
246                             GVariant *parameters,
247                             gpointer user_data)
248 {
249     g_return_if_fail (user_data != NULL);
250     g_return_if_fail (IBUS_IS_BUS (user_data));
251
252     if (g_strcmp0 (signal_name, "GlobalEngineChanged") == 0) {
253         gchar *engine_name = NULL;
254         g_variant_get (parameters, "(&s)", &engine_name);
255         g_signal_emit (IBUS_BUS (user_data),
256                        bus_signals[GLOBAL_ENGINE_CHANGED], 0,
257                        engine_name);
258     }
259     /* FIXME handle org.freedesktop.IBus.RegistryChanged signal if needed */
260 }
261
262 static void
263 _connection_closed_cb (GDBusConnection  *connection,
264                        gboolean          remote_peer_vanished,
265                        GError           *error,
266                        IBusBus          *bus)
267 {
268     if (error) {
269         /* We replaced g_warning with g_debug here because
270          * currently when ibus-daemon restarts, GTK client calls this and
271          * _g_dbus_worker_do_read_cb() sets the error message:
272          * "Underlying GIOStream returned 0 bytes on an async read"
273          * http://git.gnome.org/browse/glib/tree/gio/gdbusprivate.c#n693
274          * However we think the error message is almost harmless. */
275         g_debug ("_connection_closed_cb: %s", error->message);
276     }
277     ibus_bus_close_connection (bus);
278 }
279
280 static void
281 ibus_bus_close_connection (IBusBus *bus)
282 {
283     g_free (bus->priv->unique_name);
284     bus->priv->unique_name = NULL;
285
286     bus->priv->watch_dbus_signal_id = 0;
287     bus->priv->watch_ibus_signal_id = 0;
288
289     g_free (bus->priv->bus_address);
290     bus->priv->bus_address = NULL;
291
292     /* Cancel ongoing connect request. */
293     g_cancellable_cancel (bus->priv->cancellable);
294     g_cancellable_reset (bus->priv->cancellable);
295
296     /* unref the old connection at first */
297     if (bus->priv->connection != NULL) {
298         g_signal_handlers_disconnect_by_func (bus->priv->connection,
299                                               G_CALLBACK (_connection_closed_cb),
300                                               bus);
301         if (!g_dbus_connection_is_closed(bus->priv->connection))
302             g_dbus_connection_close(bus->priv->connection, NULL, NULL, NULL);
303         g_object_unref (bus->priv->connection);
304         bus->priv->connection = NULL;
305         g_signal_emit (bus, bus_signals[DISCONNECTED], 0);
306     }
307 }
308
309 static void
310 ibus_bus_connect_completed (IBusBus *bus)
311 {
312     g_assert (bus->priv->connection);
313     /* FIXME */
314     ibus_bus_hello (bus);
315
316     g_signal_connect (bus->priv->connection,
317                       "closed",
318                       (GCallback) _connection_closed_cb,
319                       bus);
320     if (bus->priv->watch_dbus_signal) {
321         ibus_bus_watch_dbus_signal (bus);
322     }
323     if (bus->priv->watch_ibus_signal) {
324         ibus_bus_watch_ibus_signal (bus);
325     }
326
327     g_signal_emit (bus, bus_signals[CONNECTED], 0);
328 }
329
330 static void
331 _bus_connect_async_cb (GObject      *source_object,
332                         GAsyncResult *res,
333                         gpointer      user_data)
334 {
335     g_return_if_fail (user_data != NULL);
336     g_return_if_fail (IBUS_IS_BUS (user_data));
337
338     IBusBus *bus   = IBUS_BUS (user_data);
339     GError  *error = NULL;
340
341     bus->priv->connection =
342                 g_dbus_connection_new_for_address_finish (res, &error);
343
344     if (error != NULL) {
345         g_warning ("Unable to connect to ibus: %s", error->message);
346         g_error_free (error);
347         error = NULL;
348     }
349
350     if (bus->priv->connection != NULL) {
351         ibus_bus_connect_completed (bus);
352     }
353     else {
354         g_free (bus->priv->bus_address);
355         bus->priv->bus_address = NULL;
356     }
357
358     /* unref the ref from ibus_bus_connect */
359     g_object_unref (bus);
360 }
361
362 static void
363 ibus_bus_connect_async (IBusBus *bus)
364 {
365     const gchar *bus_address = ibus_get_address ();
366
367     if (bus_address == NULL)
368         return;
369
370     if (g_strcmp0 (bus->priv->bus_address, bus_address) == 0)
371         return;
372
373     /* Close current connection and cancel ongoing connect request. */
374     ibus_bus_close_connection (bus);
375
376     bus->priv->bus_address = g_strdup (bus_address);
377     g_object_ref (bus);
378     g_dbus_connection_new_for_address (
379             bus_address,
380             G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
381             G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION,
382             NULL,
383             bus->priv->cancellable,
384             _bus_connect_async_cb, bus);
385 }
386
387 static void
388 ibus_bus_connect (IBusBus *bus)
389 {
390     const gchar *bus_address = ibus_get_address ();
391
392     if (bus_address == NULL)
393         return;
394
395     if (g_strcmp0 (bus_address, bus->priv->bus_address) == 0 &&
396         bus->priv->connection != NULL)
397         return;
398
399     /* Close current connection and cancel ongoing connect request. */
400     ibus_bus_close_connection (bus);
401
402     bus->priv->connection = g_dbus_connection_new_for_address_sync (
403             bus_address,
404             G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
405             G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION,
406             NULL, NULL, NULL);
407     if (bus->priv->connection) {
408         bus->priv->bus_address = g_strdup (bus_address);
409         ibus_bus_connect_completed (bus);
410     }
411 }
412
413 static void
414 _changed_cb (GFileMonitor       *monitor,
415              GFile              *file,
416              GFile              *other_file,
417              GFileMonitorEvent   event_type,
418              IBusBus            *bus)
419 {
420     if (event_type != G_FILE_MONITOR_EVENT_CHANGED &&
421         event_type != G_FILE_MONITOR_EVENT_CREATED &&
422         event_type != G_FILE_MONITOR_EVENT_DELETED)
423         return;
424
425     ibus_bus_connect_async (bus);
426 }
427
428 static void
429 ibus_bus_init (IBusBus *bus)
430 {
431     struct stat buf;
432     gchar *path;
433     GFile *file;
434
435     bus->priv = IBUS_BUS_GET_PRIVATE (bus);
436
437     bus->priv->config = NULL;
438     bus->priv->connection = NULL;
439     bus->priv->watch_dbus_signal = FALSE;
440     bus->priv->watch_dbus_signal_id = 0;
441     bus->priv->watch_ibus_signal = FALSE;
442     bus->priv->watch_ibus_signal_id = 0;
443     bus->priv->unique_name = NULL;
444     bus->priv->connect_async = FALSE;
445     bus->priv->bus_address = NULL;
446     bus->priv->cancellable = g_cancellable_new ();
447
448     path = g_path_get_dirname (ibus_get_socket_path ());
449
450     g_mkdir_with_parents (path, 0700);
451     g_chmod (path, 0700);
452
453     if (stat (path, &buf) == 0) {
454         if (buf.st_uid != getuid ()) {
455             g_warning ("The owner of %s is not %s!", path, ibus_get_user_name ());
456             return;
457         }
458     }
459
460     file = g_file_new_for_path (ibus_get_socket_path ());
461     bus->priv->monitor = g_file_monitor_file (file, 0, NULL, NULL);
462
463     g_signal_connect (bus->priv->monitor, "changed", (GCallback) _changed_cb, bus);
464
465     g_object_unref (file);
466     g_free (path);
467 }
468
469 static void
470 ibus_bus_set_property (IBusBus      *bus,
471                        guint         prop_id,
472                        const GValue *value,
473                        GParamSpec   *pspec)
474 {
475     switch (prop_id) {
476     case PROP_CONNECT_ASYNC:
477         bus->priv->connect_async = g_value_get_boolean (value);
478         break;
479     default:
480         G_OBJECT_WARN_INVALID_PROPERTY_ID (bus, prop_id, pspec);
481     }
482 }
483
484 static void
485 ibus_bus_get_property (IBusBus    *bus,
486                        guint       prop_id,
487                        GValue     *value,
488                        GParamSpec *pspec)
489 {
490     switch (prop_id) {
491     case PROP_CONNECT_ASYNC:
492         g_value_set_boolean (value, bus->priv->connect_async);
493         break;
494     default:
495         G_OBJECT_WARN_INVALID_PROPERTY_ID (bus, prop_id, pspec);
496     }
497 }
498
499 static GObject*
500 ibus_bus_constructor (GType                  type,
501                       guint                  n_params,
502                       GObjectConstructParam *params)
503 {
504     GObject *object;
505
506     /* share one IBusBus instance in whole application */
507     if (_bus == NULL) {
508         object = G_OBJECT_CLASS (ibus_bus_parent_class)->constructor (type, n_params, params);
509         /* make bus object sink */
510         g_object_ref_sink (object);
511         _bus = IBUS_BUS (object);
512
513         if (_bus->priv->connect_async)
514             ibus_bus_connect_async (_bus);
515         else
516             ibus_bus_connect (_bus);
517     }
518     else {
519         object = g_object_ref (_bus);
520     }
521
522     return object;
523 }
524
525 static void
526 ibus_bus_destroy (IBusObject *object)
527 {
528     g_assert (_bus == (IBusBus *)object);
529
530     IBusBus * bus = _bus;
531     _bus = NULL;
532
533     if (bus->priv->monitor) {
534         g_object_unref (bus->priv->monitor);
535         bus->priv->monitor = NULL;
536     }
537
538     if (bus->priv->config) {
539         ibus_proxy_destroy ((IBusProxy *) bus->priv->config);
540         bus->priv->config = NULL;
541     }
542
543     if (bus->priv->connection) {
544         g_signal_handlers_disconnect_by_func (bus->priv->connection,
545                                               G_CALLBACK (_connection_closed_cb),
546                                               bus);
547         /* FIXME should use async close function */
548         g_dbus_connection_close_sync (bus->priv->connection, NULL, NULL);
549         g_object_unref (bus->priv->connection);
550         bus->priv->connection = NULL;
551     }
552
553     g_free (bus->priv->unique_name);
554     bus->priv->unique_name = NULL;
555
556     g_free (bus->priv->bus_address);
557     bus->priv->bus_address = NULL;
558
559     g_cancellable_cancel (bus->priv->cancellable);
560     g_object_unref (bus->priv->cancellable);
561     bus->priv->cancellable = NULL;
562
563     IBUS_OBJECT_CLASS (ibus_bus_parent_class)->destroy (object);
564 }
565
566 static gboolean
567 _async_finish_void (GAsyncResult *res,
568                     GError      **error)
569 {
570     GSimpleAsyncResult *simple = (GSimpleAsyncResult *) res;
571     if (g_simple_async_result_propagate_error (simple, error))
572         return FALSE;
573     return TRUE;
574 }
575
576 static gchar *
577 _async_finish_object_path (GAsyncResult *res,
578                            GError      **error)
579 {
580     GSimpleAsyncResult *simple = (GSimpleAsyncResult *) res;
581     if (g_simple_async_result_propagate_error (simple, error))
582         return NULL;
583     GVariant *variant = g_simple_async_result_get_op_res_gpointer (simple);
584     g_return_val_if_fail (variant != NULL, NULL);
585     gchar *path = NULL;
586     g_variant_get (variant, "(&o)", &path);
587     return path;
588 }
589
590 static gchar *
591 _async_finish_string (GAsyncResult *res,
592                       GError      **error)
593 {
594     GSimpleAsyncResult *simple = (GSimpleAsyncResult *) res;
595     if (g_simple_async_result_propagate_error (simple, error))
596         return NULL;
597     GVariant *variant = g_simple_async_result_get_op_res_gpointer (simple);
598     g_return_val_if_fail (variant != NULL, NULL);
599     gchar *s = NULL;
600     g_variant_get (variant, "(&s)", &s);
601     return s;
602 }
603
604 static gboolean
605 _async_finish_gboolean (GAsyncResult *res,
606                         GError      **error)
607 {
608     GSimpleAsyncResult *simple = (GSimpleAsyncResult *) res;
609     if (g_simple_async_result_propagate_error (simple, error))
610         return FALSE;
611     GVariant *variant = g_simple_async_result_get_op_res_gpointer (simple);
612     g_return_val_if_fail (variant != NULL, FALSE);
613     gboolean retval = FALSE;
614     g_variant_get (variant, "(b)", &retval);
615     return retval;
616 }
617
618 static guint
619 _async_finish_guint (GAsyncResult *res,
620                      GError      **error)
621 {
622     static const guint bad_id = 0;
623     GSimpleAsyncResult *simple = (GSimpleAsyncResult *) res;
624     if (g_simple_async_result_propagate_error (simple, error))
625         return bad_id;
626     GVariant *variant = g_simple_async_result_get_op_res_gpointer (simple);
627     g_return_val_if_fail (variant != NULL, bad_id);
628
629     guint id = 0;
630     g_variant_get (variant, "(u)", &id);
631     return id;
632 }
633
634 IBusBus *
635 ibus_bus_new (void)
636 {
637     IBusBus *bus = IBUS_BUS (g_object_new (IBUS_TYPE_BUS,
638                                            "connect-async", FALSE,
639                                            NULL));
640
641     return bus;
642 }
643
644 IBusBus *
645 ibus_bus_new_async (void)
646 {
647     IBusBus *bus = IBUS_BUS (g_object_new (IBUS_TYPE_BUS,
648                                            "connect-async", TRUE,
649                                            NULL));
650
651     return bus;
652 }
653
654 gboolean
655 ibus_bus_is_connected (IBusBus *bus)
656 {
657     g_return_val_if_fail (IBUS_IS_BUS (bus), FALSE);
658
659     if (bus->priv->connection == NULL || g_dbus_connection_is_closed (bus->priv->connection))
660         return FALSE;
661
662     return TRUE;
663 }
664
665 IBusInputContext *
666 ibus_bus_create_input_context (IBusBus      *bus,
667                                const gchar  *client_name)
668 {
669     g_return_val_if_fail (IBUS_IS_BUS (bus), NULL);
670     g_return_val_if_fail (client_name != NULL, NULL);
671
672     gchar *path;
673     IBusInputContext *context = NULL;
674     GVariant *result;
675     result = ibus_bus_call_sync (bus,
676                                  IBUS_SERVICE_IBUS,
677                                  IBUS_PATH_IBUS,
678                                  IBUS_INTERFACE_IBUS,
679                                  "CreateInputContext",
680                                  g_variant_new ("(s)", client_name),
681                                  G_VARIANT_TYPE ("(o)"));
682
683     if (result != NULL) {
684         GError *error = NULL;
685         g_variant_get (result, "(&o)", &path);
686         context = ibus_input_context_new (path, bus->priv->connection, NULL, &error);
687         g_variant_unref (result);
688         if (context == NULL) {
689             g_warning ("ibus_bus_create_input_context: %s", error->message);
690             g_error_free (error);
691         }
692     }
693
694     return context;
695 }
696
697 static void
698 _create_input_context_async_step_two_done (GObject            *source_object,
699                                            GAsyncResult       *res,
700                                            GSimpleAsyncResult *simple)
701 {
702     GError *error = NULL;
703     IBusInputContext *context =
704             ibus_input_context_new_async_finish (res, &error);
705     if (context == NULL) {
706         g_simple_async_result_set_from_error (simple, error);
707         g_error_free (error);
708     }
709     else {
710         g_simple_async_result_set_op_res_gpointer (simple, context, NULL);
711     }
712     g_simple_async_result_complete_in_idle (simple);
713     g_object_unref (simple);
714 }
715
716 static void
717 _create_input_context_async_step_one_done (GDBusConnection    *connection,
718                                            GAsyncResult       *res,
719                                            GSimpleAsyncResult *simple)
720 {
721     GError *error = NULL;
722     GVariant *variant = g_dbus_connection_call_finish (connection, res, &error);
723
724     if (variant == NULL) {
725         g_simple_async_result_set_from_error (simple, error);
726         g_error_free (error);
727         g_simple_async_result_complete_in_idle (simple);
728         g_object_unref (simple);
729         return;
730     }
731
732     if (g_dbus_connection_is_closed (connection)) {
733         /*
734          * The connection is closed, can not contine next steps, so complete
735          * the asynchronous request with error.
736          */
737         g_simple_async_result_set_error (simple,
738                 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Connection is closed.");
739         g_simple_async_result_complete_in_idle (simple);
740         return;
741     }
742
743     const gchar *path = NULL;
744     g_variant_get (variant, "(&o)", &path);
745
746
747     IBusBus *bus = (IBusBus *)g_async_result_get_source_object (
748             (GAsyncResult *)simple);
749     g_assert (IBUS_IS_BUS (bus));
750
751     GCancellable *cancellable =
752             (GCancellable *)g_object_get_data ((GObject *)simple,
753                                                "cancellable");
754
755     ibus_input_context_new_async (path,
756             bus->priv->connection,
757             cancellable,
758             (GAsyncReadyCallback)_create_input_context_async_step_two_done,
759             simple);
760     /* release the reference from g_async_result_get_source_object() */
761     g_object_unref (bus);
762 }
763
764 void
765 ibus_bus_create_input_context_async (IBusBus            *bus,
766                                      const gchar        *client_name,
767                                      gint                timeout_msec,
768                                      GCancellable       *cancellable,
769                                      GAsyncReadyCallback callback,
770                                      gpointer            user_data)
771 {
772     g_return_if_fail (IBUS_IS_BUS (bus));
773     g_return_if_fail (client_name != NULL);
774     g_return_if_fail (callback != NULL);
775
776     GSimpleAsyncResult *simple = g_simple_async_result_new ((GObject *)bus,
777             callback, user_data, ibus_bus_create_input_context_async);
778
779     if (cancellable != NULL) {
780         g_object_set_data_full ((GObject *)simple,
781                                 "cancellable",
782                                 g_object_ref (cancellable),
783                                 (GDestroyNotify)g_object_unref);
784     }
785
786     /* do not use ibus_bus_call_async, instread use g_dbus_connection_call
787      * directly, because we need two async steps for create an IBusInputContext.
788      * 1. Call CreateInputContext to request ibus-daemon create a remote IC.
789      * 2. New local IBusInputContext proxy of the remote IC
790      */
791     g_dbus_connection_call (bus->priv->connection,
792             IBUS_SERVICE_IBUS,
793             IBUS_PATH_IBUS,
794             IBUS_INTERFACE_IBUS,
795             "CreateInputContext",
796             g_variant_new ("(s)", client_name),
797             G_VARIANT_TYPE("(o)"),
798             G_DBUS_CALL_FLAGS_NO_AUTO_START,
799             timeout_msec,
800             cancellable,
801             (GAsyncReadyCallback)_create_input_context_async_step_one_done,
802             simple);
803 }
804
805 IBusInputContext *
806 ibus_bus_create_input_context_async_finish (IBusBus      *bus,
807                                             GAsyncResult *res,
808                                             GError      **error)
809 {
810     g_assert (IBUS_IS_BUS (bus));
811     g_assert (g_simple_async_result_is_valid (res, (GObject *) bus,
812                                               ibus_bus_create_input_context_async));
813
814     GSimpleAsyncResult *simple = (GSimpleAsyncResult *) res;
815     if (g_simple_async_result_propagate_error (simple, error))
816         return NULL;
817     IBusInputContext *context =
818             g_simple_async_result_get_op_res_gpointer (simple);
819     g_assert (IBUS_IS_INPUT_CONTEXT (context));
820     return context;
821 }
822
823 gchar *
824 ibus_bus_current_input_context (IBusBus      *bus)
825 {
826     g_return_val_if_fail (IBUS_IS_BUS (bus), NULL);
827
828     gchar *path = NULL;
829     GVariant *result;
830     result = ibus_bus_call_sync (bus,
831                                  IBUS_SERVICE_IBUS,
832                                  IBUS_PATH_IBUS,
833                                  IBUS_INTERFACE_IBUS,
834                                  "CurrentInputContext",
835                                  NULL,
836                                  G_VARIANT_TYPE ("(o)"));
837
838     if (result != NULL) {
839         g_variant_get (result, "(o)", &path);
840         g_variant_unref (result);
841     }
842
843     return path;
844 }
845
846 void
847 ibus_bus_current_input_context_async (IBusBus            *bus,
848                                       gint                timeout_msec,
849                                       GCancellable       *cancellable,
850                                       GAsyncReadyCallback callback,
851                                       gpointer            user_data)
852 {
853     g_return_if_fail (IBUS_IS_BUS (bus));
854
855     ibus_bus_call_async (bus,
856                          IBUS_SERVICE_IBUS,
857                          IBUS_PATH_IBUS,
858                          IBUS_INTERFACE_IBUS,
859                          "CurrentInputContext",
860                          NULL,
861                          G_VARIANT_TYPE ("(o)"),
862                          ibus_bus_current_input_context_async,
863                          timeout_msec,
864                          cancellable,
865                          callback,
866                          user_data);
867 }
868
869 gchar *
870 ibus_bus_current_input_context_async_finish (IBusBus      *bus,
871                                              GAsyncResult *res,
872                                              GError      **error)
873 {
874     g_assert (IBUS_IS_BUS (bus));
875     g_assert (g_simple_async_result_is_valid (res, (GObject *) bus,
876                                               ibus_bus_current_input_context_async));
877     return g_strdup (_async_finish_object_path (res, error));
878 }
879
880 static void
881 ibus_bus_watch_dbus_signal (IBusBus *bus)
882 {
883     g_return_if_fail (bus->priv->connection != NULL);
884     g_return_if_fail (bus->priv->watch_dbus_signal_id == 0);
885
886     /* Subscribe to dbus signals such as NameOwnerChanged. */
887     bus->priv->watch_dbus_signal_id
888         = g_dbus_connection_signal_subscribe (bus->priv->connection,
889                                               DBUS_SERVICE_DBUS,
890                                               DBUS_INTERFACE_DBUS,
891                                               "NameOwnerChanged",
892                                               DBUS_PATH_DBUS,
893                                               NULL /* arg0 */,
894                                               (GDBusSignalFlags) 0,
895                                               _connection_dbus_signal_cb,
896                                               bus,
897                                               NULL /* user_data_free_func */);
898     /* FIXME handle other D-Bus signals if needed */
899 }
900
901 static void
902 ibus_bus_unwatch_dbus_signal (IBusBus *bus)
903 {
904     g_return_if_fail (bus->priv->watch_dbus_signal_id != 0);
905     g_dbus_connection_signal_unsubscribe (bus->priv->connection,
906                                           bus->priv->watch_dbus_signal_id);
907     bus->priv->watch_dbus_signal_id = 0;
908 }
909
910 void
911 ibus_bus_set_watch_dbus_signal (IBusBus        *bus,
912                                 gboolean        watch)
913 {
914     g_return_if_fail (IBUS_IS_BUS (bus));
915
916     if (bus->priv->watch_dbus_signal == watch)
917         return;
918
919     bus->priv->watch_dbus_signal = watch;
920
921     if (ibus_bus_is_connected (bus)) {
922         if (watch) {
923             ibus_bus_watch_dbus_signal (bus);
924         }
925         else {
926             ibus_bus_unwatch_dbus_signal (bus);
927         }
928     }
929 }
930
931 static void
932 ibus_bus_watch_ibus_signal (IBusBus *bus)
933 {
934     g_return_if_fail (bus->priv->connection != NULL);
935     g_return_if_fail (bus->priv->watch_ibus_signal_id == 0);
936
937     /* Subscribe to ibus signals such as GlboalEngineChanged. */
938     bus->priv->watch_ibus_signal_id
939         = g_dbus_connection_signal_subscribe (bus->priv->connection,
940                                               "org.freedesktop.IBus",
941                                               IBUS_INTERFACE_IBUS,
942                                               "GlobalEngineChanged",
943                                               IBUS_PATH_IBUS,
944                                               NULL /* arg0 */,
945                                               (GDBusSignalFlags) 0,
946                                               _connection_ibus_signal_cb,
947                                               bus,
948                                               NULL /* user_data_free_func */);
949     /* FIXME handle org.freedesktop.IBus.RegistryChanged signal if needed */
950 }
951
952 static void
953 ibus_bus_unwatch_ibus_signal (IBusBus *bus)
954 {
955     g_return_if_fail (bus->priv->watch_ibus_signal_id != 0);
956     g_dbus_connection_signal_unsubscribe (bus->priv->connection,
957                                           bus->priv->watch_ibus_signal_id);
958     bus->priv->watch_ibus_signal_id = 0;
959 }
960
961 void
962 ibus_bus_set_watch_ibus_signal (IBusBus        *bus,
963                                 gboolean        watch)
964 {
965     g_return_if_fail (IBUS_IS_BUS (bus));
966
967     if (bus->priv->watch_ibus_signal == watch)
968         return;
969
970     bus->priv->watch_ibus_signal = watch;
971
972     if (ibus_bus_is_connected (bus)) {
973         if (watch) {
974             ibus_bus_watch_ibus_signal (bus);
975         }
976         else {
977             ibus_bus_unwatch_ibus_signal (bus);
978         }
979     }
980 }
981
982 const gchar *
983 ibus_bus_hello (IBusBus *bus)
984 {
985     g_return_val_if_fail (IBUS_IS_BUS (bus), NULL);
986     g_return_val_if_fail (ibus_bus_is_connected (bus), NULL);
987
988     /* gdbus connection will say hello by self. */
989     if (bus->priv->connection)
990         return g_dbus_connection_get_unique_name (bus->priv->connection);
991     return NULL;
992 }
993
994 guint32
995 ibus_bus_request_name (IBusBus      *bus,
996                        const gchar  *name,
997                        guint32       flags)
998 {
999     g_return_val_if_fail (IBUS_IS_BUS (bus), 0);
1000     g_return_val_if_fail (name != NULL, 0);
1001
1002     guint32 retval = 0;
1003     GVariant *result;
1004     result = ibus_bus_call_sync (bus,
1005                                  DBUS_SERVICE_DBUS,
1006                                  DBUS_PATH_DBUS,
1007                                  DBUS_INTERFACE_DBUS,
1008                                  "RequestName",
1009                                  g_variant_new ("(su)", name, flags),
1010                                  G_VARIANT_TYPE ("(u)"));
1011
1012     if (result) {
1013         g_variant_get (result, "(u)", &retval);
1014         g_variant_unref (result);
1015     }
1016
1017     return retval;
1018 }
1019
1020 void
1021 ibus_bus_request_name_async (IBusBus            *bus,
1022                              const gchar        *name,
1023                              guint               flags,
1024                              gint                timeout_msec,
1025                              GCancellable       *cancellable,
1026                              GAsyncReadyCallback callback,
1027                              gpointer            user_data)
1028 {
1029     g_return_if_fail (IBUS_IS_BUS (bus));
1030     g_return_if_fail (name != NULL);
1031
1032     ibus_bus_call_async (bus,
1033                          DBUS_SERVICE_DBUS,
1034                          DBUS_PATH_DBUS,
1035                          DBUS_INTERFACE_DBUS,
1036                          "RequestName",
1037                          g_variant_new ("(su)", name, flags),
1038                          G_VARIANT_TYPE ("(u)"),
1039                          ibus_bus_request_name_async,
1040                          timeout_msec,
1041                          cancellable,
1042                          callback,
1043                          user_data);
1044 }
1045
1046 guint
1047 ibus_bus_request_name_async_finish (IBusBus      *bus,
1048                                     GAsyncResult *res,
1049                                     GError      **error)
1050 {
1051     g_assert (IBUS_IS_BUS (bus));
1052     g_assert (g_simple_async_result_is_valid (res, (GObject *) bus,
1053                                               ibus_bus_request_name_async));
1054     return _async_finish_guint (res, error);
1055 }
1056
1057 guint
1058 ibus_bus_release_name (IBusBus      *bus,
1059                        const gchar  *name)
1060 {
1061     g_return_val_if_fail (IBUS_IS_BUS (bus), 0);
1062     g_return_val_if_fail (name != NULL, 0);
1063
1064     guint retval = 0;
1065     GVariant *result;
1066     result = ibus_bus_call_sync (bus,
1067                                  DBUS_SERVICE_DBUS,
1068                                  DBUS_PATH_DBUS,
1069                                  DBUS_INTERFACE_DBUS,
1070                                  "ReleaseName",
1071                                  g_variant_new ("(s)", name),
1072                                  G_VARIANT_TYPE ("(u)"));
1073
1074     if (result) {
1075         g_variant_get (result, "(u)", &retval);
1076         g_variant_unref (result);
1077     }
1078
1079     return retval;
1080 }
1081
1082 void
1083 ibus_bus_release_name_async (IBusBus            *bus,
1084                              const gchar        *name,
1085                              gint                timeout_msec,
1086                              GCancellable       *cancellable,
1087                              GAsyncReadyCallback callback,
1088                              gpointer            user_data)
1089 {
1090     g_return_if_fail (IBUS_IS_BUS (bus));
1091     g_return_if_fail (name != NULL);
1092
1093     ibus_bus_call_async (bus,
1094                          DBUS_SERVICE_DBUS,
1095                          DBUS_PATH_DBUS,
1096                          DBUS_INTERFACE_DBUS,
1097                          "ReleaseName",
1098                          g_variant_new ("(s)", name),
1099                          G_VARIANT_TYPE ("(u)"),
1100                          ibus_bus_release_name_async,
1101                          timeout_msec,
1102                          cancellable,
1103                          callback,
1104                          user_data);
1105 }
1106
1107 guint
1108 ibus_bus_release_name_async_finish (IBusBus      *bus,
1109                                     GAsyncResult *res,
1110                                     GError      **error)
1111 {
1112     g_assert (IBUS_IS_BUS (bus));
1113     g_assert (g_simple_async_result_is_valid (res, (GObject *) bus,
1114                                               ibus_bus_release_name_async));
1115     return _async_finish_guint (res, error);
1116 }
1117
1118 GList *
1119 ibus_bus_list_queued_owners (IBusBus      *bus,
1120                              const gchar  *name)
1121 {
1122     GList *retval = NULL;
1123     GVariant *result;
1124
1125     g_return_val_if_fail (IBUS_IS_BUS (bus), NULL);
1126     g_return_val_if_fail (name != NULL, NULL);
1127
1128     result = ibus_bus_call_sync (bus,
1129                                  DBUS_SERVICE_DBUS,
1130                                  DBUS_PATH_DBUS,
1131                                  DBUS_INTERFACE_DBUS,
1132                                  "ListQueuedOwners",
1133                                  g_variant_new ("(s)", name),
1134                                  G_VARIANT_TYPE ("(as)"));
1135
1136     if (result) {
1137         GVariantIter *iter = NULL;
1138         const gchar *name = NULL;
1139         g_variant_get (result, "(as)", &iter);
1140         while (g_variant_iter_loop (iter, "&s", &name)) {
1141             if (name == NULL) {
1142                 continue;
1143             }
1144             retval = g_list_append (retval, g_strdup (name));
1145         }
1146         g_variant_iter_free (iter);
1147         g_variant_unref (result);
1148     }
1149
1150     return retval;
1151 }
1152
1153 gboolean
1154 ibus_bus_name_has_owner (IBusBus        *bus,
1155                          const gchar    *name)
1156 {
1157     g_return_val_if_fail (IBUS_IS_BUS (bus), FALSE);
1158     g_return_val_if_fail (name != NULL, FALSE);
1159
1160     gboolean retval = FALSE;
1161     GVariant *result;
1162     result = ibus_bus_call_sync (bus,
1163                                  DBUS_SERVICE_DBUS,
1164                                  DBUS_PATH_DBUS,
1165                                  DBUS_INTERFACE_DBUS,
1166                                  "NameHasOwner",
1167                                  g_variant_new ("(s)", name),
1168                                  G_VARIANT_TYPE ("(b)"));
1169
1170     if (result) {
1171         g_variant_get (result, "(b)", &retval);
1172         g_variant_unref (result);
1173     }
1174
1175     return retval;
1176 }
1177
1178 void
1179 ibus_bus_name_has_owner_async (IBusBus            *bus,
1180                                const gchar        *name,
1181                                gint                timeout_msec,
1182                                GCancellable       *cancellable,
1183                                GAsyncReadyCallback callback,
1184                                gpointer            user_data)
1185 {
1186     g_return_if_fail (IBUS_IS_BUS (bus));
1187     g_return_if_fail (name != NULL);
1188
1189     ibus_bus_call_async (bus,
1190                          DBUS_SERVICE_DBUS,
1191                          DBUS_PATH_DBUS,
1192                          DBUS_INTERFACE_DBUS,
1193                          "NameHasOwner",
1194                          g_variant_new ("(s)", name),
1195                          G_VARIANT_TYPE ("(b)"),
1196                          ibus_bus_name_has_owner_async,
1197                          timeout_msec,
1198                          cancellable,
1199                          callback,
1200                          user_data);
1201 }
1202
1203 gboolean
1204 ibus_bus_name_has_owner_async_finish (IBusBus      *bus,
1205                                       GAsyncResult *res,
1206                                       GError      **error)
1207 {
1208     g_assert (IBUS_IS_BUS (bus));
1209     g_assert (g_simple_async_result_is_valid (res, (GObject *) bus,
1210                                               ibus_bus_name_has_owner_async));
1211     return _async_finish_gboolean (res, error);
1212 }
1213
1214 GList *
1215 ibus_bus_list_names (IBusBus    *bus)
1216 {
1217     g_return_val_if_fail (IBUS_IS_BUS (bus), NULL);
1218     return NULL;
1219 }
1220
1221 gboolean
1222 ibus_bus_add_match (IBusBus     *bus,
1223                     const gchar *rule)
1224 {
1225     g_return_val_if_fail (IBUS_IS_BUS (bus), FALSE);
1226     g_return_val_if_fail (rule != NULL, FALSE);
1227
1228     GVariant *result;
1229     result = ibus_bus_call_sync (bus,
1230                                  DBUS_SERVICE_DBUS,
1231                                  DBUS_PATH_DBUS,
1232                                  DBUS_INTERFACE_DBUS,
1233                                  "AddMatch",
1234                                  g_variant_new ("(s)", rule),
1235                                  NULL);
1236
1237     if (result) {
1238         g_variant_unref (result);
1239         return TRUE;
1240     }
1241     return FALSE;
1242 }
1243
1244 void
1245 ibus_bus_add_match_async (IBusBus            *bus,
1246                           const gchar        *rule,
1247                           gint                timeout_msec,
1248                           GCancellable       *cancellable,
1249                           GAsyncReadyCallback callback,
1250                           gpointer            user_data)
1251 {
1252     g_return_if_fail (IBUS_IS_BUS (bus));
1253     g_return_if_fail (rule != NULL);
1254
1255     ibus_bus_call_async (bus,
1256                          DBUS_SERVICE_DBUS,
1257                          DBUS_PATH_DBUS,
1258                          DBUS_INTERFACE_DBUS,
1259                          "AddMatch",
1260                          g_variant_new ("(s)", rule),
1261                          NULL,
1262                          ibus_bus_add_match_async,
1263                          timeout_msec,
1264                          cancellable,
1265                          callback,
1266                          user_data);
1267 }
1268
1269 gboolean
1270 ibus_bus_add_match_async_finish (IBusBus      *bus,
1271                                  GAsyncResult *res,
1272                                  GError      **error)
1273 {
1274     g_assert (IBUS_IS_BUS (bus));
1275     g_assert (g_simple_async_result_is_valid (res, (GObject *) bus,
1276                                               ibus_bus_add_match_async));
1277     return _async_finish_void (res, error);
1278 }
1279
1280 gboolean
1281 ibus_bus_remove_match (IBusBus      *bus,
1282                        const gchar  *rule)
1283 {
1284     g_return_val_if_fail (IBUS_IS_BUS (bus), FALSE);
1285     g_return_val_if_fail (rule != NULL, FALSE);
1286
1287     GVariant *result;
1288     result = ibus_bus_call_sync (bus,
1289                                  DBUS_SERVICE_DBUS,
1290                                  DBUS_PATH_DBUS,
1291                                  DBUS_INTERFACE_DBUS,
1292                                  "RemoveMatch",
1293                                  g_variant_new ("(s)", rule),
1294                                  NULL);
1295
1296     if (result) {
1297         g_variant_unref (result);
1298         return TRUE;
1299     }
1300     return FALSE;
1301 }
1302
1303 void
1304 ibus_bus_remove_match_async (IBusBus            *bus,
1305                              const gchar        *rule,
1306                              gint                timeout_msec,
1307                              GCancellable       *cancellable,
1308                              GAsyncReadyCallback callback,
1309                              gpointer            user_data)
1310 {
1311     g_return_if_fail (IBUS_IS_BUS (bus));
1312     g_return_if_fail (rule != NULL);
1313
1314     ibus_bus_call_async (bus,
1315                          DBUS_SERVICE_DBUS,
1316                          DBUS_PATH_DBUS,
1317                          DBUS_INTERFACE_DBUS,
1318                          "RemoveMatch",
1319                          g_variant_new ("(s)", rule),
1320                          NULL,
1321                          ibus_bus_remove_match_async,
1322                          timeout_msec,
1323                          cancellable,
1324                          callback,
1325                          user_data);
1326 }
1327
1328 gboolean
1329 ibus_bus_remove_match_async_finish (IBusBus      *bus,
1330                                     GAsyncResult *res,
1331                                     GError      **error)
1332 {
1333     g_assert (IBUS_IS_BUS (bus));
1334     g_assert (g_simple_async_result_is_valid (res, (GObject *) bus,
1335                                               ibus_bus_remove_match_async));
1336     return _async_finish_void (res, error);
1337 }
1338
1339 gchar *
1340 ibus_bus_get_name_owner (IBusBus        *bus,
1341                          const gchar    *name)
1342 {
1343     g_return_val_if_fail (IBUS_IS_BUS (bus), NULL);
1344     g_return_val_if_fail (name != NULL, NULL);
1345
1346     gchar *retval = NULL;
1347     GVariant *result;
1348     result = ibus_bus_call_sync (bus,
1349                                  DBUS_SERVICE_DBUS,
1350                                  DBUS_PATH_DBUS,
1351                                  DBUS_INTERFACE_DBUS,
1352                                  "GetNameOwner",
1353                                  g_variant_new ("(s)", name),
1354                                  G_VARIANT_TYPE ("(s)"));
1355
1356     if (result) {
1357         g_variant_get (result, "(s)", &retval);
1358         g_variant_unref (result);
1359     }
1360
1361     return retval;
1362 }
1363
1364 void
1365 ibus_bus_get_name_owner_async (IBusBus            *bus,
1366                                const gchar        *name,
1367                                gint                timeout_msec,
1368                                GCancellable       *cancellable,
1369                                GAsyncReadyCallback callback,
1370                                gpointer            user_data)
1371 {
1372     g_return_if_fail (IBUS_IS_BUS (bus));
1373     g_return_if_fail (name != NULL);
1374
1375     ibus_bus_call_async (bus,
1376                          DBUS_SERVICE_DBUS,
1377                          DBUS_PATH_DBUS,
1378                          DBUS_INTERFACE_DBUS,
1379                          "GetNameOwner",
1380                          g_variant_new ("(s)", name),
1381                          G_VARIANT_TYPE ("(s)"),
1382                          ibus_bus_get_name_owner_async,
1383                          timeout_msec,
1384                          cancellable,
1385                          callback,
1386                          user_data);
1387 }
1388
1389 gchar *
1390 ibus_bus_get_name_owner_async_finish (IBusBus      *bus,
1391                                       GAsyncResult *res,
1392                                       GError      **error)
1393 {
1394     g_assert (IBUS_IS_BUS (bus));
1395     g_assert (g_simple_async_result_is_valid (res, (GObject *) bus,
1396                                               ibus_bus_get_name_owner_async));
1397     return g_strdup (_async_finish_string (res, error));
1398 }
1399
1400 GDBusConnection *
1401 ibus_bus_get_connection (IBusBus *bus)
1402 {
1403     g_return_val_if_fail (IBUS_IS_BUS (bus), NULL);
1404
1405     return bus->priv->connection;
1406 }
1407
1408 gboolean
1409 ibus_bus_exit (IBusBus *bus,
1410                gboolean restart)
1411 {
1412     g_return_val_if_fail (IBUS_IS_BUS (bus), FALSE);
1413
1414     GVariant *result;
1415     result = ibus_bus_call_sync (bus,
1416                                  IBUS_SERVICE_IBUS,
1417                                  IBUS_PATH_IBUS,
1418                                  IBUS_INTERFACE_IBUS,
1419                                  "Exit",
1420                                  g_variant_new ("(b)", restart),
1421                                  NULL);
1422
1423     if (result) {
1424         g_variant_unref (result);
1425         return TRUE;
1426     }
1427     return FALSE;
1428 }
1429
1430 void
1431 ibus_bus_exit_async (IBusBus            *bus,
1432                      gboolean            restart,
1433                      gint                timeout_msec,
1434                      GCancellable       *cancellable,
1435                      GAsyncReadyCallback callback,
1436                      gpointer            user_data)
1437 {
1438     g_return_if_fail (IBUS_IS_BUS (bus));
1439
1440     ibus_bus_call_async (bus,
1441                          IBUS_SERVICE_IBUS,
1442                          IBUS_PATH_IBUS,
1443                          IBUS_INTERFACE_IBUS,
1444                          "Exit",
1445                          g_variant_new ("(b)", restart),
1446                          NULL,
1447                          ibus_bus_exit_async,
1448                          timeout_msec,
1449                          cancellable,
1450                          callback,
1451                          user_data);
1452 }
1453
1454 gboolean
1455 ibus_bus_exit_async_finish (IBusBus      *bus,
1456                             GAsyncResult *res,
1457                             GError      **error)
1458 {
1459     g_assert (IBUS_IS_BUS (bus));
1460     g_assert (g_simple_async_result_is_valid (res, (GObject *) bus,
1461                                               ibus_bus_exit_async));
1462     return _async_finish_void (res, error);
1463 }
1464
1465 gboolean
1466 ibus_bus_register_component (IBusBus       *bus,
1467                              IBusComponent *component)
1468 {
1469     g_return_val_if_fail (IBUS_IS_BUS (bus), FALSE);
1470     g_return_val_if_fail (IBUS_IS_COMPONENT (component), FALSE);
1471
1472     GVariant *variant = ibus_serializable_serialize ((IBusSerializable *)component);
1473     GVariant *result = ibus_bus_call_sync (bus,
1474                                            IBUS_SERVICE_IBUS,
1475                                            IBUS_PATH_IBUS,
1476                                            IBUS_INTERFACE_IBUS,
1477                                            "RegisterComponent",
1478                                            g_variant_new ("(v)", variant),
1479                                            NULL);
1480     if (result) {
1481         g_variant_unref (result);
1482         return TRUE;
1483     }
1484     return FALSE;
1485 }
1486
1487 void
1488 ibus_bus_register_component_async (IBusBus            *bus,
1489                                    IBusComponent      *component,
1490                                    gint                timeout_msec,
1491                                    GCancellable       *cancellable,
1492                                    GAsyncReadyCallback callback,
1493                                    gpointer            user_data)
1494 {
1495     g_return_if_fail (IBUS_IS_BUS (bus));
1496     g_return_if_fail (IBUS_IS_COMPONENT (component));
1497
1498     GVariant *variant = ibus_serializable_serialize ((IBusSerializable *)component);
1499     ibus_bus_call_async (bus,
1500                          IBUS_SERVICE_IBUS,
1501                          IBUS_PATH_IBUS,
1502                          IBUS_INTERFACE_IBUS,
1503                          "RegisterComponent",
1504                          g_variant_new ("(v)", variant),
1505                          NULL,
1506                          ibus_bus_register_component_async,
1507                          timeout_msec,
1508                          cancellable,
1509                          callback,
1510                          user_data);
1511 }
1512
1513 gboolean
1514 ibus_bus_register_component_async_finish (IBusBus      *bus,
1515                                           GAsyncResult *res,
1516                                           GError      **error)
1517 {
1518     g_assert (IBUS_IS_BUS (bus));
1519     g_assert (g_simple_async_result_is_valid (res, (GObject *) bus,
1520                                               ibus_bus_register_component_async));
1521     return _async_finish_void (res, error);
1522 }
1523
1524 static GList *
1525 ibus_bus_do_list_engines (IBusBus *bus, gboolean active_engines_only)
1526 {
1527     g_return_val_if_fail (IBUS_IS_BUS (bus), NULL);
1528
1529     GList *retval = NULL;
1530     GVariant *result;
1531     result = ibus_bus_call_sync (bus,
1532                                  IBUS_SERVICE_IBUS,
1533                                  IBUS_PATH_IBUS,
1534                                  IBUS_INTERFACE_IBUS,
1535                                  active_engines_only ? "ListActiveEngines" : "ListEngines",
1536                                  NULL,
1537                                  G_VARIANT_TYPE ("(av)"));
1538
1539     if (result) {
1540         GVariantIter *iter = NULL;
1541         g_variant_get (result, "(av)", &iter);
1542         GVariant *var;
1543         while (g_variant_iter_loop (iter, "v", &var)) {
1544             IBusSerializable *serializable = ibus_serializable_deserialize (var);
1545             g_object_ref_sink (serializable);
1546             retval = g_list_append (retval, serializable);
1547         }
1548         g_variant_iter_free (iter);
1549         g_variant_unref (result);
1550     }
1551
1552     return retval;
1553 }
1554
1555 GList *
1556 ibus_bus_list_engines (IBusBus *bus)
1557 {
1558     return ibus_bus_do_list_engines (bus, FALSE);
1559 }
1560
1561 void
1562 ibus_bus_list_engines_async (IBusBus            *bus,
1563                              gint                timeout_msec,
1564                              GCancellable       *cancellable,
1565                              GAsyncReadyCallback callback,
1566                              gpointer            user_data)
1567 {
1568     g_return_if_fail (IBUS_IS_BUS (bus));
1569
1570     ibus_bus_call_async (bus,
1571                          IBUS_SERVICE_IBUS,
1572                          IBUS_PATH_IBUS,
1573                          IBUS_INTERFACE_IBUS,
1574                          "ListEngines",
1575                          NULL,
1576                          G_VARIANT_TYPE ("(av)"),
1577                          ibus_bus_list_engines_async,
1578                          timeout_msec,
1579                          cancellable,
1580                          callback,
1581                          user_data);
1582 }
1583
1584 GList *
1585 ibus_bus_list_engines_async_finish (IBusBus      *bus,
1586                                     GAsyncResult *res,
1587                                     GError      **error)
1588 {
1589     GSimpleAsyncResult *simple = (GSimpleAsyncResult *) res;
1590     if (g_simple_async_result_propagate_error (simple, error))
1591         return NULL;
1592     GVariant *variant = g_simple_async_result_get_op_res_gpointer (simple);
1593     g_return_val_if_fail (variant != NULL, NULL);
1594
1595     GList *retval = NULL;
1596     GVariantIter *iter = NULL;
1597     g_variant_get (variant, "(av)", &iter);
1598     GVariant *var;
1599     while (g_variant_iter_loop (iter, "v", &var)) {
1600         IBusSerializable *serializable = ibus_serializable_deserialize (var);
1601         g_object_ref_sink (serializable);
1602         retval = g_list_append (retval, serializable);
1603     }
1604     g_variant_iter_free (iter);
1605     return retval;
1606 }
1607
1608 GList *
1609 ibus_bus_list_active_engines (IBusBus *bus)
1610 {
1611     return ibus_bus_do_list_engines (bus, TRUE);
1612 }
1613
1614 void
1615 ibus_bus_list_active_engines_async (IBusBus            *bus,
1616                                     gint                timeout_msec,
1617                                     GCancellable       *cancellable,
1618                                     GAsyncReadyCallback callback,
1619                                     gpointer            user_data)
1620 {
1621     g_return_if_fail (IBUS_IS_BUS (bus));
1622
1623     ibus_bus_call_async (bus,
1624                          IBUS_SERVICE_IBUS,
1625                          IBUS_PATH_IBUS,
1626                          IBUS_INTERFACE_IBUS,
1627                          "ListActiveEngines",
1628                          NULL,
1629                          G_VARIANT_TYPE ("(av)"),
1630                          ibus_bus_list_active_engines_async,
1631                          timeout_msec,
1632                          cancellable,
1633                          callback,
1634                          user_data);
1635 }
1636
1637 GList *
1638 ibus_bus_list_active_engines_async_finish (IBusBus      *bus,
1639                                            GAsyncResult *res,
1640                                            GError      **error)
1641 {
1642     return ibus_bus_list_engines_async_finish (bus, res, error);
1643 }
1644
1645 IBusEngineDesc **
1646 ibus_bus_get_engines_by_names (IBusBus             *bus,
1647                                const gchar * const *names)
1648 {
1649     g_return_val_if_fail (IBUS_IS_BUS (bus), NULL);
1650
1651     GVariant *result;
1652     result = ibus_bus_call_sync (bus,
1653                                  IBUS_SERVICE_IBUS,
1654                                  IBUS_PATH_IBUS,
1655                                  IBUS_INTERFACE_IBUS,
1656                                  "GetEnginesByNames",
1657                                  g_variant_new("(^as)", names),
1658                                  G_VARIANT_TYPE ("(av)"));
1659     if (result == NULL)
1660         return NULL;
1661
1662     GArray *array = g_array_new (TRUE, TRUE, sizeof (IBusEngineDesc *));
1663     GVariantIter *iter = NULL;
1664     g_variant_get (result, "(av)", &iter);
1665     GVariant *var;
1666     while (g_variant_iter_loop (iter, "v", &var)) {
1667         IBusEngineDesc *desc = (IBusEngineDesc *) ibus_serializable_deserialize (var);
1668         g_object_ref_sink (desc);
1669         g_array_append_val (array, desc);
1670     }
1671     g_variant_iter_free (iter);
1672     g_variant_unref (result);
1673
1674     return (IBusEngineDesc **)g_array_free (array, FALSE);
1675 }
1676
1677 static void
1678 _config_destroy_cb (IBusConfig *config,
1679                     IBusBus    *bus)
1680 {
1681     IBusBusPrivate *priv;
1682     priv = IBUS_BUS_GET_PRIVATE (bus);
1683
1684     g_assert (priv->config == config);
1685
1686     g_object_unref (config);
1687     priv->config = NULL;
1688 }
1689
1690 IBusConfig *
1691 ibus_bus_get_config (IBusBus *bus)
1692 {
1693     g_assert (IBUS_IS_BUS (bus));
1694     g_return_val_if_fail (ibus_bus_is_connected (bus), NULL);
1695
1696     IBusBusPrivate *priv;
1697     priv = IBUS_BUS_GET_PRIVATE (bus);
1698
1699     if (priv->config == NULL && priv->connection) {
1700         priv->config = ibus_config_new (priv->connection, NULL, NULL);
1701         if (priv->config) {
1702             g_signal_connect (priv->config, "destroy", G_CALLBACK (_config_destroy_cb), bus);
1703         }
1704     }
1705
1706     return priv->config;
1707 }
1708
1709 gboolean
1710 ibus_bus_get_use_sys_layout (IBusBus *bus)
1711 {
1712     g_return_val_if_fail (IBUS_IS_BUS (bus), FALSE);
1713
1714     gboolean retval = FALSE;
1715     GVariant *result;
1716     result = ibus_bus_call_sync (bus,
1717                                  IBUS_SERVICE_IBUS,
1718                                  IBUS_PATH_IBUS,
1719                                  IBUS_INTERFACE_IBUS,
1720                                  "GetUseSysLayout",
1721                                  NULL,
1722                                  G_VARIANT_TYPE ("(b)"));
1723
1724     if (result) {
1725         g_variant_get (result, "(b)", &retval);
1726         g_variant_unref (result);
1727     }
1728
1729     return retval;
1730 }
1731
1732 void
1733 ibus_bus_get_use_sys_layout_async (IBusBus            *bus,
1734                                    gint                timeout_msec,
1735                                    GCancellable       *cancellable,
1736                                    GAsyncReadyCallback callback,
1737                                    gpointer            user_data)
1738 {
1739     g_return_if_fail (IBUS_IS_BUS (bus));
1740
1741     ibus_bus_call_async (bus,
1742                          IBUS_SERVICE_IBUS,
1743                          IBUS_PATH_IBUS,
1744                          IBUS_INTERFACE_IBUS,
1745                          "GetUseSysLayout",
1746                          NULL,
1747                          G_VARIANT_TYPE ("(b)"),
1748                          ibus_bus_get_use_sys_layout_async,
1749                          timeout_msec,
1750                          cancellable,
1751                          callback,
1752                          user_data);
1753 }
1754
1755 gboolean
1756 ibus_bus_get_use_sys_layout_async_finish (IBusBus      *bus,
1757                                           GAsyncResult *res,
1758                                           GError      **error)
1759 {
1760     g_assert (IBUS_IS_BUS (bus));
1761     g_assert (g_simple_async_result_is_valid (res, (GObject *) bus,
1762                                               ibus_bus_get_use_sys_layout_async));
1763     return _async_finish_gboolean (res, error);
1764 }
1765
1766 gboolean
1767 ibus_bus_get_use_global_engine (IBusBus *bus)
1768 {
1769     g_return_val_if_fail (IBUS_IS_BUS (bus), FALSE);
1770
1771     gboolean retval = FALSE;
1772     GVariant *result;
1773     result = ibus_bus_call_sync (bus,
1774                                  IBUS_SERVICE_IBUS,
1775                                  IBUS_PATH_IBUS,
1776                                  IBUS_INTERFACE_IBUS,
1777                                  "GetUseGlobalEngine",
1778                                  NULL,
1779                                  G_VARIANT_TYPE ("(b)"));
1780
1781     if (result) {
1782         g_variant_get (result, "(b)", &retval);
1783         g_variant_unref (result);
1784     }
1785
1786     return retval;
1787 }
1788
1789 void
1790 ibus_bus_get_use_global_engine_async (IBusBus            *bus,
1791                                       gint                timeout_msec,
1792                                       GCancellable       *cancellable,
1793                                       GAsyncReadyCallback callback,
1794                                       gpointer            user_data)
1795 {
1796     g_return_if_fail (IBUS_IS_BUS (bus));
1797
1798     ibus_bus_call_async (bus,
1799                          IBUS_SERVICE_IBUS,
1800                          IBUS_PATH_IBUS,
1801                          IBUS_INTERFACE_IBUS,
1802                          "GetUseGlobalEngine",
1803                          NULL,
1804                          G_VARIANT_TYPE ("(b)"),
1805                          ibus_bus_get_use_global_engine_async,
1806                          timeout_msec,
1807                          cancellable,
1808                          callback,
1809                          user_data);
1810 }
1811
1812 gboolean
1813 ibus_bus_get_use_global_engine_async_finish (IBusBus      *bus,
1814                                              GAsyncResult *res,
1815                                              GError      **error)
1816 {
1817     g_assert (IBUS_IS_BUS (bus));
1818     g_assert (g_simple_async_result_is_valid (res, (GObject *) bus,
1819                                               ibus_bus_get_use_global_engine_async));
1820     return _async_finish_gboolean (res, error);
1821 }
1822
1823 gboolean
1824 ibus_bus_is_global_engine_enabled (IBusBus *bus)
1825 {
1826     g_return_val_if_fail (IBUS_IS_BUS (bus), FALSE);
1827
1828     gboolean retval = FALSE;
1829     GVariant *result;
1830     result = ibus_bus_call_sync (bus,
1831                                  IBUS_SERVICE_IBUS,
1832                                  IBUS_PATH_IBUS,
1833                                  IBUS_INTERFACE_IBUS,
1834                                  "IsGlobalEngineEnabled",
1835                                  NULL,
1836                                  G_VARIANT_TYPE ("(b)"));
1837
1838     if (result) {
1839         g_variant_get (result, "(b)", &retval);
1840         g_variant_unref (result);
1841     }
1842
1843     return retval;
1844 }
1845
1846 void ibus_bus_is_global_engine_enabled_async (IBusBus            *bus,
1847                                               gint                timeout_msec,
1848                                               GCancellable       *cancellable,
1849                                               GAsyncReadyCallback callback,
1850                                               gpointer            user_data)
1851 {
1852     g_return_if_fail (IBUS_IS_BUS (bus));
1853
1854     ibus_bus_call_async (bus,
1855                          IBUS_SERVICE_IBUS,
1856                          IBUS_PATH_IBUS,
1857                          IBUS_INTERFACE_IBUS,
1858                          "IsGlobalEngineEnabled",
1859                          NULL,
1860                          G_VARIANT_TYPE ("(b)"),
1861                          ibus_bus_is_global_engine_enabled_async,
1862                          timeout_msec,
1863                          cancellable,
1864                          callback,
1865                          user_data);
1866 }
1867
1868 gboolean ibus_bus_is_global_engine_enabled_async_finish (IBusBus      *bus,
1869                                                          GAsyncResult *res,
1870                                                          GError      **error)
1871 {
1872     g_assert (IBUS_IS_BUS (bus));
1873     g_assert (g_simple_async_result_is_valid (res, (GObject *) bus,
1874                                               ibus_bus_is_global_engine_enabled_async));
1875     return _async_finish_gboolean (res, error);
1876 }
1877
1878 IBusEngineDesc *
1879 ibus_bus_get_global_engine (IBusBus *bus)
1880 {
1881     g_return_val_if_fail (IBUS_IS_BUS (bus), NULL);
1882
1883     GVariant *result;
1884     IBusEngineDesc *engine = NULL;
1885     result = ibus_bus_call_sync (bus,
1886                                  IBUS_SERVICE_IBUS,
1887                                  IBUS_PATH_IBUS,
1888                                  IBUS_INTERFACE_IBUS,
1889                                  "GetGlobalEngine",
1890                                  NULL,
1891                                  G_VARIANT_TYPE ("(v)"));
1892
1893     if (result) {
1894         GVariant *variant = NULL;
1895         g_variant_get (result, "(v)", &variant);
1896         if (variant) {
1897             engine = IBUS_ENGINE_DESC (ibus_serializable_deserialize (variant));
1898             g_variant_unref (variant);
1899         }
1900         g_variant_unref (result);
1901     }
1902
1903     return engine;
1904 }
1905
1906 void
1907 ibus_bus_get_global_engine_async (IBusBus            *bus,
1908                                   gint                timeout_msec,
1909                                   GCancellable       *cancellable,
1910                                   GAsyncReadyCallback callback,
1911                                   gpointer            user_data)
1912 {
1913     g_return_if_fail (IBUS_IS_BUS (bus));
1914
1915     ibus_bus_call_async (bus,
1916                          IBUS_SERVICE_IBUS,
1917                          IBUS_PATH_IBUS,
1918                          IBUS_INTERFACE_IBUS,
1919                          "GetGlobalEngine",
1920                          NULL,
1921                          G_VARIANT_TYPE ("(v)"),
1922                          ibus_bus_get_global_engine_async,
1923                          timeout_msec,
1924                          cancellable,
1925                          callback,
1926                          user_data);
1927 }
1928
1929 IBusEngineDesc *
1930 ibus_bus_get_global_engine_async_finish (IBusBus      *bus,
1931                                          GAsyncResult *res,
1932                                          GError      **error)
1933 {
1934     GSimpleAsyncResult *simple = (GSimpleAsyncResult *) res;
1935     if (g_simple_async_result_propagate_error (simple, error))
1936         return NULL;
1937     GVariant *variant = g_simple_async_result_get_op_res_gpointer (simple);
1938     g_return_val_if_fail (variant != NULL, NULL);
1939     GVariant *inner_variant = NULL;
1940     g_variant_get (variant, "(v)", &inner_variant);
1941
1942     IBusEngineDesc *engine = NULL;
1943     if (inner_variant) {
1944         engine = IBUS_ENGINE_DESC (ibus_serializable_deserialize (inner_variant));
1945         g_variant_unref (inner_variant);
1946     }
1947     return engine;
1948 }
1949
1950 gboolean
1951 ibus_bus_set_global_engine (IBusBus     *bus,
1952                             const gchar *global_engine)
1953 {
1954     g_return_val_if_fail (IBUS_IS_BUS (bus), FALSE);
1955     g_return_val_if_fail (global_engine != NULL, FALSE);
1956
1957     GVariant *result;
1958     result = ibus_bus_call_sync (bus,
1959                                  IBUS_SERVICE_IBUS,
1960                                  IBUS_PATH_IBUS,
1961                                  IBUS_INTERFACE_IBUS,
1962                                  "SetGlobalEngine",
1963                                  g_variant_new ("(s)", global_engine),
1964                                  NULL);
1965
1966     if (result) {
1967         g_variant_unref (result);
1968         return TRUE;
1969     }
1970     return FALSE;
1971 }
1972
1973 void
1974 ibus_bus_set_global_engine_async (IBusBus            *bus,
1975                                   const gchar        *global_engine,
1976                                   gint                timeout_msec,
1977                                   GCancellable       *cancellable,
1978                                   GAsyncReadyCallback callback,
1979                                   gpointer            user_data)
1980 {
1981     g_return_if_fail (IBUS_IS_BUS (bus));
1982     g_return_if_fail (global_engine != NULL);
1983
1984     ibus_bus_call_async (bus,
1985                          IBUS_SERVICE_IBUS,
1986                          IBUS_PATH_IBUS,
1987                          IBUS_INTERFACE_IBUS,
1988                          "SetGlobalEngine",
1989                          g_variant_new ("(s)", global_engine),
1990                          NULL, /* no return value */
1991                          ibus_bus_set_global_engine_async,
1992                          timeout_msec,
1993                          cancellable,
1994                          callback,
1995                          user_data);
1996 }
1997
1998 gboolean
1999 ibus_bus_set_global_engine_async_finish (IBusBus      *bus,
2000                                          GAsyncResult *res,
2001                                          GError      **error)
2002 {
2003     g_assert (IBUS_IS_BUS (bus));
2004     g_assert (g_simple_async_result_is_valid (res, (GObject *) bus,
2005                                               ibus_bus_set_global_engine_async));
2006     return _async_finish_void (res, error);
2007 }
2008
2009 static GVariant *
2010 ibus_bus_call_sync (IBusBus            *bus,
2011                     const gchar        *bus_name,
2012                     const gchar        *path,
2013                     const gchar        *interface,
2014                     const gchar        *member,
2015                     GVariant           *parameters,
2016                     const GVariantType *reply_type)
2017 {
2018     g_assert (IBUS_IS_BUS (bus));
2019     g_assert (member != NULL);
2020     g_return_val_if_fail (ibus_bus_is_connected (bus), NULL);
2021
2022     GError *error = NULL;
2023     GVariant *result;
2024     result = g_dbus_connection_call_sync (bus->priv->connection,
2025                                           bus_name,
2026                                           path,
2027                                           interface,
2028                                           member,
2029                                           parameters,
2030                                           reply_type,
2031                                           G_DBUS_CALL_FLAGS_NO_AUTO_START,
2032                                           ibus_get_timeout (),
2033                                           NULL,
2034                                           &error);
2035
2036     if (result == NULL) {
2037         g_warning ("ibus_bus_call_sync: %s.%s: %s", interface, member, error->message);
2038         g_error_free (error);
2039         return NULL;
2040     }
2041
2042     return result;
2043 }
2044
2045 static void
2046 ibus_bus_call_async_done (GDBusConnection *connection,
2047                           GAsyncResult    *res,
2048                           gpointer         user_data)
2049 {
2050     g_assert (G_IS_DBUS_CONNECTION (connection));
2051
2052     GSimpleAsyncResult *simple = (GSimpleAsyncResult *) user_data;
2053     GError *error = NULL;
2054     GVariant *variant = g_dbus_connection_call_finish (connection, res, &error);
2055
2056     if (variant == NULL) {
2057         /* Replace with g_simple_async_result_take_error in glib 2.28 */
2058         g_simple_async_result_set_from_error (simple, error);
2059         g_error_free (error);
2060     }
2061     else {
2062         g_simple_async_result_set_op_res_gpointer (simple, variant,
2063                                                    (GDestroyNotify) g_variant_unref);
2064     }
2065     g_simple_async_result_complete (simple);
2066     g_object_unref (simple);
2067 }
2068
2069 static void
2070 ibus_bus_call_async (IBusBus            *bus,
2071                      const gchar        *bus_name,
2072                      const gchar        *path,
2073                      const gchar        *interface,
2074                      const gchar        *member,
2075                      GVariant           *parameters,
2076                      const GVariantType *reply_type,
2077                      gpointer            source_tag,
2078                      gint                timeout_msec,
2079                      GCancellable       *cancellable,
2080                      GAsyncReadyCallback callback,
2081                      gpointer            user_data)
2082 {
2083     g_assert (IBUS_IS_BUS (bus));
2084     g_assert (member != NULL);
2085     g_return_if_fail (ibus_bus_is_connected (bus));
2086
2087     GSimpleAsyncResult *simple = g_simple_async_result_new ((GObject*) bus,
2088                                                             callback,
2089                                                             user_data,
2090                                                             source_tag);
2091
2092     g_dbus_connection_call (bus->priv->connection,
2093                             bus_name,
2094                             path,
2095                             interface,
2096                             member,
2097                             parameters,
2098                             reply_type,
2099                             G_DBUS_CALL_FLAGS_NO_AUTO_START,
2100                             timeout_msec,
2101                             cancellable,
2102                             (GAsyncReadyCallback) ibus_bus_call_async_done,
2103                             simple);
2104 }