Implemented some methods of IBusBus and IBusInputContext from yusukes@chromium.org
authorPeng Huang <shawn.p.huang@gmail.com>
Tue, 8 Dec 2009 09:29:14 +0000 (17:29 +0800)
committerPeng Huang <shawn.p.huang@gmail.com>
Tue, 8 Dec 2009 09:29:14 +0000 (17:29 +0800)
src/Makefile.am
src/ibusbus.c
src/ibusinputcontext.c
src/ibusinputcontext.h
src/test-bus.c

index da964e3d670af7e620ab3821bf470eac1727c8fd..c1f78ce95f81f39b4999e5e8cf5a06c071683fa1 100644 (file)
@@ -165,6 +165,7 @@ AM_LDFLAGS = \
        $(NULL)
 
 TESTS = \
+       test-bus \
        test-text \
        test-keymap \
        test-keynames \
index 4f80f7b664f95d43a014931d4a2b5eef0fcb21d7..f3b1fa8c4e66aa4baf8d8a818d599950dbaec74a 100644 (file)
@@ -27,6 +27,8 @@
 #include "ibusinternal.h"
 #include "ibusshare.h"
 #include "ibusconnection.h"
+#include "ibusenginedesc.h"
+#include "ibusserializable.h"
 #include "ibusconfig.h"
 
 #define IBUS_BUS_GET_PRIVATE(o)  \
@@ -782,16 +784,87 @@ ibus_bus_register_component (IBusBus       *bus,
 #endif
 }
 
+static GList *
+ibus_bus_do_list_engines (IBusBus *bus, gboolean active_engines_only)
+{
+    g_assert (IBUS_IS_BUS (bus));
+
+    IBusMessage *message, *reply;
+    IBusError *error;
+    gboolean retval;
+    IBusBusPrivate *priv;
+    IBusMessageIter iter, subiter;
+    GList *engines;
+    const gchar* member = active_engines_only ? "ListActiveEngines" : "ListEngines";
+
+    priv = IBUS_BUS_GET_PRIVATE (bus);
+    message = ibus_message_new_method_call (IBUS_SERVICE_IBUS,
+                                            IBUS_PATH_IBUS,
+                                            IBUS_INTERFACE_IBUS,
+                                            member);
+    reply = ibus_connection_send_with_reply_and_block (priv->connection,
+                                                       message,
+                                                       -1,
+                                                       &error);
+    ibus_message_unref (message);
+
+    if (reply == NULL) {
+        g_warning ("%s : %s", error->name, error->message);
+        ibus_error_free (error);
+        return NULL;
+    }
+
+    if ((error = ibus_error_new_from_message (reply)) != NULL) {
+        g_warning ("%s : %s", error->name, error->message);
+        ibus_error_free (error);
+        ibus_message_unref (reply);
+        return NULL;
+    }
+
+    retval = ibus_message_iter_init (reply, &iter);
+    if (!retval) {
+        error = ibus_error_new_from_printf (DBUS_ERROR_INVALID_ARGS,
+                                            "Message does not have arguments!");
+        g_warning ("%s : %s", error->name, error->message);
+        ibus_error_free (error);
+        ibus_message_unref (reply);
+        return NULL;
+    }
+
+    if (!ibus_message_iter_recurse (&iter, IBUS_TYPE_ARRAY, &subiter)) {
+        ibus_message_unref (reply);
+        return NULL;
+    }
+
+    if (dbus_message_iter_get_array_len (&subiter) <= 0) {
+        ibus_message_unref (reply);
+        return NULL;
+    }
+
+    engines = NULL;
+    do {
+        IBusSerializable *object = NULL;
+        if (!ibus_message_iter_get (&subiter, IBUS_TYPE_ENGINE_DESC, &object) || !object) {
+            g_warning ("Unexpected type is returned from %s", member);
+            continue;
+        }
+        engines = g_list_append (engines, object);
+    } while (ibus_message_iter_next (&subiter));
+
+    ibus_message_unref (reply);
+    return engines;
+}
+
 GList *
 ibus_bus_list_engines (IBusBus *bus)
 {
-    return NULL;
+    return ibus_bus_do_list_engines (bus, FALSE);
 }
 
 GList *
 ibus_bus_list_active_engines (IBusBus *bus)
 {
-    return NULL;
+    return ibus_bus_do_list_engines (bus, TRUE);
 }
 
 static void
