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