]> Pileus Git - ~andy/gtk/blob - gtk/gtkobject.c
doh, this was broken beyond believe.
[~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 "gtksignal.h"
32
33
34 enum {
35   DESTROY,
36   LAST_SIGNAL
37 };
38 enum {
39   PROP_0,
40   PROP_USER_DATA,
41 };
42
43
44 extern void       gtk_object_init_type           (void);        /* for gtktypeutils.h */
45 static void       gtk_object_base_class_init     (GtkObjectClass *class);
46 static void       gtk_object_base_class_finalize (GtkObjectClass *class);
47 static void       gtk_object_class_init          (GtkObjectClass *klass);
48 static void       gtk_object_init                (GtkObject      *object,
49                                                   GtkObjectClass *klass);
50 static void       gtk_object_set_property        (GObject        *object,
51                                                   guint           property_id,
52                                                   const GValue   *value,
53                                                   GParamSpec     *pspec,
54                                                   const gchar    *trailer);
55 static void       gtk_object_get_property        (GObject        *object,
56                                                   guint           property_id,
57                                                   GValue         *value,
58                                                   GParamSpec     *pspec,
59                                                   const gchar    *trailer);
60 static void       gtk_object_shutdown            (GObject        *object);
61 static void       gtk_object_real_destroy        (GtkObject      *object);
62 static void       gtk_object_finalize            (GObject        *object);
63 static void       gtk_object_notify_weaks        (GtkObject      *object);
64
65 static gpointer    parent_class = NULL;
66 static guint       object_signals[LAST_SIGNAL] = { 0 };
67 static GQuark      quark_user_data = 0;
68 static GQuark      quark_weakrefs = 0;
69
70
71 /****************************************************
72  * GtkObject type, class and instance initialization
73  *
74  ****************************************************/
75
76 GtkType
77 gtk_object_get_type (void)
78 {
79   static GtkType object_type = 0;
80
81   if (!object_type)
82     {
83       static const GTypeInfo object_info =
84       {
85         sizeof (GtkObjectClass),
86         (GBaseInitFunc) gtk_object_base_class_init,
87         (GBaseFinalizeFunc) gtk_object_base_class_finalize,
88         (GClassInitFunc) gtk_object_class_init,
89         NULL,           /* class_finalize */
90         NULL,           /* class_data */
91         sizeof (GtkObject),
92         16,                     /* n_preallocs */
93         (GInstanceInitFunc) gtk_object_init,
94       };
95       
96       object_type = g_type_register_static (G_TYPE_OBJECT, "GtkObject", &object_info, 0);
97     }
98
99   return object_type;
100 }
101
102 static void
103 gtk_object_base_class_init (GtkObjectClass *class)
104 {
105   /* reset instance specifc methods that don't get inherited */
106   class->get_arg = NULL;
107   class->set_arg = NULL;
108 }
109
110 static void
111 gtk_object_base_class_finalize (GtkObjectClass *class)
112 {
113 }
114
115 static inline gboolean
116 gtk_arg_set_from_value (GtkArg       *arg,
117                         const GValue *value,
118                         gboolean      copy_string)
119 {
120   switch (G_TYPE_FUNDAMENTAL (arg->type))
121     {
122     case G_TYPE_CHAR:           GTK_VALUE_CHAR (*arg) = g_value_get_char (value);       break;
123     case G_TYPE_UCHAR:          GTK_VALUE_UCHAR (*arg) = g_value_get_uchar (value);     break;
124     case G_TYPE_BOOLEAN:        GTK_VALUE_BOOL (*arg) = g_value_get_boolean (value);    break;
125     case G_TYPE_INT:            GTK_VALUE_INT (*arg) = g_value_get_int (value);         break;
126     case G_TYPE_UINT:           GTK_VALUE_UINT (*arg) = g_value_get_uint (value);       break;
127     case G_TYPE_LONG:           GTK_VALUE_LONG (*arg) = g_value_get_long (value);       break;
128     case G_TYPE_ULONG:          GTK_VALUE_ULONG (*arg) = g_value_get_ulong (value);     break;
129     case G_TYPE_ENUM:           GTK_VALUE_ENUM (*arg) = g_value_get_enum (value);       break;
130     case G_TYPE_FLAGS:          GTK_VALUE_FLAGS (*arg) = g_value_get_flags (value);     break;
131     case G_TYPE_FLOAT:          GTK_VALUE_FLOAT (*arg) = g_value_get_float (value);     break;
132     case G_TYPE_DOUBLE:         GTK_VALUE_DOUBLE (*arg) = g_value_get_double (value);   break;
133     case G_TYPE_BOXED:          GTK_VALUE_BOXED (*arg) = g_value_get_boxed (value);     break;
134     case G_TYPE_POINTER:        GTK_VALUE_POINTER (*arg) = g_value_get_pointer (value); break;
135     case G_TYPE_OBJECT:         GTK_VALUE_POINTER (*arg) = g_value_get_object (value);  break;
136     case G_TYPE_STRING:         if (copy_string)
137       GTK_VALUE_STRING (*arg) = g_value_dup_string (value);
138     else
139       GTK_VALUE_STRING (*arg) = g_value_get_string (value);
140     break;
141     default:
142       return FALSE;
143     }
144   return TRUE;
145 }
146
147 static inline gboolean
148 gtk_arg_to_value (GtkArg *arg,
149                   GValue *value)
150 {
151   switch (G_TYPE_FUNDAMENTAL (arg->type))
152     {
153     case G_TYPE_CHAR:           g_value_set_char (value, GTK_VALUE_CHAR (*arg));        break;
154     case G_TYPE_UCHAR:          g_value_set_uchar (value, GTK_VALUE_UCHAR (*arg));      break;
155     case G_TYPE_BOOLEAN:        g_value_set_boolean (value, GTK_VALUE_BOOL (*arg));     break;
156     case G_TYPE_INT:            g_value_set_int (value, GTK_VALUE_INT (*arg));          break;
157     case G_TYPE_UINT:           g_value_set_uint (value, GTK_VALUE_UINT (*arg));        break;
158     case G_TYPE_LONG:           g_value_set_long (value, GTK_VALUE_LONG (*arg));        break;
159     case G_TYPE_ULONG:          g_value_set_ulong (value, GTK_VALUE_ULONG (*arg));      break;
160     case G_TYPE_ENUM:           g_value_set_enum (value, GTK_VALUE_ENUM (*arg));        break;
161     case G_TYPE_FLAGS:          g_value_set_flags (value, GTK_VALUE_FLAGS (*arg));      break;
162     case G_TYPE_FLOAT:          g_value_set_float (value, GTK_VALUE_FLOAT (*arg));      break;
163     case G_TYPE_DOUBLE:         g_value_set_double (value, GTK_VALUE_DOUBLE (*arg));    break;
164     case G_TYPE_STRING:         g_value_set_string (value, GTK_VALUE_STRING (*arg));    break;
165     case G_TYPE_BOXED:          g_value_set_boxed (value, GTK_VALUE_BOXED (*arg));      break;
166     case G_TYPE_POINTER:        g_value_set_pointer (value, GTK_VALUE_POINTER (*arg));  break;
167     case G_TYPE_OBJECT:         g_value_set_object (value, GTK_VALUE_POINTER (*arg));   break;
168     default:
169       return FALSE;
170     }
171   return TRUE;
172 }
173
174 static void
175 gtk_arg_proxy_set_property (GObject      *object,
176                             guint         property_id,
177                             const GValue *value,
178                             GParamSpec   *pspec,
179                             const gchar  *trailer)
180 {
181   GtkObjectClass *class = g_type_class_peek (pspec->owner_type);
182   GtkArg arg = { 0, };
183
184   g_return_if_fail (class->set_arg != NULL);
185
186   arg.type = G_VALUE_TYPE (value);
187   gtk_arg_set_from_value (&arg, value, FALSE);
188   arg.name = pspec->name;
189   class->set_arg (GTK_OBJECT (object), &arg, property_id);
190 }
191
192 static void
193 gtk_arg_proxy_get_property (GObject     *object,
194                             guint        property_id,
195                             GValue      *value,
196                             GParamSpec  *pspec,
197                             const gchar *trailer)
198 {
199   GtkObjectClass *class = g_type_class_peek (pspec->owner_type);
200   GtkArg arg = { 0, };
201
202   g_return_if_fail (class->get_arg != NULL);
203
204   arg.type = G_VALUE_TYPE (value);
205   arg.name = pspec->name;
206   class->get_arg (GTK_OBJECT (object), &arg, property_id);
207   gtk_arg_to_value (&arg, value);
208 }
209
210 void
211 gtk_object_add_arg_type (const gchar *arg_name,
212                          GtkType      arg_type,
213                          guint        arg_flags,
214                          guint        arg_id)
215 {
216   GObjectClass *oclass;
217   GParamSpec *pspec;
218   gchar *type_name, *pname;
219   GType type;
220   
221   g_return_if_fail (arg_name != NULL);
222   g_return_if_fail (arg_type > G_TYPE_NONE);
223   g_return_if_fail (arg_id > 0);
224   g_return_if_fail (arg_flags & GTK_ARG_READWRITE);
225   if (arg_flags & G_PARAM_CONSTRUCT)
226     g_return_if_fail ((arg_flags & G_PARAM_CONSTRUCT_ONLY) == 0);
227   if (arg_flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY))
228     g_return_if_fail (arg_flags & G_PARAM_WRITABLE);
229   g_return_if_fail ((arg_flags & ~(GTK_ARG_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY)) == 0);
230
231   pname = strchr (arg_name, ':');
232   g_return_if_fail (pname && pname[1] == ':');
233
234   type_name = g_strndup (arg_name, pname - arg_name);
235   pname += 2;
236   type = g_type_from_name (type_name);
237   g_free (type_name);
238   g_return_if_fail (G_TYPE_IS_OBJECT (type));
239
240   oclass = gtk_type_class (type);
241   if (arg_flags & GTK_ARG_READABLE)
242     {
243       if (oclass->get_property && oclass->get_property != gtk_arg_proxy_get_property)
244         {
245           g_warning (G_STRLOC ": GtkArg compatibility code can't be mixed with customized %s.get_property() implementation",
246                      g_type_name (type));
247           return;
248         }
249       oclass->get_property = gtk_arg_proxy_get_property;
250     }
251   if (arg_flags & GTK_ARG_WRITABLE)
252     {
253       if (oclass->set_property && oclass->set_property != gtk_arg_proxy_set_property)
254         {
255           g_warning (G_STRLOC ": GtkArg compatibility code can't be mixed with customized %s.set_property() implementation",
256                      g_type_name (type));
257           return;
258         }
259       oclass->set_property = gtk_arg_proxy_set_property;
260     }
261   switch (G_TYPE_FUNDAMENTAL (arg_type))
262     {
263     case G_TYPE_ENUM:
264       pspec = g_param_spec_enum (pname, NULL, NULL, arg_type, 0, arg_flags);
265       break;
266     case G_TYPE_FLAGS:
267       pspec = g_param_spec_flags (pname, NULL, NULL, arg_type, 0, arg_flags);
268       break;
269     case G_TYPE_CHAR:
270       pspec = g_param_spec_char (pname, NULL, NULL, -128, 127, 0, arg_flags);
271       break;
272     case G_TYPE_UCHAR:
273       pspec = g_param_spec_uchar (pname, NULL, NULL, 0, 255, 0, arg_flags);
274       break;
275     case G_TYPE_BOOLEAN:
276       pspec = g_param_spec_boolean (pname, NULL, NULL, FALSE, arg_flags);
277       break;
278     case G_TYPE_INT:
279       pspec = g_param_spec_int (pname, NULL, NULL, -2147483647, 2147483647, 0, arg_flags);
280       break;
281     case G_TYPE_UINT:
282       pspec = g_param_spec_uint (pname, NULL, NULL, 0, 4294967295U, 0, arg_flags);
283       break;
284     case G_TYPE_FLOAT:
285       pspec = g_param_spec_float (pname, NULL, NULL, -1E+37, 1E+37, 0, arg_flags);
286       break;
287     case G_TYPE_DOUBLE:
288       pspec = g_param_spec_double (pname, NULL, NULL, -1E+307, 1E+307, 0, arg_flags);
289       break;
290     case G_TYPE_STRING:
291       pspec = g_param_spec_string (pname, NULL, NULL, NULL, arg_flags);
292       break;
293     case G_TYPE_OBJECT:
294       pspec = g_param_spec_object (pname, NULL, NULL, arg_type, arg_flags);
295       break;
296     case G_TYPE_BOXED:
297       if (!G_TYPE_IS_FUNDAMENTAL (arg_type))
298         {
299           pspec = g_param_spec_boxed (pname, NULL, NULL, arg_type, arg_flags);
300           break;
301         }
302     default:
303       g_warning (G_STRLOC ": Property type `%s' is not supported by the GtkArg compatibility code",
304                  g_type_name (arg_type));
305       return;
306     }
307   g_object_class_install_property (oclass, arg_id, pspec);
308 }
309
310 static void
311 gtk_object_class_init (GtkObjectClass *class)
312 {
313   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
314
315   parent_class = g_type_class_ref (G_TYPE_OBJECT);
316
317   gobject_class->set_property = gtk_object_set_property;
318   gobject_class->get_property = gtk_object_get_property;
319   gobject_class->shutdown = gtk_object_shutdown;
320   gobject_class->finalize = gtk_object_finalize;
321
322   class->destroy = gtk_object_real_destroy;
323
324   g_object_class_install_property (gobject_class,
325                                    PROP_USER_DATA,
326                                    g_param_spec_pointer ("user_data", "User Data",
327                                                          "Anonymous User Data Pointer",
328                                                          G_PARAM_READABLE | G_PARAM_WRITABLE));
329   object_signals[DESTROY] =
330     gtk_signal_new ("destroy",
331                     G_SIGNAL_RUN_CLEANUP | G_SIGNAL_NO_RECURSE | GTK_RUN_NO_HOOKS,
332                     GTK_CLASS_TYPE (class),
333                     GTK_SIGNAL_OFFSET (GtkObjectClass, destroy),
334                     gtk_marshal_VOID__VOID,
335                     GTK_TYPE_NONE, 0);
336 }
337
338 static void
339 gtk_object_init (GtkObject      *object,
340                  GtkObjectClass *klass)
341 {
342   GTK_OBJECT_FLAGS (object) = GTK_FLOATING;
343 }
344
345 /********************************************
346  * Functions to end a GtkObject's life time
347  *
348  ********************************************/
349 void
350 gtk_object_destroy (GtkObject *object)
351 {
352   g_return_if_fail (object != NULL);
353   g_return_if_fail (GTK_IS_OBJECT (object));
354   
355   if (!GTK_OBJECT_DESTROYED (object))
356     {
357       /* need to hold a reference count around all class method
358        * invocations.
359        */
360       gtk_object_ref (object);
361       G_OBJECT_GET_CLASS (object)->shutdown (G_OBJECT (object));
362       gtk_object_unref (object);
363     }
364 }
365
366 static void
367 gtk_object_shutdown (GObject *gobject)
368 {
369   GtkObject *object = GTK_OBJECT (gobject);
370
371   /* guard against reinvocations during
372    * destruction with the GTK_DESTROYED flag.
373    */
374   if (!GTK_OBJECT_DESTROYED (object))
375     {
376       GTK_OBJECT_SET_FLAGS (object, GTK_DESTROYED);
377       
378       gtk_signal_emit (object, object_signals[DESTROY]);
379       
380       GTK_OBJECT_UNSET_FLAGS (object, GTK_DESTROYED);
381     }
382
383   G_OBJECT_CLASS (parent_class)->shutdown (gobject);
384 }
385
386 static void
387 gtk_object_real_destroy (GtkObject *object)
388 {
389   g_signal_handlers_destroy (G_OBJECT (object));
390 }
391
392 static void
393 gtk_object_finalize (GObject *gobject)
394 {
395   GtkObject *object = GTK_OBJECT (gobject);
396
397   gtk_object_notify_weaks (object);
398   
399   G_OBJECT_CLASS (parent_class)->finalize (gobject);
400 }
401
402 /*****************************************
403  * GtkObject argument handlers
404  *
405  *****************************************/
406
407 static void
408 gtk_object_set_property (GObject      *object,
409                          guint         property_id,
410                          const GValue *value,
411                          GParamSpec   *pspec,
412                          const gchar  *trailer)
413 {
414   switch (property_id)
415     {
416     case PROP_USER_DATA:
417       gtk_object_set_user_data (GTK_OBJECT (object), g_value_get_pointer (value));
418       break;
419     default:
420       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
421       break;
422     }
423 }
424
425 static void
426 gtk_object_get_property (GObject     *object,
427                          guint        property_id,
428                          GValue      *value,
429                          GParamSpec  *pspec,
430                          const gchar *trailer)
431 {
432   switch (property_id)
433     {
434     case PROP_USER_DATA:
435       g_return_if_fail (trailer != NULL);
436
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 (object != NULL);
457   g_return_if_fail (GTK_IS_OBJECT (object));
458
459   if (GTK_OBJECT_FLOATING (object))
460     {
461       GTK_OBJECT_UNSET_FLAGS (object, GTK_FLOATING);
462       gtk_object_unref (object);
463     }
464 }
465
466 /*****************************************
467  * Weak references.
468  *
469  * Weak refs are very similar to the old "destroy" signal.  They allow
470  * one to register a callback that is called when the weakly
471  * referenced object is finalized.
472  *  
473  * They are not implemented as a signal because they really are
474  * special and need to be used with great care.  Unlike signals, which
475  * should be able to execute any code whatsoever.
476  * 
477  * A weakref callback is not allowed to retain a reference to the
478  * object.  Object data keys may be retrieved in a weak reference
479  * callback.
480  * 
481  * A weakref callback is called at most once.
482  *
483  *****************************************/
484
485 typedef struct _GtkWeakRef      GtkWeakRef;
486
487 struct _GtkWeakRef
488 {
489   GtkWeakRef       *next;
490   GtkDestroyNotify  notify;
491   gpointer          data;
492 };
493
494 void
495 gtk_object_weakref (GtkObject        *object,
496                     GtkDestroyNotify  notify,
497                     gpointer          data)
498 {
499   GtkWeakRef *weak;
500
501   g_return_if_fail (object != NULL);
502   g_return_if_fail (notify != NULL);
503   g_return_if_fail (GTK_IS_OBJECT (object));
504
505   if (!quark_weakrefs)
506     quark_weakrefs = g_quark_from_static_string ("gtk-weakrefs");
507
508   weak = g_new (GtkWeakRef, 1);
509   weak->next = gtk_object_get_data_by_id (object, quark_weakrefs);
510   weak->notify = notify;
511   weak->data = data;
512   gtk_object_set_data_by_id (object, quark_weakrefs, weak);
513 }
514
515 void
516 gtk_object_weakunref (GtkObject        *object,
517                       GtkDestroyNotify  notify,
518                       gpointer          data)
519 {
520   GtkWeakRef *weaks, *w, **wp;
521
522   g_return_if_fail (object != NULL);
523   g_return_if_fail (GTK_IS_OBJECT (object));
524
525   if (!quark_weakrefs)
526     return;
527
528   weaks = gtk_object_get_data_by_id (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             gtk_object_set_data_by_id (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 = gtk_object_get_data_by_id (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 (GTK_TYPE_IS_OBJECT (object_type), NULL);
572
573   va_start (var_args, first_property_name);
574   object = 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 }