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 /* We need an actual method for handling debug keys in GLib.
137 * For now, we'll simply use, as a method
138 * 'extern gboolean glib_debug_objects'
140 gboolean glib_debug_objects = FALSE;
142 #ifdef G_ENABLE_DEBUG
143 static volatile GObject *glib_trap_object_ref = NULL;
144 static guint debug_objects_count = 0;
145 static GHashTable *debug_objects_ht = NULL;
147 debug_objects_foreach (gpointer key,
151 GObject *object = value;
153 g_message ("[%p] stale %s\tref_count=%u",
155 G_OBJECT_TYPE_NAME (object),
159 debug_objects_atexit (void)
161 if (glib_debug_objects)
163 if (debug_objects_ht)
165 g_message ("stale GObjects: %u", debug_objects_count);
166 g_hash_table_foreach (debug_objects_ht, debug_objects_foreach, NULL);
170 #endif /* G_ENABLE_DEBUG */
173 g_object_type_init (void) /* sync with gtype.c */
175 static gboolean initialized = FALSE;
176 static const GTypeFundamentalInfo finfo = {
177 G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE,
179 static GTypeInfo info = {
180 sizeof (GObjectClass),
181 (GBaseInitFunc) g_object_base_class_init,
182 (GBaseFinalizeFunc) g_object_base_class_finalize,
183 (GClassInitFunc) g_object_do_class_init,
184 NULL /* class_destroy */,
185 NULL /* class_data */,
188 (GInstanceInitFunc) g_object_init,
189 NULL, /* value_table */
191 static const GTypeValueTable value_table = {
192 g_value_object_init, /* value_init */
193 g_value_object_free_value, /* value_free */
194 g_value_object_copy_value, /* value_copy */
195 g_value_object_peek_pointer, /* value_peek_pointer */
196 G_VALUE_COLLECT_POINTER, /* collect_type */
197 g_value_object_collect_value, /* collect_value */
198 G_VALUE_COLLECT_POINTER, /* lcopy_type */
199 g_value_object_lcopy_value, /* lcopy_value */
203 g_return_if_fail (initialized == FALSE);
208 info.value_table = &value_table;
209 type = g_type_register_fundamental (G_TYPE_OBJECT, "GObject", &info, &finfo, 0);
210 g_assert (type == G_TYPE_OBJECT);
212 #ifdef G_ENABLE_DEBUG
213 g_atexit (debug_objects_atexit);
214 #endif /* G_ENABLE_DEBUG */
218 g_object_base_class_init (GObjectClass *class)
220 GObjectClass *pclass = g_type_class_peek_parent (class);
222 /* reset instance specific fields and methods that don't get inherited */
223 class->n_property_specs = 0;
224 class->property_specs = NULL;
225 class->construct_properties = pclass ? g_slist_copy (pclass->construct_properties) : NULL;
226 class->get_property = NULL;
227 class->set_property = NULL;
231 g_object_base_class_finalize (GObjectClass *class)
235 g_message ("finallizing base class of %s", G_OBJECT_CLASS_NAME (class));
237 _g_signals_destroy (G_OBJECT_CLASS_TYPE (class));
239 g_slist_free (class->construct_properties);
240 class->construct_properties = NULL;
241 for (i = 0; i < class->n_property_specs; i++)
243 GParamSpec *pspec = class->property_specs[i];
245 g_param_spec_pool_remove (pspec_pool, pspec);
246 g_param_spec_set_qdata (pspec, quark_property_id, NULL);
247 g_param_spec_unref (pspec);
249 class->n_property_specs = 0;
250 g_free (class->property_specs);
251 class->property_specs = NULL;
255 g_object_do_class_init (GObjectClass *class)
257 quark_notify_queue = g_quark_from_static_string ("GObject-notify-queue");
258 quark_property_id = g_quark_from_static_string ("GObject-property-id");
259 quark_closure_array = g_quark_from_static_string ("GObject-closure-array");
260 pspec_pool = g_param_spec_pool_new (TRUE);
262 class->constructor = g_object_constructor;
263 class->set_property = g_object_do_set_property;
264 class->get_property = g_object_do_get_property;
265 class->shutdown = g_object_shutdown;
266 class->finalize = g_object_finalize;
267 class->dispatch_properties_changed = g_object_dispatch_properties_changed;
268 class->properties_changed = g_object_properties_changed;
269 class->notify = g_object_notify_property_changed;
271 g_object_class_install_property (class,
273 g_param_spec_pointer ("data", "Named Data",
274 "Named anonymous pointers",
275 G_PARAM_READABLE | G_PARAM_WRITABLE));
276 g_object_class_install_property (class,
278 g_param_spec_ccallback ("signal", "Signal Connection",
279 "Signal connection consisting of a callback function "
280 "and a data pointer",
282 g_object_class_install_property (class,
284 g_param_spec_ccallback ("swapped_signal", "Swapped Signal Connection",
285 "Signal connection consisting of a callback function "
286 "and a data pointer",
288 g_object_class_install_property (class,
290 g_param_spec_ccallback ("signal_after", "Signal After Connection",
291 "Signal connection consisting of a callback function "
292 "and a data pointer",
294 g_object_class_install_property (class,
295 PROP_SWAPPED_SIGNAL_AFTER,
296 g_param_spec_ccallback ("swapped_signal_after", "Swapped Signal After Connection",
297 "Signal connection consisting of a callback function "
298 "and a data pointer",
300 gobject_signals[PROPERTIES_CHANGED] =
301 g_signal_newc ("properties_changed",
302 G_TYPE_FROM_CLASS (class),
303 G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
304 G_STRUCT_OFFSET (GObjectClass, properties_changed),
305 NULL, /* accumulator */
306 g_cclosure_marshal_VOID__UINT_POINTER,
308 2, G_TYPE_UINT, G_TYPE_POINTER);
309 gobject_signals[NOTIFY] =
310 g_signal_newc ("notify",
311 G_TYPE_FROM_CLASS (class),
312 G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED | G_SIGNAL_NO_HOOKS,
313 G_STRUCT_OFFSET (GObjectClass, notify),
314 NULL, /* accumulator */
315 g_cclosure_marshal_VOID__PARAM,
321 g_object_class_install_property (GObjectClass *class,
327 g_return_if_fail (G_IS_OBJECT_CLASS (class));
328 g_return_if_fail (G_IS_PARAM_SPEC (pspec));
329 if (pspec->flags & G_PARAM_WRITABLE)
330 g_return_if_fail (class->set_property != NULL);
331 if (pspec->flags & G_PARAM_READABLE)
332 g_return_if_fail (class->get_property != NULL);
333 g_return_if_fail (property_id > 0);
334 g_return_if_fail (PARAM_SPEC_PARAM_ID (pspec) == 0); /* paranoid */
335 if (pspec->flags & G_PARAM_CONSTRUCT)
336 g_return_if_fail ((pspec->flags & G_PARAM_CONSTRUCT_ONLY) == 0);
337 if (pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY))
338 g_return_if_fail (pspec->flags & G_PARAM_WRITABLE);
340 /* expensive paranoia checks ;( */
341 for (i = 0; i < class->n_property_specs; i++)
342 if (PARAM_SPEC_PARAM_ID (class->property_specs[i]) == property_id)
344 g_warning (G_STRLOC ": class `%s' already contains a property `%s' with id %u, "
345 "cannot install property `%s'",
346 G_OBJECT_CLASS_NAME (class),
347 class->property_specs[i]->name,
352 if (g_param_spec_pool_lookup (pspec_pool, pspec->name, G_OBJECT_CLASS_TYPE (class), FALSE, NULL))
354 g_warning (G_STRLOC ": class `%s' already contains a property named `%s'",
355 G_OBJECT_CLASS_NAME (class),
360 g_param_spec_ref (pspec);
361 g_param_spec_sink (pspec);
362 g_param_spec_set_qdata (pspec, quark_property_id, GUINT_TO_POINTER (property_id));
363 g_param_spec_pool_insert (pspec_pool, pspec, G_OBJECT_CLASS_TYPE (class));
364 i = class->n_property_specs++;
365 class->property_specs = g_renew (GParamSpec*, class->property_specs, class->n_property_specs);
366 class->property_specs[i] = pspec;
367 if (pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY))
368 class->construct_properties = g_slist_prepend (class->construct_properties, pspec);
370 /* for property overrides of construct poperties, we have to get rid
371 * of the overidden inherited construct property
373 pspec = g_param_spec_pool_lookup (pspec_pool, pspec->name, g_type_parent (G_OBJECT_CLASS_TYPE (class)), TRUE, NULL);
374 if (pspec && pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY))
375 class->construct_properties = g_slist_remove (class->construct_properties, pspec);
379 g_object_class_find_property (GObjectClass *class,
380 const gchar *property_name)
382 g_return_val_if_fail (G_IS_OBJECT_CLASS (class), NULL);
383 g_return_val_if_fail (property_name != NULL, NULL);
385 return g_param_spec_pool_lookup (pspec_pool,
387 G_OBJECT_CLASS_TYPE (class),
392 free_notify_queue (gpointer data)
394 NotifyQueue *nqueue = data;
396 g_slist_free (nqueue->pspecs);
400 static inline NotifyQueue*
401 object_freeze_notifies (GObject *object)
405 nqueue = g_object_get_qdata (object, quark_notify_queue);
408 nqueue = g_new0 (NotifyQueue, 1);
409 g_object_set_qdata_full (object, quark_notify_queue, nqueue, free_notify_queue);
411 nqueue->freeze_count++;
417 object_queue_property (GObject *object,
421 /* we will dedup later */
422 nqueue->pspecs = g_slist_prepend (nqueue->pspecs, pspec);
427 g_object_init (GObject *object)
429 object->ref_count = 1;
430 g_datalist_init (&object->qdata);
432 /* freeze object's notification queue, g_object_new_valist() takes care of that */
433 object_freeze_notifies (object);
435 #ifdef G_ENABLE_DEBUG
436 if (glib_debug_objects)
438 if (!debug_objects_ht)
439 debug_objects_ht = g_hash_table_new (g_direct_hash, NULL);
440 debug_objects_count++;
441 g_hash_table_insert (debug_objects_ht, object, object);
443 #endif /* G_ENABLE_DEBUG */
447 g_object_do_set_property (GObject *object,
451 const gchar *trailer)
457 gboolean swapped, after;
458 gpointer callback, data;
460 g_return_if_fail (trailer != NULL);
462 g_object_set_data (object, trailer, g_value_get_pointer (value));
464 case PROP_SWAPPED_SIGNAL_AFTER:
466 case PROP_SIGNAL_AFTER:
468 case PROP_SWAPPED_SIGNAL:
473 g_return_if_fail (trailer != NULL);
475 g_value_get_ccallback (value, &callback, &data);
476 g_signal_connect_data (object, trailer,
477 callback, data, NULL,
481 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
487 g_object_do_get_property (GObject *object,
491 const gchar *trailer)
496 g_return_if_fail (trailer != NULL);
498 g_value_set_pointer (value, g_object_get_data (object, trailer));
501 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
507 g_object_last_unref (GObject *object)
509 g_return_if_fail (object->ref_count > 0);
511 if (object->ref_count == 1) /* may have been re-referenced meanwhile */
512 G_OBJECT_GET_CLASS (object)->shutdown (object);
514 #ifdef G_ENABLE_DEBUG
515 if (glib_trap_object_ref == object)
517 #endif /* G_ENABLE_DEBUG */
519 object->ref_count -= 1;
521 if (object->ref_count == 0) /* may have been re-referenced meanwhile */
523 G_OBJECT_GET_CLASS (object)->finalize (object);
524 #ifdef G_ENABLE_DEBUG
525 if (glib_debug_objects && debug_objects_ht)
526 g_assert (g_hash_table_lookup (debug_objects_ht, object) == NULL);
527 #endif /* G_ENABLE_DEBUG */
528 g_type_free_instance ((GTypeInstance*) object);
533 g_object_shutdown (GObject *object)
535 /* this function needs to be always present for unconditional
536 * chaining, we also might add some code here later.
537 * beware though, subclasses may invoke shutdown() arbitrarily.
542 g_object_finalize (GObject *object)
544 g_signal_handlers_destroy (object);
545 g_datalist_clear (&object->qdata);
547 #ifdef G_ENABLE_DEBUG
548 if (glib_debug_objects)
550 g_assert (g_hash_table_lookup (debug_objects_ht, object) == object);
552 g_hash_table_remove (debug_objects_ht, object);
553 debug_objects_count--;
555 #endif /* G_ENABLE_DEBUG */
559 object_thaw_notifies (GObject *object,
566 nqueue->freeze_count--;
567 if (nqueue->freeze_count)
569 g_return_if_fail (object->ref_count > 0);
571 pspecs = g_new (GParamSpec*, nqueue->n_pspecs);
572 for (slist = nqueue->pspecs; slist; slist = slist->next)
574 GParamSpec *pspec = slist->data;
577 /* dedup, make pspecs in the list unique */
579 if (pspecs[i] == pspec)
582 goto redo_dedup_check;
584 pspecs[n_pspecs++] = pspec;
586 g_object_set_qdata (object, quark_notify_queue, NULL);
589 G_OBJECT_GET_CLASS (object)->dispatch_properties_changed (object, n_pspecs, pspecs);
595 g_object_dispatch_properties_changed (GObject *object,
599 g_signal_emit (object, gobject_signals[PROPERTIES_CHANGED], 0, n_pspecs, pspecs);
603 g_object_properties_changed (GObject *object,
609 for (i = 0; i < n_pspecs; i++)
610 g_signal_emit (object, gobject_signals[NOTIFY], g_quark_from_string (pspecs[i]->name), pspecs[i]);
614 g_object_notify_property_changed (GObject *object,
618 g_message ("NOTIFICATION: property `%s' changed on object `%s'",
620 G_OBJECT_TYPE_NAME (object));
624 g_object_freeze_notify (GObject *object)
626 g_return_if_fail (G_IS_OBJECT (object));
627 if (!object->ref_count)
630 g_object_ref (object);
631 object_freeze_notifies (object);
632 g_object_unref (object);
636 g_object_notify (GObject *object,
637 const gchar *property_name)
641 g_return_if_fail (G_IS_OBJECT (object));
642 g_return_if_fail (property_name != NULL);
643 if (!object->ref_count)
646 g_object_ref (object);
647 pspec = g_param_spec_pool_lookup (pspec_pool,
649 G_OBJECT_TYPE (object),
652 g_warning ("%s: object class `%s' has no property named `%s'",
654 G_OBJECT_TYPE_NAME (object),
658 NotifyQueue *nqueue = object_freeze_notifies (object);
660 object_queue_property (object, pspec, nqueue);
661 object_thaw_notifies (object, nqueue);
663 g_object_unref (object);
667 g_object_thaw_notify (GObject *object)
671 g_return_if_fail (G_IS_OBJECT (object));
672 if (!object->ref_count)
675 g_object_ref (object);
676 nqueue = g_object_get_qdata (object, quark_notify_queue);
677 if (!nqueue || !nqueue->freeze_count)
678 g_warning (G_STRLOC ": property-changed notification for %s(%p) is not frozen",
679 G_OBJECT_TYPE_NAME (object), object);
681 object_thaw_notifies (object, nqueue);
682 g_object_unref (object);
686 object_get_property (GObject *object,
689 const gchar *trailer)
693 g_return_if_fail (g_type_is_a (G_OBJECT_TYPE (object), pspec->owner_type)); /* paranoid */
695 class = g_type_class_peek (pspec->owner_type);
697 class->get_property (object, PARAM_SPEC_PARAM_ID (pspec), value, pspec, trailer);
701 object_set_property (GObject *object,
704 const gchar *trailer,
709 g_return_if_fail (g_type_is_a (G_OBJECT_TYPE (object), pspec->owner_type)); /* paranoid */
711 class = g_type_class_peek (pspec->owner_type);
713 class->set_property (object, PARAM_SPEC_PARAM_ID (pspec), value, pspec, trailer);
714 object_queue_property (object, pspec, nqueue);
718 g_object_new (GType object_type,
719 const gchar *first_property_name,
725 g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type), NULL);
727 va_start (var_args, first_property_name);
728 object = g_object_new_valist (object_type, first_property_name, var_args);
735 g_object_new_valist (GType object_type,
736 const gchar *first_property_name,
743 GObjectConstructParam *cparams = NULL, *nparams = NULL;
744 guint n_cparams = 0, n_nparams = 0;
747 g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type), NULL);
749 class = g_type_class_ref (object_type);
750 clist = g_slist_copy (class->construct_properties);
752 /* collect parameters, sort into construction and normal ones */
753 name = first_property_name;
756 const gchar *trailer = NULL;
761 pspec = g_param_spec_pool_lookup (pspec_pool,
768 g_warning ("%s: object class `%s' has no property named `%s'",
770 g_type_name (object_type),
774 if (!(pspec->flags & G_PARAM_WRITABLE))
776 g_warning ("%s: property `%s' of object class `%s' is not writable",
779 g_type_name (object_type));
783 value = g_new (GValue, 1);
785 g_value_init (value, G_PARAM_SPEC_VALUE_TYPE (pspec));
786 G_VALUE_COLLECT (value, var_args, &error);
789 g_warning ("%s: %s", G_STRLOC, error);
792 /* we purposely leak the value here, it might not be
793 * in a sane state if an error condition occoured
797 if (pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY))
801 if (!n_cparams || n_cparams >= PREALLOC_CPARAMS)
802 cparams = g_renew (GObjectConstructParam, cparams, MAX (n_cparams + 1, PREALLOC_CPARAMS));
803 cparams[n_cparams].pspec = pspec;
804 cparams[n_cparams].value = value;
805 cparams[n_cparams].trailer = trailer;
806 for (i = 0; i < n_cparams; i++) /* picky, aren't we? ;) */
807 if (cparams[i].pspec == pspec)
808 g_warning (G_STRLOC ": construct property \"%s\" for object `%s' is being set twice",
809 pspec->name, g_type_name (object_type));
811 clist = g_slist_remove (clist, pspec); /* FIXME: unique */
815 if (!n_nparams || n_nparams >= PREALLOC_CPARAMS)
816 nparams = g_renew (GObjectConstructParam, nparams, MAX (n_nparams + 1, PREALLOC_CPARAMS));
817 nparams[n_nparams].pspec = pspec;
818 nparams[n_nparams].value = value;
819 nparams[n_nparams].trailer = trailer;
823 name = va_arg (var_args, gchar*);
826 /* construct object from construction parameters */
829 GSList *tmp = clist->next;
830 GParamSpec *pspec = clist->data;
831 GValue *value = g_new (GValue, 1);
834 g_value_init (value, G_PARAM_SPEC_VALUE_TYPE (pspec));
835 g_param_value_set_default (pspec, value);
837 if (!n_cparams || n_cparams >= PREALLOC_CPARAMS)
838 cparams = g_renew (GObjectConstructParam, cparams, MAX (n_cparams + 1, PREALLOC_CPARAMS));
839 cparams[n_cparams].pspec = pspec;
840 cparams[n_cparams].value = value;
841 cparams[n_cparams].trailer = NULL;
844 g_slist_free_1 (clist);
847 object = class->constructor (object_type, n_cparams, cparams);
849 /* free construction values */
852 g_value_unset (cparams[n_cparams].value);
853 g_free (cparams[n_cparams].value);
857 /* release g_object_init() notification queue freeze_count */
858 nqueue = object_freeze_notifies (object);
859 nqueue->freeze_count--;
861 /* set remaining properties */
865 GValue *value = nparams->value;
866 GParamSpec *pspec = nparams->pspec;
867 const gchar *trailer = nparams++->trailer;
869 /* convert if necessary */
870 if (!g_type_is_a (G_VALUE_TYPE (value), G_PARAM_SPEC_VALUE_TYPE (pspec)))
872 GValue tmp_value = { 0, };
874 g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
875 if (!g_value_convert (value, &tmp_value) ||
876 g_param_value_validate (pspec, &tmp_value))
877 g_warning ("%s: cannot convert `%s' value to property `%s' value of type `%s'",
879 G_VALUE_TYPE_NAME (value),
881 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)));
883 object_set_property (object, &tmp_value, pspec, trailer, nqueue);
884 g_value_unset (&tmp_value);
887 object_set_property (object, value, pspec, trailer, nqueue);
889 g_value_unset (value);
894 g_type_class_unref (class);
896 /* release our own freeze count and handle notifications */
897 object_thaw_notifies (object, nqueue);
903 g_object_constructor (GType type,
904 guint n_construct_properties,
905 GObjectConstructParam *construct_params)
910 object = (GObject*) g_type_create_instance (type);
912 /* set construction parameters */
913 if (n_construct_properties)
915 NotifyQueue *nqueue = object_freeze_notifies (object);
917 /* set construct properties */
918 while (n_construct_properties--)
920 GValue *value = construct_params->value;
921 GParamSpec *pspec = construct_params->pspec;
922 const gchar *trailer = construct_params++->trailer;
924 /* convert if necessary */
925 if (!g_type_is_a (G_VALUE_TYPE (value), G_PARAM_SPEC_VALUE_TYPE (pspec)))
927 GValue tmp_value = { 0, };
929 g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
930 if (!g_value_convert (value, &tmp_value) ||
931 g_param_value_validate (pspec, &tmp_value))
932 g_warning ("%s: cannot convert `%s' value to property `%s' value of type `%s'",
934 G_VALUE_TYPE_NAME (value),
936 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)));
938 object_set_property (object, &tmp_value, pspec, trailer, nqueue);
939 g_value_unset (&tmp_value);
942 object_set_property (object, value, pspec, trailer, nqueue);
944 nqueue->freeze_count--;
945 /* the notification queue is still frozen from g_object_init(), so
946 * we don't need to handle it here, g_object_new_valist() takes
955 g_object_set_valist (GObject *object,
956 const gchar *first_property_name,
962 g_return_if_fail (G_IS_OBJECT (object));
964 g_object_ref (object);
965 nqueue = object_freeze_notifies (object);
967 name = first_property_name;
970 const gchar *trailer = NULL;
971 GValue value = { 0, };
975 pspec = g_param_spec_pool_lookup (pspec_pool,
977 G_OBJECT_TYPE (object),
982 g_warning ("%s: object class `%s' has no property named `%s'",
984 G_OBJECT_TYPE_NAME (object),
988 if (!(pspec->flags & G_PARAM_WRITABLE))
990 g_warning ("%s: property `%s' of object class `%s' is not writable",
993 G_OBJECT_TYPE_NAME (object));
997 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
999 G_VALUE_COLLECT (&value, var_args, &error);
1002 g_warning ("%s: %s", G_STRLOC, error);
1005 /* we purposely leak the value here, it might not be
1006 * in a sane state if an error condition occoured
1011 object_set_property (object, &value, pspec, trailer, nqueue);
1013 g_value_unset (&value);
1015 name = va_arg (var_args, gchar*);
1018 object_thaw_notifies (object, nqueue);
1019 g_object_unref (object);
1023 g_object_get_valist (GObject *object,
1024 const gchar *first_property_name,
1029 g_return_if_fail (G_IS_OBJECT (object));
1031 g_object_ref (object);
1033 name = first_property_name;
1037 const gchar *trailer = NULL;
1038 GValue value = { 0, };
1042 pspec = g_param_spec_pool_lookup (pspec_pool,
1044 G_OBJECT_TYPE (object),
1049 g_warning ("%s: object class `%s' has no property named `%s'",
1051 G_OBJECT_TYPE_NAME (object),
1055 if (!(pspec->flags & G_PARAM_READABLE))
1057 g_warning ("%s: property `%s' of object class `%s' is not readable",
1060 G_OBJECT_TYPE_NAME (object));
1064 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
1066 object_get_property (object, &value, pspec, trailer);
1068 G_VALUE_LCOPY (&value, var_args, &error);
1071 g_warning ("%s: %s", G_STRLOC, error);
1074 /* we purposely leak the value here, it might not be
1075 * in a sane state if an error condition occoured
1080 g_value_unset (&value);
1082 name = va_arg (var_args, gchar*);
1085 g_object_unref (object);
1089 g_object_set (gpointer _object,
1090 const gchar *first_property_name,
1093 GObject *object = _object;
1096 g_return_if_fail (G_IS_OBJECT (object));
1098 va_start (var_args, first_property_name);
1099 g_object_set_valist (object, first_property_name, var_args);
1104 g_object_get (gpointer _object,
1105 const gchar *first_property_name,
1108 GObject *object = _object;
1111 g_return_if_fail (G_IS_OBJECT (object));
1113 va_start (var_args, first_property_name);
1114 g_object_get_valist (object, first_property_name, var_args);
1119 g_object_set_property (GObject *object,
1120 const gchar *property_name,
1121 const GValue *value)
1123 NotifyQueue *nqueue;
1125 const gchar *trailer;
1127 g_return_if_fail (G_IS_OBJECT (object));
1128 g_return_if_fail (property_name != NULL);
1129 g_return_if_fail (G_IS_VALUE (value));
1131 g_object_ref (object);
1132 nqueue = object_freeze_notifies (object);
1134 pspec = g_param_spec_pool_lookup (pspec_pool,
1136 G_OBJECT_TYPE (object),
1140 g_warning ("%s: object class `%s' has no property named `%s'",
1142 G_OBJECT_TYPE_NAME (object),
1146 GValue tmp_value = { 0, };
1148 /* provide a copy to work from and convert if necessary */
1149 g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
1151 if (!g_value_convert (value, &tmp_value) ||
1152 g_param_value_validate (pspec, &tmp_value))
1153 g_warning ("%s: cannot convert `%s' value to property `%s' value of type `%s'",
1155 G_VALUE_TYPE_NAME (value),
1157 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)));
1159 object_set_property (object, &tmp_value, pspec, trailer, nqueue);
1161 g_value_unset (&tmp_value);
1164 object_thaw_notifies (object, nqueue);
1165 g_object_unref (object);
1169 g_object_get_property (GObject *object,
1170 const gchar *property_name,
1174 const gchar *trailer;
1176 g_return_if_fail (G_IS_OBJECT (object));
1177 g_return_if_fail (property_name != NULL);
1178 g_return_if_fail (G_IS_VALUE (value));
1180 g_object_ref (object);
1182 pspec = g_param_spec_pool_lookup (pspec_pool,
1184 G_OBJECT_TYPE (object),
1188 g_warning ("%s: object class `%s' has no property named `%s'",
1190 G_OBJECT_TYPE_NAME (object),
1194 GValue tmp_value = { 0, };
1196 /* provide a copy to work from and later convert if necessary, so
1197 * _get_property() implementations need *not* care about freeing values
1198 * that might be already set in the property to get.
1199 * (though, at this point, GValue should exclusively be modified
1200 * through the accessor functions anyways)
1202 g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
1204 if (!g_value_types_exchangable (G_VALUE_TYPE (value), G_PARAM_SPEC_VALUE_TYPE (pspec)))
1205 g_warning ("%s: can't retrive property `%s' value of type `%s' as value of type `%s'",
1208 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1209 G_VALUE_TYPE_NAME (value));
1212 object_get_property (object, &tmp_value, pspec, trailer);
1213 g_value_convert (&tmp_value, value);
1214 /* g_value_validate (value, pspec); */
1217 g_value_unset (&tmp_value);
1220 g_object_unref (object);
1224 g_object_ref (gpointer _object)
1226 GObject *object = _object;
1228 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1229 g_return_val_if_fail (object->ref_count > 0, NULL);
1231 #ifdef G_ENABLE_DEBUG
1232 if (glib_trap_object_ref == object)
1234 #endif /* G_ENABLE_DEBUG */
1236 object->ref_count += 1;
1242 g_object_unref (gpointer _object)
1244 GObject *object = _object;
1246 g_return_if_fail (G_IS_OBJECT (object));
1247 g_return_if_fail (object->ref_count > 0);
1249 #ifdef G_ENABLE_DEBUG
1250 if (glib_trap_object_ref == object)
1252 #endif /* G_ENABLE_DEBUG */
1254 if (object->ref_count > 1)
1255 object->ref_count -= 1;
1257 g_object_last_unref (object);
1261 g_object_get_qdata (GObject *object,
1264 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1266 return quark ? g_datalist_id_get_data (&object->qdata, quark) : NULL;
1270 g_object_set_qdata (GObject *object,
1274 g_return_if_fail (G_IS_OBJECT (object));
1275 g_return_if_fail (quark > 0);
1277 g_datalist_id_set_data (&object->qdata, quark, data);
1281 g_object_set_qdata_full (GObject *object,
1284 GDestroyNotify destroy)
1286 g_return_if_fail (G_IS_OBJECT (object));
1287 g_return_if_fail (quark > 0);
1289 g_datalist_id_set_data_full (&object->qdata, quark, data, data ? destroy : NULL);
1293 g_object_steal_qdata (GObject *object,
1296 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1297 g_return_val_if_fail (quark > 0, NULL);
1299 return g_datalist_id_remove_no_notify (&object->qdata, quark);
1303 g_object_get_data (GObject *object,
1308 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1309 g_return_val_if_fail (key != NULL, NULL);
1311 quark = g_quark_try_string (key);
1313 return quark ? g_datalist_id_get_data (&object->qdata, quark) : NULL;
1317 g_object_set_data (GObject *object,
1321 g_return_if_fail (G_IS_OBJECT (object));
1322 g_return_if_fail (key != NULL);
1324 g_datalist_id_set_data (&object->qdata, g_quark_from_string (key), data);
1328 g_object_set_data_full (GObject *object,
1331 GDestroyNotify destroy)
1333 g_return_if_fail (G_IS_OBJECT (object));
1334 g_return_if_fail (key != NULL);
1336 g_datalist_id_set_data_full (&object->qdata, g_quark_from_string (key), data, data ? destroy : NULL);
1340 g_object_steal_data (GObject *object,
1345 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1346 g_return_val_if_fail (key != NULL, NULL);
1348 quark = g_quark_try_string (key);
1350 return quark ? g_datalist_id_remove_no_notify (&object->qdata, quark) : NULL;
1354 g_value_object_init (GValue *value)
1356 value->data[0].v_pointer = NULL;
1360 g_value_object_free_value (GValue *value)
1362 if (value->data[0].v_pointer)
1363 g_object_unref (value->data[0].v_pointer);
1367 g_value_object_copy_value (const GValue *src_value,
1370 if (src_value->data[0].v_pointer)
1371 dest_value->data[0].v_pointer = g_object_ref (src_value->data[0].v_pointer);
1373 dest_value->data[0].v_pointer = NULL;
1377 g_value_object_peek_pointer (const GValue *value)
1379 return value->data[0].v_pointer;
1383 g_value_object_collect_value (GValue *value,
1385 GType *collect_type,
1386 GTypeCValue *collect_value)
1388 if (collect_value->v_pointer)
1390 GObject *object = collect_value->v_pointer;
1392 if (object->g_type_instance.g_class == NULL)
1393 return g_strconcat ("invalid unclassed object pointer for value type `",
1394 G_VALUE_TYPE_NAME (value),
1397 else if (!g_type_is_a (G_OBJECT_TYPE (object), G_VALUE_TYPE (value)))
1398 return g_strconcat ("invalid object type `",
1399 G_OBJECT_TYPE_NAME (object),
1400 "' for value type `",
1401 G_VALUE_TYPE_NAME (value),
1404 value->data[0].v_pointer = g_object_ref (object);
1407 value->data[0].v_pointer = NULL;
1414 g_value_object_lcopy_value (const GValue *value,
1416 GType *collect_type,
1417 GTypeCValue *collect_value)
1419 GObject **object_p = collect_value->v_pointer;
1422 return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
1424 *object_p = value->data[0].v_pointer ? g_object_ref (value->data[0].v_pointer) : NULL;
1431 g_value_set_object (GValue *value,
1434 g_return_if_fail (G_IS_VALUE_OBJECT (value));
1436 if (value->data[0].v_pointer)
1438 g_object_unref (value->data[0].v_pointer);
1439 value->data[0].v_pointer = NULL;
1444 g_return_if_fail (G_IS_OBJECT (v_object));
1445 g_return_if_fail (g_type_is_a (G_OBJECT_TYPE (v_object), G_VALUE_TYPE (value)));
1447 value->data[0].v_pointer = v_object;
1448 g_object_ref (value->data[0].v_pointer);
1453 g_value_get_object (const GValue *value)
1455 g_return_val_if_fail (G_IS_VALUE_OBJECT (value), NULL);
1457 return value->data[0].v_pointer;
1461 g_value_dup_object (const GValue *value)
1463 g_return_val_if_fail (G_IS_VALUE_OBJECT (value), NULL);
1465 return value->data[0].v_pointer ? g_object_ref (value->data[0].v_pointer) : NULL;
1469 g_signal_connect_object (gpointer instance,
1470 const gchar *detailed_signal,
1471 GCallback c_handler,
1476 g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
1477 g_return_val_if_fail (detailed_signal != NULL, 0);
1478 g_return_val_if_fail (c_handler != NULL, 0);
1484 g_return_val_if_fail (G_IS_OBJECT (gobject), 0);
1486 closure = (swapped ? g_cclosure_new_object_swap : g_cclosure_new_object) (c_handler, gobject);
1488 return g_signal_connect_closure (instance, detailed_signal, closure, after);
1491 return g_signal_connect_data (instance, detailed_signal, c_handler, NULL, NULL, swapped, after);
1497 GClosure *closures[1]; /* flexible array */
1501 object_remove_closure (gpointer data,
1504 GObject *object = data;
1505 CArray *carray = g_object_get_qdata (object, quark_closure_array);
1508 for (i = 0; i < carray->n_closures; i++)
1509 if (carray->closures[i] == closure)
1511 carray->n_closures--;
1512 if (i < carray->n_closures)
1513 carray->closures[i] = carray->closures[carray->n_closures];
1516 g_assert_not_reached ();
1520 destroy_closure_array (gpointer data)
1522 CArray *carray = data;
1523 GObject *object = carray->object;
1524 guint i, n = carray->n_closures;
1526 for (i = 0; i < n; i++)
1528 GClosure *closure = carray->closures[i];
1530 /* removing object_remove_closure() upfront is probably faster than
1531 * letting it fiddle with quark_closure_array which is empty anyways
1533 g_closure_remove_inotify (closure, object, object_remove_closure);
1534 g_closure_invalidate (closure);
1540 g_object_watch_closure (GObject *object,
1545 g_return_if_fail (G_IS_OBJECT (object));
1546 g_return_if_fail (closure != NULL);
1547 g_return_if_fail (closure->is_invalid == FALSE);
1548 g_return_if_fail (closure->in_marshal == FALSE);
1549 g_return_if_fail (object->ref_count > 0); /* this doesn't work on finalizing objects */
1551 g_closure_add_inotify (closure, object, object_remove_closure);
1552 g_closure_add_marshal_guards (closure,
1553 object, (GClosureNotify) g_object_ref,
1554 object, (GClosureNotify) g_object_unref);
1555 carray = g_object_steal_qdata (object, quark_closure_array);
1558 carray = g_renew (CArray, NULL, 1);
1559 carray->object = object;
1560 carray->n_closures = 1;
1561 carray->closures[0] = closure;
1562 g_object_set_qdata_full (object, quark_closure_array, carray, destroy_closure_array);
1566 guint i = carray->n_closures++;
1568 carray = g_realloc (carray, sizeof (*carray) + sizeof (carray->closures[0]) * i);
1569 carray->closures[i] = closure;
1570 g_object_set_qdata_full (object, quark_closure_array, carray, destroy_closure_array);
1575 g_closure_new_object (guint sizeof_closure,
1580 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1581 g_return_val_if_fail (object->ref_count > 0, NULL); /* this doesn't work on finalizing objects */
1583 closure = g_closure_new_simple (sizeof_closure, object);
1584 g_object_watch_closure (object, closure);
1590 g_cclosure_new_object (GCallback callback_func,
1593 GObject *object = _object;
1596 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1597 g_return_val_if_fail (object->ref_count > 0, NULL); /* this doesn't work on finalizing objects */
1598 g_return_val_if_fail (callback_func != NULL, NULL);
1600 closure = g_cclosure_new (callback_func, object, NULL);
1601 g_object_watch_closure (object, closure);
1607 g_cclosure_new_object_swap (GCallback callback_func,
1610 GObject *object = _object;
1613 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1614 g_return_val_if_fail (object->ref_count > 0, NULL); /* this doesn't work on finalizing objects */
1615 g_return_val_if_fail (callback_func != NULL, NULL);
1617 closure = g_cclosure_new_swap (callback_func, object, NULL);
1618 g_object_watch_closure (object, closure);