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