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