diff --git a/NEWS b/NEWS index 0ba9da167..f2e1d5415 100644 --- a/NEWS +++ b/NEWS @@ -28,6 +28,10 @@ and GApplication. Users of these APIs will need to be adapted. * GObject - Introduce g_object_notify_by_pspec - Add GBinding + - The GVariant gtype G_TYPE_VARIANT was changed from boxed + to fundamental. We believe there were no existing users + of the boxed type, so this should not cause any applications + to break. * Test framework - Add package and version to the test report XML diff --git a/docs/reference/gobject/gobject-sections.txt b/docs/reference/gobject/gobject-sections.txt index 4b1bf0f3e..483c78599 100644 --- a/docs/reference/gobject/gobject-sections.txt +++ b/docs/reference/gobject/gobject-sections.txt @@ -147,6 +147,7 @@ G_TYPE_BOXED G_TYPE_PARAM G_TYPE_OBJECT G_TYPE_GTYPE +G_TYPE_VARIANT G_TYPE_RESERVED_GLIB_FIRST @@ -351,7 +352,6 @@ G_TYPE_REGEX G_TYPE_ARRAY G_TYPE_BYTE_ARRAY G_TYPE_PTR_ARRAY -G_TYPE_VARIANT G_TYPE_VARIANT_TYPE G_TYPE_ERROR GStrv @@ -698,6 +698,17 @@ g_param_spec_gtype g_value_get_gtype g_value_set_gtype + +G_IS_PARAM_SPEC_VARIANT +G_PARAM_SPEC_VARIANT +G_VALUE_HOLDS_VARIANT +G_TYPE_PARAM_VARIANT +GParamSpecVariant +g_param_spec_variant +g_value_get_variant +g_value_dup_variant +g_value_set_variant + g_value_set_instance g_param_spec_types diff --git a/gobject/gboxed.c b/gobject/gboxed.c index f18ffb5a7..06850931d 100644 --- a/gobject/gboxed.c +++ b/gobject/gboxed.c @@ -286,17 +286,16 @@ g_variant_type_get_gtype (void) return type_id; } +/** + * g_variant_get_gtype: + * + * Since: 2.24 + * Deprecated: 2.26 + */ GType g_variant_get_gtype (void) { - static GType type_id = 0; - - if (!type_id) - type_id = g_boxed_type_register_static (g_intern_static_string ("GVariant"), - (GBoxedCopyFunc) g_variant_ref, - (GBoxedFreeFunc) g_variant_unref); - - return type_id; + return G_TYPE_VARIANT; } GType diff --git a/gobject/gboxed.h b/gobject/gboxed.h index f46728bdf..baac62c78 100644 --- a/gobject/gboxed.h +++ b/gobject/gboxed.h @@ -194,14 +194,6 @@ GType g_boxed_type_register_static (const gchar *name, * Since: 2.24 */ #define G_TYPE_VARIANT_TYPE (g_variant_type_get_gtype ()) -/** - * G_TYPE_VARIANT: - * - * The #GType for a boxed type holding a #GVariant reference. - * - * Since: 2.24 - */ -#define G_TYPE_VARIANT (g_variant_get_gtype ()) /** * G_TYPE_ERROR: * @@ -229,10 +221,13 @@ GType g_array_get_type (void) G_GNUC_CONST; GType g_byte_array_get_type (void) G_GNUC_CONST; GType g_ptr_array_get_type (void) G_GNUC_CONST; GType g_variant_type_get_gtype(void) G_GNUC_CONST; -GType g_variant_get_gtype (void) G_GNUC_CONST; GType g_regex_get_type (void) G_GNUC_CONST; GType g_error_get_type (void) G_GNUC_CONST; +#ifndef G_DISABLE_DEPRECATED +GType g_variant_get_gtype (void) G_GNUC_CONST; +#endif + /** * GStrv: * diff --git a/gobject/glib-genmarshal.c b/gobject/glib-genmarshal.c index f96f46634..e382fdc9f 100644 --- a/gobject/glib-genmarshal.c +++ b/gobject/glib-genmarshal.c @@ -151,6 +151,7 @@ put_marshal_value_getters (void) fputs ("#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v)\n", fout); fputs ("#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v)\n", fout); fputs ("#define g_marshal_value_peek_object(v) g_value_get_object (v)\n", fout); + fputs ("#define g_marshal_value_peek_variant(v) g_value_get_variant (v)\n", fout); fputs ("#else /* !G_ENABLE_DEBUG */\n", fout); fputs ("/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API.\n", fout); fputs (" * Do not access GValues directly in your code. Instead, use the\n", fout); @@ -174,6 +175,7 @@ put_marshal_value_getters (void) fputs ("#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer\n", fout); fputs ("#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer\n", fout); fputs ("#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer\n", fout); + fputs ("#define g_marshal_value_peek_variant(v) (v)->data[0].v_pointer\n", fout); fputs ("#endif /* !G_ENABLE_DEBUG */\n", fout); fputs ("\n", fout); } @@ -202,6 +204,7 @@ complete_in_arg (InArgument *iarg) { "BOXED", "BOXED", "gpointer", "g_marshal_value_peek_boxed", }, { "POINTER", "POINTER", "gpointer", "g_marshal_value_peek_pointer", }, { "OBJECT", "OBJECT", "gpointer", "g_marshal_value_peek_object", }, + { "VARIANT", "VARIANT", "gpointer", "g_marshal_value_peek_variant", }, /* deprecated: */ { "NONE", "VOID", "void", NULL, }, { "BOOL", "BOOLEAN", "gboolean", "g_marshal_value_peek_boolean", }, @@ -246,6 +249,7 @@ complete_out_arg (OutArgument *oarg) { "BOXED", "BOXED", "gpointer", "g_value_take_boxed", }, { "POINTER", "POINTER", "gpointer", "g_value_set_pointer", }, { "OBJECT", "OBJECT", "GObject*", "g_value_take_object", }, + { "VARIANT", "VARIANT", "GVariant*", "g_value_take_variant", }, /* deprecated: */ { "NONE", "VOID", "void", NULL, }, { "BOOL", "BOOLEAN", "gboolean", "g_value_set_boolean", }, diff --git a/gobject/gmarshal.list b/gobject/gmarshal.list index f3844a1e3..533307be8 100644 --- a/gobject/gmarshal.list +++ b/gobject/gmarshal.list @@ -19,6 +19,7 @@ # BOXED for boxed (anonymous but reference counted) types (GBoxed*) # POINTER for anonymous pointer types (gpointer) # OBJECT for GObject or derived types (GObject*) +# VARIANT for variants (GVariant*) # NONE deprecated alias for VOID # BOOL deprecated alias for BOOLEAN @@ -40,6 +41,7 @@ VOID:PARAM VOID:BOXED VOID:POINTER VOID:OBJECT +VOID:VARIANT # GRuntime specific marshallers VOID:UINT,POINTER diff --git a/gobject/gobject.symbols b/gobject/gobject.symbols index f47f9e6e7..0c3dd5b2a 100644 --- a/gobject/gobject.symbols +++ b/gobject/gobject.symbols @@ -41,7 +41,6 @@ g_error_get_type G_GNUC_CONST g_ptr_array_get_type G_GNUC_CONST g_regex_get_type G_GNUC_CONST g_variant_type_get_gtype G_GNUC_CONST -g_variant_get_gtype G_GNUC_CONST g_closure_get_type G_GNUC_CONST g_value_get_type G_GNUC_CONST g_value_array_get_type G_GNUC_CONST @@ -52,6 +51,7 @@ g_value_get_boxed g_value_set_static_boxed #ifndef G_DISABLE_DEPRECATED g_value_set_boxed_take_ownership +g_variant_get_gtype G_GNUC_CONST #endif #endif #endif @@ -215,6 +215,7 @@ g_param_spec_uint64 g_param_spec_ulong g_param_spec_unichar g_param_spec_value_array +g_param_spec_variant #endif #endif @@ -294,6 +295,9 @@ g_value_take_string g_gtype_get_type g_value_set_gtype g_value_get_gtype +g_value_get_variant +g_value_dup_variant +g_value_set_variant #endif #endif diff --git a/gobject/gparamspecs.c b/gobject/gparamspecs.c index 2f49824f4..3bdfaf751 100644 --- a/gobject/gparamspecs.c +++ b/gobject/gparamspecs.c @@ -1,5 +1,6 @@ /* GObject - GLib Type, Object, Parameter and Signal Library * Copyright (C) 1997-1999, 2000-2001 Tim Janik and Red Hat, Inc. + * Copyright (C) 2010 Christian Persch * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -1098,13 +1099,71 @@ param_gtype_values_cmp (GParamSpec *pspec, return p1 < p2 ? -1 : p1 > p2; } +static void +param_variant_init (GParamSpec *pspec) +{ + GParamSpecVariant *vspec = G_PARAM_SPEC_VARIANT (pspec); + + vspec->type = NULL; + vspec->default_value = NULL; +} + +static void +param_variant_finalize (GParamSpec *pspec) +{ + GParamSpecVariant *vspec = G_PARAM_SPEC_VARIANT (pspec); + GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_VARIANT)); + + if (vspec->default_value) + g_variant_unref (vspec->default_value); + g_variant_type_free (vspec->type); + + parent_class->finalize (pspec); +} + +static void +param_variant_set_default (GParamSpec *pspec, + GValue *value) +{ + value->data[0].v_pointer = G_PARAM_SPEC_VARIANT (pspec)->default_value; + value->data[1].v_uint |= G_VALUE_NOCOPY_CONTENTS; +} + +static gboolean +param_variant_validate (GParamSpec *pspec, + GValue *value) +{ + GParamSpecVariant *vspec = G_PARAM_SPEC_VARIANT (pspec); + GVariant *variant = value->data[0].v_pointer; + + if ((variant == NULL && vspec->default_value != NULL) || + (variant != NULL && !g_variant_is_of_type (variant, vspec->type))) + { + g_param_value_set_default (pspec, value); + return TRUE; + } + + return FALSE; +} + +static gint +param_variant_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2) +{ + GVariant *v1 = value1->data[0].v_pointer; + GVariant *v2 = value2->data[0].v_pointer; + + return v1 < v2 ? -1 : v2 > v1; +} + /* --- type initialization --- */ GType *g_param_spec_types = NULL; void g_param_spec_types_init (void) { - const guint n_types = 22; + const guint n_types = 23; GType type, *spec_types, *spec_types_bound; g_param_spec_types = g_new0 (GType, n_types); @@ -1509,6 +1568,24 @@ g_param_spec_types_init (void) g_assert (type == G_TYPE_PARAM_GTYPE); } + /* G_TYPE_PARAM_VARIANT + */ + { + const GParamSpecTypeInfo pspec_info = { + sizeof (GParamSpecVariant), /* instance_size */ + 0, /* n_preallocs */ + param_variant_init, /* instance_init */ + G_TYPE_VARIANT, /* value_type */ + param_variant_finalize, /* finalize */ + param_variant_set_default, /* value_set_default */ + param_variant_validate, /* value_validate */ + param_variant_values_cmp, /* values_cmp */ + }; + type = g_param_type_register_static (g_intern_static_string ("GParamVariant"), &pspec_info); + *spec_types++ = type; + g_assert (type == G_TYPE_PARAM_VARIANT); + } + g_assert (spec_types == spec_types_bound); } @@ -2393,5 +2470,53 @@ g_param_spec_override (const gchar *name, return pspec; } +/** + * g_param_spec_variant: + * @name: canonical name of the property specified + * @nick: nick name for the property specified + * @blurb: description of the property specified + * @type: a #GVariantType + * @default_value: (allow-none): a #GVariant of type @type to use as the + * default value, or %NULL + * @flags: flags for the property specified + * + * Creates a new #GParamSpecVariant instance specifying a #GVariant + * property. + * + * If @default_value is floating, it is consumed. + * + * See g_param_spec_internal() for details on property names. + * + * Returns: the newly created #GParamSpec + * + * Since: 2.26 + */ +GParamSpec* +g_param_spec_variant (const gchar *name, + const gchar *nick, + const gchar *blurb, + const GVariantType *type, + GVariant *default_value, + GParamFlags flags) +{ + GParamSpecVariant *vspec; + + g_return_val_if_fail (type != NULL, NULL); + g_return_val_if_fail (default_value == NULL || + g_variant_is_of_type (default_value, type), NULL); + + vspec = g_param_spec_internal (G_TYPE_PARAM_VARIANT, + name, + nick, + blurb, + flags); + + vspec->type = g_variant_type_copy (type); + if (default_value) + vspec->default_value = g_variant_ref_sink (default_value); + + return G_PARAM_SPEC (vspec); +} + #define __G_PARAMSPECS_C__ #include "gobjectaliasdef.c" diff --git a/gobject/gparamspecs.h b/gobject/gparamspecs.h index 345db03fd..a61d608eb 100644 --- a/gobject/gparamspecs.h +++ b/gobject/gparamspecs.h @@ -549,6 +549,34 @@ G_BEGIN_DECLS */ #define G_PARAM_SPEC_GTYPE(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_GTYPE, GParamSpecGType)) +/** + * G_TYPE_PARAM_VARIANT: + * + * The #GType of #GParamSpecVariant. + * + * Since: 2.26 + */ +#define G_TYPE_PARAM_VARIANT (g_param_spec_types[22]) +/** + * G_IS_PARAM_SPEC_VARIANT: + * @pspec: a #GParamSpec + * + * Checks whether the given #GParamSpec is of type %G_TYPE_PARAM_VARIANT. + * + * Returns: %TRUE on success + * + * Since: 2.26 + */ +#define G_IS_PARAM_SPEC_VARIANT(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_VARIANT)) +/** + * G_PARAM_SPEC_VARIANT: + * @pspec: a #GParamSpec + * + * Casts a #GParamSpec into a #GParamSpecVariant. + * + * Since: 2.26 + */ +#define G_PARAM_SPEC_VARIANT(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_VARIANT, GParamSpecVariant)) /* --- typedefs & structures --- */ typedef struct _GParamSpecChar GParamSpecChar; @@ -573,6 +601,7 @@ typedef struct _GParamSpecValueArray GParamSpecValueArray; typedef struct _GParamSpecObject GParamSpecObject; typedef struct _GParamSpecOverride GParamSpecOverride; typedef struct _GParamSpecGType GParamSpecGType; +typedef struct _GParamSpecVariant GParamSpecVariant; /** * GParamSpecChar: @@ -921,6 +950,23 @@ struct _GParamSpecGType GParamSpec parent_instance; GType is_a_type; }; +/** + * GParamSpecVariant: + * @parent_instance: private #GParamSpec portion + * @type: a #GVariantType, or %NULL + * @default_value: a #GVariant, or %NULL + * + * A #GParamSpec derived structure that contains the meta data for #GVariant properties. + * + * Since: 2.26 + */ +struct _GParamSpecVariant +{ + GParamSpec parent_instance; + GVariantType *type; + GVariant *default_value; + gpointer padding[4]; +}; /* --- GParamSpec prototypes --- */ GParamSpec* g_param_spec_char (const gchar *name, @@ -1051,6 +1097,12 @@ GParamSpec* g_param_spec_gtype (const gchar *name, const gchar *blurb, GType is_a_type, GParamFlags flags); +GParamSpec* g_param_spec_variant (const gchar *name, + const gchar *nick, + const gchar *blurb, + const GVariantType *type, + GVariant *default_value, + GParamFlags flags); /* --- internal --- */ /* We prefix variable declarations so they can diff --git a/gobject/gtype.h b/gobject/gtype.h index 33a4a8b22..d94249d73 100644 --- a/gobject/gtype.h +++ b/gobject/gtype.h @@ -179,6 +179,17 @@ G_BEGIN_DECLS * The fundamental type for #GObject. */ #define G_TYPE_OBJECT G_TYPE_MAKE_FUNDAMENTAL (20) +/** + * G_TYPE_VARIANT: + * + * The fundamental type corresponding to #GVariant. + * + * Note: GLib 2.24 did include a boxed type with this name. It was replaced + * with this fundamental type in 2.26. + * + * Since: 2.26 + */ +#define G_TYPE_VARIANT G_TYPE_MAKE_FUNDAMENTAL (21) /* Reserved fundamental type numbers to create new fundamental @@ -208,7 +219,7 @@ G_BEGIN_DECLS * First fundamental type number to create a new fundamental type id with * G_TYPE_MAKE_FUNDAMENTAL() reserved for GLib. */ -#define G_TYPE_RESERVED_GLIB_FIRST (21) +#define G_TYPE_RESERVED_GLIB_FIRST (22) /** * G_TYPE_RESERVED_GLIB_LAST: * diff --git a/gobject/gvaluetypes.c b/gobject/gvaluetypes.c index 5713e4835..925a50396 100644 --- a/gobject/gvaluetypes.c +++ b/gobject/gvaluetypes.c @@ -1,5 +1,6 @@ /* GObject - GLib Type, Object, Parameter and Signal Library * Copyright (C) 1997-1999, 2000-2001 Tim Janik and Red Hat, Inc. + * Copyright © 2010 Christian Persch * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -361,6 +362,63 @@ value_lcopy_pointer (const GValue *value, return NULL; } +static void +value_free_variant (GValue *value) +{ + if (!(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS) && + value->data[0].v_pointer) + g_variant_unref (value->data[0].v_pointer); +} + +static void +value_copy_variant (const GValue *src_value, + GValue *dest_value) +{ + if (src_value->data[0].v_pointer) + dest_value->data[0].v_pointer = g_variant_ref_sink (src_value->data[0].v_pointer); + else + dest_value->data[0].v_pointer = NULL; +} + +static gchar* +value_collect_variant (GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags) +{ + if (!collect_values[0].v_pointer) + value->data[0].v_pointer = NULL; + else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) + { + value->data[0].v_pointer = collect_values[0].v_pointer; + value->data[1].v_uint = G_VALUE_NOCOPY_CONTENTS; + } + else + value->data[0].v_pointer = g_variant_ref_sink (collect_values[0].v_pointer); + + return NULL; +} + +static gchar* +value_lcopy_variant (const GValue *value, + guint n_collect_values, + GTypeCValue *collect_values, + guint collect_flags) +{ + GVariant **variant_p = collect_values[0].v_pointer; + + if (!variant_p) + return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value)); + + if (!value->data[0].v_pointer) + *variant_p = NULL; + else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) + *variant_p = value->data[0].v_pointer; + else + *variant_p = g_variant_ref_sink (value->data[0].v_pointer); + + return NULL; +} /* --- type initialization --- */ void @@ -550,6 +608,24 @@ g_value_types_init (void) type = g_type_register_fundamental (G_TYPE_POINTER, g_intern_static_string ("gpointer"), &info, &finfo, 0); g_assert (type == G_TYPE_POINTER); } + + /* G_TYPE_VARIANT + */ + { + static const GTypeValueTable value_table = { + value_init_pointer, /* value_init */ + value_free_variant, /* value_free */ + value_copy_variant, /* value_copy */ + value_peek_pointer0, /* value_peek_pointer */ + "p", /* collect_format */ + value_collect_variant, /* collect_value */ + "p", /* lcopy_format */ + value_lcopy_variant, /* lcopy_value */ + }; + info.value_table = &value_table; + type = g_type_register_fundamental (G_TYPE_VARIANT, g_intern_static_string ("GVariant"), &info, &finfo, 0); + g_assert (type == G_TYPE_VARIANT); + } } @@ -1101,6 +1177,78 @@ g_value_get_gtype (const GValue *value) return value->data[0].v_long; } +/** + * g_value_set_variant: + * @value: a valid #GValue of %G_TYPE_VARIANT + * @variant: a #GVariant, or %NULL + * + * Set the contents of a variant #GValue to @variant. + * If the variant is floating, it is consumed. + * + * Since: 2.26 + */ +void +g_value_set_variant (GValue *value, + GVariant *variant) +{ + GVariant *old_variant; + + g_return_if_fail (G_VALUE_HOLDS_VARIANT (value)); + + old_variant = value->data[0].v_pointer; + + if (variant) + value->data[0].v_pointer = g_variant_ref_sink (variant); + else + value->data[0].v_pointer = NULL; + + if (old_variant) + g_variant_unref (old_variant); +} + +/** + * g_value_get_variant: + * @value: a valid #GValue of %G_TYPE_VARIANT + * + * Get the contents of a variant #GValue. + * + * Returns: variant contents of @value + * + * Since: 2.26 + */ +GVariant* +g_value_get_variant (const GValue *value) +{ + g_return_val_if_fail (G_VALUE_HOLDS_VARIANT (value), NULL); + + return value->data[0].v_pointer; +} + +/** + * g_value_get_variant: + * @value: a valid #GValue of %G_TYPE_VARIANT + * + * Get the contents of a variant #GValue, increasing its refcount. + * + * Returns: variant contents of @value, should be unrefed using + * g_variant_unref() when no longer needed + * + * Since: 2.26 + */ +GVariant* +g_value_dup_variant (const GValue *value) +{ + GVariant *variant; + + g_return_val_if_fail (G_VALUE_HOLDS_VARIANT (value), NULL); + + variant = value->data[0].v_pointer; + if (variant) + g_variant_ref_sink (variant); + + return variant; +} + /** * g_strdup_value_contents: * @value: #GValue which contents are to be described. diff --git a/gobject/gvaluetypes.h b/gobject/gvaluetypes.h index 638578337..d5e27c9ee 100644 --- a/gobject/gvaluetypes.h +++ b/gobject/gvaluetypes.h @@ -163,6 +163,17 @@ G_BEGIN_DECLS * Returns: %TRUE on success. */ #define G_VALUE_HOLDS_GTYPE(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_GTYPE)) +/** + * G_VALUE_HOLDS_VARIANT: + * @value: a valid #GValue structure + * + * Checks whether the given #GValue can hold values of type %G_TYPE_VARIANT. + * + * Returns: %TRUE on success. + * + * Since: 2.26 + */ +#define G_VALUE_HOLDS_VARIANT(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_VARIANT)) /* --- prototypes --- */ @@ -212,6 +223,10 @@ GType g_gtype_get_type (void); void g_value_set_gtype (GValue *value, GType v_gtype); GType g_value_get_gtype (const GValue *value); +void g_value_set_variant (GValue *value, + GVariant *variant); +GVariant* g_value_get_variant (const GValue *value); +GVariant* g_value_dup_variant (const GValue *value); /* Convenience for registering new pointer types */ diff --git a/tests/gobject/gvalue-test.c b/tests/gobject/gvalue-test.c index 2d721e032..516a484a1 100644 --- a/tests/gobject/gvalue-test.c +++ b/tests/gobject/gvalue-test.c @@ -219,6 +219,15 @@ test_collection (void) error = collect (&value, G_TYPE_BOXED); g_assert (error == NULL); g_assert (g_value_get_gtype (&value) == G_TYPE_BOXED); + + g_value_unset (&value); + g_value_init (&value, G_TYPE_VARIANT); + error = collect (&value, g_variant_new_uint32 (42)); + g_assert (error == NULL); + g_assert (g_variant_is_of_type (g_value_get_variant (&value), G_VARIANT_TYPE ("u"))); + g_assert_cmpuint (g_variant_get_uint32 (g_value_get_variant (&value)), ==, 42); + + g_value_unset (&value); } static void @@ -357,18 +366,33 @@ test_copying (void) g_assert (error == NULL); g_assert (c == G_TYPE_BOXED); } + + { + GVariant *c = NULL; + + g_value_unset (&value); + g_value_init (&value, G_TYPE_VARIANT); + g_value_set_variant (&value, g_variant_new_uint32 (42)); + error = lcopy (&value, &c); + g_assert (error == NULL); + g_assert (c != NULL); + g_assert (g_variant_is_of_type (c, G_VARIANT_TYPE ("u"))); + g_assert_cmpuint (g_variant_get_uint32 (c), ==, 42); + g_variant_unref (c); + } } int main (int argc, char *argv[]) { - g_type_init (); - - test_enum_transformation (); - test_gtype_value (); - test_collection (); - test_copying (); + g_test_init (&argc, &argv, NULL); + g_type_init (); - return 0; + g_test_add_func ("/gvalue/enum-transformation", test_enum_transformation); + g_test_add_func ("/gvalue/gtype", test_gtype_value); + g_test_add_func ("/gvalue/collection", test_collection); + g_test_add_func ("/gvalue/copying", test_copying); + + return g_test_run (); } diff --git a/tests/gobject/paramspec-test.c b/tests/gobject/paramspec-test.c index 498aed0b0..6de850fe4 100644 --- a/tests/gobject/paramspec-test.c +++ b/tests/gobject/paramspec-test.c @@ -206,15 +206,47 @@ test_param_spec_gtype (void) g_assert (!modified && g_value_get_gtype (&value) == G_TYPE_PARAM_INT); } +static void +test_param_spec_variant (void) +{ + GParamSpec *pspec; + GValue value = { 0, }; + gboolean modified; + + pspec = g_param_spec_variant ("variant", "nick", "blurb", + G_VARIANT_TYPE ("i"), + g_variant_new_int32 (42), + G_PARAM_READWRITE); + + g_value_init (&value, G_TYPE_VARIANT); + g_value_set_variant (&value, g_variant_new_int32 (42)); + + g_assert (g_param_value_defaults (pspec, &value)); + + modified = g_param_value_validate (pspec, &value); + g_assert (!modified); + + g_value_reset (&value); + g_value_set_variant (&value, g_variant_new_uint32 (41)); + modified = g_param_value_validate (pspec, &value); + g_assert (modified); + g_assert_cmpint (g_variant_get_int32 (g_value_get_variant (&value)), ==, 42); + g_value_unset (&value); + + g_param_spec_unref (pspec); +} + int main (int argc, char *argv[]) { - g_type_init (); - - test_param_spec_char (); - test_param_spec_string (); - test_param_spec_override (); - test_param_spec_gtype (); + g_test_init (&argc, &argv, NULL); + g_type_init (); - return 0; + g_test_add_func ("/paramspec/char", test_param_spec_char); + g_test_add_func ("/paramspec/string", test_param_spec_string); + g_test_add_func ("/paramspec/override", test_param_spec_override); + g_test_add_func ("/paramspec/gtype", test_param_spec_gtype); + g_test_add_func ("/paramspec/variant", test_param_spec_variant); + + return g_test_run (); }