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