index 1dbb6302839bdbfb7d13ddf9b6da3bd2ce8803b2..359c7979edcab77dad5edb71259f0a40f3be7ed1 100644 (file)
@@ -55,7 +55,7 @@ enum {
 
 /* BusInputContextPriv */
 struct _IBusInputContextPrivate {
-    void *pad;
+    gboolean own;
 };
 typedef struct _IBusInputContextPrivate IBusInputContextPrivate;
 
@@ -114,6 +114,19 @@ ibus_input_context_new (const gchar     *path,
     return IBUS_INPUT_CONTEXT (obj);
 }
 
+IBusInputContext *
+ibus_input_context_get_input_context (const gchar        *path,
+                                      IBusConnection     *connection)
+{
+    IBusInputContext *context = ibus_input_context_new (path, connection);
+    IBusInputContextPrivate *priv;
+    if (!context)
+        return NULL;
+    priv = IBUS_INPUT_CONTEXT_GET_PRIVATE (context);
+    priv->own = FALSE;
+    return context;
+}
+
 static void
 ibus_input_context_class_init (IBusInputContextClass *klass)
 {
@@ -472,12 +485,16 @@ ibus_input_context_init (IBusInputContext *context)
 {
     IBusInputContextPrivate *priv;
     priv = IBUS_INPUT_CONTEXT_GET_PRIVATE (context);
+    priv->own = TRUE;
 }
 
 static void
 ibus_input_context_real_destroy (IBusInputContext *context)
 {
-    if (ibus_proxy_get_connection ((IBusProxy *) context) != NULL) {
+    IBusInputContextPrivate *priv;
+    priv = IBUS_INPUT_CONTEXT_GET_PRIVATE (context);
+
+    if (priv->own && ibus_proxy_get_connection ((IBusProxy *) context) != NULL) {
         ibus_proxy_call (IBUS_PROXY (context),
                          "Destroy",
                          G_TYPE_INVALID);
@@ -844,6 +861,84 @@ ibus_input_context_property_hide (IBusInputContext *context,
                      G_TYPE_INVALID);
 }
 
+gboolean
+ibus_input_context_is_enabled (IBusInputContext *context)
+{
+    g_assert (IBUS_IS_INPUT_CONTEXT (context));
+    gboolean retval = FALSE;
+
+    IBusMessage *reply_message;
+    IBusError *error = NULL;
+
+    reply_message = ibus_proxy_call_with_reply_and_block ((IBusProxy *) context,
+                                                          "IsEnabled",
+                                                          -1,
+                                                          &error,
+                                                          G_TYPE_INVALID);
+    if (!reply_message) {
+        g_debug ("%s: %s", error->name, error->message);
+        ibus_error_free (error);
+        return FALSE;
+    }
+
+    if (!ibus_message_get_args (reply_message,
+                                &error,
+                                G_TYPE_BOOLEAN, &retval,
+                                G_TYPE_INVALID)) {
+        g_debug ("%s: %s", error->name, error->message);
+        ibus_error_free (error);
+        retval = FALSE;
+    }
+    ibus_message_unref (reply_message);
+
+    return retval;
+}
+
+IBusEngineDesc *
+ibus_input_context_get_engine (IBusInputContext *context)
+{
+    g_assert (IBUS_IS_INPUT_CONTEXT (context));
+    IBusMessage *reply_message;
+    IBusError *error = NULL;
+    IBusSerializable *object = NULL;
+
+    reply_message = ibus_proxy_call_with_reply_and_block ((IBusProxy *) context,
+                                                          "GetEngine",
+                                                          -1,
+                                                          &error,
+                                                          G_TYPE_INVALID);
+    if (!reply_message) {
+        g_debug ("%s: %s", error->name, error->message);
+        ibus_error_free (error);
+        return NULL;
+    }
+
+    if (!ibus_message_get_args (reply_message,
+                                &error,
+                                IBUS_TYPE_ENGINE_DESC, &object,
+                                G_TYPE_INVALID)) {
+        g_debug ("%s: %s", error->name, error->message);
+        ibus_error_free (error);
+        ibus_message_unref (reply_message);
+        return NULL;
+    }
+    ibus_message_unref (reply_message);
+
+    return IBUS_ENGINE_DESC (object);
+}
+
+void
+ibus_input_context_set_engine (IBusInputContext *context,
+                               const gchar *name)
+{
+    g_assert (IBUS_IS_INPUT_CONTEXT (context));
+
+    ibus_proxy_call ((IBusProxy *) context,
+                     "SetEngine",
+                     G_TYPE_STRING, &name,
+                     G_TYPE_INVALID);
+}
+
 #define DEFINE_FUNC(name,Name)                              \
     void                                                    \
     ibus_input_context_##name (IBusInputContext *context)   \
index 006921c52fb6b3a6f34afabe46e3d8952091036c..8e2f625d662d3f5d4ad4dd6bffbbde0c0d0a3ee3 100644 (file)
@@ -34,6 +34,7 @@
 #define __IBUS_INPUT_CONTEXT_H_
 
 #include "ibusproxy.h"
+#include "ibusenginedesc.h"
 
 /*
  * Type macros.
@@ -90,6 +91,20 @@ GType        ibus_input_context_get_type    (void);
 IBusInputContext
             *ibus_input_context_new         (const gchar        *path,
                                              IBusConnection     *connection);
+
+/**
+ * ibus_input_context_get_input_context:
+ * @path: The path to the object that emitting the signal.
+ * @connection: An IBusConnection.
+ * @returns: An existing IBusInputContext.
+ *
+ * Gets an existing IBusInputContext.
+ */
+IBusInputContext
+            *ibus_input_context_get_input_context
+                                            (const gchar        *path,
+                                             IBusConnection     *connection);
+
 /**
  * ibus_input_context_process_key_event:
  * @context: An IBusInputContext.
@@ -206,6 +221,35 @@ void         ibus_input_context_enable      (IBusInputContext   *context);
  */
 void         ibus_input_context_disable     (IBusInputContext   *context);
 
+
+/**
+ * ibus_input_context_is_ensabled:
+ * @context: An IBusInputContext.
+ *
+ * Returns TRUE if the IME is enabled on the context.
+ */
+gboolean     ibus_input_context_is_enabled  (IBusInputContext   *context);
+
+/**
+ * ibus_input_context_disable:
+ * @context: An IBusInputContext.
+ *
+ * Returns an IME engine description for the context.
+ */
+IBusEngineDesc
+            *ibus_input_context_get_engine  (IBusInputContext   *context);
+
+/**
+ * ibus_input_context_set_engine:
+ * @context: An IBusInputContext.
+ * @name: A name of the engine.
+ *
+ * Invoked when the IME engine is changed.
+ */
+void         ibus_input_context_set_engine  (IBusInputContext   *context,
+                                             const gchar *name);
+
+
 G_END_DECLS
 #endif
 
index a7756fa55925e880e195edcda4f9fb52cadc9748..b4b442247ef60b108351121a86ceacbb6b9a6651 100644 (file)
@@ -1,22 +1,76 @@
+#include <string.h>
 #include "ibus.h"
 
+static const char *
+get_last_engine_id (const GList *engines)
+{
+    g_assert (engines);
+    const char *result = NULL;
+    for (; engines; engines = g_list_next (engines)) {
+       IBusEngineDesc *engine_desc = IBUS_ENGINE_DESC (engines->data);
+       g_assert (engine_desc);
+       result = engine_desc->name;
+    }
+    g_assert (result);
+    return g_strdup (result);
+}
+
+static void
+print_engines (const GList *engines)
+{
+    g_assert (engines);
+    for (; engines; engines = g_list_next (engines)) {
+       IBusEngineDesc *engine_desc = IBUS_ENGINE_DESC (engines->data);
+       g_assert (engine_desc);
+       g_debug ("%s (id:%s, icon:%s)", engine_desc->longname, engine_desc->name, engine_desc->icon);
+       g_object_unref (engine_desc);
+    }
+}
+
 int main()
 {
        g_type_init ();
 
-       GMainLoop *mainloop;
        IBusBus *bus;
+       GList *engines;
        IBusInputContext *context;
+       IBusEngineDesc *engine_desc;
+       const char *active_engine_name;
 
-       mainloop = g_main_loop_new (NULL, FALSE);
        bus = ibus_bus_new ();
+
+       /* Test ibusbus.c */
+       g_debug ("===== Active engines:");
+       engines = ibus_bus_list_active_engines (bus);
+       g_assert (engines);
+       active_engine_name = get_last_engine_id (engines);
+       print_engines (engines);
+       g_list_free (engines);
+
+       g_debug ("===== All engines:");
+       engines = ibus_bus_list_engines (bus);
+       g_assert (engines);
+       print_engines (engines);
+       g_list_free (engines);
+       g_debug ("Test ibusbus.c: passed.");
+
+       /* Test ibusinputcontext.c */
        context = ibus_bus_create_input_context (bus, "test");
        ibus_input_context_set_capabilities (context, 0);
-       ibus_input_context_destroy (context);
+       ibus_input_context_disable (context);
+       g_assert (ibus_input_context_is_enabled (context) == FALSE);
+       ibus_input_context_enable (context);
+       g_assert (ibus_input_context_is_enabled (context) == TRUE);
+       ibus_input_context_set_engine (context, active_engine_name);
+       engine_desc = ibus_input_context_get_engine (context);
+       g_assert (engine_desc);
+       g_assert (!strcmp (active_engine_name, engine_desc->name));
+       g_debug ("Test ibusinputcontext.c: passed.");
+
+       g_free (active_engine_name);
+       g_object_unref (engine_desc);
        g_object_unref (context);
        g_object_unref (bus);
 
-       g_main_loop_run (mainloop);
-
        return 0;
 }