Add async version of set_global_engine.
authorYusuke Sato <yusukes@chromium.org>
Wed, 16 Feb 2011 14:42:27 +0000 (23:42 +0900)
committerYusuke Sato <yusukes@chromium.org>
Wed, 16 Feb 2011 14:42:27 +0000 (23:42 +0900)
Patch from Zach Kuznia <zork@chromium.org>, modified by Yusuke Sato <yusukes@chromium.org>.

Review URL: http://codereview.appspot.com/4175047

src/ibusbus.c
src/ibusbus.h

index 6370c51..36f36d4 100644 (file)
@@ -74,13 +74,25 @@ static void      ibus_bus_watch_dbus_signal     (IBusBus                *bus);
 static void      ibus_bus_unwatch_dbus_signal   (IBusBus                *bus);
 static void      ibus_bus_watch_ibus_signal     (IBusBus                *bus);
 static void      ibus_bus_unwatch_ibus_signal   (IBusBus                *bus);
-static GVariant *ibus_bus_call                  (IBusBus                *bus,
+static GVariant *ibus_bus_call_sync             (IBusBus                *bus,
                                                  const gchar            *service,
                                                  const gchar            *path,
                                                  const gchar            *interface,
                                                  const gchar            *member,
                                                  GVariant               *parameters,
                                                  const GVariantType     *reply_type);
+static void      ibus_bus_call_async             (IBusBus                *bus,
+                                                  const gchar            *service,
+                                                  const gchar            *path,
+                                                  const gchar            *interface,
+                                                  const gchar            *member,
+                                                  GVariant               *parameters,
+                                                  const GVariantType     *reply_type,
+                                                  gpointer                source_tag,
+                                                  gint                    timeout_msec,
+                                                  GCancellable           *cancellable,
+                                                  GAsyncReadyCallback     callback,
+                                                  gpointer                user_data);
 
 G_DEFINE_TYPE (IBusBus, ibus_bus, IBUS_TYPE_OBJECT)
 
@@ -419,13 +431,13 @@ ibus_bus_create_input_context (IBusBus      *bus,
     gchar *path;
     IBusInputContext *context = NULL;
     GVariant *result;
-    result = ibus_bus_call (bus,
-                            IBUS_SERVICE_IBUS,
-                            IBUS_PATH_IBUS,
-                            IBUS_INTERFACE_IBUS,
-                            "CreateInputContext",
-                            g_variant_new ("(s)", client_name),
-                            G_VARIANT_TYPE ("(o)"));
+    result = ibus_bus_call_sync (bus,
+                                 IBUS_SERVICE_IBUS,
+                                 IBUS_PATH_IBUS,
+                                 IBUS_INTERFACE_IBUS,
+                                 "CreateInputContext",
+                                 g_variant_new ("(s)", client_name),
+                                 G_VARIANT_TYPE ("(o)"));
 
     if (result != NULL) {
         GError *error = NULL;
@@ -449,13 +461,13 @@ ibus_bus_current_input_context (IBusBus      *bus)
 
     gchar *path = NULL;
     GVariant *result;
-    result = ibus_bus_call (bus,
-                            IBUS_SERVICE_IBUS,
-                            IBUS_PATH_IBUS,
-                            IBUS_INTERFACE_IBUS,
-                            "CurrentInputContext",
-                            NULL,
-                            G_VARIANT_TYPE ("(o)"));
+    result = ibus_bus_call_sync (bus,
+                                 IBUS_SERVICE_IBUS,
+                                 IBUS_PATH_IBUS,
+                                 IBUS_INTERFACE_IBUS,
+                                 "CurrentInputContext",
+                                 NULL,
+                                 G_VARIANT_TYPE ("(o)"));
 
     if (result != NULL) {
         g_variant_get (result, "(o)", &path);
@@ -584,13 +596,13 @@ ibus_bus_hello (IBusBus *bus)
     g_free (bus->priv->unique_name);
     bus->priv->unique_name = NULL;
 
-    result = ibus_bus_call (bus,
-                            DBUS_SERVICE_DBUS,
-                            DBUS_PATH_DBUS,
-                            DBUS_INTERFACE_DBUS,
-                            "Hello",
-                            NULL,
-                            G_VARIANT_TYPE ("(s)"));
+    result = ibus_bus_call_sync (bus,
+                                 DBUS_SERVICE_DBUS,
+                                 DBUS_PATH_DBUS,
+                                 DBUS_INTERFACE_DBUS,
+                                 "Hello",
+                                 NULL,
+                                 G_VARIANT_TYPE ("(s)"));
 
     if (result) {
         g_variant_get (result, "(s)", &bus->priv->unique_name);
@@ -611,13 +623,13 @@ ibus_bus_request_name (IBusBus      *bus,
 
     guint retval = 0;
     GVariant *result;
-    result = ibus_bus_call (bus,
-                            DBUS_SERVICE_DBUS,
-                            DBUS_PATH_DBUS,
-                            DBUS_INTERFACE_DBUS,
-                            "RequestName",
-                            g_variant_new ("(su)", name, flags),
-                            G_VARIANT_TYPE ("(u)"));
+    result = ibus_bus_call_sync (bus,
+                                 DBUS_SERVICE_DBUS,
+                                 DBUS_PATH_DBUS,
+                                 DBUS_INTERFACE_DBUS,
+                                 "RequestName",
+                                 g_variant_new ("(su)", name, flags),
+                                 G_VARIANT_TYPE ("(u)"));
 
     if (result) {
         g_variant_get (result, "(u)", &retval);
@@ -636,13 +648,13 @@ ibus_bus_release_name (IBusBus      *bus,
 
     guint retval = 0;
     GVariant *result;
-    result = ibus_bus_call (bus,
-                            DBUS_SERVICE_DBUS,
-                            DBUS_PATH_DBUS,
-                            DBUS_INTERFACE_DBUS,
-                            "ReleaseName",
-                            g_variant_new ("(s)", name),
-                            G_VARIANT_TYPE ("(u)"));
+    result = ibus_bus_call_sync (bus,
+                                 DBUS_SERVICE_DBUS,
+                                 DBUS_PATH_DBUS,
+                                 DBUS_INTERFACE_DBUS,
+                                 "ReleaseName",
+                                 g_variant_new ("(s)", name),
+                                 G_VARIANT_TYPE ("(u)"));
 
     if (result) {
         g_variant_get (result, "(u)", &retval);
@@ -661,13 +673,13 @@ ibus_bus_name_has_owner (IBusBus        *bus,
 
     gboolean retval = FALSE;
     GVariant *result;
-    result = ibus_bus_call (bus,
-                            DBUS_SERVICE_DBUS,
-                            DBUS_PATH_DBUS,
-                            DBUS_INTERFACE_DBUS,
-                            "NameHasOwner",
-                            g_variant_new ("(s)", name),
-                            G_VARIANT_TYPE ("(b)"));
+    result = ibus_bus_call_sync (bus,
+                                 DBUS_SERVICE_DBUS,
+                                 DBUS_PATH_DBUS,
+                                 DBUS_INTERFACE_DBUS,
+                                 "NameHasOwner",
+                                 g_variant_new ("(s)", name),
+                                 G_VARIANT_TYPE ("(b)"));
 
     if (result) {
         g_variant_get (result, "(b)", &retval);
@@ -692,13 +704,13 @@ ibus_bus_add_match (IBusBus     *bus,
     g_return_if_fail (rule != NULL);
 
     GVariant *result;
-    result = ibus_bus_call (bus,
-                            DBUS_SERVICE_DBUS,
-                            DBUS_PATH_DBUS,
-                            DBUS_INTERFACE_DBUS,
-                            "AddMatch",
-                            g_variant_new ("(s)", rule),
-                            NULL);
+    result = ibus_bus_call_sync (bus,
+                                 DBUS_SERVICE_DBUS,
+                                 DBUS_PATH_DBUS,
+                                 DBUS_INTERFACE_DBUS,
+                                 "AddMatch",
+                                 g_variant_new ("(s)", rule),
+                                 NULL);
 
     if (result) {
         g_variant_unref (result);
@@ -713,13 +725,13 @@ ibus_bus_remove_match (IBusBus      *bus,
     g_return_if_fail (rule != NULL);
 
     GVariant *result;
-    result = ibus_bus_call (bus,
-                            DBUS_SERVICE_DBUS,
-                            DBUS_PATH_DBUS,
-                            DBUS_INTERFACE_DBUS,
-                            "RemoveMatch",
-                            g_variant_new ("(s)", rule),
-                            NULL);
+    result = ibus_bus_call_sync (bus,
+                                 DBUS_SERVICE_DBUS,
+                                 DBUS_PATH_DBUS,
+                                 DBUS_INTERFACE_DBUS,
+                                 "RemoveMatch",
+                                 g_variant_new ("(s)", rule),
+                                 NULL);
 
     if (result) {
         g_variant_unref (result);
@@ -734,13 +746,13 @@ ibus_bus_get_name_owner (IBusBus        *bus,
 
     gchar *retval = NULL;
     GVariant *result;
-    result = ibus_bus_call (bus,
-                            DBUS_SERVICE_DBUS,
-                            DBUS_PATH_DBUS,
-                            DBUS_INTERFACE_DBUS,
-                            "GetNameOwner",
-                            g_variant_new ("(s)", name),
-                            G_VARIANT_TYPE ("(s)"));
+    result = ibus_bus_call_sync (bus,
+                                 DBUS_SERVICE_DBUS,
+                                 DBUS_PATH_DBUS,
+                                 DBUS_INTERFACE_DBUS,
+                                 "GetNameOwner",
+                                 g_variant_new ("(s)", name),
+                                 G_VARIANT_TYPE ("(s)"));
 
     if (result) {
         g_variant_get (result, "(s)", &retval);
@@ -765,13 +777,13 @@ ibus_bus_exit (IBusBus *bus,
     g_return_val_if_fail (IBUS_IS_BUS (bus), FALSE);
 
     GVariant *result;
-    result = ibus_bus_call (bus,
-                            IBUS_SERVICE_IBUS,
-                            IBUS_PATH_IBUS,
-                            IBUS_INTERFACE_IBUS,
-                            "Exit",
-                            g_variant_new ("(b)", restart),
-                            NULL);
+    result = ibus_bus_call_sync (bus,
+                                 IBUS_SERVICE_IBUS,
+                                 IBUS_PATH_IBUS,
+                                 IBUS_INTERFACE_IBUS,
+                                 "Exit",
+                                 g_variant_new ("(b)", restart),
+                                 NULL);
 
     if (result) {
         g_variant_unref (result);
@@ -788,13 +800,13 @@ ibus_bus_register_component (IBusBus       *bus,
     g_return_val_if_fail (IBUS_IS_COMPONENT (component), FALSE);
 
     GVariant *variant = ibus_serializable_serialize ((IBusSerializable *)component);
-    GVariant *result = ibus_bus_call (bus,
-                                      IBUS_SERVICE_IBUS,
-                                      IBUS_PATH_IBUS,
-                                      IBUS_INTERFACE_IBUS,
-                                      "RegisterComponent",
-                                      g_variant_new ("(v)", variant),
-                                      NULL);
+    GVariant *result = ibus_bus_call_sync (bus,
+                                           IBUS_SERVICE_IBUS,
+                                           IBUS_PATH_IBUS,
+                                           IBUS_INTERFACE_IBUS,
+                                           "RegisterComponent",
+                                           g_variant_new ("(v)", variant),
+                                           NULL);
     if (result) {
         g_variant_unref (result);
         return TRUE;
@@ -809,13 +821,13 @@ ibus_bus_do_list_engines (IBusBus *bus, gboolean active_engines_only)
 
     GList *retval = NULL;
     GVariant *result;
-    result = ibus_bus_call (bus,
-                            IBUS_SERVICE_IBUS,
-                            IBUS_PATH_IBUS,
-                            IBUS_INTERFACE_IBUS,
-                            active_engines_only ? "ListActiveEngines" : "ListEngines",
-                            NULL,
-                            G_VARIANT_TYPE ("(av)"));
+    result = ibus_bus_call_sync (bus,
+                                 IBUS_SERVICE_IBUS,
+                                 IBUS_PATH_IBUS,
+                                 IBUS_INTERFACE_IBUS,
+                                 active_engines_only ? "ListActiveEngines" : "ListEngines",
+                                 NULL,
+                                 G_VARIANT_TYPE ("(av)"));
 
     if (result) {
         GVariantIter *iter = NULL;
@@ -882,13 +894,13 @@ ibus_bus_get_use_sys_layout (IBusBus *bus)
 
     gboolean retval = FALSE;
     GVariant *result;
-    result = ibus_bus_call (bus,
-                            IBUS_SERVICE_IBUS,
-                            IBUS_PATH_IBUS,
-                            IBUS_INTERFACE_IBUS,
-                            "GetUseSysLayout",
-                            NULL,
-                            G_VARIANT_TYPE ("(b)"));
+    result = ibus_bus_call_sync (bus,
+                                 IBUS_SERVICE_IBUS,
+                                 IBUS_PATH_IBUS,
+                                 IBUS_INTERFACE_IBUS,
+                                 "GetUseSysLayout",
+                                 NULL,
+                                 G_VARIANT_TYPE ("(b)"));
 
     if (result) {
         g_variant_get (result, "(b)", &retval);
@@ -905,13 +917,13 @@ ibus_bus_get_use_global_engine (IBusBus *bus)
 
     gboolean retval = FALSE;
     GVariant *result;
-    result = ibus_bus_call (bus,
-                            IBUS_SERVICE_IBUS,
-                            IBUS_PATH_IBUS,
-                            IBUS_INTERFACE_IBUS,
-                            "GetUseGlobalEngine",
-                            NULL,
-                            G_VARIANT_TYPE ("(b)"));
+    result = ibus_bus_call_sync (bus,
+                                 IBUS_SERVICE_IBUS,
+                                 IBUS_PATH_IBUS,
+                                 IBUS_INTERFACE_IBUS,
+                                 "GetUseGlobalEngine",
+                                 NULL,
+                                 G_VARIANT_TYPE ("(b)"));
 
     if (result) {
         g_variant_get (result, "(b)", &retval);
@@ -928,13 +940,13 @@ ibus_bus_is_global_engine_enabled (IBusBus *bus)
 
     gboolean retval = FALSE;
     GVariant *result;
-    result = ibus_bus_call (bus,
-                            IBUS_SERVICE_IBUS,
-                            IBUS_PATH_IBUS,
-                            IBUS_INTERFACE_IBUS,
-                            "IsGlobalEngineEnabled",
-                            NULL,
-                            G_VARIANT_TYPE ("(b)"));
+    result = ibus_bus_call_sync (bus,
+                                 IBUS_SERVICE_IBUS,
+                                 IBUS_PATH_IBUS,
+                                 IBUS_INTERFACE_IBUS,
+                                 "IsGlobalEngineEnabled",
+                                 NULL,
+                                 G_VARIANT_TYPE ("(b)"));
 
     if (result) {
         g_variant_get (result, "(b)", &retval);
@@ -951,13 +963,13 @@ ibus_bus_get_global_engine (IBusBus *bus)
 
     GVariant *result;
     IBusEngineDesc *engine = NULL;
-    result = ibus_bus_call (bus,
-                            IBUS_SERVICE_IBUS,
-                            IBUS_PATH_IBUS,
-                            IBUS_INTERFACE_IBUS,
-                            "GetGlobalEngine",
-                            NULL,
-                            G_VARIANT_TYPE ("(v)"));
+    result = ibus_bus_call_sync (bus,
+                                 IBUS_SERVICE_IBUS,
+                                 IBUS_PATH_IBUS,
+                                 IBUS_INTERFACE_IBUS,
+                                 "GetGlobalEngine",
+                                 NULL,
+                                 G_VARIANT_TYPE ("(v)"));
 
     if (result) {
         GVariant *variant = NULL;
@@ -979,13 +991,13 @@ ibus_bus_set_global_engine (IBusBus     *bus,
     g_return_val_if_fail (IBUS_IS_BUS (bus), FALSE);
 
     GVariant *result;
-    result = ibus_bus_call (bus,
-                            IBUS_SERVICE_IBUS,
-                            IBUS_PATH_IBUS,
-                            IBUS_INTERFACE_IBUS,
-                            "SetGlobalEngine",
-                            g_variant_new ("(s)", global_engine),
-                            NULL);
+    result = ibus_bus_call_sync (bus,
+                                 IBUS_SERVICE_IBUS,
+                                 IBUS_PATH_IBUS,
+                                 IBUS_INTERFACE_IBUS,
+                                 "SetGlobalEngine",
+                                 g_variant_new ("(s)", global_engine),
+                                 NULL);
 
     if (result) {
         g_variant_unref (result);
@@ -994,14 +1006,53 @@ ibus_bus_set_global_engine (IBusBus     *bus,
     return FALSE;
 }
 
+void
+ibus_bus_set_global_engine_async (IBusBus            *bus,
+                                  const gchar        *global_engine,
+                                  gint                timeout_msec,
+                                  GCancellable       *cancellable,
+                                  GAsyncReadyCallback callback,
+                                  gpointer            user_data)
+{
+    g_return_if_fail (IBUS_IS_BUS (bus));
+
+    ibus_bus_call_async (bus,
+                         IBUS_SERVICE_IBUS,
+                         IBUS_PATH_IBUS,
+                         IBUS_INTERFACE_IBUS,
+                         "SetGlobalEngine",
+                         g_variant_new ("(s)", global_engine),
+                         NULL, /* no return value */
+                         ibus_bus_set_global_engine_async,
+                         timeout_msec,
+                         cancellable,
+                         callback,
+                         user_data);
+}
+
+gboolean
+ibus_bus_set_global_engine_async_finish (IBusBus      *bus,
+                                         GAsyncResult *res,
+                                         GError      **error)
+{
+    g_assert (IBUS_IS_BUS (bus));
+    g_assert (g_simple_async_result_is_valid (res, (GObject *) bus,
+                                              ibus_bus_set_global_engine_async));
+
+    GSimpleAsyncResult *simple = (GSimpleAsyncResult *) res;
+    if (g_simple_async_result_propagate_error (simple, error))
+        return FALSE;
+    return TRUE;
+}
+
 static GVariant *
-ibus_bus_call (IBusBus            *bus,
-               const gchar        *bus_name,
-               const gchar        *path,
-               const gchar        *interface,
-               const gchar        *member,
-               GVariant           *parameters,
-               const GVariantType *reply_type)
+ibus_bus_call_sync (IBusBus            *bus,
+                    const gchar        *bus_name,
+                    const gchar        *path,
+                    const gchar        *interface,
+                    const gchar        *member,
+                    GVariant           *parameters,
+                    const GVariantType *reply_type)
 {
     g_assert (IBUS_IS_BUS (bus));
     g_assert (member != NULL);
@@ -1029,3 +1080,65 @@ ibus_bus_call (IBusBus            *bus,
 
     return result;
 }
+
+static void
+ibus_bus_call_async_done (GDBusConnection *connection,
+                          GAsyncResult    *res,
+                          gpointer         user_data)
+{
+    g_assert (G_IS_DBUS_CONNECTION (connection));
+
+    GSimpleAsyncResult *simple = (GSimpleAsyncResult *) user_data;
+    GError *error = NULL;
+    GVariant *variant = g_dbus_connection_call_finish (connection, res, &error);
+
+    if (variant == NULL) {
+        /* Replace with g_simple_async_result_take_error in glib 2.28 */
+        g_simple_async_result_set_from_error (simple, error);
+        g_error_free (error);
+    }
+    else {
+        /* FIXME If we support IPCs other than ibus_bus_set_global_engine, we
+         * might have to call g_simple_async_result_set_op_res_XXX() here. */
+        g_variant_unref (variant);
+    }
+    g_simple_async_result_complete (simple);
+    g_object_unref (simple);
+}
+
+static void
+ibus_bus_call_async (IBusBus            *bus,
+                     const gchar        *bus_name,
+                     const gchar        *path,
+                     const gchar        *interface,
+                     const gchar        *member,
+                     GVariant           *parameters,
+                     const GVariantType *reply_type,
+                     gpointer            source_tag,
+                     gint                timeout_msec,
+                     GCancellable       *cancellable,
+                     GAsyncReadyCallback callback,
+                     gpointer            user_data)
+{
+    g_assert (IBUS_IS_BUS (bus));
+    g_assert (member != NULL);
+    g_return_if_fail (ibus_bus_is_connected (bus));
+
+    GSimpleAsyncResult *simple = g_simple_async_result_new ((GObject*) bus,
+                                                            callback,
+                                                            user_data,
+                                                            source_tag);
+
+    g_dbus_connection_call (bus->priv->connection,
+                            bus_name,
+                            path,
+                            interface,
+                            member,
+                            parameters,
+                            reply_type,
+                            G_DBUS_CALL_FLAGS_NO_AUTO_START,
+                            timeout_msec,
+                            cancellable,
+                            (GAsyncReadyCallback) ibus_bus_call_async_done,
+                            simple);
+}
index 255e8eb..0fc014a 100644 (file)
@@ -125,7 +125,9 @@ const gchar *ibus_bus_hello             (IBusBus        *bus);
  * @flags: Flags (FixMe).
  * @returns: 0 if failed; positive number otherwise.
  *
- * Request a name from IBus daemon.
+ * Request a name from IBus daemon synchronously.
+ *
+ * FIXME add an asynchronous version.
  */
 guint        ibus_bus_request_name      (IBusBus        *bus,
                                          const gchar    *name,
@@ -137,7 +139,9 @@ guint        ibus_bus_request_name      (IBusBus        *bus,
  * @name: Name to be released.
  * @returns: 0 if failed; positive number otherwise.
  *
- * Release a name to IBus daemon.
+ * Release a name to IBus daemon synchronously.
+ *
+ * FIXME add an asynchronous version.
  */
 guint        ibus_bus_release_name      (IBusBus        *bus,
                                          const gchar    *name);
@@ -148,7 +152,9 @@ guint        ibus_bus_release_name      (IBusBus        *bus,
  * @name: Name to be released.
  * @returns: TRUE if the name has owner, FALSE otherwise.
  *
- * Whether the name has owner.
+ * Whether the name has owner synchronously.
+ *
+ * FIXME add an asynchronous version.
  */
 gboolean     ibus_bus_name_has_owner    (IBusBus        *bus,
                                          const gchar    *name);
@@ -168,7 +174,9 @@ GList       *ibus_bus_list_names        (IBusBus        *bus);
  * @bus: An IBusBus.
  * @rule: Match rule.
  *
- * Add a match rule to an IBusBus.
+ * Add a match rule to an IBusBus synchronously.
+ *
+ * FIXME add an asynchronous version.
  */
 void         ibus_bus_add_match         (IBusBus        *bus,
                                          const gchar    *rule);
@@ -178,7 +186,9 @@ void         ibus_bus_add_match         (IBusBus        *bus,
  * @bus: An IBusBus.
  * @rule: Match rule.
  *
- * Remove a match rule to an IBusBus.
+ * Remove a match rule to an IBusBus synchronously.
+ *
+ * FIXME add an asynchronous version.
  */
 void         ibus_bus_remove_match      (IBusBus        *bus,
                                          const gchar    *rule);
@@ -189,7 +199,9 @@ void         ibus_bus_remove_match      (IBusBus        *bus,
  * @name: Name.
  * @returns: Owner of the name. The returned value must be freed with g_free().
  *
- * Return the name owner.
+ * Return the name owner synchronously.
+ *
+ * FIXME add an asynchronous version.
  */
 gchar       *ibus_bus_get_name_owner    (IBusBus        *bus,
                                          const gchar    *name);
@@ -201,7 +213,9 @@ gchar       *ibus_bus_get_name_owner    (IBusBus        *bus,
  * @restart: Whether restarting the ibus.
  * @returns: TRUE if the "Exit" call is suceeded, FALSE otherwise.
  *
- * Exit or restart an IBusBus.
+ * Exit or restart an IBusBus synchronously.
+ *
+ * FIXME add an asynchronous version.
  */
 gboolean     ibus_bus_exit              (IBusBus        *bus,
                                          gboolean        restart);
@@ -213,7 +227,9 @@ gboolean     ibus_bus_exit              (IBusBus        *bus,
  * @returns: An newly allocated IBusInputContext if the "CreateInputContext" call
  *            is suceeded, NULL otherwise.
  *
- * Create an input context for client.
+ * Create an input context for client synchronously.
+ *
+ * FIXME add an asynchronous version.
  */
 IBusInputContext
             *ibus_bus_create_input_context
@@ -228,7 +244,9 @@ IBusInputContext
  *            "CurrentInputContext" call suceeded, NULL otherwise. The return
  *            value must be freed with g_free().
  *
- * Get the current focused input context.
+ * Get the current focused input context synchronously.
+ *
+ * FIXME add an asynchronous version.
  */
 gchar       *ibus_bus_current_input_context(IBusBus        *bus);
 
@@ -239,7 +257,9 @@ gchar       *ibus_bus_current_input_context(IBusBus        *bus);
  * @component: A input engine component.
  * @returns: TRUE if the "RegisterComponent" call is suceeded, FALSE otherwise.
  *
- * Register a componet to an IBusBus.
+ * Register a componet to an IBusBus synchronously.
+ *
+ * FIXME add an asynchronous version.
  */
 gboolean     ibus_bus_register_component(IBusBus        *bus,
                                          IBusComponent  *component);
@@ -249,7 +269,9 @@ gboolean     ibus_bus_register_component(IBusBus        *bus,
  * @bus: An IBusBus.
  * @returns: (transfer container) (element-type IBusEngineDesc): A List of engines.
  *
- * List engines.
+ * List engines synchronously.
+ *
+ * FIXME add an asynchronous version.
  */
 GList       *ibus_bus_list_engines      (IBusBus        *bus);
 
@@ -258,7 +280,9 @@ GList       *ibus_bus_list_engines      (IBusBus        *bus);
  * @bus: An IBusBus.
  * @returns: (transfer container) (element-type IBusEngineDesc): A List of active engines.
  *
- * List active engines.
+ * List active engines synchronously.
+ *
+ * FIXME add an asynchronous version.
  */
 GList       *ibus_bus_list_active_engines
                                         (IBusBus        *bus);
@@ -268,7 +292,9 @@ GList       *ibus_bus_list_active_engines
  * @bus: An IBusBus.
  * @returns: TRUE if "use_sys_layout" option is enabled.
  *
- * Check if the bus's "use_sys_layout" option is enabled or not.
+ * Check if the bus's "use_sys_layout" option is enabled or not synchronously.
+ *
+ * FIXME add an asynchronous version.
  */
 gboolean     ibus_bus_get_use_sys_layout(IBusBus        *bus);
 
@@ -277,7 +303,9 @@ gboolean     ibus_bus_get_use_sys_layout(IBusBus        *bus);
  * @bus: An IBusBus.
  * @returns: TRUE if "use_global_engine" option is enabled.
  *
- * Check if the bus's "use_global_engine" option is enabled or not.
+ * Check if the bus's "use_global_engine" option is enabled or not synchronously.
+ *
+ * FIXME add an asynchronous version.
  */
 gboolean     ibus_bus_get_use_global_engine
                                         (IBusBus        *bus);
@@ -288,7 +316,9 @@ gboolean     ibus_bus_get_use_global_engine
  * @bus: An IBusBus.
  * @returns: TRUE if the current global engine is enabled.
  *
- * Check if the current global engine is enabled or not.
+ * Check if the current global engine is enabled or not synchronously.
+ *
+ * FIXME add an asynchronous version.
  */
 gboolean     ibus_bus_is_global_engine_enabled
                                         (IBusBus        *bus);
@@ -299,7 +329,7 @@ gboolean     ibus_bus_is_global_engine_enabled
  * @returns: The description of current global engine, or NULL if there is no
  * global engine.
  *
- * Get the description of current global engine.
+ * Get the description of current global engine synchronously.
  */
 IBusEngineDesc
             *ibus_bus_get_global_engine (IBusBus        *bus);
@@ -310,12 +340,45 @@ IBusEngineDesc
  * @global_engine: A new engine name.
  * @returns: TRUE if the global engine was set successfully.
  *
- * Set current global engine.
+ * Set current global engine synchronously.
  */
 gboolean     ibus_bus_set_global_engine (IBusBus        *bus,
                                          const gchar    *global_engine);
 
 /**
+ * ibus_bus_set_global_engine_async:
+ * @bus: An IBusBus.
+ * @global_engine: A new engine name.
+ * @timeout_msec: The timeout in milliseconds or -1 to use the default timeout.
+ * @cancellable: A GCancellable or NULL.
+ * @callback: A GAsyncReadyCallback to call when the request is satisfied or NULL
+ *      if you don't care about the result of the method invocation.
+ * @user_data: The data to pass to callback.
+ *
+ * Set current global engine asynchronously.
+ */
+void ibus_bus_set_global_engine_async (IBusBus            *bus,
+                                       const gchar        *global_engine,
+                                       gint                timeout_msec,
+                                       GCancellable       *cancellable,
+                                       GAsyncReadyCallback callback,
+                                       gpointer            user_data);
+
+/**
+ * ibus_bus_set_global_engine_async_finish:
+ * @bus: An IBusBus.
+ * @res: A GAsyncResult obtained from the GAsyncReadyCallback passed to
+ *   ibus_bus_set_global_engine().
+ * @error: Return location for error or NULL.
+ * @returns: TRUE if no IPC errros. FALSE otherwise.
+ *
+ * Finishes an operation started with ibus_bus_set_global_engine().
+ */
+gboolean ibus_bus_set_global_engine_async_finish (IBusBus      *bus,
+                                                  GAsyncResult *res,
+                                                  GError      **error);
+
+/**
  * ibus_bus_set_watch_dbus_signal:
  * @bus: An IBusBus.
  * @watch: TRUE if you want ibusbus to emit "name-owner-changed" signal when