]> Pileus Git - ~andy/gtk/blob - gtk/gtkobject.c
Rename the GTK_DESTROYED flag to GTK_IN_DESTRUCTION, remove the
[~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_DESTROYED 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   gtk_object_notify_weaks (object);
393   
394   G_OBJECT_CLASS (parent_class)->finalize (gobject);
395 }
396
397 /*****************************************
398  * GtkObject argument handlers
399  *
400  *****************************************/
401
402 static void
403 gtk_object_set_property (GObject      *object,
404                          guint         property_id,
405                          const GValue *value,
406                          GParamSpec   *pspec)
407 {
408   switch (property_id)
409     {
410     case PROP_USER_DATA:
411       gtk_object_set_user_data (GTK_OBJECT (object), g_value_get_pointer (value));
412       break;
413     default:
414       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
415       break;
416     }
417 }
418
419 static void
420 gtk_object_get_property (GObject     *object,
421                          guint        property_id,
422                          GValue      *value,
423                          GParamSpec  *pspec)
424 {
425   switch (property_id)
426     {
427     case PROP_USER_DATA:
428       g_value_set_pointer (value, gtk_object_get_user_data (GTK_OBJECT (object)));
429       break;
430     default:
431       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
432       break;
433     }
434 }
435
436 /*****************************************
437  * gtk_object_sink:
438  *
439  *   arguments:
440  *
441  *   results:
442  *****************************************/
443
444 void
445 gtk_object_sink (GtkObject *object)
446 {
447   g_return_if_fail (GTK_IS_OBJECT (object));
448
449   if (GTK_OBJECT_FLOATING (object))
450     {
451       GTK_OBJECT_UNSET_FLAGS (object, GTK_FLOATING);
452       gtk_object_unref (object);
453     }
454 }
455
456 /*****************************************
457  * Weak references.
458  *
459  * Weak refs are very similar to the old "destroy" signal.  They allow
460  * one to register a callback that is called when the weakly
461  * referenced object is finalized.
462  *  
463  * They are not implemented as a signal because they really are
464  * special and need to be used with great care.  Unlike signals, which
465  * should be able to execute any code whatsoever.
466  * 
467  * A weakref callback is not allowed to retain a reference to the
468  * object.  Object data keys may be retrieved in a weak reference
469  * callback.
470  * 
471  * A weakref callback is called at most once.
472  *
473  *****************************************/
474
475 typedef struct _GtkWeakRef      GtkWeakRef;
476
477 struct _GtkWeakRef
478 {
479   GtkWeakRef       *next;
480   GtkDestroyNotify  notify;
481   gpointer          data;
482 };
483
484 void
485 gtk_object_weakref (GtkObject        *object,
486                     GtkDestroyNotify  notify,
487                     gpointer          data)
488 {
489   GtkWeakRef *weak;
490
491   g_return_if_fail (notify != NULL);
492   g_return_if_fail (GTK_IS_OBJECT (object));
493
494   if (!quark_weakrefs)
495     quark_weakrefs = g_quark_from_static_string ("gtk-weakrefs");
496
497   weak = g_new (GtkWeakRef, 1);
498   weak->next = gtk_object_get_data_by_id (object, quark_weakrefs);
499   weak->notify = notify;
500   weak->data = data;
501   gtk_object_set_data_by_id (object, quark_weakrefs, weak);
502 }
503
504 void
505 gtk_object_weakunref (GtkObject        *object,
506                       GtkDestroyNotify  notify,
507                       gpointer          data)
508 {
509   GtkWeakRef *weaks, *w, **wp;
510
511   g_return_if_fail (GTK_IS_OBJECT (object));
512
513   if (!quark_weakrefs)
514     return;
515
516   weaks = gtk_object_get_data_by_id (object, quark_weakrefs);
517   for (wp = &weaks; *wp; wp = &(*wp)->next)
518     {
519       w = *wp;
520       if (w->notify == notify && w->data == data)
521         {
522           if (w == weaks)
523             gtk_object_set_data_by_id (object, quark_weakrefs, w->next);
524           else
525             *wp = w->next;
526           g_free (w);
527           return;
528         }
529     }
530 }
531
532 static void
533 gtk_object_notify_weaks (GtkObject *object)
534 {
535   if (quark_weakrefs)
536     {
537       GtkWeakRef *w1, *w2;
538       
539       w1 = gtk_object_get_data_by_id (object, quark_weakrefs);
540       
541       while (w1)
542         {
543           w1->notify (w1->data);
544           w2 = w1->next;
545           g_free (w1);
546           w1 = w2;
547         }
548     }
549 }
550
551 GtkObject*
552 gtk_object_new (GtkType      object_type,
553                 const gchar *first_property_name,
554                 ...)
555 {
556   GtkObject *object;
557   va_list var_args;
558
559   g_return_val_if_fail (GTK_TYPE_IS_OBJECT (object_type), NULL);
560
561   va_start (var_args, first_property_name);
562   object = (GtkObject *)g_object_new_valist (object_type, first_property_name, var_args);
563   va_end (var_args);
564
565   return object;
566 }
567
568 void
569 gtk_object_get (GtkObject   *object,
570                 const gchar *first_property_name,
571                 ...)
572 {
573   va_list var_args;
574   
575   g_return_if_fail (GTK_IS_OBJECT (object));
576   
577   va_start (var_args, first_property_name);
578   g_object_get_valist (G_OBJECT (object), first_property_name, var_args);
579   va_end (var_args);
580 }
581
582 void
583 gtk_object_set (GtkObject   *object,
584                 const gchar *first_property_name,
585                 ...)
586 {
587   va_list var_args;
588   
589   g_return_if_fail (GTK_IS_OBJECT (object));
590   
591   va_start (var_args, first_property_name);
592   g_object_set_valist (G_OBJECT (object), first_property_name, var_args);
593   va_end (var_args);
594 }
595
596 /*****************************************
597  * GtkObject object_data mechanism
598  *
599  *****************************************/
600
601 void
602 gtk_object_set_data_by_id (GtkObject        *object,
603                            GQuark            data_id,
604                            gpointer          data)
605 {
606   g_return_if_fail (GTK_IS_OBJECT (object));
607   
608   g_datalist_id_set_data (&G_OBJECT (object)->qdata, data_id, data);
609 }
610
611 void
612 gtk_object_set_data (GtkObject        *object,
613                      const gchar      *key,
614                      gpointer          data)
615 {
616   g_return_if_fail (GTK_IS_OBJECT (object));
617   g_return_if_fail (key != NULL);
618   
619   g_datalist_set_data (&G_OBJECT (object)->qdata, key, data);
620 }
621
622 void
623 gtk_object_set_data_by_id_full (GtkObject        *object,
624                                 GQuark            data_id,
625                                 gpointer          data,
626                                 GtkDestroyNotify  destroy)
627 {
628   g_return_if_fail (GTK_IS_OBJECT (object));
629
630   g_datalist_id_set_data_full (&G_OBJECT (object)->qdata, data_id, data, destroy);
631 }
632
633 void
634 gtk_object_set_data_full (GtkObject        *object,
635                           const gchar      *key,
636                           gpointer          data,
637                           GtkDestroyNotify  destroy)
638 {
639   g_return_if_fail (GTK_IS_OBJECT (object));
640   g_return_if_fail (key != NULL);
641
642   g_datalist_set_data_full (&G_OBJECT (object)->qdata, key, data, destroy);
643 }
644
645 gpointer
646 gtk_object_get_data_by_id (GtkObject   *object,
647                            GQuark       data_id)
648 {
649   g_return_val_if_fail (GTK_IS_OBJECT (object), NULL);
650
651   return g_datalist_id_get_data (&G_OBJECT (object)->qdata, data_id);
652 }
653
654 gpointer
655 gtk_object_get_data (GtkObject   *object,
656                      const gchar *key)
657 {
658   g_return_val_if_fail (GTK_IS_OBJECT (object), NULL);
659   g_return_val_if_fail (key != NULL, NULL);
660
661   return g_datalist_get_data (&G_OBJECT (object)->qdata, key);
662 }
663
664 void
665 gtk_object_remove_data_by_id (GtkObject   *object,
666                               GQuark       data_id)
667 {
668   g_return_if_fail (GTK_IS_OBJECT (object));
669
670   g_datalist_id_remove_data (&G_OBJECT (object)->qdata, data_id);
671 }
672
673 void
674 gtk_object_remove_data (GtkObject   *object,
675                         const gchar *key)
676 {
677   g_return_if_fail (GTK_IS_OBJECT (object));
678   g_return_if_fail (key != NULL);
679
680   g_datalist_remove_data (&G_OBJECT (object)->qdata, key);
681 }
682
683 void
684 gtk_object_remove_no_notify_by_id (GtkObject      *object,
685                                    GQuark          key_id)
686 {
687   g_return_if_fail (GTK_IS_OBJECT (object));
688
689   g_datalist_id_remove_no_notify (&G_OBJECT (object)->qdata, key_id);
690 }
691
692 void
693 gtk_object_remove_no_notify (GtkObject       *object,
694                              const gchar     *key)
695 {
696   g_return_if_fail (GTK_IS_OBJECT (object));
697   g_return_if_fail (key != NULL);
698
699   g_datalist_remove_no_notify (&G_OBJECT (object)->qdata, key);
700 }
701
702 void
703 gtk_object_set_user_data (GtkObject *object,
704                           gpointer   data)
705 {
706   g_return_if_fail (GTK_IS_OBJECT (object));
707
708   if (!quark_user_data)
709     quark_user_data = g_quark_from_static_string ("user_data");
710
711   g_datalist_id_set_data (&G_OBJECT (object)->qdata, quark_user_data, data);
712 }
713
714 gpointer
715 gtk_object_get_user_data (GtkObject *object)
716 {
717   g_return_val_if_fail (GTK_IS_OBJECT (object), NULL);
718
719   return g_datalist_id_get_data (&G_OBJECT (object)->qdata, quark_user_data);
720 }
721
722 GtkObject*
723 gtk_object_ref (GtkObject *object)
724 {
725   g_return_val_if_fail (GTK_IS_OBJECT (object), NULL);
726
727   return (GtkObject*) g_object_ref ((GObject*) object);
728 }
729
730 void
731 gtk_object_unref (GtkObject *object)
732 {
733   g_return_if_fail (GTK_IS_OBJECT (object));
734
735   g_object_unref ((GObject*) object);
736 }