summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2005-07-09 01:46:51 +0000
committerColin Walters <walters@verbum.org>2005-07-09 01:46:51 +0000
commit0ccef79d7e9d1b19cdb10b3a147b64b41686905d (patch)
tree78df63d544586877804afe2cdef873f20771ce0d
parentd8e7405eb35974518b0b579e2e2789fd065cb477 (diff)
2005-07-08 Colin Walters <walters@verbum.org>
* test/glib/test-service-glib.xml: * test/glib/test-service-glib.c: * test/glib/test-dbus-glib.c: Test a{sv}. * glib/examples/statemachine/statemachine.c: * glib/examples/statemachine/statemachine-server.c: * glib/examples/statemachine/statemachine-client.c: Fix some bugs, add progress bar, etc. * glib/dbus-gvalue.c (register_array, register_dict): Delete; not needed anymore due to generic array/map marshalling. (dbus_g_value_types_init): Don't register basic arrays or the string/string hash. (dbus_gtype_from_signature_iter): Don't try to recurse into variants. (dbus_gtype_to_signature): Check collection/map before type metadata. (demarshal_garray_basic): Renamed to demarshal_collection_array. (demarshal_ghashtable): Renamed to demarshal_map; fix to use new generic map creation/append functions instead of hash table specifically. (get_type_demarshaller): Handle maps. (demarshal_collection): Dispatch on collection type to either demarshal_collection_ptrarray or demarshal_collection_array. (get_type_marshaller): Handle maps. (marshal_collection): Dispatch collection type to either marshal_collection_ptrarray or marshal_collection_array. (_dbus_gvalue_test): New test. * glib/dbus-gvalue-utils.c (unset_and_free_g_value): New function. (hash_free_from_gtype): Use it to free GValues. (hashtable_append): New function. (ptrarray_append): Fix prototype. (slist_append): Ditto. (_dbus_gvalue_utils_test): Extend tests. * glib/dbus-gtype-specialized.c (dbus_g_type_specialized_init_append): Renamed from dbus_g_type_specialized_collection_init_append. Remove const from value, since we steal it. (dbus_g_type_specialized_map_append): New function. * glib/dbus-gtype-specialized.h: Update prototypes. Add DBusGTypeSpecializedMapAppendFunc. * glib/dbus-gtest.c (dbus_glib_internal_do_not_use_run_tests): Run _dbus_gvalue_test. * glib/dbus-gtest.h: Prototype it.
-rw-r--r--ChangeLog52
-rw-r--r--glib/dbus-gtest.c4
-rw-r--r--glib/dbus-gtest.h1
-rw-r--r--glib/dbus-gtype-specialized.c13
-rw-r--r--glib/dbus-gtype-specialized.h15
-rw-r--r--glib/dbus-gvalue-utils.c116
-rw-r--r--glib/dbus-gvalue.c402
-rw-r--r--glib/examples/statemachine/statemachine-client.c192
-rw-r--r--glib/examples/statemachine/statemachine-server.c27
-rw-r--r--glib/examples/statemachine/statemachine.c44
-rw-r--r--test/glib/test-dbus-glib.c60
-rw-r--r--test/glib/test-service-glib.c34
-rw-r--r--test/glib/test-service-glib.xml5
13 files changed, 706 insertions, 259 deletions
diff --git a/ChangeLog b/ChangeLog
index 9ad68040..f98a6e76 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,55 @@
+2005-07-08 Colin Walters <walters@verbum.org>
+
+ * test/glib/test-service-glib.xml:
+ * test/glib/test-service-glib.c:
+ * test/glib/test-dbus-glib.c: Test a{sv}.
+
+ * glib/examples/statemachine/statemachine.c:
+ * glib/examples/statemachine/statemachine-server.c:
+ * glib/examples/statemachine/statemachine-client.c: Fix some bugs,
+ add progress bar, etc.
+
+ * glib/dbus-gvalue.c (register_array, register_dict): Delete; not
+ needed anymore due to generic array/map marshalling.
+ (dbus_g_value_types_init): Don't register basic arrays or the
+ string/string hash.
+ (dbus_gtype_from_signature_iter): Don't try to recurse into
+ variants.
+ (dbus_gtype_to_signature): Check collection/map before type
+ metadata.
+ (demarshal_garray_basic): Renamed to demarshal_collection_array.
+ (demarshal_ghashtable): Renamed to demarshal_map; fix to use new
+ generic map creation/append functions instead of hash table
+ specifically.
+ (get_type_demarshaller): Handle maps.
+ (demarshal_collection): Dispatch on collection type to either
+ demarshal_collection_ptrarray or demarshal_collection_array.
+ (get_type_marshaller): Handle maps.
+ (marshal_collection): Dispatch collection type to either
+ marshal_collection_ptrarray or marshal_collection_array.
+ (_dbus_gvalue_test): New test.
+
+ * glib/dbus-gvalue-utils.c (unset_and_free_g_value): New function.
+ (hash_free_from_gtype): Use it to free GValues.
+ (hashtable_append): New function.
+ (ptrarray_append): Fix prototype.
+ (slist_append): Ditto.
+ (_dbus_gvalue_utils_test): Extend tests.
+
+ * glib/dbus-gtype-specialized.c
+ (dbus_g_type_specialized_init_append): Renamed from
+ dbus_g_type_specialized_collection_init_append. Remove const from
+ value, since we steal it.
+ (dbus_g_type_specialized_map_append): New function.
+
+ * glib/dbus-gtype-specialized.h: Update prototypes.
+ Add DBusGTypeSpecializedMapAppendFunc.
+
+ * glib/dbus-gtest.c (dbus_glib_internal_do_not_use_run_tests): Run
+ _dbus_gvalue_test.
+
+ * glib/dbus-gtest.h: Prototype it.
+
2005-07-08 Ross Burton <ross@openedhand.com>
* dbus/dbus-glib.h:
diff --git a/glib/dbus-gtest.c b/glib/dbus-gtest.c
index 2b79feb4..e5c2e8b9 100644
--- a/glib/dbus-gtest.c
+++ b/glib/dbus-gtest.c
@@ -63,6 +63,10 @@ dbus_glib_internal_do_not_use_run_tests (const char *test_data_dir)
if (!_dbus_gvalue_utils_test (test_data_dir))
die ("gvalue utils");
+ printf ("%s: running GValue tests\n", "dbus-glib-test");
+ if (!_dbus_gvalue_test (test_data_dir))
+ die ("gvalue utils");
+
printf ("%s: running glib tests\n", "dbus-glib-test");
if (!_dbus_glib_test (test_data_dir))
die ("glib");
diff --git a/glib/dbus-gtest.h b/glib/dbus-gtest.h
index 73bf0dda..75633ea7 100644
--- a/glib/dbus-gtest.h
+++ b/glib/dbus-gtest.h
@@ -30,6 +30,7 @@ gboolean _dbus_gmain_test (const char *test_data_dir);
gboolean _dbus_gobject_test (const char *test_data_dir);
gboolean _dbus_gutils_test (const char *test_data_dir);
gboolean _dbus_glib_test (const char *test_data_dir);
+gboolean _dbus_gvalue_test (const char *test_data_dir);
gboolean _dbus_gvalue_utils_test (const char *test_data_dir);
void dbus_glib_internal_do_not_use_run_tests (const char *test_data_dir);
diff --git a/glib/dbus-gtype-specialized.c b/glib/dbus-gtype-specialized.c
index d588fa86..ccf65eef 100644
--- a/glib/dbus-gtype-specialized.c
+++ b/glib/dbus-gtype-specialized.c
@@ -427,7 +427,7 @@ typedef struct {
} DBusGTypeSpecializedAppendContextReal;
void
-dbus_g_type_specialized_collection_init_append (GValue *value, DBusGTypeSpecializedAppendContext *ctx)
+dbus_g_type_specialized_init_append (GValue *value, DBusGTypeSpecializedAppendContext *ctx)
{
DBusGTypeSpecializedAppendContextReal *realctx = (DBusGTypeSpecializedAppendContextReal *) ctx;
GType gtype;
@@ -446,7 +446,7 @@ dbus_g_type_specialized_collection_init_append (GValue *value, DBusGTypeSpeciali
void
dbus_g_type_specialized_collection_append (DBusGTypeSpecializedAppendContext *ctx,
- const GValue *elt)
+ GValue *elt)
{
DBusGTypeSpecializedAppendContextReal *realctx = (DBusGTypeSpecializedAppendContextReal *) ctx;
((DBusGTypeSpecializedCollectionVtable *) realctx->specdata->klass->vtable)->append_func (ctx, elt);
@@ -461,6 +461,15 @@ dbus_g_type_specialized_collection_end_append (DBusGTypeSpecializedAppendContext
}
void
+dbus_g_type_specialized_map_append (DBusGTypeSpecializedAppendContext *ctx,
+ GValue *key,
+ GValue *val)
+{
+ DBusGTypeSpecializedAppendContextReal *realctx = (DBusGTypeSpecializedAppendContextReal *) ctx;
+ ((DBusGTypeSpecializedMapVtable *) realctx->specdata->klass->vtable)->append_func (ctx, key, val);
+}
+
+void
dbus_g_type_map_value_iterate (const GValue *value,
DBusGTypeSpecializedMapIterator iterator,
gpointer user_data)
diff --git a/glib/dbus-gtype-specialized.h b/glib/dbus-gtype-specialized.h
index 8e47db98..e95af3e5 100644
--- a/glib/dbus-gtype-specialized.h
+++ b/glib/dbus-gtype-specialized.h
@@ -58,12 +58,17 @@ typedef struct {
gpointer d;
} DBusGTypeSpecializedAppendContext;
-void dbus_g_type_specialized_collection_init_append (GValue *val, DBusGTypeSpecializedAppendContext *ctx);
+void dbus_g_type_specialized_init_append (GValue *val, DBusGTypeSpecializedAppendContext *ctx);
-void dbus_g_type_specialized_collection_append (DBusGTypeSpecializedAppendContext *ctx, const GValue *elt);
+void dbus_g_type_specialized_collection_append (DBusGTypeSpecializedAppendContext *ctx, GValue *elt);
void dbus_g_type_specialized_collection_end_append (DBusGTypeSpecializedAppendContext *ctx);
+void dbus_g_type_specialized_map_append (DBusGTypeSpecializedAppendContext *ctx,
+ GValue *key,
+ GValue *val);
+
+
gboolean dbus_g_type_collection_get_fixed (GValue *value,
gpointer *data,
guint *len);
@@ -90,8 +95,8 @@ typedef struct {
} DBusGTypeSpecializedVtable;
typedef gboolean (*DBusGTypeSpecializedCollectionFixedAccessorFunc) (GType type, gpointer instance, gpointer *values, guint *len);
-typedef void (*DBusGTypeSpecializedCollectionIteratorFunc) (GType type, gpointer instance, DBusGTypeSpecializedCollectionIterator iterator, gpointer user_data);
-typedef void (*DBusGTypeSpecializedCollectionAppendFunc) (DBusGTypeSpecializedAppendContext *ctx, const GValue *val);
+typedef void (*DBusGTypeSpecializedCollectionIteratorFunc) (GType type, gpointer instance, DBusGTypeSpecializedCollectionIterator iterator, gpointer user_data);
+typedef void (*DBusGTypeSpecializedCollectionAppendFunc) (DBusGTypeSpecializedAppendContext *ctx, GValue *val);
typedef void (*DBusGTypeSpecializedCollectionEndAppendFunc) (DBusGTypeSpecializedAppendContext *ctx);
typedef struct {
@@ -103,10 +108,12 @@ typedef struct {
} DBusGTypeSpecializedCollectionVtable;
typedef void (*DBusGTypeSpecializedMapIteratorFunc) (GType type, gpointer instance, DBusGTypeSpecializedMapIterator iterator, gpointer user_data);
+typedef void (*DBusGTypeSpecializedMapAppendFunc) (DBusGTypeSpecializedAppendContext *ctx, GValue *key, GValue *val);
typedef struct {
DBusGTypeSpecializedVtable base_vtable;
DBusGTypeSpecializedMapIteratorFunc iterator;
+ DBusGTypeSpecializedMapAppendFunc append_func;
} DBusGTypeSpecializedMapVtable;
void dbus_g_type_specialized_init (void);
diff --git a/glib/dbus-gvalue-utils.c b/glib/dbus-gvalue-utils.c
index b281f6ee..b17eee16 100644
--- a/glib/dbus-gvalue-utils.c
+++ b/glib/dbus-gvalue-utils.c
@@ -226,6 +226,15 @@ hash_func_from_gtype (GType gtype, GHashFunc *func)
}
}
+static void
+unset_and_free_g_value (gpointer val)
+{
+ GValue *value = val;
+
+ g_value_unset (value);
+ g_free (value);
+}
+
static gboolean
hash_free_from_gtype (GType gtype, GDestroyNotify *func)
{
@@ -244,7 +253,7 @@ hash_free_from_gtype (GType gtype, GDestroyNotify *func)
default:
if (gtype == G_TYPE_VALUE)
{
- *func = (GDestroyNotify) g_value_unset;
+ *func = unset_and_free_g_value;
return TRUE;
}
return FALSE;
@@ -441,6 +450,17 @@ dbus_g_hash_table_insert_steal_values (GHashTable *table,
g_hash_table_insert (table, key, val);
}
+static void
+hashtable_append (DBusGTypeSpecializedAppendContext *ctx,
+ GValue *key,
+ GValue *val)
+{
+ GHashTable *table;
+
+ table = g_value_get_boxed (ctx->val);
+ dbus_g_hash_table_insert_steal_values (table, key, val);
+}
+
static gpointer
hashtable_constructor (GType type)
{
@@ -667,7 +687,7 @@ ptrarray_copy (GType type, gpointer src)
}
static void
-ptrarray_append (DBusGTypeSpecializedAppendContext *ctx, const GValue *value)
+ptrarray_append (DBusGTypeSpecializedAppendContext *ctx, GValue *value)
{
GPtrArray *array;
@@ -740,7 +760,7 @@ slist_copy (GType type, gpointer src)
}
static void
-slist_append (DBusGTypeSpecializedAppendContext *ctx, const GValue *value)
+slist_append (DBusGTypeSpecializedAppendContext *ctx, GValue *value)
{
GSList *list;
@@ -822,7 +842,8 @@ dbus_g_type_specialized_builtins_init (void)
NULL,
NULL
},
- hashtable_iterator
+ hashtable_iterator,
+ hashtable_append
};
dbus_g_type_register_map ("GHashTable", &hashtable_vtable, 0);
@@ -860,6 +881,35 @@ test_specialized_hash (const GValue *key, const GValue *val, gpointer user_data)
}
}
+static void
+test_specialized_hash_2 (const GValue *key, const GValue *val, gpointer user_data)
+{
+ TestSpecializedHashData *data = user_data;
+ const GValue *realval;
+
+ g_assert (G_VALUE_HOLDS_STRING (key));
+ g_assert (G_VALUE_TYPE (val) == G_TYPE_VALUE);
+
+ realval = g_value_get_boxed (val);
+
+ if (!strcmp (g_value_get_string (key), "foo"))
+ {
+ data->seen_foo = TRUE;
+ g_assert (G_VALUE_HOLDS_UINT (realval));
+ g_assert (g_value_get_uint (realval) == 20);
+ }
+ else if (!strcmp (g_value_get_string (key), "baz"))
+ {
+ data->seen_baz = TRUE;
+ g_assert (G_VALUE_HOLDS_STRING (realval));
+ g_assert (!strcmp ("bar", g_value_get_string (realval)));
+ }
+ else
+ {
+ g_assert_not_reached ();
+ }
+}
+
gboolean
_dbus_gvalue_utils_test (const char *datadir)
{
@@ -911,6 +961,62 @@ _dbus_gvalue_utils_test (const char *datadir)
g_value_unset (&val);
}
+ type = dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE);
+ g_assert (dbus_g_type_is_map (type));
+ g_assert (dbus_g_type_get_map_key_specialization (type) == G_TYPE_STRING);
+ g_assert (dbus_g_type_get_map_value_specialization (type) == G_TYPE_VALUE);
+ {
+ GHashTable *instance;
+ GValue val = { 0, };
+ TestSpecializedHashData hashdata;
+ DBusGTypeSpecializedAppendContext ctx;
+ GValue *eltval;
+
+ instance = dbus_g_type_specialized_construct (type);
+ g_value_init (&val, type);
+ g_value_set_boxed_take_ownership (&val, instance);
+
+ dbus_g_type_specialized_init_append (&val, &ctx);
+
+ {
+ GValue keyval = { 0, };
+ GValue valval = { 0, };
+ g_value_init (&keyval, G_TYPE_STRING);
+ g_value_set_string (&keyval, "foo");
+
+ g_value_init (&valval, G_TYPE_VALUE);
+ eltval = g_new0 (GValue, 1);
+ g_value_init (eltval, G_TYPE_UINT);
+ g_value_set_uint (eltval, 20);
+ g_value_set_boxed_take_ownership (&valval, eltval);
+ dbus_g_type_specialized_map_append (&ctx, &keyval, &valval);
+ }
+
+ {
+ GValue keyval = { 0, };
+ GValue valval = { 0, };
+ g_value_init (&keyval, G_TYPE_STRING);
+ g_value_set_string (&keyval, "baz");
+ g_value_init (&valval, G_TYPE_VALUE);
+ eltval = g_new0 (GValue, 1);
+ g_value_init (eltval, G_TYPE_STRING);
+ g_value_set_string (eltval, "bar");
+ g_value_set_boxed_take_ownership (&valval, eltval);
+ dbus_g_type_specialized_map_append (&ctx, &keyval, &valval);
+ }
+
+ hashdata.seen_foo = FALSE;
+ hashdata.seen_baz = FALSE;
+ dbus_g_type_map_value_iterate (&val,
+ test_specialized_hash_2,
+ &hashdata);
+
+ g_assert (hashdata.seen_foo);
+ g_assert (hashdata.seen_baz);
+
+ g_value_unset (&val);
+ }
+
type = dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRING);
g_assert (dbus_g_type_is_collection (type));
g_assert (dbus_g_type_get_collection_specialization (type) == G_TYPE_STRING);
@@ -927,7 +1033,7 @@ _dbus_gvalue_utils_test (const char *datadir)
g_value_init (&val, type);
g_value_set_boxed_take_ownership (&val, instance);
- dbus_g_type_specialized_collection_init_append (&val, &ctx);
+ dbus_g_type_specialized_init_append (&val, &ctx);
g_value_init (&eltval, G_TYPE_STRING);
g_value_set_static_string (&eltval, "foo");
diff --git a/glib/dbus-gvalue.c b/glib/dbus-gvalue.c
index 4e7495c7..88397731 100644
--- a/glib/dbus-gvalue.c
+++ b/glib/dbus-gvalue.c
@@ -22,6 +22,8 @@
*
*/
+#include "config.h"
+#include "dbus-gtest.h"
#include "dbus-gvalue.h"
#include "dbus-gobject.h"
#include "dbus-gvalue-utils.h"
@@ -76,12 +78,6 @@ static gboolean demarshal_variant (DBusGValueMarshalCtx *cont
DBusMessageIter *iter,
GValue *value,
GError **error);
-static gboolean marshal_garray_basic (DBusMessageIter *iter,
- const GValue *value);
-static gboolean demarshal_garray_basic (DBusGValueMarshalCtx *context,
- DBusMessageIter *iter,
- GValue *value,
- GError **error);
static gboolean marshal_proxy (DBusMessageIter *iter,
const GValue *value);
static gboolean demarshal_proxy (DBusGValueMarshalCtx *context,
@@ -102,17 +98,29 @@ static gboolean demarshal_object (DBusGValueMarshalCtx *cont
GError **error);
static gboolean marshal_map (DBusMessageIter *iter,
const GValue *value);
-static gboolean demarshal_ghashtable (DBusGValueMarshalCtx *context,
+static gboolean demarshal_map (DBusGValueMarshalCtx *context,
DBusMessageIter *iter,
GValue *value,
GError **error);
static gboolean marshal_collection (DBusMessageIter *iter,
const GValue *value);
+static gboolean marshal_collection_ptrarray (DBusMessageIter *iter,
+ const GValue *value);
+static gboolean marshal_collection_array (DBusMessageIter *iter,
+ const GValue *value);
static gboolean demarshal_collection (DBusGValueMarshalCtx *context,
DBusMessageIter *iter,
GValue *value,
GError **error);
+static gboolean demarshal_collection_ptrarray (DBusGValueMarshalCtx *context,
+ DBusMessageIter *iter,
+ GValue *value,
+ GError **error);
+static gboolean demarshal_collection_array (DBusGValueMarshalCtx *context,
+ DBusMessageIter *iter,
+ GValue *value,
+ GError **error);
static gboolean marshal_recurse (DBusMessageIter *iter,
const GValue *value);
@@ -198,30 +206,6 @@ register_basic (int typecode, const DBusGTypeMarshalData *typedata)
set_type_metadata (basic_typecode_to_gtype (typecode), typedata);
}
-static void
-register_array (int typecode, const DBusGTypeMarshalData *typedata)
-{
- GType elt_gtype;
- GType gtype;
-
- elt_gtype = basic_typecode_to_gtype (typecode);
- gtype = dbus_g_type_get_collection ("GArray", elt_gtype);
- set_type_metadata (gtype, typedata);
-}
-
-static void
-register_dict (int key_type, int value_type, const DBusGTypeMarshalData *typedata)
-{
- GType key_gtype;
- GType value_gtype;
- GType gtype;
-
- key_gtype = basic_typecode_to_gtype (key_type);
- value_gtype = basic_typecode_to_gtype (value_type);
- gtype = dbus_g_type_get_map ("GHashTable", key_gtype, value_gtype);
- set_type_metadata (gtype, typedata);
-}
-
void
dbus_g_value_types_init (void)
{
@@ -240,14 +224,6 @@ dbus_g_value_types_init (void)
marshal_basic,
demarshal_basic
};
- static const DBusGTypeMarshalVtable garray_basic_vtable = {
- marshal_garray_basic,
- demarshal_garray_basic
- };
- static const DBusGTypeMarshalVtable ghashtable_vtable = {
- marshal_map,
- demarshal_ghashtable
- };
/* Register basic types */
{
@@ -374,56 +350,8 @@ dbus_g_value_types_init (void)
set_type_metadata (G_TYPE_STRV, &typedata);
};
- {
- static const DBusGTypeMarshalData typedata = {
- DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BOOLEAN_AS_STRING,
- &garray_basic_vtable
- };
- register_array (DBUS_TYPE_BOOLEAN, &typedata);
- }
- {
- static const DBusGTypeMarshalData typedata = {
- DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING,
- &garray_basic_vtable
- };
- register_array (DBUS_TYPE_BYTE, &typedata);
- }
- {
- static const DBusGTypeMarshalData typedata = {
- DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_UINT32_AS_STRING,
- &garray_basic_vtable
- };
- register_array (DBUS_TYPE_UINT32, &typedata);
- }
- {
- static const DBusGTypeMarshalData typedata = {
- DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_INT32_AS_STRING,
- &garray_basic_vtable
- };
- register_array (DBUS_TYPE_INT32, &typedata);
- }
- {
- static const DBusGTypeMarshalData typedata = {
- DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_UINT64_AS_STRING,
- &garray_basic_vtable
- };
- register_array (DBUS_TYPE_UINT64, &typedata);
- }
- {
- static const DBusGTypeMarshalData typedata = {
- DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_INT64_AS_STRING,
- &garray_basic_vtable
- };
- register_array (DBUS_TYPE_INT64, &typedata);
- }
- {
- static const DBusGTypeMarshalData typedata = {
- DBUS_TYPE_ARRAY_AS_STRING DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
- &ghashtable_vtable,
- };
- register_dict (DBUS_TYPE_STRING, DBUS_TYPE_STRING, &typedata);
- }
+ /* Register some types specific to the D-BUS GLib bindings */
{
static const DBusGTypeMarshalVtable vtable = {
marshal_proxy,
@@ -535,6 +463,7 @@ dbus_g_value_iterator_get_values (DBusGValueIterator *iter,
context.gconnection = (iterval->value.recurse.toplevel)->value.toplevel.connection;
context.proxy = (iterval->value.recurse.toplevel)->value.toplevel.proxy;
+
if (!dbus_gvalue_demarshal (&context,
&(iterval->value.recurse.iterator),
value,
@@ -661,6 +590,10 @@ dbus_gtype_from_signature_iter (DBusSignatureIter *iter, gboolean is_client)
DBusSignatureIter subiter;
g_assert (dbus_type_is_container (current_type));
+
+ if (current_type == DBUS_TYPE_VARIANT)
+ return g_value_get_type ();
+
dbus_signature_iter_recurse (iter, &subiter);
if (current_type == DBUS_TYPE_ARRAY)
@@ -673,8 +606,6 @@ dbus_gtype_from_signature_iter (DBusSignatureIter *iter, gboolean is_client)
}
else if (current_type == DBUS_TYPE_STRUCT)
return signature_iter_to_g_type_struct (&subiter, is_client);
- else if (current_type == DBUS_TYPE_VARIANT)
- return g_value_get_type ();
else if (current_type == DBUS_TYPE_DICT_ENTRY)
return G_TYPE_INVALID;
else
@@ -721,10 +652,6 @@ dbus_gtype_to_signature (GType gtype)
char *ret;
DBusGTypeMarshalData *typedata;
- typedata = g_type_get_qdata (gtype, dbus_g_type_metadata_data_quark ());
- if (typedata == NULL)
- return NULL;
-
if (dbus_g_type_is_collection (gtype))
{
GType elt_gtype;
@@ -751,7 +678,12 @@ dbus_gtype_to_signature (GType gtype)
g_free (val_subsig);
}
else
- ret = g_strdup (typedata->sig);
+ {
+ typedata = g_type_get_qdata (gtype, dbus_g_type_metadata_data_quark ());
+ if (typedata == NULL)
+ return NULL;
+ ret = g_strdup (typedata->sig);
+ }
return ret;
}
@@ -1066,53 +998,18 @@ demarshal_strv (DBusGValueMarshalCtx *context,
}
static gboolean
-demarshal_garray_basic (DBusGValueMarshalCtx *context,
- DBusMessageIter *iter,
- GValue *value,
- GError **error)
-{
- DBusMessageIter subiter;
- GArray *ret;
- GType elt_gtype;
- int elt_size;
- void *msgarray;
- int msgarray_len;
-
- dbus_message_iter_recurse (iter, &subiter);
-
- elt_gtype = dbus_g_type_get_collection_specialization (G_VALUE_TYPE (value));
- g_assert (elt_gtype != G_TYPE_INVALID);
- g_assert (dbus_g_type_is_fixed (elt_gtype));
-
- elt_size = dbus_g_type_fixed_get_size (elt_gtype);
-
- ret = g_array_new (FALSE, TRUE, elt_size);
-
- msgarray = NULL;
- dbus_message_iter_get_fixed_array (&subiter,
- &msgarray,
- &msgarray_len);
- g_assert (msgarray != NULL);
- g_assert (msgarray_len >= 0);
- g_array_append_vals (ret, msgarray, (guint) msgarray_len);
-
- g_value_set_boxed_take_ownership (value, ret);
-
- return TRUE;
-}
-
-static gboolean
-demarshal_ghashtable (DBusGValueMarshalCtx *context,
- DBusMessageIter *iter,
- GValue *value,
- GError **error)
+demarshal_map (DBusGValueMarshalCtx *context,
+ DBusMessageIter *iter,
+ GValue *value,
+ GError **error)
{
GType gtype;
DBusMessageIter subiter;
int current_type;
- GHashTable *ret;
+ gpointer ret;
GType key_gtype;
GType value_gtype;
+ DBusGTypeSpecializedAppendContext appendctx;
current_type = dbus_message_iter_get_arg_type (iter);
if (current_type != DBUS_TYPE_ARRAY)
@@ -1140,14 +1037,12 @@ demarshal_ghashtable (DBusGValueMarshalCtx *context,
}
key_gtype = dbus_g_type_get_map_key_specialization (gtype);
- g_assert (dbus_gtype_is_valid_hash_key (key_gtype));
value_gtype = dbus_g_type_get_map_value_specialization (gtype);
- g_assert (dbus_gtype_is_valid_hash_value (value_gtype));
- ret = g_hash_table_new_full (dbus_g_hash_func_from_gtype (key_gtype),
- dbus_g_hash_equal_from_gtype (key_gtype),
- dbus_g_hash_free_from_gtype (key_gtype),
- dbus_g_hash_free_from_gtype (value_gtype));
+ ret = dbus_g_type_specialized_construct (gtype);
+ g_value_set_boxed_take_ownership (value, ret);
+
+ dbus_g_type_specialized_init_append (value, &appendctx);
while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID)
{
@@ -1176,14 +1071,11 @@ demarshal_ghashtable (DBusGValueMarshalCtx *context,
error))
return FALSE;
- dbus_g_hash_table_insert_steal_values (ret,
- &key_value,
- &value_value);
- /* Ownership of values passes to hash table, don't unset */
+ dbus_g_type_specialized_map_append (&appendctx, &key_value, &value_value);
+ /* Ownership of values passes to map, don't unset */
dbus_message_iter_next (&subiter);
}
- g_value_set_boxed_take_ownership (value, ret);
return TRUE;
}
@@ -1200,6 +1092,8 @@ get_type_demarshaller (GType type)
return demarshal_recurse;
if (dbus_g_type_is_collection (type))
return demarshal_collection;
+ if (dbus_g_type_is_map (type))
+ return demarshal_map;
g_warning ("No demarshaller registered for type \"%s\"", g_type_name (type));
return NULL;
@@ -1216,6 +1110,24 @@ demarshal_collection (DBusGValueMarshalCtx *context,
{
GType coltype;
GType subtype;
+
+ coltype = G_VALUE_TYPE (value);
+ subtype = dbus_g_type_get_collection_specialization (coltype);
+
+ if (dbus_g_type_is_fixed (subtype))
+ return demarshal_collection_array (context, iter, value, error);
+ else
+ return demarshal_collection_ptrarray (context, iter, value, error);
+}
+
+static gboolean
+demarshal_collection_ptrarray (DBusGValueMarshalCtx *context,
+ DBusMessageIter *iter,
+ GValue *value,
+ GError **error)
+{
+ GType coltype;
+ GType subtype;
gpointer instance;
DBusGTypeSpecializedAppendContext ctx;
DBusGValueDemarshalFunc demarshaller;
@@ -1254,7 +1166,7 @@ demarshal_collection (DBusGValueMarshalCtx *context,
instance = dbus_g_type_specialized_construct (coltype);
g_value_set_boxed_take_ownership (value, instance);
- dbus_g_type_specialized_collection_init_append (value, &ctx);
+ dbus_g_type_specialized_init_append (value, &ctx);
while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID)
{
@@ -1278,6 +1190,42 @@ demarshal_collection (DBusGValueMarshalCtx *context,
}
static gboolean
+demarshal_collection_array (DBusGValueMarshalCtx *context,
+ DBusMessageIter *iter,
+ GValue *value,
+ GError **error)
+{
+ DBusMessageIter subiter;
+ GArray *ret;
+ GType elt_gtype;
+ int elt_size;
+ void *msgarray;
+ int msgarray_len;
+
+ dbus_message_iter_recurse (iter, &subiter);
+
+ elt_gtype = dbus_g_type_get_collection_specialization (G_VALUE_TYPE (value));
+ g_assert (elt_gtype != G_TYPE_INVALID);
+ g_assert (dbus_g_type_is_fixed (elt_gtype));
+
+ elt_size = dbus_g_type_fixed_get_size (elt_gtype);
+
+ ret = g_array_new (FALSE, TRUE, elt_size);
+
+ msgarray = NULL;
+ dbus_message_iter_get_fixed_array (&subiter,
+ &msgarray,
+ &msgarray_len);
+ g_assert (msgarray != NULL);
+ g_assert (msgarray_len >= 0);
+ g_array_append_vals (ret, msgarray, (guint) msgarray_len);
+
+ g_value_set_boxed_take_ownership (value, ret);
+
+ return TRUE;
+}
+
+static gboolean
demarshal_recurse (DBusGValueMarshalCtx *context,
DBusMessageIter *iter,
GValue *value,
@@ -1545,50 +1493,6 @@ marshal_strv (DBusMessageIter *iter,
}
static gboolean
-marshal_garray_basic (DBusMessageIter *iter,
- const GValue *value)
-{
- GType elt_gtype;
- DBusMessageIter subiter;
- GArray *array;
- guint elt_size;
- char *subsignature_str;
-
- elt_gtype = dbus_g_type_get_collection_specialization (G_VALUE_TYPE (value));
- /* FIXME - this means we can't send an array of DBusGValue right now... */
- subsignature_str = dbus_gtype_to_signature (elt_gtype);
- g_assert (subsignature_str != NULL);
-
- elt_size = dbus_g_type_fixed_get_size (elt_gtype);
-
- array = g_value_get_boxed (value);
-
- if (!dbus_message_iter_open_container (iter,
- DBUS_TYPE_ARRAY,
- subsignature_str,
- &subiter))
- goto oom;
-
- /* TODO - This assumes that basic values are the same size
- * is this always true? If it is we can probably avoid
- * a lot of the overhead in _marshal_basic_instance...
- */
- if (!dbus_message_iter_append_fixed_array (&subiter,
- subsignature_str[0],
- &(array->data),
- array->len))
- goto oom;
-
- if (!dbus_message_iter_close_container (iter, &subiter))
- goto oom;
- g_free (subsignature_str);
- return TRUE;
- oom:
- g_error ("out of memory");
- return FALSE;
-}
-
-static gboolean
marshal_proxy (DBusMessageIter *iter,
const GValue *value)
{
@@ -1791,6 +1695,8 @@ get_type_marshaller (GType type)
return marshal_recurse;
if (dbus_g_type_is_collection (type))
return marshal_collection;
+ if (dbus_g_type_is_map (type))
+ return marshal_map;
g_warning ("No marshaller registered for type \"%s\"", g_type_name (type));
return NULL;
@@ -1824,6 +1730,22 @@ marshal_collection (DBusMessageIter *iter,
const GValue *value)
{
GType coltype;
+ GType subtype;
+
+ coltype = G_VALUE_TYPE (value);
+ subtype = dbus_g_type_get_collection_specialization (coltype);
+
+ if (dbus_g_type_is_fixed (subtype))
+ return marshal_collection_array (iter, value);
+ else
+ return marshal_collection_ptrarray (iter, value);
+}
+
+static gboolean
+marshal_collection_ptrarray (DBusMessageIter *iter,
+ const GValue *value)
+{
+ GType coltype;
GType elt_gtype;
DBusGValueCollectionMarshalData data;
DBusMessageIter subiter;
@@ -1861,6 +1783,51 @@ marshal_collection (DBusMessageIter *iter,
return FALSE;
}
+
+static gboolean
+marshal_collection_array (DBusMessageIter *iter,
+ const GValue *value)
+{
+ GType elt_gtype;
+ DBusMessageIter subiter;
+ GArray *array;
+ guint elt_size;
+ char *subsignature_str;
+
+ elt_gtype = dbus_g_type_get_collection_specialization (G_VALUE_TYPE (value));
+ g_assert (dbus_g_type_is_fixed (elt_gtype));
+ subsignature_str = dbus_gtype_to_signature (elt_gtype);
+ g_assert (subsignature_str != NULL);
+
+ elt_size = dbus_g_type_fixed_get_size (elt_gtype);
+
+ array = g_value_get_boxed (value);
+
+ if (!dbus_message_iter_open_container (iter,
+ DBUS_TYPE_ARRAY,
+ subsignature_str,
+ &subiter))
+ goto oom;
+
+ /* TODO - This assumes that basic values are the same size
+ * is this always true? If it is we can probably avoid
+ * a lot of the overhead in _marshal_basic_instance...
+ */
+ if (!dbus_message_iter_append_fixed_array (&subiter,
+ subsignature_str[0],
+ &(array->data),
+ array->len))
+ goto oom;
+
+ if (!dbus_message_iter_close_container (iter, &subiter))
+ goto oom;
+ g_free (subsignature_str);
+ return TRUE;
+ oom:
+ g_error ("out of memory");
+ return FALSE;
+}
+
static gboolean
marshal_recurse (DBusMessageIter *iter,
const GValue *value)
@@ -1882,3 +1849,54 @@ dbus_gvalue_marshal (DBusMessageIter *iter,
return FALSE;
return marshaller (iter, value);
}
+
+#ifdef DBUS_BUILD_TESTS
+
+static void
+assert_type_maps_to (GType gtype, const char *expected_sig)
+{
+ char *sig;
+ sig = dbus_gtype_to_signature (gtype);
+ g_assert (sig != NULL);
+ g_assert (!strcmp (expected_sig, sig));
+ g_free (sig);
+}
+
+static void
+assert_signature_maps_to (const char *sig, GType expected_gtype)
+{
+ g_assert (dbus_gtype_from_signature (sig, TRUE) == expected_gtype);
+}
+
+static void
+assert_bidirectional_mapping (GType gtype, const char *expected_sig)
+{
+ assert_type_maps_to (gtype, expected_sig);
+ assert_signature_maps_to (expected_sig, gtype);
+}
+
+/**
+ * @ingroup DBusGLibInternals
+ * Unit test for general glib stuff
+ * @returns #TRUE on success.
+ */
+gboolean
+_dbus_gvalue_test (const char *test_data_dir)
+{
+ dbus_g_value_types_init ();
+
+ assert_bidirectional_mapping (G_TYPE_STRING, DBUS_TYPE_STRING_AS_STRING);
+ assert_bidirectional_mapping (G_TYPE_UCHAR, DBUS_TYPE_BYTE_AS_STRING);
+ assert_bidirectional_mapping (G_TYPE_UINT, DBUS_TYPE_UINT32_AS_STRING);
+
+ assert_bidirectional_mapping (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
+ DBUS_TYPE_ARRAY_AS_STRING DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING);
+ assert_bidirectional_mapping (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH),
+ DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING);
+ assert_bidirectional_mapping (dbus_g_type_get_collection ("GArray", G_TYPE_INT),
+ DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_INT32_AS_STRING);
+
+ return TRUE;
+}
+
+#endif /* DBUS_BUILD_TESTS */
diff --git a/glib/examples/statemachine/statemachine-client.c b/glib/examples/statemachine/statemachine-client.c
index 54c630ff..88b21847 100644
--- a/glib/examples/statemachine/statemachine-client.c
+++ b/glib/examples/statemachine/statemachine-client.c
@@ -59,8 +59,9 @@ typedef struct
{
char *name;
char *state;
+ gdouble progress;
DBusGProxy *proxy;
- DBusGProxyCall *get_initial_state_call;
+ DBusGProxyCall *get_progress_call;
} MachineInfo;
typedef struct
@@ -91,6 +92,15 @@ proxy_to_iter (GtkTreeModel *model, DBusGProxy *proxy, GtkTreeIter *iter)
}
static void
+signal_row_change (ClientState *state, GtkTreeIter *iter)
+{
+ GtkTreePath *path;
+ path = gtk_tree_model_get_path (state->store, iter);
+ gtk_tree_model_row_changed (state->store, path, iter);
+ gtk_tree_path_free (path);
+}
+
+static void
get_machine_info_cb (DBusGProxy *proxy,
DBusGProxyCall *call,
gpointer data)
@@ -115,13 +125,67 @@ get_machine_info_cb (DBusGProxy *proxy,
info->name = name;
g_free (info->state);
info->state = statename;
- {
- GtkTreePath *path;
- path = gtk_tree_model_get_path (state->store, &iter);
- gtk_tree_model_row_changed (state->store, path, &iter);
- gtk_tree_path_free (path);
- }
- info->get_initial_state_call = NULL;
+ signal_row_change (state, &iter);
+}
+
+static void
+set_proxy_acquisition_progress (ClientState *state,
+ DBusGProxy *proxy,
+ double progress)
+{
+ MachineInfo *info;
+ GtkTreeIter iter;
+
+ if (!proxy_to_iter (state->store, proxy, &iter))
+ g_assert_not_reached ();
+ gtk_tree_model_get (state->store, &iter, 0, &info, -1);
+
+ /* Ignore machines in unknown state */
+ if (!info->state)
+ return;
+
+ if (strcmp (info->state, "Acquired"))
+ lose ("Got AcquisitionProgress signal in bad state %s",
+ info->state);
+
+ g_print ("Got acquisition progress change for %p (%s) to %f\n", proxy, info->name ? info->name : "(unknown)", progress);
+
+ info->progress = progress;
+
+ signal_row_change (state, &iter);
+}
+
+static void
+proxy_acquisition_changed_cb (DBusGProxy *proxy,
+ double progress,
+ gpointer user_data)
+{
+ set_proxy_acquisition_progress (user_data, proxy, progress);
+}
+
+static void
+get_acquiring_progress_cb (DBusGProxy *proxy,
+ DBusGProxyCall *call,
+ gpointer user_data)
+{
+ GError *error = NULL;
+ MachineInfo *info;
+ GtkTreeIter iter;
+ ClientState *state = user_data;
+ gdouble progress;
+
+ if (!proxy_to_iter (state->store, proxy, &iter))
+ g_assert_not_reached ();
+ gtk_tree_model_get (state->store, &iter, 0, &info, -1);
+
+ g_assert (info->get_progress_call == call);
+
+ if (!dbus_g_proxy_end_call (proxy, call, &error,
+ G_TYPE_DOUBLE, &progress, G_TYPE_INVALID))
+ lose_gerror ("Failed to complete GetAcquiringProgress call", error);
+ info->get_progress_call = NULL;
+
+ set_proxy_acquisition_progress (state, proxy, progress);
}
static void
@@ -139,25 +203,27 @@ proxy_state_changed_cb (DBusGProxy *proxy,
g_print ("Got state change for %p (%s) to %s\n", proxy, info->name ? info->name : "(unknown)", statename);
- /* If we got a signal for the state, we shouldn't update
- * based on the (possibly stale) call
- */
- if (info->get_initial_state_call != NULL)
- {
- g_print ("Cancelling outstanding GetInfo call for %p due to signal\n", proxy);
- dbus_g_proxy_cancel_call (proxy, info->get_initial_state_call);
- info->get_initial_state_call = NULL;
- }
-
g_free (info->state);
info->state = g_strdup (statename);
- {
- GtkTreePath *path;
- path = gtk_tree_model_get_path (state->store, &iter);
- gtk_tree_model_row_changed (state->store, path, &iter);
- gtk_tree_path_free (path);
- }
+ if (!strcmp (info->state, "Acquired"))
+ {
+ g_print ("Starting GetAcquiringProgress call for %p\n", info->proxy);
+ if (info->get_progress_call != NULL)
+ {
+ dbus_g_proxy_cancel_call (info->proxy, info->get_progress_call);
+ info->get_progress_call = NULL;
+ }
+ info->get_progress_call =
+ dbus_g_proxy_begin_call (info->proxy, "GetAcquiringProgress",
+ get_acquiring_progress_cb,
+ state, NULL,
+ G_TYPE_INVALID);
+ }
+ else
+ info->progress = 0.0;
+
+ signal_row_change (state, &iter);
}
static void
@@ -172,6 +238,7 @@ add_machine (ClientState *state,
info = g_new0 (MachineInfo, 1);
info->name = g_strdup (name);
info->state = g_strdup (mstate);
+ info->progress = 0.0;
info->proxy = dbus_g_proxy_new_for_name (state->bus,
"com.example.StateServer",
@@ -181,14 +248,11 @@ add_machine (ClientState *state,
if (!info->state)
{
g_print ("Starting GetInfo call for %p\n", info->proxy);
- info->get_initial_state_call
- = dbus_g_proxy_begin_call (info->proxy, "GetInfo",
- get_machine_info_cb,
- state, NULL,
- G_TYPE_INVALID);
+ dbus_g_proxy_begin_call (info->proxy, "GetInfo",
+ get_machine_info_cb,
+ state, NULL,
+ G_TYPE_INVALID);
}
- else
- info->get_initial_state_call = NULL;
/* Watch for state changes */
dbus_g_proxy_add_signal (info->proxy, "StateChanged",
@@ -200,6 +264,15 @@ add_machine (ClientState *state,
state,
NULL);
+ dbus_g_proxy_add_signal (info->proxy, "AcquisitionProgress",
+ G_TYPE_DOUBLE, G_TYPE_INVALID);
+
+ dbus_g_proxy_connect_signal (info->proxy,
+ "AcquisitionProgress",
+ G_CALLBACK (proxy_acquisition_changed_cb),
+ state,
+ NULL);
+
gtk_list_store_prepend (GTK_LIST_STORE (state->store), &iter);
gtk_list_store_set (GTK_LIST_STORE (state->store), &iter, 0, info, -1);
@@ -306,6 +379,12 @@ do_a_state_change (ClientState *state)
g_print ("Sending Start request to machine %s\n", info->name);
dbus_g_proxy_call_no_reply (info->proxy, "Start", G_TYPE_INVALID);
}
+ else if (!strcmp (info->state, "Loading"))
+ {
+
+ g_print ("Sending Reacquire request to machine %s\n", info->name);
+ dbus_g_proxy_call_no_reply (info->proxy, "Reacquire", G_TYPE_INVALID);
+ }
else
{
g_print ("Sending Shutdown request to machine %s\n", info->name);
@@ -318,7 +397,7 @@ do_something_random_2 (gpointer data)
{
ClientState *state = data;
do_a_state_change (state);
- g_timeout_add (g_random_int_range (500, 3000), do_something_random_2, state);
+ g_timeout_add (g_random_int_range (2000, 5000), do_something_random_2, state);
return FALSE;
}
@@ -328,12 +407,13 @@ do_something_random (gpointer data)
ClientState *state = data;
gint n_children;
- switch (g_random_int_range (0, 2))
+ switch (g_random_int_range (0, 3))
{
case 0:
send_create_machine (state);
break;
case 1:
+ case 2:
do_a_state_change (state);
break;
default:
@@ -341,8 +421,11 @@ do_something_random (gpointer data)
}
n_children = gtk_tree_model_iter_n_children (state->store, NULL);
- if (n_children >= 8)
- g_timeout_add (g_random_int_range (500, 3000), do_something_random_2, state);
+ if (n_children >= 5)
+ {
+ g_print ("MAX children reached, switching to state changes only\n");
+ g_timeout_add (g_random_int_range (500, 3000), do_something_random_2, state);
+ }
else
g_timeout_add (g_random_int_range (500, 3000), do_something_random, state);
return FALSE;
@@ -406,6 +489,34 @@ sort_by_state (GtkTreeModel *model,
info_b ? info_b->state : "");
}
+static void
+set_cell_progress (GtkTreeViewColumn *tree_column,
+ GtkCellRenderer *cell,
+ GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ MachineInfo *info;
+
+ gtk_tree_model_get (tree_model, iter, 0, &info, -1);
+
+ g_object_set (cell, "value", (int) (info->progress * 100), NULL);
+}
+
+static gint
+sort_by_progress (GtkTreeModel *model,
+ GtkTreeIter *a,
+ GtkTreeIter *b,
+ gpointer user_data)
+{
+ MachineInfo *info_a, *info_b;
+
+ gtk_tree_model_get (model, a, 0, &info_a, -1);
+ gtk_tree_model_get (model, b, 0, &info_b, -1);
+
+ return info_a->progress > info_b->progress ? 1 : -1;
+}
+
static void
get_machines_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer data)
{
@@ -458,6 +569,17 @@ get_machines_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer data)
0, sort_by_state, NULL, NULL);
gtk_tree_view_column_set_sort_column_id (col, 0);
gtk_tree_view_append_column (GTK_TREE_VIEW (state->view), col);
+
+ rend = gtk_cell_renderer_progress_new ();
+ col = gtk_tree_view_column_new_with_attributes (_("Progress"),
+ rend,
+ NULL);
+ gtk_tree_view_column_set_cell_data_func (col, rend, set_cell_progress, NULL, NULL);
+ gtk_tree_view_column_set_resizable (col, TRUE);
+ gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (state->store),
+ 0, sort_by_progress, NULL, NULL);
+ gtk_tree_view_column_set_sort_column_id (col, 0);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (state->view), col);
for (i = 0; i < objs->len; i++)
{
diff --git a/glib/examples/statemachine/statemachine-server.c b/glib/examples/statemachine/statemachine-server.c
index 7cadf1fe..2cbf39fe 100644
--- a/glib/examples/statemachine/statemachine-server.c
+++ b/glib/examples/statemachine/statemachine-server.c
@@ -104,6 +104,26 @@ sm_server_get_property (GObject *object,
}
}
+static void
+machine_state_changed_cb (SMObject *obj, const char *state, gpointer data)
+{
+ char *name;
+
+ g_object_get (obj, "name", &name, NULL);
+ g_print ("Machine %s switching to state %s\n", name, state);
+ g_free (name);
+}
+
+static void
+machine_acquisition_changed_cb (SMObject *obj, gdouble progress, gpointer data)
+{
+ char *name;
+
+ g_object_get (obj, "name", &name, NULL);
+ g_print ("Machine %s got progress %f\n", name, progress);
+ g_free (name);
+}
+
gboolean
sm_server_create_machine (SMServer *server, const char *name, GError **error)
{
@@ -130,6 +150,13 @@ sm_server_create_machine (SMServer *server, const char *name, GError **error)
g_print ("Created state machine with name %s at %s\n", name, path);
+ g_signal_connect_object (machine, "state-changed",
+ G_CALLBACK (machine_state_changed_cb),
+ NULL, 0);
+ g_signal_connect_object (machine, "acquisition-progress",
+ G_CALLBACK (machine_acquisition_changed_cb),
+ NULL, 0);
+
g_signal_emit (server, sm_server_signals[MACHINE_CREATED], 0, name, path);
return TRUE;
diff --git a/glib/examples/statemachine/statemachine.c b/glib/examples/statemachine/statemachine.c
index 2bde0058..c94e2945 100644
--- a/glib/examples/statemachine/statemachine.c
+++ b/glib/examples/statemachine/statemachine.c
@@ -103,8 +103,8 @@ sm_object_state_get_type (void)
ENUM_ENTRY (SM_OBJECT_STATE_SHUTDOWN, "Shutdown"),
ENUM_ENTRY (SM_OBJECT_STATE_INITIALIZED, "Loading"),
- ENUM_ENTRY (SM_OBJECT_STATE_ACQUIRED, "Resource acquired"),
- ENUM_ENTRY (SM_OBJECT_STATE_OPERATING, "Operating normally"),
+ ENUM_ENTRY (SM_OBJECT_STATE_ACQUIRED, "Acquired"),
+ ENUM_ENTRY (SM_OBJECT_STATE_OPERATING, "Operating"),
{ 0, 0, 0 }
};
@@ -175,6 +175,21 @@ sm_object_get_property (GObject *object,
}
}
+static const char *
+state_to_string (SMObjectState state)
+{
+ GEnumValue *value;
+ GEnumClass *prop_class;
+ const char *ret;
+
+ prop_class = g_type_class_ref (SM_TYPE_OBJECT_STATE);
+ value = g_enum_get_value (prop_class, state);
+ ret = value->value_nick;
+
+ g_type_class_unref (prop_class);
+ return ret;
+}
+
static void
queue_task (SMObject *object, guint delay, GSourceFunc func)
{
@@ -188,6 +203,8 @@ idle_state_change (gpointer data)
{
SMObject *object = data;
+ g_print ("doing idle state change for %s to %s\n",
+ object->name, state_to_string (object->requested_state));
state_change (object, object->requested_state);
return FALSE;
}
@@ -197,7 +214,8 @@ idle_further_acquire (gpointer data)
{
SMObject *object = data;
- object->acquisition_progress += g_random_double_range (0.05, 0.5);
+ g_print ("doing idle acquisition for machine %s\n", object->name);
+ object->acquisition_progress += g_random_double_range (0.20, 0.7);
if (object->acquisition_progress > 1.0)
{
object->acquisition_progress = 1.0;
@@ -220,26 +238,10 @@ clear_pending_tasks (SMObject *object)
object->pending_tasks = NULL;
}
-static const char *
-state_to_string (SMObjectState state)
-{
- GEnumValue *value;
- GEnumClass *prop_class;
- const char *ret;
-
- prop_class = g_type_class_ref (SM_TYPE_OBJECT_STATE);
- value = g_enum_get_value (prop_class, state);
- ret = value->value_nick;
-
- g_type_class_unref (prop_class);
- return ret;
-}
-
static void
state_change (SMObject *object, SMObjectState new_state)
{
g_signal_emit (object, sm_object_signals[STATE_CHANGED], 0,
- state_to_string (object->state),
state_to_string (new_state));
clear_pending_tasks (object);
@@ -288,7 +290,7 @@ sm_object_start (SMObject *object, GError **error)
gboolean
sm_object_shutdown (SMObject *object, GError **error)
{
- if (object->state != SM_OBJECT_STATE_INITIALIZED)
+ if (object->state == SM_OBJECT_STATE_SHUTDOWN)
{
g_set_error (error,
SM_ERROR,
@@ -321,7 +323,7 @@ sm_object_reinitialize (SMObject *object, GError **error)
gboolean
sm_object_reacquire (SMObject *object, GError **error)
{
- if (object->state != SM_OBJECT_STATE_ACQUIRED)
+ if (object->state == SM_OBJECT_STATE_ACQUIRED)
{
g_set_error (error,
SM_ERROR,
diff --git a/test/glib/test-dbus-glib.c b/test/glib/test-dbus-glib.c
index 15cd769a..4fbe797e 100644
--- a/test/glib/test-dbus-glib.c
+++ b/test/glib/test-dbus-glib.c
@@ -26,6 +26,13 @@ static gboolean proxy_destroy_and_nameowner_complete = FALSE;
static void lose (const char *fmt, ...) G_GNUC_NORETURN G_GNUC_PRINTF (1, 2);
static void lose_gerror (const char *prefix, GError *error) G_GNUC_NORETURN;
+static void
+unset_and_free_gvalue (gpointer val)
+{
+ g_value_unset (val);
+ g_free (val);
+}
+
static gboolean
timed_exit (gpointer loop)
{
@@ -40,6 +47,7 @@ proxy_destroyed_cb (DBusGProxy *proxy, gpointer user_data)
proxy_destroyed = TRUE;
if (proxy_destroy_and_nameowner && !proxy_destroy_and_nameowner_complete && await_terminating_service == NULL)
{
+ g_source_remove (exit_timeout);
g_main_loop_quit (loop);
proxy_destroy_and_nameowner_complete = TRUE;
}
@@ -62,11 +70,13 @@ name_owner_changed (DBusGProxy *proxy,
await_terminating_service = NULL;
if (proxy_destroy_and_nameowner && !proxy_destroy_and_nameowner_complete && proxy_destroyed)
{
+ g_source_remove (exit_timeout);
g_main_loop_quit (loop);
proxy_destroy_and_nameowner_complete = TRUE;
}
else if (!proxy_destroy_and_nameowner)
{
+ g_source_remove (exit_timeout);
g_main_loop_quit (loop);
}
}
@@ -838,6 +848,50 @@ main (int argc, char **argv)
run_mainloop ();
{
+ GValue *val;
+ GHashTable *table;
+ GHashTable *ret_table;
+
+ table = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, unset_and_free_gvalue);
+
+ val = g_new0 (GValue, 1);
+ g_value_init (val, G_TYPE_UINT);
+ g_value_set_uint (val, 42);
+ g_hash_table_insert (table, g_strdup ("foo"), val);
+
+ val = g_new0 (GValue, 1);
+ g_value_init (val, G_TYPE_STRING);
+ g_value_set_string (val, "hello");
+ g_hash_table_insert (table, g_strdup ("bar"), val);
+
+ ret_table = NULL;
+ g_print ("Calling ManyStringify\n");
+ if (!dbus_g_proxy_call (proxy, "ManyStringify", &error,
+ dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), table,
+ G_TYPE_INVALID,
+ dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), &ret_table,
+ G_TYPE_INVALID))
+ lose_gerror ("Failed to complete ManyStringify call", error);
+
+ g_assert (ret_table != NULL);
+ g_assert (g_hash_table_size (ret_table) == 2);
+
+ val = g_hash_table_lookup (ret_table, "foo");
+ g_assert (val != NULL);
+ g_assert (G_VALUE_HOLDS_STRING (val));
+ g_assert (!strcmp ("42", g_value_get_string (val)));
+
+ val = g_hash_table_lookup (ret_table, "bar");
+ g_assert (val != NULL);
+ g_assert (G_VALUE_HOLDS_STRING (val));
+ g_assert (!strcmp ("hello", g_value_get_string (val)));
+
+ g_hash_table_destroy (table);
+ g_hash_table_destroy (ret_table);
+ }
+
+ {
guint val;
char *ret_path;
DBusGProxy *ret_proxy;
@@ -1135,6 +1189,9 @@ main (int argc, char **argv)
lose_gerror ("Failed to complete Uppercase call", error);
g_free (v_STRING_2);
+ if (getenv ("DBUS_GLIB_TEST_SLEEP_AFTER_ACTIVATION1"))
+ g_usleep (8 * G_USEC_PER_SEC);
+
dbus_g_proxy_add_signal (proxy, "Frobnicate", G_TYPE_INT, G_TYPE_INVALID);
dbus_g_proxy_connect_signal (proxy, "Frobnicate",
@@ -1175,6 +1232,9 @@ main (int argc, char **argv)
G_TYPE_INVALID, G_TYPE_INVALID))
lose_gerror ("Failed to complete EmitFrobnicate call", error);
+ if (getenv ("DBUS_GLIB_TEST_SLEEP_AFTER_ACTIVATION2"))
+ g_usleep (8 * G_USEC_PER_SEC);
+
dbus_g_connection_flush (connection);
exit_timeout = g_timeout_add (5000, timed_exit, loop);
g_main_loop_run (loop);
diff --git a/test/glib/test-service-glib.c b/test/glib/test-service-glib.c
index a9e57926..580eb107 100644
--- a/test/glib/test-service-glib.c
+++ b/test/glib/test-service-glib.c
@@ -63,6 +63,8 @@ gboolean my_object_many_return (MyObject *obj, guint32 *arg0, char **arg1, gint3
gboolean my_object_recursive1 (MyObject *obj, GArray *array, guint32 *len_ret, GError **error);
gboolean my_object_recursive2 (MyObject *obj, guint32 reqlen, GArray **array, GError **error);
+gboolean my_object_many_stringify (MyObject *obj, GHashTable *vals, GHashTable **ret, GError **error);
+
gboolean my_object_objpath (MyObject *obj, const char *in, char **arg1, GError **error);
gboolean my_object_get_objs (MyObject *obj, GPtrArray **objs, GError **error);
@@ -397,6 +399,38 @@ my_object_many_uppercase (MyObject *obj, const char * const *in, char ***out, GE
return TRUE;
}
+static void
+hash_foreach_stringify (gpointer key, gpointer val, gpointer user_data)
+{
+ const char *keystr = key;
+ const GValue *value = val;
+ GValue *sval;
+ GHashTable *ret = user_data;
+
+ sval = g_new0 (GValue, 1);
+ g_value_init (sval, G_TYPE_STRING);
+ if (!g_value_transform (value, sval))
+ g_assert_not_reached ();
+
+ g_hash_table_insert (ret, g_strdup (keystr), sval);
+}
+
+static void
+unset_and_free_gvalue (gpointer val)
+{
+ g_value_unset (val);
+ g_free (val);
+}
+
+gboolean
+my_object_many_stringify (MyObject *obj, GHashTable /* char * -> GValue * */ *vals, GHashTable /* char * -> GValue * */ **ret, GError **error)
+{
+ *ret = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, unset_and_free_gvalue);
+ g_hash_table_foreach (vals, hash_foreach_stringify, *ret);
+ return TRUE;
+}
+
gboolean
my_object_objpath (MyObject *obj, const char *incoming, char **outgoing, GError **error)
{
diff --git a/test/glib/test-service-glib.xml b/test/glib/test-service-glib.xml
index 272f7b23..c299a80c 100644
--- a/test/glib/test-service-glib.xml
+++ b/test/glib/test-service-glib.xml
@@ -95,6 +95,11 @@
<arg type="u" direction="out" />
</method>
+ <method name="ManyStringify">
+ <arg type="a{sv}" direction="in"/>
+ <arg type="a{sv}" direction="out"/>
+ </method>
+
<method name="EmitFrobnicate">
</method>