mirror of
				https://gitlab.gnome.org/GNOME/glib.git
				synced 2025-10-31 00:12:19 +01:00 
			
		
		
		
	All uses of g_variant_builder_init() in gio are safe to translate to the new g_variant_builder_init_static() alternative as the type will outlive the call to g_variant_builder_end() (or is already static in nature).
		
			
				
	
	
		
			595 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			595 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | ||
|  * Copyright © 2010 Novell, Inc.
 | ||
|  *
 | ||
|  * SPDX-License-Identifier: LGPL-2.1-or-later
 | ||
|  *
 | ||
|  * 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.1 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, see <http://www.gnu.org/licenses/>.
 | ||
|  *
 | ||
|  * Author: Vincent Untz <vuntz@gnome.org>
 | ||
|  */
 | ||
| 
 | ||
| #include "config.h"
 | ||
| 
 | ||
| #include "gsettings-mapping.h"
 | ||
| 
 | ||
| static GVariant *
 | ||
| g_settings_set_mapping_int (const GValue       *value,
 | ||
|                             const GVariantType *expected_type)
 | ||
| {
 | ||
|   GVariant *variant = NULL;
 | ||
|   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
 | ||
|     return NULL;
 | ||
| 
 | ||
|   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 && (guint64) 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) l);
 | ||
| 
 | ||
|   return variant;
 | ||
| }
 | ||
| 
 | ||
| static GVariant *
 | ||
| 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 && (guint64) 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;
 | ||
|   guint64 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_equal (expected_type, G_VARIANT_TYPE_INT16))
 | ||
|     {
 | ||
|       if (u <= G_MAXINT16)
 | ||
|         variant = g_variant_new_int16 ((gint16) u);
 | ||
|     }
 | ||
|   else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT16))
 | ||
|     {
 | ||
|       if (u <= G_MAXUINT16)
 | ||
|         variant = g_variant_new_uint16 ((guint16) u);
 | ||
|     }
 | ||
|   else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT32))
 | ||
|     {
 | ||
|       if (u <= G_MAXINT32)
 | ||
|         variant = g_variant_new_int32 ((gint) u);
 | ||
|     }
 | ||
|   else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT32))
 | ||
|     {
 | ||
|       if (u <= G_MAXUINT32)
 | ||
|         variant = g_variant_new_uint32 ((guint) u);
 | ||
|     }
 | ||
|   else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT64))
 | ||
|     {
 | ||
|       if (u <= G_MAXINT64)
 | ||
|         variant = g_variant_new_int64 ((gint64) u);
 | ||
|     }
 | ||
|   else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT64))
 | ||
|     {
 | ||
|       if (u <= G_MAXUINT64)
 | ||
|         variant = g_variant_new_uint64 ((guint64) u);
 | ||
|     }
 | ||
|   else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_HANDLE))
 | ||
|     {
 | ||
|       if (u <= G_MAXUINT32)
 | ||
|         variant = g_variant_new_handle ((guint) u);
 | ||
|     }
 | ||
|   else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_DOUBLE))
 | ||
|     variant = g_variant_new_double ((gdouble) u);
 | ||
| 
 | ||
|   return variant;
 | ||
| }
 | ||
| 
 | ||
| static gboolean
 | ||
| g_settings_get_mapping_int (GValue   *value,
 | ||
|                             GVariant *variant)
 | ||
| {
 | ||
|   const GVariantType *type;
 | ||
|   gint64 l;
 | ||
| 
 | ||
|   type = g_variant_get_type (variant);
 | ||
| 
 | ||
|   if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16))
 | ||
|     l = g_variant_get_int16 (variant);
 | ||
|   else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32))
 | ||
|     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_HANDLE))
 | ||
|     l = g_variant_get_handle (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 && (guint64) 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_float (GValue   *value,
 | ||
|                               GVariant *variant)
 | ||
| {
 | ||
|   const GVariantType *type;
 | ||
|   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 && (guint64) 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 (type, G_VARIANT_TYPE_UINT16))
 | ||
|     u = g_variant_get_uint16 (variant);
 | ||
|   else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT32))
 | ||
