Blob Blame Raw
From 9614076737ee88c092af209485d1d65d2269f4ad Mon Sep 17 00:00:00 2001
From: Tsuyoshi Horo <horo@chromium.org>
Date: Thu, 18 Aug 2011 11:48:30 -0400
Subject: [PATCH] Fix for ibus_serializable_{get,set}_attachment.

TEST=Linux desktop

Review URL: http://codereview.appspot.com/4905054
Patch from Tsuyoshi Horo <horo@chromium.org>.
---
 src/ibusserializable.c        |   18 +++++++++---------
 src/ibusserializable.h        |    3 +--
 src/tests/ibus-serializable.c |   34 ++++++++++++++++++++++++++++++++++
 3 files changed, 44 insertions(+), 11 deletions(-)

diff --git a/src/ibusserializable.c b/src/ibusserializable.c
index 2e4b21f..ed89534 100644
--- a/src/ibusserializable.c
+++ b/src/ibusserializable.c
@@ -164,7 +164,7 @@ _g_value_serialize (GValue          *value)
         {                                                               \
             g##_type v;                                                 \
             v = g_value_get_##_type (value);                            \
-            return g_variant_new ("v", g_variant_new (signature, v));   \
+            return g_variant_new (signature, v);                        \
         }
     CASE_ENTRY(CHAR, char, "y");
     CASE_ENTRY(BOOLEAN, boolean, "b");
@@ -198,14 +198,14 @@ _g_value_deserialize (GVariant *variant)
     }
 
     typedef gchar *gstring;
