| 
							
							
							
						 |  |  | @@ -0,0 +1,505 @@ | 
		
	
		
			
				|  |  |  |  | /* GObject - GLib Type, Object, Parameter and Signal Library | 
		
	
		
			
				|  |  |  |  |  * Copyright (C) 2001, 2003 Red Hat, Inc. | 
		
	
		
			
				|  |  |  |  |  * | 
		
	
		
			
				|  |  |  |  |  * This library is free software; you can redistribute it and/or | 
		
	
		
			
				|  |  |  |  |  * modify it under the terms of the GNU Lesser General Public | 
		
	
		
			
				|  |  |  |  |  * License as published by the Free Software Foundation; either | 
		
	
		
			
				|  |  |  |  |  * version 2 of the License, or (at your option) any later version. | 
		
	
		
			
				|  |  |  |  |  * | 
		
	
		
			
				|  |  |  |  |  * This library is distributed in the hope that it will be useful, | 
		
	
		
			
				|  |  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
		
	
		
			
				|  |  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
		
	
		
			
				|  |  |  |  |  * Lesser General Public License for more details. | 
		
	
		
			
				|  |  |  |  |  * | 
		
	
		
			
				|  |  |  |  |  * You should have received a copy of the GNU Lesser General | 
		
	
		
			
				|  |  |  |  |  * Public License along with this library; if not, write to the | 
		
	
		
			
				|  |  |  |  |  * Free Software Foundation, Inc., 59 Temple Place, Suite 330, | 
		
	
		
			
				|  |  |  |  |  * Boston, MA 02111-1307, USA. | 
		
	
		
			
				|  |  |  |  |  */ | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | #undef	G_LOG_DOMAIN | 
		
	
		
			
				|  |  |  |  | #define	G_LOG_DOMAIN "TestIfaceProperties" | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | #undef G_DISABLE_ASSERT | 
		
	
		
			
				|  |  |  |  | #undef G_DISABLE_CHECKS | 
		
	
		
			
				|  |  |  |  | #undef G_DISABLE_CAST_CHECKS | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | #include <string.h> | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | #include <glib-object.h> | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | #include "testcommon.h" | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | /* This test tests interface properties, implementing interface | 
		
	
		
			
				|  |  |  |  |  * properties and #GParamSpecOverride. | 
		
	
		
			
				|  |  |  |  |  * | 
		
	
		
			
				|  |  |  |  |  * Four properties are tested: | 
		
	
		
			
				|  |  |  |  |  * | 
		
	
		
			
				|  |  |  |  |  * prop1: Defined in TestIface, Implemented in BaseObject with a GParamSpecOverride | 
		
	
		
			
				|  |  |  |  |  * prop2: Defined in TestIface, Implemented in BaseObject with a new property | 
		
	
		
			
				|  |  |  |  |  * prop3: Defined in TestIface, Implemented in BaseObject, Overridden in DerivedObject | 
		
	
		
			
				|  |  |  |  |  * prop4: Defined in BaseObject, Overridden in DerivedObject | 
		
	
		
			
				|  |  |  |  |  */ | 
		
	
		
			
				|  |  |  |  |     | 
		
	
		
			
				|  |  |  |  | static GType base_object_get_type (); | 
		
	
		
			
				|  |  |  |  | static GType derived_object_get_type (); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | enum { | 
		
	
		
			
				|  |  |  |  |   BASE_PROP_0, | 
		
	
		
			
				|  |  |  |  |   BASE_PROP1, | 
		
	
		
			
				|  |  |  |  |   BASE_PROP2, | 
		
	
		
			
				|  |  |  |  |   BASE_PROP3, | 
		
	
		
			
				|  |  |  |  |   BASE_PROP4 | 
		
	
		
			
				|  |  |  |  | }; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | enum { | 
		
	
		
			
				|  |  |  |  |   DERIVED_PROP_0, | 
		
	
		
			
				|  |  |  |  |   DERIVED_PROP3, | 
		
	
		
			
				|  |  |  |  |   DERIVED_PROP4 | 
		
	
		
			
				|  |  |  |  | }; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | /* | 
		
	
		
			
				|  |  |  |  |  * BaseObject, a parent class for DerivedObject | 
		
	
		
			
				|  |  |  |  |  */ | 
		
	
		
			
				|  |  |  |  | #define BASE_TYPE_OBJECT          (base_object_get_type ()) | 
		
	
		
			
				|  |  |  |  | #define BASE_OBJECT(obj)	  (G_TYPE_CHECK_INSTANCE_CAST ((obj), BASE_TYPE_OBJECT, BaseObject)) | 
		
	
		
			
				|  |  |  |  | typedef struct _BaseObject        BaseObject; | 
		
	
		
			
				|  |  |  |  | typedef struct _BaseObjectClass   BaseObjectClass; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | struct _BaseObject | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |   GObject parent_instance; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   gint val1; | 
		
	
		
			
				|  |  |  |  |   gint val2; | 
		
	
		
			
				|  |  |  |  |   gint val3; | 
		
	
		
			
				|  |  |  |  |   gint val4; | 
		
	
		
			
				|  |  |  |  | }; | 
		
	
		
			
				|  |  |  |  | struct _BaseObjectClass | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |   GObjectClass parent_class; | 
		
	
		
			
				|  |  |  |  | }; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | GObjectClass *base_parent_class; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | /* | 
		
	
		
			
				|  |  |  |  |  * DerivedObject, the child class of DerivedObject | 
		
	
		
			
				|  |  |  |  |  */ | 
		
	
		
			
				|  |  |  |  | #define DERIVED_TYPE_OBJECT          (derived_object_get_type ()) | 
		
	
		
			
				|  |  |  |  | typedef struct _DerivedObject        DerivedObject; | 
		
	
		
			
				|  |  |  |  | typedef struct _DerivedObjectClass   DerivedObjectClass; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | struct _DerivedObject | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |   BaseObject parent_instance; | 
		
	
		
			
				|  |  |  |  | }; | 
		
	
		
			
				|  |  |  |  | struct _DerivedObjectClass | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |   BaseObjectClass parent_class; | 
		
	
		
			
				|  |  |  |  | }; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | /* | 
		
	
		
			
				|  |  |  |  |  * The interface | 
		
	
		
			
				|  |  |  |  |  */ | 
		
	
		
			
				|  |  |  |  | typedef struct _TestIfaceClass TestIfaceClass; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | struct _TestIfaceClass | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |   GTypeInterface base_iface; | 
		
	
		
			
				|  |  |  |  | }; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | #define TEST_TYPE_IFACE (test_iface_get_type ()) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | /* The paramspecs installed on our interface | 
		
	
		
			
				|  |  |  |  |  */ | 
		
	
		
			
				|  |  |  |  | static GParamSpec *iface_spec1, *iface_spec2, *iface_spec3; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | /* The paramspecs inherited by our derived object | 
		
	
		
			
				|  |  |  |  |  */ | 
		
	
		
			
				|  |  |  |  | static GParamSpec *inherited_spec1, *inherited_spec2, *inherited_spec3, *inherited_spec4; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | static void | 
		
	
		
			
				|  |  |  |  | test_iface_default_init (TestIfaceClass *iface_vtable) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |   inherited_spec1 = iface_spec1 = g_param_spec_int ("prop1", | 
		
	
		
			
				|  |  |  |  | 						    "Prop1", | 
		
	
		
			
				|  |  |  |  | 						    "Property 1", | 
		
	
		
			
				|  |  |  |  | 						    G_MININT, /* min */ | 
		
	
		
			
				|  |  |  |  | 						    0xFFFF,  /* max */ | 
		
	
		
			
				|  |  |  |  | 						    42,       /* default */ | 
		
	
		
			
				|  |  |  |  | 						    G_PARAM_READWRITE | G_PARAM_CONSTRUCT); | 
		
	
		
			
				|  |  |  |  |   g_object_interface_install_property (iface_vtable, iface_spec1); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   iface_spec2 = g_param_spec_int ("prop2", | 
		
	
		
			
				|  |  |  |  | 				  "Prop2", | 
		
	
		
			
				|  |  |  |  | 				  "Property 2", | 
		
	
		
			
				|  |  |  |  | 				  G_MININT, /* min */ | 
		
	
		
			
				|  |  |  |  | 				  G_MAXINT, /* max */ | 
		
	
		
			
				|  |  |  |  | 				  0,	       /* default */ | 
		
	
		
			
				|  |  |  |  | 				  G_PARAM_WRITABLE); | 
		
	
		
			
				|  |  |  |  |   g_object_interface_install_property (iface_vtable, iface_spec2); | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |   inherited_spec3 = iface_spec3 = g_param_spec_int ("prop3", | 
		
	
		
			
				|  |  |  |  | 						    "Prop3", | 
		
	
		
			
				|  |  |  |  | 						    "Property 3", | 
		
	
		
			
				|  |  |  |  | 						    G_MININT, /* min */ | 
		
	
		
			
				|  |  |  |  | 						    G_MAXINT, /* max */ | 
		
	
		
			
				|  |  |  |  | 						    0,	       /* default */ | 
		
	
		
			
				|  |  |  |  | 						    G_PARAM_READWRITE); | 
		
	
		
			
				|  |  |  |  |   g_object_interface_install_property (iface_vtable, iface_spec3); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | static DEFINE_IFACE (TestIface, test_iface, NULL, test_iface_default_init) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | static GObject* | 
		
	
		
			
				|  |  |  |  | base_object_constructor  (GType                  type, | 
		
	
		
			
				|  |  |  |  | 			  guint                  n_construct_properties, | 
		
	
		
			
				|  |  |  |  | 			  GObjectConstructParam *construct_properties) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |   /* The constructor is the one place where a GParamSpecOverride is visible | 
		
	
		
			
				|  |  |  |  |    * to the outside world, so we do a bunch of checks here | 
		
	
		
			
				|  |  |  |  |    */ | 
		
	
		
			
				|  |  |  |  |   GValue value1 = { 0, }; | 
		
	
		
			
				|  |  |  |  |   GValue value2 = { 0, }; | 
		
	
		
			
				|  |  |  |  |   GParamSpec *pspec; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   g_assert (n_construct_properties == 1); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   pspec = construct_properties->pspec; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   /* Check we got the param spec we expected | 
		
	
		
			
				|  |  |  |  |    */ | 
		
	
		
			
				|  |  |  |  |   g_assert (G_IS_PARAM_SPEC_OVERRIDE (pspec)); | 
		
	
		
			
				|  |  |  |  |   g_assert (pspec->param_id == BASE_PROP1); | 
		
	
		
			
				|  |  |  |  |   g_assert (strcmp (g_param_spec_get_name (pspec), "prop1") == 0); | 
		
	
		
			
				|  |  |  |  |   g_assert (g_param_spec_get_redirect_target (pspec) == iface_spec1); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   /* Test redirection of the nick and blurb to the redirect target | 
		
	
		
			
				|  |  |  |  |    */ | 
		
	
		
			
				|  |  |  |  |   g_assert (strcmp (g_param_spec_get_nick (pspec), "Prop1") == 0); | 
		
	
		
			
				|  |  |  |  |   g_assert (strcmp (g_param_spec_get_blurb (pspec), "Property 1") == 0); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   /* Test forwarding of the various GParamSpec methods to the redirect target | 
		
	
		
			
				|  |  |  |  |    */ | 
		
	
		
			
				|  |  |  |  |   g_value_init (&value1, G_TYPE_INT); | 
		
	
		
			
				|  |  |  |  |   g_value_init (&value2, G_TYPE_INT); | 
		
	
		
			
				|  |  |  |  |    | 
		
	
		
			
				|  |  |  |  |   g_param_value_set_default (pspec, &value1); | 
		
	
		
			
				|  |  |  |  |   g_assert (g_value_get_int (&value1) == 42); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   g_value_reset (&value1); | 
		
	
		
			
				|  |  |  |  |   g_value_set_int (&value1, 0x10000); | 
		
	
		
			
				|  |  |  |  |   g_assert (g_param_value_validate (pspec, &value1)); | 
		
	
		
			
				|  |  |  |  |   g_assert (g_value_get_int (&value1) == 0xFFFF); | 
		
	
		
			
				|  |  |  |  |   g_assert (!g_param_value_validate (pspec, &value1)); | 
		
	
		
			
				|  |  |  |  |    | 
		
	
		
			
				|  |  |  |  |   g_value_reset (&value1); | 
		
	
		
			
				|  |  |  |  |   g_value_set_int (&value1, 1); | 
		
	
		
			
				|  |  |  |  |   g_value_set_int (&value2, 2); | 
		
	
		
			
				|  |  |  |  |   g_assert (g_param_values_cmp (pspec, &value1, &value2) < 0); | 
		
	
		
			
				|  |  |  |  |   g_assert (g_param_values_cmp (pspec, &value2, &value1) > 0); | 
		
	
		
			
				|  |  |  |  |    | 
		
	
		
			
				|  |  |  |  |   g_value_unset (&value1); | 
		
	
		
			
				|  |  |  |  |   g_value_unset (&value2); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   return base_parent_class->constructor (type, | 
		
	
		
			
				|  |  |  |  | 					 n_construct_properties, | 
		
	
		
			
				|  |  |  |  | 					 construct_properties); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | static void | 
		
	
		
			
				|  |  |  |  | base_object_set_property (GObject      *object, | 
		
	
		
			
				|  |  |  |  | 			  guint         prop_id, | 
		
	
		
			
				|  |  |  |  | 			  const GValue *value, | 
		
	
		
			
				|  |  |  |  | 			  GParamSpec   *pspec) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |   BaseObject *base_object = BASE_OBJECT (object); | 
		
	
		
			
				|  |  |  |  |    | 
		
	
		
			
				|  |  |  |  |   switch (prop_id) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |     case BASE_PROP1: | 
		
	
		
			
				|  |  |  |  |       g_assert (pspec == inherited_spec1); | 
		
	
		
			
				|  |  |  |  |       base_object->val1 = g_value_get_int (value); | 
		
	
		
			
				|  |  |  |  |       break; | 
		
	
		
			
				|  |  |  |  |     case BASE_PROP2: | 
		
	
		
			
				|  |  |  |  |       g_assert (pspec == inherited_spec2); | 
		
	
		
			
				|  |  |  |  |       base_object->val2 = g_value_get_int (value); | 
		
	
		
			
				|  |  |  |  |       break; | 
		
	
		
			
				|  |  |  |  |     case BASE_PROP3: | 
		
	
		
			
				|  |  |  |  |       g_assert_not_reached (); | 
		
	
		
			
				|  |  |  |  |       break; | 
		
	
		
			
				|  |  |  |  |     case BASE_PROP4: | 
		
	
		
			
				|  |  |  |  |       g_assert_not_reached (); | 
		
	
		
			
				|  |  |  |  |       break; | 
		
	
		
			
				|  |  |  |  |     default: | 
		
	
		
			
				|  |  |  |  |       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | 
		
	
		
			
				|  |  |  |  |       break; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | static void | 
		
	
		
			
				|  |  |  |  | base_object_get_property (GObject                *object, | 
		
	
		
			
				|  |  |  |  | 			  guint                   prop_id, | 
		
	
		
			
				|  |  |  |  | 			  GValue                 *value, | 
		
	
		
			
				|  |  |  |  | 			  GParamSpec             *pspec) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |   BaseObject *base_object = BASE_OBJECT (object); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   switch (prop_id) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |     case BASE_PROP1: | 
		
	
		
			
				|  |  |  |  |       g_assert (pspec == inherited_spec1); | 
		
	
		
			
				|  |  |  |  |       g_value_set_int (value, base_object->val1); | 
		
	
		
			
				|  |  |  |  |       break; | 
		
	
		
			
				|  |  |  |  |     case BASE_PROP2: | 
		
	
		
			
				|  |  |  |  |       g_assert (pspec == inherited_spec2); | 
		
	
		
			
				|  |  |  |  |       g_value_set_int (value, base_object->val2); | 
		
	
		
			
				|  |  |  |  |       break; | 
		
	
		
			
				|  |  |  |  |     case BASE_PROP3: | 
		
	
		
			
				|  |  |  |  |       g_assert_not_reached (); | 
		
	
		
			
				|  |  |  |  |       break; | 
		
	
		
			
				|  |  |  |  |     case BASE_PROP4: | 
		
	
		
			
				|  |  |  |  |       g_assert_not_reached (); | 
		
	
		
			
				|  |  |  |  |       break; | 
		
	
		
			
				|  |  |  |  |     default: | 
		
	
		
			
				|  |  |  |  |       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | 
		
	
		
			
				|  |  |  |  |       break; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | static void | 
		
	
		
			
				|  |  |  |  | base_object_notify (GObject    *object, | 
		
	
		
			
				|  |  |  |  | 		    GParamSpec *pspec) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |   /* The property passed to notify is the redirect target, not the | 
		
	
		
			
				|  |  |  |  |    * GParamSpecOverride | 
		
	
		
			
				|  |  |  |  |    */ | 
		
	
		
			
				|  |  |  |  |   g_assert (pspec == inherited_spec1 || | 
		
	
		
			
				|  |  |  |  | 	    pspec == inherited_spec2 || | 
		
	
		
			
				|  |  |  |  | 	    pspec == inherited_spec3 || | 
		
	
		
			
				|  |  |  |  | 	    pspec == inherited_spec4); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | static void | 
		
	
		
			
				|  |  |  |  | base_object_class_init (BaseObjectClass *class) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |   GObjectClass *object_class = G_OBJECT_CLASS (class); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   base_parent_class= g_type_class_peek_parent (class); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   object_class->constructor = base_object_constructor; | 
		
	
		
			
				|  |  |  |  |   object_class->set_property = base_object_set_property; | 
		
	
		
			
				|  |  |  |  |   object_class->get_property = base_object_get_property; | 
		
	
		
			
				|  |  |  |  |   object_class->notify = base_object_notify; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   g_object_class_override_property (object_class, BASE_PROP1, "prop1"); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   /* We override this one using a real property, not GParamSpecOverride | 
		
	
		
			
				|  |  |  |  |    * We change the flags from READONLY to READWRITE to show that we | 
		
	
		
			
				|  |  |  |  |    * can make the flags less restrictive | 
		
	
		
			
				|  |  |  |  |    */ | 
		
	
		
			
				|  |  |  |  |   inherited_spec2 = g_param_spec_int ("prop2", | 
		
	
		
			
				|  |  |  |  | 				      "Prop2", | 
		
	
		
			
				|  |  |  |  | 				      "Property 2", | 
		
	
		
			
				|  |  |  |  | 				      G_MININT, /* min */ | 
		
	
		
			
				|  |  |  |  | 				      G_MAXINT, /* max */ | 
		
	
		
			
				|  |  |  |  | 				      0,	       /* default */ | 
		
	
		
			
				|  |  |  |  | 				      G_PARAM_READWRITE); | 
		
	
		
			
				|  |  |  |  |   g_object_class_install_property (object_class, BASE_PROP2, inherited_spec2); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   g_object_class_override_property (object_class, BASE_PROP3, "prop3"); | 
		
	
		
			
				|  |  |  |  |    | 
		
	
		
			
				|  |  |  |  |   inherited_spec4 = g_param_spec_int ("prop4", | 
		
	
		
			
				|  |  |  |  | 				      "Prop4", | 
		
	
		
			
				|  |  |  |  | 				      "Property 4", | 
		
	
		
			
				|  |  |  |  | 				      G_MININT, /* min */ | 
		
	
		
			
				|  |  |  |  | 				      G_MAXINT, /* max */ | 
		
	
		
			
				|  |  |  |  | 				      0,	       /* default */ | 
		
	
		
			
				|  |  |  |  | 				      G_PARAM_READWRITE); | 
		
	
		
			
				|  |  |  |  |   g_object_class_install_property (object_class, BASE_PROP4, inherited_spec4); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | static void | 
		
	
		
			
				|  |  |  |  | base_object_init (BaseObject *base_object) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |   base_object->val1 = 42; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | static DEFINE_TYPE_FULL (BaseObject, base_object, | 
		
	
		
			
				|  |  |  |  | 			 base_object_class_init, NULL, base_object_init, | 
		
	
		
			
				|  |  |  |  | 			 G_TYPE_OBJECT, | 
		
	
		
			
				|  |  |  |  | 			 INTERFACE (NULL, TEST_TYPE_IFACE)) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | static void | 
		
	
		
			
				|  |  |  |  | derived_object_set_property (GObject      *object, | 
		
	
		
			
				|  |  |  |  | 			     guint         prop_id, | 
		
	
		
			
				|  |  |  |  | 			     const GValue *value, | 
		
	
		
			
				|  |  |  |  | 			     GParamSpec   *pspec) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |   BaseObject *base_object = BASE_OBJECT (object); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   switch (prop_id) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |     case DERIVED_PROP3: | 
		
	
		
			
				|  |  |  |  |       g_assert (pspec == inherited_spec3); | 
		
	
		
			
				|  |  |  |  |       base_object->val3 = g_value_get_int (value); | 
		
	
		
			
				|  |  |  |  |       break; | 
		
	
		
			
				|  |  |  |  |     case DERIVED_PROP4: | 
		
	
		
			
				|  |  |  |  |       g_assert (pspec == inherited_spec4); | 
		
	
		
			
				|  |  |  |  |       base_object->val4 = g_value_get_int (value); | 
		
	
		
			
				|  |  |  |  |       break; | 
		
	
		
			
				|  |  |  |  |     default: | 
		
	
		
			
				|  |  |  |  |       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | 
		
	
		
			
				|  |  |  |  |       break; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | static void | 
		
	
		
			
				|  |  |  |  | derived_object_get_property (GObject                *object, | 
		
	
		
			
				|  |  |  |  | 			     guint                   prop_id, | 
		
	
		
			
				|  |  |  |  | 			     GValue                 *value, | 
		
	
		
			
				|  |  |  |  | 			     GParamSpec             *pspec) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |   BaseObject *base_object = BASE_OBJECT (object); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   switch (prop_id) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |     case DERIVED_PROP3: | 
		
	
		
			
				|  |  |  |  |       g_assert (pspec == inherited_spec3); | 
		
	
		
			
				|  |  |  |  |       g_value_set_int (value, base_object->val3); | 
		
	
		
			
				|  |  |  |  |       break; | 
		
	
		
			
				|  |  |  |  |     case DERIVED_PROP4: | 
		
	
		
			
				|  |  |  |  |       g_assert (pspec == inherited_spec4); | 
		
	
		
			
				|  |  |  |  |       g_value_set_int (value, base_object->val4); | 
		
	
		
			
				|  |  |  |  |       break; | 
		
	
		
			
				|  |  |  |  |     default: | 
		
	
		
			
				|  |  |  |  |       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | 
		
	
		
			
				|  |  |  |  |       break; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | static void | 
		
	
		
			
				|  |  |  |  | derived_object_class_init (DerivedObjectClass *class) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |   GObjectClass *object_class = G_OBJECT_CLASS (class); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   object_class->set_property = derived_object_set_property; | 
		
	
		
			
				|  |  |  |  |   object_class->get_property = derived_object_get_property; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   /* Overriding a property that is itself overridding an interface property */ | 
		
	
		
			
				|  |  |  |  |   g_object_class_override_property (object_class, DERIVED_PROP3, "prop3"); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   /* Overriding a property not from an interface */ | 
		
	
		
			
				|  |  |  |  |   g_object_class_override_property (object_class, DERIVED_PROP4, "prop4"); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | static DEFINE_TYPE (DerivedObject, derived_object, | 
		
	
		
			
				|  |  |  |  | 		    derived_object_class_init, NULL, NULL, | 
		
	
		
			
				|  |  |  |  | 		    BASE_TYPE_OBJECT) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | /* Helper function for testing ...list_properties() | 
		
	
		
			
				|  |  |  |  |  */ | 
		
	
		
			
				|  |  |  |  | static void | 
		
	
		
			
				|  |  |  |  | assert_in_properties (GParamSpec  *param_spec, | 
		
	
		
			
				|  |  |  |  | 		      GParamSpec **properties, | 
		
	
		
			
				|  |  |  |  | 		      gint         n_properties) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |   gint i; | 
		
	
		
			
				|  |  |  |  |   gboolean found = FALSE; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   for (i = 0; i < n_properties; i++) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       if (properties[i] == param_spec) | 
		
	
		
			
				|  |  |  |  | 	found = TRUE; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   g_assert (found); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | int | 
		
	
		
			
				|  |  |  |  | main (gint   argc, | 
		
	
		
			
				|  |  |  |  |       gchar *argv[]) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |   BaseObject *object; | 
		
	
		
			
				|  |  |  |  |   GObjectClass *object_class; | 
		
	
		
			
				|  |  |  |  |   TestIfaceClass *iface_vtable; | 
		
	
		
			
				|  |  |  |  |   GParamSpec **properties; | 
		
	
		
			
				|  |  |  |  |   gint n_properties; | 
		
	
		
			
				|  |  |  |  |    | 
		
	
		
			
				|  |  |  |  |   gint val1, val2, val3, val4; | 
		
	
		
			
				|  |  |  |  | 	 | 
		
	
		
			
				|  |  |  |  |   g_log_set_always_fatal (g_log_set_always_fatal (G_LOG_FATAL_MASK) | | 
		
	
		
			
				|  |  |  |  | 			  G_LOG_LEVEL_WARNING | | 
		
	
		
			
				|  |  |  |  | 			  G_LOG_LEVEL_CRITICAL); | 
		
	
		
			
				|  |  |  |  |   g_type_init (); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   object = g_object_new (DERIVED_TYPE_OBJECT, NULL); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   /* Test setting and getting the properties | 
		
	
		
			
				|  |  |  |  |    */ | 
		
	
		
			
				|  |  |  |  |   g_object_set (object, | 
		
	
		
			
				|  |  |  |  | 		"prop1", 0x0101, | 
		
	
		
			
				|  |  |  |  | 		"prop2", 0x0202, | 
		
	
		
			
				|  |  |  |  | 		"prop3", 0x0303, | 
		
	
		
			
				|  |  |  |  | 		"prop4", 0x0404); | 
		
	
		
			
				|  |  |  |  |   g_object_get (object, | 
		
	
		
			
				|  |  |  |  | 		"prop1", &val1, | 
		
	
		
			
				|  |  |  |  | 		"prop2", &val2, | 
		
	
		
			
				|  |  |  |  | 		"prop3", &val3, | 
		
	
		
			
				|  |  |  |  | 		"prop4", &val4); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   g_assert (val1 == 0x0101); | 
		
	
		
			
				|  |  |  |  |   g_assert (val2 == 0x0202); | 
		
	
		
			
				|  |  |  |  |   g_assert (val3 == 0x0303); | 
		
	
		
			
				|  |  |  |  |   g_assert (val4 == 0x0404); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   /* Test that the right spec is passed on explicit notifications | 
		
	
		
			
				|  |  |  |  |    */ | 
		
	
		
			
				|  |  |  |  |   g_object_freeze_notify (G_OBJECT (object)); | 
		
	
		
			
				|  |  |  |  |   g_object_notify (G_OBJECT (object), "prop1"); | 
		
	
		
			
				|  |  |  |  |   g_object_notify (G_OBJECT (object), "prop2"); | 
		
	
		
			
				|  |  |  |  |   g_object_notify (G_OBJECT (object), "prop3"); | 
		
	
		
			
				|  |  |  |  |   g_object_notify (G_OBJECT (object), "prop4"); | 
		
	
		
			
				|  |  |  |  |   g_object_thaw_notify (G_OBJECT (object)); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   /* Test g_object_class_find_property() for overridden properties | 
		
	
		
			
				|  |  |  |  |    */ | 
		
	
		
			
				|  |  |  |  |   object_class = G_OBJECT_GET_CLASS (object); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   g_assert (g_object_class_find_property (object_class, "prop1") == inherited_spec1); | 
		
	
		
			
				|  |  |  |  |   g_assert (g_object_class_find_property (object_class, "prop2") == inherited_spec2); | 
		
	
		
			
				|  |  |  |  |   g_assert (g_object_class_find_property (object_class, "prop3") == inherited_spec3); | 
		
	
		
			
				|  |  |  |  |   g_assert (g_object_class_find_property (object_class, "prop4") == inherited_spec4); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   /* Test g_object_class_list_properties() for overridden properties | 
		
	
		
			
				|  |  |  |  |    */ | 
		
	
		
			
				|  |  |  |  |   properties = g_object_class_list_properties (object_class, &n_properties); | 
		
	
		
			
				|  |  |  |  |   g_assert (n_properties == 4); | 
		
	
		
			
				|  |  |  |  |   assert_in_properties (inherited_spec1, properties, n_properties); | 
		
	
		
			
				|  |  |  |  |   assert_in_properties (inherited_spec2, properties, n_properties); | 
		
	
		
			
				|  |  |  |  |   assert_in_properties (inherited_spec3, properties, n_properties); | 
		
	
		
			
				|  |  |  |  |   assert_in_properties (inherited_spec4, properties, n_properties); | 
		
	
		
			
				|  |  |  |  |   g_free (properties); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   /* Test g_object_interface_find_property() | 
		
	
		
			
				|  |  |  |  |    */ | 
		
	
		
			
				|  |  |  |  |   iface_vtable = g_type_default_interface_peek (TEST_TYPE_IFACE); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   g_assert (g_object_interface_find_property (iface_vtable, "prop1") == iface_spec1); | 
		
	
		
			
				|  |  |  |  |   g_assert (g_object_interface_find_property (iface_vtable, "prop2") == iface_spec2); | 
		
	
		
			
				|  |  |  |  |   g_assert (g_object_interface_find_property (iface_vtable, "prop3") == iface_spec3); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   /* Test g_object_interface_list_properties() | 
		
	
		
			
				|  |  |  |  |    */ | 
		
	
		
			
				|  |  |  |  |   properties = g_object_interface_list_properties (iface_vtable, &n_properties); | 
		
	
		
			
				|  |  |  |  |   g_assert (n_properties == 3); | 
		
	
		
			
				|  |  |  |  |   assert_in_properties (iface_spec1, properties, n_properties); | 
		
	
		
			
				|  |  |  |  |   assert_in_properties (iface_spec2, properties, n_properties); | 
		
	
		
			
				|  |  |  |  |   assert_in_properties (iface_spec3, properties, n_properties); | 
		
	
		
			
				|  |  |  |  |   g_free (properties); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   g_object_unref (object); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   return 0; | 
		
	
		
			
				|  |  |  |  | } |