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