Fix some issues with PLT entries.
[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   /* set remaining properties */
954   for (i = 0; i < n_oparams; i++)
955     object_set_property (object, oparams[i].pspec, oparams[i].value, nqueue);
956   g_free (oparams);
957
958   /* release our own freeze count and handle notifications */
959   if (newly_constructed || n_oparams)
960     g_object_notify_queue_thaw (object, nqueue);
961   if (unref_class)
962     g_type_class_unref (unref_class);
963
964   return object;
965 }
966
967 GObject*
968 g_object_new_valist (GType        object_type,
969                      const gchar *first_property_name,
970                      va_list      var_args)
971 {
972   GObjectClass *class;
973   GParameter *params;
974   const gchar *name;
975   GObject *object;
976   guint n_params = 0, n_alloced_params = 16;
977   
978   g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type), NULL);
979
980   if (!first_property_name)
981     return g_object_newv (object_type, 0, NULL);
982
983   class = g_type_class_ref (object_type);
984
985   params = g_new (GParameter, n_alloced_params);
986   name = first_property_name;
987   while (name)
988     {
989       gchar *error = NULL;
990       GParamSpec *pspec = g_param_spec_pool_lookup (pspec_pool,
991                                                     name,
992                                                     object_type,
993                                                     TRUE);
994       if (!pspec)
995         {
996           g_warning ("%s: object class `%s' has no property named `%s'",
997                      G_STRFUNC,
998                      g_type_name (object_type),
999                      name);
1000           break;
1001         }
1002       if (n_params >= n_alloced_params)
1003         {
1004           n_alloced_params += 16;
1005           params = g_renew (GParameter, params, n_alloced_params);
1006         }
1007       params[n_params].name = name;
1008       params[n_params].value.g_type = 0;
1009       g_value_init (&params[n_params].value, G_PARAM_SPEC_VALUE_TYPE (pspec));
1010       G_VALUE_COLLECT (&params[n_params].value, var_args, 0, &error);
1011       if (error)
1012         {
1013           g_warning ("%s: %s", G_STRFUNC, error);
1014           g_free (error);
1015           g_value_unset (&params[n_params].value);
1016           break;
1017         }
1018       n_params++;
1019       name = va_arg (var_args, gchar*);
1020     }
1021
1022   object = g_object_newv (object_type, n_params, params);
1023
1024   while (n_params--)
1025     g_value_unset (&params[n_params].value);
1026   g_free (params);
1027
1028   g_type_class_unref (class);
1029
1030   return object;
1031 }
1032
1033 static GObject*
1034 g_object_constructor (GType                  type,
1035                       guint                  n_construct_properties,
1036                       GObjectConstructParam *construct_params)
1037 {
1038   GObject *object;
1039
1040   /* create object */
1041   object = (GObject*) g_type_create_instance (type);
1042   
1043   /* set construction parameters */
1044   if (n_construct_properties)
1045     {
1046       GObjectNotifyQueue *nqueue = g_object_notify_queue_freeze (object, &property_notify_context);
1047       
1048       /* set construct properties */
1049       while (n_construct_properties--)
1050         {
1051           GValue *value = construct_params->value;
1052           GParamSpec *pspec = construct_params->pspec;
1053
1054           construct_params++;
1055           object_set_property (object, pspec, value, nqueue);
1056         }
1057       g_object_notify_queue_thaw (object, nqueue);
1058       /* the notification queue is still frozen from g_object_init(), so
1059        * we don't need to handle it here, g_object_newv() takes
1060        * care of that
1061        */
1062     }
1063
1064   return object;
1065 }
1066
1067 void
1068 g_object_set_valist (GObject     *object,
1069                      const gchar *first_property_name,
1070                      va_list      var_args)
1071 {
1072   GObjectNotifyQueue *nqueue;
1073   const gchar *name;
1074   
1075   g_return_if_fail (G_IS_OBJECT (object));
1076   
1077   g_object_ref (object);
1078   nqueue = g_object_notify_queue_freeze (object, &property_notify_context);
1079   
1080   name = first_property_name;
1081   while (name)
1082     {
1083       GValue value = { 0, };
1084       GParamSpec *pspec;
1085       gchar *error = NULL;
1086       
1087       pspec = g_param_spec_pool_lookup (pspec_pool,
1088                                         name,
1089                                         G_OBJECT_TYPE (object),
1090                                         TRUE);
1091       if (!pspec)
1092         {
1093           g_warning ("%s: object class `%s' has no property named `%s'",
1094                      G_STRFUNC,
1095                      G_OBJECT_TYPE_NAME (object),
1096                      name);
1097           break;
1098         }
1099       if (!(pspec->flags & G_PARAM_WRITABLE))
1100         {
1101           g_warning ("%s: property `%s' of object class `%s' is not writable",
1102                      G_STRFUNC,
1103                      pspec->name,
1104                      G_OBJECT_TYPE_NAME (object));
1105           break;
1106         }
1107       if ((pspec->flags & G_PARAM_CONSTRUCT_ONLY) && !object_in_construction_list (object))
1108         {
1109           g_warning ("%s: construct property \"%s\" for object `%s' can't be set after construction",
1110                      G_STRFUNC, pspec->name, G_OBJECT_TYPE_NAME (object));
1111           break;
1112         }
1113
1114       g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
1115       
1116       G_VALUE_COLLECT (&value, var_args, 0, &error);
1117       if (error)
1118         {
1119           g_warning ("%s: %s", G_STRFUNC, error);
1120           g_free (error);
1121           g_value_unset (&value);
1122           break;
1123         }
1124       
1125       object_set_property (object, pspec, &value, nqueue);
1126       g_value_unset (&value);
1127       
1128       name = va_arg (var_args, gchar*);
1129     }
1130
1131   g_object_notify_queue_thaw (object, nqueue);
1132   g_object_unref (object);
1133 }
1134
1135 void
1136 g_object_get_valist (GObject     *object,
1137                      const gchar *first_property_name,
1138                      va_list      var_args)
1139 {
1140   const gchar *name;
1141   
1142   g_return_if_fail (G_IS_OBJECT (object));
1143   
1144   g_object_ref (object);
1145   
1146   name = first_property_name;
1147   
1148   while (name)
1149     {
1150       GValue value = { 0, };
1151       GParamSpec *pspec;
1152       gchar *error;
1153       
1154       pspec = g_param_spec_pool_lookup (pspec_pool,
1155                                         name,
1156                                         G_OBJECT_TYPE (object),
1157                                         TRUE);
1158       if (!pspec)
1159         {
1160           g_warning ("%s: object class `%s' has no property named `%s'",
1161                      G_STRFUNC,
1162                      G_OBJECT_TYPE_NAME (object),
1163                      name);
1164           break;
1165         }
1166       if (!(pspec->flags & G_PARAM_READABLE))
1167         {
1168           g_warning ("%s: property `%s' of object class `%s' is not readable",
1169                      G_STRFUNC,
1170                      pspec->name,
1171                      G_OBJECT_TYPE_NAME (object));
1172           break;
1173         }
1174       
1175       g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
1176       
1177       object_get_property (object, pspec, &value);
1178       
1179       G_VALUE_LCOPY (&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       g_value_unset (&value);
1189       
1190       name = va_arg (var_args, gchar*);
1191     }
1192   
1193   g_object_unref (object);
1194 }
1195
1196 void
1197 g_object_set (gpointer     _object,
1198               const gchar *first_property_name,
1199               ...)
1200 {
1201   GObject *object = _object;
1202   va_list var_args;
1203   
1204   g_return_if_fail (G_IS_OBJECT (object));
1205   
1206   va_start (var_args, first_property_name);
1207   g_object_set_valist (object, first_property_name, var_args);
1208   va_end (var_args);
1209 }
1210
1211 void
1212 g_object_get (gpointer     _object,
1213               const gchar *first_property_name,
1214               ...)
1215 {
1216   GObject *object = _object;
1217   va_list var_args;
1218   
1219   g_return_if_fail (G_IS_OBJECT (object));
1220   
1221   va_start (var_args, first_property_name);
1222   g_object_get_valist (object, first_property_name, var_args);
1223   va_end (var_args);
1224 }
1225
1226 void
1227 g_object_set_property (GObject      *object,
1228                        const gchar  *property_name,
1229                        const GValue *value)
1230 {
1231   GObjectNotifyQueue *nqueue;
1232   GParamSpec *pspec;
1233   
1234   g_return_if_fail (G_IS_OBJECT (object));
1235   g_return_if_fail (property_name != NULL);
1236   g_return_if_fail (G_IS_VALUE (value));
1237   
1238   g_object_ref (object);
1239   nqueue = g_object_notify_queue_freeze (object, &property_notify_context);
1240   
1241   pspec = g_param_spec_pool_lookup (pspec_pool,
1242                                     property_name,
1243                                     G_OBJECT_TYPE (object),
1244                                     TRUE);
1245   if (!pspec)
1246     g_warning ("%s: object class `%s' has no property named `%s'",
1247                G_STRFUNC,
1248                G_OBJECT_TYPE_NAME (object),
1249                property_name);
1250   else if (!(pspec->flags & G_PARAM_WRITABLE))
1251     g_warning ("%s: property `%s' of object class `%s' is not writable",
1252                G_STRFUNC,
1253                pspec->name,
1254                G_OBJECT_TYPE_NAME (object));
1255   else if ((pspec->flags & G_PARAM_CONSTRUCT_ONLY) && !object_in_construction_list (object))
1256     g_warning ("%s: construct property \"%s\" for object `%s' can't be set after construction",
1257                G_STRFUNC, pspec->name, G_OBJECT_TYPE_NAME (object));
1258   else
1259     object_set_property (object, pspec, value, nqueue);
1260   
1261   g_object_notify_queue_thaw (object, nqueue);
1262   g_object_unref (object);
1263 }
1264
1265 void
1266 g_object_get_property (GObject     *object,
1267                        const gchar *property_name,
1268                        GValue      *value)
1269 {
1270   GParamSpec *pspec;
1271   
1272   g_return_if_fail (G_IS_OBJECT (object));
1273   g_return_if_fail (property_name != NULL);
1274   g_return_if_fail (G_IS_VALUE (value));
1275   
1276   g_object_ref (object);
1277   
1278   pspec = g_param_spec_pool_lookup (pspec_pool,
1279                                     property_name,
1280                                     G_OBJECT_TYPE (object),
1281                                     TRUE);
1282   if (!pspec)
1283     g_warning ("%s: object class `%s' has no property named `%s'",
1284                G_STRFUNC,
1285                G_OBJECT_TYPE_NAME (object),
1286                property_name);
1287   else if (!(pspec->flags & G_PARAM_READABLE))
1288     g_warning ("%s: property `%s' of object class `%s' is not readable",
1289                G_STRFUNC,
1290                pspec->name,
1291                G_OBJECT_TYPE_NAME (object));
1292   else
1293     {
1294       GValue *prop_value, tmp_value = { 0, };
1295       
1296       /* auto-conversion of the callers value type
1297        */
1298       if (G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (pspec))
1299         {
1300           g_value_reset (value);
1301           prop_value = value;
1302         }
1303       else if (!g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec), G_VALUE_TYPE (value)))
1304         {
1305           g_warning ("%s: can't retrieve property `%s' of type `%s' as value of type `%s'",
1306                      G_STRFUNC, pspec->name,
1307                      g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1308                      G_VALUE_TYPE_NAME (value));
1309           g_object_unref (object);
1310           return;
1311         }
1312       else
1313         {
1314           g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
1315           prop_value = &tmp_value;
1316         }
1317       object_get_property (object, pspec, prop_value);
1318       if (prop_value != value)
1319         {
1320           g_value_transform (prop_value, value);
1321           g_value_unset (&tmp_value);
1322         }
1323     }
1324   
1325   g_object_unref (object);
1326 }
1327
1328 gpointer
1329 g_object_connect (gpointer     _object,
1330                   const gchar *signal_spec,
1331                   ...)
1332 {
1333   GObject *object = _object;
1334   va_list var_args;
1335
1336   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1337   g_return_val_if_fail (object->ref_count > 0, object);
1338
1339   va_start (var_args, signal_spec);
1340   while (signal_spec)
1341     {
1342       GCallback callback = va_arg (var_args, GCallback);
1343       gpointer data = va_arg (var_args, gpointer);
1344       gulong sid;
1345
1346       if (strncmp (signal_spec, "signal::", 8) == 0)
1347         sid = g_signal_connect_data (object, signal_spec + 8,
1348                                      callback, data, NULL,
1349                                      0);
1350       else if (strncmp (signal_spec, "object_signal::", 15) == 0 ||
1351                strncmp (signal_spec, "object-signal::", 15) == 0)
1352         sid = g_signal_connect_object (object, signal_spec + 15,
1353                                        callback, data,
1354                                        0);
1355       else if (strncmp (signal_spec, "swapped_signal::", 16) == 0 ||
1356                strncmp (signal_spec, "swapped-signal::", 16) == 0)
1357         sid = g_signal_connect_data (object, signal_spec + 16,
1358                                      callback, data, NULL,
1359                                      G_CONNECT_SWAPPED);
1360       else if (strncmp (signal_spec, "swapped_object_signal::", 23) == 0 ||
1361                strncmp (signal_spec, "swapped-object-signal::", 23) == 0)
1362         sid = g_signal_connect_object (object, signal_spec + 23,
1363                                        callback, data,
1364                                        G_CONNECT_SWAPPED);
1365       else if (strncmp (signal_spec, "signal_after::", 14) == 0 ||
1366                strncmp (signal_spec, "signal-after::", 14) == 0)
1367         sid = g_signal_connect_data (object, signal_spec + 14,
1368                                      callback, data, NULL,
1369                                      G_CONNECT_AFTER);
1370       else if (strncmp (signal_spec, "object_signal_after::", 21) == 0 ||
1371                strncmp (signal_spec, "object-signal-after::", 21) == 0)
1372         sid = g_signal_connect_object (object, signal_spec + 21,
1373                                        callback, data,
1374                                        G_CONNECT_AFTER);
1375       else if (strncmp (signal_spec, "swapped_signal_after::", 22) == 0 ||
1376                strncmp (signal_spec, "swapped-signal-after::", 22) == 0)
1377         sid = g_signal_connect_data (object, signal_spec + 22,
1378                                      callback, data, NULL,
1379                                      G_CONNECT_SWAPPED | G_CONNECT_AFTER);
1380       else if (strncmp (signal_spec, "swapped_object_signal_after::", 29) == 0 ||
1381                strncmp (signal_spec, "swapped-object-signal-after::", 29) == 0)
1382         sid = g_signal_connect_object (object, signal_spec + 29,
1383                                        callback, data,
1384                                        G_CONNECT_SWAPPED | G_CONNECT_AFTER);
1385       else
1386         {
1387           g_warning ("%s: invalid signal spec \"%s\"", G_STRFUNC, signal_spec);
1388           break;
1389         }
1390       signal_spec = va_arg (var_args, gchar*);
1391     }
1392   va_end (var_args);
1393
1394   return object;
1395 }
1396
1397 void
1398 g_object_disconnect (gpointer     _object,
1399                      const gchar *signal_spec,
1400                      ...)
1401 {
1402   GObject *object = _object;
1403   va_list var_args;
1404
1405   g_return_if_fail (G_IS_OBJECT (object));
1406   g_return_if_fail (object->ref_count > 0);
1407
1408   va_start (var_args, signal_spec);
1409   while (signal_spec)
1410     {
1411       GCallback callback = va_arg (var_args, GCallback);
1412       gpointer data = va_arg (var_args, gpointer);
1413       guint sid = 0, detail = 0, mask = 0;
1414
1415       if (strncmp (signal_spec, "any_signal::", 12) == 0 ||
1416           strncmp (signal_spec, "any-signal::", 12) == 0)
1417         {
1418           signal_spec += 12;
1419           mask = G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA;
1420         }
1421       else if (strcmp (signal_spec, "any_signal") == 0 ||
1422                strcmp (signal_spec, "any-signal") == 0)
1423         {
1424           signal_spec += 10;
1425           mask = G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA;
1426         }
1427       else
1428         {
1429           g_warning ("%s: invalid signal spec \"%s\"", G_STRFUNC, signal_spec);
1430           break;
1431         }
1432
1433       if ((mask & G_SIGNAL_MATCH_ID) &&
1434           !g_signal_parse_name (signal_spec, G_OBJECT_TYPE (object), &sid, &detail, FALSE))
1435         g_warning ("%s: invalid signal name \"%s\"", G_STRFUNC, signal_spec);
1436       else if (!g_signal_handlers_disconnect_matched (object, mask | (detail ? G_SIGNAL_MATCH_DETAIL : 0),
1437                                                       sid, detail,
1438                                                       NULL, (gpointer)callback, data))
1439         g_warning ("%s: signal handler %p(%p) is not connected", G_STRFUNC, callback, data);
1440       signal_spec = va_arg (var_args, gchar*);
1441     }
1442   va_end (var_args);
1443 }
1444
1445 typedef struct {
1446   GObject *object;
1447   guint n_weak_refs;
1448   struct {
1449     GWeakNotify notify;
1450     gpointer    data;
1451   } weak_refs[1];  /* flexible array */
1452 } WeakRefStack;
1453
1454 static void
1455 weak_refs_notify (gpointer data)
1456 {
1457   WeakRefStack *wstack = data;
1458   guint i;
1459
1460   for (i = 0; i < wstack->n_weak_refs; i++)
1461     wstack->weak_refs[i].notify (wstack->weak_refs[i].data, wstack->object);
1462   g_free (wstack);
1463 }
1464
1465 void
1466 g_object_weak_ref (GObject    *object,
1467                    GWeakNotify notify,
1468                    gpointer    data)
1469 {
1470   WeakRefStack *wstack;
1471   guint i;
1472   
1473   g_return_if_fail (G_IS_OBJECT (object));
1474   g_return_if_fail (notify != NULL);
1475   g_return_if_fail (object->ref_count >= 1);
1476
1477   wstack = g_datalist_id_remove_no_notify (&object->qdata, quark_weak_refs);
1478   if (wstack)
1479     {
1480       i = wstack->n_weak_refs++;
1481       wstack = g_realloc (wstack, sizeof (*wstack) + sizeof (wstack->weak_refs[0]) * i);
1482     }
1483   else
1484     {
1485       wstack = g_renew (WeakRefStack, NULL, 1);
1486       wstack->object = object;
1487       wstack->n_weak_refs = 1;
1488       i = 0;
1489     }
1490   wstack->weak_refs[i].notify = notify;
1491   wstack->weak_refs[i].data = data;
1492   g_datalist_id_set_data_full (&object->qdata, quark_weak_refs, wstack, weak_refs_notify);
1493 }
1494
1495 void
1496 g_object_weak_unref (GObject    *object,
1497                      GWeakNotify notify,
1498                      gpointer    data)
1499 {
1500   WeakRefStack *wstack;
1501   gboolean found_one = FALSE;
1502
1503   g_return_if_fail (G_IS_OBJECT (object));
1504   g_return_if_fail (notify != NULL);
1505
1506   wstack = g_datalist_id_get_data (&object->qdata, quark_weak_refs);
1507   if (wstack)
1508     {
1509       guint i;
1510
1511       for (i = 0; i < wstack->n_weak_refs; i++)
1512         if (wstack->weak_refs[i].notify == notify &&
1513             wstack->weak_refs[i].data == data)
1514           {
1515             found_one = TRUE;
1516             wstack->n_weak_refs -= 1;
1517             if (i != wstack->n_weak_refs)
1518               wstack->weak_refs[i] = wstack->weak_refs[wstack->n_weak_refs];
1519
1520             break;
1521           }
1522     }
1523   if (!found_one)
1524     g_warning ("%s: couldn't find weak ref %p(%p)", G_STRFUNC, notify, data);
1525 }
1526
1527 void
1528 g_object_add_weak_pointer (GObject  *object, 
1529                            gpointer *weak_pointer_location)
1530 {
1531   g_return_if_fail (G_IS_OBJECT (object));
1532   g_return_if_fail (weak_pointer_location != NULL);
1533
1534   g_object_weak_ref (object, 
1535                      (GWeakNotify) g_nullify_pointer, 
1536                      weak_pointer_location);
1537 }
1538
1539 void
1540 g_object_remove_weak_pointer (GObject  *object, 
1541                               gpointer *weak_pointer_location)
1542 {
1543   g_return_if_fail (G_IS_OBJECT (object));
1544   g_return_if_fail (weak_pointer_location != NULL);
1545
1546   g_object_weak_unref (object, 
1547                        (GWeakNotify) g_nullify_pointer, 
1548                        weak_pointer_location);
1549 }
1550
1551 static guint
1552 object_floating_flag_handler (GObject        *object,
1553                               gint            job)
1554 {
1555   switch (job)
1556     {
1557       gpointer oldvalue;
1558     case +1:    /* force floating if possible */
1559       do
1560         oldvalue = g_atomic_pointer_get (&object->qdata);
1561       while (!g_atomic_pointer_compare_and_exchange ((void**) &object->qdata, oldvalue,
1562                                                      (gpointer) ((gsize) oldvalue | OBJECT_FLOATING_FLAG)));
1563       return (gsize) oldvalue & OBJECT_FLOATING_FLAG;
1564     case -1:    /* sink if possible */
1565       do
1566         oldvalue = g_atomic_pointer_get (&object->qdata);
1567       while (!g_atomic_pointer_compare_and_exchange ((void**) &object->qdata, oldvalue,
1568                                                      (gpointer) ((gsize) oldvalue & ~(gsize) OBJECT_FLOATING_FLAG)));
1569       return (gsize) oldvalue & OBJECT_FLOATING_FLAG;
1570     default:    /* check floating */
1571       return 0 != ((gsize) g_atomic_pointer_get (&object->qdata) & OBJECT_FLOATING_FLAG);
1572     }
1573 }
1574
1575 gboolean
1576 g_object_is_floating (gpointer _object)
1577 {
1578   GObject *object = _object;
1579   g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
1580   return floating_flag_handler (object, 0);
1581 }
1582
1583 gpointer
1584 g_object_ref_sink (gpointer _object)
1585 {
1586   GObject *object = _object;
1587   gboolean was_floating;
1588   g_return_val_if_fail (G_IS_OBJECT (object), object);
1589   g_return_val_if_fail (object->ref_count >= 1, object);
1590   g_object_ref (object);
1591   was_floating = floating_flag_handler (object, -1);
1592   if (was_floating)
1593     g_object_unref (object);
1594   return object;
1595 }
1596
1597 void
1598 g_object_force_floating (GObject *object)
1599 {
1600   gboolean was_floating;
1601   g_return_if_fail (G_IS_OBJECT (object));
1602   g_return_if_fail (object->ref_count >= 1);
1603
1604   was_floating = floating_flag_handler (object, +1);
1605 }
1606
1607 typedef struct {
1608   GObject *object;
1609   guint n_toggle_refs;
1610   struct {
1611     GToggleNotify notify;
1612     gpointer    data;
1613   } toggle_refs[1];  /* flexible array */
1614 } ToggleRefStack;
1615
1616 static void
1617 toggle_refs_notify (GObject *object,
1618                     gboolean is_last_ref)
1619 {
1620   ToggleRefStack *tstack = g_datalist_id_get_data (&object->qdata, quark_toggle_refs);
1621
1622   /* Reentrancy here is not as tricky as it seems, because a toggle reference
1623    * will only be notified when there is exactly one of them.
1624    */
1625   g_assert (tstack->n_toggle_refs == 1);
1626   tstack->toggle_refs[0].notify (tstack->toggle_refs[0].data, tstack->object, is_last_ref);
1627 }
1628
1629 void
1630 g_object_add_toggle_ref (GObject       *object,
1631                          GToggleNotify  notify,
1632                          gpointer       data)
1633 {
1634   ToggleRefStack *tstack;
1635   guint i;
1636   
1637   g_return_if_fail (G_IS_OBJECT (object));
1638   g_return_if_fail (notify != NULL);
1639   g_return_if_fail (object->ref_count >= 1);
1640
1641   g_object_ref (object);
1642
1643   tstack = g_datalist_id_remove_no_notify (&object->qdata, quark_toggle_refs);
1644   if (tstack)
1645     {
1646       i = tstack->n_toggle_refs++;
1647       /* allocate i = tstate->n_toggle_refs - 1 positions beyond the 1 declared
1648        * in tstate->toggle_refs */
1649       tstack = g_realloc (tstack, sizeof (*tstack) + sizeof (tstack->toggle_refs[0]) * i);
1650     }
1651   else
1652     {
1653       tstack = g_renew (ToggleRefStack, NULL, 1);
1654       tstack->object = object;
1655       tstack->n_toggle_refs = 1;
1656       i = 0;
1657     }
1658
1659   /* Set a flag for fast lookup after adding the first toggle reference */
1660   if (tstack->n_toggle_refs == 1)
1661     g_datalist_set_flags (&object->qdata, OBJECT_HAS_TOGGLE_REF_FLAG);
1662   
1663   tstack->toggle_refs[i].notify = notify;
1664   tstack->toggle_refs[i].data = data;
1665   g_datalist_id_set_data_full (&object->qdata, quark_toggle_refs, tstack,
1666                                (GDestroyNotify)g_free);
1667 }
1668  
1669 void
1670 g_object_remove_toggle_ref (GObject       *object,
1671                             GToggleNotify  notify,
1672                             gpointer       data)
1673 {
1674   ToggleRefStack *tstack;
1675   gboolean found_one = FALSE;
1676
1677   g_return_if_fail (G_IS_OBJECT (object));
1678   g_return_if_fail (notify != NULL);
1679
1680   tstack = g_datalist_id_get_data (&object->qdata, quark_toggle_refs);
1681   if (tstack)
1682     {
1683       guint i;
1684
1685       for (i = 0; i < tstack->n_toggle_refs; i++)
1686         if (tstack->toggle_refs[i].notify == notify &&
1687             tstack->toggle_refs[i].data == data)
1688           {
1689             found_one = TRUE;
1690             tstack->n_toggle_refs -= 1;
1691             if (i != tstack->n_toggle_refs)
1692               tstack->toggle_refs[i] = tstack->toggle_refs[tstack->n_toggle_refs];
1693
1694             if (tstack->n_toggle_refs == 0)
1695               g_datalist_unset_flags (&object->qdata, OBJECT_HAS_TOGGLE_REF_FLAG);
1696
1697             g_object_unref (object);
1698             
1699             break;
1700           }
1701     }
1702   
1703   if (!found_one)
1704     g_warning ("%s: couldn't find toggle ref %p(%p)", G_STRFUNC, notify, data);
1705 }
1706
1707 gpointer
1708 g_object_ref (gpointer _object)
1709 {
1710   GObject *object = _object;
1711   gint old_val;
1712
1713   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1714   g_return_val_if_fail (object->ref_count > 0, NULL);
1715   
1716 #ifdef  G_ENABLE_DEBUG
1717   if (g_trap_object_ref == object)
1718     G_BREAKPOINT ();
1719 #endif  /* G_ENABLE_DEBUG */
1720
1721
1722   old_val = g_atomic_int_exchange_and_add (&object->ref_count, 1);
1723
1724   if (old_val == 1 && OBJECT_HAS_TOGGLE_REF (object))
1725     toggle_refs_notify (object, FALSE);
1726   
1727   return object;
1728 }
1729
1730 void
1731 g_object_unref (gpointer _object)
1732 {
1733   GObject *object = _object;
1734   gint old_ref;
1735   gboolean is_zero;
1736   
1737   g_return_if_fail (G_IS_OBJECT (object));
1738   g_return_if_fail (object->ref_count > 0);
1739   
1740 #ifdef  G_ENABLE_DEBUG
1741   if (g_trap_object_ref == object)
1742     G_BREAKPOINT ();
1743 #endif  /* G_ENABLE_DEBUG */
1744
1745   /* here we want to atomically do: if (ref_count>1) { ref_count--; return; } */
1746  retry_atomic_decrement1:
1747   old_ref = g_atomic_int_get (&object->ref_count);
1748   if (old_ref > 1)
1749     {
1750       if (!g_atomic_int_compare_and_exchange (&object->ref_count, old_ref, old_ref - 1))
1751         goto retry_atomic_decrement1;
1752
1753       /* if we went from 2->1 we need to notify toggle refs if any */
1754       if (old_ref == 2 && OBJECT_HAS_TOGGLE_REF (object))
1755         toggle_refs_notify (object, TRUE);
1756     }
1757   else
1758     {
1759       /* we are about tp remove the last reference */
1760       G_OBJECT_GET_CLASS (object)->dispose (object);
1761
1762       /* may have been re-referenced meanwhile */
1763     retry_atomic_decrement2:
1764       old_ref = g_atomic_int_get (&object->ref_count);
1765       if (old_ref > 1)
1766         {
1767           if (!g_atomic_int_compare_and_exchange (&object->ref_count, old_ref, old_ref - 1))
1768             goto retry_atomic_decrement2;
1769
1770           /* if we went from 2->1 we need to notify toggle refs if any */
1771           if (old_ref == 2 && OBJECT_HAS_TOGGLE_REF (object))
1772             toggle_refs_notify (object, TRUE);
1773           
1774           return;
1775         }
1776       
1777       /* we are still in the process of taking away the last ref */
1778       g_datalist_id_set_data (&object->qdata, quark_closure_array, NULL);
1779       g_signal_handlers_destroy (object);
1780       g_datalist_id_set_data (&object->qdata, quark_weak_refs, NULL);
1781       
1782       /* decrement the last reference */
1783       is_zero = g_atomic_int_dec_and_test (&object->ref_count);
1784       
1785       /* may have been re-referenced meanwhile */
1786       if (G_LIKELY (is_zero)) 
1787         {
1788           G_OBJECT_GET_CLASS (object)->finalize (object);
1789 #ifdef  G_ENABLE_DEBUG
1790           IF_DEBUG (OBJECTS)
1791             {
1792               /* catch objects not chaining finalize handlers */
1793               G_LOCK (debug_objects);
1794               g_assert (g_hash_table_lookup (debug_objects_ht, object) == NULL);
1795               G_UNLOCK (debug_objects);
1796             }
1797 #endif  /* G_ENABLE_DEBUG */
1798           g_type_free_instance ((GTypeInstance*) object);
1799         }
1800     }
1801 }
1802
1803 gpointer
1804 g_object_get_qdata (GObject *object,
1805                     GQuark   quark)
1806 {
1807   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1808   
1809   return quark ? g_datalist_id_get_data (&object->qdata, quark) : NULL;
1810 }
1811
1812 void
1813 g_object_set_qdata (GObject *object,
1814                     GQuark   quark,
1815                     gpointer data)
1816 {
1817   g_return_if_fail (G_IS_OBJECT (object));
1818   g_return_if_fail (quark > 0);
1819   
1820   g_datalist_id_set_data (&object->qdata, quark, data);
1821 }
1822
1823 void
1824 g_object_set_qdata_full (GObject       *object,
1825                          GQuark         quark,
1826                          gpointer       data,
1827                          GDestroyNotify destroy)
1828 {
1829   g_return_if_fail (G_IS_OBJECT (object));
1830   g_return_if_fail (quark > 0);
1831   
1832   g_datalist_id_set_data_full (&object->qdata, quark, data,
1833                                data ? destroy : (GDestroyNotify) NULL);
1834 }
1835
1836 gpointer
1837 g_object_steal_qdata (GObject *object,
1838                       GQuark   quark)
1839 {
1840   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1841   g_return_val_if_fail (quark > 0, NULL);
1842   
1843   return g_datalist_id_remove_no_notify (&object->qdata, quark);
1844 }
1845
1846 gpointer
1847 g_object_get_data (GObject     *object,
1848                    const gchar *key)
1849 {
1850   GQuark quark;
1851
1852   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1853   g_return_val_if_fail (key != NULL, NULL);
1854
1855   quark = g_quark_try_string (key);
1856
1857   return quark ? g_datalist_id_get_data (&object->qdata, quark) : NULL;
1858 }
1859
1860 void
1861 g_object_set_data (GObject     *object,
1862                    const gchar *key,
1863                    gpointer     data)
1864 {
1865   g_return_if_fail (G_IS_OBJECT (object));
1866   g_return_if_fail (key != NULL);
1867
1868   g_datalist_id_set_data (&object->qdata, g_quark_from_string (key), data);
1869 }
1870
1871 void
1872 g_object_set_data_full (GObject       *object,
1873                         const gchar   *key,
1874                         gpointer       data,
1875                         GDestroyNotify destroy)
1876 {
1877   g_return_if_fail (G_IS_OBJECT (object));
1878   g_return_if_fail (key != NULL);
1879
1880   g_datalist_id_set_data_full (&object->qdata, g_quark_from_string (key), data,
1881                                data ? destroy : (GDestroyNotify) NULL);
1882 }
1883
1884 gpointer
1885 g_object_steal_data (GObject     *object,
1886                      const gchar *key)
1887 {
1888   GQuark quark;
1889
1890   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1891   g_return_val_if_fail (key != NULL, NULL);
1892
1893   quark = g_quark_try_string (key);
1894
1895   return quark ? g_datalist_id_remove_no_notify (&object->qdata, quark) : NULL;
1896 }
1897
1898 static void
1899 g_value_object_init (GValue *value)
1900 {
1901   value->data[0].v_pointer = NULL;
1902 }
1903
1904 static void
1905 g_value_object_free_value (GValue *value)
1906 {
1907   if (value->data[0].v_pointer)
1908     g_object_unref (value->data[0].v_pointer);
1909 }
1910
1911 static void
1912 g_value_object_copy_value (const GValue *src_value,
1913                            GValue       *dest_value)
1914 {
1915   if (src_value->data[0].v_pointer)
1916     dest_value->data[0].v_pointer = g_object_ref (src_value->data[0].v_pointer);
1917   else
1918     dest_value->data[0].v_pointer = NULL;
1919 }
1920
1921 static void
1922 g_value_object_transform_value (const GValue *src_value,
1923                                 GValue       *dest_value)
1924 {
1925   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)))
1926     dest_value->data[0].v_pointer = g_object_ref (src_value->data[0].v_pointer);
1927   else
1928     dest_value->data[0].v_pointer = NULL;
1929 }
1930
1931 static gpointer
1932 g_value_object_peek_pointer (const GValue *value)
1933 {
1934   return value->data[0].v_pointer;
1935 }
1936
1937 static gchar*
1938 g_value_object_collect_value (GValue      *value,
1939                               guint        n_collect_values,
1940                               GTypeCValue *collect_values,
1941                               guint        collect_flags)
1942 {
1943   if (collect_values[0].v_pointer)
1944     {
1945       GObject *object = collect_values[0].v_pointer;
1946       
1947       if (object->g_type_instance.g_class == NULL)
1948         return g_strconcat ("invalid unclassed object pointer for value type `",
1949                             G_VALUE_TYPE_NAME (value),
1950                             "'",
1951                             NULL);
1952       else if (!g_value_type_compatible (G_OBJECT_TYPE (object), G_VALUE_TYPE (value)))
1953         return g_strconcat ("invalid object type `",
1954                             G_OBJECT_TYPE_NAME (object),
1955                             "' for value type `",
1956                             G_VALUE_TYPE_NAME (value),
1957                             "'",
1958                             NULL);
1959       /* never honour G_VALUE_NOCOPY_CONTENTS for ref-counted types */
1960       value->data[0].v_pointer = g_object_ref (object);
1961     }
1962   else
1963     value->data[0].v_pointer = NULL;
1964   
1965   return NULL;
1966 }
1967
1968 static gchar*
1969 g_value_object_lcopy_value (const GValue *value,
1970                             guint        n_collect_values,
1971                             GTypeCValue *collect_values,
1972                             guint        collect_flags)
1973 {
1974   GObject **object_p = collect_values[0].v_pointer;
1975   
1976   if (!object_p)
1977     return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
1978
1979   if (!value->data[0].v_pointer)
1980     *object_p = NULL;
1981   else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
1982     *object_p = value->data[0].v_pointer;
1983   else
1984     *object_p = g_object_ref (value->data[0].v_pointer);
1985   
1986   return NULL;
1987 }
1988
1989 void
1990 g_value_set_object (GValue   *value,
1991                     gpointer  v_object)
1992 {
1993   GObject *old;
1994         
1995   g_return_if_fail (G_VALUE_HOLDS_OBJECT (value));
1996
1997   old = value->data[0].v_pointer;
1998   
1999   if (v_object)
2000     {
2001       g_return_if_fail (G_IS_OBJECT (v_object));
2002       g_return_if_fail (g_value_type_compatible (G_OBJECT_TYPE (v_object), G_VALUE_TYPE (value)));
2003
2004       value->data[0].v_pointer = v_object;
2005       g_object_ref (value->data[0].v_pointer);
2006     }
2007   else
2008     value->data[0].v_pointer = NULL;
2009   
2010   if (old)
2011     g_object_unref (old);
2012 }
2013
2014 void
2015 g_value_set_object_take_ownership (GValue  *value,
2016                                    gpointer v_object)
2017 {
2018   g_value_take_object (value, v_object);
2019 }
2020
2021 void
2022 g_value_take_object (GValue  *value,
2023                      gpointer v_object)
2024 {
2025   g_return_if_fail (G_VALUE_HOLDS_OBJECT (value));
2026
2027   if (value->data[0].v_pointer)
2028     {
2029       g_object_unref (value->data[0].v_pointer);
2030       value->data[0].v_pointer = NULL;
2031     }
2032
2033   if (v_object)
2034     {
2035       g_return_if_fail (G_IS_OBJECT (v_object));
2036       g_return_if_fail (g_value_type_compatible (G_OBJECT_TYPE (v_object), G_VALUE_TYPE (value)));
2037
2038       value->data[0].v_pointer = v_object; /* we take over the reference count */
2039     }
2040 }
2041
2042 gpointer
2043 g_value_get_object (const GValue *value)
2044 {
2045   g_return_val_if_fail (G_VALUE_HOLDS_OBJECT (value), NULL);
2046   
2047   return value->data[0].v_pointer;
2048 }
2049
2050 gpointer
2051 g_value_dup_object (const GValue *value)
2052 {
2053   g_return_val_if_fail (G_VALUE_HOLDS_OBJECT (value), NULL);
2054   
2055   return value->data[0].v_pointer ? g_object_ref (value->data[0].v_pointer) : NULL;
2056 }
2057
2058 gulong
2059 g_signal_connect_object (gpointer      instance,
2060                          const gchar  *detailed_signal,
2061                          GCallback     c_handler,
2062                          gpointer      gobject,
2063                          GConnectFlags connect_flags)
2064 {
2065   g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
2066   g_return_val_if_fail (detailed_signal != NULL, 0);
2067   g_return_val_if_fail (c_handler != NULL, 0);
2068
2069   if (gobject)
2070     {
2071       GClosure *closure;
2072
2073       g_return_val_if_fail (G_IS_OBJECT (gobject), 0);
2074
2075       closure = ((connect_flags & G_CONNECT_SWAPPED) ? g_cclosure_new_object_swap : g_cclosure_new_object) (c_handler, gobject);
2076
2077       return g_signal_connect_closure (instance, detailed_signal, closure, connect_flags & G_CONNECT_AFTER);
2078     }
2079   else
2080     return g_signal_connect_data (instance, detailed_signal, c_handler, NULL, NULL, connect_flags);
2081 }
2082
2083 typedef struct {
2084   GObject  *object;
2085   guint     n_closures;
2086   GClosure *closures[1]; /* flexible array */
2087 } CArray;
2088 /* don't change this structure without supplying an accessor for
2089  * watched closures, e.g.:
2090  * GSList* g_object_list_watched_closures (GObject *object)
2091  * {
2092  *   CArray *carray;
2093  *   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
2094  *   carray = g_object_get_data (object, "GObject-closure-array");
2095  *   if (carray)
2096  *     {
2097  *       GSList *slist = NULL;
2098  *       guint i;
2099  *       for (i = 0; i < carray->n_closures; i++)
2100  *         slist = g_slist_prepend (slist, carray->closures[i]);
2101  *       return slist;
2102  *     }
2103  *   return NULL;
2104  * }
2105  */
2106
2107 static void
2108 object_remove_closure (gpointer  data,
2109                        GClosure *closure)
2110 {
2111   GObject *object = data;
2112   CArray *carray = g_object_get_qdata (object, quark_closure_array);
2113   guint i;
2114   
2115   for (i = 0; i < carray->n_closures; i++)
2116     if (carray->closures[i] == closure)
2117       {
2118         carray->n_closures--;
2119         if (i < carray->n_closures)
2120           carray->closures[i] = carray->closures[carray->n_closures];
2121         return;
2122       }
2123   g_assert_not_reached ();
2124 }
2125
2126 static void
2127 destroy_closure_array (gpointer data)
2128 {
2129   CArray *carray = data;
2130   GObject *object = carray->object;
2131   guint i, n = carray->n_closures;
2132   
2133   for (i = 0; i < n; i++)
2134     {
2135       GClosure *closure = carray->closures[i];
2136       
2137       /* removing object_remove_closure() upfront is probably faster than
2138        * letting it fiddle with quark_closure_array which is empty anyways
2139        */
2140       g_closure_remove_invalidate_notifier (closure, object, object_remove_closure);
2141       g_closure_invalidate (closure);
2142     }
2143   g_free (carray);
2144 }
2145
2146 void
2147 g_object_watch_closure (GObject  *object,
2148                         GClosure *closure)
2149 {
2150   CArray *carray;
2151   guint i;
2152   
2153   g_return_if_fail (G_IS_OBJECT (object));
2154   g_return_if_fail (closure != NULL);
2155   g_return_if_fail (closure->is_invalid == FALSE);
2156   g_return_if_fail (closure->in_marshal == FALSE);
2157   g_return_if_fail (object->ref_count > 0);     /* this doesn't work on finalizing objects */
2158   
2159   g_closure_add_invalidate_notifier (closure, object, object_remove_closure);
2160   g_closure_add_marshal_guards (closure,
2161                                 object, (GClosureNotify) g_object_ref,
2162                                 object, (GClosureNotify) g_object_unref);
2163   carray = g_datalist_id_remove_no_notify (&object->qdata, quark_closure_array);
2164   if (!carray)
2165     {
2166       carray = g_renew (CArray, NULL, 1);
2167       carray->object = object;
2168       carray->n_closures = 1;
2169       i = 0;
2170     }
2171   else
2172     {
2173       i = carray->n_closures++;
2174       carray = g_realloc (carray, sizeof (*carray) + sizeof (carray->closures[0]) * i);
2175     }
2176   carray->closures[i] = closure;
2177   g_datalist_id_set_data_full (&object->qdata, quark_closure_array, carray, destroy_closure_array);
2178 }
2179
2180 GClosure*
2181 g_closure_new_object (guint    sizeof_closure,
2182                       GObject *object)
2183 {
2184   GClosure *closure;
2185
2186   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
2187   g_return_val_if_fail (object->ref_count > 0, NULL);     /* this doesn't work on finalizing objects */
2188
2189   closure = g_closure_new_simple (sizeof_closure, object);
2190   g_object_watch_closure (object, closure);
2191
2192   return closure;
2193 }
2194
2195 GClosure*
2196 g_cclosure_new_object (GCallback callback_func,
2197                        GObject  *object)
2198 {
2199   GClosure *closure;
2200
2201   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
2202   g_return_val_if_fail (object->ref_count > 0, NULL);     /* this doesn't work on finalizing objects */
2203   g_return_val_if_fail (callback_func != NULL, NULL);
2204
2205   closure = g_cclosure_new (callback_func, object, NULL);
2206   g_object_watch_closure (object, closure);
2207
2208   return closure;
2209 }
2210
2211 GClosure*
2212 g_cclosure_new_object_swap (GCallback callback_func,
2213                             GObject  *object)
2214 {
2215   GClosure *closure;
2216
2217   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
2218   g_return_val_if_fail (object->ref_count > 0, NULL);     /* this doesn't work on finalizing objects */
2219   g_return_val_if_fail (callback_func != NULL, NULL);
2220
2221   closure = g_cclosure_new_swap (callback_func, object, NULL);
2222   g_object_watch_closure (object, closure);
2223
2224   return closure;
2225 }
2226
2227 gsize
2228 g_object_compat_control (gsize           what,
2229                          gpointer        data)
2230 {
2231   switch (what)
2232     {
2233       gpointer *pp;
2234     case 1:     /* floating base type */
2235       return G_TYPE_INITIALLY_UNOWNED;
2236     case 2:     /* FIXME: remove this once GLib/Gtk+ break ABI again */
2237       floating_flag_handler = (guint(*)(GObject*,gint)) data;
2238       return 1;
2239     case 3:     /* FIXME: remove this once GLib/Gtk+ break ABI again */
2240       pp = data;
2241       *pp = floating_flag_handler;
2242       return 1;
2243     default:
2244       return 0;
2245     }
2246 }
2247
2248 G_DEFINE_TYPE (GInitiallyUnowned, g_initially_unowned, G_TYPE_OBJECT);
2249
2250 static void
2251 g_initially_unowned_init (GInitiallyUnowned *object)
2252 {
2253   g_object_force_floating (object);
2254 }
2255
2256 static void
2257 g_initially_unowned_class_init (GInitiallyUnownedClass *klass)
2258 {
2259 }
2260
2261 #define __G_OBJECT_C__
2262 #include "gobjectaliasdef.c"