glib/libgobject/src/gobject.c
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 /* GObject - GLib Type, Object, Parameter and Signal Library
       
     2  * Copyright (C) 1998-1999, 2000-2001 Tim Janik and Red Hat, Inc.
       
     3  * Portions copyright (c) 2006 Nokia Corporation.  All rights reserved.
       
     4  *
       
     5  * This library is free software; you can redistribute it and/or
       
     6  * modify it under the terms of the GNU Lesser General Public
       
     7  * License as published by the Free Software Foundation; either
       
     8  * version 2 of the License, or (at your option) any later version.
       
     9  *
       
    10  * This library is distributed in the hope that it will be useful,
       
    11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
       
    13  * Lesser General Public License for more details.
       
    14  *
       
    15  * You should have received a copy of the GNU Lesser General
       
    16  * Public License along with this library; if not, write to the
       
    17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
       
    18  * Boston, MA 02111-1307, USA.
       
    19  */
       
    20 #include	"gobject.h"
       
    21 #include	"gobjectalias.h"
       
    22 #ifndef __SYMBIAN32__
       
    23 #include        <glib/gdatasetprivate.h>
       
    24 #else
       
    25 #include <gdatasetprivate.h>
       
    26 #endif /* __SYMBIAN32__ */
       
    27 /*
       
    28  * MT safe with regards to reference counting.
       
    29  */
       
    30  #ifdef __SYMBIAN32__
       
    31 #include <glib_global.h>
       
    32 #include <gobject_wsd.h>
       
    33 #include <gobject_global.h>
       
    34 #endif /* __SYMBIAN32__ */
       
    35 
       
    36 #include	"gvaluecollector.h"
       
    37 #include	"gsignal.h"
       
    38 #include	"gparamspecs.h"
       
    39 #include	"gvaluetypes.h"
       
    40 #include	"gobjectnotifyqueue.c"
       
    41 #include	<string.h>
       
    42 #ifndef __SYMBIAN32__
       
    43 #include	<signal.h>
       
    44 #endif /* __SYMBIAN32__ */
       
    45 
       
    46 
       
    47 #define	PREALLOC_CPARAMS	(8)
       
    48 
       
    49 
       
    50 /* --- macros --- */
       
    51 #define PARAM_SPEC_PARAM_ID(pspec)		((pspec)->param_id)
       
    52 #define	PARAM_SPEC_SET_PARAM_ID(pspec, id)	((pspec)->param_id = (id))
       
    53 
       
    54 #define OBJECT_HAS_TOGGLE_REF_FLAG 0x1
       
    55 #define OBJECT_HAS_TOGGLE_REF(object) \
       
    56     ((G_DATALIST_GET_FLAGS (&(object)->qdata) & OBJECT_HAS_TOGGLE_REF_FLAG) != 0)
       
    57 #define OBJECT_FLOATING_FLAG 0x2
       
    58 
       
    59 
       
    60 /* --- signals --- */
       
    61 enum {
       
    62   NOTIFY,
       
    63   LAST_SIGNAL
       
    64 };
       
    65 
       
    66 
       
    67 /* --- properties --- */
       
    68 enum {
       
    69   PROP_NONE
       
    70 };
       
    71 
       
    72 
       
    73 /* --- prototypes --- */
       
    74 static void	g_object_base_class_init		(GObjectClass	*class);
       
    75 static void	g_object_base_class_finalize		(GObjectClass	*class);
       
    76 static void	g_object_do_class_init			(GObjectClass	*class);
       
    77 static void	g_object_init				(GObject	*object);
       
    78 static GObject*	g_object_constructor			(GType                  type,
       
    79 							 guint                  n_construct_properties,
       
    80 							 GObjectConstructParam *construct_params);
       
    81 static void	g_object_real_dispose			(GObject	*object);
       
    82 static void	g_object_finalize			(GObject	*object);
       
    83 static void	g_object_do_set_property		(GObject        *object,
       
    84 							 guint           property_id,
       
    85 							 const GValue   *value,
       
    86 							 GParamSpec     *pspec);
       
    87 static void	g_object_do_get_property		(GObject        *object,
       
    88 							 guint           property_id,
       
    89 							 GValue         *value,
       
    90 							 GParamSpec     *pspec);
       
    91 static void	g_value_object_init			(GValue		*value);
       
    92 static void	g_value_object_free_value		(GValue		*value);
       
    93 static void	g_value_object_copy_value		(const GValue	*src_value,
       
    94 							 GValue		*dest_value);
       
    95 static void	g_value_object_transform_value		(const GValue	*src_value,
       
    96 							 GValue		*dest_value);
       
    97 static gpointer g_value_object_peek_pointer             (const GValue   *value);
       
    98 static gchar*	g_value_object_collect_value		(GValue		*value,
       
    99 							 guint           n_collect_values,
       
   100 							 GTypeCValue    *collect_values,
       
   101 							 guint           collect_flags);
       
   102 static gchar*	g_value_object_lcopy_value		(const GValue	*value,
       
   103 							 guint           n_collect_values,
       
   104 							 GTypeCValue    *collect_values,
       
   105 							 guint           collect_flags);
       
   106 static void	g_object_dispatch_properties_changed	(GObject	*object,
       
   107 							 guint		 n_pspecs,
       
   108 							 GParamSpec    **pspecs);
       
   109 static inline void         object_get_property		(GObject        *object,
       
   110 							 GParamSpec     *pspec,
       
   111 							 GValue         *value);
       
   112 static inline void	   object_set_property		(GObject        *object,
       
   113 							 GParamSpec     *pspec,
       
   114 							 const GValue   *value,
       
   115 							 GObjectNotifyQueue *nqueue);
       
   116 #if (EMULATOR)							 
       
   117 guint               object_floating_flag_handler (GObject        *object,
       
   118                                                          gint            job);
       
   119 #else
       
   120 static guint               object_floating_flag_handler (GObject        *object,
       
   121                                                          gint            job);
       
   122 #endif /* EMULATOR */
       
   123 static void object_interface_check_properties           (gpointer        func_data,
       
   124 							 gpointer        g_iface);
       
   125 
       
   126 
       
   127 /* --- variables --- */
       
   128 #if EMULATOR
       
   129 
       
   130 PLS(quark_closure_array,gobject,GQuark)
       
   131 PLS(quark_weak_refs,gobject,GQuark)
       
   132 PLS(quark_toggle_refs,gobject,GQuark)
       
   133 PLS(pspec_pool,gobject,GParamSpecPool *)
       
   134 PLS(property_notify_context,gobject,GObjectNotifyContext)
       
   135 PLS_ARRAY(gobject_signals,gobject,gulong)
       
   136 PLS_MACRO(construct_objects_lock,gobject,GStaticMutex)
       
   137 PLS(construct_objects,gobject,GSList *)
       
   138 PLS(floating_flag_handler,gobject,function_type)
       
   139 
       
   140 #define quark_closure_array (*FUNCTION_NAME(quark_closure_array,gobject)())
       
   141 #define quark_weak_refs (*FUNCTION_NAME(quark_weak_refs,gobject)())
       
   142 #define quark_toggle_refs (*FUNCTION_NAME(quark_toggle_refs,gobject)())
       
   143 #define pspec_pool (*FUNCTION_NAME(pspec_pool,gobject)())
       
   144 #define property_notify_context (*FUNCTION_NAME(property_notify_context,gobject)())
       
   145 #define gobject_signals (FUNCTION_NAME(gobject_signals,gobject)())
       
   146 #define g__construct_objects_lock_lock (*FUNCTION_NAME_MACRO(construct_objects_lock,gobject)())
       
   147 #define construct_objects (*FUNCTION_NAME(construct_objects,gobject)())
       
   148 #define floating_flag_handler (*FUNCTION_NAME(floating_flag_handler,gobject)())
       
   149 
       
   150 #else
       
   151 
       
   152 static GQuark	            quark_closure_array = 0;
       
   153 static GQuark	            quark_weak_refs = 0;
       
   154 static GQuark	            quark_toggle_refs = 0;
       
   155 static GParamSpecPool      *pspec_pool = NULL;
       
   156 static GObjectNotifyContext property_notify_context = { 0, };
       
   157 static gulong	            gobject_signals[LAST_SIGNAL] = { 0, };
       
   158 G_LOCK_DEFINE_STATIC (construct_objects_lock);
       
   159 static GSList *construct_objects = NULL;
       
   160 static guint (*floating_flag_handler) (GObject*, gint) = object_floating_flag_handler;
       
   161 
       
   162 #endif /* EMULATOR */
       
   163 
       
   164 /* --- functions --- */
       
   165 #ifdef	G_ENABLE_DEBUG
       
   166 #define	IF_DEBUG(debug_type)	if (_g_type_debug_flags & G_TYPE_DEBUG_ ## debug_type)
       
   167 #if EMULATOR
       
   168 
       
   169 PLS_MACRO(debug_objects,gobject,GStaticMutex)
       
   170 PLS(g_trap_object_ref,gobject,volatile GObject *)
       
   171 PLS(debug_objects_count,gobject,guint)
       
   172 PLS(debug_objects_ht,gobject,GHashTable	*)
       
   173 
       
   174 #define g__debug_objects_lock (*FUNCTION_NAME_MACRO(debug_objects,gobject)())
       
   175 #define g_trap_object_ref (*FUNCTION_NAME(g_trap_object_ref,gobject)())
       
   176 #define debug_objects_count (*FUNCTION_NAME(debug_objects_count,gobject)())
       
   177 #define debug_objects_ht (*FUNCTION_NAME(debug_objects_ht,gobject)())
       
   178 
       
   179 
       
   180 #else
       
   181 
       
   182 G_LOCK_DEFINE_STATIC     (debug_objects);
       
   183 static volatile GObject *g_trap_object_ref = NULL;
       
   184 static guint		 debug_objects_count = 0;
       
   185 static GHashTable	*debug_objects_ht = NULL;
       
   186 #endif /* EMULATOR */
       
   187 static void
       
   188 debug_objects_foreach (gpointer key,
       
   189 		       gpointer value,
       
   190 		       gpointer user_data)
       
   191 {
       
   192   GObject *object = value;
       
   193 
       
   194   g_message ("[%p] stale %s\tref_count=%u",
       
   195 	     object,
       
   196 	     G_OBJECT_TYPE_NAME (object),
       
   197 	     object->ref_count);
       
   198 }
       
   199 static void
       
   200 debug_objects_atexit (void)
       
   201 {
       
   202   IF_DEBUG (OBJECTS)
       
   203     {
       
   204       G_LOCK (debug_objects);
       
   205       g_message ("stale GObjects: %u", debug_objects_count);
       
   206       g_hash_table_foreach (debug_objects_ht, debug_objects_foreach, NULL);
       
   207       G_UNLOCK (debug_objects);
       
   208     }
       
   209 }
       
   210 #endif	/* G_ENABLE_DEBUG */
       
   211 
       
   212 #if EMULATOR
       
   213 
       
   214 PLS(initialized ,g_object_type_init,gboolean)
       
   215 PLS(info  ,g_object_type_init,GTypeInfo)
       
   216 
       
   217 #define initialized  (*FUNCTION_NAME(initialized ,g_object_type_init)())
       
   218 #define info  (*FUNCTION_NAME(info ,g_object_type_init)())
       
   219 
       
   220 const GTypeInfo gobject_info = {
       
   221 	sizeof (GObjectClass),
       
   222 	(GBaseInitFunc) g_object_base_class_init,
       
   223 	(GBaseFinalizeFunc) g_object_base_class_finalize,
       
   224 	(GClassInitFunc) g_object_do_class_init,
       
   225 	NULL	/* class_destroy */,
       
   226 	NULL	/* class_data */,
       
   227 	sizeof (GObject),
       
   228 	0		/* n_preallocs */,
       
   229 	(GInstanceInitFunc) g_object_init,
       
   230 	NULL,	/* value_table */
       
   231 };
       
   232 
       
   233 
       
   234 #endif /* EMULATOR */
       
   235 
       
   236 void
       
   237 g_object_type_init (void)
       
   238 {
       
   239   #if !(EMULATOR)
       
   240   static gboolean initialized = FALSE;
       
   241   static GTypeInfo info = {
       
   242     sizeof (GObjectClass),
       
   243     (GBaseInitFunc) g_object_base_class_init,
       
   244     (GBaseFinalizeFunc) g_object_base_class_finalize,
       
   245     (GClassInitFunc) g_object_do_class_init,
       
   246     NULL	/* class_destroy */,
       
   247     NULL	/* class_data */,
       
   248     sizeof (GObject),
       
   249     0		/* n_preallocs */,
       
   250     (GInstanceInitFunc) g_object_init,
       
   251     NULL,	/* value_table */
       
   252   };
       
   253   #endif /* EMULATOR */
       
   254   static const GTypeFundamentalInfo finfo = {
       
   255     G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE,
       
   256   };
       
   257 
       
   258   static const GTypeValueTable value_table = {
       
   259     g_value_object_init,	  /* value_init */
       
   260     g_value_object_free_value,	  /* value_free */
       
   261     g_value_object_copy_value,	  /* value_copy */
       
   262     g_value_object_peek_pointer,  /* value_peek_pointer */
       
   263     "p",			  /* collect_format */
       
   264     g_value_object_collect_value, /* collect_value */
       
   265     "p",			  /* lcopy_format */
       
   266     g_value_object_lcopy_value,	  /* lcopy_value */
       
   267   };
       
   268   GType type;
       
   269   
       
   270   g_return_if_fail (initialized == FALSE);
       
   271   initialized = TRUE;
       
   272   
       
   273   /* G_TYPE_OBJECT
       
   274    */
       
   275   info.value_table = &value_table;
       
   276   type = g_type_register_fundamental (G_TYPE_OBJECT, g_intern_static_string ("GObject"), &info, &finfo, 0);
       
   277   g_assert (type == G_TYPE_OBJECT);
       
   278   g_value_register_transform_func (G_TYPE_OBJECT, G_TYPE_OBJECT, g_value_object_transform_value);
       
   279   
       
   280 #ifdef	G_ENABLE_DEBUG
       
   281   IF_DEBUG (OBJECTS)
       
   282     {
       
   283       debug_objects_ht = g_hash_table_new (g_direct_hash, NULL);
       
   284       g_atexit (debug_objects_atexit);
       
   285     }
       
   286 #endif	/* G_ENABLE_DEBUG */
       
   287 }
       
   288 
       
   289 #if EMULATOR
       
   290 #undef initialized
       
   291 #undef info
       
   292 #endif /* EMULATOR */
       
   293 
       
   294 static void
       
   295 g_object_base_class_init (GObjectClass *class)
       
   296 {
       
   297   GObjectClass *pclass = g_type_class_peek_parent (class);
       
   298 
       
   299   /* reset instance specific fields and methods that don't get inherited */
       
   300   class->construct_properties = pclass ? g_slist_copy (pclass->construct_properties) : NULL;
       
   301   class->get_property = NULL;
       
   302   class->set_property = NULL;
       
   303 }
       
   304 
       
   305 static void
       
   306 g_object_base_class_finalize (GObjectClass *class)
       
   307 {
       
   308   GList *list, *node;
       
   309   
       
   310   _g_signals_destroy (G_OBJECT_CLASS_TYPE (class));
       
   311 
       
   312   g_slist_free (class->construct_properties);
       
   313   class->construct_properties = NULL;
       
   314   list = g_param_spec_pool_list_owned (pspec_pool, G_OBJECT_CLASS_TYPE (class));
       
   315   for (node = list; node; node = node->next)
       
   316     {
       
   317       GParamSpec *pspec = node->data;
       
   318       
       
   319       g_param_spec_pool_remove (pspec_pool, pspec);
       
   320       PARAM_SPEC_SET_PARAM_ID (pspec, 0);
       
   321       g_param_spec_unref (pspec);
       
   322     }
       
   323   g_list_free (list);
       
   324 }
       
   325 
       
   326 static void
       
   327 g_object_notify_dispatcher (GObject     *object,
       
   328 			    guint        n_pspecs,
       
   329 			    GParamSpec **pspecs)
       
   330 {
       
   331   G_OBJECT_GET_CLASS (object)->dispatch_properties_changed (object, n_pspecs, pspecs);
       
   332 }
       
   333 
       
   334 static void
       
   335 g_object_do_class_init (GObjectClass *class)
       
   336 {
       
   337   /* read the comment about typedef struct CArray; on why not to change this quark */
       
   338   quark_closure_array = g_quark_from_static_string ("GObject-closure-array");
       
   339 
       
   340   quark_weak_refs = g_quark_from_static_string ("GObject-weak-references");
       
   341   quark_toggle_refs = g_quark_from_static_string ("GObject-toggle-references");
       
   342   pspec_pool = g_param_spec_pool_new (TRUE);
       
   343   property_notify_context.quark_notify_queue = g_quark_from_static_string ("GObject-notify-queue");
       
   344   property_notify_context.dispatcher = g_object_notify_dispatcher;
       
   345   
       
   346   class->constructor = g_object_constructor;
       
   347   class->set_property = g_object_do_set_property;
       
   348   class->get_property = g_object_do_get_property;
       
   349   class->dispose = g_object_real_dispose;
       
   350   class->finalize = g_object_finalize;
       
   351   class->dispatch_properties_changed = g_object_dispatch_properties_changed;
       
   352   class->notify = NULL;
       
   353 
       
   354   gobject_signals[NOTIFY] =
       
   355     g_signal_new (g_intern_static_string ("notify"),
       
   356 		  G_TYPE_FROM_CLASS (class),
       
   357 		  G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED | G_SIGNAL_NO_HOOKS | G_SIGNAL_ACTION,
       
   358 		  G_STRUCT_OFFSET (GObjectClass, notify),
       
   359 		  NULL, NULL,
       
   360 		  g_cclosure_marshal_VOID__PARAM,
       
   361 		  G_TYPE_NONE,
       
   362 		  1, G_TYPE_PARAM);
       
   363 
       
   364   /* Install a check function that we'll use to verify that classes that
       
   365    * implement an interface implement all properties for that interface
       
   366    */
       
   367   g_type_add_interface_check (NULL, object_interface_check_properties);
       
   368 }
       
   369 
       
   370 static void
       
   371 install_property_internal (GType       g_type,
       
   372 			   guint       property_id,
       
   373 			   GParamSpec *pspec)
       
   374 {
       
   375   if (g_param_spec_pool_lookup (pspec_pool, pspec->name, g_type, FALSE))
       
   376     {
       
   377       g_warning ("When installing property: type `%s' already has a property named `%s'",
       
   378 		 g_type_name (g_type),
       
   379 		 pspec->name);
       
   380       return;
       
   381     }
       
   382 
       
   383   g_param_spec_ref (pspec);
       
   384   g_param_spec_sink (pspec);
       
   385   PARAM_SPEC_SET_PARAM_ID (pspec, property_id);
       
   386   g_param_spec_pool_insert (pspec_pool, pspec, g_type);
       
   387 }
       
   388 
       
   389 EXPORT_C void
       
   390 g_object_class_install_property (GObjectClass *class,
       
   391 				 guint	       property_id,
       
   392 				 GParamSpec   *pspec)
       
   393 {
       
   394   g_return_if_fail (G_IS_OBJECT_CLASS (class));
       
   395   g_return_if_fail (G_IS_PARAM_SPEC (pspec));
       
   396   if (pspec->flags & G_PARAM_WRITABLE)
       
   397     g_return_if_fail (class->set_property != NULL);
       
   398   if (pspec->flags & G_PARAM_READABLE)
       
   399     g_return_if_fail (class->get_property != NULL);
       
   400   g_return_if_fail (property_id > 0);
       
   401   g_return_if_fail (PARAM_SPEC_PARAM_ID (pspec) == 0);	/* paranoid */
       
   402   if (pspec->flags & G_PARAM_CONSTRUCT)
       
   403     g_return_if_fail ((pspec->flags & G_PARAM_CONSTRUCT_ONLY) == 0);
       
   404   if (pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY))
       
   405     g_return_if_fail (pspec->flags & G_PARAM_WRITABLE);
       
   406 
       
   407   install_property_internal (G_OBJECT_CLASS_TYPE (class), property_id, pspec);
       
   408 
       
   409   if (pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY))
       
   410     class->construct_properties = g_slist_prepend (class->construct_properties, pspec);
       
   411 
       
   412   /* for property overrides of construct poperties, we have to get rid
       
   413    * of the overidden inherited construct property
       
   414    */
       
   415   pspec = g_param_spec_pool_lookup (pspec_pool, pspec->name, g_type_parent (G_OBJECT_CLASS_TYPE (class)), TRUE);
       
   416   if (pspec && pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY))
       
   417     class->construct_properties = g_slist_remove (class->construct_properties, pspec);
       
   418 }
       
   419 
       
   420 EXPORT_C void
       
   421 g_object_interface_install_property (gpointer      g_iface,
       
   422 				     GParamSpec   *pspec)
       
   423 {
       
   424   GTypeInterface *iface_class = g_iface;
       
   425 	
       
   426   g_return_if_fail (G_TYPE_IS_INTERFACE (iface_class->g_type));
       
   427   g_return_if_fail (G_IS_PARAM_SPEC (pspec));
       
   428   g_return_if_fail (!G_IS_PARAM_SPEC_OVERRIDE (pspec)); /* paranoid */
       
   429   g_return_if_fail (PARAM_SPEC_PARAM_ID (pspec) == 0);	/* paranoid */
       
   430 		    
       
   431   install_property_internal (iface_class->g_type, 0, pspec);
       
   432 }
       
   433 
       
   434 EXPORT_C GParamSpec*
       
   435 g_object_class_find_property (GObjectClass *class,
       
   436 			      const gchar  *property_name)
       
   437 {
       
   438   GParamSpec *pspec;
       
   439   GParamSpec *redirect;
       
   440 	
       
   441   g_return_val_if_fail (G_IS_OBJECT_CLASS (class), NULL);
       
   442   g_return_val_if_fail (property_name != NULL, NULL);
       
   443   
       
   444   pspec = g_param_spec_pool_lookup (pspec_pool,
       
   445 				    property_name,
       
   446 				    G_OBJECT_CLASS_TYPE (class),
       
   447 				    TRUE);
       
   448   if (pspec)
       
   449     {
       
   450       redirect = g_param_spec_get_redirect_target (pspec);
       
   451       if (redirect)
       
   452 	return redirect;
       
   453       else
       
   454 	return pspec;
       
   455     }
       
   456   else
       
   457     return NULL;
       
   458 }
       
   459 
       
   460 EXPORT_C GParamSpec*
       
   461 g_object_interface_find_property (gpointer      g_iface,
       
   462 				  const gchar  *property_name)
       
   463 {
       
   464   GTypeInterface *iface_class = g_iface;
       
   465 	
       
   466   g_return_val_if_fail (G_TYPE_IS_INTERFACE (iface_class->g_type), NULL);
       
   467   g_return_val_if_fail (property_name != NULL, NULL);
       
   468   
       
   469   return g_param_spec_pool_lookup (pspec_pool,
       
   470 				   property_name,
       
   471 				   iface_class->g_type,
       
   472 				   FALSE);
       
   473 }
       
   474 
       
   475 EXPORT_C void
       
   476 g_object_class_override_property (GObjectClass *oclass,
       
   477 				  guint         property_id,
       
   478 				  const gchar  *name)
       
   479 {
       
   480   GParamSpec *overridden = NULL;
       
   481   GParamSpec *new;
       
   482   GType parent_type;
       
   483   
       
   484   g_return_if_fail (G_IS_OBJECT_CLASS (oclass));
       
   485   g_return_if_fail (property_id > 0);
       
   486   g_return_if_fail (name != NULL);
       
   487 
       
   488   /* Find the overridden property; first check parent types
       
   489    */
       
   490   parent_type = g_type_parent (G_OBJECT_CLASS_TYPE (oclass));
       
   491   if (parent_type != G_TYPE_NONE)
       
   492     overridden = g_param_spec_pool_lookup (pspec_pool,
       
   493 					   name,
       
   494 					   parent_type,
       
   495 					   TRUE);
       
   496   if (!overridden)
       
   497     {
       
   498       GType *ifaces;
       
   499       guint n_ifaces;
       
   500       
       
   501       /* Now check interfaces
       
   502        */
       
   503       ifaces = g_type_interfaces (G_OBJECT_CLASS_TYPE (oclass), &n_ifaces);
       
   504       while (n_ifaces-- && !overridden)
       
   505 	{
       
   506 	  overridden = g_param_spec_pool_lookup (pspec_pool,
       
   507 						 name,
       
   508 						 ifaces[n_ifaces],
       
   509 						 FALSE);
       
   510 	}
       
   511       
       
   512       g_free (ifaces);
       
   513     }
       
   514 
       
   515   if (!overridden)
       
   516     {
       
   517       g_warning ("%s: Can't find property to override for '%s::%s'",
       
   518 		 G_STRFUNC, G_OBJECT_CLASS_NAME (oclass), name);
       
   519       return;
       
   520     }
       
   521 
       
   522   new = g_param_spec_override (name, overridden);
       
   523   g_object_class_install_property (oclass, property_id, new);
       
   524 }
       
   525 
       
   526 EXPORT_C GParamSpec** /* free result */
       
   527 g_object_class_list_properties (GObjectClass *class,
       
   528 				guint        *n_properties_p)
       
   529 {
       
   530   GParamSpec **pspecs;
       
   531   guint n;
       
   532 
       
   533   g_return_val_if_fail (G_IS_OBJECT_CLASS (class), NULL);
       
   534 
       
   535   pspecs = g_param_spec_pool_list (pspec_pool,
       
   536 				   G_OBJECT_CLASS_TYPE (class),
       
   537 				   &n);
       
   538   if (n_properties_p)
       
   539     *n_properties_p = n;
       
   540 
       
   541   return pspecs;
       
   542 }
       
   543 
       
   544 EXPORT_C GParamSpec** /* free result */
       
   545 g_object_interface_list_properties (gpointer      g_iface,
       
   546 				    guint        *n_properties_p)
       
   547 {
       
   548   GTypeInterface *iface_class = g_iface;
       
   549   GParamSpec **pspecs;
       
   550   guint n;
       
   551 
       
   552   g_return_val_if_fail (G_TYPE_IS_INTERFACE (iface_class->g_type), NULL);
       
   553 
       
   554   pspecs = g_param_spec_pool_list (pspec_pool,
       
   555 				   iface_class->g_type,
       
   556 				   &n);
       
   557   if (n_properties_p)
       
   558     *n_properties_p = n;
       
   559 
       
   560   return pspecs;
       
   561 }
       
   562 
       
   563 static void
       
   564 g_object_init (GObject *object)
       
   565 {
       
   566   object->ref_count = 1;
       
   567   g_datalist_init (&object->qdata);
       
   568   
       
   569   /* freeze object's notification queue, g_object_newv() preserves pairedness */
       
   570   g_object_notify_queue_freeze (object, &property_notify_context);
       
   571 
       
   572   /* allow construct-only properties to be set */
       
   573   G_LOCK (construct_objects_lock);
       
   574   construct_objects = g_slist_prepend (construct_objects, object);
       
   575   G_UNLOCK (construct_objects_lock);
       
   576   
       
   577 #ifdef	G_ENABLE_DEBUG
       
   578   IF_DEBUG (OBJECTS)
       
   579     {
       
   580       G_LOCK (debug_objects);
       
   581       debug_objects_count++;
       
   582       g_hash_table_insert (debug_objects_ht, object, object);
       
   583       G_UNLOCK (debug_objects);
       
   584     }
       
   585 #endif	/* G_ENABLE_DEBUG */
       
   586 }
       
   587 
       
   588 static void
       
   589 g_object_do_set_property (GObject      *object,
       
   590 			  guint         property_id,
       
   591 			  const GValue *value,
       
   592 			  GParamSpec   *pspec)
       
   593 {
       
   594   switch (property_id)
       
   595     {
       
   596     default:
       
   597       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
       
   598       break;
       
   599     }
       
   600 }
       
   601 
       
   602 static void
       
   603 g_object_do_get_property (GObject     *object,
       
   604 			  guint        property_id,
       
   605 			  GValue      *value,
       
   606 			  GParamSpec  *pspec)
       
   607 {
       
   608   switch (property_id)
       
   609     {
       
   610     default:
       
   611       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
       
   612       break;
       
   613     }
       
   614 }
       
   615 
       
   616 static void
       
   617 g_object_real_dispose (GObject *object)
       
   618 {
       
   619   g_signal_handlers_destroy (object);
       
   620   g_datalist_id_set_data (&object->qdata, quark_closure_array, NULL);
       
   621   g_datalist_id_set_data (&object->qdata, quark_weak_refs, NULL);
       
   622 }
       
   623 
       
   624 static void
       
   625 g_object_finalize (GObject *object)
       
   626 {
       
   627   g_datalist_clear (&object->qdata);
       
   628   
       
   629 #ifdef	G_ENABLE_DEBUG
       
   630   IF_DEBUG (OBJECTS)
       
   631     {
       
   632       G_LOCK (debug_objects);
       
   633       g_assert (g_hash_table_lookup (debug_objects_ht, object) == object);
       
   634       g_hash_table_remove (debug_objects_ht, object);
       
   635       debug_objects_count--;
       
   636       G_UNLOCK (debug_objects);
       
   637     }
       
   638 #endif	/* G_ENABLE_DEBUG */
       
   639 }
       
   640 
       
   641 
       
   642 static void
       
   643 g_object_dispatch_properties_changed (GObject     *object,
       
   644 				      guint        n_pspecs,
       
   645 				      GParamSpec **pspecs)
       
   646 {
       
   647   guint i;
       
   648 
       
   649   for (i = 0; i < n_pspecs; i++)
       
   650     g_signal_emit (object, gobject_signals[NOTIFY], g_quark_from_string (pspecs[i]->name), pspecs[i]);
       
   651 }
       
   652 
       
   653 EXPORT_C void
       
   654 g_object_run_dispose (GObject *object)
       
   655 {
       
   656   g_return_if_fail (G_IS_OBJECT (object));
       
   657   g_return_if_fail (object->ref_count > 0);
       
   658 
       
   659   g_object_ref (object);
       
   660   G_OBJECT_GET_CLASS (object)->dispose (object);
       
   661   g_object_unref (object);
       
   662 }
       
   663 
       
   664 EXPORT_C void
       
   665 g_object_freeze_notify (GObject *object)
       
   666 {
       
   667   g_return_if_fail (G_IS_OBJECT (object));
       
   668 
       
   669   if (g_atomic_int_get (&object->ref_count) == 0)
       
   670     return;
       
   671 
       
   672   g_object_ref (object);
       
   673   g_object_notify_queue_freeze (object, &property_notify_context);
       
   674   g_object_unref (object);
       
   675 }
       
   676 
       
   677 EXPORT_C void
       
   678 g_object_notify (GObject     *object,
       
   679 		 const gchar *property_name)
       
   680 {
       
   681   GParamSpec *pspec;
       
   682   
       
   683   g_return_if_fail (G_IS_OBJECT (object));
       
   684   g_return_if_fail (property_name != NULL);
       
   685   if (g_atomic_int_get (&object->ref_count) == 0)
       
   686     return;
       
   687   
       
   688   g_object_ref (object);
       
   689   /* We don't need to get the redirect target
       
   690    * (by, e.g. calling g_object_class_find_property())
       
   691    * because g_object_notify_queue_add() does that
       
   692    */
       
   693   pspec = g_param_spec_pool_lookup (pspec_pool,
       
   694 				    property_name,
       
   695 				    G_OBJECT_TYPE (object),
       
   696 				    TRUE);
       
   697 
       
   698   if (!pspec)
       
   699     g_warning ("%s: object class `%s' has no property named `%s'",
       
   700 	       G_STRFUNC,
       
   701 	       G_OBJECT_TYPE_NAME (object),
       
   702 	       property_name);
       
   703   else
       
   704     {
       
   705       GObjectNotifyQueue *nqueue;
       
   706       
       
   707       nqueue = g_object_notify_queue_freeze (object, &property_notify_context);
       
   708       g_object_notify_queue_add (object, nqueue, pspec);
       
   709       g_object_notify_queue_thaw (object, nqueue);
       
   710     }
       
   711   g_object_unref (object);
       
   712 }
       
   713 
       
   714 EXPORT_C void
       
   715 g_object_thaw_notify (GObject *object)
       
   716 {
       
   717   GObjectNotifyQueue *nqueue;
       
   718   
       
   719   g_return_if_fail (G_IS_OBJECT (object));
       
   720   if (g_atomic_int_get (&object->ref_count) == 0)
       
   721     return;
       
   722   
       
   723   g_object_ref (object);
       
   724   nqueue = g_object_notify_queue_from_object (object, &property_notify_context);
       
   725   if (!nqueue || !nqueue->freeze_count)
       
   726     g_warning ("%s: property-changed notification for %s(%p) is not frozen",
       
   727 	       G_STRFUNC, G_OBJECT_TYPE_NAME (object), object);
       
   728   else
       
   729     g_object_notify_queue_thaw (object, nqueue);
       
   730   g_object_unref (object);
       
   731 }
       
   732 
       
   733 static inline void
       
   734 object_get_property (GObject     *object,
       
   735 		     GParamSpec  *pspec,
       
   736 		     GValue      *value)
       
   737 {
       
   738   GObjectClass *class = g_type_class_peek (pspec->owner_type);
       
   739   guint param_id = PARAM_SPEC_PARAM_ID (pspec);
       
   740   GParamSpec *redirect;
       
   741 
       
   742   redirect = g_param_spec_get_redirect_target (pspec);
       
   743   if (redirect)
       
   744     pspec = redirect;    
       
   745   
       
   746   class->get_property (object, param_id, value, pspec);
       
   747 }
       
   748 
       
   749 static inline void
       
   750 object_set_property (GObject             *object,
       
   751 		     GParamSpec          *pspec,
       
   752 		     const GValue        *value,
       
   753 		     GObjectNotifyQueue  *nqueue)
       
   754 {
       
   755   GValue tmp_value = { 0, };
       
   756   GObjectClass *class = g_type_class_peek (pspec->owner_type);
       
   757   guint param_id = PARAM_SPEC_PARAM_ID (pspec);
       
   758   GParamSpec *redirect;
       
   759 
       
   760   redirect = g_param_spec_get_redirect_target (pspec);
       
   761   if (redirect)
       
   762     pspec = redirect;
       
   763 
       
   764   /* provide a copy to work from, convert (if necessary) and validate */
       
   765   g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
       
   766   if (!g_value_transform (value, &tmp_value))
       
   767     g_warning ("unable to set property `%s' of type `%s' from value of type `%s'",
       
   768 	       pspec->name,
       
   769 	       g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
       
   770 	       G_VALUE_TYPE_NAME (value));
       
   771   else if (g_param_value_validate (pspec, &tmp_value) && !(pspec->flags & G_PARAM_LAX_VALIDATION))
       
   772     {
       
   773       gchar *contents = g_strdup_value_contents (value);
       
   774 
       
   775       g_warning ("value \"%s\" of type `%s' is invalid or out of range for property `%s' of type `%s'",
       
   776 		 contents,
       
   777 		 G_VALUE_TYPE_NAME (value),
       
   778 		 pspec->name,
       
   779 		 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)));
       
   780       g_free (contents);
       
   781     }
       
   782   else
       
   783     {
       
   784       class->set_property (object, param_id, &tmp_value, pspec);
       
   785       g_object_notify_queue_add (object, nqueue, pspec);
       
   786     }
       
   787   g_value_unset (&tmp_value);
       
   788 }
       
   789 
       
   790 static void
       
   791 object_interface_check_properties (gpointer func_data,
       
   792 				   gpointer g_iface)
       
   793 {
       
   794   GTypeInterface *iface_class = g_iface;
       
   795   GObjectClass *class = g_type_class_peek (iface_class->g_instance_type);
       
   796   GType iface_type = iface_class->g_type;
       
   797   GParamSpec **pspecs;
       
   798   guint n;
       
   799 
       
   800   if (!G_IS_OBJECT_CLASS (class))
       
   801     return;
       
   802 
       
   803   pspecs = g_param_spec_pool_list (pspec_pool, iface_type, &n);
       
   804 
       
   805   while (n--)
       
   806     {
       
   807       GParamSpec *class_pspec = g_param_spec_pool_lookup (pspec_pool,
       
   808 							  pspecs[n]->name,
       
   809 							  G_OBJECT_CLASS_TYPE (class),
       
   810 							  TRUE);
       
   811       
       
   812       if (!class_pspec)
       
   813 	{
       
   814 	  g_critical ("Object class %s doesn't implement property "
       
   815 		      "'%s' from interface '%s'",
       
   816 		      g_type_name (G_OBJECT_CLASS_TYPE (class)),
       
   817 		      pspecs[n]->name,
       
   818 		      g_type_name (iface_type));
       
   819 
       
   820 	  continue;
       
   821 	}
       
   822 
       
   823       /* The implementation paramspec must have a less restrictive
       
   824        * type than the interface parameter spec for set() and a
       
   825        * more restrictive type for get(). We just require equality,
       
   826        * rather than doing something more complicated checking
       
   827        * the READABLE and WRITABLE flags. We also simplify here
       
   828        * by only checking the value type, not the G_PARAM_SPEC_TYPE.
       
   829        */
       
   830       if (class_pspec &&
       
   831 	  !g_type_is_a (G_PARAM_SPEC_VALUE_TYPE (pspecs[n]),
       
   832 			G_PARAM_SPEC_VALUE_TYPE (class_pspec)))
       
   833 	{
       
   834 	  g_critical ("Property '%s' on class '%s' has type '%s' "
       
   835 		      "which is different from the type '%s', "
       
   836 		      "of the property on interface '%s'\n",
       
   837 		      pspecs[n]->name,
       
   838 		      g_type_name (G_OBJECT_CLASS_TYPE (class)),
       
   839 		      g_type_name (G_PARAM_SPEC_VALUE_TYPE (class_pspec)),
       
   840 		      g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspecs[n])),
       
   841 		      g_type_name (iface_type));
       
   842 	}
       
   843       
       
   844 #define SUBSET(a,b,mask) (((a) & ~(b) & (mask)) == 0)
       
   845       
       
   846       /* CONSTRUCT and CONSTRUCT_ONLY add restrictions.
       
   847        * READABLE and WRITABLE remove restrictions. The implementation
       
   848        * paramspec must have less restrictive flags.
       
   849        */
       
   850       if (class_pspec &&
       
   851 	  (!SUBSET (class_pspec->flags,
       
   852 		    pspecs[n]->flags,
       
   853 		    G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY) ||
       
   854 	   !SUBSET (pspecs[n]->flags,
       
   855 		    class_pspec->flags,
       
   856 		    G_PARAM_READABLE | G_PARAM_WRITABLE)))
       
   857 	{
       
   858 	  g_critical ("Flags for property '%s' on class '%s' "
       
   859 		      "are not compatible with the property on"
       
   860 		      "interface '%s'\n",
       
   861 		      pspecs[n]->name,
       
   862 		      g_type_name (G_OBJECT_CLASS_TYPE (class)),
       
   863 		      g_type_name (iface_type));
       
   864 	}
       
   865 #undef SUBSET	  
       
   866     }
       
   867   
       
   868   g_free (pspecs);
       
   869 }
       
   870 
       
   871 EXPORT_C gpointer
       
   872 g_object_new (GType	   object_type,
       
   873 	      const gchar *first_property_name,
       
   874 	      ...)
       
   875 {
       
   876   GObject *object;
       
   877   va_list var_args;
       
   878   
       
   879   g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type), NULL);
       
   880   
       
   881   va_start (var_args, first_property_name);
       
   882   object = g_object_new_valist (object_type, first_property_name, var_args);
       
   883   va_end (var_args);
       
   884   
       
   885   return object;
       
   886 }
       
   887 
       
   888 static gboolean
       
   889 object_in_construction (GObject *object)
       
   890 {
       
   891   gboolean in_construction;
       
   892   G_LOCK (construct_objects_lock);
       
   893   in_construction = g_slist_find (construct_objects, object) != NULL;
       
   894   G_UNLOCK (construct_objects_lock);
       
   895   return in_construction;
       
   896 }
       
   897 
       
   898 EXPORT_C gpointer
       
   899 g_object_newv (GType       object_type,
       
   900 	       guint       n_parameters,
       
   901 	       GParameter *parameters)
       
   902 {
       
   903   GObjectConstructParam *cparams, *oparams;
       
   904   GObjectNotifyQueue *nqueue;
       
   905   GObject *object;
       
   906   GObjectClass *class, *unref_class = NULL;
       
   907   GSList *slist;
       
   908   guint n_total_cparams = 0, n_cparams = 0, n_oparams = 0, n_cvalues;
       
   909   GValue *cvalues;
       
   910   GList *clist = NULL;
       
   911   guint i;
       
   912 
       
   913   g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type), NULL);
       
   914 
       
   915   class = g_type_class_peek_static (object_type);
       
   916   if (!class)
       
   917     class = unref_class = g_type_class_ref (object_type);
       
   918   for (slist = class->construct_properties; slist; slist = slist->next)
       
   919     {
       
   920       clist = g_list_prepend (clist, slist->data);
       
   921       n_total_cparams += 1;
       
   922     }
       
   923 
       
   924   /* collect parameters, sort into construction and normal ones */
       
   925   oparams = g_new (GObjectConstructParam, n_parameters);
       
   926   cparams = g_new (GObjectConstructParam, n_total_cparams);
       
   927   
       
   928   for (i = 0; i < n_parameters; i++)
       
   929     {
       
   930       GValue *value = &parameters[i].value;
       
   931       GParamSpec *pspec = g_param_spec_pool_lookup (pspec_pool,
       
   932 						    parameters[i].name,
       
   933 						    object_type,
       
   934 						    TRUE);
       
   935       if (!pspec)
       
   936 	{
       
   937 	  g_warning ("%s: object class `%s' has no property named `%s'",
       
   938 		     G_STRFUNC,
       
   939 		     g_type_name (object_type),
       
   940 		     parameters[i].name);
       
   941 	  continue;
       
   942 	}
       
   943       if (!(pspec->flags & G_PARAM_WRITABLE))
       
   944 	{
       
   945 	  g_warning ("%s: property `%s' of object class `%s' is not writable",
       
   946 		     G_STRFUNC,
       
   947 		     pspec->name,
       
   948 		     g_type_name (object_type));
       
   949 	  continue;
       
   950 	}
       
   951       if (pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY))
       
   952 	{
       
   953 	  GList *list = g_list_find (clist, pspec);
       
   954 
       
   955 	  if (!list)
       
   956 	    {
       
   957 	      g_warning ("%s: construct property \"%s\" for object `%s' can't be set twice",
       
   958                          G_STRFUNC, pspec->name, g_type_name (object_type));
       
   959 	      continue;
       
   960 	    }
       
   961 	  cparams[n_cparams].pspec = pspec;
       
   962 	  cparams[n_cparams].value = value;
       
   963 	  n_cparams++;
       
   964 	  if (!list->prev)
       
   965 	    clist = list->next;
       
   966 	  else
       
   967 	    list->prev->next = list->next;
       
   968 	  if (list->next)
       
   969 	    list->next->prev = list->prev;
       
   970 	  g_list_free_1 (list);
       
   971 	}
       
   972       else
       
   973 	{
       
   974 	  oparams[n_oparams].pspec = pspec;
       
   975 	  oparams[n_oparams].value = value;
       
   976 	  n_oparams++;
       
   977 	}
       
   978     }
       
   979 
       
   980   /* set remaining construction properties to default values */
       
   981   n_cvalues = n_total_cparams - n_cparams;
       
   982   cvalues = g_new (GValue, n_cvalues);
       
   983   while (clist)
       
   984     {
       
   985       GList *tmp = clist->next;
       
   986       GParamSpec *pspec = clist->data;
       
   987       GValue *value = cvalues + n_total_cparams - n_cparams - 1;
       
   988 
       
   989       value->g_type = 0;
       
   990       g_value_init (value, G_PARAM_SPEC_VALUE_TYPE (pspec));
       
   991       g_param_value_set_default (pspec, value);
       
   992 
       
   993       cparams[n_cparams].pspec = pspec;
       
   994       cparams[n_cparams].value = value;
       
   995       n_cparams++;
       
   996 
       
   997       g_list_free_1 (clist);
       
   998       clist = tmp;
       
   999     }
       
  1000 
       
  1001   /* construct object from construction parameters */
       
  1002   object = class->constructor (object_type, n_total_cparams, cparams);
       
  1003   G_LOCK (construct_objects_lock);
       
  1004   construct_objects = g_slist_remove (construct_objects, object);
       
  1005   G_UNLOCK (construct_objects_lock);
       
  1006 
       
  1007   /* free construction values */
       
  1008   g_free (cparams);
       
  1009   while (n_cvalues--)
       
  1010     g_value_unset (cvalues + n_cvalues);
       
  1011   g_free (cvalues);
       
  1012   
       
  1013   /* release g_object_init() notification queue freeze_count */
       
  1014   nqueue = g_object_notify_queue_freeze (object, &property_notify_context);
       
  1015   g_object_notify_queue_thaw (object, nqueue);
       
  1016   
       
  1017   /* set remaining properties */
       
  1018   for (i = 0; i < n_oparams; i++)
       
  1019     object_set_property (object, oparams[i].pspec, oparams[i].value, nqueue);
       
  1020   g_free (oparams);
       
  1021 
       
  1022   if (unref_class)
       
  1023     g_type_class_unref (unref_class);
       
  1024 
       
  1025   /* release our own freeze count and handle notifications */
       
  1026   g_object_notify_queue_thaw (object, nqueue);
       
  1027   
       
  1028   return object;
       
  1029 }
       
  1030 
       
  1031 EXPORT_C GObject*
       
  1032 g_object_new_valist (GType	  object_type,
       
  1033 		     const gchar *first_property_name,
       
  1034 		     va_list	  var_args)
       
  1035 {
       
  1036   GObjectClass *class;
       
  1037   GParameter *params;
       
  1038   const gchar *name;
       
  1039   GObject *object;
       
  1040   guint n_params = 0, n_alloced_params = 16;
       
  1041   
       
  1042   g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type), NULL);
       
  1043 
       
  1044   if (!first_property_name)
       
  1045     return g_object_newv (object_type, 0, NULL);
       
  1046 
       
  1047   class = g_type_class_ref (object_type);
       
  1048   params = g_new (GParameter, n_alloced_params);
       
  1049   name = first_property_name;
       
  1050   while (name)
       
  1051     {
       
  1052       gchar *error = NULL;
       
  1053       GParamSpec *pspec = g_param_spec_pool_lookup (pspec_pool,
       
  1054 						    name,
       
  1055 						    object_type,
       
  1056 						    TRUE);
       
  1057       if (!pspec)
       
  1058 	{
       
  1059 	  g_warning ("%s: object class `%s' has no property named `%s'",
       
  1060 		     G_STRFUNC,
       
  1061 		     g_type_name (object_type),
       
  1062 		     name);
       
  1063 	  break;
       
  1064 	}
       
  1065       if (n_params >= n_alloced_params)
       
  1066 	{
       
  1067 	  n_alloced_params += 16;
       
  1068 	  params = g_renew (GParameter, params, n_alloced_params);
       
  1069 	}
       
  1070       params[n_params].name = name;
       
  1071       params[n_params].value.g_type = 0;
       
  1072       g_value_init (&params[n_params].value, G_PARAM_SPEC_VALUE_TYPE (pspec));
       
  1073       G_VALUE_COLLECT (&params[n_params].value, var_args, 0, &error);
       
  1074       if (error)
       
  1075 	{
       
  1076 	  g_warning ("%s: %s", G_STRFUNC, error);
       
  1077 	  g_free (error);
       
  1078           g_value_unset (&params[n_params].value);
       
  1079 	  break;
       
  1080 	}
       
  1081       n_params++;
       
  1082       name = va_arg (var_args, gchar*);
       
  1083     }
       
  1084 
       
  1085   object = g_object_newv (object_type, n_params, params);
       
  1086 
       
  1087   while (n_params--)
       
  1088     g_value_unset (&params[n_params].value);
       
  1089   g_free (params);
       
  1090 
       
  1091   g_type_class_unref (class);
       
  1092 
       
  1093   return object;
       
  1094 }
       
  1095 
       
  1096 static GObject*
       
  1097 g_object_constructor (GType                  type,
       
  1098 		      guint                  n_construct_properties,
       
  1099 		      GObjectConstructParam *construct_params)
       
  1100 {
       
  1101   GObject *object;
       
  1102 
       
  1103   /* create object */
       
  1104   object = (GObject*) g_type_create_instance (type);
       
  1105   
       
  1106   /* set construction parameters */
       
  1107   if (n_construct_properties)
       
  1108     {
       
  1109       GObjectNotifyQueue *nqueue = g_object_notify_queue_freeze (object, &property_notify_context);
       
  1110       
       
  1111       /* set construct properties */
       
  1112       while (n_construct_properties--)
       
  1113 	{
       
  1114 	  GValue *value = construct_params->value;
       
  1115 	  GParamSpec *pspec = construct_params->pspec;
       
  1116 
       
  1117 	  construct_params++;
       
  1118 	  object_set_property (object, pspec, value, nqueue);
       
  1119 	}
       
  1120       g_object_notify_queue_thaw (object, nqueue);
       
  1121       /* the notification queue is still frozen from g_object_init(), so
       
  1122        * we don't need to handle it here, g_object_newv() takes
       
  1123        * care of that
       
  1124        */
       
  1125     }
       
  1126 
       
  1127   return object;
       
  1128 }
       
  1129 
       
  1130 EXPORT_C void
       
  1131 g_object_set_valist (GObject	 *object,
       
  1132 		     const gchar *first_property_name,
       
  1133 		     va_list	  var_args)
       
  1134 {
       
  1135   GObjectNotifyQueue *nqueue;
       
  1136   const gchar *name;
       
  1137   
       
  1138   g_return_if_fail (G_IS_OBJECT (object));
       
  1139   
       
  1140   g_object_ref (object);
       
  1141   nqueue = g_object_notify_queue_freeze (object, &property_notify_context);
       
  1142   
       
  1143   name = first_property_name;
       
  1144   while (name)
       
  1145     {
       
  1146       GValue value = { 0, };
       
  1147       GParamSpec *pspec;
       
  1148       gchar *error = NULL;
       
  1149       
       
  1150       pspec = g_param_spec_pool_lookup (pspec_pool,
       
  1151 					name,
       
  1152 					G_OBJECT_TYPE (object),
       
  1153 					TRUE);
       
  1154       if (!pspec)
       
  1155 	{
       
  1156 	  g_warning ("%s: object class `%s' has no property named `%s'",
       
  1157 		     G_STRFUNC,
       
  1158 		     G_OBJECT_TYPE_NAME (object),
       
  1159 		     name);
       
  1160 	  break;
       
  1161 	}
       
  1162       if (!(pspec->flags & G_PARAM_WRITABLE))
       
  1163 	{
       
  1164 	  g_warning ("%s: property `%s' of object class `%s' is not writable",
       
  1165 		     G_STRFUNC,
       
  1166 		     pspec->name,
       
  1167 		     G_OBJECT_TYPE_NAME (object));
       
  1168 	  break;
       
  1169 	}
       
  1170       if ((pspec->flags & G_PARAM_CONSTRUCT_ONLY) && !object_in_construction (object))
       
  1171         {
       
  1172           g_warning ("%s: construct property \"%s\" for object `%s' can't be set after construction",
       
  1173                      G_STRFUNC, pspec->name, G_OBJECT_TYPE_NAME (object));
       
  1174           break;
       
  1175         }
       
  1176 
       
  1177       g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
       
  1178       
       
  1179       G_VALUE_COLLECT (&value, var_args, 0, &error);
       
  1180       if (error)
       
  1181 	{
       
  1182 	  g_warning ("%s: %s", G_STRFUNC, error);
       
  1183 	  g_free (error);
       
  1184           g_value_unset (&value);
       
  1185 	  break;
       
  1186 	}
       
  1187       
       
  1188       object_set_property (object, pspec, &value, nqueue);
       
  1189       g_value_unset (&value);
       
  1190       
       
  1191       name = va_arg (var_args, gchar*);
       
  1192     }
       
  1193 
       
  1194   g_object_notify_queue_thaw (object, nqueue);
       
  1195   g_object_unref (object);
       
  1196 }
       
  1197 
       
  1198 EXPORT_C void
       
  1199 g_object_get_valist (GObject	 *object,
       
  1200 		     const gchar *first_property_name,
       
  1201 		     va_list	  var_args)
       
  1202 {
       
  1203   const gchar *name;
       
  1204   
       
  1205   g_return_if_fail (G_IS_OBJECT (object));
       
  1206   
       
  1207   g_object_ref (object);
       
  1208   
       
  1209   name = first_property_name;
       
  1210   
       
  1211   while (name)
       
  1212     {
       
  1213       GValue value = { 0, };
       
  1214       GParamSpec *pspec;
       
  1215       gchar *error;
       
  1216       
       
  1217       pspec = g_param_spec_pool_lookup (pspec_pool,
       
  1218 					name,
       
  1219 					G_OBJECT_TYPE (object),
       
  1220 					TRUE);
       
  1221       if (!pspec)
       
  1222 	{
       
  1223 	  g_warning ("%s: object class `%s' has no property named `%s'",
       
  1224 		     G_STRFUNC,
       
  1225 		     G_OBJECT_TYPE_NAME (object),
       
  1226 		     name);
       
  1227 	  break;
       
  1228 	}
       
  1229       if (!(pspec->flags & G_PARAM_READABLE))
       
  1230 	{
       
  1231 	  g_warning ("%s: property `%s' of object class `%s' is not readable",
       
  1232 		     G_STRFUNC,
       
  1233 		     pspec->name,
       
  1234 		     G_OBJECT_TYPE_NAME (object));
       
  1235 	  break;
       
  1236 	}
       
  1237       
       
  1238       g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
       
  1239       
       
  1240       object_get_property (object, pspec, &value);
       
  1241       
       
  1242       G_VALUE_LCOPY (&value, var_args, 0, &error);
       
  1243       if (error)
       
  1244 	{
       
  1245 	  g_warning ("%s: %s", G_STRFUNC, error);
       
  1246 	  g_free (error);
       
  1247 	  g_value_unset (&value);
       
  1248 	  break;
       
  1249 	}
       
  1250       
       
  1251       g_value_unset (&value);
       
  1252       
       
  1253       name = va_arg (var_args, gchar*);
       
  1254     }
       
  1255   
       
  1256   g_object_unref (object);
       
  1257 }
       
  1258 
       
  1259 EXPORT_C void
       
  1260 g_object_set (gpointer     _object,
       
  1261 	      const gchar *first_property_name,
       
  1262 	      ...)
       
  1263 {
       
  1264   GObject *object = _object;
       
  1265   va_list var_args;
       
  1266   
       
  1267   g_return_if_fail (G_IS_OBJECT (object));
       
  1268   
       
  1269   va_start (var_args, first_property_name);
       
  1270   g_object_set_valist (object, first_property_name, var_args);
       
  1271   va_end (var_args);
       
  1272 }
       
  1273 
       
  1274 EXPORT_C void
       
  1275 g_object_get (gpointer     _object,
       
  1276 	      const gchar *first_property_name,
       
  1277 	      ...)
       
  1278 {
       
  1279   GObject *object = _object;
       
  1280   va_list var_args;
       
  1281   
       
  1282   g_return_if_fail (G_IS_OBJECT (object));
       
  1283   
       
  1284   va_start (var_args, first_property_name);
       
  1285   g_object_get_valist (object, first_property_name, var_args);
       
  1286   va_end (var_args);
       
  1287 }
       
  1288 
       
  1289 EXPORT_C void
       
  1290 g_object_set_property (GObject	    *object,
       
  1291 		       const gchar  *property_name,
       
  1292 		       const GValue *value)
       
  1293 {
       
  1294   GObjectNotifyQueue *nqueue;
       
  1295   GParamSpec *pspec;
       
  1296   
       
  1297   g_return_if_fail (G_IS_OBJECT (object));
       
  1298   g_return_if_fail (property_name != NULL);
       
  1299   g_return_if_fail (G_IS_VALUE (value));
       
  1300   
       
  1301   g_object_ref (object);
       
  1302   nqueue = g_object_notify_queue_freeze (object, &property_notify_context);
       
  1303   
       
  1304   pspec = g_param_spec_pool_lookup (pspec_pool,
       
  1305 				    property_name,
       
  1306 				    G_OBJECT_TYPE (object),
       
  1307 				    TRUE);
       
  1308   if (!pspec)
       
  1309     g_warning ("%s: object class `%s' has no property named `%s'",
       
  1310 	       G_STRFUNC,
       
  1311 	       G_OBJECT_TYPE_NAME (object),
       
  1312 	       property_name);
       
  1313   else if (!(pspec->flags & G_PARAM_WRITABLE))
       
  1314     g_warning ("%s: property `%s' of object class `%s' is not writable",
       
  1315                G_STRFUNC,
       
  1316                pspec->name,
       
  1317                G_OBJECT_TYPE_NAME (object));
       
  1318   else if ((pspec->flags & G_PARAM_CONSTRUCT_ONLY) && !object_in_construction (object))
       
  1319     g_warning ("%s: construct property \"%s\" for object `%s' can't be set after construction",
       
  1320                G_STRFUNC, pspec->name, G_OBJECT_TYPE_NAME (object));
       
  1321   else
       
  1322     object_set_property (object, pspec, value, nqueue);
       
  1323   
       
  1324   g_object_notify_queue_thaw (object, nqueue);
       
  1325   g_object_unref (object);
       
  1326 }
       
  1327 
       
  1328 EXPORT_C void
       
  1329 g_object_get_property (GObject	   *object,
       
  1330 		       const gchar *property_name,
       
  1331 		       GValue	   *value)
       
  1332 {
       
  1333   GParamSpec *pspec;
       
  1334   
       
  1335   g_return_if_fail (G_IS_OBJECT (object));
       
  1336   g_return_if_fail (property_name != NULL);
       
  1337   g_return_if_fail (G_IS_VALUE (value));
       
  1338   
       
  1339   g_object_ref (object);
       
  1340   
       
  1341   pspec = g_param_spec_pool_lookup (pspec_pool,
       
  1342 				    property_name,
       
  1343 				    G_OBJECT_TYPE (object),
       
  1344 				    TRUE);
       
  1345   if (!pspec)
       
  1346     g_warning ("%s: object class `%s' has no property named `%s'",
       
  1347 	       G_STRFUNC,
       
  1348 	       G_OBJECT_TYPE_NAME (object),
       
  1349 	       property_name);
       
  1350   else if (!(pspec->flags & G_PARAM_READABLE))
       
  1351     g_warning ("%s: property `%s' of object class `%s' is not readable",
       
  1352                G_STRFUNC,
       
  1353                pspec->name,
       
  1354                G_OBJECT_TYPE_NAME (object));
       
  1355   else
       
  1356     {
       
  1357       GValue *prop_value, tmp_value = { 0, };
       
  1358       
       
  1359       /* auto-conversion of the callers value type
       
  1360        */
       
  1361       if (G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (pspec))
       
  1362 	{
       
  1363 	  g_value_reset (value);
       
  1364 	  prop_value = value;
       
  1365 	}
       
  1366       else if (!g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec), G_VALUE_TYPE (value)))
       
  1367 	{
       
  1368 	  g_warning ("%s: can't retrieve property `%s' of type `%s' as value of type `%s'",
       
  1369 		     G_STRFUNC, pspec->name,
       
  1370 		     g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
       
  1371 		     G_VALUE_TYPE_NAME (value));
       
  1372 	  g_object_unref (object);
       
  1373 	  return;
       
  1374 	}
       
  1375       else
       
  1376 	{
       
  1377 	  g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
       
  1378 	  prop_value = &tmp_value;
       
  1379 	}
       
  1380       object_get_property (object, pspec, prop_value);
       
  1381       if (prop_value != value)
       
  1382 	{
       
  1383 	  g_value_transform (prop_value, value);
       
  1384 	  g_value_unset (&tmp_value);
       
  1385 	}
       
  1386     }
       
  1387   
       
  1388   g_object_unref (object);
       
  1389 }
       
  1390 
       
  1391 EXPORT_C gpointer
       
  1392 g_object_connect (gpointer     _object,
       
  1393 		  const gchar *signal_spec,
       
  1394 		  ...)
       
  1395 {
       
  1396   GObject *object = _object;
       
  1397   va_list var_args;
       
  1398 
       
  1399   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
       
  1400   g_return_val_if_fail (object->ref_count > 0, object);
       
  1401 
       
  1402   va_start (var_args, signal_spec);
       
  1403   while (signal_spec)
       
  1404     {
       
  1405       GCallback callback = va_arg (var_args, GCallback);
       
  1406       gpointer data = va_arg (var_args, gpointer);
       
  1407       gulong sid;
       
  1408 
       
  1409       if (strncmp (signal_spec, "signal::", 8) == 0)
       
  1410 	sid = g_signal_connect_data (object, signal_spec + 8,
       
  1411 				     callback, data, NULL,
       
  1412 				     0);
       
  1413       else if (strncmp (signal_spec, "object_signal::", 15) == 0 ||
       
  1414                strncmp (signal_spec, "object-signal::", 15) == 0)
       
  1415 	sid = g_signal_connect_object (object, signal_spec + 15,
       
  1416 				       callback, data,
       
  1417 				       0);
       
  1418       else if (strncmp (signal_spec, "swapped_signal::", 16) == 0 ||
       
  1419                strncmp (signal_spec, "swapped-signal::", 16) == 0)
       
  1420 	sid = g_signal_connect_data (object, signal_spec + 16,
       
  1421 				     callback, data, NULL,
       
  1422 				     G_CONNECT_SWAPPED);
       
  1423       else if (strncmp (signal_spec, "swapped_object_signal::", 23) == 0 ||
       
  1424                strncmp (signal_spec, "swapped-object-signal::", 23) == 0)
       
  1425 	sid = g_signal_connect_object (object, signal_spec + 23,
       
  1426 				       callback, data,
       
  1427 				       G_CONNECT_SWAPPED);
       
  1428       else if (strncmp (signal_spec, "signal_after::", 14) == 0 ||
       
  1429                strncmp (signal_spec, "signal-after::", 14) == 0)
       
  1430 	sid = g_signal_connect_data (object, signal_spec + 14,
       
  1431 				     callback, data, NULL,
       
  1432 				     G_CONNECT_AFTER);
       
  1433       else if (strncmp (signal_spec, "object_signal_after::", 21) == 0 ||
       
  1434                strncmp (signal_spec, "object-signal-after::", 21) == 0)
       
  1435 	sid = g_signal_connect_object (object, signal_spec + 21,
       
  1436 				       callback, data,
       
  1437 				       G_CONNECT_AFTER);
       
  1438       else if (strncmp (signal_spec, "swapped_signal_after::", 22) == 0 ||
       
  1439                strncmp (signal_spec, "swapped-signal-after::", 22) == 0)
       
  1440 	sid = g_signal_connect_data (object, signal_spec + 22,
       
  1441 				     callback, data, NULL,
       
  1442 				     G_CONNECT_SWAPPED | G_CONNECT_AFTER);
       
  1443       else if (strncmp (signal_spec, "swapped_object_signal_after::", 29) == 0 ||
       
  1444                strncmp (signal_spec, "swapped-object-signal-after::", 29) == 0)
       
  1445 	sid = g_signal_connect_object (object, signal_spec + 29,
       
  1446 				       callback, data,
       
  1447 				       G_CONNECT_SWAPPED | G_CONNECT_AFTER);
       
  1448       else
       
  1449 	{
       
  1450 	  g_warning ("%s: invalid signal spec \"%s\"", G_STRFUNC, signal_spec);
       
  1451 	  break;
       
  1452 	}
       
  1453       signal_spec = va_arg (var_args, gchar*);
       
  1454     }
       
  1455   va_end (var_args);
       
  1456 
       
  1457   return object;
       
  1458 }
       
  1459 
       
  1460 EXPORT_C void
       
  1461 g_object_disconnect (gpointer     _object,
       
  1462 		     const gchar *signal_spec,
       
  1463 		     ...)
       
  1464 {
       
  1465   GObject *object = _object;
       
  1466   va_list var_args;
       
  1467 
       
  1468   g_return_if_fail (G_IS_OBJECT (object));
       
  1469   g_return_if_fail (object->ref_count > 0);
       
  1470 
       
  1471   va_start (var_args, signal_spec);
       
  1472   while (signal_spec)
       
  1473     {
       
  1474       GCallback callback = va_arg (var_args, GCallback);
       
  1475       gpointer data = va_arg (var_args, gpointer);
       
  1476       guint sid = 0, detail = 0, mask = 0;
       
  1477 
       
  1478       if (strncmp (signal_spec, "any_signal::", 12) == 0 ||
       
  1479           strncmp (signal_spec, "any-signal::", 12) == 0)
       
  1480 	{
       
  1481 	  signal_spec += 12;
       
  1482 	  mask = G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA;
       
  1483 	}
       
  1484       else if (strcmp (signal_spec, "any_signal") == 0 ||
       
  1485                strcmp (signal_spec, "any-signal") == 0)
       
  1486 	{
       
  1487 	  signal_spec += 10;
       
  1488 	  mask = G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA;
       
  1489 	}
       
  1490       else
       
  1491 	{
       
  1492 	  g_warning ("%s: invalid signal spec \"%s\"", G_STRFUNC, signal_spec);
       
  1493 	  break;
       
  1494 	}
       
  1495 
       
  1496       if ((mask & G_SIGNAL_MATCH_ID) &&
       
  1497 	  !g_signal_parse_name (signal_spec, G_OBJECT_TYPE (object), &sid, &detail, FALSE))
       
  1498 	g_warning ("%s: invalid signal name \"%s\"", G_STRFUNC, signal_spec);
       
  1499       else if (!g_signal_handlers_disconnect_matched (object, mask | (detail ? G_SIGNAL_MATCH_DETAIL : 0),
       
  1500 						      sid, detail,
       
  1501 						      NULL, (gpointer)callback, data))
       
  1502 	g_warning ("%s: signal handler %p(%p) is not connected", G_STRFUNC, callback, data);
       
  1503       signal_spec = va_arg (var_args, gchar*);
       
  1504     }
       
  1505   va_end (var_args);
       
  1506 }
       
  1507 
       
  1508 typedef struct {
       
  1509   GObject *object;
       
  1510   guint n_weak_refs;
       
  1511   struct {
       
  1512     GWeakNotify notify;
       
  1513     gpointer    data;
       
  1514   } weak_refs[1];  /* flexible array */
       
  1515 } WeakRefStack;
       
  1516 
       
  1517 static void
       
  1518 weak_refs_notify (gpointer data)
       
  1519 {
       
  1520   WeakRefStack *wstack = data;
       
  1521   guint i;
       
  1522 
       
  1523   for (i = 0; i < wstack->n_weak_refs; i++)
       
  1524     wstack->weak_refs[i].notify (wstack->weak_refs[i].data, wstack->object);
       
  1525   g_free (wstack);
       
  1526 }
       
  1527 
       
  1528 EXPORT_C void
       
  1529 g_object_weak_ref (GObject    *object,
       
  1530 		   GWeakNotify notify,
       
  1531 		   gpointer    data)
       
  1532 {
       
  1533   WeakRefStack *wstack;
       
  1534   guint i;
       
  1535   
       
  1536   g_return_if_fail (G_IS_OBJECT (object));
       
  1537   g_return_if_fail (notify != NULL);
       
  1538   g_return_if_fail (object->ref_count >= 1);
       
  1539 
       
  1540   wstack = g_datalist_id_remove_no_notify (&object->qdata, quark_weak_refs);
       
  1541   if (wstack)
       
  1542     {
       
  1543       i = wstack->n_weak_refs++;
       
  1544       wstack = g_realloc (wstack, sizeof (*wstack) + sizeof (wstack->weak_refs[0]) * i);
       
  1545     }
       
  1546   else
       
  1547     {
       
  1548       wstack = g_renew (WeakRefStack, NULL, 1);
       
  1549       wstack->object = object;
       
  1550       wstack->n_weak_refs = 1;
       
  1551       i = 0;
       
  1552     }
       
  1553   wstack->weak_refs[i].notify = notify;
       
  1554   wstack->weak_refs[i].data = data;
       
  1555   g_datalist_id_set_data_full (&object->qdata, quark_weak_refs, wstack, weak_refs_notify);
       
  1556 }
       
  1557 
       
  1558 EXPORT_C void
       
  1559 g_object_weak_unref (GObject    *object,
       
  1560 		     GWeakNotify notify,
       
  1561 		     gpointer    data)
       
  1562 {
       
  1563   WeakRefStack *wstack;
       
  1564   gboolean found_one = FALSE;
       
  1565 
       
  1566   g_return_if_fail (G_IS_OBJECT (object));
       
  1567   g_return_if_fail (notify != NULL);
       
  1568 
       
  1569   wstack = g_datalist_id_get_data (&object->qdata, quark_weak_refs);
       
  1570   if (wstack)
       
  1571     {
       
  1572       guint i;
       
  1573 
       
  1574       for (i = 0; i < wstack->n_weak_refs; i++)
       
  1575 	if (wstack->weak_refs[i].notify == notify &&
       
  1576 	    wstack->weak_refs[i].data == data)
       
  1577 	  {
       
  1578 	    found_one = TRUE;
       
  1579 	    wstack->n_weak_refs -= 1;
       
  1580 	    if (i != wstack->n_weak_refs)
       
  1581 	      wstack->weak_refs[i] = wstack->weak_refs[wstack->n_weak_refs];
       
  1582 
       
  1583 	    break;
       
  1584 	  }
       
  1585     }
       
  1586   if (!found_one)
       
  1587     g_warning ("%s: couldn't find weak ref %p(%p)", G_STRFUNC, notify, data);
       
  1588 }
       
  1589 
       
  1590 EXPORT_C void
       
  1591 g_object_add_weak_pointer (GObject  *object, 
       
  1592                            gpointer *weak_pointer_location)
       
  1593 {
       
  1594   g_return_if_fail (G_IS_OBJECT (object));
       
  1595   g_return_if_fail (weak_pointer_location != NULL);
       
  1596 
       
  1597   g_object_weak_ref (object, 
       
  1598                      (GWeakNotify) g_nullify_pointer, 
       
  1599                      weak_pointer_location);
       
  1600 }
       
  1601 
       
  1602 EXPORT_C void
       
  1603 g_object_remove_weak_pointer (GObject  *object, 
       
  1604                               gpointer *weak_pointer_location)
       
  1605 {
       
  1606   g_return_if_fail (G_IS_OBJECT (object));
       
  1607   g_return_if_fail (weak_pointer_location != NULL);
       
  1608 
       
  1609   g_object_weak_unref (object, 
       
  1610                        (GWeakNotify) g_nullify_pointer, 
       
  1611                        weak_pointer_location);
       
  1612 }
       
  1613 
       
  1614 #if EMULATOR
       
  1615 guint
       
  1616 object_floating_flag_handler (GObject        *object,
       
  1617                               gint            job)
       
  1618 #else
       
  1619 static guint
       
  1620 object_floating_flag_handler (GObject        *object,
       
  1621                               gint            job)
       
  1622 #endif /* EMULATOR */
       
  1623 {
       
  1624   switch (job)
       
  1625     {
       
  1626       gpointer oldvalue;
       
  1627     case +1:    /* force floating if possible */
       
  1628       do
       
  1629         oldvalue = g_atomic_pointer_get (&object->qdata);
       
  1630       while (!g_atomic_pointer_compare_and_exchange ((void**) &object->qdata, oldvalue,
       
  1631                                                      (gpointer) ((gsize) oldvalue | OBJECT_FLOATING_FLAG)));
       
  1632       return (gsize) oldvalue & OBJECT_FLOATING_FLAG;
       
  1633     case -1:    /* sink if possible */
       
  1634       do
       
  1635         oldvalue = g_atomic_pointer_get (&object->qdata);
       
  1636       while (!g_atomic_pointer_compare_and_exchange ((void**) &object->qdata, oldvalue,
       
  1637                                                      (gpointer) ((gsize) oldvalue & ~(gsize) OBJECT_FLOATING_FLAG)));
       
  1638       return (gsize) oldvalue & OBJECT_FLOATING_FLAG;
       
  1639     default:    /* check floating */
       
  1640       return 0 != ((gsize) g_atomic_pointer_get (&object->qdata) & OBJECT_FLOATING_FLAG);
       
  1641     }
       
  1642 }
       
  1643 
       
  1644 EXPORT_C gboolean
       
  1645 g_object_is_floating (gpointer _object)
       
  1646 {
       
  1647   GObject *object = _object;
       
  1648   g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
       
  1649   return floating_flag_handler (object, 0);
       
  1650 }
       
  1651 
       
  1652 EXPORT_C gpointer
       
  1653 g_object_ref_sink (gpointer _object)
       
  1654 {
       
  1655   GObject *object = _object;
       
  1656   gboolean was_floating;
       
  1657   g_return_val_if_fail (G_IS_OBJECT (object), object);
       
  1658   g_return_val_if_fail (object->ref_count >= 1, object);
       
  1659   g_object_ref (object);
       
  1660   was_floating = floating_flag_handler (object, -1);
       
  1661   if (was_floating)
       
  1662     g_object_unref (object);
       
  1663   return object;
       
  1664 }
       
  1665 
       
  1666 EXPORT_C void
       
  1667 g_object_force_floating (GObject *object)
       
  1668 {
       
  1669   gboolean was_floating;
       
  1670   g_return_if_fail (G_IS_OBJECT (object));
       
  1671   g_return_if_fail (object->ref_count >= 1);
       
  1672 
       
  1673   was_floating = floating_flag_handler (object, +1);
       
  1674 }
       
  1675 
       
  1676 typedef struct {
       
  1677   GObject *object;
       
  1678   guint n_toggle_refs;
       
  1679   struct {
       
  1680     GToggleNotify notify;
       
  1681     gpointer    data;
       
  1682   } toggle_refs[1];  /* flexible array */
       
  1683 } ToggleRefStack;
       
  1684 
       
  1685 static void
       
  1686 toggle_refs_notify (GObject *object,
       
  1687 		    gboolean is_last_ref)
       
  1688 {
       
  1689   ToggleRefStack *tstack = g_datalist_id_get_data (&object->qdata, quark_toggle_refs);
       
  1690 
       
  1691   /* Reentrancy here is not as tricky as it seems, because a toggle reference
       
  1692    * will only be notified when there is exactly one of them.
       
  1693    */
       
  1694   g_assert (tstack->n_toggle_refs == 1);
       
  1695   tstack->toggle_refs[0].notify (tstack->toggle_refs[0].data, tstack->object, is_last_ref);
       
  1696 }
       
  1697 
       
  1698 EXPORT_C void
       
  1699 g_object_add_toggle_ref (GObject       *object,
       
  1700 			 GToggleNotify  notify,
       
  1701 			 gpointer       data)
       
  1702 {
       
  1703   ToggleRefStack *tstack;
       
  1704   guint i;
       
  1705   
       
  1706   g_return_if_fail (G_IS_OBJECT (object));
       
  1707   g_return_if_fail (notify != NULL);
       
  1708   g_return_if_fail (object->ref_count >= 1);
       
  1709 
       
  1710   g_object_ref (object);
       
  1711 
       
  1712   tstack = g_datalist_id_remove_no_notify (&object->qdata, quark_toggle_refs);
       
  1713   if (tstack)
       
  1714     {
       
  1715       i = tstack->n_toggle_refs++;
       
  1716       /* allocate i = tstate->n_toggle_refs - 1 positions beyond the 1 declared
       
  1717        * in tstate->toggle_refs */
       
  1718       tstack = g_realloc (tstack, sizeof (*tstack) + sizeof (tstack->toggle_refs[0]) * i);
       
  1719     }
       
  1720   else
       
  1721     {
       
  1722       tstack = g_renew (ToggleRefStack, NULL, 1);
       
  1723       tstack->object = object;
       
  1724       tstack->n_toggle_refs = 1;
       
  1725       i = 0;
       
  1726     }
       
  1727 
       
  1728   /* Set a flag for fast lookup after adding the first toggle reference */
       
  1729   if (tstack->n_toggle_refs == 1)
       
  1730     g_datalist_set_flags (&object->qdata, OBJECT_HAS_TOGGLE_REF_FLAG);
       
  1731   
       
  1732   tstack->toggle_refs[i].notify = notify;
       
  1733   tstack->toggle_refs[i].data = data;
       
  1734   g_datalist_id_set_data_full (&object->qdata, quark_toggle_refs, tstack,
       
  1735 			       (GDestroyNotify)g_free);
       
  1736 }
       
  1737  
       
  1738 EXPORT_C void
       
  1739 g_object_remove_toggle_ref (GObject       *object,
       
  1740 			    GToggleNotify  notify,
       
  1741 			    gpointer       data)
       
  1742 {
       
  1743   ToggleRefStack *tstack;
       
  1744   gboolean found_one = FALSE;
       
  1745 
       
  1746   g_return_if_fail (G_IS_OBJECT (object));
       
  1747   g_return_if_fail (notify != NULL);
       
  1748 
       
  1749   tstack = g_datalist_id_get_data (&object->qdata, quark_toggle_refs);
       
  1750   if (tstack)
       
  1751     {
       
  1752       guint i;
       
  1753 
       
  1754       for (i = 0; i < tstack->n_toggle_refs; i++)
       
  1755 	if (tstack->toggle_refs[i].notify == notify &&
       
  1756 	    tstack->toggle_refs[i].data == data)
       
  1757 	  {
       
  1758 	    found_one = TRUE;
       
  1759 	    tstack->n_toggle_refs -= 1;
       
  1760 	    if (i != tstack->n_toggle_refs)
       
  1761 	      tstack->toggle_refs[i] = tstack->toggle_refs[tstack->n_toggle_refs];
       
  1762 
       
  1763 	    if (tstack->n_toggle_refs == 0)
       
  1764 	      g_datalist_unset_flags (&object->qdata, OBJECT_HAS_TOGGLE_REF_FLAG);
       
  1765 
       
  1766 	    g_object_unref (object);
       
  1767 	    
       
  1768 	    break;
       
  1769 	  }
       
  1770     }
       
  1771   
       
  1772   if (!found_one)
       
  1773     g_warning ("%s: couldn't find toggle ref %p(%p)", G_STRFUNC, notify, data);
       
  1774 }
       
  1775 
       
  1776 EXPORT_C gpointer
       
  1777 g_object_ref (gpointer _object)
       
  1778 {
       
  1779   GObject *object = _object;
       
  1780   gint old_val;
       
  1781 
       
  1782   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
       
  1783   g_return_val_if_fail (object->ref_count > 0, NULL);
       
  1784   
       
  1785 #ifdef  G_ENABLE_DEBUG
       
  1786   if (g_trap_object_ref == object)
       
  1787     G_BREAKPOINT ();
       
  1788 #endif  /* G_ENABLE_DEBUG */
       
  1789 
       
  1790 
       
  1791   old_val = g_atomic_int_exchange_and_add (FIX_CASTING(int *)&object->ref_count, 1);
       
  1792 
       
  1793   if (old_val == 1 && OBJECT_HAS_TOGGLE_REF (object))
       
  1794     toggle_refs_notify (object, FALSE);
       
  1795   
       
  1796   return object;
       
  1797 }
       
  1798 
       
  1799 EXPORT_C void
       
  1800 g_object_unref (gpointer _object)
       
  1801 {
       
  1802   GObject *object = _object;
       
  1803   gint old_ref;
       
  1804   gboolean is_zero;
       
  1805   
       
  1806   g_return_if_fail (G_IS_OBJECT (object));
       
  1807   g_return_if_fail (object->ref_count > 0);
       
  1808   
       
  1809 #ifdef  G_ENABLE_DEBUG
       
  1810   if (g_trap_object_ref == object)
       
  1811     G_BREAKPOINT ();
       
  1812 #endif  /* G_ENABLE_DEBUG */
       
  1813 
       
  1814   /* here we want to atomically do: if (ref_count>1) { ref_count--; return; } */
       
  1815  retry_atomic_decrement1:
       
  1816   old_ref = g_atomic_int_get (&object->ref_count);
       
  1817   if (old_ref > 1)
       
  1818     {
       
  1819       if (!g_atomic_int_compare_and_exchange (FIX_CASTING(int *)&object->ref_count, old_ref, old_ref - 1)) 
       
  1820 	goto retry_atomic_decrement1;
       
  1821 
       
  1822       /* if we went from 2->1 we need to notify toggle refs if any */
       
  1823       if (old_ref == 2 && OBJECT_HAS_TOGGLE_REF (object))
       
  1824 	toggle_refs_notify (object, TRUE);
       
  1825     }
       
  1826   else
       
  1827     {
       
  1828       /* we are about tp remove the last reference */
       
  1829       G_OBJECT_GET_CLASS (object)->dispose (object);
       
  1830 
       
  1831       /* may have been re-referenced meanwhile */
       
  1832     retry_atomic_decrement2:
       
  1833       old_ref = g_atomic_int_get (&object->ref_count);
       
  1834       if (old_ref > 1)
       
  1835         {
       
  1836           if (!g_atomic_int_compare_and_exchange (FIX_CASTING(int *)&object->ref_count, old_ref, old_ref - 1)) 
       
  1837 	    goto retry_atomic_decrement2;
       
  1838 
       
  1839           /* if we went from 2->1 we need to notify toggle refs if any */
       
  1840           if (old_ref == 2 && OBJECT_HAS_TOGGLE_REF (object))
       
  1841 	    toggle_refs_notify (object, TRUE);
       
  1842           
       
  1843 	  return;
       
  1844 	}
       
  1845       
       
  1846       /* we are still in the process of taking away the last ref */
       
  1847       g_datalist_id_set_data (&object->qdata, quark_closure_array, NULL);
       
  1848       g_signal_handlers_destroy (object);
       
  1849       g_datalist_id_set_data (&object->qdata, quark_weak_refs, NULL);
       
  1850       
       
  1851       /* decrement the last reference */
       
  1852       is_zero = g_atomic_int_dec_and_test (FIX_CASTING(int *)&object->ref_count);
       
  1853       
       
  1854       /* may have been re-referenced meanwhile */
       
  1855       if (G_LIKELY (is_zero)) 
       
  1856 	{
       
  1857           G_OBJECT_GET_CLASS (object)->finalize (object);
       
  1858 #ifdef	G_ENABLE_DEBUG
       
  1859           IF_DEBUG (OBJECTS)
       
  1860 	    {
       
  1861 	      /* catch objects not chaining finalize handlers */
       
  1862 	      G_LOCK (debug_objects);
       
  1863 	      g_assert (g_hash_table_lookup (debug_objects_ht, object) == NULL);
       
  1864 	      G_UNLOCK (debug_objects);
       
  1865 	    }
       
  1866 #endif	/* G_ENABLE_DEBUG */
       
  1867           g_type_free_instance ((GTypeInstance*) object);
       
  1868 	}
       
  1869     }
       
  1870 }
       
  1871 
       
  1872 EXPORT_C gpointer
       
  1873 g_object_get_qdata (GObject *object,
       
  1874 		    GQuark   quark)
       
  1875 {
       
  1876   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
       
  1877   
       
  1878   return quark ? g_datalist_id_get_data (&object->qdata, quark) : NULL;
       
  1879 }
       
  1880 
       
  1881 EXPORT_C void
       
  1882 g_object_set_qdata (GObject *object,
       
  1883 		    GQuark   quark,
       
  1884 		    gpointer data)
       
  1885 {
       
  1886   g_return_if_fail (G_IS_OBJECT (object));
       
  1887   g_return_if_fail (quark > 0);
       
  1888   
       
  1889   g_datalist_id_set_data (&object->qdata, quark, data);
       
  1890 }
       
  1891 
       
  1892 EXPORT_C void
       
  1893 g_object_set_qdata_full (GObject       *object,
       
  1894 			 GQuark		quark,
       
  1895 			 gpointer	data,
       
  1896 			 GDestroyNotify destroy)
       
  1897 {
       
  1898   g_return_if_fail (G_IS_OBJECT (object));
       
  1899   g_return_if_fail (quark > 0);
       
  1900   
       
  1901   g_datalist_id_set_data_full (&object->qdata, quark, data,
       
  1902 			       data ? destroy : (GDestroyNotify) NULL);
       
  1903 }
       
  1904 
       
  1905 EXPORT_C gpointer
       
  1906 g_object_steal_qdata (GObject *object,
       
  1907 		      GQuark   quark)
       
  1908 {
       
  1909   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
       
  1910   g_return_val_if_fail (quark > 0, NULL);
       
  1911   
       
  1912   return g_datalist_id_remove_no_notify (&object->qdata, quark);
       
  1913 }
       
  1914 
       
  1915 EXPORT_C gpointer
       
  1916 g_object_get_data (GObject     *object,
       
  1917                    const gchar *key)
       
  1918 {
       
  1919   GQuark quark;
       
  1920 
       
  1921   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
       
  1922   g_return_val_if_fail (key != NULL, NULL);
       
  1923 
       
  1924   quark = g_quark_try_string (key);
       
  1925 
       
  1926   return quark ? g_datalist_id_get_data (&object->qdata, quark) : NULL;
       
  1927 }
       
  1928 
       
  1929 EXPORT_C void
       
  1930 g_object_set_data (GObject     *object,
       
  1931                    const gchar *key,
       
  1932                    gpointer     data)
       
  1933 {
       
  1934   g_return_if_fail (G_IS_OBJECT (object));
       
  1935   g_return_if_fail (key != NULL);
       
  1936 
       
  1937   g_datalist_id_set_data (&object->qdata, g_quark_from_string (key), data);
       
  1938 }
       
  1939 
       
  1940 EXPORT_C void
       
  1941 g_object_set_data_full (GObject       *object,
       
  1942                         const gchar   *key,
       
  1943                         gpointer       data,
       
  1944                         GDestroyNotify destroy)
       
  1945 {
       
  1946   g_return_if_fail (G_IS_OBJECT (object));
       
  1947   g_return_if_fail (key != NULL);
       
  1948 
       
  1949   g_datalist_id_set_data_full (&object->qdata, g_quark_from_string (key), data,
       
  1950 			       data ? destroy : (GDestroyNotify) NULL);
       
  1951 }
       
  1952 
       
  1953 EXPORT_C gpointer
       
  1954 g_object_steal_data (GObject     *object,
       
  1955                      const gchar *key)
       
  1956 {
       
  1957   GQuark quark;
       
  1958 
       
  1959   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
       
  1960   g_return_val_if_fail (key != NULL, NULL);
       
  1961 
       
  1962   quark = g_quark_try_string (key);
       
  1963 
       
  1964   return quark ? g_datalist_id_remove_no_notify (&object->qdata, quark) : NULL;
       
  1965 }
       
  1966 
       
  1967 static void
       
  1968 g_value_object_init (GValue *value)
       
  1969 {
       
  1970   value->data[0].v_pointer = NULL;
       
  1971 }
       
  1972 
       
  1973 static void
       
  1974 g_value_object_free_value (GValue *value)
       
  1975 {
       
  1976   if (value->data[0].v_pointer)
       
  1977     g_object_unref (value->data[0].v_pointer);
       
  1978 }
       
  1979 
       
  1980 static void
       
  1981 g_value_object_copy_value (const GValue *src_value,
       
  1982 			   GValue	*dest_value)
       
  1983 {
       
  1984   if (src_value->data[0].v_pointer)
       
  1985     dest_value->data[0].v_pointer = g_object_ref (src_value->data[0].v_pointer);
       
  1986   else
       
  1987     dest_value->data[0].v_pointer = NULL;
       
  1988 }
       
  1989 
       
  1990 static void
       
  1991 g_value_object_transform_value (const GValue *src_value,
       
  1992 				GValue       *dest_value)
       
  1993 {
       
  1994   if (src_value->data[0].v_pointer && g_type_is_a (G_OBJECT_TYPE (src_value->data[0].v_pointer), G_VALUE_TYPE (dest_value)))
       
  1995     dest_value->data[0].v_pointer = g_object_ref (src_value->data[0].v_pointer);
       
  1996   else
       
  1997     dest_value->data[0].v_pointer = NULL;
       
  1998 }
       
  1999 
       
  2000 static gpointer
       
  2001 g_value_object_peek_pointer (const GValue *value)
       
  2002 {
       
  2003   return value->data[0].v_pointer;
       
  2004 }
       
  2005 
       
  2006 static gchar*
       
  2007 g_value_object_collect_value (GValue	  *value,
       
  2008 			      guint        n_collect_values,
       
  2009 			      GTypeCValue *collect_values,
       
  2010 			      guint        collect_flags)
       
  2011 {
       
  2012   if (collect_values[0].v_pointer)
       
  2013     {
       
  2014       GObject *object = collect_values[0].v_pointer;
       
  2015       
       
  2016       if (object->g_type_instance.g_class == NULL)
       
  2017 	return g_strconcat ("invalid unclassed object pointer for value type `",
       
  2018 			    G_VALUE_TYPE_NAME (value),
       
  2019 			    "'",
       
  2020 			    NULL);
       
  2021       else if (!g_value_type_compatible (G_OBJECT_TYPE (object), G_VALUE_TYPE (value)))
       
  2022 	return g_strconcat ("invalid object type `",
       
  2023 			    G_OBJECT_TYPE_NAME (object),
       
  2024 			    "' for value type `",
       
  2025 			    G_VALUE_TYPE_NAME (value),
       
  2026 			    "'",
       
  2027 			    NULL);
       
  2028       /* never honour G_VALUE_NOCOPY_CONTENTS for ref-counted types */
       
  2029       value->data[0].v_pointer = g_object_ref (object);
       
  2030     }
       
  2031   else
       
  2032     value->data[0].v_pointer = NULL;
       
  2033   
       
  2034   return NULL;
       
  2035 }
       
  2036 
       
  2037 static gchar*
       
  2038 g_value_object_lcopy_value (const GValue *value,
       
  2039 			    guint        n_collect_values,
       
  2040 			    GTypeCValue *collect_values,
       
  2041 			    guint        collect_flags)
       
  2042 {
       
  2043   GObject **object_p = collect_values[0].v_pointer;
       
  2044   
       
  2045   if (!object_p)
       
  2046     return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
       
  2047 
       
  2048   if (!value->data[0].v_pointer)
       
  2049     *object_p = NULL;
       
  2050   else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
       
  2051     *object_p = value->data[0].v_pointer;
       
  2052   else
       
  2053     *object_p = g_object_ref (value->data[0].v_pointer);
       
  2054   
       
  2055   return NULL;
       
  2056 }
       
  2057 
       
  2058 EXPORT_C void
       
  2059 g_value_set_object (GValue   *value,
       
  2060 		    gpointer  v_object)
       
  2061 {
       
  2062   GObject *old;
       
  2063 	
       
  2064   g_return_if_fail (G_VALUE_HOLDS_OBJECT (value));
       
  2065 
       
  2066   old = value->data[0].v_pointer;
       
  2067   
       
  2068   if (v_object)
       
  2069     {
       
  2070       g_return_if_fail (G_IS_OBJECT (v_object));
       
  2071       g_return_if_fail (g_value_type_compatible (G_OBJECT_TYPE (v_object), G_VALUE_TYPE (value)));
       
  2072 
       
  2073       value->data[0].v_pointer = v_object;
       
  2074       g_object_ref (value->data[0].v_pointer);
       
  2075     }
       
  2076   else
       
  2077     value->data[0].v_pointer = NULL;
       
  2078   
       
  2079   if (old)
       
  2080     g_object_unref (old);
       
  2081 }
       
  2082 
       
  2083 EXPORT_C void
       
  2084 g_value_set_object_take_ownership (GValue  *value,
       
  2085 				   gpointer v_object)
       
  2086 {
       
  2087   g_value_take_object (value, v_object);
       
  2088 }
       
  2089 
       
  2090 EXPORT_C void
       
  2091 g_value_take_object (GValue  *value,
       
  2092 		     gpointer v_object)
       
  2093 {
       
  2094   g_return_if_fail (G_VALUE_HOLDS_OBJECT (value));
       
  2095 
       
  2096   if (value->data[0].v_pointer)
       
  2097     {
       
  2098       g_object_unref (value->data[0].v_pointer);
       
  2099       value->data[0].v_pointer = NULL;
       
  2100     }
       
  2101 
       
  2102   if (v_object)
       
  2103     {
       
  2104       g_return_if_fail (G_IS_OBJECT (v_object));
       
  2105       g_return_if_fail (g_value_type_compatible (G_OBJECT_TYPE (v_object), G_VALUE_TYPE (value)));
       
  2106 
       
  2107       value->data[0].v_pointer = v_object; /* we take over the reference count */
       
  2108     }
       
  2109 }
       
  2110 
       
  2111 EXPORT_C gpointer
       
  2112 g_value_get_object (const GValue *value)
       
  2113 {
       
  2114   g_return_val_if_fail (G_VALUE_HOLDS_OBJECT (value), NULL);
       
  2115   
       
  2116   return value->data[0].v_pointer;
       
  2117 }
       
  2118 
       
  2119 EXPORT_C GObject*
       
  2120 g_value_dup_object (const GValue *value)
       
  2121 {
       
  2122   g_return_val_if_fail (G_VALUE_HOLDS_OBJECT (value), NULL);
       
  2123   
       
  2124   return value->data[0].v_pointer ? g_object_ref (value->data[0].v_pointer) : NULL;
       
  2125 }
       
  2126 
       
  2127 EXPORT_C gulong
       
  2128 g_signal_connect_object (gpointer      instance,
       
  2129 			 const gchar  *detailed_signal,
       
  2130 			 GCallback     c_handler,
       
  2131 			 gpointer      gobject,
       
  2132 			 GConnectFlags connect_flags)
       
  2133 {
       
  2134   g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
       
  2135   g_return_val_if_fail (detailed_signal != NULL, 0);
       
  2136   g_return_val_if_fail (c_handler != NULL, 0);
       
  2137 
       
  2138   if (gobject)
       
  2139     {
       
  2140       GClosure *closure;
       
  2141 
       
  2142       g_return_val_if_fail (G_IS_OBJECT (gobject), 0);
       
  2143 
       
  2144       closure = ((connect_flags & G_CONNECT_SWAPPED) ? g_cclosure_new_object_swap : g_cclosure_new_object) (c_handler, gobject);
       
  2145 
       
  2146       return g_signal_connect_closure (instance, detailed_signal, closure, connect_flags & G_CONNECT_AFTER);
       
  2147     }
       
  2148   else
       
  2149     return g_signal_connect_data (instance, detailed_signal, c_handler, NULL, NULL, connect_flags);
       
  2150 }
       
  2151 
       
  2152 typedef struct {
       
  2153   GObject  *object;
       
  2154   guint     n_closures;
       
  2155   GClosure *closures[1]; /* flexible array */
       
  2156 } CArray;
       
  2157 /* don't change this structure without supplying an accessor for
       
  2158  * watched closures, e.g.:
       
  2159  * GSList* g_object_list_watched_closures (GObject *object)
       
  2160  * {
       
  2161  *   CArray *carray;
       
  2162  *   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
       
  2163  *   carray = g_object_get_data (object, "GObject-closure-array");
       
  2164  *   if (carray)
       
  2165  *     {
       
  2166  *       GSList *slist = NULL;
       
  2167  *       guint i;
       
  2168  *       for (i = 0; i < carray->n_closures; i++)
       
  2169  *         slist = g_slist_prepend (slist, carray->closures[i]);
       
  2170  *       return slist;
       
  2171  *     }
       
  2172  *   return NULL;
       
  2173  * }
       
  2174  */
       
  2175 
       
  2176 static void
       
  2177 object_remove_closure (gpointer  data,
       
  2178 		       GClosure *closure)
       
  2179 {
       
  2180   GObject *object = data;
       
  2181   CArray *carray = g_object_get_qdata (object, quark_closure_array);
       
  2182   guint i;
       
  2183   
       
  2184   for (i = 0; i < carray->n_closures; i++)
       
  2185     if (carray->closures[i] == closure)
       
  2186       {
       
  2187 	carray->n_closures--;
       
  2188 	if (i < carray->n_closures)
       
  2189 	  carray->closures[i] = carray->closures[carray->n_closures];
       
  2190 	return;
       
  2191       }
       
  2192   g_assert_not_reached ();
       
  2193 }
       
  2194 
       
  2195 static void
       
  2196 destroy_closure_array (gpointer data)
       
  2197 {
       
  2198   CArray *carray = data;
       
  2199   GObject *object = carray->object;
       
  2200   guint i, n = carray->n_closures;
       
  2201   
       
  2202   for (i = 0; i < n; i++)
       
  2203     {
       
  2204       GClosure *closure = carray->closures[i];
       
  2205       
       
  2206       /* removing object_remove_closure() upfront is probably faster than
       
  2207        * letting it fiddle with quark_closure_array which is empty anyways
       
  2208        */
       
  2209       g_closure_remove_invalidate_notifier (closure, object, object_remove_closure);
       
  2210       g_closure_invalidate (closure);
       
  2211     }
       
  2212   g_free (carray);
       
  2213 }
       
  2214 
       
  2215 EXPORT_C void
       
  2216 g_object_watch_closure (GObject  *object,
       
  2217 			GClosure *closure)
       
  2218 {
       
  2219   CArray *carray;
       
  2220   guint i;
       
  2221   
       
  2222   g_return_if_fail (G_IS_OBJECT (object));
       
  2223   g_return_if_fail (closure != NULL);
       
  2224   g_return_if_fail (closure->is_invalid == FALSE);
       
  2225   g_return_if_fail (closure->in_marshal == FALSE);
       
  2226   g_return_if_fail (object->ref_count > 0);	/* this doesn't work on finalizing objects */
       
  2227   
       
  2228   g_closure_add_invalidate_notifier (closure, object, object_remove_closure);
       
  2229   g_closure_add_marshal_guards (closure,
       
  2230 				object, (GClosureNotify) g_object_ref,
       
  2231 				object, (GClosureNotify) g_object_unref);
       
  2232   carray = g_datalist_id_remove_no_notify (&object->qdata, quark_closure_array);
       
  2233   if (!carray)
       
  2234     {
       
  2235       carray = g_renew (CArray, NULL, 1);
       
  2236       carray->object = object;
       
  2237       carray->n_closures = 1;
       
  2238       i = 0;
       
  2239     }
       
  2240   else
       
  2241     {
       
  2242       i = carray->n_closures++;
       
  2243       carray = g_realloc (carray, sizeof (*carray) + sizeof (carray->closures[0]) * i);
       
  2244     }
       
  2245   carray->closures[i] = closure;
       
  2246   g_datalist_id_set_data_full (&object->qdata, quark_closure_array, carray, destroy_closure_array);
       
  2247 }
       
  2248 
       
  2249 EXPORT_C GClosure*
       
  2250 g_closure_new_object (guint    sizeof_closure,
       
  2251 		      GObject *object)
       
  2252 {
       
  2253   GClosure *closure;
       
  2254 
       
  2255   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
       
  2256   g_return_val_if_fail (object->ref_count > 0, NULL);     /* this doesn't work on finalizing objects */
       
  2257 
       
  2258   closure = g_closure_new_simple (sizeof_closure, object);
       
  2259   g_object_watch_closure (object, closure);
       
  2260 
       
  2261   return closure;
       
  2262 }
       
  2263 
       
  2264 EXPORT_C GClosure*
       
  2265 g_cclosure_new_object (GCallback callback_func,
       
  2266 		       GObject  *object)
       
  2267 {
       
  2268   GClosure *closure;
       
  2269 
       
  2270   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
       
  2271   g_return_val_if_fail (object->ref_count > 0, NULL);     /* this doesn't work on finalizing objects */
       
  2272   g_return_val_if_fail (callback_func != NULL, NULL);
       
  2273 
       
  2274   closure = g_cclosure_new (callback_func, object, NULL);
       
  2275   g_object_watch_closure (object, closure);
       
  2276 
       
  2277   return closure;
       
  2278 }
       
  2279 
       
  2280 EXPORT_C GClosure*
       
  2281 g_cclosure_new_object_swap (GCallback callback_func,
       
  2282 			    GObject  *object)
       
  2283 {
       
  2284   GClosure *closure;
       
  2285 
       
  2286   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
       
  2287   g_return_val_if_fail (object->ref_count > 0, NULL);     /* this doesn't work on finalizing objects */
       
  2288   g_return_val_if_fail (callback_func != NULL, NULL);
       
  2289 
       
  2290   closure = g_cclosure_new_swap (callback_func, object, NULL);
       
  2291   g_object_watch_closure (object, closure);
       
  2292 
       
  2293   return closure;
       
  2294 }
       
  2295 
       
  2296 gsize
       
  2297 g_object_compat_control (gsize           what,
       
  2298                          gpointer        data)
       
  2299 {
       
  2300   switch (what)
       
  2301     {
       
  2302       gpointer *pp;
       
  2303     case 1:     /* floating base type */
       
  2304       return G_TYPE_INITIALLY_UNOWNED;
       
  2305     case 2:     /* FIXME: remove this once GLib/Gtk+ break ABI again */
       
  2306       floating_flag_handler = (guint(*)(GObject*,gint)) data;
       
  2307       return 1;
       
  2308     case 3:     /* FIXME: remove this once GLib/Gtk+ break ABI again */
       
  2309       pp = data;
       
  2310       *pp = FIX_CASTING(void *)floating_flag_handler;
       
  2311       return 1;
       
  2312     default:
       
  2313       return 0;
       
  2314     }
       
  2315 }
       
  2316 
       
  2317 #ifdef __SYMBIAN32__
       
  2318 
       
  2319 static void g_initially_unowned_init (GInitiallyUnowned *self); 
       
  2320 static void g_initially_unowned_class_init (GInitiallyUnownedClass *klass); 
       
  2321 
       
  2322 #if EMULATOR
       
  2323 
       
  2324 PLS(g_initially_unowned_parent_class,gobject,gpointer)
       
  2325 #define g_initially_unowned_parent_class (*FUNCTION_NAME(g_initially_unowned_parent_class,gobject)())
       
  2326 
       
  2327 #else
       
  2328 
       
  2329 static gpointer g_initially_unowned_parent_class = 0; 
       
  2330 
       
  2331 #endif /* EMULATOR */
       
  2332 
       
  2333 
       
  2334 static void g_initially_unowned_class_intern_init (gpointer klass)
       
  2335 { 
       
  2336 	g_initially_unowned_parent_class = g_type_class_peek_parent (klass); 
       
  2337 	g_initially_unowned_class_init ((GInitiallyUnownedClass*) klass); 
       
  2338 } 
       
  2339 
       
  2340 #if EMULATOR
       
  2341 
       
  2342 PLS(g_define_type_id,g_initially_unowned_get_type,GType)
       
  2343 #define g_define_type_id (*FUNCTION_NAME(g_define_type_id,g_initially_unowned_get_type)())
       
  2344 
       
  2345 #endif /* EMULATOR */
       
  2346 
       
  2347 EXPORT_C GType g_initially_unowned_get_type (void) 
       
  2348 { 
       
  2349 	#if !(EMULATOR)
       
  2350 	static GType g_define_type_id = 0; 
       
  2351 	#endif /* !(EMULATOR) */
       
  2352 	if ((g_define_type_id == 0)) 
       
  2353 	{ 
       
  2354 		static const GTypeInfo g_define_type_info = { sizeof (GInitiallyUnownedClass), (GBaseInitFunc) 0, (GBaseFinalizeFunc) 0, (GClassInitFunc) g_initially_unowned_class_intern_init, (GClassFinalizeFunc) 0, 0, sizeof (GInitiallyUnowned), 0, (GInstanceInitFunc) g_initially_unowned_init, 0 }; 
       
  2355 		g_define_type_id = g_type_register_static ( ((GType) ((20) << (2))), g_intern_static_string ("GInitiallyUnowned"), &g_define_type_info, (GTypeFlags) 0); 
       
  2356 		{
       
  2357 		 {} ; 
       
  2358 		} 
       
  2359 	} 
       
  2360 		return g_define_type_id; 
       
  2361 } ;
       
  2362 
       
  2363 #if EMULATOR
       
  2364 #undef g_define_type_id
       
  2365 #endif /* EMULATOR */
       
  2366 
       
  2367 #else
       
  2368 
       
  2369 G_DEFINE_TYPE (GInitiallyUnowned, g_initially_unowned, G_TYPE_OBJECT);
       
  2370 
       
  2371 #endif /* __SYMBIAN32__ */
       
  2372 
       
  2373 static void
       
  2374 g_initially_unowned_init (GInitiallyUnowned *object)
       
  2375 {
       
  2376   g_object_force_floating (object);
       
  2377 }
       
  2378 
       
  2379 static void
       
  2380 g_initially_unowned_class_init (GInitiallyUnownedClass *klass)
       
  2381 {
       
  2382 }
       
  2383 
       
  2384 #define __G_OBJECT_C__
       
  2385 #include "gobjectaliasdef.c"