summaryrefslogtreecommitdiff
path: root/gobject/gobject.c
diff options
context:
space:
mode:
Diffstat (limited to 'gobject/gobject.c')
-rw-r--r--gobject/gobject.c127
1 files changed, 122 insertions, 5 deletions
diff --git a/gobject/gobject.c b/gobject/gobject.c
index df27c36f7..07752cf25 100644
--- a/gobject/gobject.c
+++ b/gobject/gobject.c
@@ -162,6 +162,29 @@ enum {
PROP_NONE
};
+#define OPTIONAL_FLAG_IN_CONSTRUCTION 1<<0
+#define OPTIONAL_FLAG_HAS_SIGNAL_HANDLER 1<<1 /* Set if object ever had a signal handler */
+
+#if SIZEOF_INT == 4 && GLIB_SIZEOF_VOID_P == 8
+#define HAVE_OPTIONAL_FLAGS
+#endif
+
+typedef struct
+{
+ GTypeInstance g_type_instance;
+
+ /*< private >*/
+ volatile guint ref_count;
+#ifdef HAVE_OPTIONAL_FLAGS
+ volatile guint optional_flags;
+#endif
+ GData *qdata;
+} GObjectReal;
+
+G_STATIC_ASSERT(sizeof(GObject) == sizeof(GObjectReal));
+G_STATIC_ASSERT(G_STRUCT_OFFSET(GObject, ref_count) == G_STRUCT_OFFSET(GObjectReal, ref_count));
+G_STATIC_ASSERT(G_STRUCT_OFFSET(GObject, qdata) == G_STRUCT_OFFSET(GObjectReal, qdata));
+
/* --- prototypes --- */
static void g_object_base_class_init (GObjectClass *class);
@@ -1008,10 +1031,83 @@ g_object_interface_list_properties (gpointer g_iface,
return pspecs;
}
+static inline guint
+object_get_optional_flags (GObject *object)
+{
+#ifdef HAVE_OPTIONAL_FLAGS
+ GObjectReal *real = (GObjectReal *)object;
+ return (guint)g_atomic_int_get (&real->optional_flags);
+#else
+ return 0;
+#endif
+}
+
+static inline void
+object_set_optional_flags (GObject *object,
+ guint flags)
+{
+#ifdef HAVE_OPTIONAL_FLAGS
+ GObjectReal *real = (GObjectReal *)object;
+ g_atomic_int_or (&real->optional_flags, flags);
+#endif
+}
+
+static inline void
+object_unset_optional_flags (GObject *object,
+ guint flags)
+{
+#ifdef HAVE_OPTIONAL_FLAGS
+ GObjectReal *real = (GObjectReal *)object;
+ g_atomic_int_and (&real->optional_flags, ~flags);
+#endif
+}
+
+gboolean
+_g_object_has_signal_handler (GObject *object)
+{
+#ifdef HAVE_OPTIONAL_FLAGS
+ return (object_get_optional_flags (object) & OPTIONAL_FLAG_HAS_SIGNAL_HANDLER) != 0;
+#else
+ return TRUE;
+#endif
+}
+
+void
+_g_object_set_has_signal_handler (GObject *object)
+{
+#ifdef HAVE_OPTIONAL_FLAGS
+ object_set_optional_flags (object, OPTIONAL_FLAG_HAS_SIGNAL_HANDLER);
+#endif
+}
+
static inline gboolean
object_in_construction (GObject *object)
{
+#ifdef HAVE_OPTIONAL_FLAGS
+ return (object_get_optional_flags (object) & OPTIONAL_FLAG_IN_CONSTRUCTION) != 0;
+#else
return g_datalist_id_get_data (&object->qdata, quark_in_construction) != NULL;
+#endif
+}
+
+static inline void
+set_object_in_construction (GObject *object)
+{
+#ifdef HAVE_OPTIONAL_FLAGS
+ object_set_optional_flags (object, OPTIONAL_FLAG_IN_CONSTRUCTION);
+#else
+ g_datalist_id_set_data (&object->qdata, quark_in_construction, object);
+#endif
+}
+
+static inline void
+unset_object_in_construction (GObject *object)
+{
+#ifdef HAVE_OPTIONAL_FLAGS
+ object_unset_optional_flags (object, OPTIONAL_FLAG_IN_CONSTRUCTION);
+#else
+ g_datalist_id_set_data (&object->qdata, quark_in_construction, NULL);
+#endif
}
static void
@@ -1030,7 +1126,7 @@ g_object_init (GObject *object,
if (CLASS_HAS_CUSTOM_CONSTRUCTOR (class))
{
/* mark object in-construction for notify_queue_thaw() and to allow construct-only properties */
- g_datalist_id_set_data (&object->qdata, quark_in_construction, object);
+ set_object_in_construction (object);
}
GOBJECT_IF_DEBUG (OBJECTS,
@@ -1521,7 +1617,7 @@ object_interface_check_properties (gpointer check_data,
/* We do a number of checks on the properties of an interface to
* make sure that all classes implementing the interface are
- * overriding the properties in a sane way.
+ * overriding the properties correctly.
*
* We do the checks in order of importance so that we can give
* more useful error messages first.
@@ -1651,6 +1747,20 @@ g_object_get_type (void)
* Construction parameters (see #G_PARAM_CONSTRUCT, #G_PARAM_CONSTRUCT_ONLY)
* which are not explicitly specified are set to their default values.
*
+ * Note that in C, small integer types in variable argument lists are promoted
+ * up to #gint or #guint as appropriate, and read back accordingly. #gint is 32
+ * bits on every platform on which GLib is currently supported. This means that
+ * you can use C expressions of type #gint with g_object_new() and properties of
+ * type #gint or #guint or smaller. Specifically, you can use integer literals
+ * with these property types.
+ *
+ * When using property types of #gint64 or #guint64, you must ensure that the
+ * value that you provide is 64 bit. This means that you should use a cast or
+ * make use of the %G_GINT64_CONSTANT or %G_GUINT64_CONSTANT macros.
+ *
+ * Similarly, #gfloat is promoted to #gdouble, so you must ensure that the value
+ * you provide is a #gdouble, even for a property of type #gfloat.
+ *
* Returns: (transfer full) (type GObject.Object): a new instance of
* @object_type
*/
@@ -1766,7 +1876,7 @@ g_object_new_with_custom_constructor (GObjectClass *class,
*/
newly_constructed = object_in_construction (object);
if (newly_constructed)
- g_datalist_id_set_data (&object->qdata, quark_in_construction, NULL);
+ unset_object_in_construction (object);
if (CLASS_HAS_PROPS (class))
{
@@ -2479,6 +2589,11 @@ g_object_get_valist (GObject *object,
*
* Sets properties on an object.
*
+ * The same caveats about passing integer literals as varargs apply as with
+ * g_object_new(). In particular, any integer literals set as the values for
+ * properties of type #gint64 or #guint64 must be 64 bits wide, using the
+ * %G_GINT64_CONSTANT or %G_GUINT64_CONSTANT macros.
+ *
* Note that the "notify" signals are queued and only emitted (in
* reverse order) after all properties have been set. See
* g_object_freeze_notify().
@@ -2515,20 +2630,22 @@ g_object_set (gpointer _object,
* of three properties: an integer, a string and an object:
* |[<!-- language="C" -->
* gint intval;
+ * guint64 uint64val;
* gchar *strval;
* GObject *objval;
*
* g_object_get (my_object,
* "int-property", &intval,
+ * "uint64-property", &uint64val,
* "str-property", &strval,
* "obj-property", &objval,
* NULL);
*
- * // Do something with intval, strval, objval
+ * // Do something with intval, uint64val, strval, objval
*
* g_free (strval);
* g_object_unref (objval);
- * ]|
+ * ]|
*/
void
g_object_get (gpointer _object,