* 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.
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
*
* Author: Vincent Untz <vuntz@gnome.org>
*/
#include "gsettings-mapping.h"
static GVariant *
-g_settings_set_mapping_numeric (const GValue *value,
- const GVariantType *expected_type)
+g_settings_set_mapping_int (const GValue *value,
+ const GVariantType *expected_type)
{
GVariant *variant = NULL;
- glong l;
+ gint64 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;
variant = g_variant_new_handle ((guint) l);
}
else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_DOUBLE))
- variant = g_variant_new_double ((double) l);
+ variant = g_variant_new_double ((gdouble) l);
return variant;
}
static GVariant *
-g_settings_set_mapping_unsigned_numeric (const GValue *value,
- const GVariantType *expected_type)
+g_settings_set_mapping_float (const GValue *value,
+ const GVariantType *expected_type)
+{
+ GVariant *variant = NULL;
+ gdouble d;
+ gint64 l;
+
+ if (G_VALUE_HOLDS_DOUBLE (value))
+ d = g_value_get_double (value);
+ else
+ return NULL;
+
+ l = (gint64) d;
+ if (g_variant_type_equal (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_equal (expected_type, G_VARIANT_TYPE_UINT16))
+ {
+ if (0 <= l && l <= G_MAXUINT16)
+ variant = g_variant_new_uint16 ((guint16) l);
+ }
+ else if (g_variant_type_equal (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_equal (expected_type, G_VARIANT_TYPE_UINT32))
+ {
+ if (0 <= l && l <= G_MAXUINT32)
+ variant = g_variant_new_uint32 ((guint) l);
+ }
+ else if (g_variant_type_equal (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_equal (expected_type, G_VARIANT_TYPE_UINT64))
+ {
+ if (0 <= l && l <= G_MAXUINT64)
+ variant = g_variant_new_uint64 ((guint64) l);
+ }
+ else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_HANDLE))
+ {
+ if (0 <= l && l <= G_MAXUINT32)
+ variant = g_variant_new_handle ((guint) l);
+ }
+ else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_DOUBLE))
+ variant = g_variant_new_double ((gdouble) d);
+
+ return variant;
+}
+static GVariant *
+g_settings_set_mapping_unsigned_int (const GValue *value,
+ const GVariantType *expected_type)
{
GVariant *variant = NULL;
- gulong u;
+ guint64 u;
if (G_VALUE_HOLDS_UINT (value))
u = g_value_get_uint (value);
variant = g_variant_new_handle ((guint) u);
}
else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_DOUBLE))
- variant = g_variant_new_double ((double) u);
+ variant = g_variant_new_double ((gdouble) u);
return variant;
}
static gboolean
-g_settings_get_mapping_numeric (GValue *value,
- GVariant *variant)
+g_settings_get_mapping_int (GValue *value,
+ GVariant *variant)
{
const GVariantType *type;
- glong l;
+ gint64 l;
type = g_variant_get_type (variant);
l = g_variant_get_int32 (variant);
else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64))
l = g_variant_get_int64 (variant);
- else if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
- l = g_variant_get_double (variant);
else
return FALSE;
}
static gboolean
-g_settings_get_mapping_unsigned_numeric (GValue *value,
- GVariant *variant)
+g_settings_get_mapping_float (GValue *value,
+ GVariant *variant)
{
const GVariantType *type;
- gulong u;
+ gdouble d;
+ gint64 l;
+
+ type = g_variant_get_type (variant);
+
+ if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
+ d = g_variant_get_double (variant);
+ else
+ return FALSE;
+
+ l = (gint64)d;
+ 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, d);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+static gboolean
+g_settings_get_mapping_unsigned_int (GValue *value,
+ GVariant *variant)
+{
+ const GVariantType *type;
+ guint64 u;
type = g_variant_get_type (variant);
if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_BYTE))
{
if (G_VALUE_HOLDS_CHAR (value))
- return g_variant_new_byte (g_value_get_char (value));
+ return g_variant_new_byte (g_value_get_schar (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);
+ G_VALUE_HOLDS_INT64 (value))
+ return g_settings_set_mapping_int (value, expected_type);
+
+ else if (G_VALUE_HOLDS_DOUBLE (value))
+ return g_settings_set_mapping_float (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);
+ return g_settings_set_mapping_unsigned_int (value, expected_type);
else if (G_VALUE_HOLDS_STRING (value))
{
- if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_STRING))
+ if (g_value_get_string (value) == NULL)
+ return NULL;
+ else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_STRING))
return g_variant_new_string (g_value_get_string (value));
+ else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_BYTESTRING))
+ return g_variant_new_bytestring (g_value_get_string (value));
else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_OBJECT_PATH))
return g_variant_new_object_path (g_value_get_string (value));
else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_SIGNATURE))
return g_variant_new_signature (g_value_get_string (value));
}
+ else if (G_VALUE_HOLDS (value, G_TYPE_STRV))
+ {
+ if (g_value_get_boxed (value) == NULL)
+ return NULL;
+ return g_variant_new_strv ((const gchar **) g_value_get_boxed (value),
+ -1);
+ }
+
+ else if (G_VALUE_HOLDS_ENUM (value))
+ {
+ GEnumValue *enumval;
+ GEnumClass *eclass;
+
+ /* GParamSpecEnum holds a ref on the class so we just peek... */
+ eclass = g_type_class_peek (G_VALUE_TYPE (value));
+ enumval = g_enum_get_value (eclass, g_value_get_enum (value));
+
+ if (enumval)
+ return g_variant_new_string (enumval->value_nick);
+ else
+ return NULL;
+ }
+
+ else if (G_VALUE_HOLDS_FLAGS (value))
+ {
+ GVariantBuilder builder;
+ GFlagsValue *flagsval;
+ GFlagsClass *fclass;
+ guint flags;
+
+ fclass = g_type_class_peek (G_VALUE_TYPE (value));
+ flags = g_value_get_flags (value);
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
+ while (flags)
+ {
+ flagsval = g_flags_get_first_value (fclass, flags);
+
+ if (flagsval == NULL)
+ {
+ g_variant_builder_clear (&builder);
+ return NULL;
+ }
+
+ g_variant_builder_add (&builder, "s", flagsval->value_nick);
+ flags &= ~flagsval->value;
+ }
+
+ return g_variant_builder_end (&builder);
+ }
+
type_string = g_variant_type_dup_string (expected_type);
g_critical ("No GSettings bind handler for type \"%s\".", type_string);
g_free (type_string);
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));
+ g_value_set_schar (value, (gint8)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);
+ g_variant_is_of_type (variant, G_VARIANT_TYPE_INT64))
+ return g_settings_get_mapping_int (value, variant);
+
+ else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_DOUBLE))
+ return g_settings_get_mapping_float (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);
+ return g_settings_get_mapping_unsigned_int (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));
+ if (G_VALUE_HOLDS_STRING (value))
+ {
+ g_value_set_string (value, g_variant_get_string (variant, NULL));
+ return TRUE;
+ }
+
+ else if (G_VALUE_HOLDS_ENUM (value))
+ {
+ GEnumClass *eclass;
+ GEnumValue *evalue;
+ const gchar *nick;
+
+ /* GParamSpecEnum holds a ref on the class so we just peek... */
+ eclass = g_type_class_peek (G_VALUE_TYPE (value));
+ nick = g_variant_get_string (variant, NULL);
+ evalue = g_enum_get_value_by_nick (eclass, nick);
+
+ if (evalue)
+ {
+ g_value_set_enum (value, evalue->value);
+ return TRUE;
+ }
+
+ g_warning ("Unable to lookup enum nick '%s' via GType\n", nick);
+ return FALSE;
+ }
+ }
+ else if (g_variant_is_of_type (variant, G_VARIANT_TYPE ("as")))
+ {
+ if (G_VALUE_HOLDS (value, G_TYPE_STRV))
+ {
+ g_value_take_boxed (value, g_variant_dup_strv (variant, NULL));
+ return TRUE;
+ }
+
+ else if (G_VALUE_HOLDS_FLAGS (value))
+ {
+ GFlagsClass *fclass;
+ GFlagsValue *fvalue;
+ const gchar *nick;
+ GVariantIter iter;
+ guint flags = 0;
+
+ fclass = g_type_class_peek (G_VALUE_TYPE (value));
+
+ g_variant_iter_init (&iter, variant);
+ while (g_variant_iter_next (&iter, "&s", &nick))
+ {
+ fvalue = g_flags_get_value_by_nick (fclass, nick);
+
+ if (fvalue)
+ flags |= fvalue->value;
+
+ else
+ {
+ g_warning ("Unable to lookup flags nick '%s' via GType\n",
+ nick);
+ return FALSE;
+ }
+ }
+
+ g_value_set_flags (value, flags);
+ return TRUE;
+ }
+ }
+ else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_BYTESTRING))
+ {
+ g_value_set_string (value, g_variant_get_bytestring (variant));
return TRUE;
}
g_variant_type_equal (variant_type, G_VARIANT_TYPE_DOUBLE));
else if (gvalue_type == G_TYPE_STRING)
ok = (g_variant_type_equal (variant_type, G_VARIANT_TYPE_STRING) ||
+ g_variant_type_equal (variant_type, G_VARIANT_TYPE ("ay")) ||
g_variant_type_equal (variant_type, G_VARIANT_TYPE_OBJECT_PATH) ||
g_variant_type_equal (variant_type, G_VARIANT_TYPE_SIGNATURE));
+ else if (gvalue_type == G_TYPE_STRV)
+ ok = g_variant_type_equal (variant_type, G_VARIANT_TYPE ("as"));
+ else if (G_TYPE_IS_ENUM (gvalue_type))
+ ok = g_variant_type_equal (variant_type, G_VARIANT_TYPE_STRING);
+ else if (G_TYPE_IS_FLAGS (gvalue_type))
+ ok = g_variant_type_equal (variant_type, G_VARIANT_TYPE ("as"));
return ok;
}