-#define IF_ENTRY(TYPE, _type, signature)                    \
-    if (type ==  G_VARIANT_TYPE_##TYPE) {                   \
-        g##_type v;                                         \
-        g_variant_get (variant, signature, &v);             \
-        value = g_slice_new0 (GValue);                      \
-        g_value_init (value, G_TYPE_##TYPE);                \
-        g_value_set_##_type (value, v);                     \
-        return value;                                       \
+#define IF_ENTRY(TYPE, _type, signature)                      \
+    if (g_variant_type_equal(type, G_VARIANT_TYPE_##TYPE)) {  \
+        g##_type v;                                           \
+        g_variant_get (variant, signature, &v);               \
+        value = g_slice_new0 (GValue);                        \
+        g_value_init (value, G_TYPE_##TYPE);                  \
+        g_value_set_##_type (value, v);                       \
+        return value;                                         \
     }
 #define G_VARIANT_TYPE_CHAR G_VARIANT_TYPE_BYTE
     IF_ENTRY(CHAR, char, "y");
diff --git a/src/ibusserializable.h b/src/ibusserializable.h
index 358af32..8fd9f8a 100644
--- a/src/ibusserializable.h
+++ b/src/ibusserializable.h
@@ -87,12 +87,11 @@
  * ibus_serializable_get_attachment:
  * @o: An IBusSerializable.
  * @k: String formatted key for indexing value.
- * @v: Value to be attached. Should be also serializable.
  *
  * Get a value from attachment of an IBusSerializable.
  * This macro is an convenient wrapper of ibus_serializable_get_qattachment().
  */
-#define ibus_serializable_get_attachment(o, k, v)  \
+#define ibus_serializable_get_attachment(o, k)  \
     ibus_serializable_get_qattachment (o, g_quark_from_string (k))
 
 /**
diff --git a/src/tests/ibus-serializable.c b/src/tests/ibus-serializable.c
index c2a7529..e2541ec 100644
--- a/src/tests/ibus-serializable.c
+++ b/src/tests/ibus-serializable.c
@@ -128,6 +128,39 @@ test_property (void)
     g_variant_type_info_assert_no_infos ();
 }
 
+static void
+test_attachment (void)
+{
+    IBusText *text =  ibus_text_new_from_string ("main text");
+
+    GValue value1 = { 0 };
+    g_value_init(&value1, G_TYPE_INT);
+    g_value_set_int(&value1, 100);
+    ibus_serializable_set_attachment ((IBusSerializable *)text, "key1", &value1);
+
+    GValue value2 = { 0 };
+    g_value_init(&value2, G_TYPE_STRING);
+    g_value_set_string(&value2, "value string");
+    ibus_serializable_set_attachment ((IBusSerializable *)text, "key2", &value2);
+
+    GVariant *variant = ibus_serializable_serialize ((IBusSerializable *)text);
+    g_object_unref ((IBusSerializable *)text);
+
+    IBusSerializable *object = (IBusSerializable *) ibus_serializable_deserialize (variant);
+    g_variant_unref (variant);
+
+    g_assert_cmpstr (((IBusText *)object)->text, ==, "main text");
+
+    const GValue *newvalue1 = ibus_serializable_get_attachment (object, "key1");
+    g_assert (newvalue1 != NULL);
+    g_assert (g_value_get_int (newvalue1) == 100);
+
+    const GValue *newvalue2 = ibus_serializable_get_attachment (object, "key2");
+    g_assert (newvalue2 != NULL);
+    g_assert_cmpstr (g_value_get_string (newvalue2), ==, "value string");
+
+    g_variant_type_info_assert_no_infos ();
+}
 
 gint
 main (gint    argc,
@@ -142,6 +175,7 @@ main (gint    argc,
     g_test_add_func ("/ibus/enginedesc", test_engine_desc);
     g_test_add_func ("/ibus/lookuptable", test_lookup_table);
     g_test_add_func ("/ibus/property", test_property);
+    g_test_add_func ("/ibus/attachment", test_attachment);
 
     return g_test_run ();
 }
-- 
1.7.5.4

From ac9dfac13cef34288440a2ecdf067cd827fb2f8f Mon Sep 17 00:00:00 2001
From: Peng Huang <shawn.p.huang@gmail.com>
Date: Fri, 19 Aug 2011 08:23:33 -0400
Subject: [PATCH] Use GVariant as attachment for IBusSerializable.

BUG=None
TEST=Linux desktop

Review URL: http://codereview.appspot.com/4902051
---
 src/ibusserializable.c        |  176 ++++++-----------------------------------
 src/ibusserializable.h        |   81 +++++++++----------
 src/tests/ibus-serializable.c |   47 ++++++++----
 3 files changed, 98 insertions(+), 206 deletions(-)

diff --git a/src/ibusserializable.c b/src/ibusserializable.c
index ed89534..6251c89 100644
--- a/src/ibusserializable.c
+++ b/src/ibusserializable.c
@@ -124,114 +124,13 @@ ibus_serializable_destroy (IBusSerializable *serializable)
     parent_class->destroy (IBUS_OBJECT (serializable));
 }
 
-static GValue *
-ibus_g_value_dup (const GValue *value)
-{
-    GValue *new_value;
-
-    new_value = g_slice_new0 (GValue);
-    g_value_init (new_value, G_VALUE_TYPE (value));
-    g_value_copy (value, new_value);
-
-    return new_value;
-}
-
-static void
-ibus_g_value_free (GValue *value)
-{
-    g_value_unset (value);
-    g_slice_free (GValue, value);
-}
-
-static GVariant *
-_g_value_serialize (GValue          *value)
-{
-    GType type;
-
-    type = G_VALUE_TYPE (value);
-    g_return_val_if_fail (type != G_TYPE_INVALID, FALSE);
-
-    if (g_type_is_a (type, IBUS_TYPE_SERIALIZABLE)) {
-        IBusSerializable *object;
-        object = IBUS_SERIALIZABLE (g_value_get_object (value));
-        return ibus_serializable_serialize (object);
-    }
-
-    typedef const gchar *gstring;
-    switch (type) {
-#define CASE_ENTRY(TYPE, _type, signature)                              \
-    case G_TYPE_##TYPE:                                                 \
-        {                                                               \
-            g##_type v;                                                 \
-            v = g_value_get_##_type (value);                            \
-            return g_variant_new (signature, v);                        \
-        }
-    CASE_ENTRY(CHAR, char, "y");
-    CASE_ENTRY(BOOLEAN, boolean, "b");
-    CASE_ENTRY(INT, int, "i");
-    CASE_ENTRY(UINT, uint, "u");
-    CASE_ENTRY(INT64, int64,  "x");
-    CASE_ENTRY(UINT64, uint64, "t");
-    CASE_ENTRY(FLOAT, float,  "d");
-    CASE_ENTRY(DOUBLE, double, "d");
-    CASE_ENTRY(STRING, string, "s");
-#undef CASE_ENTRY
-    }
-
-    g_assert_not_reached ();
-}
-
-static GValue *
-_g_value_deserialize (GVariant *variant)
-{
-    GValue *value = NULL;
-    const GVariantType *type;
-
-    type = g_variant_get_type (variant);
-    if (type == G_VARIANT_TYPE_TUPLE) {
-        IBusSerializable *object;
-        object = ibus_serializable_deserialize (variant);
-        value = g_slice_new0 (GValue);
-        g_value_init (value, G_OBJECT_TYPE (object));
-        g_value_take_object (value, object);
-        return value;
-    }
-
-    typedef gchar *gstring;
-#define IF_ENTRY(TYPE, _type, signature)                      \
-    if (g_variant_type_equal(type, G_VARIANT_TYPE_##TYPE)) {  \
-        g##_type v;                                           \
-        g_variant_get (variant, signature, &v);               \
-        value = g_slice_new0 (GValue);                        \
-        g_value_init (value, G_TYPE_##TYPE);                  \
-        g_value_set_##_type (value, v);                       \
-        return value;                                         \
-    }
-#define G_VARIANT_TYPE_CHAR G_VARIANT_TYPE_BYTE
-    IF_ENTRY(CHAR, char, "y");
-#undef G_VARIANT_TYPE_CHAR
-    IF_ENTRY(BOOLEAN, boolean, "b");
-#define G_VARIANT_TYPE_INT G_VARIANT_TYPE_INT32
-#define G_VARIANT_TYPE_UINT G_VARIANT_TYPE_UINT32
-    IF_ENTRY(INT, int, "i");
-    IF_ENTRY(UINT, uint, "u");
-#undef G_VARIANT_TYPE_INT
-#undef G_VARIANT_TYPE_UINT
-    IF_ENTRY(INT64, int64, "x");
-    IF_ENTRY(UINT64, uint64, "t");
-    IF_ENTRY(DOUBLE, double, "d");
-    IF_ENTRY(STRING, string, "s");
-
-    g_return_val_if_reached (NULL);
-}
-
 static void
 _serialize_cb (GQuark           key,
-               GValue          *value,
+               GVariant        *value,
                GVariantBuilder *array)
 {
     g_variant_builder_add (array, "{sv}",
-                g_quark_to_string (key), _g_value_serialize (value));
+                g_quark_to_string (key), g_variant_new_variant (value));
 }
 
 static gboolean
@@ -257,21 +156,26 @@ ibus_serializable_real_deserialize (IBusSerializable *object,
     GVariantIter *iter = NULL;
     g_variant_get_child (variant, 1, "a{sv}", &iter);
     while (g_variant_iter_loop (iter, "{&sv}", &key, &value)) {
-        ibus_serializable_set_attachment (object, key, _g_value_deserialize (value));
+        GVariant *attachment = g_variant_get_variant (value);
+        ibus_serializable_set_attachment (object,
+                                          key,
+                                          attachment);
+        g_variant_unref (attachment);
+        g_variant_unref (value);
     }
     g_variant_iter_free (iter);
     return 2;
 }
 
 static void
-_copy_cb (GQuark   key,
-          GValue  *value,
-          GData  **datalist)
+_copy_cb (GQuark     key,
+          GVariant  *value,
+          GData    **datalist)
 {
     g_datalist_id_set_data_full (datalist,
                                  key,
-                                 ibus_g_value_dup (value),
-                                 (GDestroyNotify) ibus_g_value_free);
+                                 g_variant_ref (value),
+                                 (GDestroyNotify) g_variant_unref);
 }
 
 static gboolean
@@ -289,50 +193,21 @@ ibus_serializable_real_copy (IBusSerializable *dest,
     return TRUE;
 }
 
-gboolean
-ibus_serializable_set_qattachment (IBusSerializable *object,
+void
+ibus_serializable_set_qattachment (IBusSerializable *serializable,
                                    GQuark            key,
-                                   const GValue     *value)
+                                   GVariant         *value)
 {
-    g_return_val_if_fail (IBUS_IS_SERIALIZABLE (object), FALSE);
-    g_return_val_if_fail (key != 0, FALSE);
-    g_return_val_if_fail (G_IS_VALUE (value), FALSE);
-
-    IBusSerializablePrivate *priv;
-    priv = IBUS_SERIALIZABLE_GET_PRIVATE (object);
-
-    GType type = G_VALUE_TYPE (value);
-
-    switch (type) {
-    case G_TYPE_CHAR:
-    case G_TYPE_INT:
-    case G_TYPE_INT64:
-    case G_TYPE_UINT:
-    case G_TYPE_UINT64:
-    case G_TYPE_BOOLEAN:
-    case G_TYPE_DOUBLE:
-    case G_TYPE_FLOAT:
-    case G_TYPE_STRING:
-        g_datalist_id_set_data_full (&priv->attachments,
-                                      key,
-                                      ibus_g_value_dup (value),
-                                      (GDestroyNotify) ibus_g_value_free);
-        return TRUE;
-    }
-
-    if (g_type_is_a (type, IBUS_TYPE_SERIALIZABLE)) {
-        g_datalist_id_set_data_full (&priv->attachments,
-                                      key,
-                                      ibus_g_value_dup (value),
-                                      (GDestroyNotify) ibus_g_value_free);
-        return TRUE;
-    }
+    g_return_if_fail (IBUS_IS_SERIALIZABLE (serializable));
+    g_return_if_fail (key != 0);
 
-    g_warning ("The value of %s is not support serializing", g_type_name (type));
-    return FALSE;
+    g_datalist_id_set_data_full (&serializable->priv->attachments,
+                                 key,
+                                 value ? g_variant_ref_sink (value) : NULL,
+                                 (GDestroyNotify) g_variant_unref);
 }
 
-const GValue *
+GVariant *
 ibus_serializable_get_qattachment (IBusSerializable *serializable,
                                    GQuark            key)
 {
@@ -340,7 +215,8 @@ ibus_serializable_get_qattachment (IBusSerializable *serializable,
     g_return_val_if_fail (IBUS_IS_SERIALIZABLE (serializable), NULL);
     g_return_val_if_fail (key != 0, NULL);
 
-    return (const GValue *) g_datalist_id_get_data (&serializable->priv->attachments, key);
+    return (GVariant *) g_datalist_id_get_data (
+            &serializable->priv->attachments, key);
 }
 
 void
@@ -351,7 +227,7 @@ ibus_serializable_remove_qattachment (IBusSerializable *serializable,
     g_return_if_fail (IBUS_IS_SERIALIZABLE (serializable));
     g_return_if_fail (key != 0);
 
-    g_datalist_id_remove_no_notify (&serializable->priv->attachments, key);
+    g_datalist_id_set_data (&serializable->priv->attachments, key, NULL);
 }
 
 IBusSerializable *
diff --git a/src/ibusserializable.h b/src/ibusserializable.h
index 8fd9f8a..7a100c2 100644
--- a/src/ibusserializable.h
+++ b/src/ibusserializable.h
@@ -126,39 +126,40 @@ struct _IBusSerializable {
 
 /**
  * IBusSerializableSerializeFunc:
- * @object: An IBusSerializable.
- * @iter: An IBusMessageIter.
- * @returns: TRUE if succeed; FALSE otherwise.
+ * @serializable: An #IBusSerializable.
+ * @builder: A #GVariantBuilder.
+ * @returns: %TRUE if succeed; %FALSE otherwise.
  *
  * Prototype of serialize function.
  * Serialize function convert an IBusSerializable to IBusMessageIter.
  * Returns a gboolean value which indicates whether the conversion is success.
- * Return TRUE if succeed.
+ * Return %TRUE if succeed.
  */
-typedef gboolean    (* IBusSerializableSerializeFunc)   (IBusSerializable       *object,
+typedef gboolean    (* IBusSerializableSerializeFunc)   (IBusSerializable       *serializable,
                                                          GVariantBuilder        *builder);
 
 /**
  * IBusSerializableDeserializeFunc:
- * @object: An IBusSerializable.
- * @iter: An IBusMessageIter.
- * @returns: TRUE if succeed; FALSE otherwise.
+ * @serializable: An #IBusSerializable.
+ * @variant: A #GVariant contains a tuple.
+ * @returns: The number of values in the variant(tuple) are consumed.
  *
  * Prototype of deserialize function.
  * Deserialize function convert an IBusMessageIter to IBusSerializable.
- * Returns a gboolean value which indicates whether the conversion is success.
+ * Returns an integer value which indicates how many values in
+ * the variant(tuple) are consumed.
  */
-typedef gint        (* IBusSerializableDeserializeFunc) (IBusSerializable       *object,
+typedef gint        (* IBusSerializableDeserializeFunc) (IBusSerializable       *serializable,
                                                          GVariant               *variant);
 
 /**
  * IBusSerializableCopyFunc:
- * @dest: The destination IBusSerializable.
- * @src: A source IBusMessageIter.
- * @returns: TRUE if succeed; FALSE otherwise.
+ * @dest: The destination #IBusSerializable.
+ * @src: A source #IBusMessageIter.
+ * @returns: %TRUE if succeed; %FALSE otherwise.
  *
  * Prototype of copy function.
- * Copy function copy from source IBusSerializable to the destination one.
+ * Copy function copy from source #IBusSerializable to the destination one.
  * Returns a gboolean value which indicates whether the copying is success.
  */
 typedef gboolean    (* IBusSerializableCopyFunc)        (IBusSerializable       *dest,
@@ -188,79 +189,77 @@ GType                ibus_serializable_get_type         (void);
  *
  * Returns: a new instance of #IBusSerializable.
  */
-IBusSerializable *   ibus_serializable_new              (void);
+IBusSerializable    *ibus_serializable_new              (void);
 
 /**
  * ibus_serializable_set_qattachment:
- * @object: An IBusSerializable.
+ * @serializable: An #IBusSerializable.
  * @key: String formatted key for indexing value.
- * @value: Value to be attached. Should be also serializable.
- * @returns: TRUE if succeed; FALSE otherwise.
+ * @value: Value to be attached or %NULL to remove any prevoius value.
  *
- * Attach a value to an IBusSerializable. The value should be serializable as well.
- * Basic type such as integer, string are deemed to be serializable.
+ * Attach a value to an IBusSerializable. If the value is floating,
+ * the serializable will take the ownership.
  *
  * @see_also: ibus_serializable_set_attachment().
  */
-gboolean             ibus_serializable_set_qattachment  (IBusSerializable   *object,
+void                 ibus_serializable_set_qattachment  (IBusSerializable   *serializable,
                                                          GQuark              key,
-                                                         const GValue       *value);
+                                                         GVariant           *value);
 
 /**
  * ibus_serializable_get_qattachment:
- * @object: An IBusSerializable.
+ * @serializable: An #IBusSerializable.
  * @key: String formatted key for indexing value.
- * @returns: The attached value; or NULL if fail to retrieve the value.
+ * @returns: The attached value; or %NULL if fail to retrieve the value.
  *
- * Get a value from attachment of an IBusSerializable.
+ * Get a value from attachment of an #IBusSerializable.
  * @see_also: ibus_serializable_set_attachment().
  */
-const GValue        *ibus_serializable_get_qattachment  (IBusSerializable   *object,
+GVariant            *ibus_serializable_get_qattachment  (IBusSerializable   *serializable,
                                                          GQuark              key);
 
 /**
  * ibus_serializable_remove_qattachment:
- * @object: An IBusSerializable.
+ * @serializable: An #IBusSerializable.
  * @key: String formatted key for indexing value.
  *
- * Remove a value from attachment of an IBusSerializable.
+ * Remove a value from attachment of an #IBusSerializable.
  * @see_also: ibus_serializable_remove_attachment().
  */
 void                 ibus_serializable_remove_qattachment
-                                                        (IBusSerializable   *object,
+                                                        (IBusSerializable   *serializable,
                                                          GQuark              key);
 
 /**
  * ibus_serializable_copy:
- * @object: An IBusSerializable.
- * @returns: A newly allocated clone object; or NULL if @object is not serializable.
+ * @serializable: An #IBusSerializable.
+ * @returns: A newly allocated clone object; or %NULL if @object is not serializable.
  *
- * Clone an IBusSerializable.
+ * Clone an #IBusSerializable.
  * The copy method should be implemented in extended class.
  *
  * @see_also: IBusSerializableCopyFunc().
  */
-IBusSerializable    *ibus_serializable_copy             (IBusSerializable   *object);
+IBusSerializable    *ibus_serializable_copy             (IBusSerializable   *serializable);
 
 /**
  * ibus_serializable_serialize:
- * @object: An IBusSerializable.
- * @iter: An IBusMessageIter.
- * @returns: TRUE if succeed; FALSE otherwise.
+ * @serializable: An #IBusSerializable.
+ * @returns: A #GVariant.
  *
- * Serialize an IBusSerializable to an IBusMessageIter.
+ * Serialize an #IBusSerializable to a #GVariant.
  * The serialize method should be implemented in extended class.
  *
  * @see_also: IBusSerializableCopyFunc().
  */
-GVariant            *ibus_serializable_serialize        (IBusSerializable   *object);
+GVariant            *ibus_serializable_serialize        (IBusSerializable   *serializable);
 
 /**
  * ibus_serializable_deserialize:
- * @iter: An IBusMessageIter.
- * @returns: The deserialized IBusSerializable.
+ * @variant: A #GVariant.
+ * @returns: The deserialized #IBusSerializable.
  *
- * Deserialize an IBusMessageIter to an IBusSerializable/
+ * Deserialize a #GVariant to an #IBusSerializable/
  * The deserialize method should be implemented in extended class.
  *
  * @see_also: IBusSerializableCopyFunc().
diff --git a/src/tests/ibus-serializable.c b/src/tests/ibus-serializable.c
index e2541ec..d2bd61a 100644
--- a/src/tests/ibus-serializable.c
+++ b/src/tests/ibus-serializable.c
@@ -12,7 +12,7 @@ void test_serializable (IBusSerializable *object)
     g_variant_get_data (variant);
     s1 = g_variant_print (variant, TRUE);
 
-    object = (IBusSerializable *) ibus_serializable_deserialize (variant);
+    object = ibus_serializable_deserialize (variant);
     g_variant_unref (variant);
 
     variant = ibus_serializable_serialize (object);
@@ -131,34 +131,51 @@ test_property (void)
 static void
 test_attachment (void)
 {
-    IBusText *text =  ibus_text_new_from_string ("main text");
+    IBusText *text =  ibus_text_new_from_static_string ("main text");
 
-    GValue value1 = { 0 };
-    g_value_init(&value1, G_TYPE_INT);
-    g_value_set_int(&value1, 100);
-    ibus_serializable_set_attachment ((IBusSerializable *)text, "key1", &value1);
+    ibus_serializable_set_attachment ((IBusSerializable *)text,
+                                      "key1",
+                                      g_variant_new_int32 (100));
 
-    GValue value2 = { 0 };
-    g_value_init(&value2, G_TYPE_STRING);
-    g_value_set_string(&value2, "value string");
-    ibus_serializable_set_attachment ((IBusSerializable *)text, "key2", &value2);
+    ibus_serializable_set_attachment ((IBusSerializable *)text,
+                                      "key2",
+                                      g_variant_new_string ("value string"));
+
+    ibus_serializable_set_attachment ((IBusSerializable *)text,
+                                      "key3",
+                                      g_variant_new ("(iuds)",1, 2, 3.333, "test value"));
 
     GVariant *variant = ibus_serializable_serialize ((IBusSerializable *)text);
     g_object_unref ((IBusSerializable *)text);
 
-    IBusSerializable *object = (IBusSerializable *) ibus_serializable_deserialize (variant);
+    IBusSerializable *object = ibus_serializable_deserialize (variant);
     g_variant_unref (variant);
 
     g_assert_cmpstr (((IBusText *)object)->text, ==, "main text");
 
-    const GValue *newvalue1 = ibus_serializable_get_attachment (object, "key1");
+    GVariant *newvalue1 = ibus_serializable_get_attachment (object, "key1");
     g_assert (newvalue1 != NULL);
-    g_assert (g_value_get_int (newvalue1) == 100);
+    g_assert_cmpint (g_variant_get_int32 (newvalue1), ==, 100);
 
-    const GValue *newvalue2 = ibus_serializable_get_attachment (object, "key2");
+    GVariant *newvalue2 = ibus_serializable_get_attachment (object, "key2");
     g_assert (newvalue2 != NULL);
-    g_assert_cmpstr (g_value_get_string (newvalue2), ==, "value string");
+    g_assert_cmpstr (g_variant_get_string (newvalue2, NULL), ==, "value string");
+
+    {
+        GVariant *newvalue3 = ibus_serializable_get_attachment (object, "key3");
+        g_assert (newvalue3 != NULL);
+        gint32 i;
+        guint32 u;
+        gdouble d;
+        const gchar *s;
+        g_variant_get (newvalue3, "(iud&s)", &i, &u, &d, &s);
+        g_assert_cmpint (i, ==, 1);
+        g_assert_cmpuint (u, ==, 2);
+        g_assert_cmpfloat (d, ==, 3.333);
+        g_assert_cmpstr (s, ==, "test value");
+    }
 
+    g_object_unref (object);
     g_variant_type_info_assert_no_infos ();
 }
 
-- 
1.7.5.4

From adcf71e6e5de45530a09e7b9f310f2e489cd9631 Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Wed, 24 Aug 2011 11:44:21 +0900
Subject: [PATCH] Check if BusInputContext has an enabled engine in global
 input method.

BUG=RH#731610
TEST=Linux desktop

Review URL: http://codereview.appspot.com/4917041
---
 bus/ibusimpl.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/bus/ibusimpl.c b/bus/ibusimpl.c
index 853465c..1942504 100644
--- a/bus/ibusimpl.c
+++ b/bus/ibusimpl.c
@@ -1176,12 +1176,14 @@ bus_ibus_impl_set_focused_context (BusIBusImpl     *ibus,
     }
 
     BusEngineProxy *engine = NULL;
+    gboolean is_enabled = FALSE;
 
     if (ibus->focused_context) {
         if (ibus->use_global_engine) {
             /* dettach engine from the focused context */
             engine = bus_input_context_get_engine (ibus->focused_context);
             if (engine) {
+                is_enabled = bus_input_context_is_enabled (ibus->focused_context);
                 g_object_ref (engine);
                 bus_input_context_set_engine (ibus->focused_context, NULL);
             }
@@ -1203,7 +1205,9 @@ bus_ibus_impl_set_focused_context (BusIBusImpl     *ibus,
         /* attach engine to the focused context */
         if (engine != NULL) {
             bus_input_context_set_engine (context, engine);
-            bus_input_context_enable (context);
+            if (is_enabled) {
+                bus_input_context_enable (context);
+            }
             g_object_unref (engine);
         }
 
-- 
1.7.5.4

From 894ecc8e16b01d5594ef9b8f9c5530bb2e9d0502 Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Thu, 25 Aug 2011 09:59:42 +0900
Subject: [PATCH] Add Disable signal when
 bus_ibus_impl_set_context_engine_from_desc is called.

BUG=#1261
TEST=Linux desktop

Review URL: http://codereview.appspot.com/4875049
---
 bus/inputcontext.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/bus/inputcontext.c b/bus/inputcontext.c
index 723b5fd..3c81688 100644
--- a/bus/inputcontext.c
+++ b/bus/inputcontext.c
@@ -2292,6 +2292,8 @@ new_engine_cb (GObject             *obj,
                                              "Opertation was cancelled");
         }
         else {
+            /* Let BusEngineProxy call a Disable signal. */
+            bus_input_context_disable (data->context);
             bus_input_context_set_engine (data->context, engine);
             g_object_unref (engine);
             bus_input_context_enable (data->context);
-- 
1.7.5.4

From 34518370fbb5f69f8dfa2153d0d0da4473d0344d Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Wed, 7 Sep 2011 15:09:01 +0900
Subject: [PATCH] Added get methods for the members in IBusAttribute for non-C
 language.

---
 src/ibusattribute.c |   24 ++++++++++++++++++++++++
 src/ibusattribute.h |   39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+), 0 deletions(-)

diff --git a/src/ibusattribute.c b/src/ibusattribute.c
index 816bcee..aac14d4 100644
--- a/src/ibusattribute.c
+++ b/src/ibusattribute.c
@@ -124,6 +124,30 @@ ibus_attribute_new (guint type,
     return attr;
 }
 
+guint
+ibus_attribute_get_attr_type (IBusAttribute *attr)
+{
+    return attr->type;
+}
+
+guint
+ibus_attribute_get_value (IBusAttribute *attr)
+{
+    return attr->value;
+}
+
+guint
+ibus_attribute_get_start_index (IBusAttribute *attr)
+{
+    return attr->start_index;
+}
+
+guint
+ibus_attribute_get_end_index (IBusAttribute *attr)
+{
+    return attr->end_index;
+}
+
 IBusAttribute *
 ibus_attr_underline_new (guint underline_type,
                          guint start_index,
diff --git a/src/ibusattribute.h b/src/ibusattribute.h
index 2628415..f44860c 100644
--- a/src/ibusattribute.h
+++ b/src/ibusattribute.h
@@ -138,6 +138,45 @@ IBusAttribute       *ibus_attribute_new         (guint           type,
                                                  guint           value,
                                                  guint           start_index,
                                                  guint           end_index);
+
+/**
+ * ibus_attribute_get_attr_type:
+ * @returns: An enum of IBusAttrType.
+ *
+ * Returns an enum of IBusAttrType.
+ */
+guint                ibus_attribute_get_attr_type
+                                                (IBusAttribute *attr);
+
+/**
+ * ibus_attribute_get_value:
+ * @returns: An unsigned int value relative with IBusAttrType.
+ *
+ * Returns an unsigned int value relative with IBusAttrType.
+ * If the type is IBUS_ATTR_TYPE_UNDERLINE, the return value is
+ * IBusAttrUnderline. If the type is IBUS_ATTR_TYPE_FOREGROUND,
+ * the return value is the color RGB.
+ */
+guint                ibus_attribute_get_value   (IBusAttribute *attr);
+
+/**
+ * ibus_attribute_get_start_index:
+ * @returns: A start unsigned index
+ *
+ * Returns a start unsigned index
+ */
+guint                ibus_attribute_get_start_index
+                                                (IBusAttribute *attr);
+
+/**
+ * ibus_attribute_get_end_index:
+ * @returns: A end unsigned index
+ *
+ * Returns a end unsigned index
+ */
+guint                ibus_attribute_get_end_index
+                                                (IBusAttribute *attr);
+
 /**
  * ibus_attr_underline_new:
  * @underline_type: Type of underline.
-- 
1.7.5.4