2 * Copyright © 2010 Novell, Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the licence, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
19 * Author: Vincent Untz <vuntz@gnome.org>
24 #include "gsettings-mapping.h"
27 g_settings_set_mapping_int (const GValue *value,
28 const GVariantType *expected_type)
30 GVariant *variant = NULL;
33 if (G_VALUE_HOLDS_INT (value))
34 l = g_value_get_int (value);
35 else if (G_VALUE_HOLDS_INT64 (value))
36 l = g_value_get_int64 (value);
40 if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT16))
42 if (G_MININT16 <= l && l <= G_MAXINT16)
43 variant = g_variant_new_int16 ((gint16) l);
45 else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT16))
47 if (0 <= l && l <= G_MAXUINT16)
48 variant = g_variant_new_uint16 ((guint16) l);
50 else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT32))
52 if (G_MININT32 <= l && l <= G_MAXINT32)
53 variant = g_variant_new_int32 ((gint) l);
55 else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT32))
57 if (0 <= l && l <= G_MAXUINT32)
58 variant = g_variant_new_uint32 ((guint) l);
60 else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT64))
62 if (G_MININT64 <= l && l <= G_MAXINT64)
63 variant = g_variant_new_int64 ((gint64) l);
65 else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT64))
67 if (0 <= l && l <= G_MAXUINT64)
68 variant = g_variant_new_uint64 ((guint64) l);
70 else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_HANDLE))
72 if (0 <= l && l <= G_MAXUINT32)
73 variant = g_variant_new_handle ((guint) l);
75 else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_DOUBLE))
76 variant = g_variant_new_double ((gdouble) l);
82 g_settings_set_mapping_float (const GValue *value,
83 const GVariantType *expected_type)
85 GVariant *variant = NULL;
89 if (G_VALUE_HOLDS_DOUBLE (value))
90 d = g_value_get_double (value);
95 if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT16))
97 if (G_MININT16 <= l && l <= G_MAXINT16)
98 variant = g_variant_new_int16 ((gint16) l);
100 else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT16))
102 if (0 <= l && l <= G_MAXUINT16)
103 variant = g_variant_new_uint16 ((guint16) l);
105 else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT32))
107 if (G_MININT32 <= l && l <= G_MAXINT32)
108 variant = g_variant_new_int32 ((gint) l);
110 else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT32))
112 if (0 <= l && l <= G_MAXUINT32)
113 variant = g_variant_new_uint32 ((guint) l);
115 else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT64))
117 if (G_MININT64 <= l && l <= G_MAXINT64)
118 variant = g_variant_new_int64 ((gint64) l);
120 else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT64))
122 if (0 <= l && l <= G_MAXUINT64)
123 variant = g_variant_new_uint64 ((guint64) l);
125 else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_HANDLE))
127 if (0 <= l && l <= G_MAXUINT32)
128 variant = g_variant_new_handle ((guint) l);
130 else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_DOUBLE))
131 variant = g_variant_new_double ((gdouble) d);
136 g_settings_set_mapping_unsigned_int (const GValue *value,
137 const GVariantType *expected_type)
139 GVariant *variant = NULL;
142 if (G_VALUE_HOLDS_UINT (value))
143 u = g_value_get_uint (value);
144 else if (G_VALUE_HOLDS_UINT64 (value))
145 u = g_value_get_uint64 (value);
149 if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT16))
152 variant = g_variant_new_int16 ((gint16) u);
154 else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT16))
156 if (u <= G_MAXUINT16)
157 variant = g_variant_new_uint16 ((guint16) u);
159 else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT32))
162 variant = g_variant_new_int32 ((gint) u);
164 else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT32))
166 if (u <= G_MAXUINT32)
167 variant = g_variant_new_uint32 ((guint) u);
169 else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT64))
172 variant = g_variant_new_int64 ((gint64) u);
174 else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT64))
176 if (u <= G_MAXUINT64)
177 variant = g_variant_new_uint64 ((guint64) u);
179 else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_HANDLE))
181 if (u <= G_MAXUINT32)
182 variant = g_variant_new_handle ((guint) u);
184 else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_DOUBLE))
185 variant = g_variant_new_double ((gdouble) u);
191 g_settings_get_mapping_int (GValue *value,
194 const GVariantType *type;
197 type = g_variant_get_type (variant);
199 if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16))
200 l = g_variant_get_int16 (variant);
201 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32))
202 l = g_variant_get_int32 (variant);
203 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64))
204 l = g_variant_get_int64 (variant);
208 if (G_VALUE_HOLDS_INT (value))
210 g_value_set_int (value, l);
211 return (G_MININT32 <= l && l <= G_MAXINT32);
213 else if (G_VALUE_HOLDS_UINT (value))
215 g_value_set_uint (value, l);
216 return (0 <= l && l <= G_MAXUINT32);
218 else if (G_VALUE_HOLDS_INT64 (value))
220 g_value_set_int64 (value, l);
221 return (G_MININT64 <= l && l <= G_MAXINT64);
223 else if (G_VALUE_HOLDS_UINT64 (value))
225 g_value_set_uint64 (value, l);
226 return (0 <= l && l <= G_MAXUINT64);
228 else if (G_VALUE_HOLDS_DOUBLE (value))
230 g_value_set_double (value, l);
238 g_settings_get_mapping_float (GValue *value,
241 const GVariantType *type;
245 type = g_variant_get_type (variant);
247 if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
248 d = g_variant_get_double (variant);
253 if (G_VALUE_HOLDS_INT (value))
255 g_value_set_int (value, l);
256 return (G_MININT32 <= l && l <= G_MAXINT32);
258 else if (G_VALUE_HOLDS_UINT (value))
260 g_value_set_uint (value, l);
261 return (0 <= l && l <= G_MAXUINT32);
263 else if (G_VALUE_HOLDS_INT64 (value))
265 g_value_set_int64 (value, l);
266 return (G_MININT64 <= l && l <= G_MAXINT64);
268 else if (G_VALUE_HOLDS_UINT64 (value))
270 g_value_set_uint64 (value, l);
271 return (0 <= l && l <= G_MAXUINT64);
273 else if (G_VALUE_HOLDS_DOUBLE (value))
275 g_value_set_double (value, d);
282 g_settings_get_mapping_unsigned_int (GValue *value,
285 const GVariantType *type;
288 type = g_variant_get_type (variant);
290 if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT16))
291 u = g_variant_get_uint16 (variant);
292 else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT32))
293 u = g_variant_get_uint32 (variant);
294 else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT64))
295 u = g_variant_get_uint64 (variant);
296 else if (g_variant_type_equal (type, G_VARIANT_TYPE_HANDLE))
297 u = g_variant_get_handle (variant);
301 if (G_VALUE_HOLDS_INT (value))
303 g_value_set_int (value, u);
304 return (u <= G_MAXINT32);
306 else if (G_VALUE_HOLDS_UINT (value))
308 g_value_set_uint (value, u);
309 return (u <= G_MAXUINT32);
311 else if (G_VALUE_HOLDS_INT64 (value))
313 g_value_set_int64 (value, u);
314 return (u <= G_MAXINT64);
316 else if (G_VALUE_HOLDS_UINT64 (value))
318 g_value_set_uint64 (value, u);
319 return (u <= G_MAXUINT64);
321 else if (G_VALUE_HOLDS_DOUBLE (value))
323 g_value_set_double (value, u);
331 g_settings_set_mapping (const GValue *value,
332 const GVariantType *expected_type,
337 if (G_VALUE_HOLDS_BOOLEAN (value))
339 if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_BOOLEAN))
340 return g_variant_new_boolean (g_value_get_boolean (value));
343 else if (G_VALUE_HOLDS_CHAR (value) ||
344 G_VALUE_HOLDS_UCHAR (value))
346 if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_BYTE))
348 if (G_VALUE_HOLDS_CHAR (value))
349 return g_variant_new_byte (g_value_get_char (value));
351 return g_variant_new_byte (g_value_get_uchar (value));
355 else if (G_VALUE_HOLDS_INT (value) ||
356 G_VALUE_HOLDS_INT64 (value))
357 return g_settings_set_mapping_int (value, expected_type);
359 else if (G_VALUE_HOLDS_DOUBLE (value))
360 return g_settings_set_mapping_float (value, expected_type);
362 else if (G_VALUE_HOLDS_UINT (value) ||
363 G_VALUE_HOLDS_UINT64 (value))
364 return g_settings_set_mapping_unsigned_int (value, expected_type);
366 else if (G_VALUE_HOLDS_STRING (value))
368 if (g_value_get_string (value) == NULL)
370 else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_STRING))
371 return g_variant_new_string (g_value_get_string (value));
372 else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_BYTESTRING))
373 return g_variant_new_bytestring (g_value_get_string (value));
374 else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_OBJECT_PATH))
375 return g_variant_new_object_path (g_value_get_string (value));
376 else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_SIGNATURE))
377 return g_variant_new_signature (g_value_get_string (value));
380 else if (G_VALUE_HOLDS_ENUM (value))
385 /* GParamSpecEnum holds a ref on the class so we just peek... */
386 eclass = g_type_class_peek (G_VALUE_TYPE (value));
387 enumval = g_enum_get_value (eclass, g_value_get_enum (value));
390 return g_variant_new_string (enumval->value_nick);
395 else if (G_VALUE_HOLDS_FLAGS (value))
397 GVariantBuilder builder;
398 GFlagsValue *flagsval;
402 fclass = g_type_class_peek (G_VALUE_TYPE (value));
403 flags = g_value_get_flags (value);
405 g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
408 flagsval = g_flags_get_first_value (fclass, flags);
410 if (flagsval == NULL)
412 g_variant_builder_clear (&builder);
416 g_variant_builder_add (&builder, "s", flagsval->value_nick);
417 flags &= ~flagsval->value;
420 return g_variant_builder_end (&builder);
423 type_string = g_variant_type_dup_string (expected_type);
424 g_critical ("No GSettings bind handler for type \"%s\".", type_string);
425 g_free (type_string);
431 g_settings_get_mapping (GValue *value,
435 if (g_variant_is_of_type (variant, G_VARIANT_TYPE_BOOLEAN))
437 if (!G_VALUE_HOLDS_BOOLEAN (value))
439 g_value_set_boolean (value, g_variant_get_boolean (variant));
443 else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_BYTE))
445 if (G_VALUE_HOLDS_UCHAR (value))
446 g_value_set_uchar (value, g_variant_get_byte (variant));
447 else if (G_VALUE_HOLDS_CHAR (value))
448 g_value_set_char (value, (gchar) g_variant_get_byte (variant));
454 else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_INT16) ||
455 g_variant_is_of_type (variant, G_VARIANT_TYPE_INT32) ||
456 g_variant_is_of_type (variant, G_VARIANT_TYPE_INT64))
457 return g_settings_get_mapping_int (value, variant);
459 else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_DOUBLE))
460 return g_settings_get_mapping_float (value, variant);
462 else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT16) ||
463 g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT32) ||
464 g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT64) ||
465 g_variant_is_of_type (variant, G_VARIANT_TYPE_HANDLE))
466 return g_settings_get_mapping_unsigned_int (value, variant);
468 else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_STRING) ||
469 g_variant_is_of_type (variant, G_VARIANT_TYPE_OBJECT_PATH) ||
470 g_variant_is_of_type (variant, G_VARIANT_TYPE_SIGNATURE))
472 if (G_VALUE_HOLDS_STRING (value))
474 g_value_set_string (value, g_variant_get_string (variant, NULL));
478 else if (G_VALUE_HOLDS_ENUM (value))
484 /* GParamSpecEnum holds a ref on the class so we just peek... */
485 eclass = g_type_class_peek (G_VALUE_TYPE (value));
486 nick = g_variant_get_string (variant, NULL);
487 evalue = g_enum_get_value_by_nick (eclass, nick);
491 g_value_set_enum (value, evalue->value);
495 g_warning ("Unable to lookup enum nick '%s' via GType\n", nick);
499 else if (g_variant_is_of_type (variant, G_VARIANT_TYPE ("as")))
501 if (G_VALUE_HOLDS_FLAGS (value))
509 fclass = g_type_class_peek (G_VALUE_TYPE (value));
511 g_variant_iter_init (&iter, variant);
512 while (g_variant_iter_next (&iter, "&s", &nick))
514 fvalue = g_flags_get_value_by_nick (fclass, nick);
517 flags |= fvalue->value;
521 g_warning ("Unable to lookup flags nick '%s' via GType\n",
527 g_value_set_flags (value, flags);
531 else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_BYTESTRING))
533 g_value_set_string (value, g_variant_get_bytestring (variant));
537 g_critical ("No GSettings bind handler for type \"%s\".",
538 g_variant_get_type_string (variant));
544 g_settings_mapping_is_compatible (GType gvalue_type,
545 const GVariantType *variant_type)
549 if (gvalue_type == G_TYPE_BOOLEAN)
550 ok = g_variant_type_equal (variant_type, G_VARIANT_TYPE_BOOLEAN);
551 else if (gvalue_type == G_TYPE_CHAR ||
552 gvalue_type == G_TYPE_UCHAR)
553 ok = g_variant_type_equal (variant_type, G_VARIANT_TYPE_BYTE);
554 else if (gvalue_type == G_TYPE_INT ||
555 gvalue_type == G_TYPE_UINT ||
556 gvalue_type == G_TYPE_INT64 ||
557 gvalue_type == G_TYPE_UINT64 ||
558 gvalue_type == G_TYPE_DOUBLE)
559 ok = (g_variant_type_equal (variant_type, G_VARIANT_TYPE_INT16) ||
560 g_variant_type_equal (variant_type, G_VARIANT_TYPE_UINT16) ||
561 g_variant_type_equal (variant_type, G_VARIANT_TYPE_INT32) ||
562 g_variant_type_equal (variant_type, G_VARIANT_TYPE_UINT32) ||
563 g_variant_type_equal (variant_type, G_VARIANT_TYPE_INT64) ||
564 g_variant_type_equal (variant_type, G_VARIANT_TYPE_UINT64) ||
565 g_variant_type_equal (variant_type, G_VARIANT_TYPE_HANDLE) ||
566 g_variant_type_equal (variant_type, G_VARIANT_TYPE_DOUBLE));
567 else if (gvalue_type == G_TYPE_STRING)
568 ok = (g_variant_type_equal (variant_type, G_VARIANT_TYPE_STRING) ||
569 g_variant_type_equal (variant_type, G_VARIANT_TYPE ("ay")) ||
570 g_variant_type_equal (variant_type, G_VARIANT_TYPE_OBJECT_PATH) ||
571 g_variant_type_equal (variant_type, G_VARIANT_TYPE_SIGNATURE));
572 else if (G_TYPE_IS_ENUM (gvalue_type))
573 ok = g_variant_type_equal (variant_type, G_VARIANT_TYPE_STRING);
574 else if (G_TYPE_IS_FLAGS (gvalue_type))
575 ok = g_variant_type_equal (variant_type, G_VARIANT_TYPE ("as"));