1 /* GObject - GLib Type, Object, Parameter and Signal Library
2 * Copyright (C) 1998-1999, 2000-2001 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.
27 #include "gvaluecollector.h"
29 #include "gparamspecs.h"
30 #include "gvaluetypes.h"
34 #define PREALLOC_CPARAMS (8)
38 #define PARAM_SPEC_PARAM_ID(pspec) (GPOINTER_TO_UINT (g_param_spec_get_qdata ((pspec), quark_property_id)))
49 /* --- properties --- */
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 static void g_object_do_get_property (GObject *object,
78 static void g_value_object_init (GValue *value);
79 static void g_value_object_free_value (GValue *value);
80 static void g_value_object_copy_value (const GValue *src_value,
82 static void g_value_object_transform_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,
86 guint n_collect_values,
87 GTypeCValue *collect_values,
89 static gchar* g_value_object_lcopy_value (const GValue *value,
90 guint n_collect_values,
91 GTypeCValue *collect_values,
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 static inline void object_set_property (GObject *object,
113 NotifyQueue *nqueue);
116 /* --- structures --- */
125 /* --- variables --- */
126 static GQuark quark_notify_queue = 0;
127 static GQuark quark_property_id = 0;
128 static GQuark quark_closure_array = 0;
129 static GParamSpecPool *pspec_pool = NULL;
130 static gulong gobject_signals[LAST_SIGNAL] = { 0, };
133 /* --- functions --- */
134 #ifdef G_ENABLE_DEBUG
135 #define IF_DEBUG(debug_type) if (_g_type_debug_flags & G_TYPE_DEBUG_ ## debug_type)
136 G_LOCK_DEFINE_STATIC (debug_objects);
137 static volatile GObject *g_trap_object_ref = NULL;
138 static guint debug_objects_count = 0;
139 static GHashTable *debug_objects_ht = NULL;
141 debug_objects_foreach (gpointer key,
145 GObject *object = value;
147 g_message ("[%p] stale %s\tref_count=%u",
149 G_OBJECT_TYPE_NAME (object),
153 debug_objects_atexit (void)
157 G_LOCK (debug_objects);
158 if (debug_objects_ht)
160 g_message ("stale GObjects: %u", debug_objects_count);
161 g_hash_table_foreach (debug_objects_ht, debug_objects_foreach, NULL);
163 G_UNLOCK (debug_objects);
166 #endif /* G_ENABLE_DEBUG */
169 g_object_type_init (void) /* sync with gtype.c */
171 static gboolean initialized = FALSE;
172 static const GTypeFundamentalInfo finfo = {
173 G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE,
175 static GTypeInfo info = {
176 sizeof (GObjectClass),
177 (GBaseInitFunc) g_object_base_class_init,
178 (GBaseFinalizeFunc) g_object_base_class_finalize,
179 (GClassInitFunc) g_object_do_class_init,
180 NULL /* class_destroy */,
181 NULL /* class_data */,
184 (GInstanceInitFunc) g_object_init,
185 NULL, /* value_table */
187 static const GTypeValueTable value_table = {
188 g_value_object_init, /* value_init */
189 g_value_object_free_value, /* value_free */
190 g_value_object_copy_value, /* value_copy */
191 g_value_object_peek_pointer, /* value_peek_pointer */
192 "p", /* collect_format */
193 g_value_object_collect_value, /* collect_value */
194 "p", /* lcopy_format */
195 g_value_object_lcopy_value, /* lcopy_value */
199 g_return_if_fail (initialized == FALSE);
204 info.value_table = &value_table;
205 type = g_type_register_fundamental (G_TYPE_OBJECT, "GObject", &info, &finfo, 0);
206 g_assert (type == G_TYPE_OBJECT);
207 g_value_register_transform_func (G_TYPE_OBJECT, G_TYPE_OBJECT, g_value_object_transform_value);
209 #ifdef G_ENABLE_DEBUG
211 g_atexit (debug_objects_atexit);
212 #endif /* G_ENABLE_DEBUG */
216 g_object_base_class_init (GObjectClass *class)
218 GObjectClass *pclass = g_type_class_peek_parent (class);
220 /* reset instance specific fields and methods that don't get inherited */
221 class->n_property_specs = 0;
222 class->property_specs = NULL;
223 class->construct_properties = pclass ? g_slist_copy (pclass->construct_properties) : NULL;
224 class->get_property = NULL;
225 class->set_property = NULL;
229 g_object_base_class_finalize (GObjectClass *class)
233 g_message ("finallizing base class of %s", G_OBJECT_CLASS_NAME (class));
235 _g_signals_destroy (G_OBJECT_CLASS_TYPE (class));
237 g_slist_free (class->construct_properties);
238 class->construct_properties = NULL;
239 for (i = 0; i < class->n_property_specs; i++)
241 GParamSpec *pspec = class->property_specs[i];
243 g_param_spec_pool_remove (pspec_pool, pspec);
244 g_param_spec_set_qdata (pspec, quark_property_id, NULL);
245 g_param_spec_unref (pspec);
247 class->n_property_specs = 0;
248 g_free (class->property_specs);
249 class->property_specs = NULL;
253 g_object_do_class_init (GObjectClass *class)
255 quark_notify_queue = g_quark_from_static_string ("GObject-notify-queue");
256 quark_property_id = g_quark_from_static_string ("GObject-property-id");
257 quark_closure_array = g_quark_from_static_string ("GObject-closure-array");
258 pspec_pool = g_param_spec_pool_new (TRUE);
260 class->constructor = g_object_constructor;
261 class->set_property = g_object_do_set_property;
262 class->get_property = g_object_do_get_property;
263 class->shutdown = g_object_shutdown;
264 class->finalize = g_object_finalize;
265 class->dispatch_properties_changed = g_object_dispatch_properties_changed;
266 class->properties_changed = g_object_properties_changed;
267 class->notify = g_object_notify_property_changed;
269 gobject_signals[PROPERTIES_CHANGED] =
270 g_signal_newc ("properties_changed",
271 G_TYPE_FROM_CLASS (class),
272 G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
273 G_STRUCT_OFFSET (GObjectClass, properties_changed),
275 g_cclosure_marshal_VOID__UINT_POINTER,
277 2, G_TYPE_UINT, G_TYPE_POINTER);
278 gobject_signals[NOTIFY] =
279 g_signal_newc ("notify",
280 G_TYPE_FROM_CLASS (class),
281 G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED | G_SIGNAL_NO_HOOKS,
282 G_STRUCT_OFFSET (GObjectClass, notify),
284 g_cclosure_marshal_VOID__PARAM,
290 g_object_class_install_property (GObjectClass *class,
296 g_return_if_fail (G_IS_OBJECT_CLASS (class));
297 g_return_if_fail (G_IS_PARAM_SPEC (pspec));
298 if (pspec->flags & G_PARAM_WRITABLE)
299 g_return_if_fail (class->set_property != NULL);
300 if (pspec->flags & G_PARAM_READABLE)
301 g_return_if_fail (class->get_property != NULL);
302 g_return_if_fail (property_id > 0);
303 g_return_if_fail (PARAM_SPEC_PARAM_ID (pspec) == 0); /* paranoid */
304 if (pspec->flags & G_PARAM_CONSTRUCT)
305 g_return_if_fail ((pspec->flags & G_PARAM_CONSTRUCT_ONLY) == 0);
306 if (pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY))
307 g_return_if_fail (pspec->flags & G_PARAM_WRITABLE);
309 /* expensive paranoia checks ;( */
310 for (i = 0; i < class->n_property_specs; i++)
311 if (PARAM_SPEC_PARAM_ID (class->property_specs[i]) == property_id)
313 g_warning (G_STRLOC ": class `%s' already contains a property `%s' with id %u, "
314 "cannot install property `%s'",
315 G_OBJECT_CLASS_NAME (class),
316 class->property_specs[i]->name,
321 if (g_param_spec_pool_lookup (pspec_pool, pspec->name, G_OBJECT_CLASS_TYPE (class), FALSE))
323 g_warning (G_STRLOC ": class `%s' already contains a property named `%s'",
324 G_OBJECT_CLASS_NAME (class),
329 g_param_spec_ref (pspec);
330 g_param_spec_sink (pspec);
331 g_param_spec_set_qdata (pspec, quark_property_id, GUINT_TO_POINTER (property_id));
332 g_param_spec_pool_insert (pspec_pool, pspec, G_OBJECT_CLASS_TYPE (class));
333 i = class->n_property_specs++;
334 class->property_specs = g_renew (GParamSpec*, class->property_specs, class->n_property_specs);
335 class->property_specs[i] = pspec;
336 if (pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY))
337 class->construct_properties = g_slist_prepend (class->construct_properties, pspec);
339 /* for property overrides of construct poperties, we have to get rid
340 * of the overidden inherited construct property
342 pspec = g_param_spec_pool_lookup (pspec_pool, pspec->name, g_type_parent (G_OBJECT_CLASS_TYPE (class)), TRUE);
343 if (pspec && pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY))
344 class->construct_properties = g_slist_remove (class->construct_properties, pspec);
348 g_object_class_find_property (GObjectClass *class,
349 const gchar *property_name)
351 g_return_val_if_fail (G_IS_OBJECT_CLASS (class), NULL);
352 g_return_val_if_fail (property_name != NULL, NULL);
354 return g_param_spec_pool_lookup (pspec_pool,
356 G_OBJECT_CLASS_TYPE (class),
361 free_notify_queue (gpointer data)
363 NotifyQueue *nqueue = data;
365 g_slist_free (nqueue->pspecs);
369 static inline NotifyQueue*
370 object_freeze_notifies (GObject *object)
374 nqueue = g_object_get_qdata (object, quark_notify_queue);
377 nqueue = g_new0 (NotifyQueue, 1);
378 g_object_set_qdata_full (object, quark_notify_queue, nqueue, free_notify_queue);
380 nqueue->freeze_count++;
386 object_queue_property (GObject *object,
390 if (pspec->flags & G_PARAM_READABLE)
392 /* we will dedup later */
393 nqueue->pspecs = g_slist_prepend (nqueue->pspecs, pspec);
399 g_object_init (GObject *object)
401 object->ref_count = 1;
402 g_datalist_init (&object->qdata);
404 /* freeze object's notification queue, g_object_new_valist() takes care of that */
405 object_freeze_notifies (object);
407 #ifdef G_ENABLE_DEBUG
410 G_LOCK (debug_objects);
411 if (!debug_objects_ht)
412 debug_objects_ht = g_hash_table_new (g_direct_hash, NULL);
413 debug_objects_count++;
414 g_hash_table_insert (debug_objects_ht, object, object);
415 G_UNLOCK (debug_objects);
417 #endif /* G_ENABLE_DEBUG */
421 g_object_do_set_property (GObject *object,
429 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
435 g_object_do_get_property (GObject *object,
443 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
449 g_object_last_unref (GObject *object)
451 g_return_if_fail (object->ref_count > 0);
453 if (object->ref_count == 1) /* may have been re-referenced meanwhile */
454 G_OBJECT_GET_CLASS (object)->shutdown (object);
456 #ifdef G_ENABLE_DEBUG
457 if (g_trap_object_ref == object)
459 #endif /* G_ENABLE_DEBUG */
461 object->ref_count -= 1;
463 if (object->ref_count == 0) /* may have been re-referenced meanwhile */
465 g_signal_handlers_destroy (object);
466 g_object_set_qdata (object, quark_closure_array, NULL);
467 G_OBJECT_GET_CLASS (object)->finalize (object);
468 #ifdef G_ENABLE_DEBUG
471 G_LOCK (debug_objects);
472 if (debug_objects_ht)
473 g_assert (g_hash_table_lookup (debug_objects_ht, object) == NULL);
474 G_UNLOCK (debug_objects);
476 #endif /* G_ENABLE_DEBUG */
477 g_type_free_instance ((GTypeInstance*) object);
482 g_object_shutdown (GObject *object)
484 /* this function needs to be always present for unconditional
485 * chaining, we also might add some code here later.
486 * beware though, subclasses may invoke shutdown() arbitrarily.
491 g_object_finalize (GObject *object)
493 g_signal_handlers_destroy (object);
494 g_datalist_clear (&object->qdata);
496 #ifdef G_ENABLE_DEBUG
499 G_LOCK (debug_objects);
500 g_assert (g_hash_table_lookup (debug_objects_ht, object) == object);
501 g_hash_table_remove (debug_objects_ht, object);
502 debug_objects_count--;
503 G_UNLOCK (debug_objects);
505 #endif /* G_ENABLE_DEBUG */
509 object_thaw_notifies (GObject *object,
516 nqueue->freeze_count--;
517 if (nqueue->freeze_count)
519 g_return_if_fail (object->ref_count > 0);
521 pspecs = g_new (GParamSpec*, nqueue->n_pspecs);
522 for (slist = nqueue->pspecs; slist; slist = slist->next)
524 GParamSpec *pspec = slist->data;
527 /* dedup, make pspecs in the list unique */
529 if (pspecs[i] == pspec)
532 goto redo_dedup_check;
534 pspecs[n_pspecs++] = pspec;
536 g_object_set_qdata (object, quark_notify_queue, NULL);
539 G_OBJECT_GET_CLASS (object)->dispatch_properties_changed (object, n_pspecs, pspecs);
545 g_object_dispatch_properties_changed (GObject *object,
549 g_signal_emit (object, gobject_signals[PROPERTIES_CHANGED], 0, n_pspecs, pspecs);
553 g_object_properties_changed (GObject *object,
559 for (i = 0; i < n_pspecs; i++)
560 g_signal_emit (object, gobject_signals[NOTIFY], g_quark_from_string (pspecs[i]->name), pspecs[i]);
564 g_object_notify_property_changed (GObject *object,
568 g_message ("NOTIFICATION: property `%s' changed on object `%s'",
570 G_OBJECT_TYPE_NAME (object));
574 g_object_freeze_notify (GObject *object)
576 g_return_if_fail (G_IS_OBJECT (object));
577 if (!object->ref_count)
580 g_object_ref (object);
581 object_freeze_notifies (object);
582 g_object_unref (object);
586 g_object_notify (GObject *object,
587 const gchar *property_name)
591 g_return_if_fail (G_IS_OBJECT (object));
592 g_return_if_fail (property_name != NULL);
593 if (!object->ref_count)
596 g_object_ref (object);
597 pspec = g_param_spec_pool_lookup (pspec_pool,
599 G_OBJECT_TYPE (object),
602 g_warning ("%s: object class `%s' has no property named `%s'",
604 G_OBJECT_TYPE_NAME (object),
608 NotifyQueue *nqueue = object_freeze_notifies (object);
610 object_queue_property (object, pspec, nqueue);
611 object_thaw_notifies (object, nqueue);
613 g_object_unref (object);
617 g_object_thaw_notify (GObject *object)
621 g_return_if_fail (G_IS_OBJECT (object));
622 if (!object->ref_count)
625 g_object_ref (object);
626 nqueue = g_object_get_qdata (object, quark_notify_queue);
627 if (!nqueue || !nqueue->freeze_count)
628 g_warning (G_STRLOC ": property-changed notification for %s(%p) is not frozen",
629 G_OBJECT_TYPE_NAME (object), object);
631 object_thaw_notifies (object, nqueue);
632 g_object_unref (object);
636 object_get_property (GObject *object,
642 class = g_type_class_peek (pspec->owner_type);
644 class->get_property (object, PARAM_SPEC_PARAM_ID (pspec), value, pspec);
648 object_set_property (GObject *object,
653 GValue tmp_value = { 0, };
654 GObjectClass *class = g_type_class_peek (pspec->owner_type);
656 /* provide a copy to work from, convert (if necessary) and validate */
657 g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
658 if (!g_value_transform (value, &tmp_value))
659 g_warning ("unable to set property `%s' of type `%s' from value of type `%s'",
661 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
662 G_VALUE_TYPE_NAME (value));
663 else if (g_param_value_validate (pspec, &tmp_value) && !(pspec->flags & G_PARAM_LAX_VALIDATION))
665 gchar *contents = g_strdup_value_contents (value);
667 g_warning ("value \"%s\" of type `%s' is invalid for property `%s' of type `%s'",
669 G_VALUE_TYPE_NAME (value),
671 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)));
676 class->set_property (object, PARAM_SPEC_PARAM_ID (pspec), &tmp_value, pspec);
677 object_queue_property (object, pspec, nqueue);
679 g_value_unset (&tmp_value);
683 g_object_new (GType object_type,
684 const gchar *first_property_name,
690 g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type), NULL);
692 va_start (var_args, first_property_name);
693 object = g_object_new_valist (object_type, first_property_name, var_args);
700 g_object_new_valist (GType object_type,
701 const gchar *first_property_name,
708 GObjectConstructParam *cparams = NULL, *nparams = NULL;
709 guint n_cparams = 0, n_nparams = 0;
712 g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type), NULL);
714 class = g_type_class_ref (object_type);
715 clist = g_slist_copy (class->construct_properties);
717 /* collect parameters, sort into construction and normal ones */
718 name = first_property_name;
725 pspec = g_param_spec_pool_lookup (pspec_pool,
731 g_warning ("%s: object class `%s' has no property named `%s'",
733 g_type_name (object_type),
737 if (!(pspec->flags & G_PARAM_WRITABLE))
739 g_warning ("%s: property `%s' of object class `%s' is not writable",
742 g_type_name (object_type));
746 value = g_new (GValue, 1);
748 g_value_init (value, G_PARAM_SPEC_VALUE_TYPE (pspec));
749 G_VALUE_COLLECT (value, var_args, 0, &error);
752 g_warning ("%s: %s", G_STRLOC, error);
755 /* we purposely leak the value here, it might not be
756 * in a sane state if an error condition occoured
760 if (pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY))
764 if (!n_cparams || n_cparams >= PREALLOC_CPARAMS)
765 cparams = g_renew (GObjectConstructParam, cparams, MAX (n_cparams + 1, PREALLOC_CPARAMS));
766 cparams[n_cparams].pspec = pspec;
767 cparams[n_cparams].value = value;
768 for (i = 0; i < n_cparams; i++) /* picky, aren't we? ;) */
769 if (cparams[i].pspec == pspec)
770 g_warning (G_STRLOC ": construct property \"%s\" for object `%s' is being set twice",
771 pspec->name, g_type_name (object_type));
773 clist = g_slist_remove (clist, pspec); /* FIXME: unique */
777 if (!n_nparams || n_nparams >= PREALLOC_CPARAMS)
778 nparams = g_renew (GObjectConstructParam, nparams, MAX (n_nparams + 1, PREALLOC_CPARAMS));
779 nparams[n_nparams].pspec = pspec;
780 nparams[n_nparams].value = value;
784 name = va_arg (var_args, gchar*);
787 /* construct object from construction parameters */
790 GSList *tmp = clist->next;
791 GParamSpec *pspec = clist->data;
792 GValue *value = g_new (GValue, 1);
795 g_value_init (value, G_PARAM_SPEC_VALUE_TYPE (pspec));
796 g_param_value_set_default (pspec, value);
798 if (!n_cparams || n_cparams >= PREALLOC_CPARAMS)
799 cparams = g_renew (GObjectConstructParam, cparams, MAX (n_cparams + 1, PREALLOC_CPARAMS));
800 cparams[n_cparams].pspec = pspec;
801 cparams[n_cparams].value = value;
804 g_slist_free_1 (clist);
807 object = class->constructor (object_type, n_cparams, cparams);
809 /* free construction values */
812 g_value_unset (cparams[n_cparams].value);
813 g_free (cparams[n_cparams].value);
817 /* release g_object_init() notification queue freeze_count */
818 nqueue = object_freeze_notifies (object);
819 nqueue->freeze_count--;
821 /* set remaining properties */
825 GValue *value = nparams->value;
826 GParamSpec *pspec = nparams->pspec;
829 object_set_property (object, pspec, value, nqueue);
830 g_value_unset (value);
835 g_type_class_unref (class);
837 /* release our own freeze count and handle notifications */
838 object_thaw_notifies (object, nqueue);
844 g_object_constructor (GType type,
845 guint n_construct_properties,
846 GObjectConstructParam *construct_params)
851 object = (GObject*) g_type_create_instance (type);
853 /* set construction parameters */
854 if (n_construct_properties)
856 NotifyQueue *nqueue = object_freeze_notifies (object);
858 /* set construct properties */
859 while (n_construct_properties--)
861 GValue *value = construct_params->value;
862 GParamSpec *pspec = construct_params->pspec;
865 object_set_property (object, pspec, value, nqueue);
867 nqueue->freeze_count--;
868 /* the notification queue is still frozen from g_object_init(), so
869 * we don't need to handle it here, g_object_new_valist() takes
878 g_object_set_valist (GObject *object,
879 const gchar *first_property_name,
885 g_return_if_fail (G_IS_OBJECT (object));
887 g_object_ref (object);
888 nqueue = object_freeze_notifies (object);
890 name = first_property_name;
893 GValue value = { 0, };
897 pspec = g_param_spec_pool_lookup (pspec_pool,
899 G_OBJECT_TYPE (object),
903 g_warning ("%s: object class `%s' has no property named `%s'",
905 G_OBJECT_TYPE_NAME (object),
909 if (!(pspec->flags & G_PARAM_WRITABLE))
911 g_warning ("%s: property `%s' of object class `%s' is not writable",
914 G_OBJECT_TYPE_NAME (object));
918 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
920 G_VALUE_COLLECT (&value, var_args, 0, &error);
923 g_warning ("%s: %s", G_STRLOC, error);
926 /* we purposely leak the value here, it might not be
927 * in a sane state if an error condition occoured
932 object_set_property (object, pspec, &value, nqueue);
933 g_value_unset (&value);
935 name = va_arg (var_args, gchar*);
938 object_thaw_notifies (object, nqueue);
939 g_object_unref (object);
943 g_object_get_valist (GObject *object,
944 const gchar *first_property_name,
949 g_return_if_fail (G_IS_OBJECT (object));
951 g_object_ref (object);
953 name = first_property_name;
957 GValue value = { 0, };
961 pspec = g_param_spec_pool_lookup (pspec_pool,
963 G_OBJECT_TYPE (object),
967 g_warning ("%s: object class `%s' has no property named `%s'",
969 G_OBJECT_TYPE_NAME (object),
973 if (!(pspec->flags & G_PARAM_READABLE))
975 g_warning ("%s: property `%s' of object class `%s' is not readable",
978 G_OBJECT_TYPE_NAME (object));
982 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
984 object_get_property (object, pspec, &value);
986 G_VALUE_LCOPY (&value, var_args, G_VALUE_NOCOPY_CONTENTS, &error);
989 g_warning ("%s: %s", G_STRLOC, error);
991 g_value_unset (&value);
995 g_value_unset (&value);
997 name = va_arg (var_args, gchar*);
1000 g_object_unref (object);
1004 g_object_set (gpointer _object,
1005 const gchar *first_property_name,
1008 GObject *object = _object;
1011 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1013 va_start (var_args, first_property_name);
1014 g_object_set_valist (object, first_property_name, var_args);
1021 g_object_get (gpointer _object,
1022 const gchar *first_property_name,
1025 GObject *object = _object;
1028 g_return_if_fail (G_IS_OBJECT (object));
1030 va_start (var_args, first_property_name);
1031 g_object_get_valist (object, first_property_name, var_args);
1036 g_object_set_property (GObject *object,
1037 const gchar *property_name,
1038 const GValue *value)
1040 NotifyQueue *nqueue;
1043 g_return_if_fail (G_IS_OBJECT (object));
1044 g_return_if_fail (property_name != NULL);
1045 g_return_if_fail (G_IS_VALUE (value));
1047 g_object_ref (object);
1048 nqueue = object_freeze_notifies (object);
1050 pspec = g_param_spec_pool_lookup (pspec_pool,
1052 G_OBJECT_TYPE (object),
1055 g_warning ("%s: object class `%s' has no property named `%s'",
1057 G_OBJECT_TYPE_NAME (object),
1060 object_set_property (object, pspec, value, nqueue);
1062 object_thaw_notifies (object, nqueue);
1063 g_object_unref (object);
1067 g_object_get_property (GObject *object,
1068 const gchar *property_name,
1073 g_return_if_fail (G_IS_OBJECT (object));
1074 g_return_if_fail (property_name != NULL);
1075 g_return_if_fail (G_IS_VALUE (value));
1077 g_object_ref (object);
1079 pspec = g_param_spec_pool_lookup (pspec_pool,
1081 G_OBJECT_TYPE (object),
1084 g_warning ("%s: object class `%s' has no property named `%s'",
1086 G_OBJECT_TYPE_NAME (object),
1090 GValue *prop_value, tmp_value = { 0, };
1092 /* auto-conversion of the callers value type
1094 if (G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (pspec))
1096 g_value_reset (value);
1099 else if (!g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec), G_VALUE_TYPE (value)))
1101 g_warning ("can't retrive property `%s' of type `%s' as value of type `%s'",
1103 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
1104 G_VALUE_TYPE_NAME (value));
1105 g_object_unref (object);
1110 g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
1111 prop_value = &tmp_value;
1113 object_get_property (object, pspec, prop_value);
1114 if (prop_value != value)
1116 g_value_transform (prop_value, value);
1117 g_value_unset (&tmp_value);
1121 g_object_unref (object);
1125 g_object_connect (gpointer _object,
1126 const gchar *signal_spec,
1129 GObject *object = _object;
1132 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1133 g_return_val_if_fail (object->ref_count > 0, object);
1135 va_start (var_args, signal_spec);
1138 gpointer callback = va_arg (var_args, gpointer);
1139 gpointer data = va_arg (var_args, gpointer);
1142 if (strncmp (signal_spec, "signal::", 8) == 0)
1143 sid = g_signal_connect_data (object, signal_spec + 8,
1144 callback, data, NULL,
1146 else if (strncmp (signal_spec, "swapped_signal::", 16) == 0)
1147 sid = g_signal_connect_data (object, signal_spec + 16,
1148 callback, data, NULL,
1150 else if (strncmp (signal_spec, "signal_after::", 14) == 0)
1151 sid = g_signal_connect_data (object, signal_spec + 14,
1152 callback, data, NULL,
1154 else if (strncmp (signal_spec, "swapped_signal_after::", 22) == 0)
1155 sid = g_signal_connect_data (object, signal_spec + 22,
1156 callback, data, NULL,
1160 g_warning ("%s: invalid signal spec \"%s\"", G_STRLOC, signal_spec);
1163 signal_spec = va_arg (var_args, gchar*);
1171 g_object_disconnect (gpointer _object,
1172 const gchar *signal_spec,
1175 GObject *object = _object;
1178 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1179 g_return_val_if_fail (object->ref_count > 0, object);
1181 va_start (var_args, signal_spec);
1184 gpointer callback = va_arg (var_args, gpointer);
1185 gpointer data = va_arg (var_args, gpointer);
1186 guint sid = 0, detail = 0, mask = 0;
1188 if (strncmp (signal_spec, "any_signal::", 12) == 0)
1191 mask = G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA;
1193 else if (strcmp (signal_spec, "any_signal") == 0)
1196 mask = G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA;
1200 g_warning ("%s: invalid signal spec \"%s\"", G_STRLOC, signal_spec);
1204 if ((mask & G_SIGNAL_MATCH_ID) &&
1205 !g_signal_parse_name (signal_spec, G_OBJECT_TYPE (object), &sid, &detail, FALSE))
1206 g_warning ("%s: invalid signal name \"%s\"", G_STRLOC, signal_spec);
1207 else if (!g_signal_handlers_disconnect_matched (object, mask | (detail ? G_SIGNAL_MATCH_DETAIL : 0),
1209 NULL, callback, data))
1210 g_warning (G_STRLOC ": signal handler %p(%p) is not connected", callback, data);
1211 signal_spec = va_arg (var_args, gchar*);
1219 g_object_ref (gpointer _object)
1221 GObject *object = _object;
1223 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1224 g_return_val_if_fail (object->ref_count > 0, NULL);
1226 #ifdef G_ENABLE_DEBUG
1227 if (g_trap_object_ref == object)
1229 #endif /* G_ENABLE_DEBUG */
1231 object->ref_count += 1;
1237 g_object_unref (gpointer _object)
1239 GObject *object = _object;
1241 g_return_if_fail (G_IS_OBJECT (object));
1242 g_return_if_fail (object->ref_count > 0);
1244 #ifdef G_ENABLE_DEBUG
1245 if (g_trap_object_ref == object)
1247 #endif /* G_ENABLE_DEBUG */
1249 if (object->ref_count > 1)
1250 object->ref_count -= 1;
1252 g_object_last_unref (object);
1256 g_object_get_qdata (GObject *object,
1259 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1261 return quark ? g_datalist_id_get_data (&object->qdata, quark) : NULL;
1265 g_object_set_qdata (GObject *object,
1269 g_return_if_fail (G_IS_OBJECT (object));
1270 g_return_if_fail (quark > 0);
1272 g_datalist_id_set_data (&object->qdata, quark, data);
1276 g_object_set_qdata_full (GObject *object,
1279 GDestroyNotify destroy)
1281 g_return_if_fail (G_IS_OBJECT (object));
1282 g_return_if_fail (quark > 0);
1284 g_datalist_id_set_data_full (&object->qdata, quark, data, data ? destroy : NULL);
1288 g_object_steal_qdata (GObject *object,
1291 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1292 g_return_val_if_fail (quark > 0, NULL);
1294 return g_datalist_id_remove_no_notify (&object->qdata, quark);
1298 g_object_get_data (GObject *object,
1303 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1304 g_return_val_if_fail (key != NULL, NULL);
1306 quark = g_quark_try_string (key);
1308 return quark ? g_datalist_id_get_data (&object->qdata, quark) : NULL;
1312 g_object_set_data (GObject *object,
1316 g_return_if_fail (G_IS_OBJECT (object));
1317 g_return_if_fail (key != NULL);
1319 g_datalist_id_set_data (&object->qdata, g_quark_from_string (key), data);
1323 g_object_set_data_full (GObject *object,
1326 GDestroyNotify destroy)
1328 g_return_if_fail (G_IS_OBJECT (object));
1329 g_return_if_fail (key != NULL);
1331 g_datalist_id_set_data_full (&object->qdata, g_quark_from_string (key), data, data ? destroy : NULL);
1335 g_object_steal_data (GObject *object,
1340 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1341 g_return_val_if_fail (key != NULL, NULL);
1343 quark = g_quark_try_string (key);
1345 return quark ? g_datalist_id_remove_no_notify (&object->qdata, quark) : NULL;
1349 g_value_object_init (GValue *value)
1351 value->data[0].v_pointer = NULL;
1355 g_value_object_free_value (GValue *value)
1357 if (value->data[0].v_pointer)
1358 g_object_unref (value->data[0].v_pointer);
1362 g_value_object_copy_value (const GValue *src_value,
1365 if (src_value->data[0].v_pointer)
1366 dest_value->data[0].v_pointer = g_object_ref (src_value->data[0].v_pointer);
1368 dest_value->data[0].v_pointer = NULL;
1372 g_value_object_transform_value (const GValue *src_value,
1375 if (src_value->data[0].v_pointer && g_type_is_a (G_OBJECT_TYPE (src_value->data[0].v_pointer), G_VALUE_TYPE (dest_value)))
1376 dest_value->data[0].v_pointer = g_object_ref (src_value->data[0].v_pointer);
1378 dest_value->data[0].v_pointer = NULL;
1382 g_value_object_peek_pointer (const GValue *value)
1384 return value->data[0].v_pointer;
1388 g_value_object_collect_value (GValue *value,
1389 guint n_collect_values,
1390 GTypeCValue *collect_values,
1391 guint collect_flags)
1393 if (collect_values[0].v_pointer)
1395 GObject *object = collect_values[0].v_pointer;
1397 if (object->g_type_instance.g_class == NULL)
1398 return g_strconcat ("invalid unclassed object pointer for value type `",
1399 G_VALUE_TYPE_NAME (value),
1402 else if (!g_value_type_compatible (G_OBJECT_TYPE (object), G_VALUE_TYPE (value)))
1403 return g_strconcat ("invalid object type `",
1404 G_OBJECT_TYPE_NAME (object),
1405 "' for value type `",
1406 G_VALUE_TYPE_NAME (value),
1409 /* never honour G_VALUE_NOCOPY_CONTENTS for ref-counted types */
1410 value->data[0].v_pointer = g_object_ref (object);
1413 value->data[0].v_pointer = NULL;
1419 g_value_object_lcopy_value (const GValue *value,
1420 guint n_collect_values,
1421 GTypeCValue *collect_values,
1422 guint collect_flags)
1424 GObject **object_p = collect_values[0].v_pointer;
1427 return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
1429 if (!value->data[0].v_pointer)
1431 else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
1432 *object_p = value->data[0].v_pointer;
1434 *object_p = g_object_ref (value->data[0].v_pointer);
1440 g_value_set_object (GValue *value,
1443 g_return_if_fail (G_VALUE_HOLDS_OBJECT (value));
1445 if (value->data[0].v_pointer)
1447 g_object_unref (value->data[0].v_pointer);
1448 value->data[0].v_pointer = NULL;
1453 g_return_if_fail (G_IS_OBJECT (v_object));
1454 g_return_if_fail (g_value_type_compatible (G_OBJECT_TYPE (v_object), G_VALUE_TYPE (value)));
1456 value->data[0].v_pointer = v_object;
1457 g_object_ref (value->data[0].v_pointer);
1462 g_value_get_object (const GValue *value)
1464 g_return_val_if_fail (G_VALUE_HOLDS_OBJECT (value), NULL);
1466 return value->data[0].v_pointer;
1470 g_value_dup_object (const GValue *value)
1472 g_return_val_if_fail (G_VALUE_HOLDS_OBJECT (value), NULL);
1474 return value->data[0].v_pointer ? g_object_ref (value->data[0].v_pointer) : NULL;
1478 g_signal_connect_object (gpointer instance,
1479 const gchar *detailed_signal,
1480 GCallback c_handler,
1485 g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
1486 g_return_val_if_fail (detailed_signal != NULL, 0);
1487 g_return_val_if_fail (c_handler != NULL, 0);
1493 g_return_val_if_fail (G_IS_OBJECT (gobject), 0);
1495 closure = (swapped ? g_cclosure_new_object_swap : g_cclosure_new_object) (c_handler, gobject);
1497 return g_signal_connect_closure (instance, detailed_signal, closure, after);
1500 return g_signal_connect_data (instance, detailed_signal, c_handler, NULL, NULL, swapped, after);
1506 GClosure *closures[1]; /* flexible array */
1510 object_remove_closure (gpointer data,
1513 GObject *object = data;
1514 CArray *carray = g_object_get_qdata (object, quark_closure_array);
1517 for (i = 0; i < carray->n_closures; i++)
1518 if (carray->closures[i] == closure)
1520 carray->n_closures--;
1521 if (i < carray->n_closures)
1522 carray->closures[i] = carray->closures[carray->n_closures];
1525 g_assert_not_reached ();
1529 destroy_closure_array (gpointer data)
1531 CArray *carray = data;
1532 GObject *object = carray->object;
1533 guint i, n = carray->n_closures;
1535 for (i = 0; i < n; i++)
1537 GClosure *closure = carray->closures[i];
1539 /* removing object_remove_closure() upfront is probably faster than
1540 * letting it fiddle with quark_closure_array which is empty anyways
1542 g_closure_remove_invalidate_notifier (closure, object, object_remove_closure);
1543 g_closure_invalidate (closure);
1549 g_object_watch_closure (GObject *object,
1554 g_return_if_fail (G_IS_OBJECT (object));
1555 g_return_if_fail (closure != NULL);
1556 g_return_if_fail (closure->is_invalid == FALSE);
1557 g_return_if_fail (closure->in_marshal == FALSE);
1558 g_return_if_fail (object->ref_count > 0); /* this doesn't work on finalizing objects */
1560 g_closure_add_invalidate_notifier (closure, object, object_remove_closure);
1561 g_closure_add_marshal_guards (closure,
1562 object, (GClosureNotify) g_object_ref,
1563 object, (GClosureNotify) g_object_unref);
1564 carray = g_object_steal_qdata (object, quark_closure_array);
1567 carray = g_renew (CArray, NULL, 1);
1568 carray->object = object;
1569 carray->n_closures = 1;
1570 carray->closures[0] = closure;
1571 g_object_set_qdata_full (object, quark_closure_array, carray, destroy_closure_array);
1575 guint i = carray->n_closures++;
1577 carray = g_realloc (carray, sizeof (*carray) + sizeof (carray->closures[0]) * i);
1578 carray->closures[i] = closure;
1579 g_object_set_qdata_full (object, quark_closure_array, carray, destroy_closure_array);
1584 g_closure_new_object (guint sizeof_closure,
1589 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1590 g_return_val_if_fail (object->ref_count > 0, NULL); /* this doesn't work on finalizing objects */
1592 closure = g_closure_new_simple (sizeof_closure, object);
1593 g_object_watch_closure (object, closure);
1599 g_cclosure_new_object (GCallback callback_func,
1602 GObject *object = _object;
1605 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1606 g_return_val_if_fail (object->ref_count > 0, NULL); /* this doesn't work on finalizing objects */
1607 g_return_val_if_fail (callback_func != NULL, NULL);
1609 closure = g_cclosure_new (callback_func, object, NULL);
1610 g_object_watch_closure (object, closure);
1616 g_cclosure_new_object_swap (GCallback callback_func,
1619 GObject *object = _object;
1622 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
1623 g_return_val_if_fail (object->ref_count > 0, NULL); /* this doesn't work on finalizing objects */
1624 g_return_val_if_fail (callback_func != NULL, NULL);
1626 closure = g_cclosure_new_swap (callback_func, object, NULL);
1627 g_object_watch_closure (object, closure);