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