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, see <http://www.gnu.org/licenses/>.
17 * Author: Vincent Untz <vuntz@gnome.org>
22 #include "gsettings-mapping.h"
25 g_settings_set_mapping_int (const GValue
*value
,
26 const GVariantType
*expected_type
)
28 GVariant
*variant
= NULL
;
31 if (G_VALUE_HOLDS_INT (value
))
32 l
= g_value_get_int (value
);
33 else if (G_VALUE_HOLDS_INT64 (value
))
34 l
= g_value_get_int64 (value
);
38 if (g_variant_type_equal (expected_type
, G_VARIANT_TYPE_INT16
))
40 if (G_MININT16
<= l
&& l
<= G_MAXINT16
)
41 variant
= g_variant_new_int16 ((gint16
) l
);
43 else if (g_variant_type_equal (expected_type
, G_VARIANT_TYPE_UINT16
))
45 if (0 <= l
&& l
<= G_MAXUINT16
)
46 variant
= g_variant_new_uint16 ((guint16
) l
);
48 else if (g_variant_type_equal (expected_type
, G_VARIANT_TYPE_INT32
))
50 if (G_MININT32
<= l
&& l
<= G_MAXINT32
)
51 variant
= g_variant_new_int32 ((gint
) l
);
53 else if (g_variant_type_equal (expected_type
, G_VARIANT_TYPE_UINT32
))
55 if (0 <= l
&& l
<= G_MAXUINT32
)
56 variant
= g_variant_new_uint32 ((guint
) l
);
58 else if (g_variant_type_equal (expected_type
, G_VARIANT_TYPE_INT64
))
60 if (G_MININT64
<= l
&& l
<= G_MAXINT64
)
61 variant
= g_variant_new_int64 ((gint64
) l
);
63 else if (g_variant_type_equal (expected_type
, G_VARIANT_TYPE_UINT64
))
65 if (0 <= l
&& l
<= G_MAXUINT64
)
66 variant
= g_variant_new_uint64 ((guint64
) l
);
68 else if (g_variant_type_equal (expected_type
, G_VARIANT_TYPE_HANDLE
))
70 if (0 <= l
&& l
<= G_MAXUINT32
)
71 variant
= g_variant_new_handle ((guint
) l
);
73 else if (g_variant_type_equal (expected_type
, G_VARIANT_TYPE_DOUBLE
))
74 variant
= g_variant_new_double ((gdouble
) l
);
80 g_settings_set_mapping_float (const GValue
*value
,
81 const GVariantType
*expected_type
)
83 GVariant
*variant
= NULL
;
87 if (G_VALUE_HOLDS_DOUBLE (value
))
88 d
= g_value_get_double (value
);
93 if (g_variant_type_equal (expected_type
, G_VARIANT_TYPE_INT16
))
95 if (G_MININT16
<= l
&& l
<= G_MAXINT16
)
96 variant
= g_variant_new_int16 ((gint16
) l
);
98 else if (g_variant_type_equal (expected_type
, G_VARIANT_TYPE_UINT16
))
100 if (0 <= l
&& l
<= G_MAXUINT16
)
101 variant
= g_variant_new_uint16 ((guint16
) l
);
103 else if (g_variant_type_equal (expected_type
, G_VARIANT_TYPE_INT32
))
105 if (G_MININT32
<= l
&& l
<= G_MAXINT32
)
106 variant
= g_variant_new_int32 ((gint
) l
);
108 else if (g_variant_type_equal (expected_type
, G_VARIANT_TYPE_UINT32
))
110 if (0 <= l
&& l
<= G_MAXUINT32
)
111 variant
= g_variant_new_uint32 ((guint
) l
);
113 else if (g_variant_type_equal (expected_type
, G_VARIANT_TYPE_INT64
))
115 if (G_MININT64
<= l
&& l
<= G_MAXINT64
)
116 variant
= g_variant_new_int64 ((gint64
) l
);
118 else if (g_variant_type_equal (expected_type
, G_VARIANT_TYPE_UINT64
))
120 if (0 <= l
&& l
<= G_MAXUINT64
)
121 variant
= g_variant_new_uint64 ((guint64
) l
);
123 else if (g_variant_type_equal (expected_type
, G_VARIANT_TYPE_HANDLE
))
125 if (0 <= l
&& l
<= G_MAXUINT32
)
126 variant
= g_variant_new_handle ((guint
) l
);
128 else if (g_variant_type_equal (expected_type
, G_VARIANT_TYPE_DOUBLE
))
129 variant
= g_variant_new_double ((gdouble
) d
);
134 g_settings_set_mapping_unsigned_int (const GValue
*value
,
135 const GVariantType
*expected_type
)
137 GVariant
*variant
= NULL
;
140 if (G_VALUE_HOLDS_UINT (value
))
141 u
= g_value_get_uint (value
);
142 else if (G_VALUE_HOLDS_UINT64 (value
))
143 u
= g_value_get_uint64 (value
);
147 if (g_variant_type_equal (expected_type
, G_VARIANT_TYPE_INT16
))
150 variant
= g_variant_new_int16 ((gint16
) u
);
152 else if (g_variant_type_equal (expected_type
, G_VARIANT_TYPE_UINT16
))
154 if (u
<= G_MAXUINT16
)
155 variant
= g_variant_new_uint16 ((guint16
) u
);
157 else if (g_variant_type_equal (expected_type
, G_VARIANT_TYPE_INT32
))
160 variant
= g_variant_new_int32 ((gint
) u
);
162 else if (g_variant_type_equal (expected_type
, G_VARIANT_TYPE_UINT32
))
164 if (u
<= G_MAXUINT32
)
165 variant
= g_variant_new_uint32 ((guint
) u
);
167 else if (g_variant_type_equal (expected_type
, G_VARIANT_TYPE_INT64
))
170 variant
= g_variant_new_int64 ((gint64
) u
);
172 else if (g_variant_type_equal (expected_type
, G_VARIANT_TYPE_UINT64
))
174 if (u
<= G_MAXUINT64
)
175 variant
= g_variant_new_uint64 ((guint64
) u
);
177 else if (g_variant_type_equal (expected_type
, G_VARIANT_TYPE_HANDLE
))
179 if (u
<= G_MAXUINT32
)
180 variant
= g_variant_new_handle ((guint
) u
);
182 else if (g_variant_type_equal (expected_type
, G_VARIANT_TYPE_DOUBLE
))
183 variant
= g_variant_new_double ((gdouble
) u
);
189 g_settings_get_mapping_int (GValue
*value
,
192 const GVariantType
*type
;
195 type
= g_variant_get_type (variant
);
197 if (g_variant_type_equal (type
, G_VARIANT_TYPE_INT16
))
198 l
= g_variant_get_int16 (variant
);
199 else if (g_variant_type_equal (type
, G_VARIANT_TYPE_INT32
))
200 l
= g_variant_get_int32 (variant
);
201 else if (g_variant_type_equal (type
, G_VARIANT_TYPE_INT64
))
202 l
= g_variant_get_int64 (variant
);
206 if (G_VALUE_HOLDS_INT (value
))
208 g_value_set_int (value
, l
);
209 return (G_MININT32
<= l
&& l
<= G_MAXINT32
);
211 else if (G_VALUE_HOLDS_UINT (value
))
213 g_value_set_uint (value
, l
);
214 return (0 <= l
&& l
<= G_MAXUINT32
);
216 else if (G_VALUE_HOLDS_INT64 (value
))
218 g_value_set_int64 (value
, l
);
219 return (G_MININT64
<= l
&& l
<= G_MAXINT64
);
221 else if (G_VALUE_HOLDS_UINT64 (value
))
223 g_value_set_uint64 (value
, l
);
224 return (0 <= l
&& l
<= G_MAXUINT64
);
226 else if (G_VALUE_HOLDS_DOUBLE (value
))
228 g_value_set_double (value
, l
);
236 g_settings_get_mapping_float (GValue
*value
,
239 const GVariantType
*type
;
243 type
= g_variant_get_type (variant
);
245 if (g_variant_type_equal (type
, G_VARIANT_TYPE_DOUBLE
))
246 d
= g_variant_get_double (variant
);
251 if (G_VALUE_HOLDS_INT (value
))
253 g_value_set_int (value
, l
);
254 return (G_MININT32
<= l
&& l
<= G_MAXINT32
);
256 else if (G_VALUE_HOLDS_UINT (value
))
258 g_value_set_uint (value
, l
);
259 return (0 <= l
&& l
<= G_MAXUINT32
);
261 else if (G_VALUE_HOLDS_INT64 (value
))
263 g_value_set_int64 (value
, l
);
264 return (G_MININT64
<= l
&& l
<= G_MAXINT64
);
266 else if (G_VALUE_HOLDS_UINT64 (value
))
268 g_value_set_uint64 (value
, l
);
269 return (0 <= l
&& l
<= G_MAXUINT64
);
271 else if (G_VALUE_HOLDS_DOUBLE (value
))
273 g_value_set_double (value
, d
);
280 g_settings_get_mapping_unsigned_int (GValue
*value
,
283 const GVariantType
*type
;
286 type
= g_variant_get_type (variant
);
288 if (g_variant_type_equal (type
, G_VARIANT_TYPE_UINT16
))
289 u
= g_variant_get_uint16 (variant
);
290 else if (g_variant_type_equal (type
, G_VARIANT_TYPE_UINT32
))
291 u
= g_variant_get_uint32 (variant
);
292 else if (g_variant_type_equal (type
, G_VARIANT_TYPE_UINT64
))
293 u
= g_variant_get_uint64 (variant
);
294 else if (g_variant_type_equal (type
, G_VARIANT_TYPE_HANDLE
))
295 u
= g_variant_get_handle (variant
);
299 if (G_VALUE_HOLDS_INT (value
))
301 g_value_set_int (value
, u
);
302 return (u
<= G_MAXINT32
);
304 else if (G_VALUE_HOLDS_UINT (value
))
306 g_value_set_uint (value
, u
);
307 return (u
<= G_MAXUINT32
);
309 else if (G_VALUE_HOLDS_INT64 (value
))
311 g_value_set_int64 (value
, u
);
312 return (u
<= G_MAXINT64
);
314 else if (G_VALUE_HOLDS_UINT64 (value
))
316 g_value_set_uint64 (value
, u
);
317 return (u
<= G_MAXUINT64
);
319 else if (G_VALUE_HOLDS_DOUBLE (value
))
321 g_value_set_double (value
, u
);
329 g_settings_set_mapping (const GValue
*value
,
330 const GVariantType
*expected_type
,
335 if (G_VALUE_HOLDS_BOOLEAN (value
))
337 if (g_variant_type_equal (expected_type
, G_VARIANT_TYPE_BOOLEAN
))
338 return g_variant_new_boolean (g_value_get_boolean (value
));
341 else if (G_VALUE_HOLDS_CHAR (value
) ||
342 G_VALUE_HOLDS_UCHAR (value
))
344 if (g_variant_type_equal (expected_type
, G_VARIANT_TYPE_BYTE
))
346 if (G_VALUE_HOLDS_CHAR (value
))
347 return g_variant_new_byte (g_value_get_schar (value
));
349 return g_variant_new_byte (g_value_get_uchar (value
));
353 else if (G_VALUE_HOLDS_INT (value
) ||
354 G_VALUE_HOLDS_INT64 (value
))
355 return g_settings_set_mapping_int (value
, expected_type
);
357 else if (G_VALUE_HOLDS_DOUBLE (value
))
358 return g_settings_set_mapping_float (value
, expected_type
);
360 else if (G_VALUE_HOLDS_UINT (value
) ||
361 G_VALUE_HOLDS_UINT64 (value
))
362 return g_settings_set_mapping_unsigned_int (value
, expected_type
);
364 else if (G_VALUE_HOLDS_STRING (value
))
366 if (g_value_get_string (value
) == NULL
)
368 else if (g_variant_type_equal (expected_type
, G_VARIANT_TYPE_STRING
))
369 return g_variant_new_string (g_value_get_string (value
));
370 else if (g_variant_type_equal (expected_type
, G_VARIANT_TYPE_BYTESTRING
))
371 return g_variant_new_bytestring (g_value_get_string (value
));
372 else if (g_variant_type_equal (expected_type
, G_VARIANT_TYPE_OBJECT_PATH
))
373 return g_variant_new_object_path (g_value_get_string (value
));
374 else if (g_variant_type_equal (expected_type
, G_VARIANT_TYPE_SIGNATURE
))
375 return g_variant_new_signature (g_value_get_string (value
));
378 else if (G_VALUE_HOLDS (value
, G_TYPE_STRV
))
380 if (g_value_get_boxed (value
) == NULL
)
382 return g_variant_new_strv ((const gchar
**) g_value_get_boxed (value
),
386 else if (G_VALUE_HOLDS_ENUM (value
))
391 /* GParamSpecEnum holds a ref on the class so we just peek... */
392 eclass
= g_type_class_peek (G_VALUE_TYPE (value
));
393 enumval
= g_enum_get_value (eclass
, g_value_get_enum (value
));
396 return g_variant_new_string (enumval
->value_nick
);
401 else if (G_VALUE_HOLDS_FLAGS (value
))
403 GVariantBuilder builder
;
404 GFlagsValue
*flagsval
;
408 fclass
= g_type_class_peek (G_VALUE_TYPE (value
));
409 flags
= g_value_get_flags (value
);
411 g_variant_builder_init (&builder
, G_VARIANT_TYPE ("as"));
414 flagsval
= g_flags_get_first_value (fclass
, flags
);
416 if (flagsval
== NULL
)
418 g_variant_builder_clear (&builder
);
422 g_variant_builder_add (&builder
, "s", flagsval
->value_nick
);
423 flags
&= ~flagsval
->value
;
426 return g_variant_builder_end (&builder
);
429 type_string
= g_variant_type_dup_string (expected_type
);
430 g_critical ("No GSettings bind handler for type \"%s\".", type_string
);
431 g_free (type_string
);
437 g_settings_get_mapping (GValue
*value
,
441 if (g_variant_is_of_type (variant
, G_VARIANT_TYPE_BOOLEAN
))
443 if (!G_VALUE_HOLDS_BOOLEAN (value
))
445 g_value_set_boolean (value
, g_variant_get_boolean (variant
));
449 else if (g_variant_is_of_type (variant
, G_VARIANT_TYPE_BYTE
))
451 if (G_VALUE_HOLDS_UCHAR (value
))
452 g_value_set_uchar (value
, g_variant_get_byte (variant
));
453 else if (G_VALUE_HOLDS_CHAR (value
))
454 g_value_set_schar (value
, (gint8
)g_variant_get_byte (variant
));
460 else if (g_variant_is_of_type (variant
, G_VARIANT_TYPE_INT16
) ||
461 g_variant_is_of_type (variant
, G_VARIANT_TYPE_INT32
) ||
462 g_variant_is_of_type (variant
, G_VARIANT_TYPE_INT64
))
463 return g_settings_get_mapping_int (value
, variant
);
465 else if (g_variant_is_of_type (variant
, G_VARIANT_TYPE_DOUBLE
))
466 return g_settings_get_mapping_float (value
, variant
);
468 else if (g_variant_is_of_type (variant
, G_VARIANT_TYPE_UINT16
) ||
469 g_variant_is_of_type (variant
, G_VARIANT_TYPE_UINT32
) ||
470 g_variant_is_of_type (variant
, G_VARIANT_TYPE_UINT64
) ||
471 g_variant_is_of_type (variant
, G_VARIANT_TYPE_HANDLE
))
472 return g_settings_get_mapping_unsigned_int (value
, variant
);
474 else if (g_variant_is_of_type (variant
, G_VARIANT_TYPE_STRING
) ||
475 g_variant_is_of_type (variant
, G_VARIANT_TYPE_OBJECT_PATH
) ||
476 g_variant_is_of_type (variant
, G_VARIANT_TYPE_SIGNATURE
))
478 if (G_VALUE_HOLDS_STRING (value
))
480 g_value_set_string (value
, g_variant_get_string (variant
, NULL
));
484 else if (G_VALUE_HOLDS_ENUM (value
))
490 /* GParamSpecEnum holds a ref on the class so we just peek... */
491 eclass
= g_type_class_peek (G_VALUE_TYPE (value
));
492 nick
= g_variant_get_string (variant
, NULL
);
493 evalue
= g_enum_get_value_by_nick (eclass
, nick
);
497 g_value_set_enum (value
, evalue
->value
);
501 g_warning ("Unable to lookup enum nick '%s' via GType\n", nick
);
505 else if (g_variant_is_of_type (variant
, G_VARIANT_TYPE ("as")))
507 if (G_VALUE_HOLDS (value
, G_TYPE_STRV
))
509 g_value_take_boxed (value
, g_variant_dup_strv (variant
, NULL
));
513 else if (G_VALUE_HOLDS_FLAGS (value
))
521 fclass
= g_type_class_peek (G_VALUE_TYPE (value
));
523 g_variant_iter_init (&iter
, variant
);
524 while (g_variant_iter_next (&iter
, "&s", &nick
))
526 fvalue
= g_flags_get_value_by_nick (fclass
, nick
);
529 flags
|= fvalue
->value
;
533 g_warning ("Unable to lookup flags nick '%s' via GType\n",
539 g_value_set_flags (value
, flags
);
543 else if (g_variant_is_of_type (variant
, G_VARIANT_TYPE_BYTESTRING
))
545 g_value_set_string (value
, g_variant_get_bytestring (variant
));
549 g_critical ("No GSettings bind handler for type \"%s\".",
550 g_variant_get_type_string (variant
));
556 g_settings_mapping_is_compatible (GType gvalue_type
,
557 const GVariantType
*variant_type
)
561 if (gvalue_type
== G_TYPE_BOOLEAN
)
562 ok
= g_variant_type_equal (variant_type
, G_VARIANT_TYPE_BOOLEAN
);
563 else if (gvalue_type
== G_TYPE_CHAR
||
564 gvalue_type
== G_TYPE_UCHAR
)
565 ok
= g_variant_type_equal (variant_type
, G_VARIANT_TYPE_BYTE
);
566 else if (gvalue_type
== G_TYPE_INT
||
567 gvalue_type
== G_TYPE_UINT
||
568 gvalue_type
== G_TYPE_INT64
||
569 gvalue_type
== G_TYPE_UINT64
||
570 gvalue_type
== G_TYPE_DOUBLE
)
571 ok
= (g_variant_type_equal (variant_type
, G_VARIANT_TYPE_INT16
) ||
572 g_variant_type_equal (variant_type
, G_VARIANT_TYPE_UINT16
) ||
573 g_variant_type_equal (variant_type
, G_VARIANT_TYPE_INT32
) ||
574 g_variant_type_equal (variant_type
, G_VARIANT_TYPE_UINT32
) ||
575 g_variant_type_equal (variant_type
, G_VARIANT_TYPE_INT64
) ||
576 g_variant_type_equal (variant_type
, G_VARIANT_TYPE_UINT64
) ||
577 g_variant_type_equal (variant_type
, G_VARIANT_TYPE_HANDLE
) ||
578 g_variant_type_equal (variant_type
, G_VARIANT_TYPE_DOUBLE
));
579 else if (gvalue_type
== G_TYPE_STRING
)
580 ok
= (g_variant_type_equal (variant_type
, G_VARIANT_TYPE_STRING
) ||
581 g_variant_type_equal (variant_type
, G_VARIANT_TYPE ("ay")) ||
582 g_variant_type_equal (variant_type
, G_VARIANT_TYPE_OBJECT_PATH
) ||
583 g_variant_type_equal (variant_type
, G_VARIANT_TYPE_SIGNATURE
));
584 else if (gvalue_type
== G_TYPE_STRV
)
585 ok
= g_variant_type_equal (variant_type
, G_VARIANT_TYPE ("as"));
586 else if (G_TYPE_IS_ENUM (gvalue_type
))
587 ok
= g_variant_type_equal (variant_type
, G_VARIANT_TYPE_STRING
);
588 else if (G_TYPE_IS_FLAGS (gvalue_type
))
589 ok
= g_variant_type_equal (variant_type
, G_VARIANT_TYPE ("as"));