[glib/new-gsettings] Add support for common types in the default mapping functions for bind
- From: Vincent Untz <vuntz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/new-gsettings] Add support for common types in the default mapping functions for bind
- Date: Fri, 16 Apr 2010 16:57:27 +0000 (UTC)
commit d02558fbf311838a299c8a5027ea85b5c3f8e4a6
Author: Vincent Untz <vuntz gnome org>
Date: Fri Apr 16 12:55:12 2010 -0400
Add support for common types in the default mapping functions for bind
gio/gsettings.c | 349 +++++++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 328 insertions(+), 21 deletions(-)
---
diff --git a/gio/gsettings.c b/gio/gsettings.c
index adbf11b..a28e7f1 100644
--- a/gio/gsettings.c
+++ b/gio/gsettings.c
@@ -1163,14 +1163,264 @@ g_settings_binding_property_changed (GObject *object,
}
static GVariant *
+g_settings_set_mapping_numeric (const GValue *value,
+ const GVariantType *expected_type)
+{
+ GVariant *variant = NULL;
+ glong l;
+
+ if (G_VALUE_HOLDS_INT (value))
+ l = g_value_get_int (value);
+ else if (G_VALUE_HOLDS_INT64 (value))
+ l = g_value_get_int64 (value);
+ else if (G_VALUE_HOLDS_DOUBLE (value))
+ l = g_value_get_double (value);
+ else
+ return NULL;
+
+ if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_INT16))
+ {
+ if (G_MININT16 <= l && l <= G_MAXINT16)
+ variant = g_variant_new_int16 ((gint16) l);
+ }
+ else if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_UINT16))
+ {
+ if (0 <= l && l <= G_MAXUINT16)
+ variant = g_variant_new_uint16 ((guint16) l);
+ }
+ else if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_INT32))
+ {
+ if (G_MININT32 <= l && l <= G_MAXINT32)
+ variant = g_variant_new_int32 ((gint) l);
+ }
+ else if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_UINT32))
+ {
+ if (0 <= l && l <= G_MAXUINT32)
+ variant = g_variant_new_uint32 ((guint) l);
+ }
+ else if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_INT64))
+ {
+ if (G_MININT64 <= l && l <= G_MAXINT64)
+ variant = g_variant_new_int64 ((gint64) l);
+ }
+ else if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_UINT64))
+ {
+ if (0 <= l && l <= G_MAXUINT64)
+ variant = g_variant_new_uint64 ((guint64) l);
+ }
+ else if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_HANDLE))
+ {
+ if (0 <= l && l <= G_MAXUINT32)
+ variant = g_variant_new_handle ((guint) l);
+ }
+ else if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_DOUBLE))
+ variant = g_variant_new_double ((double) l);
+
+ return variant;
+}
+
+static GVariant *
+g_settings_set_mapping_unsigned_numeric (const GValue *value,
+ const GVariantType *expected_type)
+{
+ GVariant *variant = NULL;
+ gulong u;
+
+ if (G_VALUE_HOLDS_UINT (value))
+ u = g_value_get_uint (value);
+ else if (G_VALUE_HOLDS_UINT64 (value))
+ u = g_value_get_uint64 (value);
+ else
+ return NULL;
+
+ if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_INT16))
+ {
+ if (u <= G_MAXINT16)
+ variant = g_variant_new_int16 ((gint16) u);
+ }
+ else if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_UINT16))
+ {
+ if (u <= G_MAXUINT16)
+ variant = g_variant_new_uint16 ((guint16) u);
+ }
+ else if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_INT32))
+ {
+ if (u <= G_MAXINT32)
+ variant = g_variant_new_int32 ((gint) u);
+ }
+ else if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_UINT32))
+ {
+ if (u <= G_MAXUINT32)
+ variant = g_variant_new_uint32 ((guint) u);
+ }
+ else if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_INT64))
+ {
+ if (u <= G_MAXINT64)
+ variant = g_variant_new_int64 ((gint64) u);
+ }
+ else if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_UINT64))
+ {
+ if (u <= G_MAXUINT64)
+ variant = g_variant_new_uint64 ((guint64) u);
+ }
+ else if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_HANDLE))
+ {
+ if (u <= G_MAXUINT32)
+ variant = g_variant_new_handle ((guint) u);
+ }
+ else if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_DOUBLE))
+ variant = g_variant_new_double ((double) u);
+
+ return variant;
+}
+
+static gboolean
+g_settings_get_mapping_numeric (GValue *value,
+ GVariant *variant)
+{
+ const GVariantType *type;
+ glong l;
+
+ type = g_variant_get_type (variant);
+
+ if (g_variant_type_is_subtype_of (type, G_VARIANT_TYPE_INT16))
+ l = g_variant_get_int16 (variant);
+ else if (g_variant_type_is_subtype_of (type, G_VARIANT_TYPE_INT32))
+ l = g_variant_get_int32 (variant);
+ else if (g_variant_type_is_subtype_of (type, G_VARIANT_TYPE_INT64))
+ l = g_variant_get_int64 (variant);
+ else if (g_variant_type_is_subtype_of (type, G_VARIANT_TYPE_DOUBLE))
+ l = g_variant_get_double (variant);
+ else
+ return FALSE;
+
+ if (G_VALUE_HOLDS_INT (value))
+ {
+ g_value_set_int (value, l);
+ return (G_MININT32 <= l && l <= G_MAXINT32);
+ }
+ else if (G_VALUE_HOLDS_UINT (value))
+ {
+ g_value_set_uint (value, l);
+ return (0 <= l && l <= G_MAXUINT32);
+ }
+ else if (G_VALUE_HOLDS_INT64 (value))
+ {
+ g_value_set_int64 (value, l);
+ return (G_MININT64 <= l && l <= G_MAXINT64);
+ }
+ else if (G_VALUE_HOLDS_UINT64 (value))
+ {
+ g_value_set_uint64 (value, l);
+ return (0 <= l && l <= G_MAXUINT64);
+ }
+ else if (G_VALUE_HOLDS_DOUBLE (value))
+ {
+ g_value_set_double (value, l);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+g_settings_get_mapping_unsigned_numeric (GValue *value,
+ GVariant *variant)
+{
+ const GVariantType *type;
+ gulong u;
+
+ type = g_variant_get_type (variant);
+
+ if (g_variant_type_is_subtype_of (type, G_VARIANT_TYPE_UINT16))
+ u = g_variant_get_uint16 (variant);
+ else if (g_variant_type_is_subtype_of (type, G_VARIANT_TYPE_UINT32))
+ u = g_variant_get_uint32 (variant);
+ else if (g_variant_type_is_subtype_of (type, G_VARIANT_TYPE_UINT64))
+ u = g_variant_get_uint64 (variant);
+ else if (g_variant_type_is_subtype_of (type, G_VARIANT_TYPE_HANDLE))
+ u = g_variant_get_handle (variant);
+ else
+ return FALSE;
+
+ if (G_VALUE_HOLDS_INT (value))
+ {
+ g_value_set_int (value, u);
+ return (u <= G_MAXINT32);
+ }
+ else if (G_VALUE_HOLDS_UINT (value))
+ {
+ g_value_set_uint (value, u);
+ return (u <= G_MAXUINT32);
+ }
+ else if (G_VALUE_HOLDS_INT64 (value))
+ {
+ g_value_set_int64 (value, u);
+ return (u <= G_MAXINT64);
+ }
+ else if (G_VALUE_HOLDS_UINT64 (value))
+ {
+ g_value_set_uint64 (value, u);
+ return (u <= G_MAXUINT64);
+ }
+ else if (G_VALUE_HOLDS_DOUBLE (value))
+ {
+ g_value_set_double (value, u);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static GVariant *
g_settings_set_mapping (const GValue *value,
const GVariantType *expected_type,
gpointer user_data)
{
- if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_BOOLEAN))
- return g_variant_new_boolean (g_value_get_boolean (value));
+ gchar *type_string;
- g_error ("Sorry; non-boolean bindings are not supported\n");
+ if (G_VALUE_HOLDS_BOOLEAN (value))
+ {
+ if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_BOOLEAN))
+ return g_variant_new_boolean (g_value_get_boolean (value));
+ }
+
+ else if (G_VALUE_HOLDS_CHAR (value) ||
+ G_VALUE_HOLDS_UCHAR (value))
+ {
+ if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_BYTE))
+ {
+ if (G_VALUE_HOLDS_CHAR (value))
+ return g_variant_new_byte (g_value_get_char (value));
+ else
+ return g_variant_new_byte (g_value_get_uchar (value));
+ }
+ }
+
+ else if (G_VALUE_HOLDS_INT (value) ||
+ G_VALUE_HOLDS_INT64 (value) ||
+ G_VALUE_HOLDS_DOUBLE (value))
+ return g_settings_set_mapping_numeric (value, expected_type);
+
+ else if (G_VALUE_HOLDS_UINT (value) ||
+ G_VALUE_HOLDS_UINT64 (value))
+ return g_settings_set_mapping_unsigned_numeric (value, expected_type);
+
+ else if (G_VALUE_HOLDS_STRING (value))
+ {
+ if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_STRING))
+ return g_variant_new_string (g_value_get_string (value));
+ else if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_OBJECT_PATH))
+ return g_variant_new_object_path (g_value_get_string (value));
+ else if (g_variant_type_is_subtype_of (expected_type, G_VARIANT_TYPE_SIGNATURE))
+ return g_variant_new_signature (g_value_get_string (value));
+ }
+
+ type_string = g_variant_type_dup_string (expected_type);
+ g_critical ("No GSettings bind handler for type \"%s\".", type_string);
+ g_free (type_string);
+
+ return NULL;
}
static gboolean
@@ -1179,11 +1429,47 @@ g_settings_get_mapping (GValue *value,
gpointer user_data)
{
if (g_variant_is_of_type (variant, G_VARIANT_TYPE_BOOLEAN))
- g_value_set_boolean (value, g_variant_get_boolean (variant));
- else
- g_error ("Sorry; non-boolean bindings are not supported\n");
+ {
+ if (!G_VALUE_HOLDS_BOOLEAN (value))
+ return FALSE;
+ g_value_set_boolean (value, g_variant_get_boolean (variant));
+ return TRUE;
+ }
- return TRUE;
+ else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_BYTE))
+ {
+ if (G_VALUE_HOLDS_UCHAR (value))
+ g_value_set_uchar (value, g_variant_get_byte (variant));
+ else if (G_VALUE_HOLDS_CHAR (value))
+ g_value_set_char (value, (gchar) g_variant_get_byte (variant));
+ else
+ return FALSE;
+ return TRUE;
+ }
+
+ else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_INT16) ||
+ g_variant_is_of_type (variant, G_VARIANT_TYPE_INT32) ||
+ g_variant_is_of_type (variant, G_VARIANT_TYPE_INT64) ||
+ g_variant_is_of_type (variant, G_VARIANT_TYPE_DOUBLE))
+ return g_settings_get_mapping_numeric (value, variant);
+
+ else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT16) ||
+ g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT32) ||
+ g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT64) ||
+ g_variant_is_of_type (variant, G_VARIANT_TYPE_HANDLE))
+ return g_settings_get_mapping_unsigned_numeric (value, variant);
+
+ else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_STRING) ||
+ g_variant_is_of_type (variant, G_VARIANT_TYPE_OBJECT_PATH) ||
+ g_variant_is_of_type (variant, G_VARIANT_TYPE_SIGNATURE))
+ {
+ g_value_set_string (value, g_variant_get_string (variant, NULL));
+ return TRUE;
+ }
+
+ g_critical ("No GSettings bind handler for type \"%s\".", g_variant_get_type_string (variant));
+
+ return FALSE;
}
void
@@ -1252,20 +1538,41 @@ g_settings_bind_with_mapping (GSettings *settings,
if (get_mapping == NULL || set_mapping == NULL)
{
- /* XXX do some simple checks for type compatibility
-
- if (!g_type_serialiser_check (G_PARAM_SPEC_VALUE_TYPE (binding->property),
- binding->type))
- {
- g_critical ("g_settings_bind: property '%s' on class '%s' has type"
- "'%s' which is not compatible with type '%s' of key '%s'"
- "on schema '%s'", property, G_OBJECT_TYPE_NAME (object),
- g_type_name (binding->property->value_type),
- g_variant_type_dup_string (binding->type), key,
- settings->priv->schema_name);
- return;
- }
-*/
+ gboolean ok = FALSE;
+
+ if (binding->property->value_type == G_TYPE_BOOLEAN)
+ ok = g_variant_type_is_subtype_of (binding->type, G_VARIANT_TYPE_BOOLEAN);
+ else if (binding->property->value_type == G_TYPE_CHAR ||
+ binding->property->value_type == G_TYPE_UCHAR)
+ ok = g_variant_type_is_subtype_of (binding->type, G_VARIANT_TYPE_BYTE);
+ else if (binding->property->value_type == G_TYPE_INT ||
+ binding->property->value_type == G_TYPE_UINT ||
+ binding->property->value_type == G_TYPE_INT64 ||
+ binding->property->value_type == G_TYPE_UINT64 ||
+ binding->property->value_type == G_TYPE_DOUBLE)
+ ok = (g_variant_type_is_subtype_of (binding->type, G_VARIANT_TYPE_INT16) ||
+ g_variant_type_is_subtype_of (binding->type, G_VARIANT_TYPE_UINT16) ||
+ g_variant_type_is_subtype_of (binding->type, G_VARIANT_TYPE_INT32) ||
+ g_variant_type_is_subtype_of (binding->type, G_VARIANT_TYPE_UINT32) ||
+ g_variant_type_is_subtype_of (binding->type, G_VARIANT_TYPE_INT64) ||
+ g_variant_type_is_subtype_of (binding->type, G_VARIANT_TYPE_UINT64) ||
+ g_variant_type_is_subtype_of (binding->type, G_VARIANT_TYPE_HANDLE) ||
+ g_variant_type_is_subtype_of (binding->type, G_VARIANT_TYPE_DOUBLE));
+ else if (binding->property->value_type == G_TYPE_STRING)
+ ok = (g_variant_type_is_subtype_of (binding->type, G_VARIANT_TYPE_STRING) ||
+ g_variant_type_is_subtype_of (binding->type, G_VARIANT_TYPE_OBJECT_PATH) ||
+ g_variant_type_is_subtype_of (binding->type, G_VARIANT_TYPE_SIGNATURE));
+
+ if (!ok)
+ {
+ g_critical ("g_settings_bind: property '%s' on class '%s' has type"
+ "'%s' which is not compatible with type '%s' of key '%s'"
+ "on schema '%s'", property, G_OBJECT_TYPE_NAME (object),
+ g_type_name (binding->property->value_type),
+ g_variant_type_dup_string (binding->type), key,
+ settings->priv->schema_name);
+ return;
+ }
}
if (~flags & G_SETTINGS_BIND_NO_SENSITIVITY)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]