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)
34 #define PARAM_SPEC_PARAM_ID(pspec) (GPOINTER_TO_UINT (g_param_spec_get_qdata ((pspec), quark_property_id)))
45 /* --- properties --- */
52 PROP_SWAPPED_SIGNAL_AFTER
56 /* --- typedefs --- */
57 typedef struct _NotifyQueue NotifyQueue;
60 /* --- prototypes --- */
61 static void g_object_base_class_init (GObjectClass *class);
62 static void g_object_base_class_finalize (GObjectClass *class);
63 static void g_object_do_class_init (GObjectClass *class);
64 static void g_object_init (GObject *object);
65 static GObject* g_object_constructor (GType type,
66 guint n_construct_properties,
67 GObjectConstructParam *construct_params);
68 static void g_object_last_unref (GObject *object);
69 static void g_object_shutdown (GObject *object);
70 static void g_object_finalize (GObject *object);
71 static void g_object_do_set_property (GObject *object,
75 const gchar *trailer);
76 static void g_object_do_get_property (GObject *object,
80 const gchar *trailer);
81 static void g_value_object_init (GValue *value);
82 static void g_value_object_free_value (GValue *value);
83 static void g_value_object_copy_value (const GValue *src_value,
85 static gpointer g_value_object_peek_pointer (const GValue *value);
86 static gchar* g_value_object_collect_value (GValue *value,
89 GTypeCValue *collect_value);
90 static gchar* g_value_object_lcopy_value (const GValue *value,
93 GTypeCValue *collect_value);
94 static void g_object_dispatch_properties_changed (GObject *object,
97 static void g_object_properties_changed (GObject *object,
100 static void g_object_notify_property_changed (GObject *object,
102 static inline NotifyQueue* object_freeze_notifies (GObject *object);
103 static inline void object_queue_property (GObject *object,
105 NotifyQueue *nqueue);
106 static inline void object_thaw_notifies (GObject *object,
107 NotifyQueue *nqueue);
108 static inline void object_get_property (GObject *object,
111 const gchar *trailer);
112 static inline void object_set_property (GObject *object,
115 const gchar *trailer,
116 NotifyQueue *nqueue);
119 /* --- structures --- */
128 /* --- variables --- */
129 static GQuark quark_notify_queue = 0;
130 static GQuark quark_property_id = 0;
131 static GQuark quark_closure_array = 0;
132 static GParamSpecPool *pspec_pool = NULL;
133 static gulong gobject_signals[LAST_SIGNAL] = { 0, };
136 /* --- functions --- */
139 /* We need an actual method for handling debug keys in GLib.
140 * For now, we'll simply use, as a method
141 * 'extern gboolean glib_debug_objects'
143 gboolean glib_debug_objects = FALSE;
145 static guint debug_objects_count = 0;
146 static GHashTable *debug_objects_ht = NULL;
148 debug_objects_foreach (gpointer key,
152 GObject *object = value;
154 g_message ("[%p] stale %s\tref_count=%u",
156 G_OBJECT_TYPE_NAME (object),
160 debug_objects_atexit (void)
162 if (glib_debug_objects)
164 if (debug_objects_ht)
166 g_message ("stale GObjects: %u", debug_objects_count);
167 g_hash_table_foreach (debug_objects_ht, debug_objects_foreach, NULL);
171 #endif /* DEBUG_OBJECTS */
174 g_object_type_init (void) /* sync with gtype.c */
176 static gboolean initialized = FALSE;
177 static const GTypeFundamentalInfo finfo = {
178 G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE,
180 static GTypeInfo info = {
181 sizeof (GObjectClass),
182 (GBaseInitFunc) g_object_base_class_init,
183 (GBaseFinalizeFunc) g_object_base_class_finalize,
184 (GClassInitFunc) g_object_do_class_init,
185 NULL /* class_destroy */,
186 NULL /* class_data */,
189 (GInstanceInitFunc) g_object_init,
190 NULL, /* value_table */
192 static const GTypeValueTable value_table = {
193 g_value_object_init, /* value_init */
194 g_value_object_free_value, /* value_free */
195 g_value_object_copy_value, /* value_copy */
196 g_value_object_peek_pointer, /* value_peek_pointer */
197 G_VALUE_COLLECT_POINTER, /* collect_type */
198 g_value_object_collect_value, /* collect_value */
199 G_VALUE_COLLECT_POINTER, /* lcopy_type */
200 g_value_object_lcopy_value, /* lcopy_value */
204 g_return_if_fail (initialized == FALSE);
209 info.value_table = &value_table;
210 type = g_type_register_fundamental (G_TYPE_OBJECT, "GObject", &info, &finfo, 0);
211 g_assert (type == G_TYPE_OBJECT);
214 g_atexit (debug_objects_atexit);
215 #endif /* DEBUG_OBJECTS */
219 g_object_base_class_init (GObjectClass *class)
221 GObjectClass *pclass = g_type_class_peek_parent (class);
223 /* reset instance specific fields and methods that don't get inherited */
224 class->n_property_specs = 0;
225 class->property_specs = NULL;
226 class->construct_properties = pclass ? g_slist_copy (pclass->construct_properties) : NULL;
227 class->get_property = NULL;
228 class->set_property = NULL;
232 g_object_base_class_finalize (GObjectClass *class)
236 g_message ("finallizing base class of %s", G_OBJECT_CLASS_NAME (class));
238 _g_signals_destroy (G_OBJECT_CLASS_TYPE (class));
240 g_slist_free (class->construct_properties);
241 class->construct_properties = NULL;
242 for (i = 0; i < class->n_property_specs; i++)
244 GParamSpec *pspec = class->property_specs[i];
246 g_param_spec_pool_remove (pspec_pool, pspec);
247 g_param_spec_set_qdata (pspec, quark_property_id, NULL);
248 g_param_spec_unref (pspec);
250 class->n_property_specs = 0;
251 g_free (class->property_specs);
252 class->property_specs = NULL;
256 g_object_do_class_init (GObjectClass *class)
258 quark_notify_queue = g_quark_from_static_string ("GObject-notify-queue");
259 quark_property_id = g_quark_from_static_string ("GObject-property-id");
260 quark_closure_array = g_quark_from_static_string ("GObject-closure-array");
261 pspec_pool = g_param_spec_pool_new (TRUE);
263 class->constructor = g_object_constructor;
264 class->set_property = g_object_do_set_property;
265 class->get_property = g_object_do_get_property;
266 class->shutdown = g_object_shutdown;
267 class->finalize = g_object_finalize;
268 class->dispatch_properties_changed = g_object_dispatch_properties_changed;
269 class->properties_changed = g_object_properties_changed;
270 class->notify = g_object_notify_property_changed;
272 g_object_class_install_property (class,
274 g_param_spec_pointer ("data", "Named Data",
275 "Named anonymous pointers",
276 G_PARAM_READABLE | G_PARAM_WRITABLE));
277 g_object_class_install_property (class,
279 g_param_spec_ccallback ("signal", "Signal Connection",
280 "Signal connection consisting of a callback function "
281 "and a data pointer",
283 g_object_class_install_property (class,
285 g_param_spec_ccallback ("swapped_signal", "Swapped Signal Connection",
286 "Signal connection consisting of a callback function "
287 "and a data pointer",
289 g_object_class_install_property (class,
291 g_param_spec_ccallback ("signal_after", "Signal After Connection",
292 "Signal connection consisting of a callback function "
293 "and a data pointer",
295 g_object_class_install_property (class,
296 PROP_SWAPPED_SIGNAL_AFTER,
297 g_param_spec_ccallback ("swapped_signal_after", "Swapped Signal After Connection",
298 "Signal connection consisting of a callback function "
299 "and a data pointer",
301 gobject_signals[PROPERTIES_CHANGED] =
302 g_signal_new ("properties_changed",
303 G_TYPE_FROM_CLASS (class),
304 G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
305 g_signal_type_cclosure_new (G_TYPE_FROM_CLASS (class),
306 G_STRUCT_OFFSET (GObjectClass, properties_changed)),
307 NULL, /* accumulator */
308 g_cclosure_marshal_VOID__UINT_POINTER,
310 2, G_TYPE_UINT, G_TYPE_POINTER);
311 gobject_signals[NOTIFY] =
312 g_signal_new ("notify",
313 G_TYPE_FROM_CLASS (class),
314 G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED | G_SIGNAL_NO_HOOKS,
315 g_signal_type_cclosure_new (G_TYPE_FROM_CLASS (class),
316 G_STRUCT_OFFSET (GObjectClass, notify)),
317 NULL, /* accumulator */
318 g_cclosure_marshal_VOID__PARAM,
324 g_object_class_install_property (GObjectClass *class,
330 g_return_if_fail (G_IS_OBJECT_CLASS (class));
331 g_return_if_fail (G_IS_PARAM_SPEC (pspec));
332 if (pspec->flags & G_PARAM_WRITABLE)
333 g_return_if_fail (class->set_property != NULL);
334 if (pspec->flags & G_PARAM_READABLE)
335 g_return_if_fail (class->get_property != NULL);
336 g_return_if_fail (property_id > 0);
337 g_return_if_fail (PARAM_SPEC_PARAM_ID (pspec) == 0); /* paranoid */
338 if (pspec->flags & G_PARAM_CONSTRUCT)
339 g_return_if_fail ((pspec->flags & G_PARAM_CONSTRUCT_ONLY) == 0);
340 if (pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY))
341 g_return_if_fail (pspec->flags & G_PARAM_WRITABLE);
343 /* expensive paranoia checks ;( */
344 for (i = 0; i < class->n_property_specs; i++)
345 if (PARAM_SPEC_PARAM_ID (class->property_specs[i]) == property_id)
347 g_warning (G_STRLOC ": class `%s' already contains a property `%s' with id %u, "
348 "cannot install property `%s'",
349 G_OBJECT_CLASS_NAME (class),
350 class->property_specs[i]->name,
355 if (g_param_spec_pool_lookup (pspec_pool, pspec->name, G_OBJECT_CLASS_TYPE (class), FALSE, NULL))
357 g_warning (G_STRLOC ": class `%s' already contains a property named `%s'",
358 G_OBJECT_CLASS_NAME (class),
363 g_param_spec_ref (pspec);
364 g_param_spec_sink (pspec);
365 g_param_spec_set_qdata (pspec, quark_property_id, GUINT_TO_POINTER (property_id));
366 g_param_spec_pool_insert (pspec_pool, pspec, G_OBJECT_CLASS_TYPE (class));
367 i = class->n_property_specs++;
368 class->property_specs = g_renew (GParamSpec*, class->property_specs, class->n_property_specs);
369 class->property_specs[i] = pspec;
370 if (pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY))
371 class->construct_properties = g_slist_prepend (class->construct_properties, pspec);
373 /* for property overrides of construct poperties, we have to get rid
374 * of the overidden inherited construct property
376 pspec = g_param_spec_pool_lookup (pspec_pool, pspec->name, g_type_parent (G_OBJECT_CLASS_TYPE (class)), TRUE, NULL);
377 if (pspec && pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY))
378 class->construct_properties = g_slist_remove (class->construct_properties, pspec);
382 g_object_class_find_property (GObjectClass *class,
383 const gchar *property_name)
385 g_return_val_if_fail (G_IS_OBJECT_CLASS (class), NULL);
386 g_return_val_if_fail (property_name != NULL, NULL);
388 return g_param_spec_pool_lookup (pspec_pool,
390 G_OBJECT_CLASS_TYPE (class),
395 free_notify_queue (gpointer data)
397 NotifyQueue *nqueue = data;
399 g_slist_free (nqueue->pspecs);
403 static inline NotifyQueue*
404 object_freeze_notifies (GObject *object)
408 nqueue = g_object_get_qdata (object, quark_notify_queue);
411 nqueue = g_new0 (NotifyQueue, 1);
412 g_object_set_qdata_full (object, quark_notify_queue, nqueue, free_notify_queue);
414 nqueue->freeze_count++;
420 object_queue_property (GObject *object,
424 /* we will dedup later */
425 nqueue->pspecs = g_slist_prepend (nqueue->pspecs, pspec);
430 g_object_init (GObject *object)
432 object->ref_count = 1;
433 object->qdata = NULL;
435 /* freeze object's notification queue, g_object_new_valist() takes care of that */
436 object_freeze_notifies (object);
439 if (glib_debug_objects)
441 if (!debug_objects_ht)
442 debug_objects_ht = g_hash_table_new (g_direct_hash, NULL);
443 debug_objects_count++;
444 g_hash_table_insert (debug_objects_ht, object, object);
446 #endif /* DEBUG_OBJECTS */
450 g_object_do_set_property (GObject *object,
454 const gchar *trailer)
460 gboolean swapped, after;
461 gpointer callback, data;
463 g_return_if_fail (trailer != NULL);
465 g_object_set_data (object, trailer, g_value_get_pointer (value));
467 case PROP_SWAPPED_SIGNAL_AFTER:
469 case PROP_SIGNAL_AFTER:
471 case PROP_SWAPPED_SIGNAL:
476 g_return_if_fail (trailer != NULL);
478 g_value_get_ccallback (value, &callback, &data);
479 g_signal_connect_data (object, trailer,
480 callback, data, NULL,
484 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
490 g_object_do_get_property (GObject *object,
494 const gchar *trailer)
499 g_return_if_fail (trailer != NULL);
501 g_value_set_pointer (value, g_object_get_data (object, trailer));
504 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
510 g_object_last_unref (GObject *object)
512 g_return_if_fail (object->ref_count > 0);
514 if (object->ref_count == 1) /* may have been re-referenced meanwhile */
515 G_OBJECT_GET_CLASS (object)->shutdown (object);
517 object->ref_count -= 1;
519 if (object->ref_count == 0) /* may have been re-referenced meanwhile */
521 G_OBJECT_GET_CLASS (object)->finalize (object);
523 if (glib_debug_objects && debug_objects_ht)
524 g_assert (g_hash_table_lookup (debug_objects_ht, object) == NULL);
525 #endif /* DEBUG_OBJECTS */
526 g_type_free_instance ((GTypeInstance*) object);
531 g_object_shutdown (GObject *object)
533 /* this function needs to be always present for unconditional
534 * chaining, we also might add some code here later.
535 * beware though, subclasses may invoke shutdown() arbitrarily.
540 g_object_finalize (GObject *object)
542 g_signal_handlers_destroy (object);
543 g_datalist_clear (&object->qdata);
546 if (glib_debug_objects)
548 g_assert (g_hash_table_lookup (debug_objects_ht, object) == object);
550 g_hash_table_remove (debug_objects_ht, object);
551 debug_objects_count--;
553 #endif /* DEBUG_OBJECTS */
557 object_thaw_notifies (GObject *object,
564 nqueue->freeze_count--;
565 if (nqueue->freeze_count)
567 g_return_if_fail (object->ref_count > 0);
569 pspecs = g_new (GParamSpec*, nqueue->n_pspecs);
570 for (slist = nqueue->pspecs; slist; slist = slist->next)
572 GParamSpec *pspec = slist->data;
575 /* dedup, make pspecs in the list unique */
577 if (pspecs[i] == pspec)
580 goto redo_dedup_check;
582 pspecs[n_pspecs++] = pspec;
584 g_object_set_qdata (object, quark_notify_queue, NULL);
587 G_OBJECT_GET_CLASS (object)->dispatch_properties_changed (object, n_pspecs, pspecs);
593 g_object_dispatch_properties_changed (GObject *object,
597 g_signal_emit (object, gobject_signals[PROPERTIES_CHANGED], 0, n_pspecs, pspecs);
601 g_object_properties_changed (GObject *object,
607 for (i = 0; i < n_pspecs; i++)
608 g_signal_emit (object, gobject_signals[NOTIFY], g_quark_from_string (pspecs[i]->name), pspecs[i]);
612 g_object_notify_property_changed (GObject *object,
616 g_message ("NOTIFICATION: property `%s' changed on object `%s'",
618 G_OBJECT_TYPE_NAME (object));
622 g_object_freeze_notify (GObject *object)
624 g_return_if_fail (G_IS_OBJECT (object));
625 if (!object->ref_count)
628 g_object_ref (object);
629 object_freeze_notifies (object);
630 g_object_unref (object);
634 g_object_notify (GObject *object,
635 const gchar *property_name)
639 g_return_if_fail (G_IS_OBJECT (object));
640 g_return_if_fail (property_name != NULL);
641 if (!object->ref_count)
644 g_object_ref (object);
645 pspec = g_param_spec_pool_lookup (pspec_pool,
647 G_OBJECT_TYPE (object),
650 g_warning ("%s: object class `%s' has no property named `%s'",
652 G_OBJECT_TYPE_NAME (object),
656 NotifyQueue *nqueue = object_freeze_notifies (object);
658 object_queue_property (object, pspec, nqueue);
659 object_thaw_notifies (object, nqueue);
661 g_object_unref (object);
665 g_object_thaw_notify (GObject *object)
669 g_return_if_fail (G_IS_OBJECT (object));
670 if (!object->ref_count)
673 g_object_ref (object);
674 nqueue = g_object_get_qdata (object, quark_notify_queue);
675 if (!nqueue || !nqueue->freeze_count)
676 g_warning (G_STRLOC ": property-changed notification for %s(%p) is not frozen",
677 G_OBJECT_TYPE_NAME (object), object);
679 object_thaw_notifies (object, nqueue);
680 g_object_unref (object);
684 object_get_property (GObject *object,
687 const gchar *trailer)
691 g_return_if_fail (g_type_is_a (G_OBJECT_TYPE (object), pspec->owner_type)); /* paranoid */
693 class = g_type_class_peek (pspec->owner_type);
695 class->get_property (object, PARAM_SPEC_PARAM_ID (pspec), value, pspec, trailer);
699 object_set_property (GObject *object,
702 const gchar *trailer,
707 g_return_if_fail (g_type_is_a (G_OBJECT_TYPE (object), pspec->owner_type)); /* paranoid */
709 class = g_type_class_peek (pspec->owner_type);
711 class->set_property (object, PARAM_SPEC_PARAM_ID (pspec), value, pspec, trailer);
712 object_queue_property (object, pspec, nqueue);
716 g_object_new (GType object_type,
717 const gchar *first_property_name,
723 g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type), NULL);
725 va_start (var_args, first_property_name);
726 object = g_object_new_valist (object_type, first_property_name, var_args);
733 g_object_new_valist (GType object_type,
734 const gchar *first_property_name,
741 GObjectConstructParam *cparams = NULL, *nparams = NULL;
742 guint n_cparams = 0, n_nparams = 0;
745 g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type), NULL);
747 class = g_type_class_ref (object_type);
748 clist = g_slist_copy (class->construct_properties);
750 /* collect parameters, sort into construction and normal ones */
751 name = first_property_name;
754 const gchar *trailer = NULL;
759 pspec = g_param_spec_pool_lookup (pspec_pool,
766 g_warning ("%s: object class `%s' has no property named `%s'",
768 g_type_name (object_type),
772 if (!(pspec->flags & G_PARAM_WRITABLE))
774 g_warning ("%s: property `%s' of object class `%s' is not writable",
777 g_type_name (object_type));
781 value = g_new (GValue, 1);
783 g_value_init (value, G_PARAM_SPEC_VALUE_TYPE (pspec));
784 G_VALUE_COLLECT (value, var_args, &error);
787 g_warning ("%s: %s", G_STRLOC, error);
790 /* we purposely leak the value here, it might not be
791 * in a sane state if an error condition occoured
795 if (pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY))
799 if (!n_cparams || n_cparams >= PREALLOC_CPARAMS)
800 cparams = g_renew (GObjectConstructParam, cparams, MAX (n_cparams + 1, PREALLOC_CPARAMS));
801 cparams[n_cparams].pspec = pspec;
802 cparams[n_cparams].value = value;
803 cparams[n_cparams].trailer = trailer;
804 for (i = 0; i < n_cparams; i++) /* picky, aren't we? ;) */
805 if (cparams[i].pspec == pspec)
806 g_warning (G_STRLOC ": construct property \"%s\" for object `%s' is being set twice",
807 pspec->name, g_type_name (object_type));
809 clist = g_slist_remove (clist, pspec); /* FIXME: unique */
813 if (!n_nparams || n_nparams >= PREALLOC_CPARAMS)
814 nparams = g_renew (GObjectConstructParam, nparams, MAX (n_nparams + 1, PREALLOC_CPARAMS));
815 nparams[n_nparams].pspec = pspec;
816 nparams[n_nparams].value = value;
817 nparams[n_nparams].trailer = trailer;
821 name = va_arg (var_args, gchar*);
824 /* construct object from construction parameters */
827 GSList *tmp = clist->next;
828 GParamSpec *pspec = clist->data;
829 GValue *value = g_new (GValue, 1);
832 g_value_init (value, G_PARAM_SPEC_VALUE_TYPE (pspec));
833 g_param_value_set_default (pspec, value);
835 if (!n_cparams || n_cparams >= PREALLOC_CPARAMS)
836 cparams = g_renew (GObjectConstructParam, cparams, MAX (n_cparams + 1, PREALLOC_CPARAMS));
837 cparams[n_cparams].pspec = pspec;
838 cparams[n_cparams].value = value;
839 cparams[n_cparams].trailer = NULL;
842 g_slist_free_1 (clist);
845 object = class->constructor (object_type, n_cparams, cparams);
847 /* free construction values */
850 g_value_unset (cparams[n_cparams].value);
851 g_free (cparams[n_cparams].value);
855 /* release g_object_init() notification queue freeze_count */
856 nqueue = object_freeze_notifies (object);
857 nqueue->freeze_count--;
859 /* set remaining properties */
863 GValue *value = nparams->value;
864 GParamSpec *pspec = nparams->pspec;
865 const gchar *trailer = nparams++->trailer;
867 /* convert if necessary */
868 if (!g_type_is_a (G_VALUE_TYPE (value), G_PARAM_SPEC_VALUE_TYPE (pspec)))
870 GValue tmp_value = { 0, };
872 g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
873 if (!g_value_convert (value, &tmp_value) ||
874 g_param_value_validate (pspec, &tmp_value))
875 g_warning ("%s: cannot convert `%s' value to property `%s' value of type `%s'",
877 G_VALUE_TYPE_NAME (value),
879 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)));
881 object_set_property (object, &tmp_value, pspec, trailer, nqueue);
882 g_value_unset (&tmp_value);
885 object_set_property (object, value, pspec, trailer, nqueue);
887 g_value_unset (value);
892 g_type_class_unref (class);
894 /* release our own freeze count and handle notifications */
895 object_thaw_notifies (object, nqueue);
901 g_object_constructor (GType type,
902 guint n_construct_properties,
903 GObjectConstructParam *construct_params)
908 object = (GObject*) g_type_create_instance (type);
910 /* set construction parameters */
911 if (n_construct_properties)
913 NotifyQueue *nqueue = object_freeze_notifies (object);
915 /* set construct properties */
916 while (n_construct_properties--)
918 GValue *value = construct_params->value;
919 GParamSpec *pspec = construct_params->pspec;
920 const gchar *trailer = construct_params++->trailer;
922 /* convert if necessary */
923 if (!g_type_is_a (G_VALUE_TYPE (value), G_PARAM_SPEC_VALUE_TYPE (pspec)))
925 GValue tmp_value = { 0, };
927 g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
928 if (!g_value_convert (value, &tmp_value) ||
929 g_param_value_validate (pspec, &tmp_value))
930 g_warning ("%s: cannot convert `%s' value to property `%s' value of type `%s'",
932 G_VALUE_TYPE_NAME (value),
934 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)));
936 object_set_property (object, &tmp_value, pspec, trailer, nqueue);
937 g_value_unset (&tmp_value);
940 object_set_property (object, value, pspec, trailer, nqueue);
942 nqueue->freeze_count--;
943 /* the notification queue is still frozen from g_object_init(), so
944 * we don't need to handle it here, g_object_new_valist() takes
953 g_object_set_valist (GObject *object,
954 const gchar *first_property_name,
960 g_return_if_fail (G_IS_OBJECT (object));
962 g_object_ref (object);
963 nqueue = object_freeze_notifies (object);
965 name = first_property_name;
968 const gchar *trailer = NULL;
969 GValue value = { 0, };
973 pspec = g_param_spec_pool_lookup (pspec_pool,
975 G_OBJECT_TYPE (object),
980 g_warning ("%s: object class `%s' has no property named `%s'",
982 G_OBJECT_TYPE_NAME (object),
986 if (!(pspec->flags & G_PARAM_WRITABLE))
988 g_warning ("%s: property `%s' of object class `%s' is not writable",
991 G_OBJECT_TYPE_NAME (object));
995 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
997 G_VALUE_COLLECT (&value, var_args, &error);
1000 g_warning ("%s: %s", G_STRLOC, error);
1003 /* we purposely leak the value here, it might not be
1004 * in a sane state if an error condition occoured
1009 object_set_property (object, &value, pspec, trailer, nqueue);
1011 g_value_unset (&value);
1013 name = va_arg (var_args, gchar*);
1016 object_thaw_notifies (object, nqueue);
1017 g_object_unref (object);
1021 g_object_get_valist (GObject *object,
1022 const gchar *first_property_name,
1027 g_return_if_fail (G_IS_OBJECT (object));
1029 g_object_ref (object);
1031 name = first_property_name;
1035 const gchar *trailer = NULL;
1036 GValue value = { 0, };
1040 pspec = g_param_spec_pool_lookup (pspec_pool,
1042 G_OBJECT_TYPE (object),
1047 g_warning ("%s: object class `%s' has no property named `%s'",
1049 G_OBJECT_TYPE_NAME (object),
1053 if (!(pspec->flags & G_PARAM_READABLE))
1055 g_warning ("%s: property `%s' of object class `%s' is not readable",
1058 G_OBJECT_TYPE_NAME (object));
1062 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
1064 object_get_property (object, &value, pspec, trailer);
1066 G_VALUE_LCOPY (&value, var_args, &error);
1069 g_warning ("%s: %s", G_STRLOC, error);
1072 /* we purposely leak the value here, it might not be
1073 * in a sane state if an error condition occoured
1078 g_value_unset (&value);
1080 name = va_arg (var_args, gchar*);
1083 g_object_unref (object);
1087 g_object_set (gpointer _object,
1088 const gchar *first_property_name,
1091 GObject *object = _object;
1094 g_return_if_fail (G_IS_OBJECT (object));
1096 va_start (var_args, first_property_name);
1097 g_object_set_valist (object, first_property_name, var_args);
1102 g_object_get (gpointer _object,
1103 const gchar *first_property_name,
1106 GObject *object = _object;
1109 g_return_if_fail (G_IS_OBJECT (object));
1111 va_start (var_args, first_property_name);
1112 g_object_get_valist (object, first_property_name, var_args);
1117 g_object_set_property (GObject *object,
1118 const gchar *property_name,
1119 const GValue *value)
1121 NotifyQueue *nqueue;
1123 const gchar *trailer;
1125 g_return_if_fail (G_IS_OBJECT (object));
1126 g_return_if_fail (property_name != NULL);
1127 g_return_if_fail (G_IS_VALUE (value));
1129 g_object_ref (object);
1130 nqueue = object_freeze_notifies (object);
1132 pspec = g_param_spec_pool_lookup (pspec_pool,
1134 G_OBJECT_TYPE (object),
1138 g_warning ("%s: object class `%s' has no property named `%s'",
1140 G_OBJECT_TYPE_NAME (object),
1144 GValue tmp_value = { 0, };
1146 /* provide a copy to work from and convert if necessary */
1147 g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
1149 if (!g_value_convert (value, &tmp_value) ||
1150 g_param_value_validate (pspec, &tmp_value))
1151 g_warning ("%s: cannot convert `%s' value to property `%s' value of type `%s'",
1153 G_VALUE_TYPE_NAME (value),
1155 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)));
1157 object_set_property (object, &tmp_value, pspec, trailer, nqueue);
1159 g_value_unset (&tmp_value);
1162 object_thaw_notifies (object, nqueue);
1163 g_object_unref (object);
1167 g_object_get_property (GObject *object,
1168 const gchar *property_name,
1172 const gchar *trailer;
1174 g_return_if_fail (G_IS_OBJECT (object));
1175 g_return_if_fail (property_name != NULL);
1176 g_return_if_fail (G_IS_VALUE (value));
1178 g_object_ref (object);
1180 pspec = g_param_spec_pool_lookup (pspec_pool,
1182 G_OBJECT_TYPE (object),
1186 g_warning ("%s: object class `%s' has no property named `%s'",
1188 G_OBJECT_TYPE_NAME (object),
1192 GValue tmp_value = { 0, };
1194 /* provide a copy to work from and later convert if necessary, so
1195 * _get_property() implementations need *not* care about freeing values
1196 * that might be already set in the property to get.
1197 * (though, at this point, GValue should exclusively be modified
1198 * through the accessor functions anyways)
1200 g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
1202 if (!g_value_types_exchangable (G_VALUE_TYPE (value), G_PARAM_SPEC_VALUE_TYPE (pspec)))
1203 g_warning ("%s: can't retrive property `%s' value of type `%s' as value of type `%s'",
1206 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1207 G_VALUE_TYPE_NAME (value));
1210 object_get_property (object, &tmp_value, pspec, trailer);
1211 g_value_convert (&tmp_value, value);
1212 /* g_value_validate (value, pspec); */
1215 g_value_unset (&tmp_value);
1218 g_object_unref (object);
1222 g_object_ref (gpointer _object)
1224 GObject *object = _object;
1226 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1227 g_return_val_if_fail (object->ref_count > 0, NULL);
1229 object->ref_count += 1;
1235 g_object_unref (gpointer _object)
1237 GObject *object = _object;
1239 g_return_if_fail (G_IS_OBJECT (object));
1240 g_return_if_fail (object->ref_count > 0);
1242 if (object->ref_count > 1)
1243 object->ref_count -= 1;
1245 g_object_last_unref (object);
1249 g_object_get_qdata (GObject *object,
1252 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1254 return quark ? g_datalist_id_get_data (&object->qdata, quark) : NULL;
1258 g_object_set_qdata (GObject *object,
1262 g_return_if_fail (G_IS_OBJECT (object));
1263 g_return_if_fail (quark > 0);
1265 g_datalist_id_set_data (&object->qdata, quark, data);
1269 g_object_set_qdata_full (GObject *object,
1272 GDestroyNotify destroy)
1274 g_return_if_fail (G_IS_OBJECT (object));
1275 g_return_if_fail (quark > 0);
1277 g_datalist_id_set_data_full (&object->qdata, quark, data, data ? destroy : NULL);
1281 g_object_steal_qdata (GObject *object,
1284 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1285 g_return_val_if_fail (quark > 0, NULL);
1287 return g_datalist_id_remove_no_notify (&object->qdata, quark);
1291 g_object_get_data (GObject *object,
1296 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1297 g_return_val_if_fail (key != NULL, NULL);
1299 quark = g_quark_try_string (key);
1301 return quark ? g_datalist_id_get_data (&object->qdata, quark) : NULL;
1305 g_object_set_data (GObject *object,
1309 g_return_if_fail (G_IS_OBJECT (object));
1310 g_return_if_fail (key != NULL);
1312 g_datalist_id_set_data (&object->qdata, g_quark_from_string (key), data);
1316 g_object_set_data_full (GObject *object,
1319 GDestroyNotify destroy)
1321 g_return_if_fail (G_IS_OBJECT (object));
1322 g_return_if_fail (key != NULL);
1324 g_datalist_id_set_data_full (&object->qdata, g_quark_from_string (key), data, data ? destroy : NULL);
1328 g_object_steal_data (GObject *object,
1333 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1334 g_return_val_if_fail (key != NULL, NULL);
1336 quark = g_quark_try_string (key);
1338 return quark ? g_datalist_id_remove_no_notify (&object->qdata, quark) : NULL;
1342 g_value_object_init (GValue *value)
1344 value->data[0].v_pointer = NULL;
1348 g_value_object_free_value (GValue *value)
1350 if (value->data[0].v_pointer)
1351 g_object_unref (value->data[0].v_pointer);
1355 g_value_object_copy_value (const GValue *src_value,
1358 if (src_value->data[0].v_pointer)
1359 dest_value->data[0].v_pointer = g_object_ref (src_value->data[0].v_pointer);
1361 dest_value->data[0].v_pointer = NULL;
1365 g_value_object_peek_pointer (const GValue *value)
1367 return value->data[0].v_pointer;
1371 g_value_object_collect_value (GValue *value,
1373 GType *collect_type,
1374 GTypeCValue *collect_value)
1376 if (collect_value->v_pointer)
1378 GObject *object = collect_value->v_pointer;
1380 if (object->g_type_instance.g_class == NULL)
1381 return g_strconcat ("invalid unclassed object pointer for value type `",
1382 G_VALUE_TYPE_NAME (value),
1385 else if (!g_type_is_a (G_OBJECT_TYPE (object), G_VALUE_TYPE (value)))
1386 return g_strconcat ("invalid object type `",
1387 G_OBJECT_TYPE_NAME (object),
1388 "' for value type `",
1389 G_VALUE_TYPE_NAME (value),
1392 value->data[0].v_pointer = g_object_ref (object);
1395 value->data[0].v_pointer = NULL;
1402 g_value_object_lcopy_value (const GValue *value,
1404 GType *collect_type,
1405 GTypeCValue *collect_value)
1407 GObject **object_p = collect_value->v_pointer;
1410 return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
1412 *object_p = value->data[0].v_pointer ? g_object_ref (value->data[0].v_pointer) : NULL;
1419 g_value_set_object (GValue *value,
1422 g_return_if_fail (G_IS_VALUE_OBJECT (value));
1424 if (value->data[0].v_pointer)
1426 g_object_unref (value->data[0].v_pointer);
1427 value->data[0].v_pointer = NULL;
1432 g_return_if_fail (G_IS_OBJECT (v_object));
1433 g_return_if_fail (g_type_is_a (G_OBJECT_TYPE (v_object), G_VALUE_TYPE (value)));
1435 value->data[0].v_pointer = v_object;
1436 g_object_ref (value->data[0].v_pointer);
1441 g_value_get_object (const GValue *value)
1443 g_return_val_if_fail (G_IS_VALUE_OBJECT (value), NULL);
1445 return value->data[0].v_pointer;
1449 g_value_dup_object (const GValue *value)
1451 g_return_val_if_fail (G_IS_VALUE_OBJECT (value), NULL);
1453 return value->data[0].v_pointer ? g_object_ref (value->data[0].v_pointer) : NULL;
1457 g_signal_connect_object (gpointer instance,
1458 const gchar *detailed_signal,
1459 GCallback c_handler,
1464 g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
1465 g_return_val_if_fail (detailed_signal != NULL, 0);
1466 g_return_val_if_fail (c_handler != NULL, 0);
1472 g_return_val_if_fail (G_IS_OBJECT (gobject), 0);
1474 closure = (swapped ? g_cclosure_new_object_swap : g_cclosure_new_object) (c_handler, gobject);
1476 return g_signal_connect_closure (instance, detailed_signal, closure, after);
1479 return g_signal_connect_data (instance, detailed_signal, c_handler, NULL, NULL, swapped, after);
1485 GClosure *closures[1]; /* flexible array */
1489 object_remove_closure (gpointer data,
1492 GObject *object = data;
1493 CArray *carray = g_object_get_qdata (object, quark_closure_array);
1496 for (i = 0; i < carray->n_closures; i++)
1497 if (carray->closures[i] == closure)
1499 carray->n_closures--;
1500 if (i < carray->n_closures)
1501 carray->closures[i] = carray->closures[carray->n_closures];
1504 g_assert_not_reached ();
1508 destroy_closure_array (gpointer data)
1510 CArray *carray = data;
1511 GObject *object = carray->object;
1512 guint i, n = carray->n_closures;
1514 for (i = 0; i < n; i++)
1516 GClosure *closure = carray->closures[i];
1518 /* removing object_remove_closure() upfront is probably faster than
1519 * letting it fiddle with quark_closure_array which is empty anyways
1521 g_closure_remove_inotify (closure, object, object_remove_closure);
1522 g_closure_invalidate (closure);
1528 g_object_watch_closure (GObject *object,
1533 g_return_if_fail (G_IS_OBJECT (object));
1534 g_return_if_fail (closure != NULL);
1535 g_return_if_fail (closure->is_invalid == FALSE);
1536 g_return_if_fail (closure->in_marshal == FALSE);
1537 g_return_if_fail (object->ref_count > 0); /* this doesn't work on finalizing objects */
1539 g_closure_add_inotify (closure, object, object_remove_closure);
1540 g_closure_add_marshal_guards (closure,
1541 object, (GClosureNotify) g_object_ref,
1542 object, (GClosureNotify) g_object_unref);
1543 carray = g_object_steal_qdata (object, quark_closure_array);
1546 carray = g_renew (CArray, NULL, 1);
1547 carray->object = object;
1548 carray->n_closures = 1;
1549 carray->closures[0] = closure;
1550 g_object_set_qdata_full (object, quark_closure_array, carray, destroy_closure_array);
1554 guint i = carray->n_closures++;
1556 carray = g_realloc (carray, sizeof (*carray) + sizeof (carray->closures[0]) * i);
1557 carray->closures[i] = closure;
1558 g_object_set_qdata_full (object, quark_closure_array, carray, destroy_closure_array);
1563 g_closure_new_object (guint sizeof_closure,
1568 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1569 g_return_val_if_fail (object->ref_count > 0, NULL); /* this doesn't work on finalizing objects */
1571 closure = g_closure_new_simple (sizeof_closure, object);
1572 g_object_watch_closure (object, closure);
1578 g_cclosure_new_object (GCallback callback_func,
1581 GObject *object = _object;
1584 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1585 g_return_val_if_fail (object->ref_count > 0, NULL); /* this doesn't work on finalizing objects */
1586 g_return_val_if_fail (callback_func != NULL, NULL);
1588 closure = g_cclosure_new (callback_func, object, NULL);
1589 g_object_watch_closure (object, closure);
1595 g_cclosure_new_object_swap (GCallback callback_func,
1598 GObject *object = _object;
1601 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1602 g_return_val_if_fail (object->ref_count > 0, NULL); /* this doesn't work on finalizing objects */
1603 g_return_val_if_fail (callback_func != NULL, NULL);
1605 closure = g_cclosure_new_swap (callback_func, object, NULL);
1606 g_object_watch_closure (object, closure);