]> Pileus Git - ~andy/gtk/blob - gtk/gtkobject.c
Fixes for AIX compilation from Miroslaw Dobrzanski-Neumann, #72182.
[~andy/gtk] / gtk / gtkobject.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
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 Public
15  * 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 /*
21  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
22  * file for a list of people on the GTK+ Team.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
25  */
26
27 #include <stdarg.h>
28 #include <string.h>
29 #include <stdio.h>
30 #include "gtkobject.h"
31 #include "gtkmarshalers.h"
32 #include "gtksignal.h"
33
34
35 enum {
36   DESTROY,
37   LAST_SIGNAL
38 };
39 enum {
40   PROP_0,
41   PROP_USER_DATA
42 };
43
44
45 extern void       gtk_object_init_type           (void);        /* for gtktypeutils.h */
46 static void       gtk_object_base_class_init     (GtkObjectClass *class);
47 static void       gtk_object_base_class_finalize (GtkObjectClass *class);
48 static void       gtk_object_class_init          (GtkObjectClass *klass);
49 static void       gtk_object_init                (GtkObject      *object,
50                                                   GtkObjectClass *klass);
51 static void       gtk_object_set_property        (GObject        *object,
52                                                   guint           property_id,
53                                                   const GValue   *value,
54                                                   GParamSpec     *pspec);
55 static void       gtk_object_get_property        (GObject        *object,
56                                                   guint           property_id,
57                                                   GValue         *value,
58                                                   GParamSpec     *pspec);
59 static void       gtk_object_dispose            (GObject        *object);
60 static void       gtk_object_real_destroy        (GtkObject      *object);
61 static void       gtk_object_finalize            (GObject        *object);
62 static void       gtk_object_notify_weaks        (GtkObject      *object);
63
64 static gpointer    parent_class = NULL;
65 static guint       object_signals[LAST_SIGNAL] = { 0 };
66 static GQuark      quark_user_data = 0;
67 static GQuark      quark_weakrefs = 0;
68
69
70 /****************************************************
71  * GtkObject type, class and instance initialization
72  *
73  ****************************************************/
74
75 GtkType
76 gtk_object_get_type (void)
77 {
78   static GtkType object_type = 0;
79
80   if (!object_type)
81     {
82       static const GTypeInfo object_info =
83       {
84         sizeof (GtkObjectClass),
85         (GBaseInitFunc) gtk_object_base_class_init,
86         (GBaseFinalizeFunc) gtk_object_base_class_finalize,
87         (GClassInitFunc) gtk_object_class_init,
88         NULL,           /* class_finalize */
89         NULL,           /* class_data */
90         sizeof (GtkObject),
91         16,                     /* n_preallocs */
92         (GInstanceInitFunc) gtk_object_init,
93       };
94       
95       object_type = g_type_register_static (G_TYPE_OBJECT, "GtkObject", &object_info, 0);
96     }
97
98   return object_type;
99 }
100
101 static void
102 gtk_object_base_class_init (GtkObjectClass *class)
103 {
104   /* reset instance specifc methods that don't get inherited */
105   class->get_arg = NULL;
106   class->set_arg = NULL;
107 }
108
109 static void
110 gtk_object_base_class_finalize (GtkObjectClass *class)
111 {
112 }
113
114 static inline gboolean
115 gtk_arg_set_from_value (GtkArg       *arg,
116                         const GValue *value,
117                         gboolean      copy_string)
118 {
119   switch (G_TYPE_FUNDAMENTAL (arg->type))
120     {
121     case G_TYPE_CHAR:           GTK_VALUE_CHAR (*arg) = g_value_get_char (value);       break;
122     case G_TYPE_UCHAR:          GTK_VALUE_UCHAR (*arg) = g_value_get_uchar (value);     break;
123     case G_TYPE_BOOLEAN:        GTK_VALUE_BOOL (*arg) = g_value_get_boolean (value);    break;
124     case G_TYPE_INT:            GTK_VALUE_INT (*arg) = g_value_get_int (value);         break;
125     case G_TYPE_UINT:           GTK_VALUE_UINT (*arg) = g_value_get_uint (value);       break;
126     case G_TYPE_LONG:           GTK_VALUE_LONG (*arg) = g_value_get_long (value);       break;
127     case G_TYPE_ULONG:          GTK_VALUE_ULONG (*arg) = g_value_get_ulong (value);     break;
128     case G_TYPE_ENUM:           GTK_VALUE_ENUM (*arg) = g_value_get_enum (value);       break;
129     case G_TYPE_FLAGS:          GTK_VALUE_FLAGS (*arg) = g_value_get_flags (value);     break;
130     case G_TYPE_FLOAT:          GTK_VALUE_FLOAT (*arg) = g_value_get_float (value);     break;
131     case G_TYPE_DOUBLE:         GTK_VALUE_DOUBLE (*arg) = g_value_get_double (value);   break;
132     case G_TYPE_BOXED:          GTK_VALUE_BOXED (*arg) = g_value_get_boxed (value);     break;
133     case G_TYPE_POINTER:        GTK_VALUE_POINTER (*arg) = g_value_get_pointer (value); break;
134     case G_TYPE_OBJECT:         GTK_VALUE_POINTER (*arg) = g_value_get_object (value);  break;
135     case G_TYPE_STRING:         if (copy_string)
136       GTK_VALUE_STRING (*arg) = g_value_dup_string (value);
137     else
138       GTK_VALUE_STRING (*arg) = (char *) g_value_get_string (value);
139     break;
140     default:
141       return FALSE;
142     }
143   return TRUE;
144 }
145
146 static inline gboolean
147 gtk_arg_to_value (GtkArg *arg,
148                   GValue *value)
149 {
150   switch (G_TYPE_FUNDAMENTAL (arg->type))
151     {
152     case G_TYPE_CHAR:           g_value_set_char (value, GTK_VALUE_CHAR (*arg));        break;
153     case G_TYPE_UCHAR:          g_value_set_uchar (value, GTK_VALUE_UCHAR (*arg));      break;
154     case G_TYPE_BOOLEAN:        g_value_set_boolean (value, GTK_VALUE_BOOL (*arg));     break;
155     case G_TYPE_INT:            g_value_set_int (value, GTK_VALUE_INT (*arg));          break;
156     case G_TYPE_UINT:           g_value_set_uint (value, GTK_VALUE_UINT (*arg));        break;
157     case G_TYPE_LONG:           g_value_set_long (value, GTK_VALUE_LONG (*arg));        break;
158     case G_TYPE_ULONG:          g_value_set_ulong (value, GTK_VALUE_ULONG (*arg));      break;
159     case G_TYPE_ENUM:           g_value_set_enum (value, GTK_VALUE_ENUM (*arg));        break;
160     case G_TYPE_FLAGS:          g_value_set_flags (value, GTK_VALUE_FLAGS (*arg));      break;
161     case G_TYPE_FLOAT:          g_value_set_float (value, GTK_VALUE_FLOAT (*arg));      break;
162     case G_TYPE_DOUBLE:         g_value_set_double (value, GTK_VALUE_DOUBLE (*arg));    break;
163     case G_TYPE_STRING:         g_value_set_string (value, GTK_VALUE_STRING (*arg));    break;
164     case G_TYPE_BOXED:          g_value_set_boxed (value, GTK_VALUE_BOXED (*arg));      break;
165     case G_TYPE_POINTER:        g_value_set_pointer (value, GTK_VALUE_POINTER (*arg));  break;
166     case G_TYPE_OBJECT:         g_value_set_object (value, GTK_VALUE_POINTER (*arg));   break;
167     default:
168       return FALSE;
169     }
170   return TRUE;
171 }
172
173 static void
174 gtk_arg_proxy_set_property (GObject      *object,
175                             guint         property_id,
176                             const GValue *value,
177                             GParamSpec   *pspec)
178 {
179   GtkObjectClass *class = g_type_class_peek (pspec->owner_type);
180   GtkArg arg;
181
182   g_return_if_fail (class->set_arg != NULL);
183
184   memset (&arg, 0, sizeof (arg));
185   arg.type = G_VALUE_TYPE (value);
186   gtk_arg_set_from_value (&arg, value, FALSE);
187   arg.name = pspec->name;
188   class->set_arg (GTK_OBJECT (object), &arg, property_id);
189 }
190
191 static void
192 gtk_arg_proxy_get_property (GObject     *object,
193                             guint        property_id,
194                             GValue      *value,
195                             GParamSpec  *pspec)
196 {
197   GtkObjectClass *class = g_type_class_peek (pspec->owner_type);
198   GtkArg arg;
199
200   g_return_if_fail (class->get_arg != NULL);
201
202   memset (&arg, 0, sizeof (arg));
203   arg.type = G_VALUE_TYPE (value);
204   arg.name = pspec->name;
205   class->get_arg (GTK_OBJECT (object), &arg, property_id);
206   gtk_arg_to_value (&arg, value);
207 }
208
209 void
210 gtk_object_add_arg_type (const gchar *arg_name,
211                          GtkType      arg_type,
212                          guint        arg_flags,
213                          guint        arg_id)
214 {
215   GObjectClass *oclass;
216   GParamSpec *pspec;
217   gchar *type_name, *pname;
218   GType type;
219   
220   g_return_if_fail (arg_name != NULL);
221   g_return_if_fail (arg_type > G_TYPE_NONE);
222   g_return_if_fail (arg_id > 0);
223   g_return_if_fail (arg_flags & GTK_ARG_READWRITE);
224   if (arg_flags & G_PARAM_CONSTRUCT)
225     g_return_if_fail ((arg_flags & G_PARAM_CONSTRUCT_ONLY) == 0);
226   if (arg_flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY))
227     g_return_if_fail (arg_flags & G_PARAM_WRITABLE);
228   g_return_if_fail ((arg_flags & ~(GTK_ARG_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY)) == 0);
229
230   pname = strchr (arg_name, ':');
231   g_return_if_fail (pname && pname[1] == ':');
232
233   type_name = g_strndup (arg_name, pname - arg_name);
234   pname += 2;
235   type = g_type_from_name (type_name);
236   g_free (type_name);
237   g_return_if_fail (G_TYPE_IS_OBJECT (type));
238
239   oclass = gtk_type_class (type);
240   if (arg_flags & GTK_ARG_READABLE)
241     {
242       if (oclass->get_property && oclass->get_property != gtk_arg_proxy_get_property)
243         {
244           g_warning (G_STRLOC ": GtkArg compatibility code can't be mixed with customized %s.get_property() implementation",
245                      g_type_name (type));
246           return;
247         }
248       oclass->get_property = gtk_arg_proxy_get_property;
249     }
250   if (arg_flags & GTK_ARG_WRITABLE)
251     {
252       if (oclass->set_property && oclass->set_property != gtk_arg_proxy_set_property)
253         {
254           g_warning (G_STRLOC ": GtkArg compatibility code can't be mixed with customized %s.set_property() implementation",
255                      g_type_name (type));
256           return;
257         }
258       oclass->set_property = gtk_arg_proxy_set_property;
259     }
260   switch (G_TYPE_FUNDAMENTAL (arg_type))
261     {
262     case G_TYPE_ENUM:
263       pspec = g_param_spec_enum (pname, NULL, NULL, arg_type, 0, arg_flags);
264       break;
265     case G_TYPE_FLAGS:
266       pspec = g_param_spec_flags (pname, NULL, NULL, arg_type, 0, arg_flags);
267       break;
268     case G_TYPE_CHAR:
269       pspec = g_param_spec_char (pname, NULL, NULL, -128, 127, 0, arg_flags);
270       break;
271     case G_TYPE_UCHAR:
272       pspec = g_param_spec_uchar (pname, NULL, NULL, 0, 255, 0, arg_flags);
273       break;
274     case G_TYPE_BOOLEAN:
275       pspec = g_param_spec_boolean (pname, NULL, NULL, FALSE, arg_flags);
276       break;
277     case G_TYPE_INT:
278       pspec = g_param_spec_int (pname, NULL, NULL, -2147483647, 2147483647, 0, arg_flags);
279       break;
280     case G_TYPE_UINT:
281       pspec = g_param_spec_uint (pname, NULL, NULL, 0, 4294967295U, 0, arg_flags);
282       break;
283     case G_TYPE_FLOAT:
284       pspec = g_param_spec_float (pname, NULL, NULL, -1E+37, 1E+37, 0, arg_flags);
285       break;
286     case G_TYPE_DOUBLE:
287       pspec = g_param_spec_double (pname, NULL, NULL, -1E+307, 1E+307, 0, arg_flags);
288       break;
289     case G_TYPE_STRING:
290       pspec = g_param_spec_string (pname, NULL, NULL, NULL, arg_flags);
291       break;
292     case G_TYPE_POINTER:
293       pspec = g_param_spec_pointer (pname, NULL, NULL, arg_flags);
294       break;
295     case G_TYPE_OBJECT:
296       pspec = g_param_spec_object (pname, NULL, NULL, arg_type, arg_flags);
297       break;
298     case G_TYPE_BOXED:
299       if (!G_TYPE_IS_FUNDAMENTAL (arg_type))
300         {
301           pspec = g_param_spec_boxed (pname, NULL, NULL, arg_type, arg_flags);
302           break;
303         }
304     default:
305       g_warning (G_STRLOC ": Property type `%s' is not supported by the GtkArg compatibility code",
306                  g_type_name (arg_type));
307       return;
308     }
309   g_object_class_install_property (oclass, arg_id, pspec);
310 }
311
312 static void
313 gtk_object_class_init (GtkObjectClass *class)
314 {
315   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
316
317   parent_class = g_type_class_ref (G_TYPE_OBJECT);
318
319   gobject_class->set_property = gtk_object_set_property;
320   gobject_class->get_property = gtk_object_get_property;
321   gobject_class->dispose = gtk_object_dispose;
322   gobject_class->finalize = gtk_object_finalize;
323
324   class->destroy = gtk_object_real_destroy;
325
326   g_object_class_install_property (gobject_class,
327                                    PROP_USER_DATA,
328                                    g_param_spec_pointer ("user_data", "User Data",
329                                                          "Anonymous User Data Pointer",
330                                                          G_PARAM_READABLE | G_PARAM_WRITABLE));
331   object_signals[DESTROY] =
332     gtk_signal_new ("destroy",
333                     G_SIGNAL_RUN_CLEANUP | G_SIGNAL_NO_RECURSE | GTK_RUN_NO_HOOKS,
334                     GTK_CLASS_TYPE (class),
335                     GTK_SIGNAL_OFFSET (GtkObjectClass, destroy),
336                     _gtk_marshal_VOID__VOID,
337                     GTK_TYPE_NONE, 0);
338 }
339
340 static void
341 gtk_object_init (GtkObject      *object,
342                  GtkObjectClass *klass)
343 {
344   GTK_OBJECT_FLAGS (object) = GTK_FLOATING;
345 }
346
347 /********************************************
348  * Functions to end a GtkObject's life time
349  *
350  ********************************************/
351 void
352 gtk_object_destroy (GtkObject *object)
353 {
354   g_return_if_fail (object != NULL);
355   g_return_if_fail (GTK_IS_OBJECT (object));
356   
357   if (!(GTK_OBJECT_FLAGS (object) & GTK_IN_DESTRUCTION))
358     g_object_run_dispose (G_OBJECT (object));
359 }
360
361 static void
362 gtk_object_dispose (GObject *gobject)
363 {
364   GtkObject *object = GTK_OBJECT (gobject);
365
366   /* guard against reinvocations during
367    * destruction with the GTK_IN_DESTRUCTION flag.
368    */
369   if (!(GTK_OBJECT_FLAGS (object) & GTK_IN_DESTRUCTION))
370     {
371       GTK_OBJECT_SET_FLAGS (object, GTK_IN_DESTRUCTION);
372       
373       gtk_signal_emit (object, object_signals[DESTROY]);
374       
375       GTK_OBJECT_UNSET_FLAGS (object, GTK_IN_DESTRUCTION);
376     }
377
378   G_OBJECT_CLASS (parent_class)->dispose (gobject);
379 }
380
381 static void
382 gtk_object_real_destroy (GtkObject *object)
383 {
384   g_signal_handlers_destroy (G_OBJECT (object));
385 }
386
387 static void
388 gtk_object_finalize (GObject *gobject)
389 {
390   GtkObject *object = GTK_OBJECT (gobject);
391
392   if (GTK_OBJECT_FLOATING (object))
393     {
394       g_warning ("A floating object was finalized. This means that someone\n"
395                  "called g_object_unref() on an object that had only a floating\n"
396                  "reference; the initial floating reference is not owned by anyone\n"
397                  "and must be removed with gtk_object_sink() after a normal\n"
398                  "reference is obtained with g_object_ref().");
399     }
400   
401   gtk_object_notify_weaks (object);
402   
403   G_OBJECT_CLASS (parent_class)->finalize (gobject);
404 }
405
406 /*****************************************
407  * GtkObject argument handlers
408  *
409  *****************************************/
410
411 static void
412 gtk_object_set_property (GObject      *object,
413                          guint         property_id,
414                          const GValue *value,
415                          GParamSpec   *pspec)
416 {
417   switch (property_id)
418     {
419     case PROP_USER_DATA:
420       gtk_object_set_user_data (GTK_OBJECT (object), g_value_get_pointer (value));
421       break;
422     default:
423       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
424       break;
425     }
426 }
427
428 static void
429 gtk_object_get_property (GObject     *object,
430                          guint        property_id,
431                          GValue      *value,
432                          GParamSpec  *pspec)
433 {
434   switch (property_id)
435     {
436     case PROP_USER_DATA:
437       g_value_set_pointer (value, gtk_object_get_user_data (GTK_OBJECT (object)));
438       break;
439     default:
440       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
441       break;
442     }
443 }
444
445 /*****************************************
446  * gtk_object_sink:
447  *
448  *   arguments:
449  *
450  *   results:
451  *****************************************/
452
453 void
454 gtk_object_sink (GtkObject *object)
455 {
456   g_return_if_fail (GTK_IS_OBJECT (object));
457
458   if (GTK_OBJECT_FLOATING (object))
459     {
460       GTK_OBJECT_UNSET_FLAGS (object, GTK_FLOATING);
461       gtk_object_unref (object);
462     }
463 }
464
465 /*****************************************
466  * Weak references.
467  *
468  * Weak refs are very similar to the old "destroy" signal.  They allow
469  * one to register a callback that is called when the weakly
470  * referenced object is finalized.
471  *  
472  * They are not implemented as a signal because they really are
473  * special and need to be used with great care.  Unlike signals, which
474  * should be able to execute any code whatsoever.
475  * 
476  * A weakref callback is not allowed to retain a reference to the
477  * object.  Object data keys may be retrieved in a weak reference
478  * callback.
479  * 
480  * A weakref callback is called at most once.
481  *
482  *****************************************/
483
484 typedef struct _GtkWeakRef      GtkWeakRef;
485
486 struct _GtkWeakRef
487 {
488   GtkWeakRef       *next;
489   GtkDestroyNotify  notify;
490   gpointer          data;
491 };
492
493 void
494 gtk_object_weakref (GtkObject        *object,
495                     GtkDestroyNotify  notify,
496                     gpointer          data)
497 {
498   GtkWeakRef *weak;
499
500   g_return_if_fail (notify != NULL);
501   g_return_if_fail (GTK_IS_OBJECT (object));
502
503   if (!quark_weakrefs)
504     quark_weakrefs = g_quark_from_static_string ("gtk-weakrefs");
505
506   weak = g_new (GtkWeakRef, 1);
507   weak->next = gtk_object_get_data_by_id (object, quark_weakrefs);
508   weak->notify = notify;
509   weak->data = data;
510   gtk_object_set_data_by_id (object, quark_weakrefs, weak);
511 }
512
513 void
514 gtk_object_weakunref (GtkObject        *object,
515                       GtkDestroyNotify  notify,
516                       gpointer          data)
517 {
518   GtkWeakRef *weaks, *w, **wp;
519
520   g_return_if_fail (GTK_IS_OBJECT (object));
521
522   if (!quark_weakrefs)
523     return;
524
525   weaks = gtk_object_get_data_by_id (object, quark_weakrefs);
526   for (wp = &weaks; *wp; wp = &(*wp)->next)
527     {
528       w = *wp;
529       if (w->notify == notify && w->data == data)
530         {
531           if (w == weaks)
532             gtk_object_set_data_by_id (object, quark_weakrefs, w->next);
533           else
534             *wp = w->next;
535           g_free (w);
536           return;
537         }
538     }
539 }
540
541 static void
542 gtk_object_notify_weaks (GtkObject *object)
543 {
544   if (quark_weakrefs)
545     {
546       GtkWeakRef *w1, *w2;
547       
548       w1 = gtk_object_get_data_by_id (object, quark_weakrefs);
549       
550       while (w1)
551         {
552           w1->notify (w1->data);
553           w2 = w1->next;
554           g_free (w1);
555           w1 = w2;
556         }
557     }
558 }
559
560 GtkObject*
561 gtk_object_new (GtkType      object_type,
562                 const gchar *first_property_name,
563                 ...)
564 {
565   GtkObject *object;
566   va_list var_args;
567
568   g_return_val_if_fail (GTK_TYPE_IS_OBJECT (object_type), NULL);
569
570   va_start (var_args, first_property_name);
571   object = (GtkObject *)g_object_new_valist (object_type, first_property_name, var_args);
572   va_end (var_args);
573
574   return object;
575 }
576
577 void
578 gtk_object_get (GtkObject   *object,
579                 const gchar *first_property_name,
580                 ...)
581 {
582   va_list var_args;
583   
584   g_return_if_fail (GTK_IS_OBJECT (object));
585   
586   va_start (var_args, first_property_name);
587   g_object_get_valist (G_OBJECT (object), first_property_name, var_args);
588   va_end (var_args);
589 }
590
591 void
592 gtk_object_set (GtkObject   *object,
593                 const gchar *first_property_name,
594                 ...)
595 {
596   va_list var_args;
597   
598   g_return_if_fail (GTK_IS_OBJECT (object));
599   
600   va_start (var_args, first_property_name);
601   g_object_set_valist (G_OBJECT (object), first_property_name, var_args);
602   va_end (var_args);
603 }
604
605 /*****************************************
606  * GtkObject object_data mechanism
607  *
608  *****************************************/
609
610 void
611 gtk_object_set_data_by_id (GtkObject        *object,
612                            GQuark            data_id,
613                            gpointer          data)
614 {
615   g_return_if_fail (GTK_IS_OBJECT (object));
616   
617   g_datalist_id_set_data (&G_OBJECT (object)->qdata, data_id, data);
618 }
619
620 void
621 gtk_object_set_data (GtkObject        *object,
622                      const gchar      *key,
623                      gpointer          data)
624 {
625   g_return_if_fail (GTK_IS_OBJECT (object));
626   g_return_if_fail (key != NULL);
627   
628   g_datalist_set_data (&G_OBJECT (object)->qdata, key, data);
629 }
630
631 void
632 gtk_object_set_data_by_id_full (GtkObject        *object,
633                                 GQuark            data_id,
634                                 gpointer          data,
635                                 GtkDestroyNotify  destroy)
636 {
637   g_return_if_fail (GTK_IS_OBJECT (object));
638
639   g_datalist_id_set_data_full (&G_OBJECT (object)->qdata, data_id, data, destroy);
640 }
641
642 void
643 gtk_object_set_data_full (GtkObject        *object,
644                           const gchar      *key,
645                           gpointer          data,
646                           GtkDestroyNotify  destroy)
647 {
648   g_return_if_fail (GTK_IS_OBJECT (object));
649   g_return_if_fail (key != NULL);
650
651   g_datalist_set_data_full (&G_OBJECT (object)->qdata, key, data, destroy);
652 }
653
654 gpointer
655 gtk_object_get_data_by_id (GtkObject   *object,
656                            GQuark       data_id)
657 {
658   g_return_val_if_fail (GTK_IS_OBJECT (object), NULL);
659
660   return g_datalist_id_get_data (&G_OBJECT (object)->qdata, data_id);
661 }
662
663 gpointer
664 gtk_object_get_data (GtkObject   *object,
665                      const gchar *key)
666 {
667   g_return_val_if_fail (GTK_IS_OBJECT (object), NULL);
668   g_return_val_if_fail (key != NULL, NULL);
669
670   return g_datalist_get_data (&G_OBJECT (object)->qdata, key);
671 }
672
673 void
674 gtk_object_remove_data_by_id (GtkObject   *object,
675                               GQuark       data_id)
676 {
677   g_return_if_fail (GTK_IS_OBJECT (object));
678
679   g_datalist_id_remove_data (&G_OBJECT (object)->qdata, data_id);
680 }
681
682 void
683 gtk_object_remove_data (GtkObject   *object,
684                         const gchar *key)
685 {
686   g_return_if_fail (GTK_IS_OBJECT (object));
687   g_return_if_fail (key != NULL);
688
689   g_datalist_remove_data (&G_OBJECT (object)->qdata, key);
690 }
691
692 void
693 gtk_object_remove_no_notify_by_id (GtkObject      *object,
694                                    GQuark          key_id)
695 {
696   g_return_if_fail (GTK_IS_OBJECT (object));
697
698   g_datalist_id_remove_no_notify (&G_OBJECT (object)->qdata, key_id);
699 }
700
701 void
702 gtk_object_remove_no_notify (GtkObject       *object,
703                              const gchar     *key)
704 {
705   g_return_if_fail (GTK_IS_OBJECT (object));
706   g_return_if_fail (key != NULL);
707
708   g_datalist_remove_no_notify (&G_OBJECT (object)->qdata, key);
709 }
710
711 void
712 gtk_object_set_user_data (GtkObject *object,
713                           gpointer   data)
714 {
715   g_return_if_fail (GTK_IS_OBJECT (object));
716
717   if (!quark_user_data)
718     quark_user_data = g_quark_from_static_string ("user_data");
719
720   g_datalist_id_set_data (&G_OBJECT (object)->qdata, quark_user_data, data);
721 }
722
723 gpointer
724 gtk_object_get_user_data (GtkObject *object)
725 {
726   g_return_val_if_fail (GTK_IS_OBJECT (object), NULL);
727
728   return g_datalist_id_get_data (&G_OBJECT (object)->qdata, quark_user_data);
729 }
730
731 GtkObject*
732 gtk_object_ref (GtkObject *object)
733 {
734   g_return_val_if_fail (GTK_IS_OBJECT (object), NULL);
735
736   return (GtkObject*) g_object_ref ((GObject*) object);
737 }
738
739 void
740 gtk_object_unref (GtkObject *object)
741 {
742   g_return_if_fail (GTK_IS_OBJECT (object));
743
744   g_object_unref ((GObject*) object);
745 }