Added function to keep symetry with g_node_insert_before. 2000-09-29
[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     {
274       G_OBJECT_GET_CLASS (object)->finalize (object);
275       g_type_free_instance ((GTypeInstance*) object);
276     }
277 }
278
279 static void
280 g_object_do_shutdown (GObject *object)
281 {
282   /* this function needs to be always present for unconditional
283    * chaining, we also might add some code here later.
284    * beware though, subclasses may invoke shutdown() arbitrarily.
285    */
286 }
287
288 static void
289 g_object_do_finalize (GObject *object)
290 {
291   g_datalist_clear (&object->qdata);
292   
293 #ifdef  DEBUG_OBJECTS
294   if (glib_debug_objects)
295     {
296       g_assert (g_hash_table_lookup (debug_objects_ht, object) == object);
297       
298       g_hash_table_remove (debug_objects_ht, object);
299       debug_objects_count--;
300     }
301 #endif /* DEBUG_OBJECTS */
302 }
303
304 gpointer
305 g_object_new (GType        object_type,
306               const gchar *first_param_name,
307               ...)
308 {
309   GObject *object;
310   va_list var_args;
311   
312   g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type), NULL);
313   
314   va_start (var_args, first_param_name);
315   object = g_object_new_valist (object_type, first_param_name, var_args);
316   va_end (var_args);
317   
318   return object;
319 }
320
321 gpointer
322 g_object_new_valist (GType        object_type,
323                      const gchar *first_param_name,
324                      va_list      var_args)
325 {
326   GObject *object;
327   
328   g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type), NULL);
329   
330   object = (GObject*) g_type_create_instance (object_type);
331   if (first_param_name)
332     g_object_set_valist (object, first_param_name, var_args);
333   
334   return object;
335 }
336
337 static void
338 g_object_do_dispatch_param_changed (GObject    *object,
339                                     GParamSpec *pspec)
340 {
341 /*  g_message ("NOTIFICATION: parameter `%s' changed on object `%s'",
342              pspec->name,
343              G_OBJECT_TYPE_NAME (object));*/
344 }
345
346 static gboolean
347 notify_param_changed_handler (gpointer data)
348 {
349   GObject *object;
350   GObjectClass *class;
351   GSList *slist;
352   
353   /* FIXME: need GDK_THREADS lock */
354   
355   object = G_OBJECT (data);
356   class = G_OBJECT_GET_CLASS (object);
357   slist = g_datalist_id_get_data (&object->qdata, quark_param_changed_queue);
358   
359   /* a reference count is still being held */
360   
361   for (; slist; slist = slist->next)
362     if (slist->data)
363       {
364         GParamSpec *pspec = slist->data;
365         
366         slist->data = NULL;
367         class->dispatch_param_changed (object, pspec);
368       }
369   
370   g_datalist_id_set_data (&object->qdata, quark_param_changed_queue, NULL);
371   
372   return FALSE;
373 }
374
375 static void
376 g_object_do_queue_param_changed (GObject    *object,
377                                  GParamSpec *pspec)
378 {
379   GSList *slist, *last = NULL;
380   
381   /* if this is a recursive call on this object (i.e. pspecs are queued
382    * for notification, while param_changed notification is currently in
383    * progress), we simply add them to the queue that is currently being
384    * dispatched. otherwise, we later dispatch parameter changed notification
385    * asyncronously from an idle handler untill the queue is completely empty.
386    */
387   
388   slist = g_datalist_id_get_data (&object->qdata, quark_param_changed_queue);
389   for (; slist; last = slist, slist = last->next)
390     if (slist->data == pspec)
391       return;
392   
393   if (!last)
394     {
395       g_object_ref (object);
396       g_idle_add_full (G_NOTIFY_PRIORITY,
397                        notify_param_changed_handler,
398                        object,
399                        (GDestroyNotify) g_object_unref);
400       g_object_set_qdata_full (object,
401                                quark_param_changed_queue,
402                                g_slist_prepend (NULL, pspec),
403                                (GDestroyNotify) g_slist_free);
404     }
405   else
406     last->next = g_slist_prepend (NULL, pspec);
407 }
408
409 static inline void
410 object_get_param (GObject     *object,
411                   GValue      *value,
412                   GParamSpec  *pspec,
413                   const gchar *trailer)
414 {
415   GObjectClass *class;
416   
417   g_return_if_fail (g_type_is_a (G_OBJECT_TYPE (object), pspec->owner_type));   /* paranoid */
418   
419   class = g_type_class_peek (pspec->owner_type);
420   
421   class->get_param (object, PARAM_SPEC_PARAM_ID (pspec), value, pspec, trailer);
422 }
423
424 static inline void
425 object_set_param (GObject     *object,
426                   GValue      *value,
427                   GParamSpec  *pspec,
428                   const gchar *trailer)
429 {
430   GObjectClass *class;
431   
432   g_return_if_fail (g_type_is_a (G_OBJECT_TYPE (object), pspec->owner_type));   /* paranoid */
433   
434   class = g_type_class_peek (pspec->owner_type);
435   
436   class->set_param (object, PARAM_SPEC_PARAM_ID (pspec), value, pspec, trailer);
437   
438   class->queue_param_changed (object, pspec);
439 }
440
441 void
442 g_object_set_valist (GObject     *object,
443                      const gchar *first_param_name,
444                      va_list      var_args)
445 {
446   const gchar *name;
447   
448   g_return_if_fail (G_IS_OBJECT (object));
449   
450   g_object_ref (object);
451   
452   name = first_param_name;
453   
454   while (name)
455     {
456       const gchar *trailer = NULL;
457       GValue value = { 0, };
458       GParamSpec *pspec;
459       gchar *error = NULL;
460       
461       pspec = g_param_spec_hash_table_lookup (param_spec_hash_table,
462                                               name,
463                                               G_OBJECT_TYPE (object),
464                                               TRUE,
465                                               &trailer);
466       if (!pspec)
467         {
468           g_warning ("%s: object class `%s' has no parameter named `%s'",
469                      G_STRLOC,
470                      G_OBJECT_TYPE_NAME (object),
471                      name);
472           break;
473         }
474       if (!(pspec->flags & G_PARAM_WRITABLE))
475         {
476           g_warning ("%s: parameter `%s' of object class `%s' is not writable",
477                      G_STRLOC,
478                      pspec->name,
479                      G_OBJECT_TYPE_NAME (object));
480           break;
481         }
482       
483       g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
484       
485       G_VALUE_COLLECT (&value, var_args, &error);
486       if (error)
487         {
488           g_warning ("%s: %s", G_STRLOC, error);
489           g_free (error);
490           
491           /* we purposely leak the value here, it might not be
492            * in a sane state if an error condition occoured
493            */
494           break;
495         }
496       
497       object_set_param (object, &value, pspec, trailer);
498       
499       g_value_unset (&value);
500       
501       name = va_arg (var_args, gchar*);
502     }
503   
504   g_object_unref (object);
505 }
506
507 void
508 g_object_get_valist (GObject     *object,
509                      const gchar *first_param_name,
510                      va_list      var_args)
511 {
512   const gchar *name;
513   
514   g_return_if_fail (G_IS_OBJECT (object));
515   
516   g_object_ref (object);
517   
518   name = first_param_name;
519   
520   while (name)
521     {
522       const gchar *trailer = NULL;
523       GValue value = { 0, };
524       GParamSpec *pspec;
525       gchar *error = NULL;
526       
527       pspec = g_param_spec_hash_table_lookup (param_spec_hash_table,
528                                               name,
529                                               G_OBJECT_TYPE (object),
530                                               TRUE,
531                                               &trailer);
532       if (!pspec)
533         {
534           g_warning ("%s: object class `%s' has no parameter named `%s'",
535                      G_STRLOC,
536                      G_OBJECT_TYPE_NAME (object),
537                      name);
538           break;
539         }
540       if (!(pspec->flags & G_PARAM_READABLE))
541         {
542           g_warning ("%s: parameter `%s' of object class `%s' is not readable",
543                      G_STRLOC,
544                      pspec->name,
545                      G_OBJECT_TYPE_NAME (object));
546           break;
547         }
548       
549       g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
550       
551       object_get_param (object, &value, pspec, trailer);
552       
553       G_VALUE_LCOPY (&value, var_args, &error);
554       if (error)
555         {
556           g_warning ("%s: %s", G_STRLOC, error);
557           g_free (error);
558           
559           /* we purposely leak the value here, it might not be
560            * in a sane state if an error condition occoured
561            */
562           break;
563         }
564       
565       g_value_unset (&value);
566       
567       name = va_arg (var_args, gchar*);
568     }
569   
570   g_object_unref (object);
571 }
572
573 void
574 g_object_set (GObject     *object,
575               const gchar *first_param_name,
576               ...)
577 {
578   va_list var_args;
579   
580   g_return_if_fail (G_IS_OBJECT (object));
581   
582   va_start (var_args, first_param_name);
583   g_object_set_valist (object, first_param_name, var_args);
584   va_end (var_args);
585 }
586
587 void
588 g_object_get (GObject     *object,
589               const gchar *first_param_name,
590               ...)
591 {
592   va_list var_args;
593   
594   g_return_if_fail (G_IS_OBJECT (object));
595   
596   va_start (var_args, first_param_name);
597   g_object_get_valist (object, first_param_name, var_args);
598   va_end (var_args);
599 }
600
601 void
602 g_object_set_param (GObject      *object,
603                     const gchar  *param_name,
604                     const GValue *value)
605 {
606   GParamSpec *pspec;
607   const gchar *trailer;
608   
609   g_return_if_fail (G_IS_OBJECT (object));
610   g_return_if_fail (param_name != NULL);
611   g_return_if_fail (G_IS_VALUE (value));
612   
613   g_object_ref (object);
614   
615   pspec = g_param_spec_hash_table_lookup (param_spec_hash_table,
616                                           param_name,
617                                           G_OBJECT_TYPE (object),
618                                           TRUE,
619                                           &trailer);
620   if (!pspec)
621     g_warning ("%s: object class `%s' has no parameter named `%s'",
622                G_STRLOC,
623                G_OBJECT_TYPE_NAME (object),
624                param_name);
625   else
626     {
627       GValue tmp_value = { 0, };
628       
629       /* provide a copy to work from and convert if necessary */
630       g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
631       
632       if (!g_value_convert (value, &tmp_value) ||
633           g_param_value_validate (pspec, &tmp_value))
634         g_warning ("%s: cannot convert `%s' value to parameter `%s' value of type `%s'",
635                    G_STRLOC,
636                    G_VALUE_TYPE_NAME (value),
637                    pspec->name,
638                    g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)));
639       else
640         object_set_param (object, &tmp_value, pspec, trailer);
641       
642       g_value_unset (&tmp_value);
643     }
644   
645   g_object_unref (object);
646 }
647
648 void
649 g_object_get_param (GObject     *object,
650                     const gchar *param_name,
651                     GValue      *value)
652 {
653   GParamSpec *pspec;
654   const gchar *trailer;
655   
656   g_return_if_fail (G_IS_OBJECT (object));
657   g_return_if_fail (param_name != NULL);
658   g_return_if_fail (G_IS_VALUE (value));
659   
660   g_object_ref (object);
661   
662   pspec = g_param_spec_hash_table_lookup (param_spec_hash_table,
663                                           param_name,
664                                           G_OBJECT_TYPE (object),
665                                           TRUE,
666                                           &trailer);
667   if (!pspec)
668     g_warning ("%s: object class `%s' has no parameter named `%s'",
669                G_STRLOC,
670                G_OBJECT_TYPE_NAME (object),
671                param_name);
672   else
673     {
674       GValue tmp_value = { 0, };
675       
676       /* provide a copy to work from and later convert if necessary, so
677        * _get_param() implementations need *not* care about freeing values
678        * that might be already set in the parameter to get.
679        * (though, at this point, GValue should exclusively be modified
680        * through the accessor functions anyways)
681        */
682       g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
683       
684       if (!g_value_types_exchangable (G_VALUE_TYPE (value), G_PARAM_SPEC_VALUE_TYPE (pspec)))
685         g_warning ("%s: can't retrive parameter `%s' value of type `%s' as value of type `%s'",
686                    G_STRLOC,
687                    pspec->name,
688                    g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
689                    G_VALUE_TYPE_NAME (value));
690       else
691         {
692           object_get_param (object, &tmp_value, pspec, trailer);
693           g_value_convert (&tmp_value, value);
694           /* g_value_validate (value, pspec); */
695         }
696       
697       g_value_unset (&tmp_value);
698     }
699   
700   g_object_unref (object);
701 }
702
703 void
704 g_object_queue_param_changed (GObject     *object,
705                               const gchar *param_name)
706 {
707   GParamSpec *pspec;
708   
709   g_return_if_fail (G_IS_OBJECT (object));
710   g_return_if_fail (param_name != NULL);
711   
712   pspec = g_param_spec_hash_table_lookup (param_spec_hash_table,
713                                           param_name,
714                                           G_OBJECT_TYPE (object),
715                                           TRUE, NULL);
716   if (!pspec)
717     g_warning ("%s: object class `%s' has no parameter named `%s'",
718                G_STRLOC,
719                G_OBJECT_TYPE_NAME (object),
720                param_name);
721   else
722     G_OBJECT_GET_CLASS (object)->queue_param_changed (object, pspec);
723 }
724
725 GObject*
726 g_object_ref (GObject *object)
727 {
728   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
729   g_return_val_if_fail (object->ref_count > 0, NULL);
730   
731   object->ref_count += 1;
732   
733   return object;
734 }
735
736 void
737 g_object_unref (GObject *object)
738 {
739   g_return_if_fail (G_IS_OBJECT (object));
740   g_return_if_fail (object->ref_count > 0);
741   
742   if (object->ref_count > 1)
743     object->ref_count -= 1;
744   else
745     g_object_last_unref (object);
746 }
747
748 gpointer
749 g_object_get_qdata (GObject *object,
750                     GQuark   quark)
751 {
752   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
753   
754   return quark ? g_datalist_id_get_data (&object->qdata, quark) : NULL;
755 }
756
757 void
758 g_object_set_qdata (GObject *object,
759                     GQuark   quark,
760                     gpointer data)
761 {
762   g_return_if_fail (G_IS_OBJECT (object));
763   g_return_if_fail (quark > 0);
764   
765   g_datalist_id_set_data (&object->qdata, quark, data);
766 }
767
768 void
769 g_object_set_qdata_full (GObject       *object,
770                          GQuark         quark,
771                          gpointer       data,
772                          GDestroyNotify destroy)
773 {
774   g_return_if_fail (G_IS_OBJECT (object));
775   g_return_if_fail (quark > 0);
776   
777   g_datalist_id_set_data_full (&object->qdata, quark, data, data ? destroy : NULL);
778 }
779
780 gpointer
781 g_object_steal_qdata (GObject *object,
782                       GQuark   quark)
783 {
784   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
785   g_return_val_if_fail (quark > 0, NULL);
786   
787   return g_datalist_id_remove_no_notify (&object->qdata, quark);
788 }
789
790 static void
791 g_value_object_init (GValue *value)
792 {
793   value->data[0].v_pointer = NULL;
794 }
795
796 static void
797 g_value_object_free_value (GValue *value)
798 {
799   if (value->data[0].v_pointer)
800     g_object_unref (value->data[0].v_pointer);
801 }
802
803 static void
804 g_value_object_copy_value (const GValue *src_value,
805                            GValue       *dest_value)
806 {
807   if (src_value->data[0].v_pointer)
808     dest_value->data[0].v_pointer = g_object_ref (src_value->data[0].v_pointer);
809   else
810     dest_value->data[0].v_pointer = NULL;
811 }
812
813 static gchar*
814 g_value_object_collect_value (GValue      *value,
815                               guint        nth_value,
816                               GType       *collect_type,
817                               GTypeCValue *collect_value)
818 {
819   if (collect_value->v_pointer)
820     {
821       GObject *object = collect_value->v_pointer;
822       
823       if (object->g_type_instance.g_class == NULL)
824         return g_strconcat ("invalid unclassed object pointer for value type `",
825                             G_VALUE_TYPE_NAME (value),
826                             "'",
827                             NULL);
828       else if (!g_type_is_a (G_OBJECT_TYPE (object), G_VALUE_TYPE (value)))
829         return g_strconcat ("invalid object type `",
830                             G_OBJECT_TYPE_NAME (object),
831                             "' for value type `",
832                             G_VALUE_TYPE_NAME (value),
833                             "'",
834                             NULL);
835       value->data[0].v_pointer = g_object_ref (object);
836     }
837   else
838     value->data[0].v_pointer = NULL;
839   
840   *collect_type = 0;
841   return NULL;
842 }
843
844 static gchar*
845 g_value_object_lcopy_value (const GValue *value,
846                             guint         nth_value,
847                             GType        *collect_type,
848                             GTypeCValue  *collect_value)
849 {
850   GObject **object_p = collect_value->v_pointer;
851   
852   if (!object_p)
853     return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
854   
855   *object_p = value->data[0].v_pointer ? g_object_ref (value->data[0].v_pointer) : NULL;
856   
857   *collect_type = 0;
858   return NULL;
859 }
860
861 void
862 g_value_set_object (GValue  *value,
863                     GObject *v_object)
864 {
865   g_return_if_fail (G_IS_VALUE_OBJECT (value));
866   if (v_object)
867     g_return_if_fail (G_IS_OBJECT (v_object));
868   
869   if (value->data[0].v_pointer)
870     g_object_unref (value->data[0].v_pointer);
871   value->data[0].v_pointer = v_object;
872   if (value->data[0].v_pointer)
873     g_object_ref (value->data[0].v_pointer);
874 }
875
876 GObject*
877 g_value_get_object (GValue *value)
878 {
879   g_return_val_if_fail (G_IS_VALUE_OBJECT (value), NULL);
880   
881   return value->data[0].v_pointer;
882 }
883
884 GObject*
885 g_value_dup_object (GValue *value)
886 {
887   g_return_val_if_fail (G_IS_VALUE_OBJECT (value), NULL);
888   
889   return value->data[0].v_pointer ? g_object_ref (value->data[0].v_pointer) : NULL;
890 }