|     u = g_variant_get_uint32 (variant);
 | ||
|   else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT64))
 | ||
|     u = g_variant_get_uint64 (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;
 | ||
| }
 | ||
| 
 | ||
| GVariant *
 | ||
| g_settings_set_mapping (const GValue       *value,
 | ||
|                         const GVariantType *expected_type,
 | ||
|                         gpointer            user_data)
 | ||
| {
 | ||
|   gchar *type_string;
 | ||
| 
 | ||
|   if (G_VALUE_HOLDS_BOOLEAN (value))
 | ||
|     {
 | ||
|       if (g_variant_type_equal (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_equal (expected_type, G_VARIANT_TYPE_BYTE))
 | ||
|         {
 | ||
|           if (G_VALUE_HOLDS_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))
 | ||
|     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_int (value, expected_type);
 | ||
| 
 | ||
|   else if (G_VALUE_HOLDS_STRING (value))
 | ||
|     {
 | ||
|       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_static (&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);
 | ||
| 
 | ||
|   return NULL;
 | ||
| }
 | ||
| 
 | ||
| gboolean
 | ||
| g_settings_get_mapping (GValue   *value,
 | ||
|                         GVariant *variant,
 | ||
|                         gpointer  user_data)
 | ||
| {
 | ||
|   if (g_variant_is_of_type (variant, G_VARIANT_TYPE_BOOLEAN))
 | ||
|     {
 | ||
|       if (!G_VALUE_HOLDS_BOOLEAN (value))
 | ||
|         return FALSE;
 | ||
|       g_value_set_boolean (value, g_variant_get_boolean (variant));
 | ||
|       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_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_HANDLE))
 | ||
|     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))
 | ||
|     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))
 | ||
|     {
 | ||
|       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 look up enum nick ‘%s’ via GType", 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",
 | ||
|                              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_critical ("No GSettings bind handler for type \"%s\".",
 | ||
|               g_variant_get_type_string (variant));
 | ||
| 
 | ||
|   return FALSE;
 | ||
| }
 | ||
| 
 | ||
| gboolean
 | ||
| g_settings_mapping_is_compatible (GType               gvalue_type,
 | ||
|                                   const GVariantType *variant_type)
 | ||
| {
 | ||
|   gboolean ok = FALSE;
 | ||
| 
 | ||
|   if (gvalue_type == G_TYPE_BOOLEAN)
 | ||
|     ok = g_variant_type_equal (variant_type, G_VARIANT_TYPE_BOOLEAN);
 | ||
|   else if (gvalue_type == G_TYPE_CHAR  ||
 | ||
|            gvalue_type == G_TYPE_UCHAR)
 | ||
|     ok = g_variant_type_equal (variant_type, G_VARIANT_TYPE_BYTE);
 | ||
|   else if (gvalue_type == G_TYPE_INT    ||
 | ||
|            gvalue_type == G_TYPE_UINT   ||
 | ||
|            gvalue_type == G_TYPE_INT64  ||
 | ||
|            gvalue_type == G_TYPE_UINT64 ||
 | ||
|            gvalue_type == G_TYPE_DOUBLE)
 | ||
|     ok = (g_variant_type_equal (variant_type, G_VARIANT_TYPE_INT16)  ||
 | ||
|           g_variant_type_equal (variant_type, G_VARIANT_TYPE_UINT16) ||
 | ||
|           g_variant_type_equal (variant_type, G_VARIANT_TYPE_INT32)  ||
 | ||
|           g_variant_type_equal (variant_type, G_VARIANT_TYPE_UINT32) ||
 | ||
|           g_variant_type_equal (variant_type, G_VARIANT_TYPE_INT64)  ||
 | ||
|           g_variant_type_equal (variant_type, G_VARIANT_TYPE_UINT64) ||
 | ||
|           g_variant_type_equal (variant_type, G_VARIANT_TYPE_HANDLE) ||
 | ||
|           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;
 | ||
| }
 |