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