1/* GObject - GLib Type, Object, Parameter and Signal Library
2 * Copyright (C) 1998-1999, 2000-2001 Tim Janik and Red Hat, Inc.
3 *
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.1 of the License, or (at your option) any later version.
8 *
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.
13 *
14 * You should have received a copy of the GNU Lesser General
15 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
16 */
17
18/*
19 * MT safe with regards to reference counting.
20 */
21
22#include "config.h"
23
24#include <string.h>
25#include <signal.h>
26
27#include "gobject.h"
28#include "gtype-private.h"
29#include "gvaluecollector.h"
30#include "gsignal.h"
31#include "gparamspecs.h"
32#include "gvaluetypes.h"
33#include "gobject_trace.h"
34#include "gconstructor.h"
35
36/**
37 * SECTION:objects
38 * @title: GObject
39 * @short_description: The base object type
40 * @see_also: #GParamSpecObject, g_param_spec_object()
41 *
42 * GObject is the fundamental type providing the common attributes and
43 * methods for all object types in GTK+, Pango and other libraries
44 * based on GObject. The GObject class provides methods for object
45 * construction and destruction, property access methods, and signal
46 * support. Signals are described in detail [here][gobject-Signals].
47 *
48 * For a tutorial on implementing a new GObject class, see [How to define and
49 * implement a new GObject][howto-gobject]. For a list of naming conventions for
50 * GObjects and their methods, see the [GType conventions][gtype-conventions].
51 * For the high-level concepts behind GObject, read [Instantiatable classed types:
52 * Objects][gtype-instantiatable-classed].
53 *
54 * ## Floating references # {#floating-ref}
55 *
56 * **Note**: Floating references are a C convenience API and should not be
57 * used in modern GObject code. Language bindings in particular find the
58 * concept highly problematic, as floating references are not identifiable
59 * through annotations, and neither are deviations from the floating reference
60 * behavior, like types that inherit from #GInitiallyUnowned and still return
61 * a full reference from g_object_new().
62 *
63 * GInitiallyUnowned is derived from GObject. The only difference between
64 * the two is that the initial reference of a GInitiallyUnowned is flagged
65 * as a "floating" reference. This means that it is not specifically
66 * claimed to be "owned" by any code portion. The main motivation for
67 * providing floating references is C convenience. In particular, it
68 * allows code to be written as:
69 * |[<!-- language="C" -->
70 * container = create_container ();
71 * container_add_child (container, create_child());
72 * ]|
73 * If container_add_child() calls g_object_ref_sink() on the passed-in child,
74 * no reference of the newly created child is leaked. Without floating
75 * references, container_add_child() can only g_object_ref() the new child,
76 * so to implement this code without reference leaks, it would have to be
77 * written as:
78 * |[<!-- language="C" -->
79 * Child *child;
80 * container = create_container ();
81 * child = create_child ();
82 * container_add_child (container, child);
83 * g_object_unref (child);
84 * ]|
85 * The floating reference can be converted into an ordinary reference by
86 * calling g_object_ref_sink(). For already sunken objects (objects that
87 * don't have a floating reference anymore), g_object_ref_sink() is equivalent
88 * to g_object_ref() and returns a new reference.
89 *
90 * Since floating references are useful almost exclusively for C convenience,
91 * language bindings that provide automated reference and memory ownership
92 * maintenance (such as smart pointers or garbage collection) should not
93 * expose floating references in their API. The best practice for handling
94 * types that have initially floating references is to immediately sink those
95 * references after g_object_new() returns, by checking if the #GType
96 * inherits from #GInitiallyUnowned. For instance:
97 *
98 * |[<!-- language="C" -->
99 * GObject *res = g_object_new_with_properties (gtype,
100 * n_props,
101 * prop_names,
102 * prop_values);
103 *
104 * // or: if (g_type_is_a (gtype, G_TYPE_INITIALLY_UNOWNED))
105 * if (G_IS_INITIALLY_UNOWNED (res))
106 * g_object_ref_sink (res);
107 *
108 * return res;
109 * ]|
110 *
111 * Some object implementations may need to save an objects floating state
112 * across certain code portions (an example is #GtkMenu), to achieve this,
113 * the following sequence can be used:
114 *
115 * |[<!-- language="C" -->
116 * // save floating state
117 * gboolean was_floating = g_object_is_floating (object);
118 * g_object_ref_sink (object);
119 * // protected code portion
120 *
121 * ...
122 *
123 * // restore floating state
124 * if (was_floating)
125 * g_object_force_floating (object);
126 * else
127 * g_object_unref (object); // release previously acquired reference
128 * ]|
129 */
130
131
132/* --- macros --- */
133#define PARAM_SPEC_PARAM_ID(pspec) ((pspec)->param_id)
134#define PARAM_SPEC_SET_PARAM_ID(pspec, id) ((pspec)->param_id = (id))
135
136#define OBJECT_HAS_TOGGLE_REF_FLAG 0x1
137#define OBJECT_HAS_TOGGLE_REF(object) \
138 ((g_datalist_get_flags (&(object)->qdata) & OBJECT_HAS_TOGGLE_REF_FLAG) != 0)
139#define OBJECT_FLOATING_FLAG 0x2
140
141#define CLASS_HAS_PROPS_FLAG 0x1
142#define CLASS_HAS_PROPS(class) \
143 ((class)->flags & CLASS_HAS_PROPS_FLAG)
144#define CLASS_HAS_CUSTOM_CONSTRUCTOR(class) \
145 ((class)->constructor != g_object_constructor)
146#define CLASS_HAS_CUSTOM_CONSTRUCTED(class) \
147 ((class)->constructed != g_object_constructed)
148
149#define CLASS_HAS_DERIVED_CLASS_FLAG 0x2
150#define CLASS_HAS_DERIVED_CLASS(class) \
151 ((class)->flags & CLASS_HAS_DERIVED_CLASS_FLAG)
152
153/* --- signals --- */
154enum {
155 NOTIFY,
156 LAST_SIGNAL
157};
158
159
160/* --- properties --- */
161enum {
162 PROP_NONE
163};
164
165#define OPTIONAL_FLAG_IN_CONSTRUCTION 1<<0
166#define OPTIONAL_FLAG_HAS_SIGNAL_HANDLER 1<<1 /* Set if object ever had a signal handler */
167
168#if SIZEOF_INT == 4 && GLIB_SIZEOF_VOID_P == 8
169#define HAVE_OPTIONAL_FLAGS
170#endif
171
172typedef struct
173{
174 GTypeInstance g_type_instance;
175
176 /*< private >*/
177 guint ref_count; /* (atomic) */
178#ifdef HAVE_OPTIONAL_FLAGS
179 guint optional_flags; /* (atomic) */
180#endif
181 GData *qdata;
182} GObjectReal;
183
184G_STATIC_ASSERT(sizeof(GObject) == sizeof(GObjectReal));
185G_STATIC_ASSERT(G_STRUCT_OFFSET(GObject, ref_count) == G_STRUCT_OFFSET(GObjectReal, ref_count));
186G_STATIC_ASSERT(G_STRUCT_OFFSET(GObject, qdata) == G_STRUCT_OFFSET(GObjectReal, qdata));
187
188
189/* --- prototypes --- */
190static void g_object_base_class_init (GObjectClass *class);
191static void g_object_base_class_finalize (GObjectClass *class);
192static void g_object_do_class_init (GObjectClass *class);
193static void g_object_init (GObject *object,
194 GObjectClass *class);
195static GObject* g_object_constructor (GType type,
196 guint n_construct_properties,
197 GObjectConstructParam *construct_params);
198static void g_object_constructed (GObject *object);
199static void g_object_real_dispose (GObject *object);
200static void g_object_finalize (GObject *object);
201static void g_object_do_set_property (GObject *object,
202 guint property_id,
203 const GValue *value,
204 GParamSpec *pspec);
205static void g_object_do_get_property (GObject *object,
206 guint property_id,
207 GValue *value,
208 GParamSpec *pspec);
209static void g_value_object_init (GValue *value);
210static void g_value_object_free_value (GValue *value);
211static void g_value_object_copy_value (const GValue *src_value,
212 GValue *dest_value);
213static void g_value_object_transform_value (const GValue *src_value,
214 GValue *dest_value);
215static gpointer g_value_object_peek_pointer (const GValue *value);
216static gchar* g_value_object_collect_value (GValue *value,
217 guint n_collect_values,
218 GTypeCValue *collect_values,
219 guint collect_flags);
220static gchar* g_value_object_lcopy_value (const GValue *value,
221 guint n_collect_values,
222 GTypeCValue *collect_values,
223 guint collect_flags);
224static void g_object_dispatch_properties_changed (GObject *object,
225 guint n_pspecs,
226 GParamSpec **pspecs);
227static guint object_floating_flag_handler (GObject *object,
228 gint job);
229
230static void object_interface_check_properties (gpointer check_data,
231 gpointer g_iface);
232
233/* --- typedefs --- */
234typedef struct _GObjectNotifyQueue GObjectNotifyQueue;
235
236struct _GObjectNotifyQueue
237{
238 GSList *pspecs;
239 guint16 n_pspecs;
240 guint16 freeze_count;
241};
242
243/* --- variables --- */
244G_LOCK_DEFINE_STATIC (closure_array_mutex);
245G_LOCK_DEFINE_STATIC (weak_refs_mutex);
246G_LOCK_DEFINE_STATIC (toggle_refs_mutex);
247static GQuark quark_closure_array = 0;
248static GQuark quark_weak_refs = 0;
249static GQuark quark_toggle_refs = 0;
250static GQuark quark_notify_queue;
251static GQuark quark_in_construction;
252static GParamSpecPool *pspec_pool = NULL;
253static gulong gobject_signals[LAST_SIGNAL] = { 0, };
254static guint (*floating_flag_handler) (GObject*, gint) = object_floating_flag_handler;
255/* qdata pointing to GSList<GWeakRef *>, protected by weak_locations_lock */
256static GQuark quark_weak_locations = 0;
257static GRWLock weak_locations_lock;
258
259G_LOCK_DEFINE_STATIC(notify_lock);
260
261/* --- functions --- */
262static void
263g_object_notify_queue_free (gpointer data)
264{
265 GObjectNotifyQueue *nqueue = data;
266
267 g_slist_free (list: nqueue->pspecs);
268 g_slice_free (GObjectNotifyQueue, nqueue);
269}
270
271static GObjectNotifyQueue*
272g_object_notify_queue_freeze (GObject *object,
273 gboolean conditional)
274{
275 GObjectNotifyQueue *nqueue;
276
277 G_LOCK(notify_lock);
278 nqueue = g_datalist_id_get_data (datalist: &object->qdata, key_id: quark_notify_queue);
279 if (!nqueue)
280 {
281 if (conditional)
282 {
283 G_UNLOCK(notify_lock);
284 return NULL;
285 }
286
287 nqueue = g_slice_new0 (GObjectNotifyQueue);
288 g_datalist_id_set_data_full (datalist: &object->qdata, key_id: quark_notify_queue,
289 data: nqueue, destroy_func: g_object_notify_queue_free);
290 }
291
292 if (nqueue->freeze_count >= 65535)
293 g_critical("Free queue for %s (%p) is larger than 65535,"
294 " called g_object_freeze_notify() too often."
295 " Forgot to call g_object_thaw_notify() or infinite loop",
296 G_OBJECT_TYPE_NAME (object), object);
297 else
298 nqueue->freeze_count++;
299 G_UNLOCK(notify_lock);
300
301 return nqueue;
302}
303
304static void
305g_object_notify_queue_thaw (GObject *object,
306 GObjectNotifyQueue *nqueue)
307{
308 GParamSpec *pspecs_mem[16], **pspecs, **free_me = NULL;
309 GSList *slist;
310 guint n_pspecs = 0;
311
312 g_return_if_fail (g_atomic_int_get(&object->ref_count) > 0);
313
314 G_LOCK(notify_lock);
315
316 /* Just make sure we never get into some nasty race condition */
317 if (G_UNLIKELY(nqueue->freeze_count == 0)) {
318 G_UNLOCK(notify_lock);
319 g_warning ("%s: property-changed notification for %s(%p) is not frozen",
320 G_STRFUNC, G_OBJECT_TYPE_NAME (object), object);
321 return;
322 }
323
324 nqueue->freeze_count--;
325 if (nqueue->freeze_count) {
326 G_UNLOCK(notify_lock);
327 return;
328 }
329
330 pspecs = nqueue->n_pspecs > 16 ? free_me = g_new (GParamSpec*, nqueue->n_pspecs) : pspecs_mem;
331
332 for (slist = nqueue->pspecs; slist; slist = slist->next)
333 {
334 pspecs[n_pspecs++] = slist->data;
335 }
336 g_datalist_id_set_data (&object->qdata, quark_notify_queue, NULL);
337
338 G_UNLOCK(notify_lock);
339
340 if (n_pspecs)
341 G_OBJECT_GET_CLASS (object)->dispatch_properties_changed (object, n_pspecs, pspecs);
342 g_free (mem: free_me);
343}
344
345static void
346g_object_notify_queue_add (GObject *object,
347 GObjectNotifyQueue *nqueue,
348 GParamSpec *pspec)
349{
350 G_LOCK(notify_lock);
351
352 g_assert (nqueue->n_pspecs < 65535);
353
354 if (g_slist_find (list: nqueue->pspecs, data: pspec) == NULL)
355 {
356 nqueue->pspecs = g_slist_prepend (list: nqueue->pspecs, data: pspec);
357 nqueue->n_pspecs++;
358 }
359
360 G_UNLOCK(notify_lock);
361}
362
363#ifdef G_ENABLE_DEBUG
364G_LOCK_DEFINE_STATIC (debug_objects);
365static guint debug_objects_count = 0;
366static GHashTable *debug_objects_ht = NULL;
367
368static void
369debug_objects_foreach (gpointer key,
370 gpointer value,
371 gpointer user_data)
372{
373 GObject *object = value;
374
375 g_message ("[%p] stale %s\tref_count=%u",
376 object,
377 G_OBJECT_TYPE_NAME (object),
378 object->ref_count);
379}
380
381#ifdef G_HAS_CONSTRUCTORS
382#ifdef G_DEFINE_DESTRUCTOR_NEEDS_PRAGMA
383#pragma G_DEFINE_DESTRUCTOR_PRAGMA_ARGS(debug_objects_atexit)
384#endif
385G_DEFINE_DESTRUCTOR(debug_objects_atexit)
386#endif /* G_HAS_CONSTRUCTORS */
387
388static void
389debug_objects_atexit (void)
390{
391 GOBJECT_IF_DEBUG (OBJECTS,
392 {
393 G_LOCK (debug_objects);
394 g_message ("stale GObjects: %u", debug_objects_count);
395 g_hash_table_foreach (debug_objects_ht, debug_objects_foreach, NULL);
396 G_UNLOCK (debug_objects);
397 });
398}
399#endif /* G_ENABLE_DEBUG */
400
401void
402_g_object_type_init (void)
403{
404 static gboolean initialized = FALSE;
405 static const GTypeFundamentalInfo finfo = {
406 G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE,
407 };
408 GTypeInfo info = {
409 sizeof (GObjectClass),
410 (GBaseInitFunc) g_object_base_class_init,
411 (GBaseFinalizeFunc) g_object_base_class_finalize,
412 (GClassInitFunc) g_object_do_class_init,
413 NULL /* class_destroy */,
414 NULL /* class_data */,
415 sizeof (GObject),
416 0 /* n_preallocs */,
417 (GInstanceInitFunc) g_object_init,
418 NULL, /* value_table */
419 };
420 static const GTypeValueTable value_table = {
421 g_value_object_init, /* value_init */
422 g_value_object_free_value, /* value_free */
423 g_value_object_copy_value, /* value_copy */
424 g_value_object_peek_pointer, /* value_peek_pointer */
425 "p", /* collect_format */
426 g_value_object_collect_value, /* collect_value */
427 "p", /* lcopy_format */
428 g_value_object_lcopy_value, /* lcopy_value */
429 };
430 GType type G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */;
431
432 g_return_if_fail (initialized == FALSE);
433 initialized = TRUE;
434
435 /* G_TYPE_OBJECT
436 */
437 info.value_table = &value_table;
438 type = g_type_register_fundamental (G_TYPE_OBJECT, type_name: g_intern_static_string (string: "GObject"), info: &info, finfo: &finfo, flags: 0);
439 g_assert (type == G_TYPE_OBJECT);
440 g_value_register_transform_func (G_TYPE_OBJECT, G_TYPE_OBJECT, transform_func: g_value_object_transform_value);
441
442#if G_ENABLE_DEBUG
443 /* We cannot use GOBJECT_IF_DEBUG here because of the G_HAS_CONSTRUCTORS
444 * conditional in between, as the C spec leaves conditionals inside macro
445 * expansions as undefined behavior. Only GCC and Clang are known to work
446 * but compilation breaks on MSVC.
447 *
448 * See: https://bugzilla.gnome.org/show_bug.cgi?id=769504
449 */
450 if (_g_type_debug_flags & G_TYPE_DEBUG_OBJECTS) \
451 {
452 debug_objects_ht = g_hash_table_new (hash_func: g_direct_hash, NULL);
453# ifndef G_HAS_CONSTRUCTORS
454 g_atexit (debug_objects_atexit);
455# endif /* G_HAS_CONSTRUCTORS */
456 }
457#endif /* G_ENABLE_DEBUG */
458}
459
460static void
461g_object_base_class_init (GObjectClass *class)
462{
463 GObjectClass *pclass = g_type_class_peek_parent (g_class: class);
464
465 /* Don't inherit HAS_DERIVED_CLASS flag from parent class */
466 class->flags &= ~CLASS_HAS_DERIVED_CLASS_FLAG;
467
468 if (pclass)
469 pclass->flags |= CLASS_HAS_DERIVED_CLASS_FLAG;
470
471 /* reset instance specific fields and methods that don't get inherited */
472 class->construct_properties = pclass ? g_slist_copy (list: pclass->construct_properties) : NULL;
473 class->get_property = NULL;
474 class->set_property = NULL;
475}
476
477static void
478g_object_base_class_finalize (GObjectClass *class)
479{
480 GList *list, *node;
481
482 _g_signals_destroy (G_OBJECT_CLASS_TYPE (class));
483
484 g_slist_free (list: class->construct_properties);
485 class->construct_properties = NULL;
486 list = g_param_spec_pool_list_owned (pool: pspec_pool, G_OBJECT_CLASS_TYPE (class));
487 for (node = list; node; node = node->next)
488 {
489 GParamSpec *pspec = node->data;
490
491 g_param_spec_pool_remove (pool: pspec_pool, pspec);
492 PARAM_SPEC_SET_PARAM_ID (pspec, 0);
493 g_param_spec_unref (pspec);
494 }
495 g_list_free (list);
496}
497
498static void
499g_object_do_class_init (GObjectClass *class)
500{
501 /* read the comment about typedef struct CArray; on why not to change this quark */
502 quark_closure_array = g_quark_from_static_string (string: "GObject-closure-array");
503
504 quark_weak_refs = g_quark_from_static_string (string: "GObject-weak-references");
505 quark_weak_locations = g_quark_from_static_string (string: "GObject-weak-locations");
506 quark_toggle_refs = g_quark_from_static_string (string: "GObject-toggle-references");
507 quark_notify_queue = g_quark_from_static_string (string: "GObject-notify-queue");
508 quark_in_construction = g_quark_from_static_string (string: "GObject-in-construction");
509 pspec_pool = g_param_spec_pool_new (TRUE);
510
511 class->constructor = g_object_constructor;
512 class->constructed = g_object_constructed;
513 class->set_property = g_object_do_set_property;
514 class->get_property = g_object_do_get_property;
515 class->dispose = g_object_real_dispose;
516 class->finalize = g_object_finalize;
517 class->dispatch_properties_changed = g_object_dispatch_properties_changed;
518 class->notify = NULL;
519
520 /**
521 * GObject::notify:
522 * @gobject: the object which received the signal.
523 * @pspec: the #GParamSpec of the property which changed.
524 *
525 * The notify signal is emitted on an object when one of its properties has
526 * its value set through g_object_set_property(), g_object_set(), et al.
527 *
528 * Note that getting this signal doesn’t itself guarantee that the value of
529 * the property has actually changed. When it is emitted is determined by the
530 * derived GObject class. If the implementor did not create the property with
531 * %G_PARAM_EXPLICIT_NOTIFY, then any call to g_object_set_property() results
532 * in ::notify being emitted, even if the new value is the same as the old.
533 * If they did pass %G_PARAM_EXPLICIT_NOTIFY, then this signal is emitted only
534 * when they explicitly call g_object_notify() or g_object_notify_by_pspec(),
535 * and common practice is to do that only when the value has actually changed.
536 *
537 * This signal is typically used to obtain change notification for a
538 * single property, by specifying the property name as a detail in the
539 * g_signal_connect() call, like this:
540 * |[<!-- language="C" -->
541 * g_signal_connect (text_view->buffer, "notify::paste-target-list",
542 * G_CALLBACK (gtk_text_view_target_list_notify),
543 * text_view)
544 * ]|
545 * It is important to note that you must use
546 * [canonical parameter names][canonical-parameter-names] as
547 * detail strings for the notify signal.
548 */
549 gobject_signals[NOTIFY] =
550 g_signal_new (signal_name: g_intern_static_string (string: "notify"),
551 G_TYPE_FROM_CLASS (class),
552 signal_flags: G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED | G_SIGNAL_NO_HOOKS | G_SIGNAL_ACTION,
553 G_STRUCT_OFFSET (GObjectClass, notify),
554 NULL, NULL,
555 NULL,
556 G_TYPE_NONE,
557 n_params: 1, G_TYPE_PARAM);
558
559 /* Install a check function that we'll use to verify that classes that
560 * implement an interface implement all properties for that interface
561 */
562 g_type_add_interface_check (NULL, check_func: object_interface_check_properties);
563}
564
565static inline gboolean
566install_property_internal (GType g_type,
567 guint property_id,
568 GParamSpec *pspec)
569{
570 if (g_param_spec_pool_lookup (pool: pspec_pool, param_name: pspec->name, owner_type: g_type, FALSE))
571 {
572 g_warning ("When installing property: type '%s' already has a property named '%s'",
573 g_type_name (g_type),
574 pspec->name);
575 return FALSE;
576 }
577
578 g_param_spec_ref_sink (pspec);
579 PARAM_SPEC_SET_PARAM_ID (pspec, property_id);
580 g_param_spec_pool_insert (pool: pspec_pool, pspec, owner_type: g_type);
581 return TRUE;
582}
583
584static gboolean
585validate_pspec_to_install (GParamSpec *pspec)
586{
587 g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), FALSE);
588 g_return_val_if_fail (PARAM_SPEC_PARAM_ID (pspec) == 0, FALSE); /* paranoid */
589
590 g_return_val_if_fail (pspec->flags & (G_PARAM_READABLE | G_PARAM_WRITABLE), FALSE);
591
592 if (pspec->flags & G_PARAM_CONSTRUCT)
593 g_return_val_if_fail ((pspec->flags & G_PARAM_CONSTRUCT_ONLY) == 0, FALSE);
594
595 if (pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY))
596 g_return_val_if_fail (pspec->flags & G_PARAM_WRITABLE, FALSE);
597
598 return TRUE;
599}
600
601static gboolean
602validate_and_install_class_property (GObjectClass *class,
603 GType oclass_type,
604 GType parent_type,
605 guint property_id,
606 GParamSpec *pspec)
607{
608 if (!validate_pspec_to_install (pspec))
609 return FALSE;
610
611 if (pspec->flags & G_PARAM_WRITABLE)
612 g_return_val_if_fail (class->set_property != NULL, FALSE);
613 if (pspec->flags & G_PARAM_READABLE)
614 g_return_val_if_fail (class->get_property != NULL, FALSE);
615
616 class->flags |= CLASS_HAS_PROPS_FLAG;
617 if (install_property_internal (g_type: oclass_type, property_id, pspec))
618 {
619 if (pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY))
620 class->construct_properties = g_slist_append (list: class->construct_properties, data: pspec);
621
622 /* for property overrides of construct properties, we have to get rid
623 * of the overridden inherited construct property
624 */
625 pspec = g_param_spec_pool_lookup (pool: pspec_pool, param_name: pspec->name, owner_type: parent_type, TRUE);
626 if (pspec && pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY))
627 class->construct_properties = g_slist_remove (list: class->construct_properties, data: pspec);
628
629 return TRUE;
630 }
631 else
632 return FALSE;
633}
634
635/**
636 * g_object_class_install_property:
637 * @oclass: a #GObjectClass
638 * @property_id: the id for the new property
639 * @pspec: the #GParamSpec for the new property
640 *
641 * Installs a new property.
642 *
643 * All properties should be installed during the class initializer. It
644 * is possible to install properties after that, but doing so is not
645 * recommend, and specifically, is not guaranteed to be thread-safe vs.
646 * use of properties on the same type on other threads.
647 *
648 * Note that it is possible to redefine a property in a derived class,
649 * by installing a property with the same name. This can be useful at times,
650 * e.g. to change the range of allowed values or the default value.
651 */
652void
653g_object_class_install_property (GObjectClass *class,
654 guint property_id,
655 GParamSpec *pspec)
656{
657 GType oclass_type, parent_type;
658
659 g_return_if_fail (G_IS_OBJECT_CLASS (class));
660 g_return_if_fail (property_id > 0);
661
662 oclass_type = G_OBJECT_CLASS_TYPE (class);
663 parent_type = g_type_parent (type: oclass_type);
664
665 if (CLASS_HAS_DERIVED_CLASS (class))
666 g_error ("Attempt to add property %s::%s to class after it was derived", G_OBJECT_CLASS_NAME (class), pspec->name);
667
668 (void) validate_and_install_class_property (class,
669 oclass_type,
670 parent_type,
671 property_id,
672 pspec);
673}
674
675/**
676 * g_object_class_install_properties:
677 * @oclass: a #GObjectClass
678 * @n_pspecs: the length of the #GParamSpecs array
679 * @pspecs: (array length=n_pspecs): the #GParamSpecs array
680 * defining the new properties
681 *
682 * Installs new properties from an array of #GParamSpecs.
683 *
684 * All properties should be installed during the class initializer. It
685 * is possible to install properties after that, but doing so is not
686 * recommend, and specifically, is not guaranteed to be thread-safe vs.
687 * use of properties on the same type on other threads.
688 *
689 * The property id of each property is the index of each #GParamSpec in
690 * the @pspecs array.
691 *
692 * The property id of 0 is treated specially by #GObject and it should not
693 * be used to store a #GParamSpec.
694 *
695 * This function should be used if you plan to use a static array of
696 * #GParamSpecs and g_object_notify_by_pspec(). For instance, this
697 * class initialization:
698 *
699 * |[<!-- language="C" -->
700 * enum {
701 * PROP_0, PROP_FOO, PROP_BAR, N_PROPERTIES
702 * };
703 *
704 * static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
705 *
706 * static void
707 * my_object_class_init (MyObjectClass *klass)
708 * {
709 * GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
710 *
711 * obj_properties[PROP_FOO] =
712 * g_param_spec_int ("foo", "Foo", "Foo",
713 * -1, G_MAXINT,
714 * 0,
715 * G_PARAM_READWRITE);
716 *
717 * obj_properties[PROP_BAR] =
718 * g_param_spec_string ("bar", "Bar", "Bar",
719 * NULL,
720 * G_PARAM_READWRITE);
721 *
722 * gobject_class->set_property = my_object_set_property;
723 * gobject_class->get_property = my_object_get_property;
724 * g_object_class_install_properties (gobject_class,
725 * N_PROPERTIES,
726 * obj_properties);
727 * }
728 * ]|
729 *
730 * allows calling g_object_notify_by_pspec() to notify of property changes:
731 *
732 * |[<!-- language="C" -->
733 * void
734 * my_object_set_foo (MyObject *self, gint foo)
735 * {
736 * if (self->foo != foo)
737 * {
738 * self->foo = foo;
739 * g_object_notify_by_pspec (G_OBJECT (self), obj_properties[PROP_FOO]);
740 * }
741 * }
742 * ]|
743 *
744 * Since: 2.26
745 */
746void
747g_object_class_install_properties (GObjectClass *oclass,
748 guint n_pspecs,
749 GParamSpec **pspecs)
750{
751 GType oclass_type, parent_type;
752 guint i;
753
754 g_return_if_fail (G_IS_OBJECT_CLASS (oclass));
755 g_return_if_fail (n_pspecs > 1);
756 g_return_if_fail (pspecs[0] == NULL);
757
758 if (CLASS_HAS_DERIVED_CLASS (oclass))
759 g_error ("Attempt to add properties to %s after it was derived",
760 G_OBJECT_CLASS_NAME (oclass));
761
762 oclass_type = G_OBJECT_CLASS_TYPE (oclass);
763 parent_type = g_type_parent (type: oclass_type);
764
765 /* we skip the first element of the array as it would have a 0 prop_id */
766 for (i = 1; i < n_pspecs; i++)
767 {
768 GParamSpec *pspec = pspecs[i];
769
770 if (!validate_and_install_class_property (class: oclass,
771 oclass_type,
772 parent_type,
773 property_id: i,
774 pspec))
775 {
776 break;
777 }
778 }
779}
780
781/**
782 * g_object_interface_install_property:
783 * @g_iface: (type GObject.TypeInterface): any interface vtable for the
784 * interface, or the default
785 * vtable for the interface.
786 * @pspec: the #GParamSpec for the new property
787 *
788 * Add a property to an interface; this is only useful for interfaces
789 * that are added to GObject-derived types. Adding a property to an
790 * interface forces all objects classes with that interface to have a
791 * compatible property. The compatible property could be a newly
792 * created #GParamSpec, but normally
793 * g_object_class_override_property() will be used so that the object
794 * class only needs to provide an implementation and inherits the
795 * property description, default value, bounds, and so forth from the
796 * interface property.
797 *
798 * This function is meant to be called from the interface's default
799 * vtable initialization function (the @class_init member of
800 * #GTypeInfo.) It must not be called after after @class_init has
801 * been called for any object types implementing this interface.
802 *
803 * If @pspec is a floating reference, it will be consumed.
804 *
805 * Since: 2.4
806 */
807void
808g_object_interface_install_property (gpointer g_iface,
809 GParamSpec *pspec)
810{
811 GTypeInterface *iface_class = g_iface;
812
813 g_return_if_fail (G_TYPE_IS_INTERFACE (iface_class->g_type));
814 g_return_if_fail (!G_IS_PARAM_SPEC_OVERRIDE (pspec)); /* paranoid */
815
816 if (!validate_pspec_to_install (pspec))
817 return;
818
819 (void) install_property_internal (g_type: iface_class->g_type, property_id: 0, pspec);
820}
821
822/**
823 * g_object_class_find_property:
824 * @oclass: a #GObjectClass
825 * @property_name: the name of the property to look up
826 *
827 * Looks up the #GParamSpec for a property of a class.
828 *
829 * Returns: (transfer none): the #GParamSpec for the property, or
830 * %NULL if the class doesn't have a property of that name
831 */
832GParamSpec*
833g_object_class_find_property (GObjectClass *class,
834 const gchar *property_name)
835{
836 GParamSpec *pspec;
837 GParamSpec *redirect;
838
839 g_return_val_if_fail (G_IS_OBJECT_CLASS (class), NULL);
840 g_return_val_if_fail (property_name != NULL, NULL);
841
842 pspec = g_param_spec_pool_lookup (pool: pspec_pool,
843 param_name: property_name,
844 G_OBJECT_CLASS_TYPE (class),
845 TRUE);
846 if (pspec)
847 {
848 redirect = g_param_spec_get_redirect_target (pspec);
849 if (redirect)
850 return redirect;
851 else
852 return pspec;
853 }
854 else
855 return NULL;
856}
857
858/**
859 * g_object_interface_find_property:
860 * @g_iface: (type GObject.TypeInterface): any interface vtable for the
861 * interface, or the default vtable for the interface
862 * @property_name: name of a property to look up.
863 *
864 * Find the #GParamSpec with the given name for an
865 * interface. Generally, the interface vtable passed in as @g_iface
866 * will be the default vtable from g_type_default_interface_ref(), or,
867 * if you know the interface has already been loaded,
868 * g_type_default_interface_peek().
869 *
870 * Since: 2.4
871 *
872 * Returns: (transfer none): the #GParamSpec for the property of the
873 * interface with the name @property_name, or %NULL if no
874 * such property exists.
875 */
876GParamSpec*
877g_object_interface_find_property (gpointer g_iface,
878 const gchar *property_name)
879{
880 GTypeInterface *iface_class = g_iface;
881
882 g_return_val_if_fail (G_TYPE_IS_INTERFACE (iface_class->g_type), NULL);
883 g_return_val_if_fail (property_name != NULL, NULL);
884
885 return g_param_spec_pool_lookup (pool: pspec_pool,
886 param_name: property_name,
887 owner_type: iface_class->g_type,
888 FALSE);
889}
890
891/**
892 * g_object_class_override_property:
893 * @oclass: a #GObjectClass
894 * @property_id: the new property ID
895 * @name: the name of a property registered in a parent class or
896 * in an interface of this class.
897 *
898 * Registers @property_id as referring to a property with the name
899 * @name in a parent class or in an interface implemented by @oclass.
900 * This allows this class to "override" a property implementation in
901 * a parent class or to provide the implementation of a property from
902 * an interface.
903 *
904 * Internally, overriding is implemented by creating a property of type
905 * #GParamSpecOverride; generally operations that query the properties of
906 * the object class, such as g_object_class_find_property() or
907 * g_object_class_list_properties() will return the overridden
908 * property. However, in one case, the @construct_properties argument of
909 * the @constructor virtual function, the #GParamSpecOverride is passed
910 * instead, so that the @param_id field of the #GParamSpec will be
911 * correct. For virtually all uses, this makes no difference. If you
912 * need to get the overridden property, you can call
913 * g_param_spec_get_redirect_target().
914 *
915 * Since: 2.4
916 */
917void
918g_object_class_override_property (GObjectClass *oclass,
919 guint property_id,
920 const gchar *name)
921{
922 GParamSpec *overridden = NULL;
923 GParamSpec *new;
924 GType parent_type;
925
926 g_return_if_fail (G_IS_OBJECT_CLASS (oclass));
927 g_return_if_fail (property_id > 0);
928 g_return_if_fail (name != NULL);
929
930 /* Find the overridden property; first check parent types
931 */
932 parent_type = g_type_parent (G_OBJECT_CLASS_TYPE (oclass));
933 if (parent_type != G_TYPE_NONE)
934 overridden = g_param_spec_pool_lookup (pool: pspec_pool,
935 param_name: name,
936 owner_type: parent_type,
937 TRUE);
938 if (!overridden)
939 {
940 GType *ifaces;
941 guint n_ifaces;
942
943 /* Now check interfaces
944 */
945 ifaces = g_type_interfaces (G_OBJECT_CLASS_TYPE (oclass), n_interfaces: &n_ifaces);
946 while (n_ifaces-- && !overridden)
947 {
948 overridden = g_param_spec_pool_lookup (pool: pspec_pool,
949 param_name: name,
950 owner_type: ifaces[n_ifaces],
951 FALSE);
952 }
953
954 g_free (mem: ifaces);
955 }
956
957 if (!overridden)
958 {
959 g_warning ("%s: Can't find property to override for '%s::%s'",
960 G_STRFUNC, G_OBJECT_CLASS_NAME (oclass), name);
961 return;
962 }
963
964 new = g_param_spec_override (name, overridden);
965 g_object_class_install_property (class: oclass, property_id, pspec: new);
966}
967
968/**
969 * g_object_class_list_properties:
970 * @oclass: a #GObjectClass
971 * @n_properties: (out): return location for the length of the returned array
972 *
973 * Get an array of #GParamSpec* for all properties of a class.
974 *
975 * Returns: (array length=n_properties) (transfer container): an array of
976 * #GParamSpec* which should be freed after use
977 */
978GParamSpec** /* free result */
979g_object_class_list_properties (GObjectClass *class,
980 guint *n_properties_p)
981{
982 GParamSpec **pspecs;
983 guint n;
984
985 g_return_val_if_fail (G_IS_OBJECT_CLASS (class), NULL);
986
987 pspecs = g_param_spec_pool_list (pool: pspec_pool,
988 G_OBJECT_CLASS_TYPE (class),
989 n_pspecs_p: &n);
990 if (n_properties_p)
991 *n_properties_p = n;
992
993 return pspecs;
994}
995
996/**
997 * g_object_interface_list_properties:
998 * @g_iface: (type GObject.TypeInterface): any interface vtable for the
999 * interface, or the default vtable for the interface
1000 * @n_properties_p: (out): location to store number of properties returned.
1001 *
1002 * Lists the properties of an interface.Generally, the interface
1003 * vtable passed in as @g_iface will be the default vtable from
1004 * g_type_default_interface_ref(), or, if you know the interface has
1005 * already been loaded, g_type_default_interface_peek().
1006 *
1007 * Since: 2.4
1008 *
1009 * Returns: (array length=n_properties_p) (transfer container): a
1010 * pointer to an array of pointers to #GParamSpec
1011 * structures. The paramspecs are owned by GLib, but the
1012 * array should be freed with g_free() when you are done with
1013 * it.
1014 */
1015GParamSpec**
1016g_object_interface_list_properties (gpointer g_iface,
1017 guint *n_properties_p)
1018{
1019 GTypeInterface *iface_class = g_iface;
1020 GParamSpec **pspecs;
1021 guint n;
1022
1023 g_return_val_if_fail (G_TYPE_IS_INTERFACE (iface_class->g_type), NULL);
1024
1025 pspecs = g_param_spec_pool_list (pool: pspec_pool,
1026 owner_type: iface_class->g_type,
1027 n_pspecs_p: &n);
1028 if (n_properties_p)
1029 *n_properties_p = n;
1030
1031 return pspecs;
1032}
1033
1034static inline guint
1035object_get_optional_flags (GObject *object)
1036{
1037#ifdef HAVE_OPTIONAL_FLAGS
1038 GObjectReal *real = (GObjectReal *)object;
1039 return (guint)g_atomic_int_get (&real->optional_flags);
1040#else
1041 return 0;
1042#endif
1043}
1044
1045static inline void
1046object_set_optional_flags (GObject *object,
1047 guint flags)
1048{
1049#ifdef HAVE_OPTIONAL_FLAGS
1050 GObjectReal *real = (GObjectReal *)object;
1051 g_atomic_int_or (&real->optional_flags, flags);
1052#endif
1053}
1054
1055static inline void
1056object_unset_optional_flags (GObject *object,
1057 guint flags)
1058{
1059#ifdef HAVE_OPTIONAL_FLAGS
1060 GObjectReal *real = (GObjectReal *)object;
1061 g_atomic_int_and (&real->optional_flags, ~flags);
1062#endif
1063}
1064
1065gboolean
1066_g_object_has_signal_handler (GObject *object)
1067{
1068#ifdef HAVE_OPTIONAL_FLAGS
1069 return (object_get_optional_flags (object) & OPTIONAL_FLAG_HAS_SIGNAL_HANDLER) != 0;
1070#else
1071 return TRUE;
1072#endif
1073}
1074
1075void
1076_g_object_set_has_signal_handler (GObject *object)
1077{
1078#ifdef HAVE_OPTIONAL_FLAGS
1079 object_set_optional_flags (object, OPTIONAL_FLAG_HAS_SIGNAL_HANDLER);
1080#endif
1081}
1082
1083static inline gboolean
1084object_in_construction (GObject *object)
1085{
1086#ifdef HAVE_OPTIONAL_FLAGS
1087 return (object_get_optional_flags (object) & OPTIONAL_FLAG_IN_CONSTRUCTION) != 0;
1088#else
1089 return g_datalist_id_get_data (&object->qdata, quark_in_construction) != NULL;
1090#endif
1091}
1092
1093static inline void
1094set_object_in_construction (GObject *object)
1095{
1096#ifdef HAVE_OPTIONAL_FLAGS
1097 object_set_optional_flags (object, OPTIONAL_FLAG_IN_CONSTRUCTION);
1098#else
1099 g_datalist_id_set_data (&object->qdata, quark_in_construction, object);
1100#endif
1101}
1102
1103static inline void
1104unset_object_in_construction (GObject *object)
1105{
1106#ifdef HAVE_OPTIONAL_FLAGS
1107 object_unset_optional_flags (object, OPTIONAL_FLAG_IN_CONSTRUCTION);
1108#else
1109 g_datalist_id_set_data (&object->qdata, quark_in_construction, NULL);
1110#endif
1111}
1112
1113static void
1114g_object_init (GObject *object,
1115 GObjectClass *class)
1116{
1117 object->ref_count = 1;
1118 object->qdata = NULL;
1119
1120 if (CLASS_HAS_PROPS (class))
1121 {
1122 /* freeze object's notification queue, g_object_newv() preserves pairedness */
1123 g_object_notify_queue_freeze (object, FALSE);
1124 }
1125
1126 if (CLASS_HAS_CUSTOM_CONSTRUCTOR (class))
1127 {
1128 /* mark object in-construction for notify_queue_thaw() and to allow construct-only properties */
1129 set_object_in_construction (object);
1130 }
1131
1132 GOBJECT_IF_DEBUG (OBJECTS,
1133 {
1134 G_LOCK (debug_objects);
1135 debug_objects_count++;
1136 g_hash_table_add (debug_objects_ht, object);
1137 G_UNLOCK (debug_objects);
1138 });
1139}
1140
1141static void
1142g_object_do_set_property (GObject *object,
1143 guint property_id,
1144 const GValue *value,
1145 GParamSpec *pspec)
1146{
1147 switch (property_id)
1148 {
1149 default:
1150 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
1151 break;
1152 }
1153}
1154
1155static void
1156g_object_do_get_property (GObject *object,
1157 guint property_id,
1158 GValue *value,
1159 GParamSpec *pspec)
1160{
1161 switch (property_id)
1162 {
1163 default:
1164 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
1165 break;
1166 }
1167}
1168
1169static void
1170g_object_real_dispose (GObject *object)
1171{
1172 g_signal_handlers_destroy (instance: object);
1173 g_datalist_id_set_data (&object->qdata, quark_closure_array, NULL);
1174 g_datalist_id_set_data (&object->qdata, quark_weak_refs, NULL);
1175}
1176
1177static void
1178g_object_finalize (GObject *object)
1179{
1180 if (object_in_construction (object))
1181 {
1182 g_critical ("object %s %p finalized while still in-construction",
1183 G_OBJECT_TYPE_NAME (object), object);
1184 }
1185
1186 g_datalist_clear (datalist: &object->qdata);
1187
1188 GOBJECT_IF_DEBUG (OBJECTS,
1189 {
1190 G_LOCK (debug_objects);
1191 g_assert (g_hash_table_contains (debug_objects_ht, object));
1192 g_hash_table_remove (debug_objects_ht, object);
1193 debug_objects_count--;
1194 G_UNLOCK (debug_objects);
1195 });
1196}
1197
1198static void
1199g_object_dispatch_properties_changed (GObject *object,
1200 guint n_pspecs,
1201 GParamSpec **pspecs)
1202{
1203 guint i;
1204
1205 for (i = 0; i < n_pspecs; i++)
1206 g_signal_emit (instance: object, signal_id: gobject_signals[NOTIFY], detail: g_param_spec_get_name_quark (pspec: pspecs[i]), pspecs[i]);
1207}
1208
1209/**
1210 * g_object_run_dispose:
1211 * @object: a #GObject
1212 *
1213 * Releases all references to other objects. This can be used to break
1214 * reference cycles.
1215 *
1216 * This function should only be called from object system implementations.
1217 */
1218void
1219g_object_run_dispose (GObject *object)
1220{
1221 g_return_if_fail (G_IS_OBJECT (object));
1222 g_return_if_fail (g_atomic_int_get (&object->ref_count) > 0);
1223
1224 g_object_ref (object);
1225 TRACE (GOBJECT_OBJECT_DISPOSE(object,G_TYPE_FROM_INSTANCE(object), 0));
1226 G_OBJECT_GET_CLASS (object)->dispose (object);
1227 TRACE (GOBJECT_OBJECT_DISPOSE_END(object,G_TYPE_FROM_INSTANCE(object), 0));
1228 g_object_unref (object);
1229}
1230
1231/**
1232 * g_object_freeze_notify:
1233 * @object: a #GObject
1234 *
1235 * Increases the freeze count on @object. If the freeze count is
1236 * non-zero, the emission of "notify" signals on @object is
1237 * stopped. The signals are queued until the freeze count is decreased
1238 * to zero. Duplicate notifications are squashed so that at most one
1239 * #GObject::notify signal is emitted for each property modified while the
1240 * object is frozen.
1241 *
1242 * This is necessary for accessors that modify multiple properties to prevent
1243 * premature notification while the object is still being modified.
1244 */
1245void
1246g_object_freeze_notify (GObject *object)
1247{
1248 g_return_if_fail (G_IS_OBJECT (object));
1249
1250 if (g_atomic_int_get (&object->ref_count) == 0)
1251 return;
1252
1253 g_object_ref (object);
1254 g_object_notify_queue_freeze (object, FALSE);
1255 g_object_unref (object);
1256}
1257
1258static GParamSpec *
1259get_notify_pspec (GParamSpec *pspec)
1260{
1261 GParamSpec *redirected;
1262
1263 /* we don't notify on non-READABLE parameters */
1264 if (~pspec->flags & G_PARAM_READABLE)
1265 return NULL;
1266
1267 /* if the paramspec is redirected, notify on the target */
1268 redirected = g_param_spec_get_redirect_target (pspec);
1269 if (redirected != NULL)
1270 return redirected;
1271
1272 /* else, notify normally */
1273 return pspec;
1274}
1275
1276static inline void
1277g_object_notify_by_spec_internal (GObject *object,
1278 GParamSpec *pspec)
1279{
1280 GParamSpec *notify_pspec;
1281
1282 notify_pspec = get_notify_pspec (pspec);
1283
1284 if (notify_pspec != NULL)
1285 {
1286 GObjectNotifyQueue *nqueue;
1287
1288 /* conditional freeze: only increase freeze count if already frozen */
1289 nqueue = g_object_notify_queue_freeze (object, TRUE);
1290
1291 if (nqueue != NULL)
1292 {
1293 /* we're frozen, so add to the queue and release our freeze */
1294 g_object_notify_queue_add (object, nqueue, pspec: notify_pspec);
1295 g_object_notify_queue_thaw (object, nqueue);
1296 }
1297 else
1298 /* not frozen, so just dispatch the notification directly */
1299 G_OBJECT_GET_CLASS (object)
1300 ->dispatch_properties_changed (object, 1, &notify_pspec);
1301 }
1302}
1303
1304/**
1305 * g_object_notify:
1306 * @object: a #GObject
1307 * @property_name: the name of a property installed on the class of @object.
1308 *
1309 * Emits a "notify" signal for the property @property_name on @object.
1310 *
1311 * When possible, eg. when signaling a property change from within the class
1312 * that registered the property, you should use g_object_notify_by_pspec()
1313 * instead.
1314 *
1315 * Note that emission of the notify signal may be blocked with
1316 * g_object_freeze_notify(). In this case, the signal emissions are queued
1317 * and will be emitted (in reverse order) when g_object_thaw_notify() is
1318 * called.
1319 */
1320void
1321g_object_notify (GObject *object,
1322 const gchar *property_name)
1323{
1324 GParamSpec *pspec;
1325
1326 g_return_if_fail (G_IS_OBJECT (object));
1327 g_return_if_fail (property_name != NULL);
1328 if (g_atomic_int_get (&object->ref_count) == 0)
1329 return;
1330
1331 g_object_ref (object);
1332 /* We don't need to get the redirect target
1333 * (by, e.g. calling g_object_class_find_property())
1334 * because g_object_notify_queue_add() does that
1335 */
1336 pspec = g_param_spec_pool_lookup (pool: pspec_pool,
1337 param_name: property_name,
1338 G_OBJECT_TYPE (object),
1339 TRUE);
1340
1341 if (!pspec)
1342 g_warning ("%s: object class '%s' has no property named '%s'",
1343 G_STRFUNC,
1344 G_OBJECT_TYPE_NAME (object),
1345 property_name);
1346 else
1347 g_object_notify_by_spec_internal (object, pspec);
1348 g_object_unref (object);
1349}
1350
1351/**
1352 * g_object_notify_by_pspec:
1353 * @object: a #GObject
1354 * @pspec: the #GParamSpec of a property installed on the class of @object.
1355 *
1356 * Emits a "notify" signal for the property specified by @pspec on @object.
1357 *
1358 * This function omits the property name lookup, hence it is faster than
1359 * g_object_notify().
1360 *
1361 * One way to avoid using g_object_notify() from within the
1362 * class that registered the properties, and using g_object_notify_by_pspec()
1363 * instead, is to store the GParamSpec used with
1364 * g_object_class_install_property() inside a static array, e.g.:
1365 *
1366 *|[<!-- language="C" -->
1367 * enum
1368 * {
1369 * PROP_0,
1370 * PROP_FOO,
1371 * PROP_LAST
1372 * };
1373 *
1374 * static GParamSpec *properties[PROP_LAST];
1375 *
1376 * static void
1377 * my_object_class_init (MyObjectClass *klass)
1378 * {
1379 * properties[PROP_FOO] = g_param_spec_int ("foo", "Foo", "The foo",
1380 * 0, 100,
1381 * 50,
1382 * G_PARAM_READWRITE);
1383 * g_object_class_install_property (gobject_class,
1384 * PROP_FOO,
1385 * properties[PROP_FOO]);
1386 * }
1387 * ]|
1388 *
1389 * and then notify a change on the "foo" property with:
1390 *
1391 * |[<!-- language="C" -->
1392 * g_object_notify_by_pspec (self, properties[PROP_FOO]);
1393 * ]|
1394 *
1395 * Since: 2.26
1396 */
1397void
1398g_object_notify_by_pspec (GObject *object,
1399 GParamSpec *pspec)
1400{
1401
1402 g_return_if_fail (G_IS_OBJECT (object));
1403 g_return_if_fail (G_IS_PARAM_SPEC (pspec));
1404
1405 if (g_atomic_int_get (&object->ref_count) == 0)
1406 return;
1407
1408 g_object_ref (object);
1409 g_object_notify_by_spec_internal (object, pspec);
1410 g_object_unref (object);
1411}
1412
1413/**
1414 * g_object_thaw_notify:
1415 * @object: a #GObject
1416 *
1417 * Reverts the effect of a previous call to
1418 * g_object_freeze_notify(). The freeze count is decreased on @object
1419 * and when it reaches zero, queued "notify" signals are emitted.
1420 *
1421 * Duplicate notifications for each property are squashed so that at most one
1422 * #GObject::notify signal is emitted for each property, in the reverse order
1423 * in which they have been queued.
1424 *
1425 * It is an error to call this function when the freeze count is zero.
1426 */
1427void
1428g_object_thaw_notify (GObject *object)
1429{
1430 GObjectNotifyQueue *nqueue;
1431
1432 g_return_if_fail (G_IS_OBJECT (object));
1433 if (g_atomic_int_get (&object->ref_count) == 0)
1434 return;
1435
1436 g_object_ref (object);
1437
1438 /* FIXME: Freezing is the only way to get at the notify queue.
1439 * So we freeze once and then thaw twice.
1440 */
1441 nqueue = g_object_notify_queue_freeze (object, FALSE);
1442 g_object_notify_queue_thaw (object, nqueue);
1443 g_object_notify_queue_thaw (object, nqueue);
1444
1445 g_object_unref (object);
1446}
1447
1448static void
1449consider_issuing_property_deprecation_warning (const GParamSpec *pspec)
1450{
1451 static GHashTable *already_warned_table;
1452 static const gchar *enable_diagnostic;
1453 static GMutex already_warned_lock;
1454 gboolean already;
1455
1456 if (!(pspec->flags & G_PARAM_DEPRECATED))
1457 return;
1458
1459 if (g_once_init_enter (&enable_diagnostic))
1460 {
1461 const gchar *value = g_getenv (variable: "G_ENABLE_DIAGNOSTIC");
1462
1463 if (!value)
1464 value = "0";
1465
1466 g_once_init_leave (&enable_diagnostic, value);
1467 }
1468
1469 if (enable_diagnostic[0] == '0')
1470 return;
1471
1472 /* We hash only on property names: this means that we could end up in
1473 * a situation where we fail to emit a warning about a pair of
1474 * same-named deprecated properties used on two separate types.
1475 * That's pretty unlikely to occur, and even if it does, you'll still
1476 * have seen the warning for the first one...
1477 *
1478 * Doing it this way lets us hash directly on the (interned) property
1479 * name pointers.
1480 */
1481 g_mutex_lock (mutex: &already_warned_lock);
1482
1483 if (already_warned_table == NULL)
1484 already_warned_table = g_hash_table_new (NULL, NULL);
1485
1486 already = g_hash_table_contains (hash_table: already_warned_table, key: (gpointer) pspec->name);
1487 if (!already)
1488 g_hash_table_add (hash_table: already_warned_table, key: (gpointer) pspec->name);
1489
1490 g_mutex_unlock (mutex: &already_warned_lock);
1491
1492 if (!already)
1493 g_warning ("The property %s:%s is deprecated and shouldn't be used "
1494 "anymore. It will be removed in a future version.",
1495 g_type_name (pspec->owner_type), pspec->name);
1496}
1497
1498static inline void
1499object_get_property (GObject *object,
1500 GParamSpec *pspec,
1501 GValue *value)
1502{
1503 GObjectClass *class = g_type_class_peek (type: pspec->owner_type);
1504 guint param_id = PARAM_SPEC_PARAM_ID (pspec);
1505 GParamSpec *redirect;
1506
1507 if (class == NULL)
1508 {
1509 g_warning ("'%s::%s' is not a valid property name; '%s' is not a GObject subtype",
1510 g_type_name (pspec->owner_type), pspec->name, g_type_name (pspec->owner_type));
1511 return;
1512 }
1513
1514 redirect = g_param_spec_get_redirect_target (pspec);
1515 if (redirect)
1516 pspec = redirect;
1517
1518 consider_issuing_property_deprecation_warning (pspec);
1519
1520 class->get_property (object, param_id, value, pspec);
1521}
1522
1523static inline void
1524object_set_property (GObject *object,
1525 GParamSpec *pspec,
1526 const GValue *value,
1527 GObjectNotifyQueue *nqueue)
1528{
1529 GValue tmp_value = G_VALUE_INIT;
1530 GObjectClass *class = g_type_class_peek (type: pspec->owner_type);
1531 guint param_id = PARAM_SPEC_PARAM_ID (pspec);
1532 GParamSpec *redirect;
1533
1534 if (class == NULL)
1535 {
1536 g_warning ("'%s::%s' is not a valid property name; '%s' is not a GObject subtype",
1537 g_type_name (pspec->owner_type), pspec->name, g_type_name (pspec->owner_type));
1538 return;
1539 }
1540
1541 redirect = g_param_spec_get_redirect_target (pspec);
1542 if (redirect)
1543 pspec = redirect;
1544
1545 /* provide a copy to work from, convert (if necessary) and validate */
1546 g_value_init (value: &tmp_value, g_type: pspec->value_type);
1547 if (!g_value_transform (src_value: value, dest_value: &tmp_value))
1548 g_warning ("unable to set property '%s' of type '%s' from value of type '%s'",
1549 pspec->name,
1550 g_type_name (pspec->value_type),
1551 G_VALUE_TYPE_NAME (value));
1552 else if (g_param_value_validate (pspec, value: &tmp_value) && !(pspec->flags & G_PARAM_LAX_VALIDATION))
1553 {
1554 gchar *contents = g_strdup_value_contents (value);
1555
1556 g_warning ("value \"%s\" of type '%s' is invalid or out of range for property '%s' of type '%s'",
1557 contents,
1558 G_VALUE_TYPE_NAME (value),
1559 pspec->name,
1560 g_type_name (pspec->value_type));
1561 g_free (mem: contents);
1562 }
1563 else
1564 {
1565 class->set_property (object, param_id, &tmp_value, pspec);
1566
1567 if (~pspec->flags & G_PARAM_EXPLICIT_NOTIFY)
1568 {
1569 GParamSpec *notify_pspec;
1570
1571 notify_pspec = get_notify_pspec (pspec);
1572
1573 if (notify_pspec != NULL)
1574 g_object_notify_queue_add (object, nqueue, pspec: notify_pspec);
1575 }
1576 }
1577 g_value_unset (value: &tmp_value);
1578}
1579
1580static void
1581object_interface_check_properties (gpointer check_data,
1582 gpointer g_iface)
1583{
1584 GTypeInterface *iface_class = g_iface;
1585 GObjectClass *class;
1586 GType iface_type = iface_class->g_type;
1587 GParamSpec **pspecs;
1588 guint n;
1589
1590 class = g_type_class_ref (type: iface_class->g_instance_type);
1591
1592 if (class == NULL)
1593 return;
1594
1595 if (!G_IS_OBJECT_CLASS (class))
1596 goto out;
1597
1598 pspecs = g_param_spec_pool_list (pool: pspec_pool, owner_type: iface_type, n_pspecs_p: &n);
1599
1600 while (n--)
1601 {
1602 GParamSpec *class_pspec = g_param_spec_pool_lookup (pool: pspec_pool,
1603 param_name: pspecs[n]->name,
1604 G_OBJECT_CLASS_TYPE (class),
1605 TRUE);
1606
1607 if (!class_pspec)
1608 {
1609 g_critical ("Object class %s doesn't implement property "
1610 "'%s' from interface '%s'",
1611 g_type_name (G_OBJECT_CLASS_TYPE (class)),
1612 pspecs[n]->name,
1613 g_type_name (iface_type));
1614
1615 continue;
1616 }
1617
1618 /* We do a number of checks on the properties of an interface to
1619 * make sure that all classes implementing the interface are
1620 * overriding the properties correctly.
1621 *
1622 * We do the checks in order of importance so that we can give
1623 * more useful error messages first.
1624 *
1625 * First, we check that the implementation doesn't remove the
1626 * basic functionality (readability, writability) advertised by
1627 * the interface. Next, we check that it doesn't introduce
1628 * additional restrictions (such as construct-only). Finally, we
1629 * make sure the types are compatible.
1630 */
1631
1632#define SUBSET(a,b,mask) (((a) & ~(b) & (mask)) == 0)
1633 /* If the property on the interface is readable then the
1634 * implementation must be readable. If the interface is writable
1635 * then the implementation must be writable.
1636 */
1637 if (!SUBSET (pspecs[n]->flags, class_pspec->flags, G_PARAM_READABLE | G_PARAM_WRITABLE))
1638 {
1639 g_critical ("Flags for property '%s' on class '%s' remove functionality compared with the "
1640 "property on interface '%s'\n", pspecs[n]->name,
1641 g_type_name (G_OBJECT_CLASS_TYPE (class)), g_type_name (iface_type));
1642 continue;
1643 }
1644
1645 /* If the property on the interface is writable then we need to
1646 * make sure the implementation doesn't introduce new restrictions
1647 * on that writability (ie: construct-only).
1648 *
1649 * If the interface was not writable to begin with then we don't
1650 * really have any problems here because "writable at construct
1651 * time only" is still more permissive than "read only".
1652 */
1653 if (pspecs[n]->flags & G_PARAM_WRITABLE)
1654 {
1655 if (!SUBSET (class_pspec->flags, pspecs[n]->flags, G_PARAM_CONSTRUCT_ONLY))
1656 {
1657 g_critical ("Flags for property '%s' on class '%s' introduce additional restrictions on "
1658 "writability compared with the property on interface '%s'\n", pspecs[n]->name,
1659 g_type_name (G_OBJECT_CLASS_TYPE (class)), g_type_name (iface_type));
1660 continue;
1661 }
1662 }
1663#undef SUBSET
1664
1665 /* If the property on the interface is readable then we are
1666 * effectively advertising that reading the property will return a
1667 * value of a specific type. All implementations of the interface
1668 * need to return items of this type -- but may be more
1669 * restrictive. For example, it is legal to have:
1670 *
1671 * GtkWidget *get_item();
1672 *
1673 * that is implemented by a function that always returns a
1674 * GtkEntry. In short: readability implies that the
1675 * implementation value type must be equal or more restrictive.
1676 *
1677 * Similarly, if the property on the interface is writable then
1678 * must be able to accept the property being set to any value of
1679 * that type, including subclasses. In this case, we may also be
1680 * less restrictive. For example, it is legal to have:
1681 *
1682 * set_item (GtkEntry *);
1683 *
1684 * that is implemented by a function that will actually work with
1685 * any GtkWidget. In short: writability implies that the
1686 * implementation value type must be equal or less restrictive.
1687 *
1688 * In the case that the property is both readable and writable
1689 * then the only way that both of the above can be satisfied is
1690 * with a type that is exactly equal.
1691 */
1692 switch (pspecs[n]->flags & (G_PARAM_READABLE | G_PARAM_WRITABLE))
1693 {
1694 case G_PARAM_READABLE | G_PARAM_WRITABLE:
1695 /* class pspec value type must have exact equality with interface */
1696 if (pspecs[n]->value_type != class_pspec->value_type)
1697 g_critical ("Read/writable property '%s' on class '%s' has type '%s' which is not exactly equal to the "
1698 "type '%s' of the property on the interface '%s'\n", pspecs[n]->name,
1699 g_type_name (G_OBJECT_CLASS_TYPE (class)), g_type_name (G_PARAM_SPEC_VALUE_TYPE (class_pspec)),
1700 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspecs[n])), g_type_name (iface_type));
1701 break;
1702
1703 case G_PARAM_READABLE:
1704 /* class pspec value type equal or more restrictive than interface */
1705 if (!g_type_is_a (type: class_pspec->value_type, is_a_type: pspecs[n]->value_type))
1706 g_critical ("Read-only property '%s' on class '%s' has type '%s' which is not equal to or more "
1707 "restrictive than the type '%s' of the property on the interface '%s'\n", pspecs[n]->name,
1708 g_type_name (G_OBJECT_CLASS_TYPE (class)), g_type_name (G_PARAM_SPEC_VALUE_TYPE (class_pspec)),
1709 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspecs[n])), g_type_name (iface_type));
1710 break;
1711
1712 case G_PARAM_WRITABLE:
1713 /* class pspec value type equal or less restrictive than interface */
1714 if (!g_type_is_a (type: pspecs[n]->value_type, is_a_type: class_pspec->value_type))
1715 g_critical ("Write-only property '%s' on class '%s' has type '%s' which is not equal to or less "
1716 "restrictive than the type '%s' of the property on the interface '%s' \n", pspecs[n]->name,
1717 g_type_name (G_OBJECT_CLASS_TYPE (class)), g_type_name (G_PARAM_SPEC_VALUE_TYPE (class_pspec)),
1718 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspecs[n])), g_type_name (iface_type));
1719 break;
1720
1721 default:
1722 g_assert_not_reached ();
1723 }
1724 }
1725
1726 g_free (mem: pspecs);
1727
1728 out:
1729 g_type_class_unref (g_class: class);
1730}
1731
1732GType
1733g_object_get_type (void)
1734{
1735 return G_TYPE_OBJECT;
1736}
1737
1738/**
1739 * g_object_new: (skip)
1740 * @object_type: the type id of the #GObject subtype to instantiate
1741 * @first_property_name: the name of the first property
1742 * @...: the value of the first property, followed optionally by more
1743 * name/value pairs, followed by %NULL
1744 *
1745 * Creates a new instance of a #GObject subtype and sets its properties.
1746 *
1747 * Construction parameters (see #G_PARAM_CONSTRUCT, #G_PARAM_CONSTRUCT_ONLY)
1748 * which are not explicitly specified are set to their default values. Any
1749 * private data for the object is guaranteed to be initialized with zeros, as
1750 * per g_type_create_instance().
1751 *
1752 * Note that in C, small integer types in variable argument lists are promoted
1753 * up to #gint or #guint as appropriate, and read back accordingly. #gint is 32
1754 * bits on every platform on which GLib is currently supported. This means that
1755 * you can use C expressions of type #gint with g_object_new() and properties of
1756 * type #gint or #guint or smaller. Specifically, you can use integer literals
1757 * with these property types.
1758 *
1759 * When using property types of #gint64 or #guint64, you must ensure that the
1760 * value that you provide is 64 bit. This means that you should use a cast or
1761 * make use of the %G_GINT64_CONSTANT or %G_GUINT64_CONSTANT macros.
1762 *
1763 * Similarly, #gfloat is promoted to #gdouble, so you must ensure that the value
1764 * you provide is a #gdouble, even for a property of type #gfloat.
1765 *
1766 * Returns: (transfer full) (type GObject.Object): a new instance of
1767 * @object_type
1768 */
1769gpointer
1770g_object_new (GType object_type,
1771 const gchar *first_property_name,
1772 ...)
1773{
1774 GObject *object;
1775 va_list var_args;
1776
1777 /* short circuit for calls supplying no properties */
1778 if (!first_property_name)
1779 return g_object_new_with_properties (object_type, n_properties: 0, NULL, NULL);
1780
1781 va_start (var_args, first_property_name);
1782 object = g_object_new_valist (object_type, first_property_name, var_args);
1783 va_end (var_args);
1784
1785 return object;
1786}
1787
1788static gpointer
1789g_object_new_with_custom_constructor (GObjectClass *class,
1790 GObjectConstructParam *params,
1791 guint n_params)
1792{
1793 GObjectNotifyQueue *nqueue = NULL;
1794 gboolean newly_constructed;
1795 GObjectConstructParam *cparams;
1796 GObject *object;
1797 GValue *cvalues;
1798 gint n_cparams;
1799 gint cvals_used;
1800 GSList *node;
1801 guint i;
1802
1803 /* If we have ->constructed() then we have to do a lot more work.
1804 * It's possible that this is a singleton and it's also possible
1805 * that the user's constructor() will attempt to modify the values
1806 * that we pass in, so we'll need to allocate copies of them.
1807 * It's also possible that the user may attempt to call
1808 * g_object_set() from inside of their constructor, so we need to
1809 * add ourselves to a list of objects for which that is allowed
1810 * while their constructor() is running.
1811 */
1812
1813 /* Create the array of GObjectConstructParams for constructor() */
1814 n_cparams = g_slist_length (list: class->construct_properties);
1815 cparams = g_new (GObjectConstructParam, n_cparams);
1816 cvalues = g_new0 (GValue, n_cparams);
1817 cvals_used = 0;
1818 i = 0;
1819
1820 /* As above, we may find the value in the passed-in params list.
1821 *
1822 * If we have the value passed in then we can use the GValue from
1823 * it directly because it is safe to modify. If we use the
1824 * default value from the class, we had better not pass that in
1825 * and risk it being modified, so we create a new one.
1826 * */
1827 for (node = class->construct_properties; node; node = node->next)
1828 {
1829 GParamSpec *pspec;
1830 GValue *value;
1831 guint j;
1832
1833 pspec = node->data;
1834 value = NULL; /* to silence gcc... */
1835
1836 for (j = 0; j < n_params; j++)
1837 if (params[j].pspec == pspec)
1838 {
1839 consider_issuing_property_deprecation_warning (pspec);
1840 value = params[j].value;
1841 break;
1842 }
1843
1844 if (value == NULL)
1845 {
1846 value = &cvalues[cvals_used++];
1847 g_value_init (value, g_type: pspec->value_type);
1848 g_param_value_set_default (pspec, value);
1849 }
1850
1851 cparams[i].pspec = pspec;
1852 cparams[i].value = value;
1853 i++;
1854 }
1855
1856 /* construct object from construction parameters */
1857 object = class->constructor (class->g_type_class.g_type, n_cparams, cparams);
1858 /* free construction values */
1859 g_free (mem: cparams);
1860 while (cvals_used--)
1861 g_value_unset (value: &cvalues[cvals_used]);
1862 g_free (mem: cvalues);
1863
1864 /* There is code in the wild that relies on being able to return NULL
1865 * from its custom constructor. This was never a supported operation,
1866 * but since the code is already out there...
1867 */
1868 if (object == NULL)
1869 {
1870 g_critical ("Custom constructor for class %s returned NULL (which is invalid). "
1871 "Please use GInitable instead.", G_OBJECT_CLASS_NAME (class));
1872 return NULL;
1873 }
1874
1875 /* g_object_init() will have marked the object as being in-construction.
1876 * Check if the returned object still is so marked, or if this is an
1877 * already-existing singleton (in which case we should not do 'constructed').
1878 */
1879 newly_constructed = object_in_construction (object);
1880 if (newly_constructed)
1881 unset_object_in_construction (object);
1882
1883 if (CLASS_HAS_PROPS (class))
1884 {
1885 /* If this object was newly_constructed then g_object_init()
1886 * froze the queue. We need to freeze it here in order to get
1887 * the handle so that we can thaw it below (otherwise it will
1888 * be frozen forever).
1889 *
1890 * We also want to do a freeze if we have any params to set,
1891 * even on a non-newly_constructed object.
1892 *
1893 * It's possible that we have the case of non-newly created
1894 * singleton and all of the passed-in params were construct
1895 * properties so n_params > 0 but we will actually set no
1896 * properties. This is a pretty lame case to optimise, so
1897 * just ignore it and freeze anyway.
1898 */
1899 if (newly_constructed || n_params)
1900 nqueue = g_object_notify_queue_freeze (object, FALSE);
1901
1902 /* Remember: if it was newly_constructed then g_object_init()
1903 * already did a freeze, so we now have two. Release one.
1904 */
1905 if (newly_constructed)
1906 g_object_notify_queue_thaw (object, nqueue);
1907 }
1908
1909 /* run 'constructed' handler if there is a custom one */
1910 if (newly_constructed && CLASS_HAS_CUSTOM_CONSTRUCTED (class))
1911 class->constructed (object);
1912
1913 /* set remaining properties */
1914 for (i = 0; i < n_params; i++)
1915 if (!(params[i].pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY)))
1916 {
1917 consider_issuing_property_deprecation_warning (pspec: params[i].pspec);
1918 object_set_property (object, pspec: params[i].pspec, value: params[i].value, nqueue);
1919 }
1920
1921 /* If nqueue is non-NULL then we are frozen. Thaw it. */
1922 if (nqueue)
1923 g_object_notify_queue_thaw (object, nqueue);
1924
1925 return object;
1926}
1927
1928static gpointer
1929g_object_new_internal (GObjectClass *class,
1930 GObjectConstructParam *params,
1931 guint n_params)
1932{
1933 GObjectNotifyQueue *nqueue = NULL;
1934 GObject *object;
1935
1936 if G_UNLIKELY (CLASS_HAS_CUSTOM_CONSTRUCTOR (class))
1937 return g_object_new_with_custom_constructor (class, params, n_params);
1938
1939 object = (GObject *) g_type_create_instance (type: class->g_type_class.g_type);
1940
1941 if (CLASS_HAS_PROPS (class))
1942 {
1943 GSList *node;
1944
1945 /* This will have been setup in g_object_init() */
1946 nqueue = g_datalist_id_get_data (datalist: &object->qdata, key_id: quark_notify_queue);
1947 g_assert (nqueue != NULL);
1948
1949 /* We will set exactly n_construct_properties construct
1950 * properties, but they may come from either the class default
1951 * values or the passed-in parameter list.
1952 */
1953 for (node = class->construct_properties; node; node = node->next)
1954 {
1955 const GValue *value;
1956 GParamSpec *pspec;
1957 guint j;
1958
1959 pspec = node->data;
1960 value = NULL; /* to silence gcc... */
1961
1962 for (j = 0; j < n_params; j++)
1963 if (params[j].pspec == pspec)
1964 {
1965 consider_issuing_property_deprecation_warning (pspec);
1966 value = params[j].value;
1967 break;
1968 }
1969
1970 if (value == NULL)
1971 value = g_param_spec_get_default_value (pspec);
1972
1973 object_set_property (object, pspec, value, nqueue);
1974 }
1975 }
1976
1977 /* run 'constructed' handler if there is a custom one */
1978 if (CLASS_HAS_CUSTOM_CONSTRUCTED (class))
1979 class->constructed (object);
1980
1981 if (nqueue)
1982 {
1983 guint i;
1984
1985 /* Set remaining properties. The construct properties will
1986 * already have been taken, so set only the non-construct
1987 * ones.
1988 */
1989 for (i = 0; i < n_params; i++)
1990 if (!(params[i].pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY)))
1991 {
1992 consider_issuing_property_deprecation_warning (pspec: params[i].pspec);
1993 object_set_property (object, pspec: params[i].pspec, value: params[i].value, nqueue);
1994 }
1995
1996 g_object_notify_queue_thaw (object, nqueue);
1997 }
1998
1999 return object;
2000}
2001
2002
2003static inline gboolean
2004g_object_new_is_valid_property (GType object_type,
2005 GParamSpec *pspec,
2006 const char *name,
2007 GObjectConstructParam *params,
2008 guint n_params)
2009{
2010 guint i;
2011
2012 if (G_UNLIKELY (pspec == NULL))
2013 {
2014 g_critical ("%s: object class '%s' has no property named '%s'",
2015 G_STRFUNC, g_type_name (object_type), name);
2016 return FALSE;
2017 }
2018
2019 if (G_UNLIKELY (~pspec->flags & G_PARAM_WRITABLE))
2020 {
2021 g_critical ("%s: property '%s' of object class '%s' is not writable",
2022 G_STRFUNC, pspec->name, g_type_name (object_type));
2023 return FALSE;
2024 }
2025
2026 if (G_UNLIKELY (pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY)))
2027 {
2028 for (i = 0; i < n_params; i++)
2029 if (params[i].pspec == pspec)
2030 break;
2031 if (G_UNLIKELY (i != n_params))
2032 {
2033 g_critical ("%s: property '%s' for type '%s' cannot be set twice",
2034 G_STRFUNC, name, g_type_name (object_type));
2035 return FALSE;
2036 }
2037 }
2038 return TRUE;
2039}
2040
2041
2042/**
2043 * g_object_new_with_properties: (skip)
2044 * @object_type: the object type to instantiate
2045 * @n_properties: the number of properties
2046 * @names: (array length=n_properties): the names of each property to be set
2047 * @values: (array length=n_properties): the values of each property to be set
2048 *
2049 * Creates a new instance of a #GObject subtype and sets its properties using
2050 * the provided arrays. Both arrays must have exactly @n_properties elements,
2051 * and the names and values correspond by index.
2052 *
2053 * Construction parameters (see %G_PARAM_CONSTRUCT, %G_PARAM_CONSTRUCT_ONLY)
2054 * which are not explicitly specified are set to their default values.
2055 *
2056 * Returns: (type GObject.Object) (transfer full): a new instance of
2057 * @object_type
2058 *
2059 * Since: 2.54
2060 */
2061GObject *
2062g_object_new_with_properties (GType object_type,
2063 guint n_properties,
2064 const char *names[],
2065 const GValue values[])
2066{
2067 GObjectClass *class, *unref_class = NULL;
2068 GObject *object;
2069
2070 g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type), NULL);
2071
2072 /* Try to avoid thrashing the ref_count if we don't need to (since
2073 * it's a locked operation).
2074 */
2075 class = g_type_class_peek_static (type: object_type);
2076
2077 if (class == NULL)
2078 class = unref_class = g_type_class_ref (type: object_type);
2079
2080 if (n_properties > 0)
2081 {
2082 guint i, count = 0;
2083 GObjectConstructParam *params;
2084
2085 params = g_newa (GObjectConstructParam, n_properties);
2086 for (i = 0; i < n_properties; i++)
2087 {
2088 GParamSpec *pspec;
2089 pspec = g_param_spec_pool_lookup (pool: pspec_pool, param_name: names[i], owner_type: object_type, TRUE);
2090 if (!g_object_new_is_valid_property (object_type, pspec, name: names[i], params, n_params: count))
2091 continue;
2092 params[count].pspec = pspec;
2093
2094 /* Init GValue */
2095 params[count].value = g_newa (GValue, 1);
2096 memset (s: params[count].value, c: 0, n: sizeof (GValue));
2097 g_value_init (value: params[count].value, G_VALUE_TYPE (&values[i]));
2098
2099 g_value_copy (src_value: &values[i], dest_value: params[count].value);
2100 count++;
2101 }
2102 object = g_object_new_internal (class, params, n_params: count);
2103
2104 while (count--)
2105 g_value_unset (value: params[count].value);
2106 }
2107 else
2108 object = g_object_new_internal (class, NULL, n_params: 0);
2109
2110 if (unref_class != NULL)
2111 g_type_class_unref (g_class: unref_class);
2112
2113 return object;
2114}
2115
2116/**
2117 * g_object_newv:
2118 * @object_type: the type id of the #GObject subtype to instantiate
2119 * @n_parameters: the length of the @parameters array
2120 * @parameters: (array length=n_parameters): an array of #GParameter
2121 *
2122 * Creates a new instance of a #GObject subtype and sets its properties.
2123 *
2124 * Construction parameters (see #G_PARAM_CONSTRUCT, #G_PARAM_CONSTRUCT_ONLY)
2125 * which are not explicitly specified are set to their default values.
2126 *
2127 * Returns: (type GObject.Object) (transfer full): a new instance of
2128 * @object_type
2129 *
2130 * Deprecated: 2.54: Use g_object_new_with_properties() instead.
2131 * deprecated. See #GParameter for more information.
2132 */
2133G_GNUC_BEGIN_IGNORE_DEPRECATIONS
2134gpointer
2135g_object_newv (GType object_type,
2136 guint n_parameters,
2137 GParameter *parameters)
2138{
2139 GObjectClass *class, *unref_class = NULL;
2140 GObject *object;
2141
2142 g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type), NULL);
2143 g_return_val_if_fail (n_parameters == 0 || parameters != NULL, NULL);
2144
2145 /* Try to avoid thrashing the ref_count if we don't need to (since
2146 * it's a locked operation).
2147 */
2148 class = g_type_class_peek_static (type: object_type);
2149
2150 if (!class)
2151 class = unref_class = g_type_class_ref (type: object_type);
2152
2153 if (n_parameters)
2154 {
2155 GObjectConstructParam *cparams;
2156 guint i, j;
2157
2158 cparams = g_newa (GObjectConstructParam, n_parameters);
2159 j = 0;
2160
2161 for (i = 0; i < n_parameters; i++)
2162 {
2163 GParamSpec *pspec;
2164
2165 pspec = g_param_spec_pool_lookup (pool: pspec_pool, param_name: parameters[i].name, owner_type: object_type, TRUE);
2166 if (!g_object_new_is_valid_property (object_type, pspec, name: parameters[i].name, params: cparams, n_params: j))
2167 continue;
2168
2169 cparams[j].pspec = pspec;
2170 cparams[j].value = &parameters[i].value;
2171 j++;
2172 }
2173
2174 object = g_object_new_internal (class, params: cparams, n_params: j);
2175 }
2176 else
2177 /* Fast case: no properties passed in. */
2178 object = g_object_new_internal (class, NULL, n_params: 0);
2179
2180 if (unref_class)
2181 g_type_class_unref (g_class: unref_class);
2182
2183 return object;
2184}
2185G_GNUC_END_IGNORE_DEPRECATIONS
2186
2187/**
2188 * g_object_new_valist: (skip)
2189 * @object_type: the type id of the #GObject subtype to instantiate
2190 * @first_property_name: the name of the first property
2191 * @var_args: the value of the first property, followed optionally by more
2192 * name/value pairs, followed by %NULL
2193 *
2194 * Creates a new instance of a #GObject subtype and sets its properties.
2195 *
2196 * Construction parameters (see #G_PARAM_CONSTRUCT, #G_PARAM_CONSTRUCT_ONLY)
2197 * which are not explicitly specified are set to their default values.
2198 *
2199 * Returns: a new instance of @object_type
2200 */
2201GObject*
2202g_object_new_valist (GType object_type,
2203 const gchar *first_property_name,
2204 va_list var_args)
2205{
2206 GObjectClass *class, *unref_class = NULL;
2207 GObject *object;
2208
2209 g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type), NULL);
2210
2211 /* Try to avoid thrashing the ref_count if we don't need to (since
2212 * it's a locked operation).
2213 */
2214 class = g_type_class_peek_static (type: object_type);
2215
2216 if (!class)
2217 class = unref_class = g_type_class_ref (type: object_type);
2218
2219 if (first_property_name)
2220 {
2221 GObjectConstructParam params_stack[16];
2222 GValue values_stack[G_N_ELEMENTS (params_stack)];
2223 const gchar *name;
2224 GObjectConstructParam *params = params_stack;
2225 GValue *values = values_stack;
2226 guint n_params = 0;
2227 guint n_params_alloc = G_N_ELEMENTS (params_stack);
2228
2229 name = first_property_name;
2230
2231 do
2232 {
2233 gchar *error = NULL;
2234 GParamSpec *pspec;
2235
2236 pspec = g_param_spec_pool_lookup (pool: pspec_pool, param_name: name, owner_type: object_type, TRUE);
2237
2238 if (!g_object_new_is_valid_property (object_type, pspec, name, params, n_params))
2239 break;
2240
2241 if (G_UNLIKELY (n_params == n_params_alloc))
2242 {
2243 guint i;
2244
2245 if (n_params_alloc == G_N_ELEMENTS (params_stack))
2246 {
2247 n_params_alloc = G_N_ELEMENTS (params_stack) * 2u;
2248 params = g_new (GObjectConstructParam, n_params_alloc);
2249 values = g_new (GValue, n_params_alloc);
2250 memcpy (dest: params, src: params_stack, n: sizeof (GObjectConstructParam) * n_params);
2251 memcpy (dest: values, src: values_stack, n: sizeof (GValue) * n_params);
2252 }
2253 else
2254 {
2255 n_params_alloc *= 2u;
2256 params = g_realloc (mem: params, n_bytes: sizeof (GObjectConstructParam) * n_params_alloc);
2257 values = g_realloc (mem: values, n_bytes: sizeof (GValue) * n_params_alloc);
2258 }
2259
2260 for (i = 0; i < n_params; i++)
2261 params[i].value = &values[i];
2262 }
2263
2264 params[n_params].pspec = pspec;
2265 params[n_params].value = &values[n_params];
2266 memset (s: &values[n_params], c: 0, n: sizeof (GValue));
2267
2268 G_VALUE_COLLECT_INIT (&values[n_params], pspec->value_type, var_args, 0, &error);
2269
2270 if (error)
2271 {
2272 g_critical ("%s: %s", G_STRFUNC, error);
2273 g_value_unset (value: &values[n_params]);
2274 g_free (mem: error);
2275 break;
2276 }
2277
2278 n_params++;
2279 }
2280 while ((name = va_arg (var_args, const gchar *)));
2281
2282 object = g_object_new_internal (class, params, n_params);
2283
2284 while (n_params--)
2285 g_value_unset (value: params[n_params].value);
2286
2287 if (G_UNLIKELY (n_params_alloc != G_N_ELEMENTS (params_stack)))
2288 {
2289 g_free (mem: params);
2290 g_free (mem: values);
2291 }
2292 }
2293 else
2294 /* Fast case: no properties passed in. */
2295 object = g_object_new_internal (class, NULL, n_params: 0);
2296
2297 if (unref_class)
2298 g_type_class_unref (g_class: unref_class);
2299
2300 return object;
2301}
2302
2303static GObject*
2304g_object_constructor (GType type,
2305 guint n_construct_properties,
2306 GObjectConstructParam *construct_params)
2307{
2308 GObject *object;
2309
2310 /* create object */
2311 object = (GObject*) g_type_create_instance (type);
2312
2313 /* set construction parameters */
2314 if (n_construct_properties)
2315 {
2316 GObjectNotifyQueue *nqueue = g_object_notify_queue_freeze (object, FALSE);
2317
2318 /* set construct properties */
2319 while (n_construct_properties--)
2320 {
2321 GValue *value = construct_params->value;
2322 GParamSpec *pspec = construct_params->pspec;
2323
2324 construct_params++;
2325 object_set_property (object, pspec, value, nqueue);
2326 }
2327 g_object_notify_queue_thaw (object, nqueue);
2328 /* the notification queue is still frozen from g_object_init(), so
2329 * we don't need to handle it here, g_object_newv() takes
2330 * care of that
2331 */
2332 }
2333
2334 return object;
2335}
2336
2337static void
2338g_object_constructed (GObject *object)
2339{
2340 /* empty default impl to allow unconditional upchaining */
2341}
2342
2343static inline gboolean
2344g_object_set_is_valid_property (GObject *object,
2345 GParamSpec *pspec,
2346 const char *property_name)
2347{
2348 if (G_UNLIKELY (pspec == NULL))
2349 {
2350 g_warning ("%s: object class '%s' has no property named '%s'",
2351 G_STRFUNC, G_OBJECT_TYPE_NAME (object), property_name);
2352 return FALSE;
2353 }
2354 if (G_UNLIKELY (!(pspec->flags & G_PARAM_WRITABLE)))
2355 {
2356 g_warning ("%s: property '%s' of object class '%s' is not writable",
2357 G_STRFUNC, pspec->name, G_OBJECT_TYPE_NAME (object));
2358 return FALSE;
2359 }
2360 if (G_UNLIKELY (((pspec->flags & G_PARAM_CONSTRUCT_ONLY) && !object_in_construction (object))))
2361 {
2362 g_warning ("%s: construct property \"%s\" for object '%s' can't be set after construction",
2363 G_STRFUNC, pspec->name, G_OBJECT_TYPE_NAME (object));
2364 return FALSE;
2365 }
2366 return TRUE;
2367}
2368
2369/**
2370 * g_object_setv: (skip)
2371 * @object: a #GObject
2372 * @n_properties: the number of properties
2373 * @names: (array length=n_properties): the names of each property to be set
2374 * @values: (array length=n_properties): the values of each property to be set
2375 *
2376 * Sets @n_properties properties for an @object.
2377 * Properties to be set will be taken from @values. All properties must be
2378 * valid. Warnings will be emitted and undefined behaviour may result if invalid
2379 * properties are passed in.
2380 *
2381 * Since: 2.54
2382 */
2383void
2384g_object_setv (GObject *object,
2385 guint n_properties,
2386 const gchar *names[],
2387 const GValue values[])
2388{
2389 guint i;
2390 GObjectNotifyQueue *nqueue;
2391 GParamSpec *pspec;
2392 GType obj_type;
2393
2394 g_return_if_fail (G_IS_OBJECT (object));
2395
2396 if (n_properties == 0)
2397 return;
2398
2399 g_object_ref (object);
2400 obj_type = G_OBJECT_TYPE (object);
2401 nqueue = g_object_notify_queue_freeze (object, FALSE);
2402 for (i = 0; i < n_properties; i++)
2403 {
2404 pspec = g_param_spec_pool_lookup (pool: pspec_pool, param_name: names[i], owner_type: obj_type, TRUE);
2405
2406 if (!g_object_set_is_valid_property (object, pspec, property_name: names[i]))
2407 break;
2408
2409 consider_issuing_property_deprecation_warning (pspec);
2410 object_set_property (object, pspec, value: &values[i], nqueue);
2411 }
2412
2413 g_object_notify_queue_thaw (object, nqueue);
2414 g_object_unref (object);
2415}
2416
2417/**
2418 * g_object_set_valist: (skip)
2419 * @object: a #GObject
2420 * @first_property_name: name of the first property to set
2421 * @var_args: value for the first property, followed optionally by more
2422 * name/value pairs, followed by %NULL
2423 *
2424 * Sets properties on an object.
2425 */
2426void
2427g_object_set_valist (GObject *object,
2428 const gchar *first_property_name,
2429 va_list var_args)
2430{
2431 GObjectNotifyQueue *nqueue;
2432 const gchar *name;
2433
2434 g_return_if_fail (G_IS_OBJECT (object));
2435
2436 g_object_ref (object);
2437 nqueue = g_object_notify_queue_freeze (object, FALSE);
2438
2439 name = first_property_name;
2440 while (name)
2441 {
2442 GValue value = G_VALUE_INIT;
2443 GParamSpec *pspec;
2444 gchar *error = NULL;
2445
2446 pspec = g_param_spec_pool_lookup (pool: pspec_pool,
2447 param_name: name,
2448 G_OBJECT_TYPE (object),
2449 TRUE);
2450
2451 if (!g_object_set_is_valid_property (object, pspec, property_name: name))
2452 break;
2453
2454 G_VALUE_COLLECT_INIT (&value, pspec->value_type, var_args,
2455 0, &error);
2456 if (error)
2457 {
2458 g_warning ("%s: %s", G_STRFUNC, error);
2459 g_free (mem: error);
2460 g_value_unset (value: &value);
2461 break;
2462 }
2463
2464 consider_issuing_property_deprecation_warning (pspec);
2465 object_set_property (object, pspec, value: &value, nqueue);
2466 g_value_unset (value: &value);
2467
2468 name = va_arg (var_args, gchar*);
2469 }
2470
2471 g_object_notify_queue_thaw (object, nqueue);
2472 g_object_unref (object);
2473}
2474
2475static inline gboolean
2476g_object_get_is_valid_property (GObject *object,
2477 GParamSpec *pspec,
2478 const char *property_name)
2479{
2480 if (G_UNLIKELY (pspec == NULL))
2481 {
2482 g_warning ("%s: object class '%s' has no property named '%s'",
2483 G_STRFUNC, G_OBJECT_TYPE_NAME (object), property_name);
2484 return FALSE;
2485 }
2486 if (G_UNLIKELY (!(pspec->flags & G_PARAM_READABLE)))
2487 {
2488 g_warning ("%s: property '%s' of object class '%s' is not readable",
2489 G_STRFUNC, pspec->name, G_OBJECT_TYPE_NAME (object));
2490 return FALSE;
2491 }
2492 return TRUE;
2493}
2494
2495/**
2496 * g_object_getv:
2497 * @object: a #GObject
2498 * @n_properties: the number of properties
2499 * @names: (array length=n_properties): the names of each property to get
2500 * @values: (array length=n_properties): the values of each property to get
2501 *
2502 * Gets @n_properties properties for an @object.
2503 * Obtained properties will be set to @values. All properties must be valid.
2504 * Warnings will be emitted and undefined behaviour may result if invalid
2505 * properties are passed in.
2506 *
2507 * Since: 2.54
2508 */
2509void
2510g_object_getv (GObject *object,
2511 guint n_properties,
2512 const gchar *names[],
2513 GValue values[])
2514{
2515 guint i;
2516 GParamSpec *pspec;
2517 GType obj_type;
2518
2519 g_return_if_fail (G_IS_OBJECT (object));
2520
2521 if (n_properties == 0)
2522 return;
2523
2524 g_object_ref (object);
2525
2526 obj_type = G_OBJECT_TYPE (object);
2527 for (i = 0; i < n_properties; i++)
2528 {
2529 pspec = g_param_spec_pool_lookup (pool: pspec_pool,
2530 param_name: names[i],
2531 owner_type: obj_type,
2532 TRUE);
2533 if (!g_object_get_is_valid_property (object, pspec, property_name: names[i]))
2534 break;
2535
2536 memset (s: &values[i], c: 0, n: sizeof (GValue));
2537 g_value_init (value: &values[i], g_type: pspec->value_type);
2538 object_get_property (object, pspec, value: &values[i]);
2539 }
2540 g_object_unref (object);
2541}
2542
2543/**
2544 * g_object_get_valist: (skip)
2545 * @object: a #GObject
2546 * @first_property_name: name of the first property to get
2547 * @var_args: return location for the first property, followed optionally by more
2548 * name/return location pairs, followed by %NULL
2549 *
2550 * Gets properties of an object.
2551 *
2552 * In general, a copy is made of the property contents and the caller
2553 * is responsible for freeing the memory in the appropriate manner for
2554 * the type, for instance by calling g_free() or g_object_unref().
2555 *
2556 * See g_object_get().
2557 */
2558void
2559g_object_get_valist (GObject *object,
2560 const gchar *first_property_name,
2561 va_list var_args)
2562{
2563 const gchar *name;
2564
2565 g_return_if_fail (G_IS_OBJECT (object));
2566
2567 g_object_ref (object);
2568
2569 name = first_property_name;
2570
2571 while (name)
2572 {
2573 GValue value = G_VALUE_INIT;
2574 GParamSpec *pspec;
2575 gchar *error;
2576
2577 pspec = g_param_spec_pool_lookup (pool: pspec_pool,
2578 param_name: name,
2579 G_OBJECT_TYPE (object),
2580 TRUE);
2581
2582 if (!g_object_get_is_valid_property (object, pspec, property_name: name))
2583 break;
2584
2585 g_value_init (value: &value, g_type: pspec->value_type);
2586
2587 object_get_property (object, pspec, value: &value);
2588
2589 G_VALUE_LCOPY (&value, var_args, 0, &error);
2590 if (error)
2591 {
2592 g_warning ("%s: %s", G_STRFUNC, error);
2593 g_free (mem: error);
2594 g_value_unset (value: &value);
2595 break;
2596 }
2597
2598 g_value_unset (value: &value);
2599
2600 name = va_arg (var_args, gchar*);
2601 }
2602
2603 g_object_unref (object);
2604}
2605
2606/**
2607 * g_object_set: (skip)
2608 * @object: (type GObject.Object): a #GObject
2609 * @first_property_name: name of the first property to set
2610 * @...: value for the first property, followed optionally by more
2611 * name/value pairs, followed by %NULL
2612 *
2613 * Sets properties on an object.
2614 *
2615 * The same caveats about passing integer literals as varargs apply as with
2616 * g_object_new(). In particular, any integer literals set as the values for
2617 * properties of type #gint64 or #guint64 must be 64 bits wide, using the
2618 * %G_GINT64_CONSTANT or %G_GUINT64_CONSTANT macros.
2619 *
2620 * Note that the "notify" signals are queued and only emitted (in
2621 * reverse order) after all properties have been set. See
2622 * g_object_freeze_notify().
2623 */
2624void
2625g_object_set (gpointer _object,
2626 const gchar *first_property_name,
2627 ...)
2628{
2629 GObject *object = _object;
2630 va_list var_args;
2631
2632 g_return_if_fail (G_IS_OBJECT (object));
2633
2634 va_start (var_args, first_property_name);
2635 g_object_set_valist (object, first_property_name, var_args);
2636 va_end (var_args);
2637}
2638
2639/**
2640 * g_object_get: (skip)
2641 * @object: (type GObject.Object): a #GObject
2642 * @first_property_name: name of the first property to get
2643 * @...: return location for the first property, followed optionally by more
2644 * name/return location pairs, followed by %NULL
2645 *
2646 * Gets properties of an object.
2647 *
2648 * In general, a copy is made of the property contents and the caller
2649 * is responsible for freeing the memory in the appropriate manner for
2650 * the type, for instance by calling g_free() or g_object_unref().
2651 *
2652 * Here is an example of using g_object_get() to get the contents
2653 * of three properties: an integer, a string and an object:
2654 * |[<!-- language="C" -->
2655 * gint intval;
2656 * guint64 uint64val;
2657 * gchar *strval;
2658 * GObject *objval;
2659 *
2660 * g_object_get (my_object,
2661 * "int-property", &intval,
2662 * "uint64-property", &uint64val,
2663 * "str-property", &strval,
2664 * "obj-property", &objval,
2665 * NULL);
2666 *
2667 * // Do something with intval, uint64val, strval, objval
2668 *
2669 * g_free (strval);
2670 * g_object_unref (objval);
2671 * ]|
2672 */
2673void
2674g_object_get (gpointer _object,
2675 const gchar *first_property_name,
2676 ...)
2677{
2678 GObject *object = _object;
2679 va_list var_args;
2680
2681 g_return_if_fail (G_IS_OBJECT (object));
2682
2683 va_start (var_args, first_property_name);
2684 g_object_get_valist (object, first_property_name, var_args);
2685 va_end (var_args);
2686}
2687
2688/**
2689 * g_object_set_property:
2690 * @object: a #GObject
2691 * @property_name: the name of the property to set
2692 * @value: the value
2693 *
2694 * Sets a property on an object.
2695 */
2696void
2697g_object_set_property (GObject *object,
2698 const gchar *property_name,
2699 const GValue *value)
2700{
2701 g_object_setv (object, n_properties: 1, names: &property_name, values: value);
2702}
2703
2704/**
2705 * g_object_get_property:
2706 * @object: a #GObject
2707 * @property_name: the name of the property to get
2708 * @value: return location for the property value
2709 *
2710 * Gets a property of an object.
2711 *
2712 * The @value can be:
2713 *
2714 * - an empty #GValue initialized by %G_VALUE_INIT, which will be
2715 * automatically initialized with the expected type of the property
2716 * (since GLib 2.60)
2717 * - a #GValue initialized with the expected type of the property
2718 * - a #GValue initialized with a type to which the expected type
2719 * of the property can be transformed
2720 *
2721 * In general, a copy is made of the property contents and the caller is
2722 * responsible for freeing the memory by calling g_value_unset().
2723 *
2724 * Note that g_object_get_property() is really intended for language
2725 * bindings, g_object_get() is much more convenient for C programming.
2726 */
2727void
2728g_object_get_property (GObject *object,
2729 const gchar *property_name,
2730 GValue *value)
2731{
2732 GParamSpec *pspec;
2733
2734 g_return_if_fail (G_IS_OBJECT (object));
2735 g_return_if_fail (property_name != NULL);
2736 g_return_if_fail (value != NULL);
2737
2738 g_object_ref (object);
2739
2740 pspec = g_param_spec_pool_lookup (pool: pspec_pool,
2741 param_name: property_name,
2742 G_OBJECT_TYPE (object),
2743 TRUE);
2744
2745 if (g_object_get_is_valid_property (object, pspec, property_name))
2746 {
2747 GValue *prop_value, tmp_value = G_VALUE_INIT;
2748
2749 if (G_VALUE_TYPE (value) == G_TYPE_INVALID)
2750 {
2751 /* zero-initialized value */
2752 g_value_init (value, g_type: pspec->value_type);
2753 prop_value = value;
2754 }
2755 else if (G_VALUE_TYPE (value) == pspec->value_type)
2756 {
2757 /* auto-conversion of the callers value type */
2758 g_value_reset (value);
2759 prop_value = value;
2760 }
2761 else if (!g_value_type_transformable (src_type: pspec->value_type, G_VALUE_TYPE (value)))
2762 {
2763 g_warning ("%s: can't retrieve property '%s' of type '%s' as value of type '%s'",
2764 G_STRFUNC, pspec->name,
2765 g_type_name (pspec->value_type),
2766 G_VALUE_TYPE_NAME (value));
2767 g_object_unref (object);
2768 return;
2769 }
2770 else
2771 {
2772 g_value_init (value: &tmp_value, g_type: pspec->value_type);
2773 prop_value = &tmp_value;
2774 }
2775 object_get_property (object, pspec, value: prop_value);
2776 if (prop_value != value)
2777 {
2778 g_value_transform (src_value: prop_value, dest_value: value);
2779 g_value_unset (value: &tmp_value);
2780 }
2781 }
2782
2783 g_object_unref (object);
2784}
2785
2786/**
2787 * g_object_connect: (skip)
2788 * @object: (type GObject.Object): a #GObject
2789 * @signal_spec: the spec for the first signal
2790 * @...: #GCallback for the first signal, followed by data for the
2791 * first signal, followed optionally by more signal
2792 * spec/callback/data triples, followed by %NULL
2793 *
2794 * A convenience function to connect multiple signals at once.
2795 *
2796 * The signal specs expected by this function have the form
2797 * "modifier::signal_name", where modifier can be one of the following:
2798 * - signal: equivalent to g_signal_connect_data (..., NULL, 0)
2799 * - object-signal, object_signal: equivalent to g_signal_connect_object (..., 0)
2800 * - swapped-signal, swapped_signal: equivalent to g_signal_connect_data (..., NULL, G_CONNECT_SWAPPED)
2801 * - swapped_object_signal, swapped-object-signal: equivalent to g_signal_connect_object (..., G_CONNECT_SWAPPED)
2802 * - signal_after, signal-after: equivalent to g_signal_connect_data (..., NULL, G_CONNECT_AFTER)
2803 * - object_signal_after, object-signal-after: equivalent to g_signal_connect_object (..., G_CONNECT_AFTER)
2804 * - swapped_signal_after, swapped-signal-after: equivalent to g_signal_connect_data (..., NULL, G_CONNECT_SWAPPED | G_CONNECT_AFTER)
2805 * - swapped_object_signal_after, swapped-object-signal-after: equivalent to g_signal_connect_object (..., G_CONNECT_SWAPPED | G_CONNECT_AFTER)
2806 *
2807 * |[<!-- language="C" -->
2808 * menu->toplevel = g_object_connect (g_object_new (GTK_TYPE_WINDOW,
2809 * "type", GTK_WINDOW_POPUP,
2810 * "child", menu,
2811 * NULL),
2812 * "signal::event", gtk_menu_window_event, menu,
2813 * "signal::size_request", gtk_menu_window_size_request, menu,
2814 * "signal::destroy", gtk_widget_destroyed, &menu->toplevel,
2815 * NULL);
2816 * ]|
2817 *
2818 * Returns: (transfer none) (type GObject.Object): @object
2819 */
2820gpointer
2821g_object_connect (gpointer _object,
2822 const gchar *signal_spec,
2823 ...)
2824{
2825 GObject *object = _object;
2826 va_list var_args;
2827
2828 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
2829 g_return_val_if_fail (object->ref_count > 0, object);
2830
2831 va_start (var_args, signal_spec);
2832 while (signal_spec)
2833 {
2834 GCallback callback = va_arg (var_args, GCallback);
2835 gpointer data = va_arg (var_args, gpointer);
2836
2837 if (strncmp (s1: signal_spec, s2: "signal::", n: 8) == 0)
2838 g_signal_connect_data (instance: object, detailed_signal: signal_spec + 8,
2839 c_handler: callback, data, NULL,
2840 connect_flags: 0);
2841 else if (strncmp (s1: signal_spec, s2: "object_signal::", n: 15) == 0 ||
2842 strncmp (s1: signal_spec, s2: "object-signal::", n: 15) == 0)
2843 g_signal_connect_object (instance: object, detailed_signal: signal_spec + 15,
2844 c_handler: callback, gobject: data,
2845 connect_flags: 0);
2846 else if (strncmp (s1: signal_spec, s2: "swapped_signal::", n: 16) == 0 ||
2847 strncmp (s1: signal_spec, s2: "swapped-signal::", n: 16) == 0)
2848 g_signal_connect_data (instance: object, detailed_signal: signal_spec + 16,
2849 c_handler: callback, data, NULL,
2850 connect_flags: G_CONNECT_SWAPPED);
2851 else if (strncmp (s1: signal_spec, s2: "swapped_object_signal::", n: 23) == 0 ||
2852 strncmp (s1: signal_spec, s2: "swapped-object-signal::", n: 23) == 0)
2853 g_signal_connect_object (instance: object, detailed_signal: signal_spec + 23,
2854 c_handler: callback, gobject: data,
2855 connect_flags: G_CONNECT_SWAPPED);
2856 else if (strncmp (s1: signal_spec, s2: "signal_after::", n: 14) == 0 ||
2857 strncmp (s1: signal_spec, s2: "signal-after::", n: 14) == 0)
2858 g_signal_connect_data (instance: object, detailed_signal: signal_spec + 14,
2859 c_handler: callback, data, NULL,
2860 connect_flags: G_CONNECT_AFTER);
2861 else if (strncmp (s1: signal_spec, s2: "object_signal_after::", n: 21) == 0 ||
2862 strncmp (s1: signal_spec, s2: "object-signal-after::", n: 21) == 0)
2863 g_signal_connect_object (instance: object, detailed_signal: signal_spec + 21,
2864 c_handler: callback, gobject: data,
2865 connect_flags: G_CONNECT_AFTER);
2866 else if (strncmp (s1: signal_spec, s2: "swapped_signal_after::", n: 22) == 0 ||
2867 strncmp (s1: signal_spec, s2: "swapped-signal-after::", n: 22) == 0)
2868 g_signal_connect_data (instance: object, detailed_signal: signal_spec + 22,
2869 c_handler: callback, data, NULL,
2870 connect_flags: G_CONNECT_SWAPPED | G_CONNECT_AFTER);
2871 else if (strncmp (s1: signal_spec, s2: "swapped_object_signal_after::", n: 29) == 0 ||
2872 strncmp (s1: signal_spec, s2: "swapped-object-signal-after::", n: 29) == 0)
2873 g_signal_connect_object (instance: object, detailed_signal: signal_spec + 29,
2874 c_handler: callback, gobject: data,
2875 connect_flags: G_CONNECT_SWAPPED | G_CONNECT_AFTER);
2876 else
2877 {
2878 g_warning ("%s: invalid signal spec \"%s\"", G_STRFUNC, signal_spec);
2879 break;
2880 }
2881 signal_spec = va_arg (var_args, gchar*);
2882 }
2883 va_end (var_args);
2884
2885 return object;
2886}
2887
2888/**
2889 * g_object_disconnect: (skip)
2890 * @object: (type GObject.Object): a #GObject
2891 * @signal_spec: the spec for the first signal
2892 * @...: #GCallback for the first signal, followed by data for the first signal,
2893 * followed optionally by more signal spec/callback/data triples,
2894 * followed by %NULL
2895 *
2896 * A convenience function to disconnect multiple signals at once.
2897 *
2898 * The signal specs expected by this function have the form
2899 * "any_signal", which means to disconnect any signal with matching
2900 * callback and data, or "any_signal::signal_name", which only
2901 * disconnects the signal named "signal_name".
2902 */
2903void
2904g_object_disconnect (gpointer _object,
2905 const gchar *signal_spec,
2906 ...)
2907{
2908 GObject *object = _object;
2909 va_list var_args;
2910
2911 g_return_if_fail (G_IS_OBJECT (object));
2912 g_return_if_fail (object->ref_count > 0);
2913
2914 va_start (var_args, signal_spec);
2915 while (signal_spec)
2916 {
2917 GCallback callback = va_arg (var_args, GCallback);
2918 gpointer data = va_arg (var_args, gpointer);
2919 guint sid = 0, detail = 0, mask = 0;
2920
2921 if (strncmp (s1: signal_spec, s2: "any_signal::", n: 12) == 0 ||
2922 strncmp (s1: signal_spec, s2: "any-signal::", n: 12) == 0)
2923 {
2924 signal_spec += 12;
2925 mask = G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA;
2926 }
2927 else if (strcmp (s1: signal_spec, s2: "any_signal") == 0 ||
2928 strcmp (s1: signal_spec, s2: "any-signal") == 0)
2929 {
2930 signal_spec += 10;
2931 mask = G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA;
2932 }
2933 else
2934 {
2935 g_warning ("%s: invalid signal spec \"%s\"", G_STRFUNC, signal_spec);
2936 break;
2937 }
2938
2939 if ((mask & G_SIGNAL_MATCH_ID) &&
2940 !g_signal_parse_name (detailed_signal: signal_spec, G_OBJECT_TYPE (object), signal_id_p: &sid, detail_p: &detail, FALSE))
2941 g_warning ("%s: invalid signal name \"%s\"", G_STRFUNC, signal_spec);
2942 else if (!g_signal_handlers_disconnect_matched (instance: object, mask: mask | (detail ? G_SIGNAL_MATCH_DETAIL : 0),
2943 signal_id: sid, detail,
2944 NULL, func: (gpointer)callback, data))
2945 g_warning ("%s: signal handler %p(%p) is not connected", G_STRFUNC, callback, data);
2946 signal_spec = va_arg (var_args, gchar*);
2947 }
2948 va_end (var_args);
2949}
2950
2951typedef struct {
2952 GObject *object;
2953 guint n_weak_refs;
2954 struct {
2955 GWeakNotify notify;
2956 gpointer data;
2957 } weak_refs[1]; /* flexible array */
2958} WeakRefStack;
2959
2960static void
2961weak_refs_notify (gpointer data)
2962{
2963 WeakRefStack *wstack = data;
2964 guint i;
2965
2966 for (i = 0; i < wstack->n_weak_refs; i++)
2967 wstack->weak_refs[i].notify (wstack->weak_refs[i].data, wstack->object);
2968 g_free (mem: wstack);
2969}
2970
2971/**
2972 * g_object_weak_ref: (skip)
2973 * @object: #GObject to reference weakly
2974 * @notify: callback to invoke before the object is freed
2975 * @data: extra data to pass to notify
2976 *
2977 * Adds a weak reference callback to an object. Weak references are
2978 * used for notification when an object is disposed. They are called
2979 * "weak references" because they allow you to safely hold a pointer
2980 * to an object without calling g_object_ref() (g_object_ref() adds a
2981 * strong reference, that is, forces the object to stay alive).
2982 *
2983 * Note that the weak references created by this method are not
2984 * thread-safe: they cannot safely be used in one thread if the
2985 * object's last g_object_unref() might happen in another thread.
2986 * Use #GWeakRef if thread-safety is required.
2987 */
2988void
2989g_object_weak_ref (GObject *object,
2990 GWeakNotify notify,
2991 gpointer data)
2992{
2993 WeakRefStack *wstack;
2994 guint i;
2995
2996 g_return_if_fail (G_IS_OBJECT (object));
2997 g_return_if_fail (notify != NULL);
2998 g_return_if_fail (g_atomic_int_get (&object->ref_count) >= 1);
2999
3000 G_LOCK (weak_refs_mutex);
3001 wstack = g_datalist_id_remove_no_notify (datalist: &object->qdata, key_id: quark_weak_refs);
3002 if (wstack)
3003 {
3004 i = wstack->n_weak_refs++;
3005 wstack = g_realloc (mem: wstack, n_bytes: sizeof (*wstack) + sizeof (wstack->weak_refs[0]) * i);
3006 }
3007 else
3008 {
3009 wstack = g_renew (WeakRefStack, NULL, 1);
3010 wstack->object = object;
3011 wstack->n_weak_refs = 1;
3012 i = 0;
3013 }
3014 wstack->weak_refs[i].notify = notify;
3015 wstack->weak_refs[i].data = data;
3016 g_datalist_id_set_data_full (datalist: &object->qdata, key_id: quark_weak_refs, data: wstack, destroy_func: weak_refs_notify);
3017 G_UNLOCK (weak_refs_mutex);
3018}
3019
3020/**
3021 * g_object_weak_unref: (skip)
3022 * @object: #GObject to remove a weak reference from
3023 * @notify: callback to search for
3024 * @data: data to search for
3025 *
3026 * Removes a weak reference callback to an object.
3027 */
3028void
3029g_object_weak_unref (GObject *object,
3030 GWeakNotify notify,
3031 gpointer data)
3032{
3033 WeakRefStack *wstack;
3034 gboolean found_one = FALSE;
3035
3036 g_return_if_fail (G_IS_OBJECT (object));
3037 g_return_if_fail (notify != NULL);
3038
3039 G_LOCK (weak_refs_mutex);
3040 wstack = g_datalist_id_get_data (datalist: &object->qdata, key_id: quark_weak_refs);
3041 if (wstack)
3042 {
3043 guint i;
3044
3045 for (i = 0; i < wstack->n_weak_refs; i++)
3046 if (wstack->weak_refs[i].notify == notify &&
3047 wstack->weak_refs[i].data == data)
3048 {
3049 found_one = TRUE;
3050 wstack->n_weak_refs -= 1;
3051 if (i != wstack->n_weak_refs)
3052 wstack->weak_refs[i] = wstack->weak_refs[wstack->n_weak_refs];
3053
3054 break;
3055 }
3056 }
3057 G_UNLOCK (weak_refs_mutex);
3058 if (!found_one)
3059 g_warning ("%s: couldn't find weak ref %p(%p)", G_STRFUNC, notify, data);
3060}
3061
3062/**
3063 * g_object_add_weak_pointer: (skip)
3064 * @object: The object that should be weak referenced.
3065 * @weak_pointer_location: (inout) (not optional): The memory address
3066 * of a pointer.
3067 *
3068 * Adds a weak reference from weak_pointer to @object to indicate that
3069 * the pointer located at @weak_pointer_location is only valid during
3070 * the lifetime of @object. When the @object is finalized,
3071 * @weak_pointer will be set to %NULL.
3072 *
3073 * Note that as with g_object_weak_ref(), the weak references created by
3074 * this method are not thread-safe: they cannot safely be used in one
3075 * thread if the object's last g_object_unref() might happen in another
3076 * thread. Use #GWeakRef if thread-safety is required.
3077 */
3078void
3079g_object_add_weak_pointer (GObject *object,
3080 gpointer *weak_pointer_location)
3081{
3082 g_return_if_fail (G_IS_OBJECT (object));
3083 g_return_if_fail (weak_pointer_location != NULL);
3084
3085 g_object_weak_ref (object,
3086 notify: (GWeakNotify) g_nullify_pointer,
3087 data: weak_pointer_location);
3088}
3089
3090/**
3091 * g_object_remove_weak_pointer: (skip)
3092 * @object: The object that is weak referenced.
3093 * @weak_pointer_location: (inout) (not optional): The memory address
3094 * of a pointer.
3095 *
3096 * Removes a weak reference from @object that was previously added
3097 * using g_object_add_weak_pointer(). The @weak_pointer_location has
3098 * to match the one used with g_object_add_weak_pointer().
3099 */
3100void
3101g_object_remove_weak_pointer (GObject *object,
3102 gpointer *weak_pointer_location)
3103{
3104 g_return_if_fail (G_IS_OBJECT (object));
3105 g_return_if_fail (weak_pointer_location != NULL);
3106
3107 g_object_weak_unref (object,
3108 notify: (GWeakNotify) g_nullify_pointer,
3109 data: weak_pointer_location);
3110}
3111
3112static guint
3113object_floating_flag_handler (GObject *object,
3114 gint job)
3115{
3116 switch (job)
3117 {
3118 gpointer oldvalue;
3119 case +1: /* force floating if possible */
3120 do
3121 oldvalue = g_atomic_pointer_get (&object->qdata);
3122 while (!g_atomic_pointer_compare_and_exchange ((void**) &object->qdata, oldvalue,
3123 (gpointer) ((gsize) oldvalue | OBJECT_FLOATING_FLAG)));
3124 return (gsize) oldvalue & OBJECT_FLOATING_FLAG;
3125 case -1: /* sink if possible */
3126 do
3127 oldvalue = g_atomic_pointer_get (&object->qdata);
3128 while (!g_atomic_pointer_compare_and_exchange ((void**) &object->qdata, oldvalue,
3129 (gpointer) ((gsize) oldvalue & ~(gsize) OBJECT_FLOATING_FLAG)));
3130 return (gsize) oldvalue & OBJECT_FLOATING_FLAG;
3131 default: /* check floating */
3132 return 0 != ((gsize) g_atomic_pointer_get (&object->qdata) & OBJECT_FLOATING_FLAG);
3133 }
3134}
3135
3136/**
3137 * g_object_is_floating:
3138 * @object: (type GObject.Object): a #GObject
3139 *
3140 * Checks whether @object has a [floating][floating-ref] reference.
3141 *
3142 * Since: 2.10
3143 *
3144 * Returns: %TRUE if @object has a floating reference
3145 */
3146gboolean
3147g_object_is_floating (gpointer _object)
3148{
3149 GObject *object = _object;
3150 g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
3151 return floating_flag_handler (object, 0);
3152}
3153
3154/**
3155 * g_object_ref_sink:
3156 * @object: (type GObject.Object): a #GObject
3157 *
3158 * Increase the reference count of @object, and possibly remove the
3159 * [floating][floating-ref] reference, if @object has a floating reference.
3160 *
3161 * In other words, if the object is floating, then this call "assumes
3162 * ownership" of the floating reference, converting it to a normal
3163 * reference by clearing the floating flag while leaving the reference
3164 * count unchanged. If the object is not floating, then this call
3165 * adds a new normal reference increasing the reference count by one.
3166 *
3167 * Since GLib 2.56, the type of @object will be propagated to the return type
3168 * under the same conditions as for g_object_ref().
3169 *
3170 * Since: 2.10
3171 *
3172 * Returns: (type GObject.Object) (transfer none): @object
3173 */
3174gpointer
3175(g_object_ref_sink) (gpointer _object)
3176{
3177 GObject *object = _object;
3178 gboolean was_floating;
3179 g_return_val_if_fail (G_IS_OBJECT (object), object);
3180 g_return_val_if_fail (g_atomic_int_get (&object->ref_count) >= 1, object);
3181 g_object_ref (object);
3182 was_floating = floating_flag_handler (object, -1);
3183 if (was_floating)
3184 g_object_unref (object);
3185 return object;
3186}
3187
3188/**
3189 * g_object_force_floating:
3190 * @object: a #GObject
3191 *
3192 * This function is intended for #GObject implementations to re-enforce
3193 * a [floating][floating-ref] object reference. Doing this is seldom
3194 * required: all #GInitiallyUnowneds are created with a floating reference
3195 * which usually just needs to be sunken by calling g_object_ref_sink().
3196 *
3197 * Since: 2.10
3198 */
3199void
3200g_object_force_floating (GObject *object)
3201{
3202 g_return_if_fail (G_IS_OBJECT (object));
3203 g_return_if_fail (g_atomic_int_get (&object->ref_count) >= 1);
3204
3205 floating_flag_handler (object, +1);
3206}
3207
3208typedef struct {
3209 GObject *object;
3210 guint n_toggle_refs;
3211 struct {
3212 GToggleNotify notify;
3213 gpointer data;
3214 } toggle_refs[1]; /* flexible array */
3215} ToggleRefStack;
3216
3217static void
3218toggle_refs_notify (GObject *object,
3219 gboolean is_last_ref)
3220{
3221 ToggleRefStack tstack, *tstackptr;
3222
3223 G_LOCK (toggle_refs_mutex);
3224 tstackptr = g_datalist_id_get_data (datalist: &object->qdata, key_id: quark_toggle_refs);
3225 tstack = *tstackptr;
3226 G_UNLOCK (toggle_refs_mutex);
3227
3228 /* Reentrancy here is not as tricky as it seems, because a toggle reference
3229 * will only be notified when there is exactly one of them.
3230 */
3231 g_assert (tstack.n_toggle_refs == 1);
3232 tstack.toggle_refs[0].notify (tstack.toggle_refs[0].data, tstack.object, is_last_ref);
3233}
3234
3235/**
3236 * g_object_add_toggle_ref: (skip)
3237 * @object: a #GObject
3238 * @notify: a function to call when this reference is the
3239 * last reference to the object, or is no longer
3240 * the last reference.
3241 * @data: data to pass to @notify
3242 *
3243 * Increases the reference count of the object by one and sets a
3244 * callback to be called when all other references to the object are
3245 * dropped, or when this is already the last reference to the object
3246 * and another reference is established.
3247 *
3248 * This functionality is intended for binding @object to a proxy
3249 * object managed by another memory manager. This is done with two
3250 * paired references: the strong reference added by
3251 * g_object_add_toggle_ref() and a reverse reference to the proxy
3252 * object which is either a strong reference or weak reference.
3253 *
3254 * The setup is that when there are no other references to @object,
3255 * only a weak reference is held in the reverse direction from @object
3256 * to the proxy object, but when there are other references held to
3257 * @object, a strong reference is held. The @notify callback is called
3258 * when the reference from @object to the proxy object should be
3259 * "toggled" from strong to weak (@is_last_ref true) or weak to strong
3260 * (@is_last_ref false).
3261 *
3262 * Since a (normal) reference must be held to the object before
3263 * calling g_object_add_toggle_ref(), the initial state of the reverse
3264 * link is always strong.
3265 *
3266 * Multiple toggle references may be added to the same gobject,
3267 * however if there are multiple toggle references to an object, none
3268 * of them will ever be notified until all but one are removed. For
3269 * this reason, you should only ever use a toggle reference if there
3270 * is important state in the proxy object.
3271 *
3272 * Since: 2.8
3273 */
3274void
3275g_object_add_toggle_ref (GObject *object,
3276 GToggleNotify notify,
3277 gpointer data)
3278{
3279 ToggleRefStack *tstack;
3280 guint i;
3281
3282 g_return_if_fail (G_IS_OBJECT (object));
3283 g_return_if_fail (notify != NULL);
3284 g_return_if_fail (g_atomic_int_get (&object->ref_count) >= 1);
3285
3286 g_object_ref (object);
3287
3288 G_LOCK (toggle_refs_mutex);
3289 tstack = g_datalist_id_remove_no_notify (datalist: &object->qdata, key_id: quark_toggle_refs);
3290 if (tstack)
3291 {
3292 i = tstack->n_toggle_refs++;
3293 /* allocate i = tstate->n_toggle_refs - 1 positions beyond the 1 declared
3294 * in tstate->toggle_refs */
3295 tstack = g_realloc (mem: tstack, n_bytes: sizeof (*tstack) + sizeof (tstack->toggle_refs[0]) * i);
3296 }
3297 else
3298 {
3299 tstack = g_renew (ToggleRefStack, NULL, 1);
3300 tstack->object = object;
3301 tstack->n_toggle_refs = 1;
3302 i = 0;
3303 }
3304
3305 /* Set a flag for fast lookup after adding the first toggle reference */
3306 if (tstack->n_toggle_refs == 1)
3307 g_datalist_set_flags (datalist: &object->qdata, OBJECT_HAS_TOGGLE_REF_FLAG);
3308
3309 tstack->toggle_refs[i].notify = notify;
3310 tstack->toggle_refs[i].data = data;
3311 g_datalist_id_set_data_full (datalist: &object->qdata, key_id: quark_toggle_refs, data: tstack,
3312 destroy_func: (GDestroyNotify)g_free);
3313 G_UNLOCK (toggle_refs_mutex);
3314}
3315
3316/**
3317 * g_object_remove_toggle_ref: (skip)
3318 * @object: a #GObject
3319 * @notify: a function to call when this reference is the
3320 * last reference to the object, or is no longer
3321 * the last reference.
3322 * @data: data to pass to @notify
3323 *
3324 * Removes a reference added with g_object_add_toggle_ref(). The
3325 * reference count of the object is decreased by one.
3326 *
3327 * Since: 2.8
3328 */
3329void
3330g_object_remove_toggle_ref (GObject *object,
3331 GToggleNotify notify,
3332 gpointer data)
3333{
3334 ToggleRefStack *tstack;
3335 gboolean found_one = FALSE;
3336
3337 g_return_if_fail (G_IS_OBJECT (object));
3338 g_return_if_fail (notify != NULL);
3339
3340 G_LOCK (toggle_refs_mutex);
3341 tstack = g_datalist_id_get_data (datalist: &object->qdata, key_id: quark_toggle_refs);
3342 if (tstack)
3343 {
3344 guint i;
3345
3346 for (i = 0; i < tstack->n_toggle_refs; i++)
3347 if (tstack->toggle_refs[i].notify == notify &&
3348 tstack->toggle_refs[i].data == data)
3349 {
3350 found_one = TRUE;
3351 tstack->n_toggle_refs -= 1;
3352 if (i != tstack->n_toggle_refs)
3353 tstack->toggle_refs[i] = tstack->toggle_refs[tstack->n_toggle_refs];
3354
3355 if (tstack->n_toggle_refs == 0)
3356 g_datalist_unset_flags (datalist: &object->qdata, OBJECT_HAS_TOGGLE_REF_FLAG);
3357
3358 break;
3359 }
3360 }
3361 G_UNLOCK (toggle_refs_mutex);
3362
3363 if (found_one)
3364 g_object_unref (object);
3365 else
3366 g_warning ("%s: couldn't find toggle ref %p(%p)", G_STRFUNC, notify, data);
3367}
3368
3369/**
3370 * g_object_ref:
3371 * @object: (type GObject.Object): a #GObject
3372 *
3373 * Increases the reference count of @object.
3374 *
3375 * Since GLib 2.56, if `GLIB_VERSION_MAX_ALLOWED` is 2.56 or greater, the type
3376 * of @object will be propagated to the return type (using the GCC typeof()
3377 * extension), so any casting the caller needs to do on the return type must be
3378 * explicit.
3379 *
3380 * Returns: (type GObject.Object) (transfer none): the same @object
3381 */
3382gpointer
3383(g_object_ref) (gpointer _object)
3384{
3385 GObject *object = _object;
3386 gint old_val;
3387 gboolean object_already_finalized;
3388
3389 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
3390
3391 old_val = g_atomic_int_add (&object->ref_count, 1);
3392 object_already_finalized = (old_val <= 0);
3393 g_return_val_if_fail (!object_already_finalized, NULL);
3394
3395 if (old_val == 1 && OBJECT_HAS_TOGGLE_REF (object))
3396 toggle_refs_notify (object, FALSE);
3397
3398 TRACE (GOBJECT_OBJECT_REF(object,G_TYPE_FROM_INSTANCE(object),old_val));
3399
3400 return object;
3401}
3402
3403/**
3404 * g_object_unref:
3405 * @object: (type GObject.Object): a #GObject
3406 *
3407 * Decreases the reference count of @object. When its reference count
3408 * drops to 0, the object is finalized (i.e. its memory is freed).
3409 *
3410 * If the pointer to the #GObject may be reused in future (for example, if it is
3411 * an instance variable of another object), it is recommended to clear the
3412 * pointer to %NULL rather than retain a dangling pointer to a potentially
3413 * invalid #GObject instance. Use g_clear_object() for this.
3414 */
3415void
3416g_object_unref (gpointer _object)
3417{
3418 GObject *object = _object;
3419 gint old_ref;
3420
3421 g_return_if_fail (G_IS_OBJECT (object));
3422
3423 /* here we want to atomically do: if (ref_count>1) { ref_count--; return; } */
3424 retry_atomic_decrement1:
3425 old_ref = g_atomic_int_get (&object->ref_count);
3426 if (old_ref > 1)
3427 {
3428 /* valid if last 2 refs are owned by this call to unref and the toggle_ref */
3429 gboolean has_toggle_ref = OBJECT_HAS_TOGGLE_REF (object);
3430
3431 if (!g_atomic_int_compare_and_exchange ((int *)&object->ref_count, old_ref, old_ref - 1))
3432 goto retry_atomic_decrement1;
3433
3434 TRACE (GOBJECT_OBJECT_UNREF(object,G_TYPE_FROM_INSTANCE(object),old_ref));
3435
3436 /* if we went from 2->1 we need to notify toggle refs if any */
3437 if (old_ref == 2 && has_toggle_ref) /* The last ref being held in this case is owned by the toggle_ref */
3438 toggle_refs_notify (object, TRUE);
3439 }
3440 else
3441 {
3442 GSList **weak_locations;
3443
3444 /* The only way that this object can live at this point is if
3445 * there are outstanding weak references already established
3446 * before we got here.
3447 *
3448 * If there were not already weak references then no more can be
3449 * established at this time, because the other thread would have
3450 * to hold a strong ref in order to call
3451 * g_object_add_weak_pointer() and then we wouldn't be here.
3452 */
3453 weak_locations = g_datalist_id_get_data (datalist: &object->qdata, key_id: quark_weak_locations);
3454
3455 if (weak_locations != NULL)
3456 {
3457 g_rw_lock_writer_lock (rw_lock: &weak_locations_lock);
3458
3459 /* It is possible that one of the weak references beat us to
3460 * the lock. Make sure the refcount is still what we expected
3461 * it to be.
3462 */
3463 old_ref = g_atomic_int_get (&object->ref_count);
3464 if (old_ref != 1)
3465 {
3466 g_rw_lock_writer_unlock (rw_lock: &weak_locations_lock);
3467 goto retry_atomic_decrement1;
3468 }
3469
3470 /* We got the lock first, so the object will definitely die
3471 * now. Clear out all the weak references.
3472 */
3473 while (*weak_locations)
3474 {
3475 GWeakRef *weak_ref_location = (*weak_locations)->data;
3476
3477 weak_ref_location->priv.p = NULL;
3478 *weak_locations = g_slist_delete_link (list: *weak_locations, link_: *weak_locations);
3479 }
3480
3481 g_rw_lock_writer_unlock (rw_lock: &weak_locations_lock);
3482 }
3483
3484 /* we are about to remove the last reference */
3485 TRACE (GOBJECT_OBJECT_DISPOSE(object,G_TYPE_FROM_INSTANCE(object), 1));
3486 G_OBJECT_GET_CLASS (object)->dispose (object);
3487 TRACE (GOBJECT_OBJECT_DISPOSE_END(object,G_TYPE_FROM_INSTANCE(object), 1));
3488
3489 /* may have been re-referenced meanwhile */
3490 retry_atomic_decrement2:
3491 old_ref = g_atomic_int_get ((int *)&object->ref_count);
3492 if (old_ref > 1)
3493 {
3494 /* valid if last 2 refs are owned by this call to unref and the toggle_ref */
3495 gboolean has_toggle_ref = OBJECT_HAS_TOGGLE_REF (object);
3496
3497 if (!g_atomic_int_compare_and_exchange ((int *)&object->ref_count, old_ref, old_ref - 1))
3498 goto retry_atomic_decrement2;
3499
3500 TRACE (GOBJECT_OBJECT_UNREF(object,G_TYPE_FROM_INSTANCE(object),old_ref));
3501
3502 /* if we went from 2->1 we need to notify toggle refs if any */
3503 if (old_ref == 2 && has_toggle_ref) /* The last ref being held in this case is owned by the toggle_ref */
3504 toggle_refs_notify (object, TRUE);
3505
3506 return;
3507 }
3508
3509 /* we are still in the process of taking away the last ref */
3510 g_datalist_id_set_data (&object->qdata, quark_closure_array, NULL);
3511 g_signal_handlers_destroy (instance: object);
3512 g_datalist_id_set_data (&object->qdata, quark_weak_refs, NULL);
3513
3514 /* decrement the last reference */
3515 old_ref = g_atomic_int_add (&object->ref_count, -1);
3516 g_return_if_fail (old_ref > 0);
3517
3518 TRACE (GOBJECT_OBJECT_UNREF(object,G_TYPE_FROM_INSTANCE(object),old_ref));
3519
3520 /* may have been re-referenced meanwhile */
3521 if (G_LIKELY (old_ref == 1))
3522 {
3523 TRACE (GOBJECT_OBJECT_FINALIZE(object,G_TYPE_FROM_INSTANCE(object)));
3524 G_OBJECT_GET_CLASS (object)->finalize (object);
3525
3526 TRACE (GOBJECT_OBJECT_FINALIZE_END(object,G_TYPE_FROM_INSTANCE(object)));
3527
3528 GOBJECT_IF_DEBUG (OBJECTS,
3529 {
3530 gboolean was_present;
3531
3532 /* catch objects not chaining finalize handlers */
3533 G_LOCK (debug_objects);
3534 was_present = g_hash_table_remove (debug_objects_ht, object);
3535 G_UNLOCK (debug_objects);
3536
3537 if (was_present)
3538 g_critical ("Object %p of type %s not finalized correctly.",
3539 object, G_OBJECT_TYPE_NAME (object));
3540 });
3541 g_type_free_instance (instance: (GTypeInstance*) object);
3542 }
3543 }
3544}
3545
3546/**
3547 * g_clear_object: (skip)
3548 * @object_ptr: a pointer to a #GObject reference
3549 *
3550 * Clears a reference to a #GObject.
3551 *
3552 * @object_ptr must not be %NULL.
3553 *
3554 * If the reference is %NULL then this function does nothing.
3555 * Otherwise, the reference count of the object is decreased and the
3556 * pointer is set to %NULL.
3557 *
3558 * A macro is also included that allows this function to be used without
3559 * pointer casts.
3560 *
3561 * Since: 2.28
3562 **/
3563#undef g_clear_object
3564void
3565g_clear_object (GObject **object_ptr)
3566{
3567 g_clear_pointer (object_ptr, g_object_unref);
3568}
3569
3570/**
3571 * g_object_get_qdata:
3572 * @object: The GObject to get a stored user data pointer from
3573 * @quark: A #GQuark, naming the user data pointer
3574 *
3575 * This function gets back user data pointers stored via
3576 * g_object_set_qdata().
3577 *
3578 * Returns: (transfer none) (nullable): The user data pointer set, or %NULL
3579 */
3580gpointer
3581g_object_get_qdata (GObject *object,
3582 GQuark quark)
3583{
3584 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
3585
3586 return quark ? g_datalist_id_get_data (datalist: &object->qdata, key_id: quark) : NULL;
3587}
3588
3589/**
3590 * g_object_set_qdata: (skip)
3591 * @object: The GObject to set store a user data pointer
3592 * @quark: A #GQuark, naming the user data pointer
3593 * @data: (nullable): An opaque user data pointer
3594 *
3595 * This sets an opaque, named pointer on an object.
3596 * The name is specified through a #GQuark (retrieved e.g. via
3597 * g_quark_from_static_string()), and the pointer
3598 * can be gotten back from the @object with g_object_get_qdata()
3599 * until the @object is finalized.
3600 * Setting a previously set user data pointer, overrides (frees)
3601 * the old pointer set, using #NULL as pointer essentially
3602 * removes the data stored.
3603 */
3604void
3605g_object_set_qdata (GObject *object,
3606 GQuark quark,
3607 gpointer data)
3608{
3609 g_return_if_fail (G_IS_OBJECT (object));
3610 g_return_if_fail (quark > 0);
3611
3612 g_datalist_id_set_data (&object->qdata, quark, data);
3613}
3614
3615/**
3616 * g_object_dup_qdata: (skip)
3617 * @object: the #GObject to store user data on
3618 * @quark: a #GQuark, naming the user data pointer
3619 * @dup_func: (nullable): function to dup the value
3620 * @user_data: (nullable): passed as user_data to @dup_func
3621 *
3622 * This is a variant of g_object_get_qdata() which returns
3623 * a 'duplicate' of the value. @dup_func defines the
3624 * meaning of 'duplicate' in this context, it could e.g.
3625 * take a reference on a ref-counted object.
3626 *
3627 * If the @quark is not set on the object then @dup_func
3628 * will be called with a %NULL argument.
3629 *
3630 * Note that @dup_func is called while user data of @object
3631 * is locked.
3632 *
3633 * This function can be useful to avoid races when multiple
3634 * threads are using object data on the same key on the same
3635 * object.
3636 *
3637 * Returns: the result of calling @dup_func on the value
3638 * associated with @quark on @object, or %NULL if not set.
3639 * If @dup_func is %NULL, the value is returned
3640 * unmodified.
3641 *
3642 * Since: 2.34
3643 */
3644gpointer
3645g_object_dup_qdata (GObject *object,
3646 GQuark quark,
3647 GDuplicateFunc dup_func,
3648 gpointer user_data)
3649{
3650 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
3651 g_return_val_if_fail (quark > 0, NULL);
3652
3653 return g_datalist_id_dup_data (datalist: &object->qdata, key_id: quark, dup_func, user_data);
3654}
3655
3656/**
3657 * g_object_replace_qdata: (skip)
3658 * @object: the #GObject to store user data on
3659 * @quark: a #GQuark, naming the user data pointer
3660 * @oldval: (nullable): the old value to compare against
3661 * @newval: (nullable): the new value
3662 * @destroy: (nullable): a destroy notify for the new value
3663 * @old_destroy: (out) (optional): destroy notify for the existing value
3664 *
3665 * Compares the user data for the key @quark on @object with
3666 * @oldval, and if they are the same, replaces @oldval with
3667 * @newval.
3668 *
3669 * This is like a typical atomic compare-and-exchange
3670 * operation, for user data on an object.
3671 *
3672 * If the previous value was replaced then ownership of the
3673 * old value (@oldval) is passed to the caller, including
3674 * the registered destroy notify for it (passed out in @old_destroy).
3675 * It’s up to the caller to free this as needed, which may
3676 * or may not include using @old_destroy as sometimes replacement
3677 * should not destroy the object in the normal way.
3678 *
3679 * Returns: %TRUE if the existing value for @quark was replaced
3680 * by @newval, %FALSE otherwise.
3681 *
3682 * Since: 2.34
3683 */
3684gboolean
3685g_object_replace_qdata (GObject *object,
3686 GQuark quark,
3687 gpointer oldval,
3688 gpointer newval,
3689 GDestroyNotify destroy,
3690 GDestroyNotify *old_destroy)
3691{
3692 g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
3693 g_return_val_if_fail (quark > 0, FALSE);
3694
3695 return g_datalist_id_replace_data (datalist: &object->qdata, key_id: quark,
3696 oldval, newval, destroy,
3697 old_destroy);
3698}
3699
3700/**
3701 * g_object_set_qdata_full: (skip)
3702 * @object: The GObject to set store a user data pointer
3703 * @quark: A #GQuark, naming the user data pointer
3704 * @data: (nullable): An opaque user data pointer
3705 * @destroy: (nullable): Function to invoke with @data as argument, when @data
3706 * needs to be freed
3707 *
3708 * This function works like g_object_set_qdata(), but in addition,
3709 * a void (*destroy) (gpointer) function may be specified which is
3710 * called with @data as argument when the @object is finalized, or
3711 * the data is being overwritten by a call to g_object_set_qdata()
3712 * with the same @quark.
3713 */
3714void
3715g_object_set_qdata_full (GObject *object,
3716 GQuark quark,
3717 gpointer data,
3718 GDestroyNotify destroy)
3719{
3720 g_return_if_fail (G_IS_OBJECT (object));
3721 g_return_if_fail (quark > 0);
3722
3723 g_datalist_id_set_data_full (datalist: &object->qdata, key_id: quark, data,
3724 destroy_func: data ? destroy : (GDestroyNotify) NULL);
3725}
3726
3727/**
3728 * g_object_steal_qdata:
3729 * @object: The GObject to get a stored user data pointer from
3730 * @quark: A #GQuark, naming the user data pointer
3731 *
3732 * This function gets back user data pointers stored via
3733 * g_object_set_qdata() and removes the @data from object
3734 * without invoking its destroy() function (if any was
3735 * set).
3736 * Usually, calling this function is only required to update
3737 * user data pointers with a destroy notifier, for example:
3738 * |[<!-- language="C" -->
3739 * void
3740 * object_add_to_user_list (GObject *object,
3741 * const gchar *new_string)
3742 * {
3743 * // the quark, naming the object data
3744 * GQuark quark_string_list = g_quark_from_static_string ("my-string-list");
3745 * // retrieve the old string list
3746 * GList *list = g_object_steal_qdata (object, quark_string_list);
3747 *
3748 * // prepend new string
3749 * list = g_list_prepend (list, g_strdup (new_string));
3750 * // this changed 'list', so we need to set it again
3751 * g_object_set_qdata_full (object, quark_string_list, list, free_string_list);
3752 * }
3753 * static void
3754 * free_string_list (gpointer data)
3755 * {
3756 * GList *node, *list = data;
3757 *
3758 * for (node = list; node; node = node->next)
3759 * g_free (node->data);
3760 * g_list_free (list);
3761 * }
3762 * ]|
3763 * Using g_object_get_qdata() in the above example, instead of
3764 * g_object_steal_qdata() would have left the destroy function set,
3765 * and thus the partial string list would have been freed upon
3766 * g_object_set_qdata_full().
3767 *
3768 * Returns: (transfer full) (nullable): The user data pointer set, or %NULL
3769 */
3770gpointer
3771g_object_steal_qdata (GObject *object,
3772 GQuark quark)
3773{
3774 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
3775 g_return_val_if_fail (quark > 0, NULL);
3776
3777 return g_datalist_id_remove_no_notify (datalist: &object->qdata, key_id: quark);
3778}
3779
3780/**
3781 * g_object_get_data:
3782 * @object: #GObject containing the associations
3783 * @key: name of the key for that association
3784 *
3785 * Gets a named field from the objects table of associations (see g_object_set_data()).
3786 *
3787 * Returns: (transfer none) (nullable): the data if found,
3788 * or %NULL if no such data exists.
3789 */
3790gpointer
3791g_object_get_data (GObject *object,
3792 const gchar *key)
3793{
3794 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
3795 g_return_val_if_fail (key != NULL, NULL);
3796
3797 return g_datalist_get_data (datalist: &object->qdata, key);
3798}
3799
3800/**
3801 * g_object_set_data:
3802 * @object: #GObject containing the associations.
3803 * @key: name of the key
3804 * @data: (nullable): data to associate with that key
3805 *
3806 * Each object carries around a table of associations from
3807 * strings to pointers. This function lets you set an association.
3808 *
3809 * If the object already had an association with that name,
3810 * the old association will be destroyed.
3811 *
3812 * Internally, the @key is converted to a #GQuark using g_quark_from_string().
3813 * This means a copy of @key is kept permanently (even after @object has been
3814 * finalized) — so it is recommended to only use a small, bounded set of values
3815 * for @key in your program, to avoid the #GQuark storage growing unbounded.
3816 */
3817void
3818g_object_set_data (GObject *object,
3819 const gchar *key,
3820 gpointer data)
3821{
3822 g_return_if_fail (G_IS_OBJECT (object));
3823 g_return_if_fail (key != NULL);
3824
3825 g_datalist_id_set_data (&object->qdata, g_quark_from_string (key), data);
3826}
3827
3828/**
3829 * g_object_dup_data: (skip)
3830 * @object: the #GObject to store user data on
3831 * @key: a string, naming the user data pointer
3832 * @dup_func: (nullable): function to dup the value
3833 * @user_data: (nullable): passed as user_data to @dup_func
3834 *
3835 * This is a variant of g_object_get_data() which returns
3836 * a 'duplicate' of the value. @dup_func defines the
3837 * meaning of 'duplicate' in this context, it could e.g.
3838 * take a reference on a ref-counted object.
3839 *
3840 * If the @key is not set on the object then @dup_func
3841 * will be called with a %NULL argument.
3842 *
3843 * Note that @dup_func is called while user data of @object
3844 * is locked.
3845 *
3846 * This function can be useful to avoid races when multiple
3847 * threads are using object data on the same key on the same
3848 * object.
3849 *
3850 * Returns: the result of calling @dup_func on the value
3851 * associated with @key on @object, or %NULL if not set.
3852 * If @dup_func is %NULL, the value is returned
3853 * unmodified.
3854 *
3855 * Since: 2.34
3856 */
3857gpointer
3858g_object_dup_data (GObject *object,
3859 const gchar *key,
3860 GDuplicateFunc dup_func,
3861 gpointer user_data)
3862{
3863 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
3864 g_return_val_if_fail (key != NULL, NULL);
3865
3866 return g_datalist_id_dup_data (datalist: &object->qdata,
3867 key_id: g_quark_from_string (string: key),
3868 dup_func, user_data);
3869}
3870
3871/**
3872 * g_object_replace_data: (skip)
3873 * @object: the #GObject to store user data on
3874 * @key: a string, naming the user data pointer
3875 * @oldval: (nullable): the old value to compare against
3876 * @newval: (nullable): the new value
3877 * @destroy: (nullable): a destroy notify for the new value
3878 * @old_destroy: (out) (optional): destroy notify for the existing value
3879 *
3880 * Compares the user data for the key @key on @object with
3881 * @oldval, and if they are the same, replaces @oldval with
3882 * @newval.
3883 *
3884 * This is like a typical atomic compare-and-exchange
3885 * operation, for user data on an object.
3886 *
3887 * If the previous value was replaced then ownership of the
3888 * old value (@oldval) is passed to the caller, including
3889 * the registered destroy notify for it (passed out in @old_destroy).
3890 * It’s up to the caller to free this as needed, which may
3891 * or may not include using @old_destroy as sometimes replacement
3892 * should not destroy the object in the normal way.
3893 *
3894 * See g_object_set_data() for guidance on using a small, bounded set of values
3895 * for @key.
3896 *
3897 * Returns: %TRUE if the existing value for @key was replaced
3898 * by @newval, %FALSE otherwise.
3899 *
3900 * Since: 2.34
3901 */
3902gboolean
3903g_object_replace_data (GObject *object,
3904 const gchar *key,
3905 gpointer oldval,
3906 gpointer newval,
3907 GDestroyNotify destroy,
3908 GDestroyNotify *old_destroy)
3909{
3910 g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
3911 g_return_val_if_fail (key != NULL, FALSE);
3912
3913 return g_datalist_id_replace_data (datalist: &object->qdata,
3914 key_id: g_quark_from_string (string: key),
3915 oldval, newval, destroy,
3916 old_destroy);
3917}
3918
3919/**
3920 * g_object_set_data_full: (skip)
3921 * @object: #GObject containing the associations
3922 * @key: name of the key
3923 * @data: (nullable): data to associate with that key
3924 * @destroy: (nullable): function to call when the association is destroyed
3925 *
3926 * Like g_object_set_data() except it adds notification
3927 * for when the association is destroyed, either by setting it
3928 * to a different value or when the object is destroyed.
3929 *
3930 * Note that the @destroy callback is not called if @data is %NULL.
3931 */
3932void
3933g_object_set_data_full (GObject *object,
3934 const gchar *key,
3935 gpointer data,
3936 GDestroyNotify destroy)
3937{
3938 g_return_if_fail (G_IS_OBJECT (object));
3939 g_return_if_fail (key != NULL);
3940
3941 g_datalist_id_set_data_full (datalist: &object->qdata, key_id: g_quark_from_string (string: key), data,
3942 destroy_func: data ? destroy : (GDestroyNotify) NULL);
3943}
3944
3945/**
3946 * g_object_steal_data:
3947 * @object: #GObject containing the associations
3948 * @key: name of the key
3949 *
3950 * Remove a specified datum from the object's data associations,
3951 * without invoking the association's destroy handler.
3952 *
3953 * Returns: (transfer full) (nullable): the data if found, or %NULL
3954 * if no such data exists.
3955 */
3956gpointer
3957g_object_steal_data (GObject *object,
3958 const gchar *key)
3959{
3960 GQuark quark;
3961
3962 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
3963 g_return_val_if_fail (key != NULL, NULL);
3964
3965 quark = g_quark_try_string (string: key);
3966
3967 return quark ? g_datalist_id_remove_no_notify (datalist: &object->qdata, key_id: quark) : NULL;
3968}
3969
3970static void
3971g_value_object_init (GValue *value)
3972{
3973 value->data[0].v_pointer = NULL;
3974}
3975
3976static void
3977g_value_object_free_value (GValue *value)
3978{
3979 if (value->data[0].v_pointer)
3980 g_object_unref (object: value->data[0].v_pointer);
3981}
3982
3983static void
3984g_value_object_copy_value (const GValue *src_value,
3985 GValue *dest_value)
3986{
3987 if (src_value->data[0].v_pointer)
3988 dest_value->data[0].v_pointer = g_object_ref (src_value->data[0].v_pointer);
3989 else
3990 dest_value->data[0].v_pointer = NULL;
3991}
3992
3993static void
3994g_value_object_transform_value (const GValue *src_value,
3995 GValue *dest_value)
3996{
3997 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)))
3998 dest_value->data[0].v_pointer = g_object_ref (src_value->data[0].v_pointer);
3999 else
4000 dest_value->data[0].v_pointer = NULL;
4001}
4002
4003static gpointer
4004g_value_object_peek_pointer (const GValue *value)
4005{
4006 return value->data[0].v_pointer;
4007}
4008
4009static gchar*
4010g_value_object_collect_value (GValue *value,
4011 guint n_collect_values,
4012 GTypeCValue *collect_values,
4013 guint collect_flags)
4014{
4015 if (collect_values[0].v_pointer)
4016 {
4017 GObject *object = collect_values[0].v_pointer;
4018
4019 if (object->g_type_instance.g_class == NULL)
4020 return g_strconcat (string1: "invalid unclassed object pointer for value type '",
4021 G_VALUE_TYPE_NAME (value),
4022 "'",
4023 NULL);
4024 else if (!g_value_type_compatible (G_OBJECT_TYPE (object), G_VALUE_TYPE (value)))
4025 return g_strconcat (string1: "invalid object type '",
4026 G_OBJECT_TYPE_NAME (object),
4027 "' for value type '",
4028 G_VALUE_TYPE_NAME (value),
4029 "'",
4030 NULL);
4031 /* never honour G_VALUE_NOCOPY_CONTENTS for ref-counted types */
4032 value->data[0].v_pointer = g_object_ref (object);
4033 }
4034 else
4035 value->data[0].v_pointer = NULL;
4036
4037 return NULL;
4038}
4039
4040static gchar*
4041g_value_object_lcopy_value (const GValue *value,
4042 guint n_collect_values,
4043 GTypeCValue *collect_values,
4044 guint collect_flags)
4045{
4046 GObject **object_p = collect_values[0].v_pointer;
4047
4048 g_return_val_if_fail (object_p != NULL, g_strdup_printf ("value location for '%s' passed as NULL", G_VALUE_TYPE_NAME (value)));
4049
4050 if (!value->data[0].v_pointer)
4051 *object_p = NULL;
4052 else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
4053 *object_p = value->data[0].v_pointer;
4054 else
4055 *object_p = g_object_ref (value->data[0].v_pointer);
4056
4057 return NULL;
4058}
4059
4060/**
4061 * g_value_set_object:
4062 * @value: a valid #GValue of %G_TYPE_OBJECT derived type
4063 * @v_object: (type GObject.Object) (nullable): object value to be set
4064 *
4065 * Set the contents of a %G_TYPE_OBJECT derived #GValue to @v_object.
4066 *
4067 * g_value_set_object() increases the reference count of @v_object
4068 * (the #GValue holds a reference to @v_object). If you do not wish
4069 * to increase the reference count of the object (i.e. you wish to
4070 * pass your current reference to the #GValue because you no longer
4071 * need it), use g_value_take_object() instead.
4072 *
4073 * It is important that your #GValue holds a reference to @v_object (either its
4074 * own, or one it has taken) to ensure that the object won't be destroyed while
4075 * the #GValue still exists).
4076 */
4077void
4078g_value_set_object (GValue *value,
4079 gpointer v_object)
4080{
4081 GObject *old;
4082
4083 g_return_if_fail (G_VALUE_HOLDS_OBJECT (value));
4084
4085 old = value->data[0].v_pointer;
4086
4087 if (v_object)
4088 {
4089 g_return_if_fail (G_IS_OBJECT (v_object));
4090 g_return_if_fail (g_value_type_compatible (G_OBJECT_TYPE (v_object), G_VALUE_TYPE (value)));
4091
4092 value->data[0].v_pointer = v_object;
4093 g_object_ref (value->data[0].v_pointer);
4094 }
4095 else
4096 value->data[0].v_pointer = NULL;
4097
4098 if (old)
4099 g_object_unref (object: old);
4100}
4101
4102/**
4103 * g_value_set_object_take_ownership: (skip)
4104 * @value: a valid #GValue of %G_TYPE_OBJECT derived type
4105 * @v_object: (nullable): object value to be set
4106 *
4107 * This is an internal function introduced mainly for C marshallers.
4108 *
4109 * Deprecated: 2.4: Use g_value_take_object() instead.
4110 */
4111void
4112g_value_set_object_take_ownership (GValue *value,
4113 gpointer v_object)
4114{
4115 g_value_take_object (value, v_object);
4116}
4117
4118/**
4119 * g_value_take_object: (skip)
4120 * @value: a valid #GValue of %G_TYPE_OBJECT derived type
4121 * @v_object: (nullable): object value to be set
4122 *
4123 * Sets the contents of a %G_TYPE_OBJECT derived #GValue to @v_object
4124 * and takes over the ownership of the caller’s reference to @v_object;
4125 * the caller doesn’t have to unref it any more (i.e. the reference
4126 * count of the object is not increased).
4127 *
4128 * If you want the #GValue to hold its own reference to @v_object, use
4129 * g_value_set_object() instead.
4130 *
4131 * Since: 2.4
4132 */
4133void
4134g_value_take_object (GValue *value,
4135 gpointer v_object)
4136{
4137 g_return_if_fail (G_VALUE_HOLDS_OBJECT (value));
4138
4139 if (value->data[0].v_pointer)
4140 {
4141 g_object_unref (object: value->data[0].v_pointer);
4142 value->data[0].v_pointer = NULL;
4143 }
4144
4145 if (v_object)
4146 {
4147 g_return_if_fail (G_IS_OBJECT (v_object));
4148 g_return_if_fail (g_value_type_compatible (G_OBJECT_TYPE (v_object), G_VALUE_TYPE (value)));
4149
4150 value->data[0].v_pointer = v_object; /* we take over the reference count */
4151 }
4152}
4153
4154/**
4155 * g_value_get_object:
4156 * @value: a valid #GValue of %G_TYPE_OBJECT derived type
4157 *
4158 * Get the contents of a %G_TYPE_OBJECT derived #GValue.
4159 *
4160 * Returns: (type GObject.Object) (transfer none): object contents of @value
4161 */
4162gpointer
4163g_value_get_object (const GValue *value)
4164{
4165 g_return_val_if_fail (G_VALUE_HOLDS_OBJECT (value), NULL);
4166
4167 return value->data[0].v_pointer;
4168}
4169
4170/**
4171 * g_value_dup_object:
4172 * @value: a valid #GValue whose type is derived from %G_TYPE_OBJECT
4173 *
4174 * Get the contents of a %G_TYPE_OBJECT derived #GValue, increasing
4175 * its reference count. If the contents of the #GValue are %NULL, then
4176 * %NULL will be returned.
4177 *
4178 * Returns: (type GObject.Object) (transfer full): object content of @value,
4179 * should be unreferenced when no longer needed.
4180 */
4181gpointer
4182g_value_dup_object (const GValue *value)
4183{
4184 g_return_val_if_fail (G_VALUE_HOLDS_OBJECT (value), NULL);
4185
4186 return value->data[0].v_pointer ? g_object_ref (value->data[0].v_pointer) : NULL;
4187}
4188
4189/**
4190 * g_signal_connect_object: (skip)
4191 * @instance: (type GObject.TypeInstance): the instance to connect to.
4192 * @detailed_signal: a string of the form "signal-name::detail".
4193 * @c_handler: the #GCallback to connect.
4194 * @gobject: (type GObject.Object) (nullable): the object to pass as data
4195 * to @c_handler.
4196 * @connect_flags: a combination of #GConnectFlags.
4197 *
4198 * This is similar to g_signal_connect_data(), but uses a closure which
4199 * ensures that the @gobject stays alive during the call to @c_handler
4200 * by temporarily adding a reference count to @gobject.
4201 *
4202 * When the @gobject is destroyed the signal handler will be automatically
4203 * disconnected. Note that this is not currently threadsafe (ie:
4204 * emitting a signal while @gobject is being destroyed in another thread
4205 * is not safe).
4206 *
4207 * Returns: the handler id.
4208 */
4209gulong
4210g_signal_connect_object (gpointer instance,
4211 const gchar *detailed_signal,
4212 GCallback c_handler,
4213 gpointer gobject,
4214 GConnectFlags connect_flags)
4215{
4216 g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
4217 g_return_val_if_fail (detailed_signal != NULL, 0);
4218 g_return_val_if_fail (c_handler != NULL, 0);
4219
4220 if (gobject)
4221 {
4222 GClosure *closure;
4223
4224 g_return_val_if_fail (G_IS_OBJECT (gobject), 0);
4225
4226 closure = ((connect_flags & G_CONNECT_SWAPPED) ? g_cclosure_new_object_swap : g_cclosure_new_object) (c_handler, gobject);
4227
4228 return g_signal_connect_closure (instance, detailed_signal, closure, after: connect_flags & G_CONNECT_AFTER);
4229 }
4230 else
4231 return g_signal_connect_data (instance, detailed_signal, c_handler, NULL, NULL, connect_flags);
4232}
4233
4234typedef struct {
4235 GObject *object;
4236 guint n_closures;
4237 GClosure *closures[1]; /* flexible array */
4238} CArray;
4239/* don't change this structure without supplying an accessor for
4240 * watched closures, e.g.:
4241 * GSList* g_object_list_watched_closures (GObject *object)
4242 * {
4243 * CArray *carray;
4244 * g_return_val_if_fail (G_IS_OBJECT (object), NULL);
4245 * carray = g_object_get_data (object, "GObject-closure-array");
4246 * if (carray)
4247 * {
4248 * GSList *slist = NULL;
4249 * guint i;
4250 * for (i = 0; i < carray->n_closures; i++)
4251 * slist = g_slist_prepend (slist, carray->closures[i]);
4252 * return slist;
4253 * }
4254 * return NULL;
4255 * }
4256 */
4257
4258static void
4259object_remove_closure (gpointer data,
4260 GClosure *closure)
4261{
4262 GObject *object = data;
4263 CArray *carray;
4264 guint i;
4265
4266 G_LOCK (closure_array_mutex);
4267 carray = g_object_get_qdata (object, quark: quark_closure_array);
4268 for (i = 0; i < carray->n_closures; i++)
4269 if (carray->closures[i] == closure)
4270 {
4271 carray->n_closures--;
4272 if (i < carray->n_closures)
4273 carray->closures[i] = carray->closures[carray->n_closures];
4274 G_UNLOCK (closure_array_mutex);
4275 return;
4276 }
4277 G_UNLOCK (closure_array_mutex);
4278 g_assert_not_reached ();
4279}
4280
4281static void
4282destroy_closure_array (gpointer data)
4283{
4284 CArray *carray = data;
4285 GObject *object = carray->object;
4286 guint i, n = carray->n_closures;
4287
4288 for (i = 0; i < n; i++)
4289 {
4290 GClosure *closure = carray->closures[i];
4291
4292 /* removing object_remove_closure() upfront is probably faster than
4293 * letting it fiddle with quark_closure_array which is empty anyways
4294 */
4295 g_closure_remove_invalidate_notifier (closure, notify_data: object, notify_func: object_remove_closure);
4296 g_closure_invalidate (closure);
4297 }
4298 g_free (mem: carray);
4299}
4300
4301/**
4302 * g_object_watch_closure:
4303 * @object: #GObject restricting lifetime of @closure
4304 * @closure: #GClosure to watch
4305 *
4306 * This function essentially limits the life time of the @closure to
4307 * the life time of the object. That is, when the object is finalized,
4308 * the @closure is invalidated by calling g_closure_invalidate() on
4309 * it, in order to prevent invocations of the closure with a finalized
4310 * (nonexisting) object. Also, g_object_ref() and g_object_unref() are
4311 * added as marshal guards to the @closure, to ensure that an extra
4312 * reference count is held on @object during invocation of the
4313 * @closure. Usually, this function will be called on closures that
4314 * use this @object as closure data.
4315 */
4316void
4317g_object_watch_closure (GObject *object,
4318 GClosure *closure)
4319{
4320 CArray *carray;
4321 guint i;
4322
4323 g_return_if_fail (G_IS_OBJECT (object));
4324 g_return_if_fail (closure != NULL);
4325 g_return_if_fail (closure->is_invalid == FALSE);
4326 g_return_if_fail (closure->in_marshal == FALSE);
4327 g_return_if_fail (g_atomic_int_get (&object->ref_count) > 0); /* this doesn't work on finalizing objects */
4328
4329 g_closure_add_invalidate_notifier (closure, notify_data: object, notify_func: object_remove_closure);
4330 g_closure_add_marshal_guards (closure,
4331 pre_marshal_data: object, pre_marshal_notify: (GClosureNotify) g_object_ref,
4332 post_marshal_data: object, post_marshal_notify: (GClosureNotify) g_object_unref);
4333 G_LOCK (closure_array_mutex);
4334 carray = g_datalist_id_remove_no_notify (datalist: &object->qdata, key_id: quark_closure_array);
4335 if (!carray)
4336 {
4337 carray = g_renew (CArray, NULL, 1);
4338 carray->object = object;
4339 carray->n_closures = 1;
4340 i = 0;
4341 }
4342 else
4343 {
4344 i = carray->n_closures++;
4345 carray = g_realloc (mem: carray, n_bytes: sizeof (*carray) + sizeof (carray->closures[0]) * i);
4346 }
4347 carray->closures[i] = closure;
4348 g_datalist_id_set_data_full (datalist: &object->qdata, key_id: quark_closure_array, data: carray, destroy_func: destroy_closure_array);
4349 G_UNLOCK (closure_array_mutex);
4350}
4351
4352/**
4353 * g_closure_new_object:
4354 * @sizeof_closure: the size of the structure to allocate, must be at least
4355 * `sizeof (GClosure)`
4356 * @object: a #GObject pointer to store in the @data field of the newly
4357 * allocated #GClosure
4358 *
4359 * A variant of g_closure_new_simple() which stores @object in the
4360 * @data field of the closure and calls g_object_watch_closure() on
4361 * @object and the created closure. This function is mainly useful
4362 * when implementing new types of closures.
4363 *
4364 * Returns: (transfer floating): a newly allocated #GClosure
4365 */
4366GClosure *
4367g_closure_new_object (guint sizeof_closure,
4368 GObject *object)
4369{
4370 GClosure *closure;
4371
4372 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
4373 g_return_val_if_fail (g_atomic_int_get (&object->ref_count) > 0, NULL); /* this doesn't work on finalizing objects */
4374
4375 closure = g_closure_new_simple (sizeof_closure, data: object);
4376 g_object_watch_closure (object, closure);
4377
4378 return closure;
4379}
4380
4381/**
4382 * g_cclosure_new_object: (skip)
4383 * @callback_func: the function to invoke
4384 * @object: a #GObject pointer to pass to @callback_func
4385 *
4386 * A variant of g_cclosure_new() which uses @object as @user_data and
4387 * calls g_object_watch_closure() on @object and the created
4388 * closure. This function is useful when you have a callback closely
4389 * associated with a #GObject, and want the callback to no longer run
4390 * after the object is is freed.
4391 *
4392 * Returns: (transfer floating): a new #GCClosure
4393 */
4394GClosure *
4395g_cclosure_new_object (GCallback callback_func,
4396 GObject *object)
4397{
4398 GClosure *closure;
4399
4400 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
4401 g_return_val_if_fail (g_atomic_int_get (&object->ref_count) > 0, NULL); /* this doesn't work on finalizing objects */
4402 g_return_val_if_fail (callback_func != NULL, NULL);
4403
4404 closure = g_cclosure_new (callback_func, user_data: object, NULL);
4405 g_object_watch_closure (object, closure);
4406
4407 return closure;
4408}
4409
4410/**
4411 * g_cclosure_new_object_swap: (skip)
4412 * @callback_func: the function to invoke
4413 * @object: a #GObject pointer to pass to @callback_func
4414 *
4415 * A variant of g_cclosure_new_swap() which uses @object as @user_data
4416 * and calls g_object_watch_closure() on @object and the created
4417 * closure. This function is useful when you have a callback closely
4418 * associated with a #GObject, and want the callback to no longer run
4419 * after the object is is freed.
4420 *
4421 * Returns: (transfer floating): a new #GCClosure
4422 */
4423GClosure *
4424g_cclosure_new_object_swap (GCallback callback_func,
4425 GObject *object)
4426{
4427 GClosure *closure;
4428
4429 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
4430 g_return_val_if_fail (g_atomic_int_get (&object->ref_count) > 0, NULL); /* this doesn't work on finalizing objects */
4431 g_return_val_if_fail (callback_func != NULL, NULL);
4432
4433 closure = g_cclosure_new_swap (callback_func, user_data: object, NULL);
4434 g_object_watch_closure (object, closure);
4435
4436 return closure;
4437}
4438
4439gsize
4440g_object_compat_control (gsize what,
4441 gpointer data)
4442{
4443 switch (what)
4444 {
4445 gpointer *pp;
4446 case 1: /* floating base type */
4447 return G_TYPE_INITIALLY_UNOWNED;
4448 case 2: /* FIXME: remove this once GLib/Gtk+ break ABI again */
4449 floating_flag_handler = (guint(*)(GObject*,gint)) data;
4450 return 1;
4451 case 3: /* FIXME: remove this once GLib/Gtk+ break ABI again */
4452 pp = data;
4453 *pp = floating_flag_handler;
4454 return 1;
4455 default:
4456 return 0;
4457 }
4458}
4459
4460G_DEFINE_TYPE (GInitiallyUnowned, g_initially_unowned, G_TYPE_OBJECT)
4461
4462static void
4463g_initially_unowned_init (GInitiallyUnowned *object)
4464{
4465 g_object_force_floating (object);
4466}
4467
4468static void
4469g_initially_unowned_class_init (GInitiallyUnownedClass *klass)
4470{
4471}
4472
4473/**
4474 * GWeakRef:
4475 *
4476 * A structure containing a weak reference to a #GObject. It can either
4477 * be empty (i.e. point to %NULL), or point to an object for as long as
4478 * at least one "strong" reference to that object exists. Before the
4479 * object's #GObjectClass.dispose method is called, every #GWeakRef
4480 * associated with becomes empty (i.e. points to %NULL).
4481 *
4482 * Like #GValue, #GWeakRef can be statically allocated, stack- or
4483 * heap-allocated, or embedded in larger structures.
4484 *
4485 * Unlike g_object_weak_ref() and g_object_add_weak_pointer(), this weak
4486 * reference is thread-safe: converting a weak pointer to a reference is
4487 * atomic with respect to invalidation of weak pointers to destroyed
4488 * objects.
4489 *
4490 * If the object's #GObjectClass.dispose method results in additional
4491 * references to the object being held, any #GWeakRefs taken
4492 * before it was disposed will continue to point to %NULL. If
4493 * #GWeakRefs are taken after the object is disposed and
4494 * re-referenced, they will continue to point to it until its refcount
4495 * goes back to zero, at which point they too will be invalidated.
4496 */
4497
4498/**
4499 * g_weak_ref_init: (skip)
4500 * @weak_ref: (inout): uninitialized or empty location for a weak
4501 * reference
4502 * @object: (type GObject.Object) (nullable): a #GObject or %NULL
4503 *
4504 * Initialise a non-statically-allocated #GWeakRef.
4505 *
4506 * This function also calls g_weak_ref_set() with @object on the
4507 * freshly-initialised weak reference.
4508 *
4509 * This function should always be matched with a call to
4510 * g_weak_ref_clear(). It is not necessary to use this function for a
4511 * #GWeakRef in static storage because it will already be
4512 * properly initialised. Just use g_weak_ref_set() directly.
4513 *
4514 * Since: 2.32
4515 */
4516void
4517g_weak_ref_init (GWeakRef *weak_ref,
4518 gpointer object)
4519{
4520 weak_ref->priv.p = NULL;
4521
4522 g_weak_ref_set (weak_ref, object);
4523}
4524
4525/**
4526 * g_weak_ref_clear: (skip)
4527 * @weak_ref: (inout): location of a weak reference, which
4528 * may be empty
4529 *
4530 * Frees resources associated with a non-statically-allocated #GWeakRef.
4531 * After this call, the #GWeakRef is left in an undefined state.
4532 *
4533 * You should only call this on a #GWeakRef that previously had
4534 * g_weak_ref_init() called on it.
4535 *
4536 * Since: 2.32
4537 */
4538void
4539g_weak_ref_clear (GWeakRef *weak_ref)
4540{
4541 g_weak_ref_set (weak_ref, NULL);
4542
4543 /* be unkind */
4544 weak_ref->priv.p = (void *) 0xccccccccu;
4545}
4546
4547/**
4548 * g_weak_ref_get: (skip)
4549 * @weak_ref: (inout): location of a weak reference to a #GObject
4550 *
4551 * If @weak_ref is not empty, atomically acquire a strong
4552 * reference to the object it points to, and return that reference.
4553 *
4554 * This function is needed because of the potential race between taking
4555 * the pointer value and g_object_ref() on it, if the object was losing
4556 * its last reference at the same time in a different thread.
4557 *
4558 * The caller should release the resulting reference in the usual way,
4559 * by using g_object_unref().
4560 *
4561 * Returns: (transfer full) (type GObject.Object): the object pointed to
4562 * by @weak_ref, or %NULL if it was empty
4563 *
4564 * Since: 2.32
4565 */
4566gpointer
4567g_weak_ref_get (GWeakRef *weak_ref)
4568{
4569 gpointer object_or_null;
4570
4571 g_return_val_if_fail (weak_ref!= NULL, NULL);
4572
4573 g_rw_lock_reader_lock (rw_lock: &weak_locations_lock);
4574
4575 object_or_null = weak_ref->priv.p;
4576
4577 if (object_or_null != NULL)
4578 g_object_ref (object_or_null);
4579
4580 g_rw_lock_reader_unlock (rw_lock: &weak_locations_lock);
4581
4582 return object_or_null;
4583}
4584
4585/**
4586 * g_weak_ref_set: (skip)
4587 * @weak_ref: location for a weak reference
4588 * @object: (type GObject.Object) (nullable): a #GObject or %NULL
4589 *
4590 * Change the object to which @weak_ref points, or set it to
4591 * %NULL.
4592 *
4593 * You must own a strong reference on @object while calling this
4594 * function.
4595 *
4596 * Since: 2.32
4597 */
4598void
4599g_weak_ref_set (GWeakRef *weak_ref,
4600 gpointer object)
4601{
4602 GSList **weak_locations;
4603 GObject *new_object;
4604 GObject *old_object;
4605
4606 g_return_if_fail (weak_ref != NULL);
4607 g_return_if_fail (object == NULL || G_IS_OBJECT (object));
4608
4609 new_object = object;
4610
4611 g_rw_lock_writer_lock (rw_lock: &weak_locations_lock);
4612
4613 /* We use the extra level of indirection here so that if we have ever
4614 * had a weak pointer installed at any point in time on this object,
4615 * we can see that there is a non-NULL value associated with the
4616 * weak-pointer quark and know that this value will not change at any
4617 * point in the object's lifetime.
4618 *
4619 * Both properties are important for reducing the amount of times we
4620 * need to acquire locks and for decreasing the duration of time the
4621 * lock is held while avoiding some rather tricky races.
4622 *
4623 * Specifically: we can avoid having to do an extra unconditional lock
4624 * in g_object_unref() without worrying about some extremely tricky
4625 * races.
4626 */
4627
4628 old_object = weak_ref->priv.p;
4629 if (new_object != old_object)
4630 {
4631 weak_ref->priv.p = new_object;
4632
4633 /* Remove the weak ref from the old object */
4634 if (old_object != NULL)
4635 {
4636 weak_locations = g_datalist_id_get_data (datalist: &old_object->qdata, key_id: quark_weak_locations);
4637 /* for it to point to an object, the object must have had it added once */
4638 g_assert (weak_locations != NULL);
4639
4640 *weak_locations = g_slist_remove (list: *weak_locations, data: weak_ref);
4641 }
4642
4643 /* Add the weak ref to the new object */
4644 if (new_object != NULL)
4645 {
4646 weak_locations = g_datalist_id_get_data (datalist: &new_object->qdata, key_id: quark_weak_locations);
4647
4648 if (weak_locations == NULL)
4649 {
4650 weak_locations = g_new0 (GSList *, 1);
4651 g_datalist_id_set_data_full (datalist: &new_object->qdata, key_id: quark_weak_locations, data: weak_locations, destroy_func: g_free);
4652 }
4653
4654 *weak_locations = g_slist_prepend (list: *weak_locations, data: weak_ref);
4655 }
4656 }
4657
4658 g_rw_lock_writer_unlock (rw_lock: &weak_locations_lock);
4659}
4660

source code of gtk/subprojects/glib/gobject/gobject.c