summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/reference/gobject/gobject-sections.txt2
-rw-r--r--gobject/gobject.symbols2
-rw-r--r--gobject/gproperty.c153
-rw-r--r--gobject/gproperty.h14
-rw-r--r--gobject/tests/autoproperties.c2
-rw-r--r--gobject/tests/gproperty-example-base.c3
-rw-r--r--gobject/tests/gproperty-example-derived.c9
7 files changed, 144 insertions, 41 deletions
diff --git a/docs/reference/gobject/gobject-sections.txt b/docs/reference/gobject/gobject-sections.txt
index 2e3a93699..e71552501 100644
--- a/docs/reference/gobject/gobject-sections.txt
+++ b/docs/reference/gobject/gobject-sections.txt
@@ -892,6 +892,8 @@ g_property_is_writable
g_property_is_redable
g_property_is_deprecated
g_property_is_atomic
+g_property_is_copy_set
+g_property_is_copy_get
g_property_describe
g_property_set_range_values
g_property_get_range_values
diff --git a/gobject/gobject.symbols b/gobject/gobject.symbols
index 17229244e..fde734a8a 100644
--- a/gobject/gobject.symbols
+++ b/gobject/gobject.symbols
@@ -233,6 +233,8 @@ g_property_get_valist
g_property_get_value
g_property_get_value_type
g_property_is_atomic
+g_property_is_copy_get
+g_property_is_copy_set
g_property_is_deprecated
g_property_is_readable
g_property_is_writable
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
diff --git a/gobject/gproperty.h b/gobject/gproperty.h
index c1565633c..72c2c14a9 100644
--- a/gobject/gproperty.h
+++ b/gobject/gproperty.h
@@ -57,6 +57,13 @@ typedef struct _GProperty GProperty;
* @G_PROPERTY_ATOMIC: Whether the autogenerated setter function should
* be thread-safe, and acquire a lock when changing the value of the
* property.
+ * @G_PROPERTY_COPY_SET: Whether the property will make a copy or
+ * take a reference when being set to a new value
+ * @G_PROPERTY_COPY_GET: Whether the property will make a copy or
+ * take a reference when the value is being retrieved
+ * @G_PROPERTY_COPY: Whether the property will make a copy, or take a
+ * reference, of the new value being set, and return a copy, or
+ * increase the reference count, of the value being retrieved
*
* Flags for properties declared using #GProperty and relative macros.
*
@@ -70,7 +77,10 @@ typedef enum {
G_PROPERTY_READWRITE = (G_PROPERTY_READABLE | G_PROPERTY_WRITABLE),
G_PROPERTY_DEPRECATED = 1 << 2,
- G_PROPERTY_ATOMIC = 1 << 3
+ G_PROPERTY_ATOMIC = 1 << 3,
+ G_PROPERTY_COPY_SET = 1 << 4,
+ G_PROPERTY_COPY_GET = 1 << 5,
+ G_PROPERTY_COPY = (G_PROPERTY_COPY_SET | G_PROPERTY_COPY_GET)
} GPropertyFlags;
GType g_property_get_type (void) G_GNUC_CONST;
@@ -84,6 +94,8 @@ gboolean g_property_is_writable (GProperty *property)
gboolean g_property_is_readable (GProperty *property);
gboolean g_property_is_deprecated (GProperty *property);
gboolean g_property_is_atomic (GProperty *property);
+gboolean g_property_is_copy_set (GProperty *property);
+gboolean g_property_is_copy_get (GProperty *property);
void g_property_describe (GProperty *property,
const char *nick,
diff --git a/gobject/tests/autoproperties.c b/gobject/tests/autoproperties.c
index 69522e8ee..8fdd948ef 100644
--- a/gobject/tests/autoproperties.c
+++ b/gobject/tests/autoproperties.c
@@ -333,7 +333,7 @@ test_object_class_init (TestObjectClass *klass)
TEST_FLAGS_VALUE_FOO);
test_object_properties[PROP_BOXED] =
- g_boxed_property_new ("boxed", G_PROPERTY_READWRITE,
+ g_boxed_property_new ("boxed", G_PROPERTY_READWRITE | G_PROPERTY_COPY_SET,
G_STRUCT_OFFSET (TestObjectPrivate, boxed),
NULL, NULL);
g_property_set_prerequisite (G_PROPERTY (test_object_properties[PROP_BOXED]),
diff --git a/gobject/tests/gproperty-example-base.c b/gobject/tests/gproperty-example-base.c
index d8b67f60b..3cb9d4b23 100644
--- a/gobject/tests/gproperty-example-base.c
+++ b/gobject/tests/gproperty-example-base.c
@@ -90,7 +90,8 @@ test_file_class_init (TestFileClass *klass)
g_type_class_add_private (klass, sizeof (TestFilePrivate));
test_file_properties[PROP_PATH] =
- g_string_property_new ("path", G_PROPERTY_READWRITE,
+ g_string_property_new ("path",
+ G_PROPERTY_READWRITE | G_PROPERTY_COPY_SET,
G_STRUCT_OFFSET (TestFilePrivate, path),
(GPropertyStringSet) test_file_set_path,
NULL);
diff --git a/gobject/tests/gproperty-example-derived.c b/gobject/tests/gproperty-example-derived.c
index bdde06eaf..813c9093e 100644
--- a/gobject/tests/gproperty-example-derived.c
+++ b/gobject/tests/gproperty-example-derived.c
@@ -207,7 +207,8 @@ test_file_mp3_class_init (TestFileMp3Class *klass)
g_type_class_add_private (klass, sizeof (TestFileMp3Private));
test_file_mp3_properties[PROP_ALBUM] =
- g_string_property_new ("album", G_PROPERTY_READWRITE,
+ g_string_property_new ("album",
+ G_PROPERTY_READWRITE | G_PROPERTY_COPY_SET,
G_STRUCT_OFFSET (TestFileMp3Private, album),
NULL, NULL);
g_property_set_default (G_PROPERTY (test_file_mp3_properties[PROP_ALBUM]),
@@ -215,7 +216,8 @@ test_file_mp3_class_init (TestFileMp3Class *klass)
"Unknown Album");
test_file_mp3_properties[PROP_ARTIST] =
- g_string_property_new ("artist", G_PROPERTY_READWRITE,
+ g_string_property_new ("artist",
+ G_PROPERTY_READWRITE | G_PROPERTY_COPY_SET,
G_STRUCT_OFFSET (TestFileMp3Private, artist),
NULL, NULL);
g_property_set_default (G_PROPERTY (test_file_mp3_properties[PROP_ARTIST]),
@@ -223,7 +225,8 @@ test_file_mp3_class_init (TestFileMp3Class *klass)
"Unknown Author");
test_file_mp3_properties[PROP_TITLE] =
- g_string_property_new ("title", G_PROPERTY_READWRITE,
+ g_string_property_new ("title",
+ G_PROPERTY_READWRITE | G_PROPERTY_COPY_SET,
G_STRUCT_OFFSET (TestFileMp3Private, title),
NULL, NULL);
g_property_set_default (G_PROPERTY (test_file_mp3_properties[PROP_TITLE]),