2011-04-22 14:08:11 +01:00
|
|
|
/* gproperty.c: Property definitions for GObject
|
|
|
|
*
|
|
|
|
* Copyright © 2012 Emmanuele Bassi <ebassi@gnome.org>
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General
|
|
|
|
* Public License along with this library; if not, write to the
|
|
|
|
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
|
|
|
* Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* SECTION:gproperty
|
|
|
|
* @Title: GProperty
|
|
|
|
* @Short_Desc: Property definitions for GObject
|
|
|
|
*
|
|
|
|
* #GProperty is a type of #GParamSpec for defining properties for #GObject.
|
|
|
|
*
|
|
|
|
* The main difference between #GProperty and #GParamSpec is that #GProperty
|
|
|
|
* enforces a specific set of best practices for accessing values exposed
|
|
|
|
* as #GObject properties.
|
|
|
|
*
|
|
|
|
* #GProperty uses direct access to the fields in the instance private data
|
|
|
|
* structure whenever possible, and allows specifying accessor functions in
|
|
|
|
* cases where it is necessary. For direct access to the private structure
|
|
|
|
* members, #GProperty will assume that the instance structure contains a
|
|
|
|
* pointer to the private data structure as its last member, e.g.:
|
|
|
|
*
|
|
|
|
* |[
|
|
|
|
* typedef struct _TestObject TestObject;
|
|
|
|
* typedef struct _TestObjectPrivate TestObjectPrivate;
|
|
|
|
*
|
|
|
|
* struct _TestObject
|
|
|
|
* {
|
|
|
|
* GObject parent_instance;
|
|
|
|
*
|
|
|
|
* TestObjectPrivate *priv;
|
|
|
|
* };
|
|
|
|
* ]|
|
|
|
|
*
|
|
|
|
* #GProperty is strongly typed, both at compilation time and at run time.
|
|
|
|
*
|
|
|
|
* Unlike #GParamSpec, there is a single public #GProperty class with various
|
|
|
|
* constructors; all public #GProperty methods operate depending on the type
|
|
|
|
* handled by the #GProperty.
|
|
|
|
*
|
|
|
|
* The #GParamSpec methods can be used with #GProperty transparently, to
|
|
|
|
* allow backward compatibility with existing code that introspects #GObject
|
|
|
|
* properties through the #GParamSpec API.
|
|
|
|
*
|
|
|
|
* <refsect2>
|
|
|
|
* <title>Using GProperty</title>
|
|
|
|
* <para>A typical example of #GProperty usage is:</para>
|
|
|
|
*
|
|
|
|
* |[
|
|
|
|
* /* the private data structure */
|
|
|
|
* struct _TestObjectPrivate
|
|
|
|
* {
|
|
|
|
* int x;
|
|
|
|
* int y;
|
|
|
|
* int width;
|
|
|
|
* int height;
|
|
|
|
* };
|
|
|
|
*
|
|
|
|
* /* identifiers for each property in the array */
|
|
|
|
* enum { PROP_0, PROP_X, PROP_Y, PROP_WIDTH, PROP_HEIGHT, LAST_PROP };
|
|
|
|
*
|
|
|
|
* /* an array of properties */
|
|
|
|
* static GParamSpec *test_object_properties[LAST_PROP] = { 0, };
|
|
|
|
*
|
|
|
|
* static void
|
|
|
|
* test_object_class_init (TestObjectClass *klass)
|
|
|
|
* {
|
|
|
|
* g_type_class_add_private (klass, sizeof (TestObjectPrivate));
|
|
|
|
*
|
|
|
|
* test_object_properties[PROP_X] =
|
|
|
|
* g_int_property_new ("x", G_PROPERTY_READWRITE,
|
|
|
|
* G_STRUCT_OFFSET (TestObjectPrivate, x),
|
|
|
|
* NULL,
|
|
|
|
* NULL);
|
|
|
|
*
|
|
|
|
* test_object_properties[PROP_Y] =
|
|
|
|
* g_int_property_new ("y", G_PROPERTY_READWRITE,
|
|
|
|
* G_STRUCT_OFFSET (TestObjectPrivate, y),
|
|
|
|
* NULL,
|
|
|
|
* NULL);
|
|
|
|
*
|
|
|
|
* test_object_properties[PROP_WIDTH] =
|
|
|
|
* g_int_property_new ("width", G_PROPERTY_READWRITE,
|
|
|
|
* G_STRUCT_OFFSET (TestObjectPrivate, width),
|
|
|
|
* NULL,
|
|
|
|
* NULL);
|
|
|
|
*
|
|
|
|
* test_object_properties[PROP_HEIGHT] =
|
|
|
|
* g_int_property_new ("height", G_PROPERTY_READWRITE,
|
|
|
|
* G_STRUCT_OFFSET (TestObjectPrivate, height),
|
|
|
|
* NULL,
|
|
|
|
* NULL);
|
|
|
|
*
|
|
|
|
* g_object_class_install_properties (G_OBJECT_CLASS (klass),
|
|
|
|
* G_N_ELEMENTS (test_object_properties),
|
|
|
|
* test_object_properties);
|
|
|
|
* }
|
|
|
|
* ]|
|
|
|
|
* <para>The main differences with the #GParamSpec creation and installation
|
|
|
|
* code are:</para>
|
|
|
|
*
|
|
|
|
* <itemizedlist>
|
|
|
|
* <listitem><para>the constructors take the same parameters</para></listitem>
|
|
|
|
* <listitem><para>there are not #GObject set_property and get_property
|
|
|
|
* virtual function assignments</para></listitem>
|
|
|
|
* <listitem><para>all properties use direct access of the member in the
|
|
|
|
* instance private data structure</para></listitem>
|
|
|
|
* </itemizedlist>
|
|
|
|
*
|
|
|
|
* <refsect3>
|
|
|
|
* <title>Setting and getting values</title>
|
|
|
|
* <para>Writing accessors for properties defined using #GProperties is
|
|
|
|
* a simple case of calling g_property_set() or g_property_get(), for
|
|
|
|
* instance the code below is the simplest form of setter and getter
|
|
|
|
* pair for the "x" property as defined above:</para>
|
|
|
|
* |[
|
|
|
|
* void
|
|
|
|
* test_object_set_x (TestObject *self,
|
|
|
|
* int x)
|
|
|
|
* {
|
|
|
|
* g_return_if_fail (TEST_IS_OBJECT (self));
|
|
|
|
*
|
|
|
|
* g_property_set (G_PROPERTY (test_object_properties[PROP_X]), self, x);
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
* int
|
|
|
|
* test_object_get_x (TestObject *self)
|
|
|
|
* {
|
|
|
|
* int retval;
|
|
|
|
*
|
|
|
|
* g_return_val_if_fail (TEST_IS_OBJECT (self), 0);
|
|
|
|
*
|
|
|
|
* g_property_get (G_PROPERTY (test_object_properties[PROP_X]),
|
|
|
|
* self,
|
|
|
|
* &retval);
|
|
|
|
*
|
|
|
|
* return retval;
|
|
|
|
* }
|
|
|
|
* ]|
|
|
|
|
* <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, 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>
|
|
|
|
* <title>Ranges and validation</title>
|
|
|
|
* <para>For different property types it is possible to set a range of
|
|
|
|
* valid values; the setter function can then use g_property_validate()
|
|
|
|
* to check whether the new value is valid.</para>
|
|
|
|
*
|
|
|
|
* <para>The range is set using g_property_set_range():</para>
|
|
|
|
*
|
|
|
|
* |[
|
|
|
|
* test_object_properties[PROP_WIDTH] =
|
|
|
|
* g_int_property_new ("width", G_PROPERTY_READWRITE,
|
|
|
|
* G_STRUCT_OFFSET (TestObjectPrivate, width),
|
|
|
|
* NULL, NULL);
|
|
|
|
* g_property_set_range (G_PROPERTY (test_object_properties[PROP_WIDTH]),
|
|
|
|
* 0.0, /* minimum value */
|
|
|
|
* G_MAXINT /* maximum value */)
|
|
|
|
*
|
|
|
|
* test_object_properties[PROP_HEIGHT] =
|
|
|
|
* g_int_property_new ("height", G_PROPERTY_READWRITE,
|
|
|
|
* G_STRUCT_OFFSET (TestObjectPrivate, height),
|
|
|
|
* NULL, NULL);
|
|
|
|
* g_property_set_range (G_PROPERTY (test_object_properties[PROP_HEIGHT]),
|
|
|
|
* 0.0, /* minimum value */
|
|
|
|
* G_MAXINT /* maximum value */)
|
|
|
|
* ]|
|
|
|
|
*
|
|
|
|
* <para>The example above keeps the "width" and "height" properties as
|
|
|
|
* integers, but limits the range of valid values to [ 0, %G_MAXINT ].</para>
|
|
|
|
*
|
|
|
|
* <para>Validation is automatically performed when setting a property
|
|
|
|
* through g_property_set(); explicit setter methods can use g_property_validate()
|
|
|
|
* to perform the validation, e.g.:</para>
|
|
|
|
*
|
|
|
|
* |[
|
|
|
|
* void
|
|
|
|
* test_object_set_width (TestObject *self,
|
|
|
|
* int width)
|
|
|
|
* {
|
|
|
|
* GProperty *property;
|
|
|
|
*
|
|
|
|
* property = G_PROPERTY (test_object_properties[PROP_WIDTH]);
|
|
|
|
*
|
|
|
|
* g_return_if_fail (!g_property_validate (property, width));
|
|
|
|
*
|
|
|
|
* /* we deliberately do not use g_property_set() here because
|
|
|
|
* * g_property_set() will implicitly call g_property_validate()
|
|
|
|
* * prior to setting the property
|
|
|
|
* */
|
|
|
|
* if (self->priv->width == width)
|
|
|
|
* return;
|
|
|
|
*
|
|
|
|
* self->priv->width = width;
|
|
|
|
*
|
|
|
|
* g_object_notify_by_pspec (G_OBJECT (self), G_PARAM_SPEC (property));
|
|
|
|
*
|
|
|
|
* test_object_queue_foo (self);
|
|
|
|
* }
|
|
|
|
* ]|
|
|
|
|
* </refsect3>
|
|
|
|
*
|
|
|
|
* <refsect3>
|
|
|
|
* <title>Default values</title>
|
|
|
|
* <para>Default values are declared using g_property_set_default(), e.g.:</para>
|
|
|
|
* |[
|
|
|
|
* test_object_properties[PROP_WIDTH] =
|
|
|
|
* g_int_property_new ("width", G_PROPERTY_READWRITE,
|
|
|
|
* G_STRUCT_OFFSET (TestObjectPrivate, width),
|
|
|
|
* NULL, NULL);
|
|
|
|
* g_property_set_range (G_PROPERTY (test_object_properties[PROP_WIDTH]),
|
|
|
|
* 0, /* minimum value */
|
|
|
|
* G_MAXINT /* maximum value */)
|
|
|
|
* g_property_set_default (G_PROPERTY (test_object_properties[PROP_WIDTH]),
|
|
|
|
* G_OBJECT_CLASS (klass),
|
|
|
|
* 1);
|
|
|
|
*
|
|
|
|
* test_object_properties[PROP_HEIGHT] =
|
|
|
|
* g_int_property_new ("height", G_PROPERTY_READWRITE,
|
|
|
|
* G_STRUCT_OFFSET (TestObjectPrivate, height),
|
|
|
|
* NULL, NULL);
|
|
|
|
* g_property_set_range (G_PROPERTY (test_object_properties[PROP_HEIGHT]),
|
|
|
|
* 0, /* minimum value */
|
|
|
|
* G_MAXINT /* maximum value */)
|
|
|
|
* g_property_set_default (G_PROPERTY (test_object_properties[PROP_HEIGHT]),
|
|
|
|
* G_OBJECT_CLASS (klass),
|
|
|
|
* 1);
|
|
|
|
* ]|
|
|
|
|
*
|
|
|
|
* <para>Sub-classes can use g_property_override_default() on an existing property
|
|
|
|
* of their parent classes to override the default value:</para>
|
|
|
|
*
|
|
|
|
* |[
|
|
|
|
* property = g_object_class_find_property (G_OBJECT_CLASS (klass), "width");
|
|
|
|
* g_property_override_default (G_PROPERTY (property),
|
|
|
|
* G_OBJECT_CLASS (klass),
|
|
|
|
* 200);
|
|
|
|
* ]|
|
|
|
|
*
|
|
|
|
* <para>The default value can be retrieved using g_property_get_default(),
|
|
|
|
* for instance during instance initialization:</para>
|
|
|
|
*
|
|
|
|
* |[
|
|
|
|
* static void
|
|
|
|
* test_object_init (TestObject *self)
|
|
|
|
* {
|
|
|
|
* self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, TEST_TYPE_OBJECT,
|
|
|
|
* TestObjectPrivate);
|
|
|
|
*
|
|
|
|
* g_property_get_default (G_PROPERTY (test_object_properties[PROP_WIDTH]),
|
|
|
|
* self,
|
|
|
|
* &(self->priv->width));
|
|
|
|
* g_property_get_default (G_PROPERTY (test_object_properties[PROP_HEIGHT]),
|
|
|
|
* self,
|
|
|
|
* &(self->priv->height));
|
|
|
|
* }
|
|
|
|
* ]|
|
|
|
|
*
|
|
|
|
* <para>or to return the default value when writing a getter:</para>
|
|
|
|
*
|
|
|
|
* |[
|
|
|
|
* int
|
|
|
|
* test_object_get_width (TestObject *self)
|
|
|
|
* {
|
|
|
|
* GProperty *property;
|
|
|
|
* int retval;
|
|
|
|
*
|
|
|
|
* property = G_PROPERTY (test_object_properties[PROP_WIDTH]);
|
|
|
|
*
|
|
|
|
* /* return the default width if self has not been foobarized */
|
|
|
|
* if (!self->priv->is_foobarized)
|
|
|
|
* g_property_get_default (property, self, &retval);
|
|
|
|
* else
|
|
|
|
* g_property_get (property, self, &retval);
|
|
|
|
*
|
|
|
|
* return retval;
|
|
|
|
* }
|
|
|
|
* ]|
|
|
|
|
*
|
|
|
|
* <para>The reason why the object instance is necessary when calling
|
|
|
|
* g_property_get_default() is to retrieve the correct default for the
|
|
|
|
* given instance type, in case sub-classes overridden the default value
|
|
|
|
* using g_property_override_default().</para>
|
|
|
|
* </refsect3>
|
|
|
|
*
|
|
|
|
* <refsect3>
|
|
|
|
* <title>Custom accessors</title>
|
|
|
|
* <para>For cases where the direct access to a structure field does not
|
|
|
|
* match the semantics of the property it is possible to pass a setter
|
|
|
|
* and a getter function when creating a #GProperty:</para>
|
|
|
|
*
|
|
|
|
* |[
|
|
|
|
* test_object_property[PROP_COMPLEX] =
|
|
|
|
* g_object_property_new ("complex", G_PROPERTY_READWRITE, -1,
|
|
|
|
* test_object_set_complex,
|
|
|
|
* test_object_get_complex);
|
|
|
|
* g_property_set_prerequisite (G_PROPERTY (test_object_property[PROP_COMPLEX]),
|
|
|
|
* TEST_TYPE_COMPLEX);
|
|
|
|
* ]|
|
|
|
|
*
|
|
|
|
* <para>The accessors can be public or private functions. The implementation
|
|
|
|
* of an explicit setter will be called under the #GProperty lock if the
|
|
|
|
* property is declared using the %G_PROPERTY_ATOMIC flag; the setter should
|
|
|
|
* not notify the property on changes, and should return %TRUE if the value
|
|
|
|
* was modified. An example of a setter is:</para>
|
|
|
|
*
|
|
|
|
* |[
|
|
|
|
* static gboolean
|
|
|
|
* test_object_set_complex (gpointer self_,
|
|
|
|
* gpointer value_)
|
|
|
|
* {
|
|
|
|
* TestObject *self = self_;
|
|
|
|
* TestComplex *value = value_;
|
|
|
|
*
|
|
|
|
* if (self->priv->complex == value)
|
|
|
|
* return FALSE;
|
|
|
|
*
|
|
|
|
* if (self->priv->complex != NULL)
|
|
|
|
* {
|
|
|
|
* test_complex_set_back_pointer (self->priv->complex, NULL);
|
|
|
|
* g_object_unref (self->priv->complex);
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
* self->priv->complex = value;
|
|
|
|
*
|
|
|
|
* if (self->priv->complex != NULL)
|
|
|
|
* {
|
|
|
|
* g_object_ref (self->priv->complex);
|
|
|
|
* test_complex_set_back_pointer (self->priv->complex, self);
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
* test_object_queue_foo (self);
|
|
|
|
*
|
|
|
|
* return TRUE;
|
|
|
|
* }
|
|
|
|
* ]|
|
|
|
|
*
|
|
|
|
* <para>It is also possible to still pass the offset of the structure
|
|
|
|
* field, and provide either the setter or the getter function:</para>
|
|
|
|
*
|
|
|
|
* |[
|
|
|
|
* test_object_property[PROP_WIDTH] =
|
|
|
|
* g_int_property_new ("width", G_PROPERTY_READWRITE | G_PROPERTY_COPY_SET,
|
|
|
|
* G_STRUCT_OFFSET (TestObjectPrivate, width),
|
|
|
|
* test_object_set_width, /* explicit setter */
|
|
|
|
* NULL /* implicit getter */);
|
|
|
|
* ]|
|
|
|
|
*
|
|
|
|
* <para>Calling g_property_set() using the "width" property in the example
|
|
|
|
* above will result in calling test_object_set_width(); calling, instead,
|
|
|
|
* g_property_get() using the "width" property will result in accessing
|
|
|
|
* the width structure member.</para>
|
|
|
|
*
|
|
|
|
* <warning><para>You must not call g_property_set() inside the implementation
|
|
|
|
* of test_object_set_width(), in order to avoid loops.</para></warning>
|
|
|
|
* </refsect3>
|
|
|
|
*
|
|
|
|
* <refsect3>
|
|
|
|
* <title>Special flags</title>
|
|
|
|
* <para>#GProperty has its own set of flags to be passed to its
|
|
|
|
* constructor functions. Alongside the usual %G_PROPERTY_READABLE
|
|
|
|
* and %G_PROPERTY_WRITABLE, which control the access policy for
|
|
|
|
* setter and getter functions, there are the following flags:</para>
|
|
|
|
*
|
|
|
|
* <itemizedlist>
|
|
|
|
* <listitem><para>%G_PROPERTY_DEPRECATED, a flag for marking
|
|
|
|
* deprecated properties. If the G_ENABLE_DIAGNOSTIC environment
|
|
|
|
* variable is set, calling g_property_set() and g_property_get()
|
|
|
|
* on the deprecated properties will result in a run time warning
|
|
|
|
* printed on the console.</para></listitem>
|
|
|
|
* <listitem><para>%G_PROPERTY_ATOMIC, a flag for marking access
|
|
|
|
* to properties a threadsafe operation. It is possible to change
|
|
|
|
* the locking mechanism by using g_property_set_lock_functions()
|
|
|
|
* and replacing both the lock and the unlock function, which can
|
|
|
|
* then be called by g_property_lock() and g_property_unlock()
|
|
|
|
* when needed.</para></listitem>
|
|
|
|
* </itemizedlist>
|
|
|
|
* </refsect3>
|
|
|
|
*
|
|
|
|
* </refsect2>
|
|
|
|
*
|
|
|
|
* <refsect2>
|
|
|
|
* <title>Auto-generating setters and getters</title>
|
|
|
|
* <para>Similarly to the #G_DEFINE_TYPE macro for defining a new
|
|
|
|
* #GObject type, GObject also provides various macros for
|
|
|
|
* auto-generating the accessors pair of functions.</para>
|
|
|
|
* <para>The most simple way to define a setter and getter pair is
|
|
|
|
* to use the #G_DEFINE_PROPERTY_GET_SET macro. This macro generates
|
|
|
|
* a getter and a setter using the type name, the type of the
|
|
|
|
* property and the name of the property, for instance:</para>
|
|
|
|
*
|
|
|
|
* |[
|
|
|
|
* G_DEFINE_PROPERTY_GET_SET (TestObject, test_object, int, x)
|
|
|
|
* G_DEFINE_PROPERTY_GET_SET (TestObject, test_object, int, y)
|
|
|
|
* G_DEFINE_PROPERTY_GET_SET (TestObject, test_object, int, width)
|
|
|
|
* G_DEFINE_PROPERTY_GET_SET (TestObject, test_object, int, height)
|
|
|
|
* ]|
|
|
|
|
*
|
|
|
|
* <para>The generated accessor pairs will use the #GProperty API
|
|
|
|
* to validate and access the property value. It is also possible
|
|
|
|
* to separate the setter and getter generation by using the
|
|
|
|
* #G_DEFINE_PROPERTY_GET and #G_DEFINE_PROPERTY_SET macros.</para>
|
|
|
|
*
|
|
|
|
* <para>If either the setter or the getter functions require additional
|
|
|
|
* custom code to be added to the auto-generated one, it is possible to
|
|
|
|
* use the #G_DEFINE_PROPERTY_GET_WITH_CODE macro and its sibling, the
|
|
|
|
* #G_DEFINE_PROPERTY_SET_WITH_CODE macro, for instance:</para>
|
|
|
|
*
|
|
|
|
* |[
|
|
|
|
* G_DEFINE_PROPERTY_GET (TestObject, test_object, int, width)
|
|
|
|
* G_DEFINE_PROPERTY_SET_WITH_CODE (Test_object, test_object, int, width,
|
|
|
|
* test_object_queue_action (self))
|
|
|
|
* ]|
|
|
|
|
*
|
|
|
|
* <para>The WITH_CODE variant of the setter will define the "self" and
|
|
|
|
* "value" variables for the instance and the new value respectively; the
|
|
|
|
* custom code will be executed only after the value has been set.
|
|
|
|
* For the WITH_CODE variant of the getter, the macro will define the
|
|
|
|
* "self" and "retval" variables for the instance and the returned value
|
|
|
|
* respectively; the custom code will be executed before retrieving the
|
|
|
|
* value of the property to be returned.</para>
|
|
|
|
* </refsect2>
|
|
|
|
*
|
|
|
|
* <example id="gproperty-example-base">
|
|
|
|
* <title>Base object class using GProperty</title>
|
|
|
|
* <para>The example below shows how to use #GProperty and the code
|
|
|
|
* generation macros to implement a simple base class called
|
|
|
|
* "TestFile".</para>
|
|
|
|
* <programlisting>
|
|
|
|
* <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../gobject/tests/gproperty-example-base.c">
|
|
|
|
* <xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback>
|
|
|
|
* </xi:include>
|
|
|
|
* </programlisting>
|
|
|
|
* </example>
|
|
|
|
*
|
|
|
|
* <example id="gproperty-example-derived">
|
|
|
|
* <title>Derived object class using GProperty</title>
|
|
|
|
* <para>The example below shows how to use #GProperty and the code
|
|
|
|
* generation macros to implement a simple base class called
|
|
|
|
* "TestFile" and a derived class called "TestFileMp3".</para>
|
|
|
|
* <programlisting>
|
|
|
|
* <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../gobject/tests/gproperty-example-derived.c">
|
|
|
|
* <xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback>
|
|
|
|
* </xi:include>
|
|
|
|
* </programlisting>
|
|
|
|
* </example>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include "gproperty.h"
|
|
|
|
|
|
|
|
#include "gvaluecollector.h"
|
|
|
|
#include "gparam.h"
|
|
|
|
#include "gtype.h"
|
|
|
|
#include "gvalue.h"
|
|
|
|
#include "gvaluetypes.h"
|
|
|
|
|
|
|
|
struct _GProperty
|
|
|
|
{
|
|
|
|
GParamSpec parent_instance;
|
|
|
|
|
|
|
|
guint flags : 15;
|
|
|
|
guint is_installed : 1;
|
|
|
|
|
|
|
|
guint16 type_size;
|
|
|
|
guint16 priv_offset;
|
|
|
|
guint16 field_offset;
|
|
|
|
|
|
|
|
GQuark prop_id;
|
|
|
|
|
|
|
|
GPropertyLockFunc lock_func;
|
|
|
|
GPropertyUnlockFunc unlock_func;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* defines for the integer sub-types we don't have */
|
|
|
|
#define g_value_get_int8 g_value_get_int
|
|
|
|
#define g_value_get_int16 g_value_get_int
|
|
|
|
#define g_value_get_int32 g_value_get_int
|
|
|
|
|
|
|
|
#define g_value_get_uint8 g_value_get_uint
|
|
|
|
#define g_value_get_uint16 g_value_get_uint
|
|
|
|
#define g_value_get_uint32 g_value_get_uint
|
|
|
|
|
|
|
|
#define DEFINE_PROPERTY_INTEGER(G_t, g_t, c_t, G_T, defVal, minVal, maxVal) \
|
|
|
|
typedef struct { \
|
|
|
|
GProperty parent; \
|
|
|
|
\
|
|
|
|
c_t min_value; \
|
|
|
|
c_t max_value; \
|
|
|
|
\
|
|
|
|
GProperty##G_t##Set setter; \
|
|
|
|
GProperty##G_t##Get getter; \
|
|
|
|
} G##G_t##Property; \
|
|
|
|
\
|
|
|
|
static gint \
|
|
|
|
property_##g_t##_values_cmp (GParamSpec *pspec, \
|
|
|
|
const GValue *value_a, \
|
|
|
|
const GValue *value_b) \
|
|
|
|
{ \
|
|
|
|
c_t val_a = g_value_get_##g_t (value_a); \
|
|
|
|
c_t val_b = g_value_get_##g_t (value_b); \
|
|
|
|
\
|
|
|
|
if (val_a < val_b) \
|
|
|
|
return -1; \
|
|
|
|
\
|
|
|
|
if (val_a > val_b) \
|
|
|
|
return 1; \
|
|
|
|
\
|
|
|
|
return 0; \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
static gboolean \
|
|
|
|
property_##g_t##_validate (GParamSpec *pspec, \
|
|
|
|
GValue *value) \
|
|
|
|
{ \
|
|
|
|
G##G_t##Property *internal = (G##G_t##Property *) pspec; \
|
|
|
|
c_t oval = g_value_get_##g_t (value); \
|
|
|
|
c_t nval = oval; \
|
|
|
|
\
|
|
|
|
nval = CLAMP (nval, internal->min_value, internal->max_value); \
|
|
|
|
\
|
|
|
|
return nval != oval; \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
static void \
|
|
|
|
property_##g_t##_class_init (GParamSpecClass *klass) \
|
|
|
|
{ \
|
|
|
|
klass->value_type = G_T; \
|
|
|
|
\
|
|
|
|
klass->value_validate = property_##g_t##_validate; \
|
|
|
|
klass->values_cmp = property_##g_t##_values_cmp; \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
static void \
|
|
|
|
property_##g_t##_init (GParamSpec *pspec) \
|
|
|
|
{ \
|
|
|
|
G##G_t##Property *property = (G##G_t##Property *) pspec; \
|
|
|
|
\
|
|
|
|
property->min_value = minVal; \
|
|
|
|
property->max_value = maxVal; \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
GType _g_##g_t##_property_get_type (void); /* forward declaration for -Wmissing-prototypes */ \
|
|
|
|
\
|
|
|
|
GType \
|
|
|
|
_g_##g_t##_property_get_type (void) \
|
|
|
|
{ \
|
|
|
|
static volatile gsize pspec_type_id__volatile = 0; \
|
|
|
|
\
|
|
|
|
if (g_once_init_enter (&pspec_type_id__volatile)) \
|
|
|
|
{ \
|
|
|
|
const GTypeInfo info = { \
|
|
|
|
sizeof (GParamSpecClass), \
|
|
|
|
NULL, NULL, \
|
|
|
|
(GClassInitFunc) property_##g_t##_class_init, \
|
|
|
|
NULL, NULL, \
|
|
|
|
sizeof (G##G_t##Property), \
|
|
|
|
0, \
|
|
|
|
(GInstanceInitFunc) property_##g_t##_init, \
|
|
|
|
}; \
|
|
|
|
\
|
|
|
|
GType pspec_type_id = \
|
|
|
|
g_type_register_static (G_TYPE_PROPERTY, \
|
|
|
|
g_intern_static_string ("G" #G_t "Property"), \
|
|
|
|
&info, 0); \
|
|
|
|
\
|
|
|
|
g_once_init_leave (&pspec_type_id__volatile, pspec_type_id); \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
return pspec_type_id__volatile; \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
GParamSpec * \
|
|
|
|
g_##g_t##_property_new (const gchar *name, \
|
|
|
|
GPropertyFlags flags, \
|
|
|
|
gssize offset, \
|
|
|
|
GProperty##G_t##Set setter, \
|
|
|
|
GProperty##G_t##Get getter) \
|
|
|
|
{ \
|
|
|
|
GProperty *prop; \
|
|
|
|
G##G_t##Property *internal; \
|
|
|
|
\
|
|
|
|
g_return_val_if_fail (name != NULL, NULL); \
|
|
|
|
\
|
|
|
|
if (setter == NULL && getter == NULL) \
|
|
|
|
g_return_val_if_fail (offset >= 0, NULL); \
|
2012-11-12 19:37:56 +00:00
|
|
|
if (setter == NULL) \
|
|
|
|
flags |= G_PROPERTY_DIRECT_SET; \
|
|
|
|
if (getter == NULL) \
|
|
|
|
flags |= G_PROPERTY_DIRECT_GET; \
|
2011-04-22 14:08:11 +01:00
|
|
|
\
|
|
|
|
prop = g_param_spec_internal (_g_##g_t##_property_get_type (), \
|
|
|
|
name, NULL, NULL, \
|
|
|
|
property_flags_to_param_flags (flags)); \
|
|
|
|
\
|
|
|
|
prop->flags = flags; \
|
|
|
|
\
|
|
|
|
G_PARAM_SPEC (prop)->value_type = G_T; \
|
|
|
|
\
|
|
|
|
prop->field_offset = offset; \
|
|
|
|
\
|
|
|
|
prop->is_installed = FALSE; \
|
|
|
|
\
|
|
|
|
prop->type_size = sizeof (c_t); \
|
|
|
|
\
|
|
|
|
internal = (G##G_t##Property *) prop; \
|
|
|
|
internal->setter = setter; \
|
|
|
|
internal->getter = getter; \
|
|
|
|
\
|
|
|
|
return G_PARAM_SPEC (prop); \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
static inline void \
|
|
|
|
g_##g_t##_property_set_range (GProperty *property, \
|
|
|
|
c_t min_value, \
|
|
|
|
c_t max_value) \
|
|
|
|
{ \
|
|
|
|
if (min_value > max_value) \
|
|
|
|
{ \
|
|
|
|
g_critical (G_STRLOC ": Invalid range for " #g_t " property '%s'", \
|
|
|
|
G_PARAM_SPEC (property)->name); \
|
|
|
|
return; \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
((G##G_t##Property *) property)->min_value = min_value; \
|
|
|
|
((G##G_t##Property *) property)->max_value = max_value; \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
static inline void \
|
|
|
|
g_##g_t##_property_get_range (GProperty *property, \
|
|
|
|
c_t *min_value, \
|
|
|
|
c_t *max_value) \
|
|
|
|
{ \
|
|
|
|
*min_value = ((G##G_t##Property *) property)->min_value; \
|
|
|
|
*max_value = ((G##G_t##Property *) property)->max_value; \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
static inline gboolean \
|
|
|
|
g_##g_t##_property_validate (GProperty *property, \
|
|
|
|
c_t value) \
|
|
|
|
{ \
|
|
|
|
G##G_t##Property *internal = (G##G_t##Property *) property; \
|
|
|
|
\
|
|
|
|
if (value >= internal->min_value && \
|
|
|
|
value <= internal->max_value) \
|
|
|
|
return TRUE; \
|
|
|
|
\
|
|
|
|
return FALSE; \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
static inline gboolean \
|
|
|
|
g_##g_t##_property_set_value (GProperty *property, \
|
|
|
|
gpointer gobject, \
|
|
|
|
c_t value) \
|
|
|
|
{ \
|
|
|
|
gboolean retval; \
|
|
|
|
\
|
|
|
|
if ((property->flags & G_PROPERTY_WRITABLE) == 0) \
|
|
|
|
{ \
|
|
|
|
g_critical ("The property '%s' of object '%s' is not writable", \
|
|
|
|
G_PARAM_SPEC (property)->name, \
|
|
|
|
G_OBJECT_TYPE_NAME (gobject)); \
|
|
|
|
return FALSE; \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
if (!g_##g_t##_property_validate (property, value)) \
|
|
|
|
{ \
|
|
|
|
g_warning ("The value for the property '%s' of object '%s' is out of the valid range", \
|
|
|
|
G_PARAM_SPEC (property)->name, \
|
|
|
|
G_OBJECT_TYPE_NAME (gobject)); \
|
|
|
|
return FALSE; \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
if (((G##G_t##Property *) property)->setter != NULL) \
|
|
|
|
{ \
|
|
|
|
property_lock_internal (property, gobject); \
|
|
|
|
\
|
|
|
|
retval = ((G##G_t##Property *) property)->setter (gobject, value); \
|
|
|
|
\
|
|
|
|
property_unlock_internal (property, gobject); \
|
|
|
|
\
|
|
|
|
if (retval) \
|
|
|
|
g_object_notify_by_pspec (gobject, (GParamSpec *) property); \
|
|
|
|
} \
|
|
|
|
else if (property->field_offset >= 0) \
|
|
|
|
{ \
|
|
|
|
gpointer priv_p, field_p; \
|
|
|
|
\
|
|
|
|
property_lock_internal (property, gobject); \
|
|
|
|
\
|
|
|
|
priv_p = get_private_pointer (gobject, property->priv_offset); \
|
|
|
|
field_p = G_STRUCT_MEMBER_P (priv_p, property->field_offset); \
|
|
|
|
\
|
|
|
|
if ((* (c_t *) field_p) == value) \
|
|
|
|
{ \
|
|
|
|
property_unlock_internal (property, gobject); \
|
|
|
|
return FALSE; \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
(* (c_t *) field_p) = value; \
|
|
|
|
\
|
|
|
|
property_unlock_internal (property, gobject); \
|
|
|
|
\
|
|
|
|
g_object_notify_by_pspec (gobject, (GParamSpec *) property); \
|
|
|
|
\
|
|
|
|
retval = TRUE; \
|
|
|
|
} \
|
|
|
|
else \
|
|
|
|
{ \
|
|
|
|
g_critical (G_STRLOC ": No setter function or field offset specified " \
|
|
|
|
"for property '%s'", \
|
|
|
|
G_PARAM_SPEC (property)->name); \
|
|
|
|
\
|
|
|
|
retval = FALSE; \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
return retval; \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
static inline c_t \
|
|
|
|
g_##g_t##_property_get_value (GProperty *property, \
|
|
|
|
gpointer gobject) \
|
|
|
|
{ \
|
|
|
|
if ((property->flags & G_PROPERTY_READABLE) == 0) \
|
|
|
|
{ \
|
|
|
|
g_critical ("The property '%s' of object '%s' is not readable", \
|
|
|
|
G_PARAM_SPEC (property)->name, \
|
|
|
|
G_OBJECT_TYPE_NAME (gobject)); \
|
|
|
|
return FALSE; \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
if (((G##G_t##Property *) property)->getter != NULL) \
|
|
|
|
{ \
|
|
|
|
return ((G##G_t##Property *) property)->getter (gobject); \
|
|
|
|
} \
|
|
|
|
else if (property->field_offset >= 0) \
|
|
|
|
{ \
|
|
|
|
gpointer priv_p, field_p; \
|
|
|
|
\
|
|
|
|
priv_p = get_private_pointer (gobject, property->priv_offset); \
|
|
|
|
field_p = G_STRUCT_MEMBER_P (priv_p, property->field_offset); \
|
|
|
|
\
|
|
|
|
return (* (c_t *) field_p); \
|
|
|
|
} \
|
|
|
|
else \
|
|
|
|
{ \
|
|
|
|
g_critical (G_STRLOC ": No setter function or field offset specified " \
|
|
|
|
"for property '%s'", \
|
|
|
|
G_PARAM_SPEC (property)->name); \
|
|
|
|
return defVal; \
|
|
|
|
} \
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
g_property_default_lock (GProperty *property,
|
|
|
|
gpointer gobject)
|
|
|
|
{
|
|
|
|
gpointer bit_lock_p;
|
|
|
|
|
|
|
|
bit_lock_p = g_object_get_qdata (gobject, property->prop_id);
|
|
|
|
if (bit_lock_p == NULL)
|
|
|
|
{
|
|
|
|
bit_lock_p = g_new0 (gint, 1);
|
|
|
|
g_object_set_qdata_full (gobject, property->prop_id, bit_lock_p, g_free);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_bit_lock (bit_lock_p, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
g_property_default_unlock (GProperty *property,
|
|
|
|
gpointer gobject)
|
|
|
|
{
|
|
|
|
gpointer bit_lock_p;
|
|
|
|
|
|
|
|
bit_lock_p = g_object_get_qdata (gobject, property->prop_id);
|
|
|
|
if (bit_lock_p == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
g_bit_unlock (bit_lock_p, 0);
|
|
|
|
g_object_set_qdata (gobject, property->prop_id, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
property_lock_internal (GProperty *property,
|
|
|
|
gpointer gobject)
|
|
|
|
{
|
|
|
|
if (G_LIKELY ((property->flags & G_PROPERTY_ATOMIC) == 0))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (property->lock_func != NULL)
|
|
|
|
property->lock_func (property, gobject);
|
|
|
|
else
|
|
|
|
g_property_default_lock (property, gobject);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
property_unlock_internal (GProperty *property,
|
|
|
|
gpointer gobject)
|
|
|
|
{
|
|
|
|
if (G_LIKELY ((property->flags & G_PROPERTY_ATOMIC) == 0))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (property->unlock_func != NULL)
|
|
|
|
property->unlock_func (property, gobject);
|
|
|
|
else
|
|
|
|
g_property_default_unlock (property, gobject);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline gpointer
|
|
|
|
get_private_pointer (gpointer instance,
|
|
|
|
gssize offset)
|
|
|
|
{
|
|
|
|
gpointer priv_p;
|
|
|
|
|
|
|
|
if (offset < 0)
|
|
|
|
priv_p = g_type_instance_get_private (instance, G_OBJECT_TYPE (instance));
|
|
|
|
else
|
|
|
|
priv_p = G_STRUCT_MEMBER_P (instance, offset);
|
|
|
|
|
|
|
|
return priv_p;
|
|
|
|
}
|
|
|
|
|
|
|
|
static GParamFlags
|
|
|
|
property_flags_to_param_flags (GPropertyFlags flags)
|
|
|
|
{
|
|
|
|
GParamFlags retval = 0;
|
|
|
|
|
|
|
|
if (flags & G_PROPERTY_READABLE)
|
|
|
|
retval |= G_PARAM_READABLE;
|
|
|
|
|
|
|
|
if (flags & G_PROPERTY_WRITABLE)
|
|
|
|
retval |= G_PARAM_WRITABLE;
|
|
|
|
|
|
|
|
if (flags & G_PROPERTY_DEPRECATED)
|
|
|
|
retval |= G_PARAM_DEPRECATED;
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2012-11-12 19:37:56 +00:00
|
|
|
gpointer
|
|
|
|
g_property_get_field (GProperty *property,
|
|
|
|
gpointer gobject)
|
|
|
|
{
|
|
|
|
gpointer priv_p;
|
|
|
|
|
|
|
|
g_return_val_if_fail (G_IS_PROPERTY (property), NULL);
|
|
|
|
g_return_val_if_fail (G_IS_OBJECT (gobject), NULL);
|
|
|
|
g_return_val_if_fail (property->field_offset >= 0, NULL);
|
|
|
|
|
|
|
|
priv_p = get_private_pointer (gobject, property->priv_offset);
|
|
|
|
if (priv_p == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return G_STRUCT_MEMBER_P (priv_p, property->field_offset);
|
|
|
|
}
|
|
|
|
|
2011-04-22 14:08:11 +01:00
|
|
|
/* forward declaration */
|
|
|
|
static void property_set_default (GParamSpec *pspec,
|
|
|
|
GValue *value);
|
|
|
|
|
|
|
|
static const GValue *
|
|
|
|
property_get_default_for_type (GProperty *property,
|
|
|
|
GType gtype)
|
|
|
|
{
|
|
|
|
GParamSpec *pspec = (GParamSpec *) property;
|
|
|
|
|
|
|
|
if (gtype == G_TYPE_INVALID)
|
|
|
|
{
|
|
|
|
if (G_UNLIKELY (property->prop_id == 0))
|
|
|
|
{
|
|
|
|
gchar *lock_name = g_strconcat ("__g_property_id_", pspec->name, NULL);
|
|
|
|
|
|
|
|
property->prop_id = g_quark_from_string (lock_name);
|
|
|
|
g_free (lock_name);
|
|
|
|
}
|
|
|
|
|
|
|
|
return g_param_spec_get_qdata (pspec, property->prop_id);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return g_param_spec_get_qdata (pspec, g_type_qname (gtype));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
value_unset_and_free (gpointer data)
|
|
|
|
{
|
|
|
|
GValue *value = data;
|
|
|
|
|
|
|
|
g_value_unset (value);
|
|
|
|
g_free (value);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
property_set_default_for_type (GProperty *property,
|
|
|
|
GType gtype,
|
|
|
|
GValue *value)
|
|
|
|
{
|
|
|
|
GParamSpec *pspec = (GParamSpec *) property;
|
|
|
|
|
|
|
|
if (gtype == G_TYPE_INVALID)
|
|
|
|
{
|
|
|
|
if (G_UNLIKELY (property->prop_id == 0))
|
|
|
|
{
|
|
|
|
gchar *lock_name = g_strconcat ("__g_property_id_", pspec->name, NULL);
|
|
|
|
|
|
|
|
property->prop_id = g_quark_from_string (lock_name);
|
|
|
|
g_free (lock_name);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (g_param_spec_get_qdata (pspec, property->prop_id) != NULL)
|
|
|
|
{
|
|
|
|
g_critical (G_STRLOC ": The property '%s' already has a default "
|
|
|
|
"value. Use g_property_override_default() instead.",
|
|
|
|
pspec->name);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_param_spec_set_qdata_full (pspec, property->prop_id,
|
|
|
|
value,
|
|
|
|
value_unset_and_free);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
g_param_spec_set_qdata_full (pspec, g_type_qname (gtype),
|
|
|
|
value,
|
|
|
|
value_unset_and_free);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_boolean_property_new:
|
|
|
|
* @name: canonical name of the property
|
|
|
|
* @flags: flags for the property
|
|
|
|
* @offset: the offset in the private structure of the field
|
|
|
|
* that stores the property, or -1
|
|
|
|
* @setter: (allow-none): the setter function for the property
|
|
|
|
* @getter: (allow-none): the getter function for the property
|
|
|
|
*
|
|
|
|
* Creates a new #GProperty mapping to a boolean value.
|
|
|
|
*
|
|
|
|
* Return value: the newly created #GProperty
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
DEFINE_PROPERTY_INTEGER (Boolean, boolean, gboolean, G_TYPE_BOOLEAN, FALSE, FALSE, TRUE)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_int_property_new:
|
|
|
|
* @name: canonical name of the property
|
|
|
|
* @flags: flags for the property
|
|
|
|
* @offset: the offset in the private structure of the field
|
|
|
|
* that stores the property, or -1
|
|
|
|
* @setter: (allow-none): the setter function for the property, or %NULL
|
|
|
|
* @getter: (allow-none): the getter function for the property, or %NULL
|
|
|
|
*
|
|
|
|
* Creates a new #GProperty mapping to an integer value.
|
|
|
|
*
|
|
|
|
* The default range of valid values is [ %G_MININT, %G_MAXINT ].
|
|
|
|
*
|
|
|
|
* If you require a specific integer size, use g_int8_property_new(),
|
|
|
|
* g_int16_property_new(), g_int32_property_new() or g_int64_property_new().
|
|
|
|
*
|
|
|
|
* Return value: the newly created #GProperty
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
DEFINE_PROPERTY_INTEGER (Int, int, int, G_TYPE_INT, 0, G_MININT, G_MAXINT)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_int8_property_new:
|
|
|
|
* @name: canonical name of the property
|
|
|
|
* @flags: flags for the property
|
|
|
|
* @offset: the offset in the private structure of the field
|
|
|
|
* that stores the property, or -1
|
|
|
|
* @setter: (allow-none): the setter function for the property, or %NULL
|
|
|
|
* @getter: (allow-none): the getter function for the property, or %NULL
|
|
|
|
*
|
|
|
|
* Creates a new #GProperty mapping to an 8 bits integer value.
|
|
|
|
*
|
|
|
|
* The default range of valid values is [ %G_MININT8, %G_MAXINT8 ].
|
|
|
|
*
|
|
|
|
* Return value: the newly created #GProperty
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
DEFINE_PROPERTY_INTEGER (Int8, int8, gint8, G_TYPE_INT, 0, G_MININT8, G_MAXINT8)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_int16_property_new:
|
|
|
|
* @name: canonical name of the property
|
|
|
|
* @flags: flags for the property
|
|
|
|
* @offset: the offset in the private structure of the field
|
|
|
|
* that stores the property, or -1
|
|
|
|
* @setter: (allow-none): the setter function for the property, or %NULL
|
|
|
|
* @getter: (allow-none): the getter function for the property, or %NULL
|
|
|
|
*
|
|
|
|
* Creates a new #GProperty mapping to a 16 bits integer value.
|
|
|
|
*
|
|
|
|
* The default range of valid values is [ %G_MININT16, %G_MAXINT16 ].
|
|
|
|
*
|
|
|
|
* Return value: the newly created #GProperty
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
DEFINE_PROPERTY_INTEGER (Int16, int16, gint16, G_TYPE_INT, 0, G_MININT16, G_MAXINT16)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_int32_property_new:
|
|
|
|
* @name: canonical name of the property
|
|
|
|
* @flags: flags for the property
|
|
|
|
* @offset: the offset in the private structure of the field
|
|
|
|
* that stores the property, or -1
|
|
|
|
* @setter: (allow-none): the setter function for the property, or %NULL
|
|
|
|
* @getter: (allow-none): the getter function for the property, or %NULL
|
|
|
|
*
|
|
|
|
* Creates a new #GProperty mapping to a 32 bits integer value.
|
|
|
|
*
|
|
|
|
* The default range of valid values is [ %G_MININT32, %G_MAXINT32 ].
|
|
|
|
*
|
|
|
|
* Return value: the newly created #GProperty
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
DEFINE_PROPERTY_INTEGER (Int32, int32, gint32, G_TYPE_INT, 0, G_MININT32, G_MAXINT32)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_int64_property_new:
|
|
|
|
* @name: canonical name of the property
|
|
|
|
* @flags: flags for the property
|
|
|
|
* @offset: the offset in the private structure of the field
|
|
|
|
* that stores the property, or -1
|
|
|
|
* @setter: (allow-none): the setter function for the property, or %NULL
|
|
|
|
* @getter: (allow-none): the getter function for the property, or %NULL
|
|
|
|
*
|
|
|
|
* Creates a new #GProperty mapping to a 64 bits integer value.
|
|
|
|
*
|
|
|
|
* The default range of valid values is [ %G_MININT64, %G_MAXINT64 ].
|
|
|
|
*
|
|
|
|
* Return value: the newly created #GProperty
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
DEFINE_PROPERTY_INTEGER (Int64, int64, gint64, G_TYPE_INT64, 0, G_MININT64, G_MAXINT64)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_long_property_new:
|
|
|
|
* @name: canonical name of the property
|
|
|
|
* @flags: flags for the property
|
|
|
|
* @offset: the offset in the private structure of the field
|
|
|
|
* that stores the property, or -1
|
|
|
|
* @setter: (allow-none): the setter function for the property, or %NULL
|
|
|
|
* @getter: (allow-none): the getter function for the property, or %NULL
|
|
|
|
*
|
|
|
|
* Creates a new #GProperty mapping to a long integer value.
|
|
|
|
*
|
|
|
|
* The default range of valid values is [ %G_MINLONG, %G_MAXLONG ].
|
|
|
|
*
|
|
|
|
* Return value: the newly created #GProperty
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
DEFINE_PROPERTY_INTEGER (Long, long, long, G_TYPE_LONG, 0, G_MINLONG, G_MAXLONG)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_uint_property_new:
|
|
|
|
* @name: canonical name of the property
|
|
|
|
* @flags: flags for the property
|
|
|
|
* @offset: the offset in the private structure of the field
|
|
|
|
* that stores the property, or -1
|
|
|
|
* @setter: (allow-none): the setter function for the property, or %NULL
|
|
|
|
* @getter: (allow-none): the getter function for the property, or %NULL
|
|
|
|
*
|
|
|
|
* Creates a new #GProperty mapping to an unsigned integer value.
|
|
|
|
*
|
|
|
|
* The default range of valid values is [ 0, %G_MAXUINT ].
|
|
|
|
*
|
|
|
|
* If you require a specific integer size, use g_uint8_property_new(),
|
|
|
|
* g_uint16_property_new(), g_uint32_property_new() or g_uint64_property_new().
|
|
|
|
*
|
|
|
|
* Return value: the newly created #GProperty
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
DEFINE_PROPERTY_INTEGER (UInt, uint, guint, G_TYPE_UINT, 0, 0, G_MAXUINT)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_uint8_property_new:
|
|
|
|
* @name: canonical name of the property
|
|
|
|
* @flags: flags for the property
|
|
|
|
* @offset: the offset in the private structure of the field
|
|
|
|
* that stores the property, or -1
|
|
|
|
* @setter: (allow-none): the setter function for the property, or %NULL
|
|
|
|
* @getter: (allow-none): the getter function for the property, or %NULL
|
|
|
|
*
|
|
|
|
* Creates a new #GProperty mapping to an unsigned 8 bits integer value.
|
|
|
|
*
|
|
|
|
* The default range of valid values is [ 0, %G_MAXUINT8 ].
|
|
|
|
*
|
|
|
|
* Return value: the newly created #GProperty
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
DEFINE_PROPERTY_INTEGER (UInt8, uint8, guint8, G_TYPE_UINT, 0, 0, G_MAXUINT8)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_uint16_property_new:
|
|
|
|
* @name: canonical name of the property
|
|
|
|
* @flags: flags for the property
|
|
|
|
* @offset: the offset in the private structure of the field
|
|
|
|
* that stores the property, or -1
|
|
|
|
* @setter: (allow-none): the setter function for the property, or %NULL
|
|
|
|
* @getter: (allow-none): the getter function for the property, or %NULL
|
|
|
|
*
|
|
|
|
* Creates a new #GProperty mapping to an unsigned 16 bits integer value.
|
|
|
|
*
|
|
|
|
* The default range of valid values is [ 0, %G_MAXUINT16 ].
|
|
|
|
*
|
|
|
|
* Return value: the newly created #GProperty
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
DEFINE_PROPERTY_INTEGER (UInt16, uint16, guint16, G_TYPE_UINT, 0, 0, G_MAXUINT16)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_uint32_property_new:
|
|
|
|
* @name: canonical name of the property
|
|
|
|
* @flags: flags for the property
|
|
|
|
* @offset: the offset in the private structure of the field
|
|
|
|
* that stores the property, or -1
|
|
|
|
* @setter: (allow-none): the setter function for the property, or %NULL
|
|
|
|
* @getter: (allow-none): the getter function for the property, or %NULL
|
|
|
|
*
|
|
|
|
* Creates a new #GProperty mapping to an unsigned 32 bits integer value.
|
|
|
|
*
|
|
|
|
* The default range of valid values is [ 0, %G_MAXUINT32 ].
|
|
|
|
*
|
|
|
|
* Return value: the newly created #GProperty
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
DEFINE_PROPERTY_INTEGER (UInt32, uint32, guint32, G_TYPE_UINT, 0, 0, G_MAXUINT32)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_uint64_property_new:
|
|
|
|
* @name: canonical name of the property
|
|
|
|
* @flags: flags for the property
|
|
|
|
* @offset: the offset in the private structure of the field
|
|
|
|
* that stores the property, or -1
|
|
|
|
* @setter: (allow-none): the setter function for the property, or %NULL
|
|
|
|
* @getter: (allow-none): the getter function for the property, or %NULL
|
|
|
|
*
|
|
|
|
* Creates a new #GProperty mapping to an unsigned 64 bits integer value.
|
|
|
|
*
|
|
|
|
* The default range of valid values is [ 0, %G_MAXUINT64 ].
|
|
|
|
*
|
|
|
|
* Return value: the newly created #GProperty
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
DEFINE_PROPERTY_INTEGER (UInt64, uint64, guint64, G_TYPE_UINT64, 0, 0, G_MAXUINT64)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_ulong_property_new:
|
|
|
|
* @name: canonical name of the property
|
|
|
|
* @flags: flags for the property
|
|
|
|
* @offset: the offset in the private structure of the field
|
|
|
|
* that stores the property, or -1
|
|
|
|
* @setter: (allow-none): the setter function for the property, or %NULL
|
|
|
|
* @getter: (allow-none): the getter function for the property, or %NULL
|
|
|
|
*
|
|
|
|
* Creates a new #GProperty mapping to an unsigned long integer value.
|
|
|
|
*
|
|
|
|
* The default range of valid values is [ 0, %G_MAXULONG ].
|
|
|
|
*
|
|
|
|
* Return value: the newly created #GProperty
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
DEFINE_PROPERTY_INTEGER (ULong, ulong, gulong, G_TYPE_ULONG, 0, 0, G_MAXULONG)
|
|
|
|
|
|
|
|
/*
|
|
|
|
* GEnum
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* forward declaration for -Wmissing-prototypes */
|
|
|
|
GType _g_enum_property_get_type (void);
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
GProperty parent;
|
|
|
|
|
|
|
|
GEnumClass *e_class;
|
|
|
|
|
|
|
|
GPropertyEnumSet setter;
|
|
|
|
GPropertyEnumGet getter;
|
|
|
|
} GEnumProperty;
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
property_enum_validate (GParamSpec *pspec,
|
|
|
|
GValue *value)
|
|
|
|
{
|
|
|
|
GEnumProperty *property = (GEnumProperty *) pspec;
|
|
|
|
glong oval = value->data[0].v_long;
|
|
|
|
|
|
|
|
if (property->e_class == NULL ||
|
|
|
|
g_enum_get_value (property->e_class, value->data[0].v_long) == NULL)
|
|
|
|
property_set_default (pspec, value);
|
|
|
|
|
|
|
|
return value->data[0].v_long != oval;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
property_enum_finalize (GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
GEnumProperty *property = (GEnumProperty *) pspec;
|
|
|
|
GParamSpecClass *parent_class =
|
|
|
|
g_type_class_peek (g_type_parent (_g_enum_property_get_type ()));
|
|
|
|
|
|
|
|
if (property->e_class)
|
|
|
|
{
|
|
|
|
g_type_class_unref (property->e_class);
|
|
|
|
property->e_class = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
parent_class->finalize (pspec);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
property_enum_class_init (GParamSpecClass *klass)
|
|
|
|
{
|
|
|
|
klass->value_type = G_TYPE_FLAGS;
|
|
|
|
|
|
|
|
klass->value_validate = property_enum_validate;
|
|
|
|
|
|
|
|
klass->finalize = property_enum_finalize;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
property_enum_init (GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
GType
|
|
|
|
_g_enum_property_get_type (void)
|
|
|
|
{
|
|
|
|
static volatile gsize pspec_type_id__volatile = 0;
|
|
|
|
|
|
|
|
if (g_once_init_enter (&pspec_type_id__volatile))
|
|
|
|
{
|
|
|
|
const GTypeInfo info = {
|
|
|
|
sizeof (GParamSpecClass),
|
|
|
|
NULL, NULL,
|
|
|
|
(GClassInitFunc) property_enum_class_init,
|
|
|
|
NULL, NULL,
|
|
|
|
sizeof (GEnumProperty),
|
|
|
|
0,
|
|
|
|
(GInstanceInitFunc) property_enum_init,
|
|
|
|
};
|
|
|
|
|
|
|
|
GType pspec_type_id =
|
|
|
|
g_type_register_static (G_TYPE_PROPERTY,
|
|
|
|
g_intern_static_string ("GEnumProperty"),
|
|
|
|
&info, 0);
|
|
|
|
|
|
|
|
g_once_init_leave (&pspec_type_id__volatile, pspec_type_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
return pspec_type_id__volatile;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_enum_property_new:
|
|
|
|
* @name: canonical name of the property
|
|
|
|
* @enum: enum for the property
|
|
|
|
* @offset: the offset in the private structure of the field
|
|
|
|
* that stores the property, or -1
|
|
|
|
* @setter: (allow-none): the setter function for the property
|
|
|
|
* @getter: (allow-none): the getter function for the property
|
|
|
|
*
|
|
|
|
* Creates a new #GProperty mapping to a enumeration type registered
|
|
|
|
* as a sub-type of %G_TYPE_ENUM.
|
|
|
|
*
|
|
|
|
* You should use g_property_set_prerequisite() to set the type
|
|
|
|
* of the enumeration for validation; if the pre-requisite is unset,
|
|
|
|
* setting or getting this property will result in a warning.
|
|
|
|
*
|
|
|
|
* Return value: the newly created #GProperty
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
GParamSpec *
|
|
|
|
g_enum_property_new (const gchar *name,
|
|
|
|
GPropertyFlags flags,
|
|
|
|
gssize offset,
|
|
|
|
GPropertyEnumSet setter,
|
|
|
|
GPropertyEnumGet getter)
|
|
|
|
{
|
|
|
|
GProperty *prop;
|
|
|
|
GEnumProperty *internal;
|
|
|
|
|
|
|
|
if (setter == NULL && getter == NULL)
|
|
|
|
g_return_val_if_fail (offset >= 0, NULL);
|
2012-11-12 19:37:56 +00:00
|
|
|
if (setter == NULL)
|
|
|
|
flags |= G_PROPERTY_DIRECT_SET;
|
|
|
|
if (getter == NULL)
|
|
|
|
flags |= G_PROPERTY_DIRECT_GET;
|
2011-04-22 14:08:11 +01:00
|
|
|
|
|
|
|
prop = g_param_spec_internal (_g_enum_property_get_type (),
|
|
|
|
name, NULL, NULL,
|
|
|
|
property_flags_to_param_flags (flags));
|
|
|
|
|
|
|
|
prop->flags = flags;
|
|
|
|
|
|
|
|
G_PARAM_SPEC (prop)->value_type = G_TYPE_ENUM;
|
|
|
|
|
|
|
|
prop->field_offset = offset;
|
|
|
|
|
|
|
|
prop->is_installed = FALSE;
|
|
|
|
|
|
|
|
prop->type_size = sizeof (glong);
|
|
|
|
|
|
|
|
internal = (GEnumProperty *) prop;
|
|
|
|
internal->setter = setter;
|
|
|
|
internal->getter = getter;
|
|
|
|
|
|
|
|
return G_PARAM_SPEC (prop);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline gboolean
|
|
|
|
g_enum_property_validate (GProperty *property,
|
|
|
|
glong value)
|
|
|
|
{
|
|
|
|
GEnumProperty *e_prop = (GEnumProperty *) property;
|
|
|
|
|
|
|
|
if (e_prop->e_class != NULL)
|
|
|
|
{
|
|
|
|
if (g_enum_get_value (e_prop->e_class, value) != NULL)
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline gboolean
|
|
|
|
g_enum_property_set_value (GProperty *property,
|
|
|
|
gpointer gobject,
|
|
|
|
glong value)
|
|
|
|
{
|
|
|
|
gboolean retval = FALSE;
|
|
|
|
|
|
|
|
if ((property->flags & G_PROPERTY_WRITABLE) == 0)
|
|
|
|
{
|
|
|
|
g_critical ("The property '%s' of object '%s' is not writable",
|
|
|
|
G_PARAM_SPEC (property)->name,
|
|
|
|
G_OBJECT_TYPE_NAME (gobject));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!g_enum_property_validate (property, value))
|
|
|
|
{
|
|
|
|
g_warning ("The value for the property '%s' of object '%s' is out of the valid range",
|
|
|
|
G_PARAM_SPEC (property)->name,
|
|
|
|
G_OBJECT_TYPE_NAME (gobject));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (((GEnumProperty *) property)->setter != NULL)
|
|
|
|
{
|
|
|
|
property_lock_internal (property, gobject);
|
|
|
|
|
|
|
|
retval = ((GEnumProperty *) property)->setter (gobject, value);
|
|
|
|
|
|
|
|
property_unlock_internal (property, gobject);
|
|
|
|
|
|
|
|
if (retval)
|
|
|
|
g_object_notify_by_pspec (gobject, (GParamSpec *) property);
|
|
|
|
}
|
|
|
|
else if (property->field_offset >= 0)
|
|
|
|
{
|
|
|
|
gpointer priv_p, field_p;
|
|
|
|
|
|
|
|
property_lock_internal (property, gobject);
|
|
|
|
|
|
|
|
priv_p = get_private_pointer (gobject, property->priv_offset);
|
|
|
|
field_p = G_STRUCT_MEMBER_P (priv_p, property->field_offset);
|
|
|
|
|
|
|
|
if ((* (gulong *) field_p) == value)
|
|
|
|
{
|
|
|
|
property_unlock_internal (property, gobject);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
(* (gulong *) field_p) = value;
|
|
|
|
|
|
|
|
property_unlock_internal (property, gobject);
|
|
|
|
|
|
|
|
g_object_notify_by_pspec (gobject, (GParamSpec *) property);
|
|
|
|
|
|
|
|
retval = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
g_critical (G_STRLOC ": No setter function or field offset specified "
|
|
|
|
"for property '%s'",
|
|
|
|
G_PARAM_SPEC (property)->name);
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline gulong
|
|
|
|
g_enum_property_get_value (GProperty *property,
|
|
|
|
gpointer gobject)
|
|
|
|
{
|
|
|
|
if ((property->flags & G_PROPERTY_READABLE) == 0)
|
|
|
|
{
|
|
|
|
g_critical ("The property '%s' of object '%s' is not readable",
|
|
|
|
G_PARAM_SPEC (property)->name,
|
|
|
|
G_OBJECT_TYPE_NAME (gobject));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (((GEnumProperty *) property)->getter != NULL)
|
|
|
|
{
|
|
|
|
return ((GEnumProperty *) property)->getter (gobject);
|
|
|
|
}
|
|
|
|
else if (property->field_offset >= 0)
|
|
|
|
{
|
|
|
|
gpointer priv_p, field_p;
|
|
|
|
|
|
|
|
priv_p = get_private_pointer (gobject, property->priv_offset);
|
|
|
|
field_p = G_STRUCT_MEMBER_P (priv_p, property->field_offset);
|
|
|
|
|
|
|
|
return (* (gulong *) field_p);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_critical (G_STRLOC ": No getter function or field offset specified "
|
|
|
|
"for property '%s'",
|
|
|
|
G_PARAM_SPEC (property)->name);
|
|
|
|
return 0.0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* GFlags
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* forward declaration for -Wmissing-prototypes */
|
|
|
|
GType _g_flags_property_get_type (void);
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
GProperty parent;
|
|
|
|
|
|
|
|
GFlagsClass *f_class;
|
|
|
|
|
|
|
|
GPropertyFlagsSet setter;
|
|
|
|
GPropertyFlagsGet getter;
|
|
|
|
} GFlagsProperty;
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
property_flags_validate (GParamSpec *pspec,
|
|
|
|
GValue *value)
|
|
|
|
{
|
|
|
|
GFlagsProperty *property = (GFlagsProperty *) pspec;
|
|
|
|
gulong oval = value->data[0].v_ulong;
|
|
|
|
|
|
|
|
if (property->f_class != NULL)
|
|
|
|
value->data[0].v_ulong &= property->f_class->mask;
|
|
|
|
else
|
|
|
|
property_set_default (pspec, value);
|
|
|
|
|
|
|
|
return value->data[0].v_ulong != oval;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
property_flags_finalize (GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
GFlagsProperty *property = (GFlagsProperty *) pspec;
|
|
|
|
GParamSpecClass *parent_class =
|
|
|
|
g_type_class_peek (g_type_parent (_g_flags_property_get_type ()));
|
|
|
|
|
|
|
|
if (property->f_class)
|
|
|
|
{
|
|
|
|
g_type_class_unref (property->f_class);
|
|
|
|
property->f_class = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
parent_class->finalize (pspec);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
property_flags_class_init (GParamSpecClass *klass)
|
|
|
|
{
|
|
|
|
klass->value_type = G_TYPE_FLAGS;
|
|
|
|
|
|
|
|
klass->value_validate = property_flags_validate;
|
|
|
|
|
|
|
|
klass->finalize = property_flags_finalize;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
property_flags_init (GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
GType
|
|
|
|
_g_flags_property_get_type (void)
|
|
|
|
{
|
|
|
|
static volatile gsize pspec_type_id__volatile = 0;
|
|
|
|
|
|
|
|
if (g_once_init_enter (&pspec_type_id__volatile))
|
|
|
|
{
|
|
|
|
const GTypeInfo info = {
|
|
|
|
sizeof (GParamSpecClass),
|
|
|
|
NULL, NULL,
|
|
|
|
(GClassInitFunc) property_flags_class_init,
|
|
|
|
NULL, NULL,
|
|
|
|
sizeof (GFlagsProperty),
|
|
|
|
0,
|
|
|
|
(GInstanceInitFunc) property_flags_init,
|
|
|
|
};
|
|
|
|
|
|
|
|
GType pspec_type_id =
|
|
|
|
g_type_register_static (G_TYPE_PROPERTY,
|
|
|
|
g_intern_static_string ("GFlagsProperty"),
|
|
|
|
&info, 0);
|
|
|
|
|
|
|
|
g_once_init_leave (&pspec_type_id__volatile, pspec_type_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
return pspec_type_id__volatile;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_flags_property_new:
|
|
|
|
* @name: canonical name of the property
|
|
|
|
* @flags: flags for the property
|
|
|
|
* @offset: the offset in the private structure of the field
|
|
|
|
* that stores the property, or -1
|
|
|
|
* @setter: (allow-none): the setter function for the property
|
|
|
|
* @getter: (allow-none): the getter function for the property
|
|
|
|
*
|
|
|
|
* Creates a new #GProperty mapping to a flag type registered
|
|
|
|
* as a sub-type of %G_TYPE_FLAGS.
|
|
|
|
*
|
|
|
|
* You should use g_property_set_prerequisite() to set the type
|
|
|
|
* of the flags for validation; if the pre-requisite is unset,
|
|
|
|
* setting or getting this property will result in a warning.
|
|
|
|
*
|
|
|
|
* Return value: the newly created #GProperty
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
GParamSpec *
|
|
|
|
g_flags_property_new (const gchar *name,
|
|
|
|
GPropertyFlags flags,
|
|
|
|
gssize offset,
|
|
|
|
GPropertyFlagsSet setter,
|
|
|
|
GPropertyFlagsGet getter)
|
|
|
|
{
|
|
|
|
GProperty *prop;
|
|
|
|
GFlagsProperty *internal;
|
|
|
|
|
|
|
|
if (setter == NULL && getter == NULL)
|
|
|
|
g_return_val_if_fail (offset >= 0, NULL);
|
2012-11-12 19:37:56 +00:00
|
|
|
if (setter == NULL)
|
|
|
|
flags |= G_PROPERTY_DIRECT_SET;
|
|
|
|
if (getter == NULL)
|
|
|
|
flags |= G_PROPERTY_DIRECT_GET;
|
2011-04-22 14:08:11 +01:00
|
|
|
|
|
|
|
prop = g_param_spec_internal (_g_flags_property_get_type (),
|
|
|
|
name, NULL, NULL,
|
|
|
|
property_flags_to_param_flags (flags));
|
|
|
|
|
|
|
|
prop->flags = flags;
|
|
|
|
|
|
|
|
G_PARAM_SPEC (prop)->value_type = G_TYPE_FLAGS;
|
|
|
|
|
|
|
|
prop->field_offset = offset;
|
|
|
|
|
|
|
|
prop->is_installed = FALSE;
|
|
|
|
|
|
|
|
prop->type_size = sizeof (gulong);
|
|
|
|
|
|
|
|
internal = (GFlagsProperty *) prop;
|
|
|
|
internal->setter = setter;
|
|
|
|
internal->getter = getter;
|
|
|
|
|
|
|
|
return G_PARAM_SPEC (prop);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline gboolean
|
|
|
|
g_flags_property_validate (GProperty *property,
|
|
|
|
gulong value)
|
|
|
|
{
|
|
|
|
GFlagsProperty *f_prop = (GFlagsProperty *) property;
|
|
|
|
|
|
|
|
if (f_prop->f_class != NULL)
|
|
|
|
{
|
|
|
|
gulong masked_value = value;
|
|
|
|
|
|
|
|
masked_value &= f_prop->f_class->mask;
|
|
|
|
|
|
|
|
return masked_value == value;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline gboolean
|
|
|
|
g_flags_property_set_value (GProperty *property,
|
|
|
|
gpointer gobject,
|
|
|
|
gulong value)
|
|
|
|
{
|
|
|
|
gboolean retval = FALSE;
|
|
|
|
|
|
|
|
if ((property->flags & G_PROPERTY_WRITABLE) == 0)
|
|
|
|
{
|
|
|
|
g_critical ("The property '%s' of object '%s' is not writable",
|
|
|
|
G_PARAM_SPEC (property)->name,
|
|
|
|
G_OBJECT_TYPE_NAME (gobject));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!g_flags_property_validate (property, value))
|
|
|
|
{
|
|
|
|
g_warning ("The value for the property '%s' of object '%s' is out of the valid range",
|
|
|
|
G_PARAM_SPEC (property)->name,
|
|
|
|
G_OBJECT_TYPE_NAME (gobject));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (((GFlagsProperty *) property)->setter != NULL)
|
|
|
|
{
|
|
|
|
property_lock_internal (property, gobject);
|
|
|
|
|
|
|
|
retval = ((GFlagsProperty *) property)->setter (gobject, value);
|
|
|
|
|
|
|
|
property_unlock_internal (property, gobject);
|
|
|
|
|
|
|
|
if (retval)
|
|
|
|
g_object_notify_by_pspec (gobject, (GParamSpec *) property);
|
|
|
|
}
|
|
|
|
else if (property->field_offset >= 0)
|
|
|
|
{
|
|
|
|
gpointer priv_p, field_p;
|
|
|
|
|
|
|
|
property_lock_internal (property, gobject);
|
|
|
|
|
|
|
|
priv_p = get_private_pointer (gobject, property->priv_offset);
|
|
|
|
field_p = G_STRUCT_MEMBER_P (priv_p, property->field_offset);
|
|
|
|
|
|
|
|
if ((* (gulong *) field_p) == value)
|
|
|
|
{
|
|
|
|
property_unlock_internal (property, gobject);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
(* (gulong *) field_p) = value;
|
|
|
|
|
|
|
|
property_unlock_internal (property, gobject);
|
|
|
|
|
|
|
|
g_object_notify_by_pspec (gobject, (GParamSpec *) property);
|
|
|
|
|
|
|
|
retval = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
g_critical (G_STRLOC ": No setter function or field offset specified "
|
|
|
|
"for property '%s'",
|
|
|
|
G_PARAM_SPEC (property)->name);
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline gulong
|
|
|
|
g_flags_property_get_value (GProperty *property,
|
|
|
|
gpointer gobject)
|
|
|
|
{
|
|
|
|
if ((property->flags & G_PROPERTY_READABLE) == 0)
|
|
|
|
{
|
|
|
|
g_critical ("The property '%s' of object '%s' is not readable",
|
|
|
|
G_PARAM_SPEC (property)->name,
|
|
|
|
G_OBJECT_TYPE_NAME (gobject));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (((GFlagsProperty *) property)->getter != NULL)
|
|
|
|
{
|
|
|
|
return ((GFlagsProperty *) property)->getter (gobject);
|
|
|
|
}
|
|
|
|
else if (property->field_offset >= 0)
|
|
|
|
{
|
|
|
|
gpointer priv_p, field_p;
|
|
|
|
|
|
|
|
priv_p = get_private_pointer (gobject, property->priv_offset);
|
|
|
|
field_p = G_STRUCT_MEMBER_P (priv_p, property->field_offset);
|
|
|
|
|
|
|
|
return (* (gulong *) field_p);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_critical (G_STRLOC ": No getter function or field offset specified "
|
|
|
|
"for property '%s'",
|
|
|
|
G_PARAM_SPEC (property)->name);
|
|
|
|
return 0.0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* GFloat
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define G_FLOAT_EPSILON (1e-30)
|
|
|
|
|
|
|
|
/* forward declaration for -Wmissing-prototypes */
|
|
|
|
GType _g_float_property_get_type (void);
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
GProperty parent;
|
|
|
|
|
|
|
|
gfloat min_value;
|
|
|
|
gfloat max_value;
|
|
|
|
gfloat epsilon;
|
|
|
|
|
|
|
|
GPropertyFloatSet setter;
|
|
|
|
GPropertyFloatGet getter;
|
|
|
|
} GFloatProperty;
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
property_float_validate (GParamSpec *pspec,
|
|
|
|
GValue *value)
|
|
|
|
{
|
|
|
|
GFloatProperty *property = (GFloatProperty *) pspec;
|
|
|
|
gfloat oval = value->data[0].v_float;
|
|
|
|
|
|
|
|
value->data[0].v_float = CLAMP (value->data[0].v_float,
|
|
|
|
property->min_value,
|
|
|
|
property->max_value);
|
|
|
|
|
|
|
|
return value->data[0].v_float != oval;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
property_float_values_cmp (GParamSpec *pspec,
|
|
|
|
const GValue *value1,
|
|
|
|
const GValue *value2)
|
|
|
|
{
|
|
|
|
gfloat epsilon = ((GFloatProperty *) pspec)->epsilon;
|
|
|
|
|
|
|
|
if (value1->data[0].v_float < value2->data[0].v_float)
|
|
|
|
return - (value2->data[0].v_float - value1->data[0].v_float > epsilon);
|
|
|
|
else
|
|
|
|
return value1->data[0].v_float - value2->data[0].v_float > epsilon;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
property_float_class_init (GParamSpecClass *klass)
|
|
|
|
{
|
|
|
|
klass->value_type = G_TYPE_FLOAT;
|
|
|
|
|
|
|
|
klass->value_validate = property_float_validate;
|
|
|
|
klass->values_cmp = property_float_values_cmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
property_float_init (GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
GFloatProperty *property = (GFloatProperty *) pspec;
|
|
|
|
|
|
|
|
property->min_value = -G_MAXFLOAT;
|
|
|
|
property->max_value = G_MAXFLOAT;
|
|
|
|
property->epsilon = G_FLOAT_EPSILON;
|
|
|
|
}
|
|
|
|
|
|
|
|
GType
|
|
|
|
_g_float_property_get_type (void)
|
|
|
|
{
|
|
|
|
static volatile gsize pspec_type_id__volatile = 0;
|
|
|
|
|
|
|
|
if (g_once_init_enter (&pspec_type_id__volatile))
|
|
|
|
{
|
|
|
|
const GTypeInfo info = {
|
|
|
|
sizeof (GParamSpecClass),
|
|
|
|
NULL, NULL,
|
|
|
|
(GClassInitFunc) property_float_class_init,
|
|
|
|
NULL, NULL,
|
|
|
|
sizeof (GFloatProperty),
|
|
|
|
0,
|
|
|
|
(GInstanceInitFunc) property_float_init,
|
|
|
|
};
|
|
|
|
|
|
|
|
GType pspec_type_id =
|
|
|
|
g_type_register_static (G_TYPE_PROPERTY,
|
|
|
|
g_intern_static_string ("GFloatProperty"),
|
|
|
|
&info, 0);
|
|
|
|
|
|
|
|
g_once_init_leave (&pspec_type_id__volatile, pspec_type_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
return pspec_type_id__volatile;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_float_property_new:
|
|
|
|
* @name: canonical name of the property
|
|
|
|
* @flags: flags for the property
|
|
|
|
* @offset: the offset in the private structure of the field
|
|
|
|
* that stores the property, or -1
|
|
|
|
* @setter: (allow-none): the setter function for the property
|
|
|
|
* @getter: (allow-none): the getter function for the property
|
|
|
|
*
|
|
|
|
* Creates a new #GProperty mapping to a single precision floating
|
|
|
|
* point value.
|
|
|
|
*
|
|
|
|
* Return value: the newly created #GProperty
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
GParamSpec *
|
|
|
|
g_float_property_new (const gchar *name,
|
|
|
|
GPropertyFlags flags,
|
|
|
|
gssize offset,
|
|
|
|
GPropertyFloatSet setter,
|
|
|
|
GPropertyFloatGet getter)
|
|
|
|
{
|
|
|
|
GProperty *prop;
|
|
|
|
GFloatProperty *internal;
|
|
|
|
|
|
|
|
if (setter == NULL && getter == NULL)
|
|
|
|
g_return_val_if_fail (offset >= 0, NULL);
|
2012-11-12 19:37:56 +00:00
|
|
|
if (setter == NULL)
|
|
|
|
flags |= G_PROPERTY_DIRECT_SET;
|
|
|
|
if (getter == NULL)
|
|
|
|
flags |= G_PROPERTY_DIRECT_GET;
|
2011-04-22 14:08:11 +01:00
|
|
|
|
|
|
|
prop = g_param_spec_internal (_g_float_property_get_type (),
|
|
|
|
name, NULL, NULL,
|
|
|
|
property_flags_to_param_flags (flags));
|
|
|
|
|
|
|
|
prop->flags = flags;
|
|
|
|
|
|
|
|
G_PARAM_SPEC (prop)->value_type = G_TYPE_FLOAT;
|
|
|
|
|
|
|
|
prop->field_offset = offset;
|
|
|
|
|
|
|
|
prop->is_installed = FALSE;
|
|
|
|
|
|
|
|
prop->type_size = sizeof (gfloat);
|
|
|
|
|
|
|
|
internal = (GFloatProperty *) prop;
|
|
|
|
internal->setter = setter;
|
|
|
|
internal->getter = getter;
|
|
|
|
|
|
|
|
return G_PARAM_SPEC (prop);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
g_float_property_set_range (GProperty *property,
|
|
|
|
gfloat min_value,
|
|
|
|
gfloat max_value)
|
|
|
|
{
|
|
|
|
if (min_value > max_value)
|
|
|
|
{
|
|
|
|
g_critical (G_STRLOC ": Invalid range for the property '%s'",
|
|
|
|
G_PARAM_SPEC (property)->name);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
((GFloatProperty *) property)->min_value = min_value;
|
|
|
|
((GFloatProperty *) property)->max_value = max_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
g_float_property_get_range (GProperty *property,
|
|
|
|
gfloat *min_value,
|
|
|
|
gfloat *max_value)
|
|
|
|
{
|
|
|
|
*min_value = ((GFloatProperty *) property)->min_value;
|
|
|
|
*max_value = ((GFloatProperty *) property)->max_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline gboolean
|
|
|
|
g_float_property_validate (GProperty *property,
|
|
|
|
gfloat value)
|
|
|
|
{
|
|
|
|
GFloatProperty *internal = (GFloatProperty *) property;
|
|
|
|
|
|
|
|
if (value >= internal->min_value &&
|
|
|
|
value <= internal->max_value)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline gboolean
|
|
|
|
g_float_property_set_value (GProperty *property,
|
|
|
|
gpointer gobject,
|
|
|
|
gfloat value)
|
|
|
|
{
|
|
|
|
gboolean retval = FALSE;
|
|
|
|
|
|
|
|
if ((property->flags & G_PROPERTY_WRITABLE) == 0)
|
|
|
|
{
|
|
|
|
g_critical ("The property '%s' of object '%s' is not writable",
|
|
|
|
G_PARAM_SPEC (property)->name,
|
|
|
|
G_OBJECT_TYPE_NAME (gobject));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!g_float_property_validate (property, value))
|
|
|
|
{
|
|
|
|
g_warning ("The value for the property '%s' of object '%s' is out of the valid range",
|
|
|
|
G_PARAM_SPEC (property)->name,
|
|
|
|
G_OBJECT_TYPE_NAME (gobject));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (((GFloatProperty *) property)->setter != NULL)
|
|
|
|
{
|
|
|
|
property_lock_internal (property, gobject);
|
|
|
|
|
|
|
|
retval = ((GFloatProperty *) property)->setter (gobject, value);
|
|
|
|
|
|
|
|
property_unlock_internal (property, gobject);
|
|
|
|
|
|
|
|
if (retval)
|
|
|
|
g_object_notify_by_pspec (gobject, (GParamSpec *) property);
|
|
|
|
}
|
|
|
|
else if (property->field_offset >= 0)
|
|
|
|
{
|
|
|
|
gpointer priv_p, field_p;
|
|
|
|
|
|
|
|
property_lock_internal (property, gobject);
|
|
|
|
|
|
|
|
priv_p = get_private_pointer (gobject, property->priv_offset);
|
|
|
|
field_p = G_STRUCT_MEMBER_P (priv_p, property->field_offset);
|
|
|
|
|
|
|
|
if ((* (gfloat *) field_p) == value)
|
|
|
|
{
|
|
|
|
property_unlock_internal (property, gobject);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
(* (gfloat *) field_p) = value;
|
|
|
|
|
|
|
|
property_unlock_internal (property, gobject);
|
|
|
|
|
|
|
|
g_object_notify_by_pspec (gobject, (GParamSpec *) property);
|
|
|
|
|
|
|
|
retval = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
g_critical (G_STRLOC ": No setter function or field offset specified "
|
|
|
|
"for property '%s'",
|
|
|
|
G_PARAM_SPEC (property)->name);
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline gfloat
|
|
|
|
g_float_property_get_value (GProperty *property,
|
|
|
|
gpointer gobject)
|
|
|
|
{
|
|
|
|
if ((property->flags & G_PROPERTY_READABLE) == 0)
|
|
|
|
{
|
|
|
|
g_critical ("The property '%s' of object '%s' is not readable",
|
|
|
|
G_PARAM_SPEC (property)->name,
|
|
|
|
G_OBJECT_TYPE_NAME (gobject));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (((GFloatProperty *) property)->getter != NULL)
|
|
|
|
{
|
|
|
|
return ((GFloatProperty *) property)->getter (gobject);
|
|
|
|
}
|
|
|
|
else if (property->field_offset >= 0)
|
|
|
|
{
|
|
|
|
gpointer priv_p, field_p;
|
|
|
|
|
|
|
|
priv_p = get_private_pointer (gobject, property->priv_offset);
|
|
|
|
field_p = G_STRUCT_MEMBER_P (priv_p, property->field_offset);
|
|
|
|
|
|
|
|
return (* (gfloat *) field_p);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_critical (G_STRLOC ": No getter function or field offset specified "
|
|
|
|
"for property '%s'",
|
|
|
|
G_PARAM_SPEC (property)->name);
|
|
|
|
return 0.0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* GDouble
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define G_DOUBLE_EPSILON (1e-90)
|
|
|
|
|
|
|
|
/* forward declaration for -Wmissing-prototypes */
|
|
|
|
GType _g_double_property_get_type (void);
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
GProperty parent;
|
|
|
|
|
|
|
|
gdouble min_value;
|
|
|
|
gdouble max_value;
|
|
|
|
gdouble epsilon;
|
|
|
|
|
|
|
|
GPropertyDoubleSet setter;
|
|
|
|
GPropertyDoubleGet getter;
|
|
|
|
} GDoubleProperty;
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
property_double_validate (GParamSpec *pspec,
|
|
|
|
GValue *value)
|
|
|
|
{
|
|
|
|
GDoubleProperty *property = (GDoubleProperty *) pspec;
|
|
|
|
gdouble oval = value->data[0].v_double;
|
|
|
|
|
|
|
|
value->data[0].v_double = CLAMP (value->data[0].v_double,
|
|
|
|
property->min_value,
|
|
|
|
property->max_value);
|
|
|
|
|
|
|
|
return value->data[0].v_double != oval;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
property_double_values_cmp (GParamSpec *pspec,
|
|
|
|
const GValue *value1,
|
|
|
|
const GValue *value2)
|
|
|
|
{
|
|
|
|
gdouble epsilon = ((GDoubleProperty *) pspec)->epsilon;
|
|
|
|
|
|
|
|
if (value1->data[0].v_double < value2->data[0].v_double)
|
|
|
|
return - (value2->data[0].v_double - value1->data[0].v_double > epsilon);
|
|
|
|
else
|
|
|
|
return value1->data[0].v_double - value2->data[0].v_double > epsilon;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
property_double_class_init (GParamSpecClass *klass)
|
|
|
|
{
|
|
|
|
klass->value_type = G_TYPE_DOUBLE;
|
|
|
|
|
|
|
|
klass->value_validate = property_double_validate;
|
|
|
|
klass->values_cmp = property_double_values_cmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
property_double_init (GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
GDoubleProperty *property = (GDoubleProperty *) pspec;
|
|
|
|
|
|
|
|
property->min_value = -G_MAXDOUBLE;
|
|
|
|
property->max_value = G_MAXDOUBLE;
|
|
|
|
property->epsilon = G_DOUBLE_EPSILON;
|
|
|
|
}
|
|
|
|
|
|
|
|
GType
|
|
|
|
_g_double_property_get_type (void)
|
|
|
|
{
|
|
|
|
static volatile gsize pspec_type_id__volatile = 0;
|
|
|
|
|
|
|
|
if (g_once_init_enter (&pspec_type_id__volatile))
|
|
|
|
{
|
|
|
|
const GTypeInfo info = {
|
|
|
|
sizeof (GParamSpecClass),
|
|
|
|
NULL, NULL,
|
|
|
|
(GClassInitFunc) property_double_class_init,
|
|
|
|
NULL, NULL,
|
|
|
|
sizeof (GDoubleProperty),
|
|
|
|
0,
|
|
|
|
(GInstanceInitFunc) property_double_init,
|
|
|
|
};
|
|
|
|
|
|
|
|
GType pspec_type_id =
|
|
|
|
g_type_register_static (G_TYPE_PROPERTY,
|
|
|
|
g_intern_static_string ("GDoubleProperty"),
|
|
|
|
&info, 0);
|
|
|
|
|
|
|
|
g_once_init_leave (&pspec_type_id__volatile, pspec_type_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
return pspec_type_id__volatile;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_double_property_new:
|
|
|
|
* @name: canonical name of the property
|
|
|
|
* @flags: flags for the property
|
|
|
|
* @offset: the offset in the private structure of the field
|
|
|
|
* that stores the property, or -1
|
|
|
|
* @setter: (allow-none): the setter function for the property
|
|
|
|
* @getter: (allow-none): the getter function for the property
|
|
|
|
*
|
|
|
|
* Creates a new #GProperty mapping to a double precision floating
|
|
|
|
* point value.
|
|
|
|
*
|
|
|
|
* Return value: the newly created #GProperty
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
GParamSpec *
|
|
|
|
g_double_property_new (const gchar *name,
|
|
|
|
GPropertyFlags flags,
|
|
|
|
gssize offset,
|
|
|
|
GPropertyDoubleSet setter,
|
|
|
|
GPropertyDoubleGet getter)
|
|
|
|
{
|
|
|
|
GProperty *prop;
|
|
|
|
GDoubleProperty *internal;
|
|
|
|
|
|
|
|
if (setter == NULL && getter == NULL)
|
|
|
|
g_return_val_if_fail (offset >= 0, NULL);
|
2012-11-12 19:37:56 +00:00
|
|
|
if (setter == NULL)
|
|
|
|
flags |= G_PROPERTY_DIRECT_SET;
|
|
|
|
if (getter == NULL)
|
|
|
|
flags |= G_PROPERTY_DIRECT_GET;
|
2011-04-22 14:08:11 +01:00
|
|
|
|
|
|
|
prop = g_param_spec_internal (_g_double_property_get_type (),
|
|
|
|
name, NULL, NULL,
|
|
|
|
property_flags_to_param_flags (flags));
|
|
|
|
|
|
|
|
prop->flags = flags;
|
|
|
|
|
|
|
|
G_PARAM_SPEC (prop)->value_type = G_TYPE_DOUBLE;
|
|
|
|
|
|
|
|
prop->field_offset = offset;
|
|
|
|
|
|
|
|
prop->is_installed = FALSE;
|
|
|
|
|
|
|
|
prop->type_size = sizeof (gdouble);
|
|
|
|
|
|
|
|
internal = (GDoubleProperty *) prop;
|
|
|
|
internal->setter = setter;
|
|
|
|
internal->getter = getter;
|
|
|
|
|
|
|
|
return G_PARAM_SPEC (prop);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
g_double_property_set_range (GProperty *property,
|
|
|
|
gdouble min_value,
|
|
|
|
gdouble max_value)
|
|
|
|
{
|
|
|
|
if (min_value > max_value)
|
|
|
|
{
|
|
|
|
g_critical (G_STRLOC ": Invalid range for property '%s'",
|
|
|
|
G_PARAM_SPEC (property)->name);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
((GDoubleProperty *) property)->min_value = min_value;
|
|
|
|
((GDoubleProperty *) property)->max_value = max_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
g_double_property_get_range (GProperty *property,
|
|
|
|
gdouble *min_value,
|
|
|
|
gdouble *max_value)
|
|
|
|
{
|
|
|
|
*min_value = ((GDoubleProperty *) property)->min_value;
|
|
|
|
*max_value = ((GDoubleProperty *) property)->max_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline gboolean
|
|
|
|
g_double_property_validate (GProperty *property,
|
|
|
|
gdouble value)
|
|
|
|
{
|
|
|
|
GDoubleProperty *internal = (GDoubleProperty *) property;
|
|
|
|
|
|
|
|
if (value >= internal->min_value &&
|
|
|
|
value <= internal->max_value)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline gboolean
|
|
|
|
g_double_property_set_value (GProperty *property,
|
|
|
|
gpointer gobject,
|
|
|
|
gdouble value)
|
|
|
|
{
|
|
|
|
gboolean retval = FALSE;
|
|
|
|
|
|
|
|
if ((property->flags & G_PROPERTY_WRITABLE) == 0)
|
|
|
|
{
|
|
|
|
g_critical ("The property '%s' of object '%s' is not writable",
|
|
|
|
G_PARAM_SPEC (property)->name,
|
|
|
|
G_OBJECT_TYPE_NAME (gobject));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!g_double_property_validate (property, value))
|
|
|
|
{
|
|
|
|
g_warning ("The value for the property '%s' of object '%s' is out of the valid range",
|
|
|
|
G_PARAM_SPEC (property)->name,
|
|
|
|
G_OBJECT_TYPE_NAME (gobject));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (((GDoubleProperty *) property)->setter != NULL)
|
|
|
|
{
|
|
|
|
property_lock_internal (property, gobject);
|
|
|
|
|
|
|
|
retval = ((GDoubleProperty *) property)->setter (gobject, value);
|
|
|
|
|
|
|
|
property_unlock_internal (property, gobject);
|
|
|
|
|
|
|
|
if (retval)
|
|
|
|
g_object_notify_by_pspec (gobject, (GParamSpec *) property);
|
|
|
|
}
|
|
|
|
else if (property->field_offset >= 0)
|
|
|
|
{
|
|
|
|
gpointer priv_p, field_p;
|
|
|
|
|
|
|
|
property_lock_internal (property, gobject);
|
|
|
|
|
|
|
|
priv_p = get_private_pointer (gobject, property->priv_offset);
|
|
|
|
field_p = G_STRUCT_MEMBER_P (priv_p, property->field_offset);
|
|
|
|
|
|
|
|
if ((* (gdouble *) field_p) == value)
|
|
|
|
{
|
|
|
|
property_unlock_internal (property, gobject);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
(* (gdouble *) field_p) = value;
|
|
|
|
|
|
|
|
property_unlock_internal (property, gobject);
|
|
|
|
|
|
|
|
g_object_notify_by_pspec (gobject, (GParamSpec *) property);
|
|
|
|
|
|
|
|
retval = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
g_critical (G_STRLOC ": No setter function or field offset specified "
|
|
|
|
"for property '%s'",
|
|
|
|
G_PARAM_SPEC (property)->name);
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline gdouble
|
|
|
|
g_double_property_get_value (GProperty *property,
|
|
|
|
gpointer gobject)
|
|
|
|
{
|
|
|
|
if ((property->flags & G_PROPERTY_READABLE) == 0)
|
|
|
|
{
|
|
|
|
g_critical ("The property '%s' of object '%s' is not readable",
|
|
|
|
G_PARAM_SPEC (property)->name,
|
|
|
|
G_OBJECT_TYPE_NAME (gobject));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (((GDoubleProperty *) property)->getter != NULL)
|
|
|
|
{
|
|
|
|
return ((GDoubleProperty *) property)->getter (gobject);
|
|
|
|
}
|
|
|
|
else if (property->field_offset >= 0)
|
|
|
|
{
|
|
|
|
gpointer priv_p, field_p;
|
|
|
|
|
|
|
|
priv_p = get_private_pointer (gobject, property->priv_offset);
|
|
|
|
field_p = G_STRUCT_MEMBER_P (priv_p, property->field_offset);
|
|
|
|
|
|
|
|
return (* (gdouble *) field_p);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_critical (G_STRLOC ": No getter function or field offset specified "
|
|
|
|
"for property '%s'",
|
|
|
|
G_PARAM_SPEC (property)->name);
|
|
|
|
return 0.0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* GString
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* forward declaration for -Wmissing-prototypes */
|
|
|
|
GType _g_string_property_get_type (void);
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
GProperty parent;
|
|
|
|
|
|
|
|
GPropertyStringSet setter;
|
|
|
|
GPropertyStringGet getter;
|
|
|
|
} GStringProperty;
|
|
|
|
|
|
|
|
static void
|
|
|
|
property_string_class_init (GParamSpecClass *klass)
|
|
|
|
{
|
|
|
|
klass->value_type = G_TYPE_STRING;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
property_string_init (GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
GType
|
|
|
|
_g_string_property_get_type (void)
|
|
|
|
{
|
|
|
|
static volatile gsize pspec_type_id__volatile = 0;
|
|
|
|
|
|
|
|
if (g_once_init_enter (&pspec_type_id__volatile))
|
|
|
|
{
|
|
|
|
const GTypeInfo info = {
|
|
|
|
sizeof (GParamSpecClass),
|
|
|
|
NULL, NULL,
|
|
|
|
(GClassInitFunc) property_string_class_init,
|
|
|
|
NULL, NULL,
|
|
|
|
sizeof (GStringProperty),
|
|
|
|
0,
|
|
|
|
(GInstanceInitFunc) property_string_init,
|
|
|
|
};
|
|
|
|
|
|
|
|
GType pspec_type_id =
|
|
|
|
g_type_register_static (G_TYPE_PROPERTY,
|
|
|
|
g_intern_static_string ("GStringProperty"),
|
|
|
|
&info, 0);
|
|
|
|
|
|
|
|
g_once_init_leave (&pspec_type_id__volatile, pspec_type_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
return pspec_type_id__volatile;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_string_property_new:
|
|
|
|
* @name: canonical name of the property
|
|
|
|
* @flags: flags for the property
|
|
|
|
* @offset: the offset in the private structure of the field
|
|
|
|
* that stores the property, or -1
|
|
|
|
* @setter: (allow-none): the setter function for the property
|
|
|
|
* @getter: (allow-none): the getter function for the property
|
|
|
|
*
|
|
|
|
* Creates a new #GProperty mapping to a string value.
|
|
|
|
*
|
|
|
|
* Return value: the newly created #GProperty
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
GParamSpec *
|
|
|
|
g_string_property_new (const gchar *name,
|
|
|
|
GPropertyFlags flags,
|
|
|
|
gssize offset,
|
|
|
|
GPropertyStringSet setter,
|
|
|
|
GPropertyStringGet getter)
|
|
|
|
{
|
|
|
|
GProperty *prop;
|
|
|
|
GStringProperty *internal;
|
|
|
|
|
|
|
|
if (setter == NULL && getter == NULL)
|
|
|
|
g_return_val_if_fail (offset >= 0, NULL);
|
2012-11-12 19:37:56 +00:00
|
|
|
if (setter == NULL)
|
|
|
|
flags |= G_PROPERTY_DIRECT_SET;
|
|
|
|
if (getter == NULL)
|
|
|
|
flags |= G_PROPERTY_DIRECT_GET;
|
2011-04-22 14:08:11 +01:00
|
|
|
|
|
|
|
prop = g_param_spec_internal (_g_string_property_get_type (),
|
|
|
|
name, NULL, NULL,
|
|
|
|
property_flags_to_param_flags (flags));
|
|
|
|
|
|
|
|
prop->flags = flags;
|
|
|
|
|
|
|
|
G_PARAM_SPEC (prop)->value_type = G_TYPE_STRING;
|
|
|
|
|
|
|
|
prop->field_offset = offset;
|
|
|
|
|
|
|
|
prop->is_installed = FALSE;
|
|
|
|
|
|
|
|
prop->type_size = sizeof (gchar*);
|
|
|
|
|
|
|
|
internal = (GStringProperty *) prop;
|
|
|
|
internal->setter = setter;
|
|
|
|
internal->getter = getter;
|
|
|
|
|
|
|
|
return G_PARAM_SPEC (prop);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline gboolean
|
|
|
|
g_string_property_validate (GProperty *property,
|
|
|
|
const gchar *value)
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline gboolean
|
|
|
|
g_string_property_set_value (GProperty *property,
|
|
|
|
gpointer gobject,
|
|
|
|
const gchar *value)
|
|
|
|
{
|
|
|
|
gboolean retval = FALSE;
|
|
|
|
|
|
|
|
if ((property->flags & G_PROPERTY_WRITABLE) == 0)
|
|
|
|
{
|
|
|
|
g_critical ("The property '%s' of object '%s' is not writable",
|
|
|
|
G_PARAM_SPEC (property)->name,
|
|
|
|
G_OBJECT_TYPE_NAME (gobject));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!g_string_property_validate (property, value))
|
|
|
|
{
|
|
|
|
g_warning ("The value for the property '%s' of object '%s' is out of the valid range",
|
|
|
|
G_PARAM_SPEC (property)->name,
|
|
|
|
G_OBJECT_TYPE_NAME (gobject));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (((GStringProperty *) property)->setter != NULL)
|
|
|
|
{
|
|
|
|
property_lock_internal (property, gobject);
|
|
|
|
|
|
|
|
retval = ((GStringProperty *) property)->setter (gobject, value);
|
|
|
|
|
|
|
|
property_unlock_internal (property, gobject);
|
|
|
|
|
|
|
|
if (retval)
|
|
|
|
g_object_notify_by_pspec (gobject, (GParamSpec *) property);
|
|
|
|
}
|
|
|
|
else if (property->field_offset >= 0)
|
|
|
|
{
|
|
|
|
gpointer priv_p, field_p;
|
|
|
|
gchar *str;
|
|
|
|
|
|
|
|
property_lock_internal (property, gobject);
|
|
|
|
|
|
|
|
priv_p = get_private_pointer (gobject, property->priv_offset);
|
|
|
|
field_p = G_STRUCT_MEMBER_P (priv_p, property->field_offset);
|
|
|
|
|
|
|
|
str = (* (gpointer *) field_p);
|
|
|
|
|
|
|
|
if (g_strcmp0 (str, value) == 0)
|
|
|
|
{
|
|
|
|
property_unlock_internal (property, gobject);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
g_object_notify_by_pspec (gobject, (GParamSpec *) property);
|
|
|
|
|
|
|
|
retval = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
g_critical (G_STRLOC ": No setter function or field offset specified "
|
|
|
|
"for property '%s'",
|
|
|
|
G_PARAM_SPEC (property)->name);
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline const gchar *
|
|
|
|
g_string_property_get_value (GProperty *property,
|
|
|
|
gpointer gobject)
|
|
|
|
{
|
|
|
|
if ((property->flags & G_PROPERTY_READABLE) == 0)
|
|
|
|
{
|
|
|
|
g_critical ("The property '%s' of object '%s' is not readable",
|
|
|
|
G_PARAM_SPEC (property)->name,
|
|
|
|
G_OBJECT_TYPE_NAME (gobject));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (((GStringProperty *) property)->getter != NULL)
|
|
|
|
{
|
|
|
|
return ((GStringProperty *) property)->getter (gobject);
|
|
|
|
}
|
|
|
|
else if (property->field_offset >= 0)
|
|
|
|
{
|
|
|
|
gpointer priv_p, field_p;
|
|
|
|
gchar *retval;
|
|
|
|
|
|
|
|
priv_p = get_private_pointer (gobject, property->priv_offset);
|
|
|
|
field_p = G_STRUCT_MEMBER_P (priv_p, property->field_offset);
|
|
|
|
|
|
|
|
if (property->flags & G_PROPERTY_COPY_GET)
|
|
|
|
retval = g_strdup ((* (gpointer *) field_p));
|
|
|
|
else
|
|
|
|
retval = (* (gpointer *) field_p);
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_critical (G_STRLOC ": No getter function or field offset specified "
|
|
|
|
"for property '%s'",
|
|
|
|
G_PARAM_SPEC (property)->name);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* GBoxed
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* forward declaration for -Wmissing-prototypes */
|
|
|
|
GType _g_boxed_property_get_type (void);
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
GProperty parent;
|
|
|
|
|
|
|
|
GPropertyBoxedSet setter;
|
|
|
|
GPropertyBoxedGet getter;
|
|
|
|
} GBoxedProperty;
|
|
|
|
|
|
|
|
static void
|
|
|
|
property_boxed_class_init (GParamSpecClass *klass)
|
|
|
|
{
|
|
|
|
klass->value_type = G_TYPE_BOXED;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
property_boxed_init (GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
GType
|
|
|
|
_g_boxed_property_get_type (void)
|
|
|
|
{
|
|
|
|
static volatile gsize pspec_type_id__volatile = 0;
|
|
|
|
|
|
|
|
if (g_once_init_enter (&pspec_type_id__volatile))
|
|
|
|
{
|
|
|
|
const GTypeInfo info = {
|
|
|
|
sizeof (GParamSpecClass),
|
|
|
|
NULL, NULL,
|
|
|
|
(GClassInitFunc) property_boxed_class_init,
|
|
|
|
NULL, NULL,
|
|
|
|
sizeof (GBoxedProperty),
|
|
|
|
0,
|
|
|
|
(GInstanceInitFunc) property_boxed_init,
|
|
|
|
};
|
|
|
|
|
|
|
|
GType pspec_type_id =
|
|
|
|
g_type_register_static (G_TYPE_PROPERTY,
|
|
|
|
g_intern_static_string ("GBoxedProperty"),
|
|
|
|
&info, 0);
|
|
|
|
|
|
|
|
g_once_init_leave (&pspec_type_id__volatile, pspec_type_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
return pspec_type_id__volatile;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_boxed_property_new:
|
|
|
|
* @name: canonical name of the property
|
|
|
|
* @flags: flags for the property
|
|
|
|
* @offset: the offset in the private structure of the field
|
|
|
|
* that stores the property, or -1
|
|
|
|
* @setter: (allow-none): the setter function for the property
|
|
|
|
* @getter: (allow-none): the getter function for the property
|
|
|
|
*
|
|
|
|
* Creates a new #GProperty mapping to a boxed value.
|
|
|
|
*
|
|
|
|
* You can use g_property_set_prerequisite() to specify the #GType
|
|
|
|
* of the boxed value.
|
|
|
|
*
|
|
|
|
* Return value: the newly created #GProperty
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
GParamSpec *
|
|
|
|
g_boxed_property_new (const gchar *name,
|
|
|
|
GPropertyFlags flags,
|
|
|
|
gssize offset,
|
|
|
|
GPropertyBoxedSet setter,
|
|
|
|
GPropertyBoxedGet getter)
|
|
|
|
{
|
|
|
|
GProperty *prop;
|
|
|
|
GBoxedProperty *internal;
|
|
|
|
|
|
|
|
if (setter == NULL && getter == NULL)
|
|
|
|
g_return_val_if_fail (offset >= 0, NULL);
|
2012-11-12 19:37:56 +00:00
|
|
|
if (setter == NULL)
|
|
|
|
flags |= G_PROPERTY_DIRECT_SET;
|
|
|
|
if (getter == NULL)
|
|
|
|
flags |= G_PROPERTY_DIRECT_GET;
|
2011-04-22 14:08:11 +01:00
|
|
|
|
|
|
|
prop = g_param_spec_internal (_g_boxed_property_get_type (),
|
|
|
|
name, NULL, NULL,
|
|
|
|
property_flags_to_param_flags (flags));
|
|
|
|
|
|
|
|
prop->flags = flags;
|
|
|
|
|
|
|
|
G_PARAM_SPEC (prop)->value_type = G_TYPE_BOXED;
|
|
|
|
|
|
|
|
prop->field_offset = offset;
|
|
|
|
|
|
|
|
prop->is_installed = FALSE;
|
|
|
|
|
|
|
|
prop->type_size = sizeof (gpointer);
|
|
|
|
|
|
|
|
internal = (GBoxedProperty *) prop;
|
|
|
|
internal->setter = setter;
|
|
|
|
internal->getter = getter;
|
|
|
|
|
|
|
|
return G_PARAM_SPEC (prop);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline gboolean
|
|
|
|
g_boxed_property_validate (GProperty *property,
|
|
|
|
gconstpointer value)
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline gboolean
|
|
|
|
g_boxed_property_set_value (GProperty *property,
|
|
|
|
gpointer gobject,
|
|
|
|
gpointer value)
|
|
|
|
{
|
|
|
|
gboolean retval = FALSE;
|
|
|
|
|
|
|
|
if ((property->flags & G_PROPERTY_WRITABLE) == 0)
|
|
|
|
{
|
|
|
|
g_critical ("The property '%s' of object '%s' is not writable",
|
|
|
|
G_PARAM_SPEC (property)->name,
|
|
|
|
G_OBJECT_TYPE_NAME (gobject));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!g_boxed_property_validate (property, value))
|
|
|
|
{
|
|
|
|
g_warning ("The value for the property '%s' of object '%s' is out of the valid range",
|
|
|
|
G_PARAM_SPEC (property)->name,
|
|
|
|
G_OBJECT_TYPE_NAME (gobject));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (((GBoxedProperty *) property)->setter != NULL)
|
|
|
|
{
|
|
|
|
property_lock_internal (property, gobject);
|
|
|
|
|
|
|
|
retval = ((GBoxedProperty *) property)->setter (gobject, value);
|
|
|
|
|
|
|
|
property_unlock_internal (property, gobject);
|
|
|
|
|
|
|
|
if (retval)
|
|
|
|
g_object_notify_by_pspec (gobject, (GParamSpec *) property);
|
|
|
|
}
|
|
|
|
else if (property->field_offset >= 0)
|
|
|
|
{
|
|
|
|
gpointer priv_p, field_p;
|
|
|
|
gpointer old_value;
|
|
|
|
|
|
|
|
property_lock_internal (property, gobject);
|
|
|
|
|
|
|
|
priv_p = get_private_pointer (gobject, property->priv_offset);
|
|
|
|
field_p = G_STRUCT_MEMBER_P (priv_p, property->field_offset);
|
|
|
|
|
|
|
|
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 (old_value != NULL)
|
|
|
|
g_boxed_free (((GParamSpec *) property)->value_type, old_value);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
(* (gpointer *) field_p) = value;
|
|
|
|
|
|
|
|
property_unlock_internal (property, gobject);
|
|
|
|
|
|
|
|
g_object_notify_by_pspec (gobject, (GParamSpec *) property);
|
|
|
|
|
|
|
|
retval = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
g_critical (G_STRLOC ": No setter function or field offset specified "
|
|
|
|
"for property '%s'",
|
|
|
|
G_PARAM_SPEC (property)->name);
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline gpointer
|
|
|
|
g_boxed_property_get_value (GProperty *property,
|
|
|
|
gpointer gobject)
|
|
|
|
{
|
|
|
|
if ((property->flags & G_PROPERTY_READABLE) == 0)
|
|
|
|
{
|
|
|
|
g_critical ("The property '%s' of object '%s' is not readable",
|
|
|
|
G_PARAM_SPEC (property)->name,
|
|
|
|
G_OBJECT_TYPE_NAME (gobject));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (((GBoxedProperty *) property)->getter != NULL)
|
|
|
|
{
|
|
|
|
return ((GBoxedProperty *) property)->getter (gobject);
|
|
|
|
}
|
|
|
|
else if (property->field_offset >= 0)
|
|
|
|
{
|
|
|
|
gpointer priv_p, field_p;
|
|
|
|
gpointer value;
|
|
|
|
|
|
|
|
priv_p = get_private_pointer (gobject, property->priv_offset);
|
|
|
|
field_p = G_STRUCT_MEMBER_P (priv_p, property->field_offset);
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_critical (G_STRLOC ": No getter function or field offset specified "
|
|
|
|
"for property '%s'",
|
|
|
|
G_PARAM_SPEC (property)->name);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* GObject
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* forward declaration for -Wmissing-prototypes */
|
|
|
|
GType _g_object_property_get_type (void);
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
GProperty parent;
|
|
|
|
|
|
|
|
GPropertyObjectSet setter;
|
|
|
|
GPropertyObjectGet getter;
|
|
|
|
} GObjectProperty;
|
|
|
|
|
|
|
|
static void
|
|
|
|
property_object_class_init (GParamSpecClass *klass)
|
|
|
|
{
|
|
|
|
klass->value_type = G_TYPE_OBJECT;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
property_object_init (GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
GType
|
|
|
|
_g_object_property_get_type (void)
|
|
|
|
{
|
|
|
|
static volatile gsize pspec_type_id__volatile = 0;
|
|
|
|
|
|
|
|
if (g_once_init_enter (&pspec_type_id__volatile))
|
|
|
|
{
|
|
|
|
const GTypeInfo info = {
|
|
|
|
sizeof (GParamSpecClass),
|
|
|
|
NULL, NULL,
|
|
|
|
(GClassInitFunc) property_object_class_init,
|
|
|
|
NULL, NULL,
|
|
|
|
sizeof (GObjectProperty),
|
|
|
|
0,
|
|
|
|
(GInstanceInitFunc) property_object_init,
|
|
|
|
};
|
|
|
|
|
|
|
|
GType pspec_type_id =
|
|
|
|
g_type_register_static (G_TYPE_PROPERTY,
|
|
|
|
g_intern_static_string ("GObjectProperty"),
|
|
|
|
&info, 0);
|
|
|
|
|
|
|
|
g_once_init_leave (&pspec_type_id__volatile, pspec_type_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
return pspec_type_id__volatile;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_object_property_new:
|
|
|
|
* @name: canonical name of the property
|
|
|
|
* @flags: flags for the property
|
|
|
|
* @offset: the offset in the private structure of the field
|
|
|
|
* that stores the property, or -1
|
|
|
|
* @setter: (allow-none): the setter function for the property
|
|
|
|
* @getter: (allow-none): the getter function for the property
|
|
|
|
*
|
|
|
|
* Creates a new #GProperty mapping to an object value.
|
|
|
|
*
|
|
|
|
* You can use g_property_set_prerequisite() to specify the #GType
|
|
|
|
* of the object value.
|
|
|
|
*
|
|
|
|
* Return value: the newly created #GProperty
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
GParamSpec *
|
|
|
|
g_object_property_new (const gchar *name,
|
|
|
|
GPropertyFlags flags,
|
|
|
|
gssize offset,
|
|
|
|
GPropertyObjectSet setter,
|
|
|
|
GPropertyObjectGet getter)
|
|
|
|
{
|
|
|
|
GProperty *prop;
|
|
|
|
GObjectProperty *internal;
|
|
|
|
|
|
|
|
if (setter == NULL && getter == NULL)
|
|
|
|
g_return_val_if_fail (offset >= 0, NULL);
|
2012-11-12 19:37:56 +00:00
|
|
|
if (setter == NULL)
|
|
|
|
flags |= G_PROPERTY_DIRECT_SET;
|
|
|
|
if (getter == NULL)
|
|
|
|
flags |= G_PROPERTY_DIRECT_GET;
|
2011-04-22 14:08:11 +01:00
|
|
|
|
|
|
|
prop = g_param_spec_internal (_g_object_property_get_type (),
|
|
|
|
name, NULL, NULL,
|
|
|
|
property_flags_to_param_flags (flags));
|
|
|
|
|
|
|
|
prop->flags = flags;
|
|
|
|
|
|
|
|
G_PARAM_SPEC (prop)->value_type = G_TYPE_OBJECT;
|
|
|
|
|
|
|
|
prop->field_offset = offset;
|
|
|
|
|
|
|
|
prop->is_installed = FALSE;
|
|
|
|
|
|
|
|
prop->type_size = sizeof (gpointer);
|
|
|
|
|
|
|
|
internal = (GObjectProperty *) prop;
|
|
|
|
internal->setter = setter;
|
|
|
|
internal->getter = getter;
|
|
|
|
|
|
|
|
return G_PARAM_SPEC (prop);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline gboolean
|
|
|
|
g_object_property_validate (GProperty *property,
|
|
|
|
gconstpointer value)
|
|
|
|
{
|
|
|
|
if (value == NULL)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
return g_type_is_a (G_OBJECT_TYPE (value), G_PARAM_SPEC (property)->value_type);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline gboolean
|
|
|
|
g_object_property_set_value (GProperty *property,
|
|
|
|
gpointer gobject,
|
|
|
|
gpointer value)
|
|
|
|
{
|
|
|
|
gboolean retval = FALSE;
|
|
|
|
|
|
|
|
if ((property->flags & G_PROPERTY_WRITABLE) == 0)
|
|
|
|
{
|
|
|
|
g_critical ("The property '%s' of object '%s' is not writable",
|
|
|
|
G_PARAM_SPEC (property)->name,
|
|
|
|
G_OBJECT_TYPE_NAME (gobject));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!g_object_property_validate (property, value))
|
|
|
|
{
|
|
|
|
g_warning ("The value for the property '%s' of object '%s' is out of the valid range",
|
|
|
|
G_PARAM_SPEC (property)->name,
|
|
|
|
G_OBJECT_TYPE_NAME (gobject));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (((GObjectProperty *) property)->setter != NULL)
|
|
|
|
{
|
|
|
|
property_lock_internal (property, gobject);
|
|
|
|
|
|
|
|
retval = ((GObjectProperty *) property)->setter (gobject, value);
|
|
|
|
|
|
|
|
property_unlock_internal (property, gobject);
|
|
|
|
|
|
|
|
if (retval)
|
|
|
|
g_object_notify_by_pspec (gobject, (GParamSpec *) property);
|
|
|
|
}
|
|
|
|
else if (property->field_offset >= 0)
|
|
|
|
{
|
|
|
|
gpointer priv_p, field_p;
|
|
|
|
gpointer obj;
|
|
|
|
|
|
|
|
g_return_val_if_fail (value == NULL || G_IS_OBJECT (value), FALSE);
|
|
|
|
|
|
|
|
property_lock_internal (property, gobject);
|
|
|
|
|
|
|
|
priv_p = get_private_pointer (gobject, property->priv_offset);
|
|
|
|
field_p = G_STRUCT_MEMBER_P (priv_p, property->field_offset);
|
|
|
|
|
|
|
|
if ((* (gpointer *) field_p) == value)
|
|
|
|
{
|
|
|
|
property_unlock_internal (property, gobject);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (property->flags & G_PROPERTY_COPY_SET)
|
|
|
|
{
|
|
|
|
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);
|
|
|
|
|
|
|
|
g_object_notify_by_pspec (gobject, (GParamSpec *) property);
|
|
|
|
|
|
|
|
retval = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
g_critical (G_STRLOC ": No setter function or field offset specified "
|
|
|
|
"for property '%s'",
|
|
|
|
G_PARAM_SPEC (property)->name);
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline gpointer
|
|
|
|
g_object_property_get_value (GProperty *property,
|
|
|
|
gpointer gobject)
|
|
|
|
{
|
|
|
|
if ((property->flags & G_PROPERTY_READABLE) == 0)
|
|
|
|
{
|
|
|
|
g_critical ("The property '%s' of object '%s' is not readable",
|
|
|
|
G_PARAM_SPEC (property)->name,
|
|
|
|
G_OBJECT_TYPE_NAME (gobject));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (((GObjectProperty *) property)->getter != NULL)
|
|
|
|
{
|
|
|
|
return ((GObjectProperty *) property)->getter (gobject);
|
|
|
|
}
|
|
|
|
else if (property->field_offset >= 0)
|
|
|
|
{
|
|
|
|
gpointer priv_p, field_p;
|
|
|
|
|
|
|
|
priv_p = g_type_instance_get_private (gobject, G_OBJECT_TYPE (gobject));
|
|
|
|
field_p = G_STRUCT_MEMBER_P (priv_p, property->field_offset);
|
|
|
|
|
|
|
|
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
|
|
|
|
{
|
|
|
|
g_critical (G_STRLOC ": No getter function or field offset specified "
|
|
|
|
"for property '%s'",
|
|
|
|
G_PARAM_SPEC (property)->name);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* gpointer
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* forward declaration for -Wmissing-prototypes */
|
|
|
|
GType _g_pointer_property_get_type (void);
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
GProperty parent;
|
|
|
|
|
|
|
|
GPropertyPointerSet setter;
|
|
|
|
GPropertyPointerGet getter;
|
|
|
|
} GPointerProperty;
|
|
|
|
|
|
|
|
static void
|
|
|
|
property_pointer_class_init (GParamSpecClass *klass)
|
|
|
|
{
|
|
|
|
klass->value_type = G_TYPE_POINTER;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
property_pointer_init (GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
GType
|
|
|
|
_g_pointer_property_get_type (void)
|
|
|
|
{
|
|
|
|
static volatile gsize pspec_type_id__volatile = 0;
|
|
|
|
|
|
|
|
if (g_once_init_enter (&pspec_type_id__volatile))
|
|
|
|
{
|
|
|
|
const GTypeInfo info = {
|
|
|
|
sizeof (GParamSpecClass),
|
|
|
|
NULL, NULL,
|
|
|
|
(GClassInitFunc) property_pointer_class_init,
|
|
|
|
NULL, NULL,
|
|
|
|
sizeof (GPointerProperty),
|
|
|
|
0,
|
|
|
|
(GInstanceInitFunc) property_pointer_init,
|
|
|
|
};
|
|
|
|
|
|
|
|
GType pspec_type_id =
|
|
|
|
g_type_register_static (G_TYPE_PROPERTY,
|
|
|
|
g_intern_static_string ("GPointerProperty"),
|
|
|
|
&info, 0);
|
|
|
|
|
|
|
|
g_once_init_leave (&pspec_type_id__volatile, pspec_type_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
return pspec_type_id__volatile;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_pointer_property_new:
|
|
|
|
* @name: canonical name of the property
|
|
|
|
* @flags: flags for the property
|
|
|
|
* @offset: the offset in the private structure of the field
|
|
|
|
* that stores the property, or -1
|
|
|
|
* @setter: (allow-none): the setter function for the property
|
|
|
|
* @getter: (allow-none): the getter function for the property
|
|
|
|
*
|
|
|
|
* Creates a new #GProperty mapping to an untyped pointer.
|
|
|
|
*
|
|
|
|
* Return value: the newly created #GProperty
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
GParamSpec *
|
|
|
|
g_pointer_property_new (const gchar *name,
|
|
|
|
GPropertyFlags flags,
|
|
|
|
gssize offset,
|
|
|
|
GPropertyObjectSet setter,
|
|
|
|
GPropertyObjectGet getter)
|
|
|
|
{
|
|
|
|
GProperty *prop;
|
|
|
|
GPointerProperty *internal;
|
|
|
|
|
|
|
|
if (setter == NULL && getter == NULL)
|
|
|
|
g_return_val_if_fail (offset >= 0, NULL);
|
2012-11-12 19:37:56 +00:00
|
|
|
if (setter == NULL)
|
|
|
|
flags |= G_PROPERTY_DIRECT_SET;
|
|
|
|
if (getter == NULL)
|
|
|
|
flags |= G_PROPERTY_DIRECT_GET;
|
2011-04-22 14:08:11 +01:00
|
|
|
|
|
|
|
prop = g_param_spec_internal (_g_pointer_property_get_type (),
|
|
|
|
name, NULL, NULL,
|
|
|
|
property_flags_to_param_flags (flags));
|
|
|
|
|
|
|
|
prop->flags = flags;
|
|
|
|
|
|
|
|
G_PARAM_SPEC (prop)->value_type = G_TYPE_POINTER;
|
|
|
|
|
|
|
|
prop->field_offset = offset;
|
|
|
|
|
|
|
|
prop->is_installed = FALSE;
|
|
|
|
|
|
|
|
prop->type_size = sizeof (gpointer);
|
|
|
|
|
|
|
|
internal = (GPointerProperty *) prop;
|
|
|
|
internal->setter = setter;
|
|
|
|
internal->getter = getter;
|
|
|
|
|
|
|
|
return G_PARAM_SPEC (prop);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline gboolean
|
|
|
|
g_pointer_property_validate (GProperty *property,
|
|
|
|
gconstpointer value)
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline gboolean
|
|
|
|
g_pointer_property_set_value (GProperty *property,
|
|
|
|
gpointer gobject,
|
|
|
|
gpointer value)
|
|
|
|
{
|
|
|
|
gboolean retval = FALSE;
|
|
|
|
|
|
|
|
if ((property->flags & G_PROPERTY_WRITABLE) == 0)
|
|
|
|
{
|
|
|
|
g_critical ("The property '%s' of object '%s' is not writable",
|
|
|
|
G_PARAM_SPEC (property)->name,
|
|
|
|
G_OBJECT_TYPE_NAME (gobject));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!g_pointer_property_validate (property, value))
|
|
|
|
{
|
|
|
|
g_warning ("The value for the property '%s' of object '%s' is out of the valid range",
|
|
|
|
G_PARAM_SPEC (property)->name,
|
|
|
|
G_OBJECT_TYPE_NAME (gobject));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (((GPointerProperty *) property)->setter != NULL)
|
|
|
|
{
|
|
|
|
property_lock_internal (property, gobject);
|
|
|
|
|
|
|
|
retval = ((GPointerProperty *) property)->setter (gobject, value);
|
|
|
|
|
|
|
|
property_unlock_internal (property, gobject);
|
|
|
|
|
|
|
|
if (retval)
|
|
|
|
g_object_notify_by_pspec (gobject, (GParamSpec *) property);
|
|
|
|
}
|
|
|
|
else if (property->field_offset >= 0)
|
|
|
|
{
|
|
|
|
gpointer priv_p, field_p;
|
|
|
|
|
|
|
|
property_lock_internal (property, gobject);
|
|
|
|
|
|
|
|
priv_p = get_private_pointer (gobject, property->priv_offset);
|
|
|
|
field_p = G_STRUCT_MEMBER_P (priv_p, property->field_offset);
|
|
|
|
|
|
|
|
if ((* (gpointer *) field_p) == value)
|
|
|
|
{
|
|
|
|
property_unlock_internal (property, gobject);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
(* (gpointer *) field_p) = value;
|
|
|
|
|
|
|
|
property_unlock_internal (property, gobject);
|
|
|
|
|
|
|
|
g_object_notify_by_pspec (gobject, (GParamSpec *) property);
|
|
|
|
|
|
|
|
retval = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
g_critical (G_STRLOC ": No setter function or field offset specified "
|
|
|
|
"for property '%s'",
|
|
|
|
G_PARAM_SPEC (property)->name);
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline gpointer
|
|
|
|
g_pointer_property_get_value (GProperty *property,
|
|
|
|
gpointer gobject)
|
|
|
|
{
|
|
|
|
if ((property->flags & G_PROPERTY_READABLE) == 0)
|
|
|
|
{
|
|
|
|
g_critical ("The property '%s' of object '%s' is not readable",
|
|
|
|
G_PARAM_SPEC (property)->name,
|
|
|
|
G_OBJECT_TYPE_NAME (gobject));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (((GPointerProperty *) property)->getter != NULL)
|
|
|
|
{
|
|
|
|
return ((GPointerProperty *) property)->getter (gobject);
|
|
|
|
}
|
|
|
|
else if (property->field_offset >= 0)
|
|
|
|
{
|
|
|
|
gpointer priv_p, field_p;
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_critical (G_STRLOC ": No getter function or field offset specified "
|
|
|
|
"for property '%s'",
|
|
|
|
G_PARAM_SPEC (property)->name);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* GProperty common API
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*< private >
|
|
|
|
* g_property_set_installed:
|
|
|
|
* @property: a #GProperty
|
|
|
|
* @class_gtype: the #GType of the class that installed @property
|
|
|
|
*
|
|
|
|
* Performs additional work once a type class has been associated to
|
|
|
|
* the property.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
_g_property_set_installed (GProperty *property,
|
|
|
|
gpointer g_class,
|
|
|
|
GType class_gtype)
|
|
|
|
{
|
|
|
|
if (property->field_offset >= 0)
|
|
|
|
{
|
|
|
|
gboolean is_interface = G_TYPE_IS_INTERFACE (class_gtype);
|
|
|
|
|
|
|
|
if (is_interface)
|
|
|
|
{
|
|
|
|
g_critical (G_STRLOC ": The property '%s' has a field offset value "
|
|
|
|
"but it is being installed on an interface of type '%s'. "
|
|
|
|
"Properties installed on interfaces cannot have direct "
|
|
|
|
"access to a structure field.",
|
|
|
|
G_PARAM_SPEC (property)->name,
|
|
|
|
g_type_name (class_gtype));
|
|
|
|
property->priv_offset = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
property->priv_offset = g_type_class_get_instance_private_offset (g_class, class_gtype);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
property->priv_offset = -1;
|
|
|
|
|
|
|
|
/* if the property is using the default locking, pre-compute the
|
|
|
|
* quark for the lock
|
|
|
|
*/
|
|
|
|
if ((property->flags & G_PROPERTY_ATOMIC) != 0 &&
|
|
|
|
property->prop_id == 0 &&
|
|
|
|
property->lock_func == NULL)
|
|
|
|
{
|
|
|
|
gchar *lock_n = g_strconcat ("-g-property-id-",
|
|
|
|
G_PARAM_SPEC (property)->name,
|
|
|
|
NULL);
|
|
|
|
property->prop_id = g_quark_from_string (lock_n);
|
|
|
|
g_free (lock_n);
|
|
|
|
}
|
|
|
|
|
|
|
|
property->is_installed = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
is_canonical (const gchar *key)
|
|
|
|
{
|
|
|
|
const gchar *p;
|
|
|
|
|
|
|
|
for (p = key; *p != 0; p++)
|
|
|
|
{
|
|
|
|
gchar c = *p;
|
|
|
|
|
|
|
|
if (c != '-' &&
|
|
|
|
(c < '0' || c > '9') &&
|
|
|
|
(c < 'A' || c > 'Z') &&
|
|
|
|
(c < 'a' || c > 'z'))
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
canonicalize_name (gchar *key)
|
|
|
|
{
|
|
|
|
gchar *p;
|
|
|
|
|
|
|
|
for (p = key; *p != 0; p++)
|
|
|
|
{
|
|
|
|
gchar c = *p;
|
|
|
|
|
|
|
|
if (c != '-' &&
|
|
|
|
(c < '0' || c > '9') &&
|
|
|
|
(c < 'A' || c > 'Z') &&
|
|
|
|
(c < 'a' || c > 'z'))
|
|
|
|
*p = '-';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_property_canonicalize_name:
|
|
|
|
* @name: a string
|
|
|
|
*
|
|
|
|
* Canonicalizes a string into a property name.
|
|
|
|
*
|
|
|
|
* Return value: (transfer full): a newly allocated string with
|
|
|
|
* the canonical version of @name
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
gchar *
|
|
|
|
g_property_canonicalize_name (const gchar *name)
|
|
|
|
{
|
|
|
|
gchar *retval;
|
|
|
|
|
|
|
|
g_return_val_if_fail (name != NULL, NULL);
|
|
|
|
|
|
|
|
if (is_canonical (name))
|
|
|
|
return g_strdup (g_intern_string (name));
|
|
|
|
|
|
|
|
retval = g_strdup (name);
|
|
|
|
canonicalize_name (retval);
|
|
|
|
g_intern_string (retval);
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_property_describe:
|
|
|
|
* @property: a #GProperty
|
|
|
|
* @nick: a static string with the user-readable name
|
|
|
|
* of the property
|
|
|
|
* @blurb: a static string with the user-readable description
|
|
|
|
* of the property
|
|
|
|
*
|
|
|
|
* Sets the user-readable, and optionally translatable, name and
|
|
|
|
* description of the property.
|
|
|
|
*
|
|
|
|
* This function cannot be called more than once.
|
|
|
|
*
|
|
|
|
* This function is a convenience wrapper around g_param_spec_set_static_nick()
|
|
|
|
* and g_param_spec_set_static_blurb().
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
g_property_describe (GProperty *property,
|
|
|
|
const char *nick,
|
|
|
|
const char *blurb)
|
|
|
|
{
|
|
|
|
GParamSpec *pspec;
|
|
|
|
|
|
|
|
g_return_if_fail (G_IS_PROPERTY (property));
|
|
|
|
g_return_if_fail (nick != NULL);
|
|
|
|
g_return_if_fail (blurb != NULL);
|
|
|
|
|
|
|
|
pspec = G_PARAM_SPEC (property);
|
|
|
|
|
|
|
|
g_param_spec_set_static_nick (pspec, nick);
|
|
|
|
g_param_spec_set_static_blurb (pspec, blurb);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_property_set_prerequisite:
|
|
|
|
* @property: a #GProperty
|
|
|
|
* @gtype: the prerequisite type
|
|
|
|
*
|
|
|
|
* Sets the prerequisite type for the @property.
|
|
|
|
*
|
|
|
|
* The prerequisite type must have the @property GType as a super-type,
|
|
|
|
* and will be used to make the type checking stricter.
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
g_property_set_prerequisite (GProperty *property,
|
|
|
|
GType gtype)
|
|
|
|
{
|
|
|
|
g_return_if_fail (G_IS_PROPERTY (property));
|
|
|
|
g_return_if_fail (gtype != G_TYPE_INVALID);
|
|
|
|
g_return_if_fail (G_PARAM_SPEC (property)->value_type != G_TYPE_INVALID);
|
|
|
|
g_return_if_fail (g_type_is_a (gtype, G_PARAM_SPEC (property)->value_type));
|
|
|
|
|
|
|
|
switch (G_PARAM_SPEC (property)->value_type)
|
|
|
|
{
|
|
|
|
case G_TYPE_BOXED:
|
|
|
|
case G_TYPE_OBJECT:
|
|
|
|
G_PARAM_SPEC (property)->value_type = gtype;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_ENUM:
|
|
|
|
G_PARAM_SPEC (property)->value_type = gtype;
|
|
|
|
((GEnumProperty *) property)->e_class = g_type_class_ref (gtype);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_FLAGS:
|
|
|
|
G_PARAM_SPEC (property)->value_type = gtype;
|
|
|
|
((GFlagsProperty *) property)->f_class = g_type_class_ref (gtype);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_property_set_range_values:
|
|
|
|
* @property: a #GProperty
|
|
|
|
* @min_value: a #GValue with the minimum value of the range
|
|
|
|
* @max_value: a #GValue with the maximum value of the range
|
|
|
|
*
|
|
|
|
* Sets the valid range of @property, using #GValue<!-- -->s.
|
|
|
|
*
|
|
|
|
* This function is intended for language bindings.
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
g_property_set_range_values (GProperty *property,
|
|
|
|
const GValue *min_value,
|
|
|
|
const GValue *max_value)
|
|
|
|
{
|
|
|
|
GType gtype;
|
|
|
|
|
|
|
|
g_return_if_fail (G_IS_PROPERTY (property));
|
|
|
|
g_return_if_fail (G_PARAM_SPEC (property)->value_type != G_TYPE_INVALID);
|
|
|
|
g_return_if_fail (!property->is_installed);
|
|
|
|
g_return_if_fail (min_value != NULL && max_value != NULL);
|
|
|
|
|
|
|
|
gtype = G_PARAM_SPEC (property)->value_type;
|
|
|
|
g_return_if_fail (g_value_type_transformable (G_VALUE_TYPE (min_value), gtype));
|
|
|
|
g_return_if_fail (g_value_type_transformable (G_VALUE_TYPE (max_value), gtype));
|
|
|
|
|
|
|
|
switch (gtype)
|
|
|
|
{
|
|
|
|
case G_TYPE_BOOLEAN:
|
|
|
|
g_boolean_property_set_range (property,
|
|
|
|
g_value_get_boolean (min_value),
|
|
|
|
g_value_get_boolean (max_value));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_INT:
|
|
|
|
{
|
|
|
|
gint min_v = g_value_get_int (min_value);
|
|
|
|
gint max_v = g_value_get_int (max_value);
|
|
|
|
|
|
|
|
switch (property->type_size)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
g_int8_property_set_range (property, min_v, max_v);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
g_int16_property_set_range (property, min_v, max_v);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
g_int32_property_set_range (property, min_v, max_v);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
g_int_property_set_range (property, min_v, max_v);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_INT64:
|
|
|
|
g_int64_property_set_range (property,
|
|
|
|
g_value_get_int64 (min_value),
|
|
|
|
g_value_get_int64 (max_value));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_LONG:
|
|
|
|
g_long_property_set_range (property,
|
|
|
|
g_value_get_long (min_value),
|
|
|
|
g_value_get_long (max_value));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_UINT:
|
|
|
|
{
|
|
|
|
guint min_v = g_value_get_uint (min_value);
|
|
|
|
guint max_v = g_value_get_uint (max_value);
|
|
|
|
|
|
|
|
switch (property->type_size)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
g_uint8_property_set_range (property, min_v, max_v);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
g_uint16_property_set_range (property, min_v, max_v);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
g_uint32_property_set_range (property, min_v, max_v);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
g_uint_property_set_range (property, min_v, max_v);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_UINT64:
|
|
|
|
g_uint64_property_set_range (property,
|
|
|
|
g_value_get_uint64 (min_value),
|
|
|
|
g_value_get_uint64 (max_value));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_ULONG:
|
|
|
|
g_ulong_property_set_range (property,
|
|
|
|
g_value_get_ulong (min_value),
|
|
|
|
g_value_get_ulong (max_value));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_FLOAT:
|
|
|
|
g_float_property_set_range (property,
|
|
|
|
g_value_get_float (min_value),
|
|
|
|
g_value_get_float (max_value));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_DOUBLE:
|
|
|
|
g_double_property_set_range (property,
|
|
|
|
g_value_get_double (min_value),
|
|
|
|
g_value_get_double (max_value));
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_property_get_range_values:
|
|
|
|
* @property: a #GProperty
|
|
|
|
* @min_value: a valid #GValue, initialized to the type of @property
|
|
|
|
* @max_value: a valid #GValue, initialized to the type of @property
|
|
|
|
*
|
|
|
|
* Retrieves the bounds of the range of valid values for @property
|
|
|
|
* and stores them into @min_value and @max_value.
|
|
|
|
*
|
|
|
|
* Return value: %TRUE if successful, and %FALSE otherwise
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
g_property_get_range_values (GProperty *property,
|
|
|
|
GValue *min_value,
|
|
|
|
GValue *max_value)
|
|
|
|
{
|
|
|
|
gboolean retval;
|
|
|
|
GType gtype;
|
|
|
|
|
|
|
|
g_return_val_if_fail (G_IS_PROPERTY (property), FALSE);
|
|
|
|
g_return_val_if_fail (min_value != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (max_value != NULL, FALSE);
|
|
|
|
|
|
|
|
gtype = G_PARAM_SPEC (property)->value_type;
|
|
|
|
g_return_val_if_fail (g_value_type_compatible (gtype, G_VALUE_TYPE (min_value)), FALSE);
|
|
|
|
g_return_val_if_fail (g_value_type_compatible (gtype, G_VALUE_TYPE (max_value)), FALSE);
|
|
|
|
|
|
|
|
switch (gtype)
|
|
|
|
{
|
|
|
|
case G_TYPE_BOOLEAN:
|
|
|
|
{
|
|
|
|
gboolean min_v, max_v;
|
|
|
|
|
|
|
|
g_boolean_property_get_range (property, &min_v, &max_v);
|
|
|
|
g_value_set_boolean (min_value, min_v);
|
|
|
|
g_value_set_boolean (max_value, max_v);
|
|
|
|
}
|
|
|
|
retval = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_INT:
|
|
|
|
{
|
|
|
|
gint min_v, max_v;
|
|
|
|
|
|
|
|
switch (property->type_size)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
g_int8_property_get_range (property, (gint8 *) &min_v, (gint8 *) &max_v);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
g_int16_property_get_range (property, (gint16 *) &min_v, (gint16 *) &max_v);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
g_int32_property_get_range (property, (gint32 *) &min_v, (gint32 *) &max_v);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
g_int_property_get_range (property, &min_v, &max_v);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_value_set_int (min_value, min_v);
|
|
|
|
g_value_set_int (max_value, max_v);
|
|
|
|
}
|
|
|
|
retval = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_INT64:
|
|
|
|
{
|
|
|
|
gint64 min_v, max_v;
|
|
|
|
|
|
|
|
g_int64_property_get_range (property, &min_v, &max_v);
|
|
|
|
g_value_set_int64 (min_value, min_v);
|
|
|
|
g_value_set_int64 (max_value, max_v);
|
|
|
|
}
|
|
|
|
retval = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_LONG:
|
|
|
|
{
|
|
|
|
glong min_v, max_v;
|
|
|
|
|
|
|
|
g_long_property_get_range (property, &min_v, &max_v);
|
|
|
|
g_value_set_long (min_value, min_v);
|
|
|
|
g_value_set_long (max_value, max_v);
|
|
|
|
}
|
|
|
|
retval = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_UINT:
|
|
|
|
{
|
|
|
|
guint min_v, max_v;
|
|
|
|
|
|
|
|
switch (property->type_size)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
g_uint8_property_get_range (property, (guint8 *) &min_v, (guint8 *) &max_v);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
g_uint16_property_get_range (property, (guint16 *) &min_v, (guint16 *) &max_v);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
g_uint32_property_get_range (property, (guint32 *) &min_v, (guint32 *) &max_v);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
g_uint_property_get_range (property, &min_v, &max_v);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_value_set_uint (min_value, min_v);
|
|
|
|
g_value_set_uint (max_value, max_v);
|
|
|
|
}
|
|
|
|
retval = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_UINT64:
|
|
|
|
{
|
|
|
|
guint64 min_v, max_v;
|
|
|
|
|
|
|
|
g_uint64_property_get_range (property, &min_v, &max_v);
|
|
|
|
g_value_set_uint64 (min_value, min_v);
|
|
|
|
g_value_set_uint64 (max_value, max_v);
|
|
|
|
}
|
|
|
|
retval = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_ULONG:
|
|
|
|
{
|
|
|
|
gulong min_v, max_v;
|
|
|
|
|
|
|
|
g_ulong_property_get_range (property, &min_v, &max_v);
|
|
|
|
g_value_set_ulong (min_value, min_v);
|
|
|
|
g_value_set_ulong (max_value, max_v);
|
|
|
|
}
|
|
|
|
retval = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_FLOAT:
|
|
|
|
{
|
|
|
|
gfloat min_v, max_v;
|
|
|
|
|
|
|
|
g_float_property_get_range (property, &min_v, &max_v);
|
|
|
|
g_value_set_float (min_value, min_v);
|
|
|
|
g_value_set_float (max_value, max_v);
|
|
|
|
}
|
|
|
|
retval = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_DOUBLE:
|
|
|
|
{
|
|
|
|
gdouble min_v, max_v;
|
|
|
|
|
|
|
|
g_double_property_get_range (property, &min_v, &max_v);
|
|
|
|
g_value_set_double (min_value, min_v);
|
|
|
|
g_value_set_double (max_value, max_v);
|
|
|
|
}
|
|
|
|
retval = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
g_critical (G_STRLOC ": Invalid type '%s'", g_type_name (gtype));
|
|
|
|
retval = FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_property_set_range:
|
|
|
|
* @property: a #GProperty
|
|
|
|
* @...: the minimum and maximum values of the range
|
|
|
|
*
|
|
|
|
* Sets the range of valid values for @property.
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
g_property_set_range (GProperty *property,
|
|
|
|
...)
|
|
|
|
{
|
|
|
|
GType gtype;
|
|
|
|
va_list args;
|
|
|
|
|
|
|
|
g_return_if_fail (G_IS_PROPERTY (property));
|
|
|
|
g_return_if_fail (!property->is_installed);
|
|
|
|
|
|
|
|
gtype = G_PARAM_SPEC (property)->value_type;
|
|
|
|
g_return_if_fail (gtype != G_TYPE_INVALID);
|
|
|
|
|
|
|
|
va_start (args, property);
|
|
|
|
|
|
|
|
switch (G_TYPE_FUNDAMENTAL (gtype))
|
|
|
|
{
|
|
|
|
case G_TYPE_BOOLEAN:
|
|
|
|
{
|
|
|
|
gboolean min_v = va_arg (args, gboolean);
|
|
|
|
gboolean max_v = va_arg (args, gboolean);
|
|
|
|
|
|
|
|
g_boolean_property_set_range (property, min_v, max_v);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_INT:
|
|
|
|
{
|
|
|
|
gint min_v = va_arg (args, gint);
|
|
|
|
gint max_v = va_arg (args, gint);
|
|
|
|
|
|
|
|
switch (property->type_size)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
g_int8_property_set_range (property, min_v, max_v);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
g_int16_property_set_range (property, min_v, max_v);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
g_int32_property_set_range (property, min_v, max_v);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
g_int_property_set_range (property, min_v, max_v);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_INT64:
|
|
|
|
{
|
|
|
|
gint64 min_v = va_arg (args, gint64);
|
|
|
|
gint64 max_v = va_arg (args, gint64);
|
|
|
|
|
|
|
|
g_int64_property_set_range (property, min_v, max_v);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_LONG:
|
|
|
|
{
|
|
|
|
glong min_v = va_arg (args, glong);
|
|
|
|
glong max_v = va_arg (args, glong);
|
|
|
|
|
|
|
|
g_long_property_set_range (property, min_v, max_v);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_UINT:
|
|
|
|
{
|
|
|
|
guint min_v = va_arg (args, guint);
|
|
|
|
guint max_v = va_arg (args, guint);
|
|
|
|
|
|
|
|
switch (property->type_size)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
g_uint8_property_set_range (property, min_v, max_v);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
g_uint16_property_set_range (property, min_v, max_v);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
g_uint32_property_set_range (property, min_v, max_v);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
g_uint_property_set_range (property, min_v, max_v);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_UINT64:
|
|
|
|
{
|
|
|
|
guint64 min_v = va_arg (args, guint64);
|
|
|
|
guint64 max_v = va_arg (args, guint64);
|
|
|
|
|
|
|
|
g_uint64_property_set_range (property, min_v, max_v);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_ULONG:
|
|
|
|
{
|
|
|
|
gulong min_v = va_arg (args, gulong);
|
|
|
|
gulong max_v = va_arg (args, gulong);
|
|
|
|
|
|
|
|
g_ulong_property_set_range (property, min_v, max_v);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_FLOAT:
|
|
|
|
{
|
|
|
|
gfloat min_v = va_arg (args, gdouble);
|
|
|
|
gfloat max_v = va_arg (args, gdouble);
|
|
|
|
|
|
|
|
g_float_property_set_range (property, min_v, max_v);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_DOUBLE:
|
|
|
|
{
|
|
|
|
gdouble min_v = va_arg (args, gdouble);
|
|
|
|
gdouble max_v = va_arg (args, gdouble);
|
|
|
|
|
|
|
|
g_double_property_set_range (property, min_v, max_v);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
g_critical (G_STRLOC ": Invalid type %s", g_type_name (gtype));
|
|
|
|
}
|
|
|
|
|
|
|
|
va_end (args);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_property_get_range:
|
|
|
|
* @property: a #GProperty
|
|
|
|
* @...: the return locations for the minimum and maximum values
|
|
|
|
* of the range
|
|
|
|
*
|
|
|
|
* Retrieves the bounds of the range of valid values for @property.
|
|
|
|
*
|
|
|
|
* Return value: %TRUE on success, and %FALSE otherwise
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
g_property_get_range (GProperty *property,
|
|
|
|
...)
|
|
|
|
{
|
|
|
|
va_list var_args;
|
|
|
|
GType gtype;
|
|
|
|
gboolean retval;
|
|
|
|
gpointer min_p, max_p;
|
|
|
|
|
|
|
|
g_return_val_if_fail (G_IS_PROPERTY (property), FALSE);
|
|
|
|
g_return_val_if_fail (G_PARAM_SPEC (property)->value_type != G_TYPE_INVALID, FALSE);
|
|
|
|
|
|
|
|
gtype = G_PARAM_SPEC (property)->value_type;
|
|
|
|
|
|
|
|
va_start (var_args, property);
|
|
|
|
|
|
|
|
min_p = va_arg (var_args, gpointer);
|
|
|
|
max_p = va_arg (var_args, gpointer);
|
|
|
|
|
|
|
|
switch (G_TYPE_FUNDAMENTAL (gtype))
|
|
|
|
{
|
|
|
|
case G_TYPE_BOOLEAN:
|
|
|
|
g_boolean_property_get_range (property, (gboolean *) min_p, (gboolean *) max_p);
|
|
|
|
retval = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_INT:
|
|
|
|
switch (property->type_size)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
g_int8_property_get_range (property, (gint8 *) min_p, (gint8 *) max_p);
|
|
|
|
retval = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
g_int16_property_get_range (property, (gint16 *) min_p, (gint16 *) max_p);
|
|
|
|
retval = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
g_int32_property_get_range (property, (gint32 *) min_p, (gint32 *) max_p);
|
|
|
|
retval = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
g_int_property_get_range (property, (gint *) min_p, (gint *) max_p);
|
|
|
|
retval = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_INT64:
|
|
|
|
g_int64_property_get_range (property, (gint64 *) min_p, (gint64 *) max_p);
|
|
|
|
retval = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_LONG:
|
|
|
|
g_long_property_get_range (property, (glong *) min_p, (glong *) max_p);
|
|
|
|
retval = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_UINT:
|
|
|
|
switch (property->type_size)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
g_uint8_property_get_range (property, (guint8 *) min_p, (guint8 *) max_p);
|
|
|
|
retval = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
g_uint16_property_get_range (property, (guint16 *) min_p, (guint16 *) max_p);
|
|
|
|
retval = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
g_uint32_property_get_range (property, (guint32 *) min_p, (guint32 *) max_p);
|
|
|
|
retval = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
g_uint_property_get_range (property, (guint *) min_p, (guint *) max_p);
|
|
|
|
retval = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_UINT64:
|
|
|
|
g_uint64_property_get_range (property, (guint64 *) min_p, (guint64 *) max_p);
|
|
|
|
retval = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_ULONG:
|
|
|
|
g_ulong_property_get_range (property, (gulong *) min_p, (gulong *) max_p);
|
|
|
|
retval = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_FLOAT:
|
|
|
|
g_float_property_get_range (property, (gfloat *) min_p, (gfloat *) max_p);
|
|
|
|
retval = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_DOUBLE:
|
|
|
|
g_double_property_get_range (property, (gdouble *) min_p, (gdouble *) max_p);
|
|
|
|
retval = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
g_critical (G_STRLOC ": Invalid type %s", g_type_name (gtype));
|
|
|
|
retval = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
va_end (var_args);
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_property_set_default_value:
|
|
|
|
* @property: a #GProperty
|
|
|
|
* @gobject_class: a #GObject class pointer
|
|
|
|
* @default_value: a #GValue, initialized to the property type
|
|
|
|
* containing the default value for the given class
|
|
|
|
*
|
|
|
|
* Sets the default value of @property for the given class.
|
|
|
|
*
|
|
|
|
* This function is a #GValue variant of g_property_set_default(), and
|
|
|
|
* it is meant to be used by language bindings.
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
g_property_set_default_value (GProperty *property,
|
|
|
|
const GValue *default_value)
|
|
|
|
{
|
|
|
|
GValue *value;
|
|
|
|
GType gtype;
|
|
|
|
|
|
|
|
g_return_if_fail (G_IS_PROPERTY (property));
|
|
|
|
g_return_if_fail (G_PARAM_SPEC (property)->value_type != G_TYPE_INVALID);
|
|
|
|
g_return_if_fail (default_value != NULL);
|
|
|
|
|
|
|
|
gtype = G_PARAM_SPEC (property)->value_type;
|
|
|
|
|
|
|
|
g_return_if_fail (g_value_type_transformable (G_VALUE_TYPE (default_value), gtype));
|
|
|
|
|
|
|
|
value = g_new0 (GValue, 1);
|
|
|
|
g_value_init (value, gtype);
|
|
|
|
if (!g_value_transform (default_value, value))
|
|
|
|
{
|
|
|
|
g_critical (G_STRLOC ": unable to set the default value for "
|
|
|
|
"property '%s': the type %s of the value is not "
|
|
|
|
"compatible with the type of the %s property",
|
|
|
|
G_PARAM_SPEC (property)->name,
|
|
|
|
g_type_name (G_VALUE_TYPE (default_value)),
|
|
|
|
g_type_name (gtype));
|
|
|
|
|
|
|
|
g_value_unset (value);
|
|
|
|
g_free (value);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
property_set_default_for_type (property, G_TYPE_INVALID, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_property_override_default_value:
|
|
|
|
* @property: a #GProperty
|
|
|
|
* @class_gtype: the type of the class overriding the value
|
|
|
|
* @default_value: a #GValue containing a value with the type of the
|
|
|
|
* property or a transformable type
|
|
|
|
*
|
|
|
|
* Overrides the default value of a @property for the given class
|
|
|
|
* type.
|
|
|
|
*
|
|
|
|
* This function should only be called by language bindings.
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
g_property_override_default_value (GProperty *property,
|
|
|
|
GType class_gtype,
|
|
|
|
const GValue *default_value)
|
|
|
|
{
|
|
|
|
GValue *value;
|
|
|
|
GType gtype;
|
|
|
|
|
|
|
|
g_return_if_fail (G_IS_PROPERTY (property));
|
|
|
|
g_return_if_fail (G_PARAM_SPEC (property)->value_type != G_TYPE_INVALID);
|
|
|
|
g_return_if_fail (g_type_name (class_gtype) != 0);
|
|
|
|
g_return_if_fail (default_value != NULL);
|
|
|
|
|
|
|
|
gtype = G_PARAM_SPEC (property)->value_type;
|
|
|
|
|
|
|
|
g_return_if_fail (g_value_type_transformable (G_VALUE_TYPE (default_value), gtype));
|
|
|
|
|
|
|
|
value = g_new0 (GValue, 1);
|
|
|
|
g_value_init (value, gtype);
|
|
|
|
if (!g_value_transform (default_value, value))
|
|
|
|
{
|
|
|
|
g_critical (G_STRLOC ": unable to set the default value for "
|
|
|
|
"property '%s': the type %s of the value is not "
|
|
|
|
"compatible with the type of the %s property",
|
|
|
|
G_PARAM_SPEC (property)->name,
|
|
|
|
g_type_name (G_VALUE_TYPE (default_value)),
|
|
|
|
g_type_name (gtype));
|
|
|
|
|
|
|
|
g_value_unset (value);
|
|
|
|
g_free (value);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* takes ownership of value */
|
|
|
|
property_set_default_for_type (property, class_gtype, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_property_get_default_value_for_type:
|
|
|
|
* @property: a #GProperty
|
|
|
|
* @gtype: a valid #GType
|
|
|
|
* @value: a #GValue initialized to the property type
|
|
|
|
*
|
|
|
|
* Retrieves the default value of the property for the given type.
|
|
|
|
*
|
|
|
|
* This function is meant to be used by language bindings and other
|
|
|
|
* introspection tools; #GObject implementations should use
|
|
|
|
* g_property_get_default() instead.
|
|
|
|
*
|
|
|
|
* Return value: %TRUE if there is a default got the given type,
|
|
|
|
* and %FALSE otherwise.
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
g_property_get_default_value_for_type (GProperty *property,
|
|
|
|
GType gtype,
|
|
|
|
GValue *value)
|
|
|
|
{
|
|
|
|
const GValue *default_value = NULL;
|
|
|
|
GType iter;
|
|
|
|
|
|
|
|
g_return_val_if_fail (G_IS_PROPERTY (property), FALSE);
|
|
|
|
g_return_val_if_fail (G_PARAM_SPEC (property)->value_type != G_TYPE_INVALID, FALSE);
|
|
|
|
g_return_val_if_fail (g_type_name (gtype) != 0, FALSE);
|
|
|
|
|
|
|
|
/* we need to recurse through the inheritance chain... */
|
|
|
|
iter = gtype;
|
|
|
|
while (iter != G_TYPE_INVALID && default_value == NULL)
|
|
|
|
{
|
|
|
|
default_value = property_get_default_for_type (property, iter);
|
|
|
|
gtype = g_type_parent (iter);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (default_value != NULL)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
/* ... and eventually check the implemented interfaces */
|
|
|
|
if (default_value == NULL)
|
|
|
|
{
|
|
|
|
GType *ifaces;
|
|
|
|
guint n_ifaces;
|
|
|
|
|
|
|
|
ifaces = g_type_interfaces (gtype, &n_ifaces);
|
|
|
|
while (n_ifaces-- && default_value == NULL)
|
|
|
|
{
|
|
|
|
iter = ifaces[n_ifaces];
|
|
|
|
default_value = property_get_default_for_type (property, iter);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free (ifaces);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (default_value != NULL)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
/* if the property hasn't been overridden then we look for the default */
|
|
|
|
default_value = property_get_default_for_type (property, G_TYPE_INVALID);
|
|
|
|
|
|
|
|
if (default_value == NULL)
|
|
|
|
{
|
|
|
|
g_critical (G_STRLOC ": No default value of property '%s' "
|
|
|
|
"was found for type '%s'",
|
|
|
|
G_PARAM_SPEC (property)->name,
|
|
|
|
g_type_name (gtype));
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
out:
|
|
|
|
if (!g_value_transform (default_value, value))
|
|
|
|
{
|
|
|
|
g_critical (G_STRLOC ": Unable to transform a value of type '%s' "
|
|
|
|
"into a value of type '%s'",
|
|
|
|
g_type_name (G_VALUE_TYPE (default_value)),
|
|
|
|
g_type_name (G_VALUE_TYPE (value)));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_property_get_default_value:
|
|
|
|
* @property: a #GProperty
|
|
|
|
* @gobject: a #GObject
|
|
|
|
* @value: a #GValue initialized to the type of the property
|
|
|
|
*
|
|
|
|
* Retrieves the default value of @property for the given @gobject
|
|
|
|
* type.
|
|
|
|
*
|
|
|
|
* This function should only be used by language bindings and other
|
|
|
|
* introspection tools.
|
|
|
|
*
|
|
|
|
* Return value: %TRUE if a default value was found, and %FALSE
|
|
|
|
* otherwise
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
g_property_get_default_value (GProperty *property,
|
|
|
|
gpointer gobject,
|
|
|
|
GValue *value)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (G_IS_OBJECT (gobject), FALSE);
|
|
|
|
|
|
|
|
return g_property_get_default_value_for_type (property,
|
|
|
|
G_OBJECT_TYPE (gobject),
|
|
|
|
value);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_property_set_default:
|
|
|
|
* @property: a #GProperty
|
|
|
|
* @...: the default value for the property
|
|
|
|
*
|
|
|
|
* Sets the default value of @property.
|
|
|
|
*
|
|
|
|
* This function can only be called once for each property; derived
|
|
|
|
* types should call g_property_override_default() instead.
|
|
|
|
*
|
|
|
|
* See also g_property_override_default() and
|
|
|
|
* g_object_class_override_property_default().
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
g_property_set_default (GProperty *property,
|
|
|
|
...)
|
|
|
|
{
|
|
|
|
GValue *value;
|
|
|
|
GType p_type;
|
|
|
|
gchar *error;
|
|
|
|
va_list var_args;
|
|
|
|
|
|
|
|
g_return_if_fail (G_IS_PROPERTY (property));
|
|
|
|
g_return_if_fail (G_PARAM_SPEC (property)->value_type != G_TYPE_INVALID);
|
|
|
|
|
|
|
|
p_type = G_PARAM_SPEC (property)->value_type;
|
|
|
|
|
|
|
|
va_start (var_args, property);
|
|
|
|
|
|
|
|
value = g_new0 (GValue, 1);
|
|
|
|
G_VALUE_COLLECT_INIT (value, p_type, var_args, 0, &error);
|
|
|
|
if (error != NULL)
|
|
|
|
{
|
|
|
|
g_critical (G_STRLOC ": %s", error);
|
|
|
|
g_free (error);
|
|
|
|
g_value_unset (value);
|
|
|
|
g_free (value);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* takes ownership of the GValue */
|
|
|
|
property_set_default_for_type (property, G_TYPE_INVALID, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
va_end (var_args);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_property_get_default:
|
|
|
|
* @property: a #GProperty
|
|
|
|
* @gobject: a #GObject instance
|
|
|
|
* @...: the return location for the default value
|
|
|
|
*
|
|
|
|
* Retrieves the default value of @property for the type of the
|
|
|
|
* instance passed.
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
g_property_get_default (GProperty *property,
|
|
|
|
gpointer gobject,
|
|
|
|
...)
|
|
|
|
{
|
|
|
|
GValue value = { 0, };
|
|
|
|
GType gtype, p_type;
|
|
|
|
gchar *error;
|
|
|
|
va_list var_args;
|
|
|
|
const GValue *default_value = NULL;
|
|
|
|
|
|
|
|
g_return_if_fail (G_IS_PROPERTY (property));
|
|
|
|
g_return_if_fail (G_IS_OBJECT (gobject));
|
|
|
|
g_return_if_fail (G_PARAM_SPEC (property)->value_type != G_TYPE_INVALID);
|
|
|
|
|
|
|
|
p_type = G_PARAM_SPEC (property)->value_type;
|
|
|
|
|
|
|
|
/* we perform a copy here because if the default value was not found,
|
|
|
|
* we can use the pre-initialized value safely in G_VALUE_LCOPY and
|
|
|
|
* return something sensible
|
|
|
|
*/
|
|
|
|
g_value_init (&value, p_type);
|
|
|
|
|
|
|
|
gtype = G_OBJECT_TYPE (gobject);
|
|
|
|
|
|
|
|
/* we need to recurse through the inheritance chain... */
|
|
|
|
while (gtype != G_TYPE_INVALID && default_value == NULL)
|
|
|
|
{
|
|
|
|
default_value = property_get_default_for_type (property, gtype);
|
|
|
|
gtype = g_type_parent (gtype);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (default_value != NULL)
|
|
|
|
goto lcopy;
|
|
|
|
|
|
|
|
/* ... and eventually check the implemented interfaces */
|
|
|
|
if (default_value == NULL)
|
|
|
|
{
|
|
|
|
GType *ifaces;
|
|
|
|
guint n_ifaces;
|
|
|
|
|
|
|
|
gtype = G_OBJECT_TYPE (gobject);
|
|
|
|
|
|
|
|
ifaces = g_type_interfaces (gtype, &n_ifaces);
|
|
|
|
while (n_ifaces-- && default_value == NULL)
|
|
|
|
{
|
|
|
|
gtype = ifaces[n_ifaces];
|
|
|
|
default_value = property_get_default_for_type (property, gtype);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free (ifaces);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (default_value != NULL)
|
|
|
|
goto lcopy;
|
|
|
|
|
|
|
|
/* if the property hasn't been overridden then we look for the default */
|
|
|
|
default_value = property_get_default_for_type (property, G_TYPE_INVALID);
|
|
|
|
|
|
|
|
lcopy:
|
|
|
|
if (default_value != NULL)
|
|
|
|
g_value_copy (default_value, &value);
|
|
|
|
else
|
|
|
|
g_critical (G_STRLOC ": No default value of property '%s' "
|
|
|
|
"was found for type '%s'",
|
|
|
|
G_PARAM_SPEC (property)->name,
|
|
|
|
G_OBJECT_TYPE_NAME (gobject));
|
|
|
|
|
|
|
|
va_start (var_args, gobject);
|
|
|
|
|
|
|
|
G_VALUE_LCOPY (&value, var_args, 0, &error);
|
|
|
|
if (error != NULL)
|
|
|
|
{
|
|
|
|
g_warning (G_STRLOC ": %s", error);
|
|
|
|
g_free (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
va_end (var_args);
|
|
|
|
g_value_unset (&value);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_property_override_default:
|
|
|
|
* @property: a #GProperty
|
|
|
|
* @class_gtype: the type of the class overriding the default
|
|
|
|
* @...: the new default value for the property
|
|
|
|
*
|
|
|
|
* Overrides the default value of @property for the given class type.
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
g_property_override_default (GProperty *property,
|
|
|
|
GType class_gtype,
|
|
|
|
...)
|
|
|
|
{
|
|
|
|
GValue *value;
|
|
|
|
GType p_type;
|
|
|
|
gchar *error;
|
|
|
|
va_list var_args;
|
|
|
|
|
|
|
|
g_return_if_fail (G_IS_PROPERTY (property));
|
|
|
|
g_return_if_fail (G_PARAM_SPEC (property)->value_type != G_TYPE_INVALID);
|
|
|
|
g_return_if_fail (g_type_name (class_gtype) != 0);
|
|
|
|
|
|
|
|
p_type = G_PARAM_SPEC (property)->value_type;
|
|
|
|
|
|
|
|
va_start (var_args, class_gtype);
|
|
|
|
|
|
|
|
value = g_new0 (GValue, 1);
|
|
|
|
G_VALUE_COLLECT_INIT (value, p_type, var_args, 0, &error);
|
|
|
|
if (error != NULL)
|
|
|
|
{
|
|
|
|
g_critical (G_STRLOC ": %s", error);
|
|
|
|
g_free (error);
|
|
|
|
g_value_unset (value);
|
|
|
|
g_free (value);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* takes ownership of the GValue */
|
|
|
|
property_set_default_for_type (property, class_gtype, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
va_end (var_args);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_property_set_va:
|
|
|
|
* @property: a #GProperty
|
|
|
|
* @gobject: a #GObject instance
|
|
|
|
* @flags: collection flags, as a bitwise or of #GPropertyCollectFlags values
|
|
|
|
* @args: the value to set, inside a pointer to a #va_list
|
|
|
|
*
|
|
|
|
* Sets the value of @property for the given #GObject instance.
|
|
|
|
*
|
|
|
|
* This function is the va_list variant of g_property_set().
|
|
|
|
*
|
|
|
|
* Return value: %TRUE if the value was set, and %FALSE otherwise
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
g_property_set_va (GProperty *property,
|
|
|
|
gpointer gobject,
|
|
|
|
GPropertyCollectFlags flags,
|
|
|
|
va_list *args)
|
|
|
|
{
|
|
|
|
gboolean retval;
|
|
|
|
GType gtype;
|
|
|
|
|
|
|
|
g_return_val_if_fail (G_IS_PROPERTY (property), FALSE);
|
|
|
|
g_return_val_if_fail (G_IS_OBJECT (gobject), FALSE);
|
|
|
|
g_return_val_if_fail (property->is_installed, FALSE);
|
|
|
|
|
|
|
|
g_object_ref (gobject);
|
|
|
|
|
|
|
|
gtype = ((GParamSpec *) property)->value_type;
|
|
|
|
|
|
|
|
switch (G_TYPE_FUNDAMENTAL (gtype))
|
|
|
|
{
|
|
|
|
case G_TYPE_BOOLEAN:
|
|
|
|
retval = g_boolean_property_set_value (property, gobject, va_arg (*args, gboolean));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_INT:
|
|
|
|
switch (property->type_size)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
retval = g_int8_property_set_value (property, gobject, va_arg (*args, gint));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
retval = g_int16_property_set_value (property, gobject, va_arg (*args, gint));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
retval = g_int32_property_set_value (property, gobject, va_arg (*args, gint));
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
retval = g_int_property_set_value (property, gobject, va_arg (*args, gint));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_INT64:
|
|
|
|
retval = g_int64_property_set_value (property, gobject, va_arg (*args, gint64));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_LONG:
|
|
|
|
retval = g_long_property_set_value (property, gobject, va_arg (*args, glong));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_UINT:
|
|
|
|
switch (property->type_size)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
retval = g_uint8_property_set_value (property, gobject, va_arg (*args, guint));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
retval = g_uint16_property_set_value (property, gobject, va_arg (*args, guint));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
retval = g_uint32_property_set_value (property, gobject, va_arg (*args, guint));
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
retval = g_uint_property_set_value (property, gobject, va_arg (*args, guint));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_UINT64:
|
|
|
|
retval = g_uint64_property_set_value (property, gobject, va_arg (*args, guint64));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_ULONG:
|
|
|
|
retval = g_ulong_property_set_value (property, gobject, va_arg (*args, gulong));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_ENUM:
|
|
|
|
retval = g_enum_property_set_value (property, gobject, va_arg (*args, glong));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_FLAGS:
|
|
|
|
retval = g_flags_property_set_value (property, gobject, va_arg (*args, gulong));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_FLOAT:
|
|
|
|
retval = g_float_property_set_value (property, gobject, va_arg (*args, gdouble));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_DOUBLE:
|
|
|
|
retval = g_double_property_set_value (property, gobject, va_arg (*args, gdouble));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_STRING:
|
|
|
|
retval = g_string_property_set_value (property, gobject, va_arg (*args, gchar *));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_BOXED:
|
|
|
|
retval = g_boxed_property_set_value (property, gobject, va_arg (*args, gpointer));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_OBJECT:
|
|
|
|
retval = g_object_property_set_value (property, gobject, va_arg (*args, gpointer));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_POINTER:
|
|
|
|
retval = g_pointer_property_set_value (property, gobject, va_arg (*args, gpointer));
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
g_critical (G_STRLOC ": Invalid type %s", g_type_name (gtype));
|
|
|
|
retval = FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_object_unref (gobject);
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_property_get_va:
|
|
|
|
* @property: a #GProperty
|
|
|
|
* @gobject: a #GObject instance
|
|
|
|
* @flags: collection flags
|
|
|
|
* @args: a pointer to a #va_list with the property
|
|
|
|
*
|
|
|
|
* Retrieves the value of @property for the given #GObject instance.
|
|
|
|
*
|
|
|
|
* This function is the va_list variant of g_property_get().
|
|
|
|
*
|
|
|
|
* Return value: %TRUE if the value was successfully retrieved, and
|
|
|
|
* %FALSE otherwise
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
g_property_get_va (GProperty *property,
|
|
|
|
gpointer gobject,
|
|
|
|
GPropertyCollectFlags flags,
|
|
|
|
va_list *args)
|
|
|
|
{
|
|
|
|
GType gtype;
|
|
|
|
gpointer ret_p = NULL;
|
|
|
|
|
|
|
|
g_return_val_if_fail (G_IS_PROPERTY (property), FALSE);
|
|
|
|
g_return_val_if_fail (G_IS_OBJECT (gobject), FALSE);
|
|
|
|
g_return_val_if_fail (property->is_installed, FALSE);
|
|
|
|
|
|
|
|
gtype = G_PARAM_SPEC (property)->value_type;
|
|
|
|
|
|
|
|
ret_p = va_arg (*args, gpointer);
|
|
|
|
if (ret_p == NULL)
|
|
|
|
{
|
|
|
|
g_critical (G_STRLOC ": value location for a property of type '%s' passed as NULL",
|
|
|
|
g_type_name (gtype));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (G_TYPE_FUNDAMENTAL (gtype))
|
|
|
|
{
|
|
|
|
case G_TYPE_BOOLEAN:
|
|
|
|
(* (gboolean *) ret_p) = g_boolean_property_get_value (property, gobject);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_INT:
|
|
|
|
switch (property->type_size)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
(* (gint8 *) ret_p) = g_int8_property_get_value (property, gobject);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
(* (gint16 *) ret_p) = g_int16_property_get_value (property, gobject);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
(* (gint32 *) ret_p) = g_int32_property_get_value (property, gobject);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
(* (gint *) ret_p) = g_int_property_get_value (property, gobject);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_INT64:
|
|
|
|
(* (gint64 *) ret_p) = g_int64_property_get_value (property, gobject);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_LONG:
|
|
|
|
(* (glong *) ret_p) = g_long_property_get_value (property, gobject);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_UINT:
|
|
|
|
switch (property->type_size)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
(* (guint8 *) ret_p) = g_uint8_property_get_value (property, gobject);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
(* (guint16 *) ret_p) = g_uint16_property_get_value (property, gobject);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
(* (guint32 *) ret_p) = g_uint32_property_get_value (property, gobject);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
(* (guint *) ret_p) = g_uint_property_get_value (property, gobject);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_UINT64:
|
|
|
|
(* (guint64 *) ret_p) = g_uint64_property_get_value (property, gobject);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_ULONG:
|
|
|
|
(* (gulong *) ret_p) = g_ulong_property_get_value (property, gobject);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_ENUM:
|
|
|
|
(* (glong *) ret_p) = g_enum_property_get_value (property, gobject);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_FLAGS:
|
|
|
|
(* (gulong *) ret_p) = g_flags_property_get_value (property, gobject);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_FLOAT:
|
|
|
|
(* (gfloat *) ret_p) = g_float_property_get_value (property, gobject);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_DOUBLE:
|
|
|
|
(* (gdouble *) ret_p) = g_double_property_get_value (property, gobject);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_STRING:
|
|
|
|
{
|
|
|
|
const gchar *value;
|
|
|
|
|
|
|
|
value = g_string_property_get_value (property, gobject);
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_BOXED:
|
|
|
|
{
|
|
|
|
gpointer boxed;
|
|
|
|
|
|
|
|
boxed = g_boxed_property_get_value (property, gobject);
|
|
|
|
|
|
|
|
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);
|
|
|
|
else
|
|
|
|
(* (gpointer *) ret_p) = NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
(* (gpointer *) ret_p) = (gpointer) boxed;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_OBJECT:
|
|
|
|
{
|
|
|
|
gpointer obj = g_object_property_get_value (property, gobject);
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_POINTER:
|
|
|
|
(* (gpointer *) ret_p) = g_pointer_property_get_value (property, gobject);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
g_critical (G_STRLOC ": Invalid type %s", g_type_name (gtype));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_property_set:
|
|
|
|
* @property: a #GProperty
|
|
|
|
* @gobject: a #GObject instance
|
|
|
|
* @...: the value to be set
|
|
|
|
*
|
|
|
|
* Sets the value of the @property for the given #GObject instance.
|
|
|
|
*
|
|
|
|
* The value will either be copied or have its reference count increased.
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
g_property_set (GProperty *property,
|
|
|
|
gpointer gobject,
|
|
|
|
...)
|
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
gboolean res;
|
|
|
|
|
|
|
|
va_start (args, gobject);
|
|
|
|
res = g_property_set_va (property, gobject, 0, &args);
|
|
|
|
va_end (args);
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_property_get:
|
|
|
|
* @property: a #GProperty
|
|
|
|
* @gobject: a #GObject instance
|
|
|
|
* @...: a pointer to the value to be retrieved
|
|
|
|
*
|
|
|
|
* Retrieves the value of the @property for the given #GObject instance.
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
g_property_get (GProperty *property,
|
|
|
|
gpointer gobject,
|
|
|
|
...)
|
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
gboolean retval;
|
|
|
|
|
|
|
|
va_start (args, gobject);
|
|
|
|
retval = g_property_get_va (property, gobject, 0, &args);
|
|
|
|
va_end (args);
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_property_set_value:
|
|
|
|
* @property: a #GProperty
|
|
|
|
* @gobject: a #GObject instance
|
|
|
|
* @value: a #GValue
|
|
|
|
*
|
|
|
|
* Sets the value of the @property for the given #GObject instance
|
|
|
|
* by unboxing it from the #GValue, honouring eventual transformation
|
|
|
|
* functions between the #GValue type and the property type.
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
g_property_set_value (GProperty *property,
|
|
|
|
gpointer gobject,
|
|
|
|
const GValue *value)
|
|
|
|
{
|
|
|
|
GValue copy = { 0, };
|
|
|
|
GType gtype;
|
|
|
|
|
|
|
|
g_return_if_fail (G_IS_PROPERTY (property));
|
|
|
|
g_return_if_fail (G_IS_OBJECT (gobject));
|
|
|
|
g_return_if_fail (value != NULL);
|
|
|
|
g_return_if_fail (property->is_installed);
|
|
|
|
|
|
|
|
gtype = G_PARAM_SPEC (property)->value_type;
|
|
|
|
|
|
|
|
g_return_if_fail (g_value_type_transformable (G_VALUE_TYPE (value), gtype));
|
|
|
|
|
|
|
|
g_value_init (©, gtype);
|
|
|
|
if (!g_value_transform (value, ©))
|
|
|
|
{
|
|
|
|
g_critical (G_STRLOC ": Unable to transform a value of type '%s' "
|
|
|
|
"into a value of type '%s'",
|
|
|
|
g_type_name (G_VALUE_TYPE (value)),
|
|
|
|
g_type_name (gtype));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_object_ref (gobject);
|
|
|
|
|
|
|
|
switch (G_TYPE_FUNDAMENTAL (gtype))
|
|
|
|
{
|
|
|
|
case G_TYPE_BOOLEAN:
|
|
|
|
g_boolean_property_set_value (property, gobject, g_value_get_boolean (©));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_INT:
|
|
|
|
{
|
|
|
|
gint val = g_value_get_int (©);
|
|
|
|
|
|
|
|
switch (property->type_size)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
g_int8_property_set_value (property, gobject, val);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
g_int16_property_set_value (property, gobject, val);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
g_int32_property_set_value (property, gobject, val);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
g_int_property_set_value (property, gobject, val);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_INT64:
|
|
|
|
g_int64_property_set_value (property, gobject, g_value_get_int64 (©));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_LONG:
|
|
|
|
g_long_property_set_value (property, gobject, g_value_get_long (©));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_UINT:
|
|
|
|
{
|
|
|
|
guint val = g_value_get_uint (©);
|
|
|
|
|
|
|
|
switch (property->type_size)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
g_uint8_property_set_value (property, gobject, val);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
g_uint16_property_set_value (property, gobject, val);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
g_uint32_property_set_value (property, gobject, val);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
g_uint_property_set_value (property, gobject, val);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_UINT64:
|
|
|
|
g_uint64_property_set_value (property, gobject, g_value_get_uint64 (©));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_ULONG:
|
|
|
|
g_ulong_property_set_value (property, gobject, g_value_get_ulong (©));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_FLOAT:
|
|
|
|
g_float_property_set_value (property, gobject, g_value_get_float (©));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_DOUBLE:
|
|
|
|
g_double_property_set_value (property, gobject, g_value_get_double (©));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_ENUM:
|
|
|
|
g_enum_property_set_value (property, gobject, g_value_get_enum (©));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_FLAGS:
|
|
|
|
g_flags_property_set_value (property, gobject, g_value_get_flags (©));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_STRING:
|
|
|
|
g_string_property_set_value (property, gobject, g_value_get_string (©));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_BOXED:
|
|
|
|
g_boxed_property_set_value (property, gobject, g_value_get_boxed (©));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_OBJECT:
|
|
|
|
g_object_property_set_value (property, gobject, g_value_get_object (©));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_POINTER:
|
|
|
|
g_pointer_property_set_value (property, gobject, g_value_get_pointer (©));
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
g_critical (G_STRLOC ": Invalid type %s", g_type_name (G_VALUE_TYPE (©)));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_object_unref (gobject);
|
|
|
|
|
|
|
|
g_value_unset (©);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_property_get_value:
|
|
|
|
* @property: a #GProperty
|
|
|
|
* @gobject: a #GObject instance
|
|
|
|
* @value: a #GValue, initialized to the type of the property or to a
|
|
|
|
* type that satisfies the transformable relation
|
|
|
|
*
|
|
|
|
* Retrieves the value of @property for the object instance, and
|
|
|
|
* boxes it inside a #GValue, honouring eventual transformation
|
|
|
|
* functions between the #GValue type and the property type.
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
g_property_get_value (GProperty *property,
|
|
|
|
gpointer gobject,
|
|
|
|
GValue *value)
|
|
|
|
{
|
|
|
|
GType gtype;
|
|
|
|
GValue copy = { 0, };
|
|
|
|
|
|
|
|
g_return_if_fail (G_IS_PROPERTY (property));
|
|
|
|
g_return_if_fail (G_IS_OBJECT (gobject));
|
|
|
|
g_return_if_fail (value != NULL);
|
|
|
|
g_return_if_fail (property->is_installed);
|
|
|
|
|
|
|
|
gtype = G_PARAM_SPEC (property)->value_type;
|
|
|
|
|
|
|
|
g_return_if_fail (g_value_type_transformable (G_VALUE_TYPE (value), gtype));
|
|
|
|
|
|
|
|
g_value_init (©, gtype);
|
|
|
|
|
|
|
|
switch (G_TYPE_FUNDAMENTAL (gtype))
|
|
|
|
{
|
|
|
|
case G_TYPE_BOOLEAN:
|
|
|
|
g_value_set_boolean (©, g_boolean_property_get_value (property, gobject));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_INT:
|
|
|
|
{
|
|
|
|
gint val;
|
|
|
|
|
|
|
|
switch (property->type_size)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
val = g_int8_property_get_value (property, gobject);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
val = g_int16_property_get_value (property, gobject);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
val = g_int32_property_get_value (property, gobject);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
val = g_int_property_get_value (property, gobject);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_value_set_int (©, val);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_INT64:
|
|
|
|
g_value_set_int64 (©, g_int64_property_get_value (property, gobject));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_LONG:
|
|
|
|
g_value_set_long (©, g_long_property_get_value (property, gobject));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_UINT:
|
|
|
|
{
|
|
|
|
guint val;
|
|
|
|
|
|
|
|
switch (property->type_size)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
val = g_uint8_property_get_value (property, gobject);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
val = g_uint16_property_get_value (property, gobject);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
val = g_uint32_property_get_value (property, gobject);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
val = g_uint_property_get_value (property, gobject);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_value_set_uint (©, val);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_UINT64:
|
|
|
|
g_value_set_uint64 (©, g_uint64_property_get_value (property, gobject));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_ULONG:
|
|
|
|
g_value_set_ulong (©, g_ulong_property_get_value (property, gobject));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_STRING:
|
|
|
|
g_value_set_string (©, g_string_property_get_value (property, gobject));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_CHAR:
|
|
|
|
g_value_set_schar (©, g_int8_property_get_value (property, gobject));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_UCHAR:
|
|
|
|
g_value_set_uchar (©, g_uint8_property_get_value (property, gobject));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_ENUM:
|
|
|
|
g_value_set_enum (©, g_enum_property_get_value (property, gobject));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_FLAGS:
|
|
|
|
g_value_set_flags (©, g_flags_property_get_value (property, gobject));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_FLOAT:
|
|
|
|
g_value_set_float (©, g_float_property_get_value (property, gobject));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_DOUBLE:
|
|
|
|
g_value_set_double (©, g_double_property_get_value (property, gobject));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_BOXED:
|
|
|
|
g_value_set_boxed (©, g_boxed_property_get_value (property, gobject));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_OBJECT:
|
|
|
|
g_value_set_object (©, g_object_property_get_value (property, gobject));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_POINTER:
|
|
|
|
g_value_set_pointer (©, g_pointer_property_get_value (property, gobject));
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
g_critical (G_STRLOC ": Invalid type %s", g_type_name (gtype));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!g_value_transform (©, value))
|
|
|
|
{
|
|
|
|
g_critical (G_STRLOC ": Unable to transform a value of type '%s' into "
|
|
|
|
"a value of type '%s'",
|
|
|
|
g_type_name (gtype),
|
|
|
|
g_type_name (G_VALUE_TYPE (value)));
|
|
|
|
}
|
|
|
|
|
|
|
|
g_value_unset (©);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_property_get_value_type:
|
|
|
|
* @property: a #GProperty
|
|
|
|
*
|
|
|
|
* Retrieves the #GType of the value stored by the property.
|
|
|
|
*
|
|
|
|
* If a prerequisite type has been set, it will be the returned type.
|
|
|
|
*
|
|
|
|
* Return value: a #GType
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
GType
|
|
|
|
g_property_get_value_type (GProperty *property)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (G_IS_PROPERTY (property), G_TYPE_INVALID);
|
|
|
|
|
|
|
|
return G_PARAM_SPEC (property)->value_type;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_property_validate:
|
|
|
|
* @property: a #GProperty
|
|
|
|
* @...: the value to validate
|
|
|
|
*
|
|
|
|
* Validates the passed value against the validation rules of
|
|
|
|
* the @property.
|
|
|
|
*
|
|
|
|
* Return value: %TRUE if the value is valid, and %FALSE otherwise
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
g_property_validate (GProperty *property,
|
|
|
|
...)
|
|
|
|
{
|
|
|
|
gboolean retval = FALSE;
|
|
|
|
GType gtype;
|
|
|
|
va_list args;
|
|
|
|
|
|
|
|
g_return_val_if_fail (G_IS_PROPERTY (property), FALSE);
|
|
|
|
|
|
|
|
va_start (args, property);
|
|
|
|
|
|
|
|
gtype = G_PARAM_SPEC (property)->value_type;
|
|
|
|
|
|
|
|
switch (G_TYPE_FUNDAMENTAL (gtype))
|
|
|
|
{
|
|
|
|
case G_TYPE_BOOLEAN:
|
|
|
|
retval = g_boolean_property_validate (property, va_arg (args, gboolean));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_INT:
|
|
|
|
switch (property->type_size)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
retval = g_int8_property_validate (property, va_arg (args, gint));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
retval = g_int16_property_validate (property, va_arg (args, gint));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
retval = g_int32_property_validate (property, va_arg (args, gint));
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
retval = g_int_property_validate (property, va_arg (args, gint));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_INT64:
|
|
|
|
retval = g_int64_property_validate (property, va_arg (args, gint64));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_LONG:
|
|
|
|
retval = g_long_property_validate (property, va_arg (args, glong));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_UINT:
|
|
|
|
switch (property->type_size)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
retval = g_uint8_property_validate (property, va_arg (args, guint));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
retval = g_uint16_property_validate (property, va_arg (args, guint));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
retval = g_uint32_property_validate (property, va_arg (args, guint));
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
retval = g_uint_property_validate (property, va_arg (args, guint));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_UINT64:
|
|
|
|
retval = g_uint64_property_validate (property, va_arg (args, guint64));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_ULONG:
|
|
|
|
retval = g_ulong_property_validate (property, va_arg (args, gulong));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_FLOAT:
|
|
|
|
retval = g_float_property_validate (property, va_arg (args, gdouble));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_DOUBLE:
|
|
|
|
retval = g_double_property_validate (property, va_arg (args, gdouble));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_ENUM:
|
|
|
|
retval = g_enum_property_validate (property, va_arg (args, glong));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_FLAGS:
|
|
|
|
retval = g_enum_property_validate (property, va_arg (args, gulong));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_STRING:
|
|
|
|
retval = g_string_property_validate (property, va_arg (args, gchar *));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_BOXED:
|
|
|
|
retval = g_boxed_property_validate (property, va_arg (args, gpointer));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_OBJECT:
|
|
|
|
retval = g_object_property_validate (property, va_arg (args, gpointer));
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
g_critical (G_STRLOC ": Invalid type %s", g_type_name (gtype));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
va_end (args);
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_property_validate_value:
|
|
|
|
* @property: a #GProperty
|
|
|
|
* @value: a #GValue initialized to the property type or to a type
|
|
|
|
* that is transformable into the property type
|
|
|
|
*
|
|
|
|
* Validates the value stored inside the passed #GValue against the
|
|
|
|
* @property rules.
|
|
|
|
*
|
|
|
|
* Return value: %TRUE if the value is valid, and %FALSE otherwise
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
g_property_validate_value (GProperty *property,
|
|
|
|
GValue *value)
|
|
|
|
{
|
|
|
|
GValue copy = { 0, };
|
|
|
|
gboolean retval = FALSE;
|
|
|
|
GType gtype;
|
|
|
|
|
|
|
|
g_return_val_if_fail (G_IS_PROPERTY (property), FALSE);
|
|
|
|
g_return_val_if_fail (value != NULL, FALSE);
|
|
|
|
|
|
|
|
gtype = G_PARAM_SPEC (property)->value_type;
|
|
|
|
|
|
|
|
g_return_val_if_fail (g_value_type_transformable (gtype, G_VALUE_TYPE (value)), FALSE);
|
|
|
|
|
|
|
|
g_value_init (©, gtype);
|
|
|
|
|
|
|
|
if (!g_value_transform (value, ©))
|
|
|
|
{
|
|
|
|
g_critical (G_STRLOC ": Unable to transform a value of type '%s' "
|
|
|
|
"to a value of type '%s'",
|
|
|
|
g_type_name (G_VALUE_TYPE (value)),
|
|
|
|
g_type_name (gtype));
|
|
|
|
g_value_unset (©);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (G_TYPE_FUNDAMENTAL (gtype))
|
|
|
|
{
|
|
|
|
case G_TYPE_BOOLEAN:
|
|
|
|
retval = g_boolean_property_validate (property, g_value_get_boolean (©));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_INT:
|
|
|
|
{
|
|
|
|
gint val = g_value_get_int (©);
|
|
|
|
|
|
|
|
switch (property->type_size)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
retval = g_int8_property_validate (property, val);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
retval = g_int16_property_validate (property, val);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
retval = g_int32_property_validate (property, val);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
retval = g_int_property_validate (property, val);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_INT64:
|
|
|
|
retval = g_int64_property_validate (property, g_value_get_int64 (©));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_LONG:
|
|
|
|
retval = g_long_property_validate (property, g_value_get_long (©));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_UINT:
|
|
|
|
{
|
|
|
|
guint val = g_value_get_uint (©);
|
|
|
|
|
|
|
|
switch (property->type_size)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
retval = g_uint8_property_validate (property, val);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
retval = g_uint16_property_validate (property, val);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
retval = g_uint32_property_validate (property, val);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
retval = g_uint_property_validate (property, val);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_UINT64:
|
|
|
|
retval = g_uint64_property_validate (property, g_value_get_uint64 (©));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_ULONG:
|
|
|
|
retval = g_ulong_property_validate (property, g_value_get_ulong (©));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_FLOAT:
|
|
|
|
retval = g_float_property_validate (property, g_value_get_float (©));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_DOUBLE:
|
|
|
|
retval = g_double_property_validate (property, g_value_get_double (©));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_ENUM:
|
|
|
|
retval = g_enum_property_validate (property, g_value_get_enum (©));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_FLAGS:
|
|
|
|
retval = g_flags_property_validate (property, g_value_get_flags (©));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_STRING:
|
|
|
|
retval = g_string_property_validate (property, g_value_get_string (©));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_BOXED:
|
|
|
|
retval = g_boxed_property_validate (property, g_value_get_boxed (©));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case G_TYPE_OBJECT:
|
|
|
|
retval = g_object_property_validate (property, g_value_get_object (©));
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
g_critical (G_STRLOC ": Invalid type %s", g_type_name (gtype));
|
|
|
|
retval = FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_value_unset (©);
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_property_is_writable:
|
|
|
|
* @property: a #GProperty
|
|
|
|
*
|
|
|
|
* Checks whether the @property has the %G_PROPERTY_WRITABLE flag set.
|
|
|
|
*
|
|
|
|
* Return value: %TRUE if the flag is set, and %FALSE otherwise
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
g_property_is_writable (GProperty *property)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (G_IS_PROPERTY (property), FALSE);
|
|
|
|
|
|
|
|
return (property->flags & G_PROPERTY_WRITABLE) != 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_property_is_readable:
|
|
|
|
* @property: a #GProperty
|
|
|
|
*
|
|
|
|
* Checks whether the @property has the %G_PROPERTY_READABLE flag set.
|
|
|
|
*
|
|
|
|
* Return value: %TRUE if the flag is set, and %FALSE otherwise
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
g_property_is_readable (GProperty *property)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (G_IS_PROPERTY (property), FALSE);
|
|
|
|
|
|
|
|
return (property->flags & G_PROPERTY_READABLE) != 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_property_is_deprecated:
|
|
|
|
* @property: a #GProperty
|
|
|
|
*
|
|
|
|
* Checks whether the @property has the %G_PROPERTY_DEPRECATED flag set.
|
|
|
|
*
|
|
|
|
* Return value: %TRUE if the flag is set, and %FALSE otherwise
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
g_property_is_deprecated (GProperty *property)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (G_IS_PROPERTY (property), FALSE);
|
|
|
|
|
|
|
|
return (property->flags & G_PROPERTY_DEPRECATED) != 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_property_is_atomic:
|
|
|
|
* @property: a #GProperty
|
|
|
|
*
|
|
|
|
* Checks whether the @property has the %G_PROPERTY_ATOMIC flag set.
|
|
|
|
*
|
|
|
|
* Return value: %TRUE if the flag is set, and %FALSE otherwise
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
g_property_is_atomic (GProperty *property)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (G_IS_PROPERTY (property), FALSE);
|
|
|
|
|
|
|
|
return (property->flags & G_PROPERTY_ATOMIC) != 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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.36
|
|
|
|
*/
|
|
|
|
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.36
|
|
|
|
*/
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2012-11-12 19:37:56 +00:00
|
|
|
gboolean
|
|
|
|
g_property_is_direct_set (GProperty *property)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (G_IS_PROPERTY (property), FALSE);
|
|
|
|
|
|
|
|
return (property->flags & G_PROPERTY_DIRECT_SET) != 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
g_property_is_direct_get (GProperty *property)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (G_IS_PROPERTY (property), FALSE);
|
|
|
|
|
|
|
|
return (property->flags & G_PROPERTY_DIRECT_GET) != 0;
|
|
|
|
}
|
|
|
|
|
2011-04-22 14:08:11 +01:00
|
|
|
/**
|
|
|
|
* g_property_lock:
|
|
|
|
* @property: a #GProperty
|
|
|
|
* @gobject: a #GObject
|
|
|
|
*
|
|
|
|
* Locks a property on the given object.
|
|
|
|
*
|
|
|
|
* Use g_property_unlock() to unlock the property when done.
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
g_property_lock (GProperty *property,
|
|
|
|
gpointer gobject)
|
|
|
|
{
|
|
|
|
g_return_if_fail (G_IS_PROPERTY (property));
|
|
|
|
g_return_if_fail (G_IS_OBJECT (gobject));
|
|
|
|
|
|
|
|
property_lock_internal (property, gobject);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_property_unlock:
|
|
|
|
* @property: a #GProperty
|
|
|
|
* @gobject: a #GObject
|
|
|
|
*
|
|
|
|
* Unlocks a property on the given object previously locked
|
|
|
|
* using g_property_lock().
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
g_property_unlock (GProperty *property,
|
|
|
|
gpointer gobject)
|
|
|
|
{
|
|
|
|
g_return_if_fail (G_IS_PROPERTY (property));
|
|
|
|
g_return_if_fail (G_IS_OBJECT (gobject));
|
|
|
|
|
|
|
|
property_unlock_internal (property, gobject);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* g_property_set_lock_functions:
|
|
|
|
* @property: a #GProperty
|
|
|
|
* @lock_func: (allow-none): the function to be called when locking
|
|
|
|
* the @property, or %NULL for the default locking function
|
|
|
|
* @unlock_func: (allow-none): the function to be called when unlocking
|
|
|
|
* the @property, or %NULL for the default unlocking function
|
|
|
|
*
|
|
|
|
* Replaces the locking and unlocking functions for @property with
|
|
|
|
* custom functions.
|
|
|
|
*
|
|
|
|
* Since: 2.36
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
g_property_set_lock_functions (GProperty *property,
|
|
|
|
GPropertyLockFunc lock_func,
|
|
|
|
GPropertyUnlockFunc unlock_func)
|
|
|
|
{
|
|
|
|
g_return_if_fail (G_IS_PROPERTY (property));
|
|
|
|
g_return_if_fail (!property->is_installed);
|
|
|
|
|
|
|
|
if (lock_func == NULL)
|
|
|
|
g_return_if_fail (unlock_func == NULL);
|
|
|
|
|
|
|
|
property->lock_func = lock_func;
|
|
|
|
property->unlock_func = unlock_func;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
property_finalize (GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PROPERTY));
|
|
|
|
|
|
|
|
parent_class->finalize (pspec);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
property_set_default (GParamSpec *pspec,
|
|
|
|
GValue *value)
|
|
|
|
{
|
|
|
|
GProperty *property = G_PROPERTY (pspec);
|
|
|
|
const GValue *default_value;
|
|
|
|
|
|
|
|
default_value = property_get_default_for_type (property, G_TYPE_INVALID);
|
|
|
|
if (default_value != NULL)
|
|
|
|
g_value_copy (default_value, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
property_validate (GParamSpec *pspec,
|
|
|
|
GValue *value)
|
|
|
|
{
|
|
|
|
GProperty *property = G_PROPERTY (pspec);
|
|
|
|
|
|
|
|
if (!g_value_type_transformable (G_VALUE_TYPE (value), pspec->value_type))
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
return !g_property_validate_value (property, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
property_values_cmp (GParamSpec *pspec,
|
|
|
|
const GValue *value1,
|
|
|
|
const GValue *value2)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
property_class_init (GParamSpecClass *klass)
|
|
|
|
{
|
|
|
|
klass->value_type = G_TYPE_INVALID;
|
|
|
|
|
|
|
|
klass->value_set_default = property_set_default;
|
|
|
|
klass->value_validate = property_validate;
|
|
|
|
klass->values_cmp = property_values_cmp;
|
|
|
|
|
|
|
|
klass->finalize = property_finalize;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
property_init (GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
GProperty *property = G_PROPERTY (pspec);
|
|
|
|
|
|
|
|
pspec->value_type = G_TYPE_INVALID;
|
|
|
|
|
|
|
|
property->field_offset = -1;
|
|
|
|
property->priv_offset = -1;
|
|
|
|
|
|
|
|
property->lock_func = NULL;
|
|
|
|
property->unlock_func = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
GType
|
|
|
|
g_property_get_type (void)
|
|
|
|
{
|
|
|
|
static volatile gsize pspec_type_id__volatile = 0;
|
|
|
|
|
|
|
|
if (g_once_init_enter (&pspec_type_id__volatile))
|
|
|
|
{
|
|
|
|
const GTypeInfo info = {
|
|
|
|
sizeof (GParamSpecClass),
|
|
|
|
NULL, NULL,
|
|
|
|
(GClassInitFunc) property_class_init,
|
|
|
|
NULL, NULL,
|
|
|
|
sizeof (GProperty),
|
|
|
|
0,
|
|
|
|
(GInstanceInitFunc) property_init,
|
|
|
|
};
|
|
|
|
|
|
|
|
GType pspec_type_id =
|
|
|
|
g_type_register_static (G_TYPE_PARAM,
|
|
|
|
g_intern_static_string ("GProperty"),
|
|
|
|
&info, 0);
|
|
|
|
|
|
|
|
g_once_init_leave (&pspec_type_id__volatile, pspec_type_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
return pspec_type_id__volatile;
|
|
|
|
}
|