summaryrefslogtreecommitdiff
path: root/gobject/gproperty.c
diff options
context:
space:
mode:
Diffstat (limited to 'gobject/gproperty.c')
-rw-r--r--gobject/gproperty.c153
1 files changed, 118 insertions, 35 deletions
diff --git a/gobject/gproperty.c b/gobject/gproperty.c
index b94b62b3e..89ff1d5f7 100644
--- a/gobject/gproperty.c
+++ b/gobject/gproperty.c
@@ -156,11 +156,18 @@
* ]|
* <para>Note that calling g_property_set() for a property holding a
* complex type (e.g. #GObject or #GBoxed) without a specific setter
- * function will result in the value being copied in the private data
- * structure's field. In contrast, calling g_property_get() will return
- * a pointer to the private data structure's field: it is up to the
- * getter function to decide whether to return a copy of the internal
- * data or the pointer itself.</para>
+ * function will, by default, result in the pointer to the new value
+ * being copied in the private data structure's field; if you need to
+ * copy a boxed type, or take a reference on an object type, you will
+ * need to set the %G_PROPERTY_COPY_SET flag when creating the
+ * property.</para>
+ *
+ * <para>Calling g_property_get() will return a pointer to the private
+ * data structure's field, unless %G_PROPERTY_COPY_GET is set when
+ * creating the property, in which case the returned value will either
+ * be a copy of the private data structure field if it is a boxed type
+ * or the instance with its reference count increased if it is an object
+ * type.</para>
* </refsect3>
*
* <refsect3>
@@ -363,7 +370,7 @@
*
* |[
* test_object_property[PROP_WIDTH] =
- * g_int_property_new ("width", G_PROPERTY_READWRITE,
+ * g_int_property_new ("width", G_PROPERTY_READWRITE | G_PROPERTY_COPY_SET,
* G_STRUCT_OFFSET (TestObjectPrivate, width),
* test_object_set_width, /&ast; explicit setter &ast;/
* NULL /&ast; implicit getter &ast;/);
@@ -432,7 +439,7 @@
* |[
* G_DEFINE_PROPERTY_GET (TestObject, test_object, int, width)
* G_DEFINE_PROPERTY_SET_WITH_CODE (Test_object, test_object, int, width,
- * test_object_queue_resize (self))
+ * test_object_queue_action (self))
* ]|
*
* <para>The WITH_CODE variant of the setter will define the "self" and
@@ -2405,8 +2412,13 @@ g_string_property_set_value (GProperty *property,
return FALSE;
}
- g_free (str);
- (* (gpointer *) field_p) = g_strdup (value);
+ if (property->flags & G_PROPERTY_COPY_SET)
+ {
+ g_free (str);
+ (* (gpointer *) field_p) = g_strdup (value);
+ }
+ else
+ (* (gpointer *) field_p) = (gpointer) value;
property_unlock_internal (property, gobject);
@@ -2446,7 +2458,10 @@ g_string_property_get_value (GProperty *property,
priv_p = get_private_pointer (gobject, property->priv_offset);
field_p = G_STRUCT_MEMBER_P (priv_p, property->field_offset);
- retval = (* (gpointer *) field_p);
+ if (property->flags & G_PROPERTY_COPY_GET)
+ retval = g_strdup ((* (gpointer *) field_p));
+ else
+ retval = (* (gpointer *) field_p);
return retval;
}
@@ -2612,15 +2627,20 @@ g_boxed_property_set_value (GProperty *property,
priv_p = get_private_pointer (gobject, property->priv_offset);
field_p = G_STRUCT_MEMBER_P (priv_p, property->field_offset);
- old_value = (* (gpointer *) field_p);
+ if (property->flags & G_PROPERTY_COPY_SET)
+ {
+ old_value = (* (gpointer *) field_p);
- if (value != NULL)
- (* (gpointer *) field_p) = g_boxed_copy (((GParamSpec *) property)->value_type, value);
- else
- (* (gpointer *) field_p) = NULL;
+ if (value != NULL)
+ (* (gpointer *) field_p) = g_boxed_copy (((GParamSpec *) property)->value_type, value);
+ else
+ (* (gpointer *) field_p) = NULL;
- if (old_value != NULL)
- g_boxed_free (((GParamSpec *) property)->value_type, old_value);
+ if (old_value != NULL)
+ g_boxed_free (((GParamSpec *) property)->value_type, old_value);
+ }
+ else
+ (* (gpointer *) field_p) = value;
property_unlock_internal (property, gobject);
@@ -2659,7 +2679,11 @@ g_boxed_property_get_value (GProperty *property,
priv_p = get_private_pointer (gobject, property->priv_offset);
field_p = G_STRUCT_MEMBER_P (priv_p, property->field_offset);
- value = (* (gpointer *) field_p);
+
+ if (property->flags & G_PROPERTY_COPY_GET)
+ value = g_boxed_copy (((GParamSpec *) property)->value_type, (* (gpointer *) field_p));
+ else
+ value = (* (gpointer *) field_p);
return value;
}
@@ -2836,19 +2860,24 @@ g_object_property_set_value (GProperty *property,
return FALSE;
}
- obj = (* (gpointer *) field_p);
- if (obj != NULL)
- g_object_unref (obj);
-
- (* (gpointer *) field_p) = obj = value;
-
- if (obj != NULL)
+ if (property->flags & G_PROPERTY_COPY_SET)
{
- if (G_IS_INITIALLY_UNOWNED (obj))
- g_object_ref_sink (obj);
- else
- g_object_ref (obj);
+ obj = (* (gpointer *) field_p);
+ if (obj != NULL)
+ g_object_unref (obj);
+
+ (* (gpointer *) field_p) = obj = value;
+
+ if (obj != NULL)
+ {
+ if (G_IS_INITIALLY_UNOWNED (obj))
+ g_object_ref_sink (obj);
+ else
+ g_object_ref (obj);
+ }
}
+ else
+ (* (gpointer *) field_p) = value;
property_unlock_internal (property, gobject);
@@ -2887,7 +2916,17 @@ g_object_property_get_value (GProperty *property,
priv_p = g_type_instance_get_private (gobject, G_OBJECT_TYPE (gobject));
field_p = G_STRUCT_MEMBER_P (priv_p, property->field_offset);
- return (* (gpointer *) field_p);
+ if (property->flags & G_PROPERTY_COPY_GET)
+ {
+ gpointer value = (* (gpointer *) field_p);
+
+ if (value != NULL)
+ return g_object_ref (value);
+ else
+ return NULL;
+ }
+ else
+ return (* (gpointer *) field_p);
}
else
{
@@ -4558,8 +4597,11 @@ g_property_get_valist (GProperty *property,
value = g_string_property_get_value (property, gobject);
- if ((flags & G_PROPERTY_COLLECT_COPY) != 0)
- (* (gchar **) ret_p) = g_strdup (value);
+ if (((flags & G_PROPERTY_COLLECT_COPY) != 0) &&
+ (property->flags & G_PROPERTY_COPY_GET) == 0)
+ {
+ (* (gchar **) ret_p) = g_strdup (value);
+ }
else
(* (gconstpointer *) ret_p) = value;
}
@@ -4571,7 +4613,8 @@ g_property_get_valist (GProperty *property,
boxed = g_boxed_property_get_value (property, gobject);
- if ((flags & G_PROPERTY_COLLECT_COPY) != 0)
+ if (((flags & G_PROPERTY_COLLECT_COPY) != 0) &&
+ (property->flags & G_PROPERTY_COPY_GET) == 0)
{
if (boxed != NULL)
(* (gpointer *) ret_p) = g_boxed_copy (gtype, boxed);
@@ -4587,8 +4630,12 @@ g_property_get_valist (GProperty *property,
{
gpointer obj = g_object_property_get_value (property, gobject);
- if (((flags & G_PROPERTY_COLLECT_REF) != 0) && obj != NULL)
- (* (gpointer *) ret_p) = g_object_ref (obj);
+ if ((((flags & G_PROPERTY_COLLECT_REF) != 0) &&
+ (property->flags & G_PROPERTY_COPY_GET) == 0) &&
+ (obj != NULL))
+ {
+ (* (gpointer *) ret_p) = g_object_ref (obj);
+ }
else
(* (gpointer *) ret_p) = obj;
}
@@ -5349,6 +5396,42 @@ g_property_is_atomic (GProperty *property)
}
/**
+ * g_property_is_copy_set:
+ * @property: a #GProperty
+ *
+ * Checks whether the @property has the %G_PROPERTY_COPY_SET flag set.
+ *
+ * Return value: %TRUE if the flag is set, and %FALSE otherwise
+ *
+ * Since: 2.30
+ */
+gboolean
+g_property_is_copy_set (GProperty *property)
+{
+ g_return_val_if_fail (G_IS_PROPERTY (property), FALSE);
+
+ return (property->flags & G_PROPERTY_COPY_SET) != 0;
+}
+
+/**
+ * g_property_is_copy_get:
+ * @property: a #GProperty
+ *
+ * Checks whether the @property has the %G_PROPERTY_COPY_GET flag set.
+ *
+ * Return value: %TRUE if the flag is set, and %FALSE otherwise
+ *
+ * Since: 2.30
+ */
+gboolean
+g_property_is_copy_get (GProperty *property)
+{
+ g_return_val_if_fail (G_IS_PROPERTY (property), FALSE);
+
+ return (property->flags & G_PROPERTY_COPY_GET) != 0;
+}
+
+/**
* g_property_lock:
* @property: a #GProperty
* @gobject: a #GObject