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.
25 #include "gvaluecollector.h"
27 #include "gparamspecs.h"
28 #include "gvaluetypes.h"
29 #include "gobjectnotifyqueue.c"
33 #define PREALLOC_CPARAMS (8)
37 #define PARAM_SPEC_PARAM_ID(pspec) ((pspec)->param_id)
38 #define PARAM_SPEC_SET_PARAM_ID(pspec, id) ((pspec)->param_id = (id))
49 /* --- properties --- */
55 /* --- prototypes --- */
56 static void g_object_base_class_init (GObjectClass
*class);
57 static void g_object_base_class_finalize (GObjectClass
*class);
58 static void g_object_do_class_init (GObjectClass
*class);
59 static void g_object_init (GObject
*object
);
60 static GObject
* g_object_constructor (GType type
,
61 guint n_construct_properties
,
62 GObjectConstructParam
*construct_params
);
63 static void g_object_last_unref (GObject
*object
);
64 static void g_object_real_dispose (GObject
*object
);
65 static void g_object_finalize (GObject
*object
);
66 static void g_object_do_set_property (GObject
*object
,
70 static void g_object_do_get_property (GObject
*object
,
74 static void g_value_object_init (GValue
*value
);
75 static void g_value_object_free_value (GValue
*value
);
76 static void g_value_object_copy_value (const GValue
*src_value
,
78 static void g_value_object_transform_value (const GValue
*src_value
,
80 static gpointer
g_value_object_peek_pointer (const GValue
*value
);
81 static gchar
* g_value_object_collect_value (GValue
*value
,
82 guint n_collect_values
,
83 GTypeCValue
*collect_values
,
85 static gchar
* g_value_object_lcopy_value (const GValue
*value
,
86 guint n_collect_values
,
87 GTypeCValue
*collect_values
,
89 static void g_object_dispatch_properties_changed (GObject
*object
,
92 static inline void object_get_property (GObject
*object
,
95 static inline void object_set_property (GObject
*object
,
98 GObjectNotifyQueue
*nqueue
);
101 /* --- variables --- */
102 static GQuark quark_closure_array
= 0;
103 static GQuark quark_weak_refs
= 0;
104 static GParamSpecPool
*pspec_pool
= NULL
;
105 static GObjectNotifyContext property_notify_context
= { 0, };
106 static gulong gobject_signals
[LAST_SIGNAL
] = { 0, };
109 /* --- functions --- */
110 #ifdef G_ENABLE_DEBUG
111 #define IF_DEBUG(debug_type) if (_g_type_debug_flags & G_TYPE_DEBUG_ ## debug_type)
112 G_LOCK_DEFINE_STATIC (debug_objects
);
113 static volatile GObject
*g_trap_object_ref
= NULL
;
114 static guint debug_objects_count
= 0;
115 static GHashTable
*debug_objects_ht
= NULL
;
117 debug_objects_foreach (gpointer key
,
121 GObject
*object
= value
;
123 g_message ("[%p] stale %s\tref_count=%u",
125 G_OBJECT_TYPE_NAME (object
),
129 debug_objects_atexit (void)
133 G_LOCK (debug_objects
);
134 g_message ("stale GObjects: %u", debug_objects_count
);
135 g_hash_table_foreach (debug_objects_ht
, debug_objects_foreach
, NULL
);
136 G_UNLOCK (debug_objects
);
139 #endif /* G_ENABLE_DEBUG */
142 g_object_type_init (void) /* sync with gtype.c */
144 static gboolean initialized
= FALSE
;
145 static const GTypeFundamentalInfo finfo
= {
146 G_TYPE_FLAG_CLASSED
| G_TYPE_FLAG_INSTANTIATABLE
| G_TYPE_FLAG_DERIVABLE
| G_TYPE_FLAG_DEEP_DERIVABLE
,
148 static GTypeInfo info
= {
149 sizeof (GObjectClass
),
150 (GBaseInitFunc
) g_object_base_class_init
,
151 (GBaseFinalizeFunc
) g_object_base_class_finalize
,
152 (GClassInitFunc
) g_object_do_class_init
,
153 NULL
/* class_destroy */,
154 NULL
/* class_data */,
157 (GInstanceInitFunc
) g_object_init
,
158 NULL
, /* value_table */
160 static const GTypeValueTable value_table
= {
161 g_value_object_init
, /* value_init */
162 g_value_object_free_value
, /* value_free */
163 g_value_object_copy_value
, /* value_copy */
164 g_value_object_peek_pointer
, /* value_peek_pointer */
165 "p", /* collect_format */
166 g_value_object_collect_value
, /* collect_value */
167 "p", /* lcopy_format */
168 g_value_object_lcopy_value
, /* lcopy_value */
172 g_return_if_fail (initialized
== FALSE
);
177 info
.value_table
= &value_table
;
178 type
= g_type_register_fundamental (G_TYPE_OBJECT
, "GObject", &info
, &finfo
, 0);
179 g_assert (type
== G_TYPE_OBJECT
);
180 g_value_register_transform_func (G_TYPE_OBJECT
, G_TYPE_OBJECT
, g_value_object_transform_value
);
182 #ifdef G_ENABLE_DEBUG
185 debug_objects_ht
= g_hash_table_new (g_direct_hash
, NULL
);
186 g_atexit (debug_objects_atexit
);
188 #endif /* G_ENABLE_DEBUG */
192 g_object_base_class_init (GObjectClass
*class)
194 GObjectClass
*pclass
= g_type_class_peek_parent (class);
196 /* reset instance specific fields and methods that don't get inherited */
197 class->construct_properties
= pclass
? g_slist_copy (pclass
->construct_properties
) : NULL
;
198 class->get_property
= NULL
;
199 class->set_property
= NULL
;
203 g_object_base_class_finalize (GObjectClass
*class)
207 g_message ("finalizing base class of %s", G_OBJECT_CLASS_NAME (class));
209 _g_signals_destroy (G_OBJECT_CLASS_TYPE (class));
211 g_slist_free (class->construct_properties
);
212 class->construct_properties
= NULL
;
213 list
= g_param_spec_pool_list_owned (pspec_pool
, G_OBJECT_CLASS_TYPE (class));
214 for (node
= list
; node
; node
= node
->next
)
216 GParamSpec
*pspec
= node
->data
;
218 g_param_spec_pool_remove (pspec_pool
, pspec
);
219 PARAM_SPEC_SET_PARAM_ID (pspec
, 0);
220 g_param_spec_unref (pspec
);
226 g_object_notify_dispatcher (GObject
*object
,
230 G_OBJECT_GET_CLASS (object
)->dispatch_properties_changed (object
, n_pspecs
, pspecs
);
234 g_object_do_class_init (GObjectClass
*class)
236 quark_closure_array
= g_quark_from_static_string ("GObject-closure-array");
237 quark_weak_refs
= g_quark_from_static_string ("GObject-weak-references");
238 pspec_pool
= g_param_spec_pool_new (TRUE
);
239 property_notify_context
.quark_notify_queue
= g_quark_from_static_string ("GObject-notify-queue");
240 property_notify_context
.dispatcher
= g_object_notify_dispatcher
;
242 class->constructor
= g_object_constructor
;
243 class->set_property
= g_object_do_set_property
;
244 class->get_property
= g_object_do_get_property
;
245 class->dispose
= g_object_real_dispose
;
246 class->finalize
= g_object_finalize
;
247 class->dispatch_properties_changed
= g_object_dispatch_properties_changed
;
248 class->notify
= NULL
;
250 gobject_signals
[NOTIFY
] =
251 g_signal_new ("notify",
252 G_TYPE_FROM_CLASS (class),
253 G_SIGNAL_RUN_FIRST
| G_SIGNAL_NO_RECURSE
| G_SIGNAL_DETAILED
| G_SIGNAL_NO_HOOKS
,
254 G_STRUCT_OFFSET (GObjectClass
, notify
),
256 g_cclosure_marshal_VOID__PARAM
,
262 g_object_class_install_property (GObjectClass
*class,
266 g_return_if_fail (G_IS_OBJECT_CLASS (class));
267 g_return_if_fail (G_IS_PARAM_SPEC (pspec
));
268 if (pspec
->flags
& G_PARAM_WRITABLE
)
269 g_return_if_fail (class->set_property
!= NULL
);
270 if (pspec
->flags
& G_PARAM_READABLE
)
271 g_return_if_fail (class->get_property
!= NULL
);
272 g_return_if_fail (property_id
> 0);
273 g_return_if_fail (PARAM_SPEC_PARAM_ID (pspec
) == 0); /* paranoid */
274 if (pspec
->flags
& G_PARAM_CONSTRUCT
)
275 g_return_if_fail ((pspec
->flags
& G_PARAM_CONSTRUCT_ONLY
) == 0);
276 if (pspec
->flags
& (G_PARAM_CONSTRUCT
| G_PARAM_CONSTRUCT_ONLY
))
277 g_return_if_fail (pspec
->flags
& G_PARAM_WRITABLE
);
279 if (g_param_spec_pool_lookup (pspec_pool
, pspec
->name
, G_OBJECT_CLASS_TYPE (class), FALSE
))
281 g_warning (G_STRLOC
": class `%s' already contains a property named `%s'",
282 G_OBJECT_CLASS_NAME (class),
287 g_param_spec_ref (pspec
);
288 g_param_spec_sink (pspec
);
289 PARAM_SPEC_SET_PARAM_ID (pspec
, property_id
);
290 g_param_spec_pool_insert (pspec_pool
, pspec
, G_OBJECT_CLASS_TYPE (class));
291 if (pspec
->flags
& (G_PARAM_CONSTRUCT
| G_PARAM_CONSTRUCT_ONLY
))
292 class->construct_properties
= g_slist_prepend (class->construct_properties
, pspec
);
294 /* for property overrides of construct poperties, we have to get rid
295 * of the overidden inherited construct property
297 pspec
= g_param_spec_pool_lookup (pspec_pool
, pspec
->name
, g_type_parent (G_OBJECT_CLASS_TYPE (class)), TRUE
);
298 if (pspec
&& pspec
->flags
& (G_PARAM_CONSTRUCT
| G_PARAM_CONSTRUCT_ONLY
))
299 class->construct_properties
= g_slist_remove (class->construct_properties
, pspec
);
303 g_object_class_find_property (GObjectClass
*class,
304 const gchar
*property_name
)
306 g_return_val_if_fail (G_IS_OBJECT_CLASS (class), NULL
);
307 g_return_val_if_fail (property_name
!= NULL
, NULL
);
309 return g_param_spec_pool_lookup (pspec_pool
,
311 G_OBJECT_CLASS_TYPE (class),
315 GParamSpec
** /* free result */
316 g_object_class_list_properties (GObjectClass
*class,
317 guint
*n_properties_p
)
322 g_return_val_if_fail (G_IS_OBJECT_CLASS (class), NULL
);
324 pspecs
= g_param_spec_pool_list (pspec_pool
,
325 G_OBJECT_CLASS_TYPE (class),
334 g_object_init (GObject
*object
)
336 object
->ref_count
= 1;
337 g_datalist_init (&object
->qdata
);
339 /* freeze object's notification queue, g_object_newv() preserves pairedness */
340 g_object_notify_queue_freeze (object
, &property_notify_context
);
342 #ifdef G_ENABLE_DEBUG
345 G_LOCK (debug_objects
);
346 debug_objects_count
++;
347 g_hash_table_insert (debug_objects_ht
, object
, object
);
348 G_UNLOCK (debug_objects
);
350 #endif /* G_ENABLE_DEBUG */
354 g_object_do_set_property (GObject
*object
,
362 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
368 g_object_do_get_property (GObject
*object
,
376 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
382 g_object_real_dispose (GObject
*object
)
386 g_signal_handlers_destroy (object
);
387 g_datalist_id_set_data (&object
->qdata
, quark_closure_array
, NULL
);
389 /* yes, temporarily altering the ref_count is hackish, but that
390 * enforces people not jerking around with weak_ref notifiers
392 ref_count
= object
->ref_count
;
393 object
->ref_count
= 0;
394 g_datalist_id_set_data (&object
->qdata
, quark_weak_refs
, NULL
);
395 object
->ref_count
= ref_count
;
399 g_object_finalize (GObject
*object
)
401 g_datalist_clear (&object
->qdata
);
403 #ifdef G_ENABLE_DEBUG
406 G_LOCK (debug_objects
);
407 g_assert (g_hash_table_lookup (debug_objects_ht
, object
) == object
);
408 g_hash_table_remove (debug_objects_ht
, object
);
409 debug_objects_count
--;
410 G_UNLOCK (debug_objects
);
412 #endif /* G_ENABLE_DEBUG */
416 g_object_last_unref (GObject
*object
)
418 g_return_if_fail (object
->ref_count
> 0);
420 if (object
->ref_count
== 1) /* may have been re-referenced meanwhile */
421 G_OBJECT_GET_CLASS (object
)->dispose (object
);
423 #ifdef G_ENABLE_DEBUG
424 if (g_trap_object_ref
== object
)
426 #endif /* G_ENABLE_DEBUG */
428 object
->ref_count
-= 1;
430 if (object
->ref_count
== 0) /* may have been re-referenced meanwhile */
432 g_signal_handlers_destroy (object
);
433 g_datalist_id_set_data (&object
->qdata
, quark_weak_refs
, NULL
);
434 G_OBJECT_GET_CLASS (object
)->finalize (object
);
435 #ifdef G_ENABLE_DEBUG
438 /* catch objects not chaining finalize handlers */
439 G_LOCK (debug_objects
);
440 g_assert (g_hash_table_lookup (debug_objects_ht
, object
) == NULL
);
441 G_UNLOCK (debug_objects
);
443 #endif /* G_ENABLE_DEBUG */
444 g_type_free_instance ((GTypeInstance
*) object
);
449 g_object_dispatch_properties_changed (GObject
*object
,
455 for (i
= 0; i
< n_pspecs
; i
++)
456 g_signal_emit (object
, gobject_signals
[NOTIFY
], g_quark_from_string (pspecs
[i
]->name
), pspecs
[i
]);
460 g_object_run_dispose (GObject
*object
)
462 g_return_if_fail (G_IS_OBJECT (object
));
463 g_return_if_fail (object
->ref_count
> 0);
465 g_object_ref (object
);
466 G_OBJECT_GET_CLASS (object
)->dispose (object
);
467 g_object_unref (object
);
471 g_object_freeze_notify (GObject
*object
)
473 g_return_if_fail (G_IS_OBJECT (object
));
474 if (!object
->ref_count
)
477 g_object_ref (object
);
478 g_object_notify_queue_freeze (object
, &property_notify_context
);
479 g_object_unref (object
);
483 g_object_notify (GObject
*object
,
484 const gchar
*property_name
)
488 g_return_if_fail (G_IS_OBJECT (object
));
489 g_return_if_fail (property_name
!= NULL
);
490 if (!object
->ref_count
)
493 g_object_ref (object
);
494 pspec
= g_param_spec_pool_lookup (pspec_pool
,
496 G_OBJECT_TYPE (object
),
499 g_warning ("%s: object class `%s' has no property named `%s'",
501 G_OBJECT_TYPE_NAME (object
),
505 GObjectNotifyQueue
*nqueue
= g_object_notify_queue_freeze (object
, &property_notify_context
);
507 g_object_notify_queue_add (object
, nqueue
, pspec
);
508 g_object_notify_queue_thaw (object
, nqueue
);
510 g_object_unref (object
);
514 g_object_thaw_notify (GObject
*object
)
516 GObjectNotifyQueue
*nqueue
;
518 g_return_if_fail (G_IS_OBJECT (object
));
519 if (!object
->ref_count
)
522 g_object_ref (object
);
523 nqueue
= g_object_notify_queue_from_object (object
, &property_notify_context
);
524 if (!nqueue
|| !nqueue
->freeze_count
)
525 g_warning (G_STRLOC
": property-changed notification for %s(%p) is not frozen",
526 G_OBJECT_TYPE_NAME (object
), object
);
528 g_object_notify_queue_thaw (object
, nqueue
);
529 g_object_unref (object
);
533 object_get_property (GObject
*object
,
537 GObjectClass
*class = g_type_class_peek (pspec
->owner_type
);
539 class->get_property (object
, PARAM_SPEC_PARAM_ID (pspec
), value
, pspec
);
543 object_set_property (GObject
*object
,
546 GObjectNotifyQueue
*nqueue
)
548 GValue tmp_value
= { 0, };
549 GObjectClass
*class = g_type_class_peek (pspec
->owner_type
);
551 /* provide a copy to work from, convert (if necessary) and validate */
552 g_value_init (&tmp_value
, G_PARAM_SPEC_VALUE_TYPE (pspec
));
553 if (!g_value_transform (value
, &tmp_value
))
554 g_warning ("unable to set property `%s' of type `%s' from value of type `%s'",
556 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec
)),
557 G_VALUE_TYPE_NAME (value
));
558 else if (g_param_value_validate (pspec
, &tmp_value
) && !(pspec
->flags
& G_PARAM_LAX_VALIDATION
))
560 gchar
*contents
= g_strdup_value_contents (value
);
562 g_warning ("value \"%s\" of type `%s' is invalid for property `%s' of type `%s'",
564 G_VALUE_TYPE_NAME (value
),
566 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec
)));
571 class->set_property (object
, PARAM_SPEC_PARAM_ID (pspec
), &tmp_value
, pspec
);
572 g_object_notify_queue_add (object
, nqueue
, pspec
);
574 g_value_unset (&tmp_value
);
578 g_object_new (GType object_type
,
579 const gchar
*first_property_name
,
585 g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type
), NULL
);
587 va_start (var_args
, first_property_name
);
588 object
= g_object_new_valist (object_type
, first_property_name
, var_args
);
595 g_object_newv (GType object_type
,
597 GParameter
*parameters
)
599 GObjectConstructParam
*cparams
, *oparams
;
600 GObjectNotifyQueue
*nqueue
;
604 guint n_total_cparams
= 0, n_cparams
= 0, n_oparams
= 0, n_cvalues
;
609 g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type
), NULL
);
611 class = g_type_class_ref (object_type
);
612 for (slist
= class->construct_properties
; slist
; slist
= slist
->next
)
614 clist
= g_list_prepend (clist
, slist
->data
);
615 n_total_cparams
+= 1;
618 /* collect parameters, sort into construction and normal ones */
619 oparams
= g_new (GObjectConstructParam
, n_parameters
);
620 cparams
= g_new (GObjectConstructParam
, n_total_cparams
);
621 for (i
= 0; i
< n_parameters
; i
++)
623 GValue
*value
= ¶meters
[i
].value
;
624 GParamSpec
*pspec
= g_param_spec_pool_lookup (pspec_pool
,
630 g_warning ("%s: object class `%s' has no property named `%s'",
632 g_type_name (object_type
),
636 if (!(pspec
->flags
& G_PARAM_WRITABLE
))
638 g_warning ("%s: property `%s' of object class `%s' is not writable",
641 g_type_name (object_type
));
644 if (pspec
->flags
& (G_PARAM_CONSTRUCT
| G_PARAM_CONSTRUCT_ONLY
))
646 GList
*list
= g_list_find (clist
, pspec
);
650 g_warning (G_STRLOC
": construct property \"%s\" for object `%s' can't be set twice",
651 pspec
->name
, g_type_name (object_type
));
654 cparams
[n_cparams
].pspec
= pspec
;
655 cparams
[n_cparams
].value
= value
;
660 list
->prev
->next
= list
->next
;
662 list
->next
->prev
= list
->prev
;
663 g_list_free_1 (list
);
667 oparams
[n_oparams
].pspec
= pspec
;
668 oparams
[n_oparams
].value
= value
;
673 /* set remaining construction properties to default values */
674 n_cvalues
= n_total_cparams
- n_cparams
;
675 cvalues
= g_new (GValue
, n_cvalues
);
678 GList
*tmp
= clist
->next
;
679 GParamSpec
*pspec
= clist
->data
;
680 GValue
*value
= cvalues
+ n_total_cparams
- n_cparams
- 1;
683 g_value_init (value
, G_PARAM_SPEC_VALUE_TYPE (pspec
));
684 g_param_value_set_default (pspec
, value
);
686 cparams
[n_cparams
].pspec
= pspec
;
687 cparams
[n_cparams
].value
= value
;
690 g_list_free_1 (clist
);
694 /* construct object from construction parameters */
695 object
= class->constructor (object_type
, n_total_cparams
, cparams
);
697 /* free construction values */
700 g_value_unset (cvalues
+ n_cvalues
);
703 /* release g_object_init() notification queue freeze_count */
704 nqueue
= g_object_notify_queue_freeze (object
, &property_notify_context
);
705 g_object_notify_queue_thaw (object
, nqueue
);
707 /* set remaining properties */
708 for (i
= 0; i
< n_oparams
; i
++)
709 object_set_property (object
, oparams
[i
].pspec
, oparams
[i
].value
, nqueue
);
712 g_type_class_unref (class);
714 /* release our own freeze count and handle notifications */
715 g_object_notify_queue_thaw (object
, nqueue
);
721 g_object_new_valist (GType object_type
,
722 const gchar
*first_property_name
,
729 guint n_params
= 0, n_alloced_params
= 16;
731 g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type
), NULL
);
733 if (!first_property_name
)
734 return g_object_newv (object_type
, 0, NULL
);
736 class = g_type_class_ref (object_type
);
738 params
= g_new (GParameter
, n_alloced_params
);
739 name
= first_property_name
;
743 GParamSpec
*pspec
= g_param_spec_pool_lookup (pspec_pool
,
749 g_warning ("%s: object class `%s' has no property named `%s'",
751 g_type_name (object_type
),
755 if (n_params
>= n_alloced_params
)
757 n_alloced_params
+= 16;
758 params
= g_renew (GParameter
, params
, n_alloced_params
);
760 params
[n_params
].name
= name
;
761 params
[n_params
].value
.g_type
= 0;
762 g_value_init (¶ms
[n_params
].value
, G_PARAM_SPEC_VALUE_TYPE (pspec
));
763 G_VALUE_COLLECT (¶ms
[n_params
].value
, var_args
, 0, &error
);
766 g_warning ("%s: %s", G_STRLOC
, error
);
769 /* we purposely leak the value here, it might not be
770 * in a sane state if an error condition occoured
775 name
= va_arg (var_args
, gchar
*);
778 object
= g_object_newv (object_type
, n_params
, params
);
781 g_value_unset (¶ms
[n_params
].value
);
784 g_type_class_unref (class);
790 g_object_constructor (GType type
,
791 guint n_construct_properties
,
792 GObjectConstructParam
*construct_params
)
797 object
= (GObject
*) g_type_create_instance (type
);
799 /* set construction parameters */
800 if (n_construct_properties
)
802 GObjectNotifyQueue
*nqueue
= g_object_notify_queue_freeze (object
, &property_notify_context
);
804 /* set construct properties */
805 while (n_construct_properties
--)
807 GValue
*value
= construct_params
->value
;
808 GParamSpec
*pspec
= construct_params
->pspec
;
811 object_set_property (object
, pspec
, value
, nqueue
);
813 g_object_notify_queue_thaw (object
, nqueue
);
814 /* the notification queue is still frozen from g_object_init(), so
815 * we don't need to handle it here, g_object_newv() takes
824 g_object_set_valist (GObject
*object
,
825 const gchar
*first_property_name
,
828 GObjectNotifyQueue
*nqueue
;
831 g_return_if_fail (G_IS_OBJECT (object
));
833 g_object_ref (object
);
834 nqueue
= g_object_notify_queue_freeze (object
, &property_notify_context
);
836 name
= first_property_name
;
839 GValue value
= { 0, };
843 pspec
= g_param_spec_pool_lookup (pspec_pool
,
845 G_OBJECT_TYPE (object
),
849 g_warning ("%s: object class `%s' has no property named `%s'",
851 G_OBJECT_TYPE_NAME (object
),
855 if (!(pspec
->flags
& G_PARAM_WRITABLE
))
857 g_warning ("%s: property `%s' of object class `%s' is not writable",
860 G_OBJECT_TYPE_NAME (object
));
864 g_value_init (&value
, G_PARAM_SPEC_VALUE_TYPE (pspec
));
866 G_VALUE_COLLECT (&value
, var_args
, 0, &error
);
869 g_warning ("%s: %s", G_STRLOC
, error
);
872 /* we purposely leak the value here, it might not be
873 * in a sane state if an error condition occoured
878 object_set_property (object
, pspec
, &value
, nqueue
);
879 g_value_unset (&value
);
881 name
= va_arg (var_args
, gchar
*);
884 g_object_notify_queue_thaw (object
, nqueue
);
885 g_object_unref (object
);
889 g_object_get_valist (GObject
*object
,
890 const gchar
*first_property_name
,
895 g_return_if_fail (G_IS_OBJECT (object
));
897 g_object_ref (object
);
899 name
= first_property_name
;
903 GValue value
= { 0, };
907 pspec
= g_param_spec_pool_lookup (pspec_pool
,
909 G_OBJECT_TYPE (object
),
913 g_warning ("%s: object class `%s' has no property named `%s'",
915 G_OBJECT_TYPE_NAME (object
),
919 if (!(pspec
->flags
& G_PARAM_READABLE
))
921 g_warning ("%s: property `%s' of object class `%s' is not readable",
924 G_OBJECT_TYPE_NAME (object
));
928 g_value_init (&value
, G_PARAM_SPEC_VALUE_TYPE (pspec
));
930 object_get_property (object
, pspec
, &value
);
932 G_VALUE_LCOPY (&value
, var_args
, 0, &error
);
935 g_warning ("%s: %s", G_STRLOC
, error
);
937 g_value_unset (&value
);
941 g_value_unset (&value
);
943 name
= va_arg (var_args
, gchar
*);
946 g_object_unref (object
);
950 g_object_set (gpointer _object
,
951 const gchar
*first_property_name
,
954 GObject
*object
= _object
;
957 g_return_if_fail (G_IS_OBJECT (object
));
959 va_start (var_args
, first_property_name
);
960 g_object_set_valist (object
, first_property_name
, var_args
);
965 g_object_get (gpointer _object
,
966 const gchar
*first_property_name
,
969 GObject
*object
= _object
;
972 g_return_if_fail (G_IS_OBJECT (object
));
974 va_start (var_args
, first_property_name
);
975 g_object_get_valist (object
, first_property_name
, var_args
);
980 g_object_set_property (GObject
*object
,
981 const gchar
*property_name
,
984 GObjectNotifyQueue
*nqueue
;
987 g_return_if_fail (G_IS_OBJECT (object
));
988 g_return_if_fail (property_name
!= NULL
);
989 g_return_if_fail (G_IS_VALUE (value
));
991 g_object_ref (object
);
992 nqueue
= g_object_notify_queue_freeze (object
, &property_notify_context
);
994 pspec
= g_param_spec_pool_lookup (pspec_pool
,
996 G_OBJECT_TYPE (object
),
999 g_warning ("%s: object class `%s' has no property named `%s'",
1001 G_OBJECT_TYPE_NAME (object
),
1004 object_set_property (object
, pspec
, value
, nqueue
);
1006 g_object_notify_queue_thaw (object
, nqueue
);
1007 g_object_unref (object
);
1011 g_object_get_property (GObject
*object
,
1012 const gchar
*property_name
,
1017 g_return_if_fail (G_IS_OBJECT (object
));
1018 g_return_if_fail (property_name
!= NULL
);
1019 g_return_if_fail (G_IS_VALUE (value
));
1021 g_object_ref (object
);
1023 pspec
= g_param_spec_pool_lookup (pspec_pool
,
1025 G_OBJECT_TYPE (object
),
1028 g_warning ("%s: object class `%s' has no property named `%s'",
1030 G_OBJECT_TYPE_NAME (object
),
1034 GValue
*prop_value
, tmp_value
= { 0, };
1036 /* auto-conversion of the callers value type
1038 if (G_VALUE_TYPE (value
) == G_PARAM_SPEC_VALUE_TYPE (pspec
))
1040 g_value_reset (value
);
1043 else if (!g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec
), G_VALUE_TYPE (value
)))
1045 g_warning ("can't retrieve property `%s' of type `%s' as value of type `%s'",
1047 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec
)),
1048 G_VALUE_TYPE_NAME (value
));
1049 g_object_unref (object
);
1054 g_value_init (&tmp_value
, G_PARAM_SPEC_VALUE_TYPE (pspec
));
1055 prop_value
= &tmp_value
;
1057 object_get_property (object
, pspec
, prop_value
);
1058 if (prop_value
!= value
)
1060 g_value_transform (prop_value
, value
);
1061 g_value_unset (&tmp_value
);
1065 g_object_unref (object
);
1069 g_object_connect (gpointer _object
,
1070 const gchar
*signal_spec
,
1073 GObject
*object
= _object
;
1076 g_return_val_if_fail (G_IS_OBJECT (object
), NULL
);
1077 g_return_val_if_fail (object
->ref_count
> 0, object
);
1079 va_start (var_args
, signal_spec
);
1082 gpointer callback
= va_arg (var_args
, gpointer
);
1083 gpointer data
= va_arg (var_args
, gpointer
);
1086 if (strncmp (signal_spec
, "signal::", 8) == 0)
1087 sid
= g_signal_connect_data (object
, signal_spec
+ 8,
1088 callback
, data
, NULL
,
1090 else if (strncmp (signal_spec
, "object_signal::", 15) == 0)
1091 sid
= g_signal_connect_object (object
, signal_spec
+ 15,
1094 else if (strncmp (signal_spec
, "swapped_signal::", 16) == 0)
1095 sid
= g_signal_connect_data (object
, signal_spec
+ 16,
1096 callback
, data
, NULL
,
1098 else if (strncmp (signal_spec
, "swapped_object_signal::", 23) == 0)
1099 sid
= g_signal_connect_object (object
, signal_spec
+ 23,
1102 else if (strncmp (signal_spec
, "signal_after::", 14) == 0)
1103 sid
= g_signal_connect_data (object
, signal_spec
+ 14,
1104 callback
, data
, NULL
,
1106 else if (strncmp (signal_spec
, "object_signal_after::", 21) == 0)
1107 sid
= g_signal_connect_object (object
, signal_spec
+ 21,
1110 else if (strncmp (signal_spec
, "swapped_signal_after::", 22) == 0)
1111 sid
= g_signal_connect_data (object
, signal_spec
+ 22,
1112 callback
, data
, NULL
,
1113 G_CONNECT_SWAPPED
| G_CONNECT_AFTER
);
1114 else if (strncmp (signal_spec
, "swapped_object_signal_after::", 29) == 0)
1115 sid
= g_signal_connect_object (object
, signal_spec
+ 29,
1117 G_CONNECT_SWAPPED
| G_CONNECT_AFTER
);
1120 g_warning ("%s: invalid signal spec \"%s\"", G_STRLOC
, signal_spec
);
1123 signal_spec
= va_arg (var_args
, gchar
*);
1131 g_object_disconnect (gpointer _object
,
1132 const gchar
*signal_spec
,
1135 GObject
*object
= _object
;
1138 g_return_if_fail (G_IS_OBJECT (object
));
1139 g_return_if_fail (object
->ref_count
> 0);
1141 va_start (var_args
, signal_spec
);
1144 gpointer callback
= va_arg (var_args
, gpointer
);
1145 gpointer data
= va_arg (var_args
, gpointer
);
1146 guint sid
= 0, detail
= 0, mask
= 0;
1148 if (strncmp (signal_spec
, "any_signal::", 12) == 0)
1151 mask
= G_SIGNAL_MATCH_ID
| G_SIGNAL_MATCH_FUNC
| G_SIGNAL_MATCH_DATA
;
1153 else if (strcmp (signal_spec
, "any_signal") == 0)
1156 mask
= G_SIGNAL_MATCH_FUNC
| G_SIGNAL_MATCH_DATA
;
1160 g_warning ("%s: invalid signal spec \"%s\"", G_STRLOC
, signal_spec
);
1164 if ((mask
& G_SIGNAL_MATCH_ID
) &&
1165 !g_signal_parse_name (signal_spec
, G_OBJECT_TYPE (object
), &sid
, &detail
, FALSE
))
1166 g_warning ("%s: invalid signal name \"%s\"", G_STRLOC
, signal_spec
);
1167 else if (!g_signal_handlers_disconnect_matched (object
, mask
| (detail
? G_SIGNAL_MATCH_DETAIL
: 0),
1169 NULL
, callback
, data
))
1170 g_warning (G_STRLOC
": signal handler %p(%p) is not connected", callback
, data
);
1171 signal_spec
= va_arg (var_args
, gchar
*);
1182 } weak_refs
[1]; /* flexible array */
1186 weak_refs_notify (gpointer data
)
1188 WeakRefStack
*wstack
= data
;
1191 for (i
= 0; i
< wstack
->n_weak_refs
; i
++)
1192 wstack
->weak_refs
[i
].notify (wstack
->weak_refs
[i
].data
, wstack
->object
);
1197 g_object_weak_ref (GObject
*object
,
1201 WeakRefStack
*wstack
;
1204 g_return_if_fail (G_IS_OBJECT (object
));
1205 g_return_if_fail (notify
!= NULL
);
1206 g_return_if_fail (object
->ref_count
>= 1);
1208 wstack
= g_datalist_id_remove_no_notify (&object
->qdata
, quark_weak_refs
);
1211 i
= wstack
->n_weak_refs
++;
1212 wstack
= g_realloc (wstack
, sizeof (*wstack
) + sizeof (wstack
->weak_refs
[0]) * i
);
1216 wstack
= g_renew (WeakRefStack
, NULL
, 1);
1217 wstack
->object
= object
;
1218 wstack
->n_weak_refs
= 1;
1221 wstack
->weak_refs
[i
].notify
= notify
;
1222 wstack
->weak_refs
[i
].data
= data
;
1223 g_datalist_id_set_data_full (&object
->qdata
, quark_weak_refs
, wstack
, weak_refs_notify
);
1227 g_object_weak_unref (GObject
*object
,
1231 WeakRefStack
*wstack
;
1232 gboolean found_one
= FALSE
;
1234 g_return_if_fail (G_IS_OBJECT (object
));
1235 g_return_if_fail (notify
!= NULL
);
1237 wstack
= g_datalist_id_get_data (&object
->qdata
, quark_weak_refs
);
1242 for (i
= 0; i
< wstack
->n_weak_refs
; i
++)
1243 if (wstack
->weak_refs
[i
].notify
== notify
&&
1244 wstack
->weak_refs
[i
].data
== data
)
1247 wstack
->n_weak_refs
-= 1;
1248 if (i
!= wstack
->n_weak_refs
)
1250 wstack
->weak_refs
[i
].notify
= wstack
->weak_refs
[wstack
->n_weak_refs
].notify
;
1251 wstack
->weak_refs
[i
].data
= wstack
->weak_refs
[wstack
->n_weak_refs
].data
;
1257 g_warning (G_STRLOC
": couldn't find weak ref %p(%p)", notify
, data
);
1261 g_object_add_weak_pointer (GObject
*object
,
1262 gpointer
*weak_pointer_location
)
1264 g_return_if_fail (G_IS_OBJECT (object
));
1265 g_return_if_fail (weak_pointer_location
!= NULL
);
1267 g_object_weak_ref (object
,
1268 (GWeakNotify
) g_nullify_pointer
,
1269 weak_pointer_location
);
1273 g_object_remove_weak_pointer (GObject
*object
,
1274 gpointer
*weak_pointer_location
)
1276 g_return_if_fail (G_IS_OBJECT (object
));
1277 g_return_if_fail (weak_pointer_location
!= NULL
);
1279 g_object_weak_unref (object
,
1280 (GWeakNotify
) g_nullify_pointer
,
1281 weak_pointer_location
);
1285 g_object_ref (gpointer _object
)
1287 GObject
*object
= _object
;
1289 g_return_val_if_fail (G_IS_OBJECT (object
), NULL
);
1290 g_return_val_if_fail (object
->ref_count
> 0, NULL
);
1292 #ifdef G_ENABLE_DEBUG
1293 if (g_trap_object_ref
== object
)
1295 #endif /* G_ENABLE_DEBUG */
1297 object
->ref_count
+= 1;
1303 g_object_unref (gpointer _object
)
1305 GObject
*object
= _object
;
1307 g_return_if_fail (G_IS_OBJECT (object
));
1308 g_return_if_fail (object
->ref_count
> 0);
1310 #ifdef G_ENABLE_DEBUG
1311 if (g_trap_object_ref
== object
)
1313 #endif /* G_ENABLE_DEBUG */
1315 if (object
->ref_count
> 1)
1316 object
->ref_count
-= 1;
1318 g_object_last_unref (object
);
1322 g_object_get_qdata (GObject
*object
,
1325 g_return_val_if_fail (G_IS_OBJECT (object
), NULL
);
1327 return quark
? g_datalist_id_get_data (&object
->qdata
, quark
) : NULL
;
1331 g_object_set_qdata (GObject
*object
,
1335 g_return_if_fail (G_IS_OBJECT (object
));
1336 g_return_if_fail (quark
> 0);
1338 g_datalist_id_set_data (&object
->qdata
, quark
, data
);
1342 g_object_set_qdata_full (GObject
*object
,
1345 GDestroyNotify destroy
)
1347 g_return_if_fail (G_IS_OBJECT (object
));
1348 g_return_if_fail (quark
> 0);
1350 g_datalist_id_set_data_full (&object
->qdata
, quark
, data
,
1351 data
? destroy
: (GDestroyNotify
) NULL
);
1355 g_object_steal_qdata (GObject
*object
,
1358 g_return_val_if_fail (G_IS_OBJECT (object
), NULL
);
1359 g_return_val_if_fail (quark
> 0, NULL
);
1361 return g_datalist_id_remove_no_notify (&object
->qdata
, quark
);
1365 g_object_get_data (GObject
*object
,
1370 g_return_val_if_fail (G_IS_OBJECT (object
), NULL
);
1371 g_return_val_if_fail (key
!= NULL
, NULL
);
1373 quark
= g_quark_try_string (key
);
1375 return quark
? g_datalist_id_get_data (&object
->qdata
, quark
) : NULL
;
1379 g_object_set_data (GObject
*object
,
1383 g_return_if_fail (G_IS_OBJECT (object
));
1384 g_return_if_fail (key
!= NULL
);
1386 g_datalist_id_set_data (&object
->qdata
, g_quark_from_string (key
), data
);
1390 g_object_set_data_full (GObject
*object
,
1393 GDestroyNotify destroy
)
1395 g_return_if_fail (G_IS_OBJECT (object
));
1396 g_return_if_fail (key
!= NULL
);
1398 g_datalist_id_set_data_full (&object
->qdata
, g_quark_from_string (key
), data
,
1399 data
? destroy
: (GDestroyNotify
) NULL
);
1403 g_object_steal_data (GObject
*object
,
1408 g_return_val_if_fail (G_IS_OBJECT (object
), NULL
);
1409 g_return_val_if_fail (key
!= NULL
, NULL
);
1411 quark
= g_quark_try_string (key
);
1413 return quark
? g_datalist_id_remove_no_notify (&object
->qdata
, quark
) : NULL
;
1417 g_value_object_init (GValue
*value
)
1419 value
->data
[0].v_pointer
= NULL
;
1423 g_value_object_free_value (GValue
*value
)
1425 if (value
->data
[0].v_pointer
)
1426 g_object_unref (value
->data
[0].v_pointer
);
1430 g_value_object_copy_value (const GValue
*src_value
,
1433 if (src_value
->data
[0].v_pointer
)
1434 dest_value
->data
[0].v_pointer
= g_object_ref (src_value
->data
[0].v_pointer
);
1436 dest_value
->data
[0].v_pointer
= NULL
;
1440 g_value_object_transform_value (const GValue
*src_value
,
1443 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
)))
1444 dest_value
->data
[0].v_pointer
= g_object_ref (src_value
->data
[0].v_pointer
);
1446 dest_value
->data
[0].v_pointer
= NULL
;
1450 g_value_object_peek_pointer (const GValue
*value
)
1452 return value
->data
[0].v_pointer
;
1456 g_value_object_collect_value (GValue
*value
,
1457 guint n_collect_values
,
1458 GTypeCValue
*collect_values
,
1459 guint collect_flags
)
1461 if (collect_values
[0].v_pointer
)
1463 GObject
*object
= collect_values
[0].v_pointer
;
1465 if (object
->g_type_instance
.g_class
== NULL
)
1466 return g_strconcat ("invalid unclassed object pointer for value type `",
1467 G_VALUE_TYPE_NAME (value
),
1470 else if (!g_value_type_compatible (G_OBJECT_TYPE (object
), G_VALUE_TYPE (value
)))
1471 return g_strconcat ("invalid object type `",
1472 G_OBJECT_TYPE_NAME (object
),
1473 "' for value type `",
1474 G_VALUE_TYPE_NAME (value
),
1477 /* never honour G_VALUE_NOCOPY_CONTENTS for ref-counted types */
1478 value
->data
[0].v_pointer
= g_object_ref (object
);
1481 value
->data
[0].v_pointer
= NULL
;
1487 g_value_object_lcopy_value (const GValue
*value
,
1488 guint n_collect_values
,
1489 GTypeCValue
*collect_values
,
1490 guint collect_flags
)
1492 GObject
**object_p
= collect_values
[0].v_pointer
;
1495 return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value
));
1497 if (!value
->data
[0].v_pointer
)
1499 else if (collect_flags
& G_VALUE_NOCOPY_CONTENTS
)
1500 *object_p
= value
->data
[0].v_pointer
;
1502 *object_p
= g_object_ref (value
->data
[0].v_pointer
);
1508 g_value_set_object (GValue
*value
,
1511 g_return_if_fail (G_VALUE_HOLDS_OBJECT (value
));
1513 if (value
->data
[0].v_pointer
)
1515 g_object_unref (value
->data
[0].v_pointer
);
1516 value
->data
[0].v_pointer
= NULL
;
1521 g_return_if_fail (G_IS_OBJECT (v_object
));
1522 g_return_if_fail (g_value_type_compatible (G_OBJECT_TYPE (v_object
), G_VALUE_TYPE (value
)));
1524 value
->data
[0].v_pointer
= v_object
;
1525 g_object_ref (value
->data
[0].v_pointer
);
1530 g_value_get_object (const GValue
*value
)
1532 g_return_val_if_fail (G_VALUE_HOLDS_OBJECT (value
), NULL
);
1534 return value
->data
[0].v_pointer
;
1538 g_value_dup_object (const GValue
*value
)
1540 g_return_val_if_fail (G_VALUE_HOLDS_OBJECT (value
), NULL
);
1542 return value
->data
[0].v_pointer
? g_object_ref (value
->data
[0].v_pointer
) : NULL
;
1546 g_signal_connect_object (gpointer instance
,
1547 const gchar
*detailed_signal
,
1548 GCallback c_handler
,
1550 GConnectFlags connect_flags
)
1552 g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance
), 0);
1553 g_return_val_if_fail (detailed_signal
!= NULL
, 0);
1554 g_return_val_if_fail (c_handler
!= NULL
, 0);
1560 g_return_val_if_fail (G_IS_OBJECT (gobject
), 0);
1562 closure
= ((connect_flags
& G_CONNECT_SWAPPED
) ? g_cclosure_new_object_swap
: g_cclosure_new_object
) (c_handler
, gobject
);
1564 return g_signal_connect_closure (instance
, detailed_signal
, closure
, connect_flags
& G_CONNECT_AFTER
);
1567 return g_signal_connect_data (instance
, detailed_signal
, c_handler
, NULL
, NULL
, connect_flags
);
1573 GClosure
*closures
[1]; /* flexible array */
1577 object_remove_closure (gpointer data
,
1580 GObject
*object
= data
;
1581 CArray
*carray
= g_object_get_qdata (object
, quark_closure_array
);
1584 for (i
= 0; i
< carray
->n_closures
; i
++)
1585 if (carray
->closures
[i
] == closure
)
1587 carray
->n_closures
--;
1588 if (i
< carray
->n_closures
)
1589 carray
->closures
[i
] = carray
->closures
[carray
->n_closures
];
1592 g_assert_not_reached ();
1596 destroy_closure_array (gpointer data
)
1598 CArray
*carray
= data
;
1599 GObject
*object
= carray
->object
;
1600 guint i
, n
= carray
->n_closures
;
1602 for (i
= 0; i
< n
; i
++)
1604 GClosure
*closure
= carray
->closures
[i
];
1606 /* removing object_remove_closure() upfront is probably faster than
1607 * letting it fiddle with quark_closure_array which is empty anyways
1609 g_closure_remove_invalidate_notifier (closure
, object
, object_remove_closure
);
1610 g_closure_invalidate (closure
);
1616 g_object_watch_closure (GObject
*object
,
1622 g_return_if_fail (G_IS_OBJECT (object
));
1623 g_return_if_fail (closure
!= NULL
);
1624 g_return_if_fail (closure
->is_invalid
== FALSE
);
1625 g_return_if_fail (closure
->in_marshal
== FALSE
);
1626 g_return_if_fail (object
->ref_count
> 0); /* this doesn't work on finalizing objects */
1628 g_closure_add_invalidate_notifier (closure
, object
, object_remove_closure
);
1629 g_closure_add_marshal_guards (closure
,
1630 object
, (GClosureNotify
) g_object_ref
,
1631 object
, (GClosureNotify
) g_object_unref
);
1632 carray
= g_datalist_id_remove_no_notify (&object
->qdata
, quark_closure_array
);
1635 carray
= g_renew (CArray
, NULL
, 1);
1636 carray
->object
= object
;
1637 carray
->n_closures
= 1;
1642 i
= carray
->n_closures
++;
1643 carray
= g_realloc (carray
, sizeof (*carray
) + sizeof (carray
->closures
[0]) * i
);
1645 carray
->closures
[i
] = closure
;
1646 g_datalist_id_set_data_full (&object
->qdata
, quark_closure_array
, carray
, destroy_closure_array
);
1650 g_closure_new_object (guint sizeof_closure
,
1655 g_return_val_if_fail (G_IS_OBJECT (object
), NULL
);
1656 g_return_val_if_fail (object
->ref_count
> 0, NULL
); /* this doesn't work on finalizing objects */
1658 closure
= g_closure_new_simple (sizeof_closure
, object
);
1659 g_object_watch_closure (object
, closure
);
1665 g_cclosure_new_object (GCallback callback_func
,
1670 g_return_val_if_fail (G_IS_OBJECT (object
), NULL
);
1671 g_return_val_if_fail (object
->ref_count
> 0, NULL
); /* this doesn't work on finalizing objects */
1672 g_return_val_if_fail (callback_func
!= NULL
, NULL
);
1674 closure
= g_cclosure_new (callback_func
, object
, NULL
);
1675 g_object_watch_closure (object
, closure
);
1681 g_cclosure_new_object_swap (GCallback callback_func
,
1686 g_return_val_if_fail (G_IS_OBJECT (object
), NULL
);
1687 g_return_val_if_fail (object
->ref_count
> 0, NULL
); /* this doesn't work on finalizing objects */
1688 g_return_val_if_fail (callback_func
!= NULL
, NULL
);
1690 closure
= g_cclosure_new_swap (callback_func
, object
, NULL
);
1691 g_object_watch_closure (object
, closure
);