ri Oct 27 05:35:14 2000 Tim Janik <timj@gtk.org>
[platform/upstream/glib.git] / gobject / gobject.c
1 /* GObject - GLib Type, Object, Parameter and Signal Library
2  * Copyright (C) 1998, 1999, 2000 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
20 #include <string.h>
21
22 #include "gobject.h"
23 #include "gvaluecollector.h"
24
25
26 #define DEBUG_OBJECTS
27
28
29 /* --- macros --- */
30 #define PARAM_SPEC_PARAM_ID(pspec)      (GPOINTER_TO_UINT (g_param_spec_get_qdata ((pspec), quark_param_id)))
31
32
33 /* --- prototypes --- */
34 static void     g_object_base_class_init                (GObjectClass   *class);
35 static void     g_object_base_class_finalize            (GObjectClass   *class);
36 static void     g_object_do_class_init                  (GObjectClass   *class);
37 static void     g_object_do_init                        (GObject        *object);
38 static void     g_object_do_queue_param_changed         (GObject        *object,
39                                                          GParamSpec     *pspec);
40 static void     g_object_do_dispatch_param_changed      (GObject        *object,
41                                                          GParamSpec     *pspec);
42 static void     g_object_last_unref                     (GObject        *object);
43 static void     g_object_do_shutdown                    (GObject        *object);
44 static void     g_object_do_finalize                    (GObject        *object);
45 static void     g_value_object_init                     (GValue         *value);
46 static void     g_value_object_free_value               (GValue         *value);
47 static void     g_value_object_copy_value               (const GValue   *src_value,
48                                                          GValue         *dest_value);
49 static gpointer g_value_object_peek_pointer             (const GValue   *value);
50 static gchar*   g_value_object_collect_value            (GValue         *value,
51                                                          guint           nth_value,
52                                                          GType          *collect_type,
53                                                          GTypeCValue    *collect_value);
54 static gchar*   g_value_object_lcopy_value              (const GValue   *value,
55                                                          guint           nth_value,
56                                                          GType          *collect_type,
57                                                          GTypeCValue    *collect_value);
58
59
60 /* --- variables --- */
61 static GQuark            quark_param_id = 0;
62 static GQuark            quark_param_changed_queue = 0;
63 static GQuark            quark_closure_array = 0;
64 static GHashTable       *param_spec_hash_table = NULL;
65
66
67 /* --- functions --- */
68 #ifdef  DEBUG_OBJECTS
69
70 /* We need an actual method for handling debug keys in GLib.
71  * For now, we'll simply use, as a method
72  * 'extern gboolean glib_debug_objects'
73  */
74 gboolean glib_debug_objects = FALSE;
75
76 static guint              debug_objects_count = 0;
77 static GHashTable        *debug_objects_ht = NULL;
78 static void
79 debug_objects_foreach (gpointer key,
80                        gpointer value,
81                        gpointer user_data)
82 {
83   GObject *object = value;
84   
85   g_message ("[%p] stale %s\tref_count=%u",
86              object,
87              G_OBJECT_TYPE_NAME (object),
88              object->ref_count);
89 }
90 static void
91 debug_objects_atexit (void)
92 {
93   if (glib_debug_objects)
94     {
95       if (debug_objects_ht)
96         {
97           g_message ("stale GObjects: %u", debug_objects_count);
98           g_hash_table_foreach (debug_objects_ht, debug_objects_foreach, NULL);
99         }
100     }
101 }
102 #endif /* DEBUG_OBJECTS */
103
104 void
105 g_object_type_init (void)       /* sync with gtype.c */
106 {
107   static gboolean initialized = FALSE;
108   static const GTypeFundamentalInfo finfo = {
109     G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE,
110   };
111   static GTypeInfo info = {
112     sizeof (GObjectClass),
113     (GBaseInitFunc) g_object_base_class_init,
114     (GBaseFinalizeFunc) g_object_base_class_finalize,
115     (GClassInitFunc) g_object_do_class_init,
116     NULL        /* class_destroy */,
117     NULL        /* class_data */,
118     sizeof (GObject),
119     0           /* n_preallocs */,
120     (GInstanceInitFunc) g_object_do_init,
121     NULL,       /* value_table */
122   };
123   static const GTypeValueTable value_table = {
124     g_value_object_init,          /* value_init */
125     g_value_object_free_value,    /* value_free */
126     g_value_object_copy_value,    /* value_copy */
127     g_value_object_peek_pointer,  /* value_peek_pointer */
128     G_VALUE_COLLECT_POINTER,      /* collect_type */
129     g_value_object_collect_value, /* collect_value */
130     G_VALUE_COLLECT_POINTER,      /* lcopy_type */
131     g_value_object_lcopy_value,   /* lcopy_value */
132   };
133   GType type;
134   
135   g_return_if_fail (initialized == FALSE);
136   initialized = TRUE;
137   
138   /* G_TYPE_OBJECT
139    */
140   info.value_table = &value_table;
141   type = g_type_register_fundamental (G_TYPE_OBJECT, "GObject", &info, &finfo, 0);
142   g_assert (type == G_TYPE_OBJECT);
143   
144 #ifdef  DEBUG_OBJECTS
145   g_atexit (debug_objects_atexit);
146 #endif /* DEBUG_OBJECTS */
147 }
148
149 static void
150 g_object_base_class_init (GObjectClass *class)
151 {
152   /* reset instance specific fields and methods that don't get inherited */
153   class->n_param_specs = 0;
154   class->param_specs = NULL;
155   class->get_param = NULL;
156   class->set_param = NULL;
157 }
158
159 static void
160 g_object_base_class_finalize (GObjectClass *class)
161 {
162   guint i;
163   
164   g_message ("finallizing base class of %s", G_OBJECT_CLASS_NAME (class));
165   
166   for (i = 0; i < class->n_param_specs; i++)
167     {
168       GParamSpec *pspec = class->param_specs[i];
169       
170       g_param_spec_hash_table_remove (param_spec_hash_table, pspec);
171       g_param_spec_set_qdata (pspec, quark_param_id, NULL);
172       g_param_spec_unref (pspec);
173     }
174   class->n_param_specs = 0;
175   g_free (class->param_specs);
176   class->param_specs = NULL;
177 }
178
179 static void
180 g_object_do_class_init (GObjectClass *class)
181 {
182   quark_param_id = g_quark_from_static_string ("glib-object-param-id");
183   quark_param_changed_queue = g_quark_from_static_string ("glib-object-param-changed-queue");
184   quark_closure_array = g_quark_from_static_string ("GObject-closure-array");
185   param_spec_hash_table = g_param_spec_hash_table_new ();
186   
187   class->queue_param_changed = g_object_do_queue_param_changed;
188   class->dispatch_param_changed = g_object_do_dispatch_param_changed;
189   class->shutdown = g_object_do_shutdown;
190   class->finalize = g_object_do_finalize;
191 }
192
193 void
194 g_object_class_install_param (GObjectClass *class,
195                               guint         param_id,
196                               GParamSpec   *pspec /* 1 ref_count taken over */)
197 {
198   guint i;
199   
200   g_return_if_fail (G_IS_OBJECT_CLASS (class));
201   g_return_if_fail (G_IS_PARAM_SPEC (pspec));
202   if (pspec->flags & G_PARAM_WRITABLE)
203     g_return_if_fail (class->set_param != NULL);
204   if (pspec->flags & G_PARAM_READABLE)
205     g_return_if_fail (class->get_param != NULL);
206   g_return_if_fail (param_id > 0);
207   g_return_if_fail (PARAM_SPEC_PARAM_ID (pspec) == 0);  /* paranoid */
208   
209   /* expensive paranoia checks ;( */
210   for (i = 0; i < class->n_param_specs; i++)
211     if (PARAM_SPEC_PARAM_ID (class->param_specs[i]) == param_id)
212       {
213         g_warning (G_STRLOC ": class `%s' already contains a parameter `%s' with id %u, "
214                    "cannot install parameter `%s'",
215                    G_OBJECT_CLASS_NAME (class),
216                    class->param_specs[i]->name,
217                    param_id,
218                    pspec->name);
219         return;
220       }
221   if (g_object_class_find_param_spec (class, pspec->name))
222     {
223       g_warning (G_STRLOC ": class `%s' already contains a parameter named `%s'",
224                  G_OBJECT_CLASS_NAME (class),
225                  pspec->name);
226       return;
227     }
228   
229   g_param_spec_set_qdata (pspec, quark_param_id, GUINT_TO_POINTER (param_id));
230   g_param_spec_hash_table_insert (param_spec_hash_table, pspec, G_OBJECT_CLASS_TYPE (class));
231   i = class->n_param_specs++;
232   class->param_specs = g_renew (GParamSpec*, class->param_specs, class->n_param_specs);
233   class->param_specs[i] = pspec;
234 }
235
236 GParamSpec*
237 g_object_class_find_param_spec (GObjectClass *class,
238                                 const gchar  *param_name)
239 {
240   g_return_val_if_fail (G_IS_OBJECT_CLASS (class), NULL);
241   g_return_val_if_fail (param_name != NULL, NULL);
242   
243   return g_param_spec_hash_table_lookup (param_spec_hash_table,
244                                          param_name,
245                                          G_OBJECT_CLASS_TYPE (class),
246                                          TRUE, NULL);
247 }
248
249 static void
250 g_object_do_init (GObject *object)
251 {
252   object->ref_count = 1;
253   object->qdata = NULL;
254   
255 #ifdef  DEBUG_OBJECTS
256   if (glib_debug_objects)
257     {
258       if (!debug_objects_ht)
259         debug_objects_ht = g_hash_table_new (g_direct_hash, NULL);
260       debug_objects_count++;
261       g_hash_table_insert (debug_objects_ht, object, object);
262     }
263 #endif /* DEBUG_OBJECTS */
264 }
265
266 static void
267 g_object_last_unref (GObject *object)
268 {
269   g_return_if_fail (object->ref_count > 0);
270   
271   if (object->ref_count == 1)   /* may have been re-referenced meanwhile */
272     G_OBJECT_GET_CLASS (object)->shutdown (object);
273   
274   object->ref_count -= 1;
275   
276   if (object->ref_count == 0)   /* may have been re-referenced meanwhile */
277     {
278       G_OBJECT_GET_CLASS (object)->finalize (object);
279       g_type_free_instance ((GTypeInstance*) object);
280     }
281 }
282
283 static void
284 g_object_do_shutdown (GObject *object)
285 {
286   /* this function needs to be always present for unconditional
287    * chaining, we also might add some code here later.
288    * beware though, subclasses may invoke shutdown() arbitrarily.
289    */
290 }
291
292 static void
293 g_object_do_finalize (GObject *object)
294 {
295   g_datalist_clear (&object->qdata);
296   
297 #ifdef  DEBUG_OBJECTS
298   if (glib_debug_objects)
299     {
300       g_assert (g_hash_table_lookup (debug_objects_ht, object) == object);
301       
302       g_hash_table_remove (debug_objects_ht, object);
303       debug_objects_count--;
304     }
305 #endif /* DEBUG_OBJECTS */
306 }
307
308 gpointer
309 g_object_new (GType        object_type,
310               const gchar *first_param_name,
311               ...)
312 {
313   GObject *object;
314   va_list var_args;
315   
316   g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type), NULL);
317   
318   va_start (var_args, first_param_name);
319   object = g_object_new_valist (object_type, first_param_name, var_args);
320   va_end (var_args);
321   
322   return object;
323 }
324
325 gpointer
326 g_object_new_valist (GType        object_type,
327                      const gchar *first_param_name,
328                      va_list      var_args)
329 {
330   GObject *object;
331   
332   g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type), NULL);
333   
334   object = (GObject*) g_type_create_instance (object_type);
335   if (first_param_name)
336     g_object_set_valist (object, first_param_name, var_args);
337   
338   return object;
339 }
340
341 static void
342 g_object_do_dispatch_param_changed (GObject    *object,
343                                     GParamSpec *pspec)
344 {
345 /*  g_message ("NOTIFICATION: parameter `%s' changed on object `%s'",
346              pspec->name,
347              G_OBJECT_TYPE_NAME (object));*/
348 }
349
350 static gboolean
351 notify_param_changed_handler (gpointer data)
352 {
353   GObject *object;
354   GObjectClass *class;
355   GSList *slist;
356   
357   /* FIXME: need GDK_THREADS lock */
358   
359   object = G_OBJECT (data);
360   class = G_OBJECT_GET_CLASS (object);
361   slist = g_datalist_id_get_data (&object->qdata, quark_param_changed_queue);
362   
363   /* a reference count is still being held */
364   
365   for (; slist; slist = slist->next)
366     if (slist->data)
367       {
368         GParamSpec *pspec = slist->data;
369         
370         slist->data = NULL;
371         class->dispatch_param_changed (object, pspec);
372       }
373   
374   g_datalist_id_set_data (&object->qdata, quark_param_changed_queue, NULL);
375   
376   return FALSE;
377 }
378
379 static void
380 g_object_do_queue_param_changed (GObject    *object,
381                                  GParamSpec *pspec)
382 {
383   GSList *slist, *last = NULL;
384   
385   /* if this is a recursive call on this object (i.e. pspecs are queued
386    * for notification, while param_changed notification is currently in
387    * progress), we simply add them to the queue that is currently being
388    * dispatched. otherwise, we later dispatch parameter changed notification
389    * asyncronously from an idle handler untill the queue is completely empty.
390    */
391   
392   slist = g_datalist_id_get_data (&object->qdata, quark_param_changed_queue);
393   for (; slist; last = slist, slist = last->next)
394     if (slist->data == pspec)
395       return;
396   
397   if (!last)
398     {
399       g_object_ref (object);
400       g_idle_add_full (G_NOTIFY_PRIORITY,
401                        notify_param_changed_handler,
402                        object,
403                        (GDestroyNotify) g_object_unref);
404       g_object_set_qdata_full (object,
405                                quark_param_changed_queue,
406                                g_slist_prepend (NULL, pspec),
407                                (GDestroyNotify) g_slist_free);
408     }
409   else
410     last->next = g_slist_prepend (NULL, pspec);
411 }
412
413 static inline void
414 object_get_param (GObject     *object,
415                   GValue      *value,
416                   GParamSpec  *pspec,
417                   const gchar *trailer)
418 {
419   GObjectClass *class;
420   
421   g_return_if_fail (g_type_is_a (G_OBJECT_TYPE (object), pspec->owner_type));   /* paranoid */
422   
423   class = g_type_class_peek (pspec->owner_type);
424   
425   class->get_param (object, PARAM_SPEC_PARAM_ID (pspec), value, pspec, trailer);
426 }
427
428 static inline void
429 object_set_param (GObject     *object,
430                   GValue      *value,
431                   GParamSpec  *pspec,
432                   const gchar *trailer)
433 {
434   GObjectClass *class;
435   
436   g_return_if_fail (g_type_is_a (G_OBJECT_TYPE (object), pspec->owner_type));   /* paranoid */
437   
438   class = g_type_class_peek (pspec->owner_type);
439   
440   class->set_param (object, PARAM_SPEC_PARAM_ID (pspec), value, pspec, trailer);
441   
442   class->queue_param_changed (object, pspec);
443 }
444
445 void
446 g_object_set_valist (GObject     *object,
447                      const gchar *first_param_name,
448                      va_list      var_args)
449 {
450   const gchar *name;
451   
452   g_return_if_fail (G_IS_OBJECT (object));
453   
454   g_object_ref (object);
455   
456   name = first_param_name;
457   
458   while (name)
459     {
460       const gchar *trailer = NULL;
461       GValue value = { 0, };
462       GParamSpec *pspec;
463       gchar *error = NULL;
464       
465       pspec = g_param_spec_hash_table_lookup (param_spec_hash_table,
466                                               name,
467                                               G_OBJECT_TYPE (object),
468                                               TRUE,
469                                               &trailer);
470       if (!pspec)
471         {
472           g_warning ("%s: object class `%s' has no parameter named `%s'",
473                      G_STRLOC,
474                      G_OBJECT_TYPE_NAME (object),
475                      name);
476           break;
477         }
478       if (!(pspec->flags & G_PARAM_WRITABLE))
479         {
480           g_warning ("%s: parameter `%s' of object class `%s' is not writable",
481                      G_STRLOC,
482                      pspec->name,
483                      G_OBJECT_TYPE_NAME (object));
484           break;
485         }
486       
487       g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
488       
489       G_VALUE_COLLECT (&value, var_args, &error);
490       if (error)
491         {
492           g_warning ("%s: %s", G_STRLOC, error);
493           g_free (error);
494           
495           /* we purposely leak the value here, it might not be
496            * in a sane state if an error condition occoured
497            */
498           break;
499         }
500       
501       object_set_param (object, &value, pspec, trailer);
502       
503       g_value_unset (&value);
504       
505       name = va_arg (var_args, gchar*);
506     }
507   
508   g_object_unref (object);
509 }
510
511 void
512 g_object_get_valist (GObject     *object,
513                      const gchar *first_param_name,
514                      va_list      var_args)
515 {
516   const gchar *name;
517   
518   g_return_if_fail (G_IS_OBJECT (object));
519   
520   g_object_ref (object);
521   
522   name = first_param_name;
523   
524   while (name)
525     {
526       const gchar *trailer = NULL;
527       GValue value = { 0, };
528       GParamSpec *pspec;
529       gchar *error = NULL;
530       
531       pspec = g_param_spec_hash_table_lookup (param_spec_hash_table,
532                                               name,
533                                               G_OBJECT_TYPE (object),
534                                               TRUE,
535                                               &trailer);
536       if (!pspec)
537         {
538           g_warning ("%s: object class `%s' has no parameter named `%s'",
539                      G_STRLOC,
540                      G_OBJECT_TYPE_NAME (object),
541                      name);
542           break;
543         }
544       if (!(pspec->flags & G_PARAM_READABLE))
545         {
546           g_warning ("%s: parameter `%s' of object class `%s' is not readable",
547                      G_STRLOC,
548                      pspec->name,
549                      G_OBJECT_TYPE_NAME (object));
550           break;
551         }
552       
553       g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
554       
555       object_get_param (object, &value, pspec, trailer);
556       
557       G_VALUE_LCOPY (&value, var_args, &error);
558       if (error)
559         {
560           g_warning ("%s: %s", G_STRLOC, error);
561           g_free (error);
562           
563           /* we purposely leak the value here, it might not be
564            * in a sane state if an error condition occoured
565            */
566           break;
567         }
568       
569       g_value_unset (&value);
570       
571       name = va_arg (var_args, gchar*);
572     }
573   
574   g_object_unref (object);
575 }
576
577 void
578 g_object_set (GObject     *object,
579               const gchar *first_param_name,
580               ...)
581 {
582   va_list var_args;
583   
584   g_return_if_fail (G_IS_OBJECT (object));
585   
586   va_start (var_args, first_param_name);
587   g_object_set_valist (object, first_param_name, var_args);
588   va_end (var_args);
589 }
590
591 void
592 g_object_get (GObject     *object,
593               const gchar *first_param_name,
594               ...)
595 {
596   va_list var_args;
597   
598   g_return_if_fail (G_IS_OBJECT (object));
599   
600   va_start (var_args, first_param_name);
601   g_object_get_valist (object, first_param_name, var_args);
602   va_end (var_args);
603 }
604
605 void
606 g_object_set_param (GObject      *object,
607                     const gchar  *param_name,
608                     const GValue *value)
609 {
610   GParamSpec *pspec;
611   const gchar *trailer;
612   
613   g_return_if_fail (G_IS_OBJECT (object));
614   g_return_if_fail (param_name != NULL);
615   g_return_if_fail (G_IS_VALUE (value));
616   
617   g_object_ref (object);
618   
619   pspec = g_param_spec_hash_table_lookup (param_spec_hash_table,
620                                           param_name,
621                                           G_OBJECT_TYPE (object),
622                                           TRUE,
623                                           &trailer);
624   if (!pspec)
625     g_warning ("%s: object class `%s' has no parameter named `%s'",
626                G_STRLOC,
627                G_OBJECT_TYPE_NAME (object),
628                param_name);
629   else
630     {
631       GValue tmp_value = { 0, };
632       
633       /* provide a copy to work from and convert if necessary */
634       g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
635       
636       if (!g_value_convert (value, &tmp_value) ||
637           g_param_value_validate (pspec, &tmp_value))
638         g_warning ("%s: cannot convert `%s' value to parameter `%s' value of type `%s'",
639                    G_STRLOC,
640                    G_VALUE_TYPE_NAME (value),
641                    pspec->name,
642                    g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)));
643       else
644         object_set_param (object, &tmp_value, pspec, trailer);
645       
646       g_value_unset (&tmp_value);
647     }
648   
649   g_object_unref (object);
650 }
651
652 void
653 g_object_get_param (GObject     *object,
654                     const gchar *param_name,
655                     GValue      *value)
656 {
657   GParamSpec *pspec;
658   const gchar *trailer;
659   
660   g_return_if_fail (G_IS_OBJECT (object));
661   g_return_if_fail (param_name != NULL);
662   g_return_if_fail (G_IS_VALUE (value));
663   
664   g_object_ref (object);
665   
666   pspec = g_param_spec_hash_table_lookup (param_spec_hash_table,
667                                           param_name,
668                                           G_OBJECT_TYPE (object),
669                                           TRUE,
670                                           &trailer);
671   if (!pspec)
672     g_warning ("%s: object class `%s' has no parameter named `%s'",
673                G_STRLOC,
674                G_OBJECT_TYPE_NAME (object),
675                param_name);
676   else
677     {
678       GValue tmp_value = { 0, };
679       
680       /* provide a copy to work from and later convert if necessary, so
681        * _get_param() implementations need *not* care about freeing values
682        * that might be already set in the parameter to get.
683        * (though, at this point, GValue should exclusively be modified
684        * through the accessor functions anyways)
685        */
686       g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
687       
688       if (!g_value_types_exchangable (G_VALUE_TYPE (value), G_PARAM_SPEC_VALUE_TYPE (pspec)))
689         g_warning ("%s: can't retrive parameter `%s' value of type `%s' as value of type `%s'",
690                    G_STRLOC,
691                    pspec->name,
692                    g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
693                    G_VALUE_TYPE_NAME (value));
694       else
695         {
696           object_get_param (object, &tmp_value, pspec, trailer);
697           g_value_convert (&tmp_value, value);
698           /* g_value_validate (value, pspec); */
699         }
700       
701       g_value_unset (&tmp_value);
702     }
703   
704   g_object_unref (object);
705 }
706
707 void
708 g_object_queue_param_changed (GObject     *object,
709                               const gchar *param_name)
710 {
711   GParamSpec *pspec;
712   
713   g_return_if_fail (G_IS_OBJECT (object));
714   g_return_if_fail (param_name != NULL);
715   
716   pspec = g_param_spec_hash_table_lookup (param_spec_hash_table,
717                                           param_name,
718                                           G_OBJECT_TYPE (object),
719                                           TRUE, NULL);
720   if (!pspec)
721     g_warning ("%s: object class `%s' has no parameter named `%s'",
722                G_STRLOC,
723                G_OBJECT_TYPE_NAME (object),
724                param_name);
725   else
726     G_OBJECT_GET_CLASS (object)->queue_param_changed (object, pspec);
727 }
728
729 GObject*
730 g_object_ref (GObject *object)
731 {
732   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
733   g_return_val_if_fail (object->ref_count > 0, NULL);
734   
735   object->ref_count += 1;
736   
737   return object;
738 }
739
740 void
741 g_object_unref (GObject *object)
742 {
743   g_return_if_fail (G_IS_OBJECT (object));
744   g_return_if_fail (object->ref_count > 0);
745   
746   if (object->ref_count > 1)
747     object->ref_count -= 1;
748   else
749     g_object_last_unref (object);
750 }
751
752 gpointer
753 g_object_get_qdata (GObject *object,
754                     GQuark   quark)
755 {
756   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
757   
758   return quark ? g_datalist_id_get_data (&object->qdata, quark) : NULL;
759 }
760
761 void
762 g_object_set_qdata (GObject *object,
763                     GQuark   quark,
764                     gpointer data)
765 {
766   g_return_if_fail (G_IS_OBJECT (object));
767   g_return_if_fail (quark > 0);
768   
769   g_datalist_id_set_data (&object->qdata, quark, data);
770 }
771
772 void
773 g_object_set_qdata_full (GObject       *object,
774                          GQuark         quark,
775                          gpointer       data,
776                          GDestroyNotify destroy)
777 {
778   g_return_if_fail (G_IS_OBJECT (object));
779   g_return_if_fail (quark > 0);
780   
781   g_datalist_id_set_data_full (&object->qdata, quark, data, data ? destroy : NULL);
782 }
783
784 gpointer
785 g_object_steal_qdata (GObject *object,
786                       GQuark   quark)
787 {
788   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
789   g_return_val_if_fail (quark > 0, NULL);
790   
791   return g_datalist_id_remove_no_notify (&object->qdata, quark);
792 }
793
794 static void
795 g_value_object_init (GValue *value)
796 {
797   value->data[0].v_pointer = NULL;
798 }
799
800 static void
801 g_value_object_free_value (GValue *value)
802 {
803   if (value->data[0].v_pointer)
804     g_object_unref (value->data[0].v_pointer);
805 }
806
807 static void
808 g_value_object_copy_value (const GValue *src_value,
809                            GValue       *dest_value)
810 {
811   if (src_value->data[0].v_pointer)
812     dest_value->data[0].v_pointer = g_object_ref (src_value->data[0].v_pointer);
813   else
814     dest_value->data[0].v_pointer = NULL;
815 }
816
817 static gpointer
818 g_value_object_peek_pointer (const GValue *value)
819 {
820   return value->data[0].v_pointer;
821 }
822
823 static gchar*
824 g_value_object_collect_value (GValue      *value,
825                               guint        nth_value,
826                               GType       *collect_type,
827                               GTypeCValue *collect_value)
828 {
829   if (collect_value->v_pointer)
830     {
831       GObject *object = collect_value->v_pointer;
832       
833       if (object->g_type_instance.g_class == NULL)
834         return g_strconcat ("invalid unclassed object pointer for value type `",
835                             G_VALUE_TYPE_NAME (value),
836                             "'",
837                             NULL);
838       else if (!g_type_is_a (G_OBJECT_TYPE (object), G_VALUE_TYPE (value)))
839         return g_strconcat ("invalid object type `",
840                             G_OBJECT_TYPE_NAME (object),
841                             "' for value type `",
842                             G_VALUE_TYPE_NAME (value),
843                             "'",
844                             NULL);
845       value->data[0].v_pointer = g_object_ref (object);
846     }
847   else
848     value->data[0].v_pointer = NULL;
849   
850   *collect_type = 0;
851   return NULL;
852 }
853
854 static gchar*
855 g_value_object_lcopy_value (const GValue *value,
856                             guint         nth_value,
857                             GType        *collect_type,
858                             GTypeCValue  *collect_value)
859 {
860   GObject **object_p = collect_value->v_pointer;
861   
862   if (!object_p)
863     return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
864   
865   *object_p = value->data[0].v_pointer ? g_object_ref (value->data[0].v_pointer) : NULL;
866   
867   *collect_type = 0;
868   return NULL;
869 }
870
871 void
872 g_value_set_object (GValue  *value,
873                     GObject *v_object)
874 {
875   g_return_if_fail (G_IS_VALUE_OBJECT (value));
876   if (v_object)
877     g_return_if_fail (G_IS_OBJECT (v_object));
878   
879   if (value->data[0].v_pointer)
880     g_object_unref (value->data[0].v_pointer);
881   value->data[0].v_pointer = v_object;
882   if (value->data[0].v_pointer)
883     g_object_ref (value->data[0].v_pointer);
884 }
885
886 GObject*
887 g_value_get_object (const GValue *value)
888 {
889   g_return_val_if_fail (G_IS_VALUE_OBJECT (value), NULL);
890   
891   return value->data[0].v_pointer;
892 }
893
894 GObject*
895 g_value_dup_object (const GValue *value)
896 {
897   g_return_val_if_fail (G_IS_VALUE_OBJECT (value), NULL);
898   
899   return value->data[0].v_pointer ? g_object_ref (value->data[0].v_pointer) : NULL;
900 }
901
902 typedef struct {
903   GObject  *object;
904   guint     n_closures;
905   GClosure *closures[1]; /* flexible array */
906 } CArray;
907
908 static void
909 object_remove_closure (gpointer  data,
910                        GClosure *closure)
911 {
912   GObject *object = data;
913   CArray *carray = g_object_get_qdata (object, quark_closure_array);
914   guint i;
915   
916   for (i = 0; i < carray->n_closures; i++)
917     if (carray->closures[i] == closure)
918       {
919         carray->n_closures--;
920         if (i < carray->n_closures)
921           carray->closures[i] = carray->closures[carray->n_closures];
922         return;
923       }
924   g_assert_not_reached ();
925 }
926
927 static void
928 destroy_closure_array (gpointer data)
929 {
930   CArray *carray = data;
931   GObject *object = carray->object;
932   guint i, n = carray->n_closures;
933   
934   for (i = 0; i < n; i++)
935     {
936       GClosure *closure = carray->closures[i];
937       
938       /* removing object_remove_closure() upfront is probably faster than
939        * letting it fiddle with quark_closure_array which is empty anyways
940        */
941       g_closure_remove_inotify (closure, object, object_remove_closure);
942       g_closure_invalidate (closure);
943     }
944   g_free (carray);
945 }
946
947 void
948 g_object_watch_closure (GObject  *object,
949                         GClosure *closure)
950 {
951   CArray *carray;
952   
953   g_return_if_fail (G_IS_OBJECT (object));
954   g_return_if_fail (closure != NULL);
955   g_return_if_fail (closure->is_invalid == FALSE);
956   g_return_if_fail (closure->in_marshal == FALSE);
957   g_return_if_fail (object->ref_count > 0);     /* this doesn't work on finalizing objects */
958   
959   g_closure_add_inotify (closure, object, object_remove_closure);
960   g_closure_add_marshal_guards (closure,
961                                 object, (GClosureNotify) g_object_ref,
962                                 object, (GClosureNotify) g_object_unref);
963   carray = g_object_steal_qdata (object, quark_closure_array);
964   if (!carray)
965     {
966       carray = g_renew (CArray, NULL, 1);
967       carray->object = object;
968       carray->n_closures = 1;
969       carray->closures[0] = closure;
970       g_object_set_qdata_full (object, quark_closure_array, carray, destroy_closure_array);
971     }
972   else
973     {
974       guint i = carray->n_closures++;
975       
976       carray = g_realloc (carray, sizeof (*carray) + sizeof (carray->closures[0]) * i);
977       carray->closures[i] = closure;
978       g_object_set_qdata_full (object, quark_closure_array, carray, destroy_closure_array);
979     }
980 }
981
982 GClosure*
983 g_closure_new_object (guint    sizeof_closure,
984                       GObject *object)
985 {
986   GClosure *closure;
987
988   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
989   g_return_val_if_fail (object->ref_count > 0, NULL);     /* this doesn't work on finalizing objects */
990
991   closure = g_closure_new_simple (sizeof_closure, object);
992   g_object_watch_closure (object, closure);
993
994   return closure;
995 }
996
997 GClosure*
998 g_cclosure_new_object (gpointer  _object,
999                        GCallback callback_func)
1000 {
1001   GObject *object = _object;
1002   GClosure *closure;
1003
1004   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1005   g_return_val_if_fail (object->ref_count > 0, NULL);     /* this doesn't work on finalizing objects */
1006   g_return_val_if_fail (callback_func != NULL, NULL);
1007
1008   closure = g_cclosure_new (callback_func, object, NULL);
1009   g_object_watch_closure (object, closure);
1010
1011   return closure;
1012 }
1013
1014 GClosure*
1015 g_cclosure_new_object_swap (gpointer  _object,
1016                             GCallback callback_func)
1017 {
1018   GObject *object = _object;
1019   GClosure *closure;
1020
1021   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1022   g_return_val_if_fail (object->ref_count > 0, NULL);     /* this doesn't work on finalizing objects */
1023   g_return_val_if_fail (callback_func != NULL, NULL);
1024
1025   closure = g_cclosure_new_swap (callback_func, object, NULL);
1026   g_object_watch_closure (object, closure);
1027
1028   return closure;
1029 }