1 /* GObject - GLib Type, Object, Parameter and Signal Library
2 * Copyright (C) 1998, 1999, 2000 Tim Janik and Red Hat, Inc.
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.
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.
14 * You should have received a copy of the GNU Lesser General
15 * Public License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
17 * Boston, MA 02111-1307, USA.
22 #include "gvaluecollector.h"
24 #include "gparamspecs.h"
25 #include "gvaluetypes.h"
29 #define PREALLOC_CPARAMS (8)
33 #define PARAM_SPEC_PARAM_ID(pspec) (GPOINTER_TO_UINT (g_param_spec_get_qdata ((pspec), quark_property_id)))
44 /* --- properties --- */
51 PROP_SWAPPED_SIGNAL_AFTER
55 /* --- typedefs --- */
56 typedef struct _NotifyQueue NotifyQueue;
59 /* --- prototypes --- */
60 static void g_object_base_class_init (GObjectClass *class);
61 static void g_object_base_class_finalize (GObjectClass *class);
62 static void g_object_do_class_init (GObjectClass *class);
63 static void g_object_init (GObject *object);
64 static GObject* g_object_constructor (GType type,
65 guint n_construct_properties,
66 GObjectConstructParam *construct_params);
67 static void g_object_last_unref (GObject *object);
68 static void g_object_shutdown (GObject *object);
69 static void g_object_finalize (GObject *object);
70 static void g_object_do_set_property (GObject *object,
74 const gchar *trailer);
75 static void g_object_do_get_property (GObject *object,
79 const gchar *trailer);
80 static void g_value_object_init (GValue *value);
81 static void g_value_object_free_value (GValue *value);
82 static void g_value_object_copy_value (const GValue *src_value,
84 static gpointer g_value_object_peek_pointer (const GValue *value);
85 static gchar* g_value_object_collect_value (GValue *value,
88 GTypeCValue *collect_value);
89 static gchar* g_value_object_lcopy_value (const GValue *value,
92 GTypeCValue *collect_value);
93 static void g_object_dispatch_properties_changed (GObject *object,
96 static void g_object_properties_changed (GObject *object,
99 static void g_object_notify_property_changed (GObject *object,
101 static inline NotifyQueue* object_freeze_notifies (GObject *object);
102 static inline void object_queue_property (GObject *object,
104 NotifyQueue *nqueue);
105 static inline void object_thaw_notifies (GObject *object,
106 NotifyQueue *nqueue);
107 static inline void object_get_property (GObject *object,
110 const gchar *trailer);
111 static inline void object_set_property (GObject *object,
114 const gchar *trailer,
115 NotifyQueue *nqueue);
118 /* --- structures --- */
127 /* --- variables --- */
128 static GQuark quark_notify_queue = 0;
129 static GQuark quark_property_id = 0;
130 static GQuark quark_closure_array = 0;
131 static GParamSpecPool *pspec_pool = NULL;
132 static gulong gobject_signals[LAST_SIGNAL] = { 0, };
135 /* --- functions --- */
136 #ifdef G_ENABLE_DEBUG
137 /* We need an actual method for handling debug keys in GLib.
138 * For now, we'll simply use, as a method
139 * 'extern gboolean glib_debug_objects'
141 static volatile GObject *glib_trap_object_ref = NULL;
142 gboolean glib_debug_objects = FALSE;
143 static guint debug_objects_count = 0;
144 static GHashTable *debug_objects_ht = NULL;
146 debug_objects_foreach (gpointer key,
150 GObject *object = value;
152 g_message ("[%p] stale %s\tref_count=%u",
154 G_OBJECT_TYPE_NAME (object),
158 debug_objects_atexit (void)
160 if (glib_debug_objects)
162 if (debug_objects_ht)
164 g_message ("stale GObjects: %u", debug_objects_count);
165 g_hash_table_foreach (debug_objects_ht, debug_objects_foreach, NULL);
169 #endif /* G_ENABLE_DEBUG */
172 g_object_type_init (void) /* sync with gtype.c */
174 static gboolean initialized = FALSE;
175 static const GTypeFundamentalInfo finfo = {
176 G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE,
178 static GTypeInfo info = {
179 sizeof (GObjectClass),
180 (GBaseInitFunc) g_object_base_class_init,
181 (GBaseFinalizeFunc) g_object_base_class_finalize,
182 (GClassInitFunc) g_object_do_class_init,
183 NULL /* class_destroy */,
184 NULL /* class_data */,
187 (GInstanceInitFunc) g_object_init,
188 NULL, /* value_table */
190 static const GTypeValueTable value_table = {
191 g_value_object_init, /* value_init */
192 g_value_object_free_value, /* value_free */
193 g_value_object_copy_value, /* value_copy */
194 g_value_object_peek_pointer, /* value_peek_pointer */
195 G_VALUE_COLLECT_POINTER, /* collect_type */
196 g_value_object_collect_value, /* collect_value */
197 G_VALUE_COLLECT_POINTER, /* lcopy_type */
198 g_value_object_lcopy_value, /* lcopy_value */
202 g_return_if_fail (initialized == FALSE);
207 info.value_table = &value_table;
208 type = g_type_register_fundamental (G_TYPE_OBJECT, "GObject", &info, &finfo, 0);
209 g_assert (type == G_TYPE_OBJECT);
211 #ifdef G_ENABLE_DEBUG
212 g_atexit (debug_objects_atexit);
213 #endif /* G_ENABLE_DEBUG */
217 g_object_base_class_init (GObjectClass *class)
219 GObjectClass *pclass = g_type_class_peek_parent (class);
221 /* reset instance specific fields and methods that don't get inherited */
222 class->n_property_specs = 0;
223 class->property_specs = NULL;
224 class->construct_properties = pclass ? g_slist_copy (pclass->construct_properties) : NULL;
225 class->get_property = NULL;
226 class->set_property = NULL;
230 g_object_base_class_finalize (GObjectClass *class)
234 g_message ("finallizing base class of %s", G_OBJECT_CLASS_NAME (class));
236 _g_signals_destroy (G_OBJECT_CLASS_TYPE (class));
238 g_slist_free (class->construct_properties);
239 class->construct_properties = NULL;
240 for (i = 0; i < class->n_property_specs; i++)
242 GParamSpec *pspec = class->property_specs[i];
244 g_param_spec_pool_remove (pspec_pool, pspec);
245 g_param_spec_set_qdata (pspec, quark_property_id, NULL);
246 g_param_spec_unref (pspec);
248 class->n_property_specs = 0;
249 g_free (class->property_specs);
250 class->property_specs = NULL;
254 g_object_do_class_init (GObjectClass *class)
256 quark_notify_queue = g_quark_from_static_string ("GObject-notify-queue");
257 quark_property_id = g_quark_from_static_string ("GObject-property-id");
258 quark_closure_array = g_quark_from_static_string ("GObject-closure-array");
259 pspec_pool = g_param_spec_pool_new (TRUE);
261 class->constructor = g_object_constructor;
262 class->set_property = g_object_do_set_property;
263 class->get_property = g_object_do_get_property;
264 class->shutdown = g_object_shutdown;
265 class->finalize = g_object_finalize;
266 class->dispatch_properties_changed = g_object_dispatch_properties_changed;
267 class->properties_changed = g_object_properties_changed;
268 class->notify = g_object_notify_property_changed;
270 g_object_class_install_property (class,
272 g_param_spec_pointer ("data", "Named Data",
273 "Named anonymous pointers",
274 G_PARAM_READABLE | G_PARAM_WRITABLE));
275 g_object_class_install_property (class,
277 g_param_spec_ccallback ("signal", "Signal Connection",
278 "Signal connection consisting of a callback function "
279 "and a data pointer",
281 g_object_class_install_property (class,
283 g_param_spec_ccallback ("swapped_signal", "Swapped Signal Connection",
284 "Signal connection consisting of a callback function "
285 "and a data pointer",
287 g_object_class_install_property (class,
289 g_param_spec_ccallback ("signal_after", "Signal After Connection",
290 "Signal connection consisting of a callback function "
291 "and a data pointer",
293 g_object_class_install_property (class,
294 PROP_SWAPPED_SIGNAL_AFTER,
295 g_param_spec_ccallback ("swapped_signal_after", "Swapped Signal After Connection",
296 "Signal connection consisting of a callback function "
297 "and a data pointer",
299 gobject_signals[PROPERTIES_CHANGED] =
300 g_signal_newc ("properties_changed",
301 G_TYPE_FROM_CLASS (class),
302 G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
303 G_STRUCT_OFFSET (GObjectClass, properties_changed),
304 NULL, /* accumulator */
305 g_cclosure_marshal_VOID__UINT_POINTER,
307 2, G_TYPE_UINT, G_TYPE_POINTER);
308 gobject_signals[NOTIFY] =
309 g_signal_newc ("notify",
310 G_TYPE_FROM_CLASS (class),
311 G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED | G_SIGNAL_NO_HOOKS,
312 G_STRUCT_OFFSET (GObjectClass, notify),
313 NULL, /* accumulator */
314 g_cclosure_marshal_VOID__PARAM,
320 g_object_class_install_property (GObjectClass *class,
326 g_return_if_fail (G_IS_OBJECT_CLASS (class));
327 g_return_if_fail (G_IS_PARAM_SPEC (pspec));
328 if (pspec->flags & G_PARAM_WRITABLE)
329 g_return_if_fail (class->set_property != NULL);
330 if (pspec->flags & G_PARAM_READABLE)
331 g_return_if_fail (class->get_property != NULL);
332 g_return_if_fail (property_id > 0);
333 g_return_if_fail (PARAM_SPEC_PARAM_ID (pspec) == 0); /* paranoid */
334 if (pspec->flags & G_PARAM_CONSTRUCT)
335 g_return_if_fail ((pspec->flags & G_PARAM_CONSTRUCT_ONLY) == 0);
336 if (pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY))
337 g_return_if_fail (pspec->flags & G_PARAM_WRITABLE);
339 /* expensive paranoia checks ;( */
340 for (i = 0; i < class->n_property_specs; i++)
341 if (PARAM_SPEC_PARAM_ID (class->property_specs[i]) == property_id)
343 g_warning (G_STRLOC ": class `%s' already contains a property `%s' with id %u, "
344 "cannot install property `%s'",
345 G_OBJECT_CLASS_NAME (class),
346 class->property_specs[i]->name,
351 if (g_param_spec_pool_lookup (pspec_pool, pspec->name, G_OBJECT_CLASS_TYPE (class), FALSE, NULL))
353 g_warning (G_STRLOC ": class `%s' already contains a property named `%s'",
354 G_OBJECT_CLASS_NAME (class),
359 g_param_spec_ref (pspec);
360 g_param_spec_sink (pspec);
361 g_param_spec_set_qdata (pspec, quark_property_id, GUINT_TO_POINTER (property_id));
362 g_param_spec_pool_insert (pspec_pool, pspec, G_OBJECT_CLASS_TYPE (class));
363 i = class->n_property_specs++;
364 class->property_specs = g_renew (GParamSpec*, class->property_specs, class->n_property_specs);
365 class->property_specs[i] = pspec;
366 if (pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY))
367 class->construct_properties = g_slist_prepend (class->construct_properties, pspec);
369 /* for property overrides of construct poperties, we have to get rid
370 * of the overidden inherited construct property
372 pspec = g_param_spec_pool_lookup (pspec_pool, pspec->name, g_type_parent (G_OBJECT_CLASS_TYPE (class)), TRUE, NULL);
373 if (pspec && pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY))
374 class->construct_properties = g_slist_remove (class->construct_properties, pspec);
378 g_object_class_find_property (GObjectClass *class,
379 const gchar *property_name)
381 g_return_val_if_fail (G_IS_OBJECT_CLASS (class), NULL);
382 g_return_val_if_fail (property_name != NULL, NULL);
384 return g_param_spec_pool_lookup (pspec_pool,
386 G_OBJECT_CLASS_TYPE (class),
391 free_notify_queue (gpointer data)
393 NotifyQueue *nqueue = data;
395 g_slist_free (nqueue->pspecs);
399 static inline NotifyQueue*
400 object_freeze_notifies (GObject *object)
404 nqueue = g_object_get_qdata (object, quark_notify_queue);
407 nqueue = g_new0 (NotifyQueue, 1);
408 g_object_set_qdata_full (object, quark_notify_queue, nqueue, free_notify_queue);
410 nqueue->freeze_count++;
416 object_queue_property (GObject *object,
420 /* we will dedup later */
421 nqueue->pspecs = g_slist_prepend (nqueue->pspecs, pspec);
426 g_object_init (GObject *object)
428 object->ref_count = 1;
429 g_datalist_init (&object->qdata);
431 /* freeze object's notification queue, g_object_new_valist() takes care of that */
432 object_freeze_notifies (object);
434 #ifdef G_ENABLE_DEBUG
435 if (glib_debug_objects)
437 if (!debug_objects_ht)
438 debug_objects_ht = g_hash_table_new (g_direct_hash, NULL);
439 debug_objects_count++;
440 g_hash_table_insert (debug_objects_ht, object, object);
442 #endif /* G_ENABLE_DEBUG */
446 g_object_do_set_property (GObject *object,
450 const gchar *trailer)
456 gboolean swapped, after;
457 gpointer callback, data;
459 g_return_if_fail (trailer != NULL);
461 g_object_set_data (object, trailer, g_value_get_pointer (value));
463 case PROP_SWAPPED_SIGNAL_AFTER:
465 case PROP_SIGNAL_AFTER:
467 case PROP_SWAPPED_SIGNAL:
472 g_return_if_fail (trailer != NULL);
474 g_value_get_ccallback (value, &callback, &data);
475 g_signal_connect_data (object, trailer,
476 callback, data, NULL,
480 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
486 g_object_do_get_property (GObject *object,
490 const gchar *trailer)
495 g_return_if_fail (trailer != NULL);
497 g_value_set_pointer (value, g_object_get_data (object, trailer));
500 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
506 g_object_last_unref (GObject *object)
508 g_return_if_fail (object->ref_count > 0);
510 if (object->ref_count == 1) /* may have been re-referenced meanwhile */
511 G_OBJECT_GET_CLASS (object)->shutdown (object);
513 #ifdef G_ENABLE_DEBUG
514 if (glib_trap_object_ref == object)
516 #endif /* G_ENABLE_DEBUG */
518 object->ref_count -= 1;
520 if (object->ref_count == 0) /* may have been re-referenced meanwhile */
522 G_OBJECT_GET_CLASS (object)->finalize (object);
523 #ifdef G_ENABLE_DEBUG
524 if (glib_debug_objects && debug_objects_ht)
525 g_assert (g_hash_table_lookup (debug_objects_ht, object) == NULL);
526 #endif /* G_ENABLE_DEBUG */
527 g_type_free_instance ((GTypeInstance*) object);
532 g_object_shutdown (GObject *object)
534 /* this function needs to be always present for unconditional
535 * chaining, we also might add some code here later.
536 * beware though, subclasses may invoke shutdown() arbitrarily.
541 g_object_finalize (GObject *object)
543 g_signal_handlers_destroy (object);
544 g_datalist_clear (&object->qdata);
546 #ifdef G_ENABLE_DEBUG
547 if (glib_debug_objects)
549 g_assert (g_hash_table_lookup (debug_objects_ht, object) == object);
551 g_hash_table_remove (debug_objects_ht, object);
552 debug_objects_count--;
554 #endif /* G_ENABLE_DEBUG */
558 object_thaw_notifies (GObject *object,
565 nqueue->freeze_count--;
566 if (nqueue->freeze_count)
568 g_return_if_fail (object->ref_count > 0);
570 pspecs = g_new (GParamSpec*, nqueue->n_pspecs);
571 for (slist = nqueue->pspecs; slist; slist = slist->next)
573 GParamSpec *pspec = slist->data;
576 /* dedup, make pspecs in the list unique */
578 if (pspecs[i] == pspec)
581 goto redo_dedup_check;
583 pspecs[n_pspecs++] = pspec;
585 g_object_set_qdata (object, quark_notify_queue, NULL);
588 G_OBJECT_GET_CLASS (object)->dispatch_properties_changed (object, n_pspecs, pspecs);
594 g_object_dispatch_properties_changed (GObject *object,
598 g_signal_emit (object, gobject_signals[PROPERTIES_CHANGED], 0, n_pspecs, pspecs);
602 g_object_properties_changed (GObject *object,
608 for (i = 0; i < n_pspecs; i++)
609 g_signal_emit (object, gobject_signals[NOTIFY], g_quark_from_string (pspecs[i]->name), pspecs[i]);
613 g_object_notify_property_changed (GObject *object,
617 g_message ("NOTIFICATION: property `%s' changed on object `%s'",
619 G_OBJECT_TYPE_NAME (object));
623 g_object_freeze_notify (GObject *object)
625 g_return_if_fail (G_IS_OBJECT (object));
626 if (!object->ref_count)
629 g_object_ref (object);
630 object_freeze_notifies (object);
631 g_object_unref (object);
635 g_object_notify (GObject *object,
636 const gchar *property_name)
640 g_return_if_fail (G_IS_OBJECT (object));
641 g_return_if_fail (property_name != NULL);
642 if (!object->ref_count)
645 g_object_ref (object);
646 pspec = g_param_spec_pool_lookup (pspec_pool,
648 G_OBJECT_TYPE (object),
651 g_warning ("%s: object class `%s' has no property named `%s'",
653 G_OBJECT_TYPE_NAME (object),
657 NotifyQueue *nqueue = object_freeze_notifies (object);
659 object_queue_property (object, pspec, nqueue);
660 object_thaw_notifies (object, nqueue);
662 g_object_unref (object);
666 g_object_thaw_notify (GObject *object)
670 g_return_if_fail (G_IS_OBJECT (object));
671 if (!object->ref_count)
674 g_object_ref (object);
675 nqueue = g_object_get_qdata (object, quark_notify_queue);
676 if (!nqueue || !nqueue->freeze_count)
677 g_warning (G_STRLOC ": property-changed notification for %s(%p) is not frozen",
678 G_OBJECT_TYPE_NAME (object), object);
680 object_thaw_notifies (object, nqueue);
681 g_object_unref (object);
685 object_get_property (GObject *object,
688 const gchar *trailer)
692 g_return_if_fail (g_type_is_a (G_OBJECT_TYPE (object), pspec->owner_type)); /* paranoid */
694 class = g_type_class_peek (pspec->owner_type);
696 class->get_property (object, PARAM_SPEC_PARAM_ID (pspec), value, pspec, trailer);
700 object_set_property (GObject *object,
703 const gchar *trailer,
708 g_return_if_fail (g_type_is_a (G_OBJECT_TYPE (object), pspec->owner_type)); /* paranoid */
710 class = g_type_class_peek (pspec->owner_type);
712 class->set_property (object, PARAM_SPEC_PARAM_ID (pspec), value, pspec, trailer);
713 object_queue_property (object, pspec, nqueue);
717 g_object_new (GType object_type,
718 const gchar *first_property_name,
724 g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type), NULL);
726 va_start (var_args, first_property_name);
727 object = g_object_new_valist (object_type, first_property_name, var_args);
734 g_object_new_valist (GType object_type,
735 const gchar *first_property_name,
742 GObjectConstructParam *cparams = NULL, *nparams = NULL;
743 guint n_cparams = 0, n_nparams = 0;
746 g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type), NULL);
748 class = g_type_class_ref (object_type);
749 clist = g_slist_copy (class->construct_properties);
751 /* collect parameters, sort into construction and normal ones */
752 name = first_property_name;
755 const gchar *trailer = NULL;
760 pspec = g_param_spec_pool_lookup (pspec_pool,
767 g_warning ("%s: object class `%s' has no property named `%s'",
769 g_type_name (object_type),
773 if (!(pspec->flags & G_PARAM_WRITABLE))
775 g_warning ("%s: property `%s' of object class `%s' is not writable",
778 g_type_name (object_type));
782 value = g_new (GValue, 1);
784 g_value_init (value, G_PARAM_SPEC_VALUE_TYPE (pspec));
785 G_VALUE_COLLECT (value, var_args, &error);
788 g_warning ("%s: %s", G_STRLOC, error);
791 /* we purposely leak the value here, it might not be
792 * in a sane state if an error condition occoured
796 if (pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY))
800 if (!n_cparams || n_cparams >= PREALLOC_CPARAMS)
801 cparams = g_renew (GObjectConstructParam, cparams, MAX (n_cparams + 1, PREALLOC_CPARAMS));
802 cparams[n_cparams].pspec = pspec;
803 cparams[n_cparams].value = value;
804 cparams[n_cparams].trailer = trailer;
805 for (i = 0; i < n_cparams; i++) /* picky, aren't we? ;) */
806 if (cparams[i].pspec == pspec)
807 g_warning (G_STRLOC ": construct property \"%s\" for object `%s' is being set twice",
808 pspec->name, g_type_name (object_type));
810 clist = g_slist_remove (clist, pspec); /* FIXME: unique */
814 if (!n_nparams || n_nparams >= PREALLOC_CPARAMS)
815 nparams = g_renew (GObjectConstructParam, nparams, MAX (n_nparams + 1, PREALLOC_CPARAMS));
816 nparams[n_nparams].pspec = pspec;
817 nparams[n_nparams].value = value;
818 nparams[n_nparams].trailer = trailer;
822 name = va_arg (var_args, gchar*);
825 /* construct object from construction parameters */
828 GSList *tmp = clist->next;
829 GParamSpec *pspec = clist->data;
830 GValue *value = g_new (GValue, 1);
833 g_value_init (value, G_PARAM_SPEC_VALUE_TYPE (pspec));
834 g_param_value_set_default (pspec, value);
836 if (!n_cparams || n_cparams >= PREALLOC_CPARAMS)
837 cparams = g_renew (GObjectConstructParam, cparams, MAX (n_cparams + 1, PREALLOC_CPARAMS));
838 cparams[n_cparams].pspec = pspec;
839 cparams[n_cparams].value = value;
840 cparams[n_cparams].trailer = NULL;
843 g_slist_free_1 (clist);
846 object = class->constructor (object_type, n_cparams, cparams);
848 /* free construction values */
851 g_value_unset (cparams[n_cparams].value);
852 g_free (cparams[n_cparams].value);
856 /* release g_object_init() notification queue freeze_count */
857 nqueue = object_freeze_notifies (object);
858 nqueue->freeze_count--;
860 /* set remaining properties */
864 GValue *value = nparams->value;
865 GParamSpec *pspec = nparams->pspec;
866 const gchar *trailer = nparams++->trailer;
868 /* convert if necessary */
869 if (!g_type_is_a (G_VALUE_TYPE (value), G_PARAM_SPEC_VALUE_TYPE (pspec)))
871 GValue tmp_value = { 0, };
873 g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
874 if (!g_value_convert (value, &tmp_value) ||
875 g_param_value_validate (pspec, &tmp_value))
876 g_warning ("%s: cannot convert `%s' value to property `%s' value of type `%s'",
878 G_VALUE_TYPE_NAME (value),
880 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)));
882 object_set_property (object, &tmp_value, pspec, trailer, nqueue);
883 g_value_unset (&tmp_value);
886 object_set_property (object, value, pspec, trailer, nqueue);
888 g_value_unset (value);
893 g_type_class_unref (class);
895 /* release our own freeze count and handle notifications */
896 object_thaw_notifies (object, nqueue);
902 g_object_constructor (GType type,
903 guint n_construct_properties,
904 GObjectConstructParam *construct_params)
909 object = (GObject*) g_type_create_instance (type);
911 /* set construction parameters */
912 if (n_construct_properties)
914 NotifyQueue *nqueue = object_freeze_notifies (object);
916 /* set construct properties */
917 while (n_construct_properties--)
919 GValue *value = construct_params->value;
920 GParamSpec *pspec = construct_params->pspec;
921 const gchar *trailer = construct_params++->trailer;
923 /* convert if necessary */
924 if (!g_type_is_a (G_VALUE_TYPE (value), G_PARAM_SPEC_VALUE_TYPE (pspec)))
926 GValue tmp_value = { 0, };
928 g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
929 if (!g_value_convert (value, &tmp_value) ||
930 g_param_value_validate (pspec, &tmp_value))
931 g_warning ("%s: cannot convert `%s' value to property `%s' value of type `%s'",
933 G_VALUE_TYPE_NAME (value),
935 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)));
937 object_set_property (object, &tmp_value, pspec, trailer, nqueue);
938 g_value_unset (&tmp_value);
941 object_set_property (object, value, pspec, trailer, nqueue);
943 nqueue->freeze_count--;
944 /* the notification queue is still frozen from g_object_init(), so
945 * we don't need to handle it here, g_object_new_valist() takes
954 g_object_set_valist (GObject *object,
955 const gchar *first_property_name,
961 g_return_if_fail (G_IS_OBJECT (object));
963 g_object_ref (object);
964 nqueue = object_freeze_notifies (object);
966 name = first_property_name;
969 const gchar *trailer = NULL;
970 GValue value = { 0, };
974 pspec = g_param_spec_pool_lookup (pspec_pool,
976 G_OBJECT_TYPE (object),
981 g_warning ("%s: object class `%s' has no property named `%s'",
983 G_OBJECT_TYPE_NAME (object),
987 if (!(pspec->flags & G_PARAM_WRITABLE))
989 g_warning ("%s: property `%s' of object class `%s' is not writable",
992 G_OBJECT_TYPE_NAME (object));
996 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
998 G_VALUE_COLLECT (&value, var_args, &error);
1001 g_warning ("%s: %s", G_STRLOC, error);
1004 /* we purposely leak the value here, it might not be
1005 * in a sane state if an error condition occoured
1010 object_set_property (object, &value, pspec, trailer, nqueue);
1012 g_value_unset (&value);
1014 name = va_arg (var_args, gchar*);
1017 object_thaw_notifies (object, nqueue);
1018 g_object_unref (object);
1022 g_object_get_valist (GObject *object,
1023 const gchar *first_property_name,
1028 g_return_if_fail (G_IS_OBJECT (object));
1030 g_object_ref (object);
1032 name = first_property_name;
1036 const gchar *trailer = NULL;
1037 GValue value = { 0, };
1041 pspec = g_param_spec_pool_lookup (pspec_pool,
1043 G_OBJECT_TYPE (object),
1048 g_warning ("%s: object class `%s' has no property named `%s'",
1050 G_OBJECT_TYPE_NAME (object),
1054 if (!(pspec->flags & G_PARAM_READABLE))
1056 g_warning ("%s: property `%s' of object class `%s' is not readable",
1059 G_OBJECT_TYPE_NAME (object));
1063 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
1065 object_get_property (object, &value, pspec, trailer);
1067 G_VALUE_LCOPY (&value, var_args, &error);
1070 g_warning ("%s: %s", G_STRLOC, error);
1073 /* we purposely leak the value here, it might not be
1074 * in a sane state if an error condition occoured
1079 g_value_unset (&value);
1081 name = va_arg (var_args, gchar*);
1084 g_object_unref (object);
1088 g_object_set (gpointer _object,
1089 const gchar *first_property_name,
1092 GObject *object = _object;
1095 g_return_if_fail (G_IS_OBJECT (object));
1097 va_start (var_args, first_property_name);
1098 g_object_set_valist (object, first_property_name, var_args);
1103 g_object_get (gpointer _object,
1104 const gchar *first_property_name,
1107 GObject *object = _object;
1110 g_return_if_fail (G_IS_OBJECT (object));
1112 va_start (var_args, first_property_name);
1113 g_object_get_valist (object, first_property_name, var_args);
1118 g_object_set_property (GObject *object,
1119 const gchar *property_name,
1120 const GValue *value)
1122 NotifyQueue *nqueue;
1124 const gchar *trailer;
1126 g_return_if_fail (G_IS_OBJECT (object));
1127 g_return_if_fail (property_name != NULL);
1128 g_return_if_fail (G_IS_VALUE (value));
1130 g_object_ref (object);
1131 nqueue = object_freeze_notifies (object);
1133 pspec = g_param_spec_pool_lookup (pspec_pool,
1135 G_OBJECT_TYPE (object),
1139 g_warning ("%s: object class `%s' has no property named `%s'",
1141 G_OBJECT_TYPE_NAME (object),
1145 GValue tmp_value = { 0, };
1147 /* provide a copy to work from and convert if necessary */
1148 g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
1150 if (!g_value_convert (value, &tmp_value) ||
1151 g_param_value_validate (pspec, &tmp_value))
1152 g_warning ("%s: cannot convert `%s' value to property `%s' value of type `%s'",
1154 G_VALUE_TYPE_NAME (value),
1156 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)));
1158 object_set_property (object, &tmp_value, pspec, trailer, nqueue);
1160 g_value_unset (&tmp_value);
1163 object_thaw_notifies (object, nqueue);
1164 g_object_unref (object);
1168 g_object_get_property (GObject *object,
1169 const gchar *property_name,
1173 const gchar *trailer;
1175 g_return_if_fail (G_IS_OBJECT (object));
1176 g_return_if_fail (property_name != NULL);
1177 g_return_if_fail (G_IS_VALUE (value));
1179 g_object_ref (object);
1181 pspec = g_param_spec_pool_lookup (pspec_pool,
1183 G_OBJECT_TYPE (object),
1187 g_warning ("%s: object class `%s' has no property named `%s'",
1189 G_OBJECT_TYPE_NAME (object),
1193 GValue tmp_value = { 0, };
1195 /* provide a copy to work from and later convert if necessary, so
1196 * _get_property() implementations need *not* care about freeing values
1197 * that might be already set in the property to get.
1198 * (though, at this point, GValue should exclusively be modified
1199 * through the accessor functions anyways)
1201 g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
1203 if (!g_value_types_exchangable (G_VALUE_TYPE (value), G_PARAM_SPEC_VALUE_TYPE (pspec)))
1204 g_warning ("%s: can't retrive property `%s' value of type `%s' as value of type `%s'",
1207 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1208 G_VALUE_TYPE_NAME (value));
1211 object_get_property (object, &tmp_value, pspec, trailer);
1212 g_value_convert (&tmp_value, value);
1213 /* g_value_validate (value, pspec); */
1216 g_value_unset (&tmp_value);
1219 g_object_unref (object);
1223 g_object_ref (gpointer _object)
1225 GObject *object = _object;
1227 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1228 g_return_val_if_fail (object->ref_count > 0, NULL);
1230 #ifdef G_ENABLE_DEBUG
1231 if (glib_trap_object_ref == object)
1233 #endif /* G_ENABLE_DEBUG */
1235 object->ref_count += 1;
1241 g_object_unref (gpointer _object)
1243 GObject *object = _object;
1245 g_return_if_fail (G_IS_OBJECT (object));
1246 g_return_if_fail (object->ref_count > 0);
1248 #ifdef G_ENABLE_DEBUG
1249 if (glib_trap_object_ref == object)
1251 #endif /* G_ENABLE_DEBUG */
1253 if (object->ref_count > 1)
1254 object->ref_count -= 1;
1256 g_object_last_unref (object);
1260 g_object_get_qdata (GObject *object,
1263 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1265 return quark ? g_datalist_id_get_data (&object->qdata, quark) : NULL;
1269 g_object_set_qdata (GObject *object,
1273 g_return_if_fail (G_IS_OBJECT (object));
1274 g_return_if_fail (quark > 0);
1276 g_datalist_id_set_data (&object->qdata, quark, data);
1280 g_object_set_qdata_full (GObject *object,
1283 GDestroyNotify destroy)
1285 g_return_if_fail (G_IS_OBJECT (object));
1286 g_return_if_fail (quark > 0);
1288 g_datalist_id_set_data_full (&object->qdata, quark, data, data ? destroy : NULL);
1292 g_object_steal_qdata (GObject *object,
1295 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1296 g_return_val_if_fail (quark > 0, NULL);
1298 return g_datalist_id_remove_no_notify (&object->qdata, quark);
1302 g_object_get_data (GObject *object,
1307 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1308 g_return_val_if_fail (key != NULL, NULL);
1310 quark = g_quark_try_string (key);
1312 return quark ? g_datalist_id_get_data (&object->qdata, quark) : NULL;
1316 g_object_set_data (GObject *object,
1320 g_return_if_fail (G_IS_OBJECT (object));
1321 g_return_if_fail (key != NULL);
1323 g_datalist_id_set_data (&object->qdata, g_quark_from_string (key), data);
1327 g_object_set_data_full (GObject *object,
1330 GDestroyNotify destroy)
1332 g_return_if_fail (G_IS_OBJECT (object));
1333 g_return_if_fail (key != NULL);
1335 g_datalist_id_set_data_full (&object->qdata, g_quark_from_string (key), data, data ? destroy : NULL);
1339 g_object_steal_data (GObject *object,
1344 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1345 g_return_val_if_fail (key != NULL, NULL);
1347 quark = g_quark_try_string (key);
1349 return quark ? g_datalist_id_remove_no_notify (&object->qdata, quark) : NULL;
1353 g_value_object_init (GValue *value)
1355 value->data[0].v_pointer = NULL;
1359 g_value_object_free_value (GValue *value)
1361 if (value->data[0].v_pointer)
1362 g_object_unref (value->data[0].v_pointer);
1366 g_value_object_copy_value (const GValue *src_value,
1369 if (src_value->data[0].v_pointer)
1370 dest_value->data[0].v_pointer = g_object_ref (src_value->data[0].v_pointer);
1372 dest_value->data[0].v_pointer = NULL;
1376 g_value_object_peek_pointer (const GValue *value)
1378 return value->data[0].v_pointer;
1382 g_value_object_collect_value (GValue *value,
1384 GType *collect_type,
1385 GTypeCValue *collect_value)
1387 if (collect_value->v_pointer)
1389 GObject *object = collect_value->v_pointer;
1391 if (object->g_type_instance.g_class == NULL)
1392 return g_strconcat ("invalid unclassed object pointer for value type `",
1393 G_VALUE_TYPE_NAME (value),
1396 else if (!g_type_is_a (G_OBJECT_TYPE (object), G_VALUE_TYPE (value)))
1397 return g_strconcat ("invalid object type `",
1398 G_OBJECT_TYPE_NAME (object),
1399 "' for value type `",
1400 G_VALUE_TYPE_NAME (value),
1403 value->data[0].v_pointer = g_object_ref (object);
1406 value->data[0].v_pointer = NULL;
1413 g_value_object_lcopy_value (const GValue *value,
1415 GType *collect_type,
1416 GTypeCValue *collect_value)
1418 GObject **object_p = collect_value->v_pointer;
1421 return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
1423 *object_p = value->data[0].v_pointer ? g_object_ref (value->data[0].v_pointer) : NULL;
1430 g_value_set_object (GValue *value,
1433 g_return_if_fail (G_IS_VALUE_OBJECT (value));
1435 if (value->data[0].v_pointer)
1437 g_object_unref (value->data[0].v_pointer);
1438 value->data[0].v_pointer = NULL;
1443 g_return_if_fail (G_IS_OBJECT (v_object));
1444 g_return_if_fail (g_type_is_a (G_OBJECT_TYPE (v_object), G_VALUE_TYPE (value)));
1446 value->data[0].v_pointer = v_object;
1447 g_object_ref (value->data[0].v_pointer);
1452 g_value_get_object (const GValue *value)
1454 g_return_val_if_fail (G_IS_VALUE_OBJECT (value), NULL);
1456 return value->data[0].v_pointer;
1460 g_value_dup_object (const GValue *value)
1462 g_return_val_if_fail (G_IS_VALUE_OBJECT (value), NULL);
1464 return value->data[0].v_pointer ? g_object_ref (value->data[0].v_pointer) : NULL;
1468 g_signal_connect_object (gpointer instance,
1469 const gchar *detailed_signal,
1470 GCallback c_handler,
1475 g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
1476 g_return_val_if_fail (detailed_signal != NULL, 0);
1477 g_return_val_if_fail (c_handler != NULL, 0);
1483 g_return_val_if_fail (G_IS_OBJECT (gobject), 0);
1485 closure = (swapped ? g_cclosure_new_object_swap : g_cclosure_new_object) (c_handler, gobject);
1487 return g_signal_connect_closure (instance, detailed_signal, closure, after);
1490 return g_signal_connect_data (instance, detailed_signal, c_handler, NULL, NULL, swapped, after);
1496 GClosure *closures[1]; /* flexible array */
1500 object_remove_closure (gpointer data,
1503 GObject *object = data;
1504 CArray *carray = g_object_get_qdata (object, quark_closure_array);
1507 for (i = 0; i < carray->n_closures; i++)
1508 if (carray->closures[i] == closure)
1510 carray->n_closures--;
1511 if (i < carray->n_closures)
1512 carray->closures[i] = carray->closures[carray->n_closures];
1515 g_assert_not_reached ();
1519 destroy_closure_array (gpointer data)
1521 CArray *carray = data;
1522 GObject *object = carray->object;
1523 guint i, n = carray->n_closures;
1525 for (i = 0; i < n; i++)
1527 GClosure *closure = carray->closures[i];
1529 /* removing object_remove_closure() upfront is probably faster than
1530 * letting it fiddle with quark_closure_array which is empty anyways
1532 g_closure_remove_inotify (closure, object, object_remove_closure);
1533 g_closure_invalidate (closure);
1539 g_object_watch_closure (GObject *object,
1544 g_return_if_fail (G_IS_OBJECT (object));
1545 g_return_if_fail (closure != NULL);
1546 g_return_if_fail (closure->is_invalid == FALSE);
1547 g_return_if_fail (closure->in_marshal == FALSE);
1548 g_return_if_fail (object->ref_count > 0); /* this doesn't work on finalizing objects */
1550 g_closure_add_inotify (closure, object, object_remove_closure);
1551 g_closure_add_marshal_guards (closure,
1552 object, (GClosureNotify) g_object_ref,
1553 object, (GClosureNotify) g_object_unref);
1554 carray = g_object_steal_qdata (object, quark_closure_array);
1557 carray = g_renew (CArray, NULL, 1);
1558 carray->object = object;
1559 carray->n_closures = 1;
1560 carray->closures[0] = closure;
1561 g_object_set_qdata_full (object, quark_closure_array, carray, destroy_closure_array);
1565 guint i = carray->n_closures++;
1567 carray = g_realloc (carray, sizeof (*carray) + sizeof (carray->closures[0]) * i);
1568 carray->closures[i] = closure;
1569 g_object_set_qdata_full (object, quark_closure_array, carray, destroy_closure_array);
1574 g_closure_new_object (guint sizeof_closure,
1579 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1580 g_return_val_if_fail (object->ref_count > 0, NULL); /* this doesn't work on finalizing objects */
1582 closure = g_closure_new_simple (sizeof_closure, object);
1583 g_object_watch_closure (object, closure);
1589 g_cclosure_new_object (GCallback callback_func,
1592 GObject *object = _object;
1595 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1596 g_return_val_if_fail (object->ref_count > 0, NULL); /* this doesn't work on finalizing objects */
1597 g_return_val_if_fail (callback_func != NULL, NULL);
1599 closure = g_cclosure_new (callback_func, object, NULL);
1600 g_object_watch_closure (object, closure);
1606 g_cclosure_new_object_swap (GCallback callback_func,
1609 GObject *object = _object;
1612 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1613 g_return_val_if_fail (object->ref_count > 0, NULL); /* this doesn't work on finalizing objects */
1614 g_return_val_if_fail (callback_func != NULL, NULL);
1616 closure = g_cclosure_new_swap (callback_func, object, NULL);
1617 g_object_watch_closure (object, closure);