1 /* GObject - GLib Type, Object, Parameter and Signal Library
2 * Copyright (C) 1997-1999, 2000-2001 Tim Janik and Red Hat, 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 License, 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
15 * Public 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.
24 #include "../config.h"
26 #include "gparamspecs.h"
28 #include "gvaluecollector.h"
29 #include "gvaluearray.h"
32 #define G_FLOAT_EPSILON (1e-30)
33 #define G_DOUBLE_EPSILON (1e-90)
36 /* --- param spec functions --- */
38 param_char_init (GParamSpec *pspec)
40 GParamSpecChar *cspec = G_PARAM_SPEC_CHAR (pspec);
42 cspec->minimum = 0x7f;
43 cspec->maximum = 0x80;
44 cspec->default_value = 0;
48 param_char_set_default (GParamSpec *pspec,
51 value->data[0].v_int = G_PARAM_SPEC_CHAR (pspec)->default_value;
55 param_char_validate (GParamSpec *pspec,
58 GParamSpecChar *cspec = G_PARAM_SPEC_CHAR (pspec);
59 gint oval = value->data[0].v_int;
61 value->data[0].v_int = CLAMP (value->data[0].v_int, cspec->minimum, cspec->maximum);
63 return value->data[0].v_int != oval;
67 param_uchar_init (GParamSpec *pspec)
69 GParamSpecUChar *uspec = G_PARAM_SPEC_UCHAR (pspec);
72 uspec->maximum = 0xff;
73 uspec->default_value = 0;
77 param_uchar_set_default (GParamSpec *pspec,
80 value->data[0].v_uint = G_PARAM_SPEC_UCHAR (pspec)->default_value;
84 param_uchar_validate (GParamSpec *pspec,
87 GParamSpecUChar *uspec = G_PARAM_SPEC_UCHAR (pspec);
88 guint oval = value->data[0].v_uint;
90 value->data[0].v_uint = CLAMP (value->data[0].v_uint, uspec->minimum, uspec->maximum);
92 return value->data[0].v_uint != oval;
96 param_boolean_set_default (GParamSpec *pspec,
99 value->data[0].v_int = G_PARAM_SPEC_BOOLEAN (pspec)->default_value;
103 param_boolean_validate (GParamSpec *pspec,
106 gint oval = value->data[0].v_int;
108 value->data[0].v_int = value->data[0].v_int != FALSE;
110 return value->data[0].v_int != oval;
114 param_int_init (GParamSpec *pspec)
116 GParamSpecInt *ispec = G_PARAM_SPEC_INT (pspec);
118 ispec->minimum = 0x7fffffff;
119 ispec->maximum = 0x80000000;
120 ispec->default_value = 0;
124 param_int_set_default (GParamSpec *pspec,
127 value->data[0].v_int = G_PARAM_SPEC_INT (pspec)->default_value;
131 param_int_validate (GParamSpec *pspec,
134 GParamSpecInt *ispec = G_PARAM_SPEC_INT (pspec);
135 gint oval = value->data[0].v_int;
137 value->data[0].v_int = CLAMP (value->data[0].v_int, ispec->minimum, ispec->maximum);
139 return value->data[0].v_int != oval;
143 param_int_values_cmp (GParamSpec *pspec,
144 const GValue *value1,
145 const GValue *value2)
147 if (value1->data[0].v_int < value2->data[0].v_int)
150 return value1->data[0].v_int > value2->data[0].v_int;
154 param_uint_init (GParamSpec *pspec)
156 GParamSpecUInt *uspec = G_PARAM_SPEC_UINT (pspec);
159 uspec->maximum = 0xffffffff;
160 uspec->default_value = 0;
164 param_uint_set_default (GParamSpec *pspec,
167 value->data[0].v_uint = G_PARAM_SPEC_UINT (pspec)->default_value;
171 param_uint_validate (GParamSpec *pspec,
174 GParamSpecUInt *uspec = G_PARAM_SPEC_UINT (pspec);
175 guint oval = value->data[0].v_uint;
177 value->data[0].v_uint = CLAMP (value->data[0].v_uint, uspec->minimum, uspec->maximum);
179 return value->data[0].v_uint != oval;
183 param_uint_values_cmp (GParamSpec *pspec,
184 const GValue *value1,
185 const GValue *value2)
187 if (value1->data[0].v_uint < value2->data[0].v_uint)
190 return value1->data[0].v_uint > value2->data[0].v_uint;
194 param_long_init (GParamSpec *pspec)
196 GParamSpecLong *lspec = G_PARAM_SPEC_LONG (pspec);
199 lspec->minimum = 0x7fffffff;
200 lspec->maximum = 0x80000000;
201 #else /* SIZEOF_LONG != 4 (8) */
202 lspec->minimum = 0x7fffffffffffffff;
203 lspec->maximum = 0x8000000000000000;
205 lspec->default_value = 0;
209 param_long_set_default (GParamSpec *pspec,
212 value->data[0].v_long = G_PARAM_SPEC_LONG (pspec)->default_value;
216 param_long_validate (GParamSpec *pspec,
219 GParamSpecLong *lspec = G_PARAM_SPEC_LONG (pspec);
220 glong oval = value->data[0].v_long;
222 value->data[0].v_long = CLAMP (value->data[0].v_long, lspec->minimum, lspec->maximum);
224 return value->data[0].v_long != oval;
228 param_long_values_cmp (GParamSpec *pspec,
229 const GValue *value1,
230 const GValue *value2)
232 if (value1->data[0].v_long < value2->data[0].v_long)
235 return value1->data[0].v_long > value2->data[0].v_long;
239 param_ulong_init (GParamSpec *pspec)
241 GParamSpecULong *uspec = G_PARAM_SPEC_ULONG (pspec);
245 uspec->maximum = 0xffffffff;
246 #else /* SIZEOF_LONG != 4 (8) */
247 uspec->maximum = 0xffffffffffffffff;
249 uspec->default_value = 0;
253 param_ulong_set_default (GParamSpec *pspec,
256 value->data[0].v_ulong = G_PARAM_SPEC_ULONG (pspec)->default_value;
260 param_ulong_validate (GParamSpec *pspec,
263 GParamSpecULong *uspec = G_PARAM_SPEC_ULONG (pspec);
264 gulong oval = value->data[0].v_ulong;
266 value->data[0].v_ulong = CLAMP (value->data[0].v_ulong, uspec->minimum, uspec->maximum);
268 return value->data[0].v_ulong != oval;
272 param_ulong_values_cmp (GParamSpec *pspec,
273 const GValue *value1,
274 const GValue *value2)
276 if (value1->data[0].v_ulong < value2->data[0].v_ulong)
279 return value1->data[0].v_ulong > value2->data[0].v_ulong;
283 param_int64_init (GParamSpec *pspec)
285 GParamSpecInt64 *lspec = G_PARAM_SPEC_INT64 (pspec);
287 lspec->minimum = G_MININT64;
288 lspec->maximum = G_MAXINT64;
289 lspec->default_value = 0;
293 param_int64_set_default (GParamSpec *pspec,
296 value->data[0].v_int64 = G_PARAM_SPEC_INT64 (pspec)->default_value;
300 param_int64_validate (GParamSpec *pspec,
303 GParamSpecInt64 *lspec = G_PARAM_SPEC_INT64 (pspec);
304 gint64 oval = value->data[0].v_int64;
306 value->data[0].v_int64 = CLAMP (value->data[0].v_int64, lspec->minimum, lspec->maximum);
308 return value->data[0].v_int64 != oval;
312 param_int64_values_cmp (GParamSpec *pspec,
313 const GValue *value1,
314 const GValue *value2)
316 if (value1->data[0].v_int64 < value2->data[0].v_int64)
319 return value1->data[0].v_int64 > value2->data[0].v_int64;
323 param_uint64_init (GParamSpec *pspec)
325 GParamSpecUInt64 *uspec = G_PARAM_SPEC_UINT64 (pspec);
328 uspec->maximum = G_MAXUINT64;
329 uspec->default_value = 0;
333 param_uint64_set_default (GParamSpec *pspec,
336 value->data[0].v_uint64 = G_PARAM_SPEC_UINT64 (pspec)->default_value;
340 param_uint64_validate (GParamSpec *pspec,
343 GParamSpecUInt64 *uspec = G_PARAM_SPEC_UINT64 (pspec);
344 guint64 oval = value->data[0].v_uint64;
346 value->data[0].v_uint64 = CLAMP (value->data[0].v_uint64, uspec->minimum, uspec->maximum);
348 return value->data[0].v_uint64 != oval;
352 param_uint64_values_cmp (GParamSpec *pspec,
353 const GValue *value1,
354 const GValue *value2)
356 if (value1->data[0].v_uint64 < value2->data[0].v_uint64)
359 return value1->data[0].v_uint64 > value2->data[0].v_uint64;
363 param_unichar_init (GParamSpec *pspec)
365 GParamSpecUnichar *uspec = G_PARAM_SPEC_UNICHAR (pspec);
367 uspec->default_value = 0;
371 param_unichar_set_default (GParamSpec *pspec,
374 value->data[0].v_uint = G_PARAM_SPEC_UNICHAR (pspec)->default_value;
378 param_unichar_validate (GParamSpec *pspec,
381 gunichar oval = value->data[0].v_uint;
382 gboolean changed = FALSE;
384 if (!g_unichar_validate (oval))
386 value->data[0].v_uint = 0;
394 param_unichar_values_cmp (GParamSpec *pspec,
395 const GValue *value1,
396 const GValue *value2)
398 if (value1->data[0].v_uint < value2->data[0].v_uint)
401 return value1->data[0].v_uint > value2->data[0].v_uint;
405 param_enum_init (GParamSpec *pspec)
407 GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec);
409 espec->enum_class = NULL;
410 espec->default_value = 0;
414 param_enum_finalize (GParamSpec *pspec)
416 GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec);
417 GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_ENUM));
419 if (espec->enum_class)
421 g_type_class_unref (espec->enum_class);
422 espec->enum_class = NULL;
425 parent_class->finalize (pspec);
429 param_enum_set_default (GParamSpec *pspec,
432 value->data[0].v_long = G_PARAM_SPEC_ENUM (pspec)->default_value;
436 param_enum_validate (GParamSpec *pspec,
439 GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec);
440 glong oval = value->data[0].v_long;
442 if (!espec->enum_class ||
443 !g_enum_get_value (espec->enum_class, value->data[0].v_long))
444 value->data[0].v_long = espec->default_value;
446 return value->data[0].v_long != oval;
450 param_flags_init (GParamSpec *pspec)
452 GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec);
454 fspec->flags_class = NULL;
455 fspec->default_value = 0;
459 param_flags_finalize (GParamSpec *pspec)
461 GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec);
462 GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_FLAGS));
464 if (fspec->flags_class)
466 g_type_class_unref (fspec->flags_class);
467 fspec->flags_class = NULL;
470 parent_class->finalize (pspec);
474 param_flags_set_default (GParamSpec *pspec,
477 value->data[0].v_ulong = G_PARAM_SPEC_FLAGS (pspec)->default_value;
481 param_flags_validate (GParamSpec *pspec,
484 GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec);
485 gulong oval = value->data[0].v_ulong;
487 if (fspec->flags_class)
488 value->data[0].v_ulong &= fspec->flags_class->mask;
490 value->data[0].v_ulong = fspec->default_value;
492 return value->data[0].v_ulong != oval;
496 param_float_init (GParamSpec *pspec)
498 GParamSpecFloat *fspec = G_PARAM_SPEC_FLOAT (pspec);
500 fspec->minimum = G_MINFLOAT;
501 fspec->maximum = G_MAXFLOAT;
502 fspec->default_value = 0;
503 fspec->epsilon = G_FLOAT_EPSILON;
507 param_float_set_default (GParamSpec *pspec,
510 value->data[0].v_float = G_PARAM_SPEC_FLOAT (pspec)->default_value;
514 param_float_validate (GParamSpec *pspec,
517 GParamSpecFloat *fspec = G_PARAM_SPEC_FLOAT (pspec);
518 gfloat oval = value->data[0].v_float;
520 value->data[0].v_float = CLAMP (value->data[0].v_float, fspec->minimum, fspec->maximum);
522 return value->data[0].v_float != oval;
526 param_float_values_cmp (GParamSpec *pspec,
527 const GValue *value1,
528 const GValue *value2)
530 gfloat epsilon = G_PARAM_SPEC_FLOAT (pspec)->epsilon;
532 if (value1->data[0].v_float < value2->data[0].v_float)
533 return - (value2->data[0].v_float - value1->data[0].v_float > epsilon);
535 return value1->data[0].v_float - value2->data[0].v_float > epsilon;
539 param_double_init (GParamSpec *pspec)
541 GParamSpecDouble *dspec = G_PARAM_SPEC_DOUBLE (pspec);
543 dspec->minimum = G_MINDOUBLE;
544 dspec->maximum = G_MAXDOUBLE;
545 dspec->default_value = 0;
546 dspec->epsilon = G_DOUBLE_EPSILON;
550 param_double_set_default (GParamSpec *pspec,
553 value->data[0].v_double = G_PARAM_SPEC_DOUBLE (pspec)->default_value;
557 param_double_validate (GParamSpec *pspec,
560 GParamSpecDouble *dspec = G_PARAM_SPEC_DOUBLE (pspec);
561 gdouble oval = value->data[0].v_double;
563 value->data[0].v_double = CLAMP (value->data[0].v_double, dspec->minimum, dspec->maximum);
565 return value->data[0].v_double != oval;
569 param_double_values_cmp (GParamSpec *pspec,
570 const GValue *value1,
571 const GValue *value2)
573 gdouble epsilon = G_PARAM_SPEC_DOUBLE (pspec)->epsilon;
575 if (value1->data[0].v_double < value2->data[0].v_double)
576 return - (value2->data[0].v_double - value1->data[0].v_double > epsilon);
578 return value1->data[0].v_double - value2->data[0].v_double > epsilon;
582 param_string_init (GParamSpec *pspec)
584 GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec);
586 sspec->default_value = NULL;
587 sspec->cset_first = NULL;
588 sspec->cset_nth = NULL;
589 sspec->substitutor = '_';
590 sspec->null_fold_if_empty = FALSE;
591 sspec->ensure_non_null = FALSE;
595 param_string_finalize (GParamSpec *pspec)
597 GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec);
598 GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_STRING));
600 g_free (sspec->default_value);
601 g_free (sspec->cset_first);
602 g_free (sspec->cset_nth);
603 sspec->default_value = NULL;
604 sspec->cset_first = NULL;
605 sspec->cset_nth = NULL;
607 parent_class->finalize (pspec);
611 param_string_set_default (GParamSpec *pspec,
614 value->data[0].v_pointer = g_strdup (G_PARAM_SPEC_STRING (pspec)->default_value);
618 param_string_validate (GParamSpec *pspec,
621 GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec);
622 gchar *string = value->data[0].v_pointer;
625 if (string && string[0])
629 if (sspec->cset_first && !strchr (sspec->cset_first, string[0]))
631 string[0] = sspec->substitutor;
635 for (s = string + 1; *s; s++)
636 if (!strchr (sspec->cset_nth, *s))
638 *s = sspec->substitutor;
642 if (sspec->null_fold_if_empty && string && string[0] == 0)
644 g_free (value->data[0].v_pointer);
645 value->data[0].v_pointer = NULL;
647 string = value->data[0].v_pointer;
649 if (sspec->ensure_non_null && !string)
651 value->data[0].v_pointer = g_strdup ("");
653 string = value->data[0].v_pointer;
660 param_string_values_cmp (GParamSpec *pspec,
661 const GValue *value1,
662 const GValue *value2)
664 if (!value1->data[0].v_pointer)
665 return value2->data[0].v_pointer != NULL ? -1 : 0;
666 else if (!value2->data[0].v_pointer)
667 return value1->data[0].v_pointer != NULL;
669 return strcmp (value1->data[0].v_pointer, value2->data[0].v_pointer);
673 param_param_init (GParamSpec *pspec)
675 /* GParamSpecParam *spec = G_PARAM_SPEC_PARAM (pspec); */
679 param_param_set_default (GParamSpec *pspec,
682 value->data[0].v_pointer = NULL;
686 param_param_validate (GParamSpec *pspec,
689 /* GParamSpecParam *spec = G_PARAM_SPEC_PARAM (pspec); */
690 GParamSpec *param = value->data[0].v_pointer;
693 if (param && !g_value_type_compatible (G_PARAM_SPEC_TYPE (param), G_PARAM_SPEC_VALUE_TYPE (pspec)))
695 g_param_spec_unref (param);
696 value->data[0].v_pointer = NULL;
704 param_boxed_init (GParamSpec *pspec)
706 /* GParamSpecBoxed *bspec = G_PARAM_SPEC_BOXED (pspec); */
710 param_boxed_set_default (GParamSpec *pspec,
713 value->data[0].v_pointer = NULL;
717 param_boxed_validate (GParamSpec *pspec,
720 /* GParamSpecBoxed *bspec = G_PARAM_SPEC_BOXED (pspec); */
723 /* can't do a whole lot here since we haven't even G_BOXED_TYPE() */
729 param_boxed_values_cmp (GParamSpec *pspec,
730 const GValue *value1,
731 const GValue *value2)
733 guint8 *p1 = value1->data[0].v_pointer;
734 guint8 *p2 = value2->data[0].v_pointer;
736 /* not much to compare here, try to at least provide stable lesser/greater result */
738 return p1 < p2 ? -1 : p1 > p2;
742 param_pointer_init (GParamSpec *pspec)
744 /* GParamSpecPointer *spec = G_PARAM_SPEC_POINTER (pspec); */
748 param_pointer_set_default (GParamSpec *pspec,
751 value->data[0].v_pointer = NULL;
755 param_pointer_validate (GParamSpec *pspec,
758 /* GParamSpecPointer *spec = G_PARAM_SPEC_POINTER (pspec); */
765 param_pointer_values_cmp (GParamSpec *pspec,
766 const GValue *value1,
767 const GValue *value2)
769 guint8 *p1 = value1->data[0].v_pointer;
770 guint8 *p2 = value2->data[0].v_pointer;
772 /* not much to compare here, try to at least provide stable lesser/greater result */
774 return p1 < p2 ? -1 : p1 > p2;
778 param_value_array_init (GParamSpec *pspec)
780 GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
782 aspec->element_spec = NULL;
783 aspec->fixed_n_elements = 0; /* disable */
787 value_array_ensure_size (GValueArray *value_array,
788 guint fixed_n_elements)
792 if (fixed_n_elements)
794 while (value_array->n_values < fixed_n_elements)
796 g_value_array_append (value_array, NULL);
799 while (value_array->n_values > fixed_n_elements)
801 g_value_array_remove (value_array, value_array->n_values - 1);
809 param_value_array_finalize (GParamSpec *pspec)
811 GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
812 GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_VALUE_ARRAY));
814 if (aspec->element_spec)
816 g_param_spec_unref (aspec->element_spec);
817 aspec->element_spec = NULL;
820 parent_class->finalize (pspec);
824 param_value_array_set_default (GParamSpec *pspec,
827 GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
829 if (!value->data[0].v_pointer && aspec->fixed_n_elements)
830 value->data[0].v_pointer = g_value_array_new (aspec->fixed_n_elements);
832 if (value->data[0].v_pointer)
834 /* g_value_reset (value); already done */
835 value_array_ensure_size (value->data[0].v_pointer, aspec->fixed_n_elements);
840 param_value_array_validate (GParamSpec *pspec,
843 GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
844 GValueArray *value_array = value->data[0].v_pointer;
847 if (!value->data[0].v_pointer && aspec->fixed_n_elements)
848 value->data[0].v_pointer = g_value_array_new (aspec->fixed_n_elements);
850 if (value->data[0].v_pointer)
852 /* ensure array size validity */
853 changed += value_array_ensure_size (value_array, aspec->fixed_n_elements);
855 /* ensure array values validity against a present element spec */
856 if (aspec->element_spec)
858 GParamSpec *element_spec = aspec->element_spec;
861 for (i = 0; i < value_array->n_values; i++)
863 GValue *element = value_array->values + i;
865 /* need to fixup value type, or ensure that the array value is initialized at all */
866 if (!g_value_type_compatible (G_VALUE_TYPE (element), G_PARAM_SPEC_VALUE_TYPE (element_spec)))
868 if (G_VALUE_TYPE (element) != 0)
869 g_value_unset (element);
870 g_value_init (element, G_PARAM_SPEC_VALUE_TYPE (element_spec));
871 g_param_value_set_default (element_spec, element);
874 /* validate array value against element_spec */
875 changed += g_param_value_validate (element_spec, element);
884 param_value_array_values_cmp (GParamSpec *pspec,
885 const GValue *value1,
886 const GValue *value2)
888 GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
889 GValueArray *value_array1 = value1->data[0].v_pointer;
890 GValueArray *value_array2 = value2->data[0].v_pointer;
892 if (!value_array1 || !value_array2)
893 return value_array2 ? -1 : value_array1 != value_array2;
895 if (value_array1->n_values != value_array2->n_values)
896 return value_array1->n_values < value_array2->n_values ? -1 : 1;
897 else if (!aspec->element_spec)
899 /* we need an element specification for comparisons, so there's not much
900 * to compare here, try to at least provide stable lesser/greater result
902 return value_array1->n_values < value_array2->n_values ? -1 : value_array1->n_values > value_array2->n_values;
904 else /* value_array1->n_values == value_array2->n_values */
908 for (i = 0; i < value_array1->n_values; i++)
910 GValue *element1 = value_array1->values + i;
911 GValue *element2 = value_array2->values + i;
914 /* need corresponding element types, provide stable result otherwise */
915 if (G_VALUE_TYPE (element1) != G_VALUE_TYPE (element2))
916 return G_VALUE_TYPE (element1) < G_VALUE_TYPE (element2) ? -1 : 1;
917 cmp = g_param_values_cmp (aspec->element_spec, element1, element2);
926 param_object_init (GParamSpec *pspec)
928 /* GParamSpecObject *ospec = G_PARAM_SPEC_OBJECT (pspec); */
932 param_object_set_default (GParamSpec *pspec,
935 value->data[0].v_pointer = NULL;
939 param_object_validate (GParamSpec *pspec,
942 GParamSpecObject *ospec = G_PARAM_SPEC_OBJECT (pspec);
943 GObject *object = value->data[0].v_pointer;
946 if (object && !g_value_type_compatible (G_OBJECT_TYPE (object), G_PARAM_SPEC_VALUE_TYPE (ospec)))
948 g_object_unref (object);
949 value->data[0].v_pointer = NULL;
957 param_object_values_cmp (GParamSpec *pspec,
958 const GValue *value1,
959 const GValue *value2)
961 guint8 *p1 = value1->data[0].v_pointer;
962 guint8 *p2 = value2->data[0].v_pointer;
964 /* not much to compare here, try to at least provide stable lesser/greater result */
966 return p1 < p2 ? -1 : p1 > p2;
970 /* --- type initialization --- */
971 GType *g_param_spec_types = NULL;
974 g_param_spec_types_init (void) /* sync with gtype.c */
976 const guint n_types = 20;
977 GType type, *spec_types, *spec_types_bound;
979 g_param_spec_types = g_new0 (GType, n_types);
980 spec_types = g_param_spec_types;
981 spec_types_bound = g_param_spec_types + n_types;
986 static const GParamSpecTypeInfo pspec_info = {
987 sizeof (GParamSpecChar), /* instance_size */
988 16, /* n_preallocs */
989 param_char_init, /* instance_init */
990 G_TYPE_CHAR, /* value_type */
992 param_char_set_default, /* value_set_default */
993 param_char_validate, /* value_validate */
994 param_int_values_cmp, /* values_cmp */
996 type = g_param_type_register_static ("GParamChar", &pspec_info);
997 *spec_types++ = type;
998 g_assert (type == G_TYPE_PARAM_CHAR);
1001 /* G_TYPE_PARAM_UCHAR
1004 static const GParamSpecTypeInfo pspec_info = {
1005 sizeof (GParamSpecUChar), /* instance_size */
1006 16, /* n_preallocs */
1007 param_uchar_init, /* instance_init */
1008 G_TYPE_UCHAR, /* value_type */
1009 NULL, /* finalize */
1010 param_uchar_set_default, /* value_set_default */
1011 param_uchar_validate, /* value_validate */
1012 param_uint_values_cmp, /* values_cmp */
1014 type = g_param_type_register_static ("GParamUChar", &pspec_info);
1015 *spec_types++ = type;
1016 g_assert (type == G_TYPE_PARAM_UCHAR);
1019 /* G_TYPE_PARAM_BOOLEAN
1022 static const GParamSpecTypeInfo pspec_info = {
1023 sizeof (GParamSpecBoolean), /* instance_size */
1024 16, /* n_preallocs */
1025 NULL, /* instance_init */
1026 G_TYPE_BOOLEAN, /* value_type */
1027 NULL, /* finalize */
1028 param_boolean_set_default, /* value_set_default */
1029 param_boolean_validate, /* value_validate */
1030 param_int_values_cmp, /* values_cmp */
1032 type = g_param_type_register_static ("GParamBoolean", &pspec_info);
1033 *spec_types++ = type;
1034 g_assert (type == G_TYPE_PARAM_BOOLEAN);
1040 static const GParamSpecTypeInfo pspec_info = {
1041 sizeof (GParamSpecInt), /* instance_size */
1042 16, /* n_preallocs */
1043 param_int_init, /* instance_init */
1044 G_TYPE_INT, /* value_type */
1045 NULL, /* finalize */
1046 param_int_set_default, /* value_set_default */
1047 param_int_validate, /* value_validate */
1048 param_int_values_cmp, /* values_cmp */
1050 type = g_param_type_register_static ("GParamInt", &pspec_info);
1051 *spec_types++ = type;
1052 g_assert (type == G_TYPE_PARAM_INT);
1055 /* G_TYPE_PARAM_UINT
1058 static const GParamSpecTypeInfo pspec_info = {
1059 sizeof (GParamSpecUInt), /* instance_size */
1060 16, /* n_preallocs */
1061 param_uint_init, /* instance_init */
1062 G_TYPE_UINT, /* value_type */
1063 NULL, /* finalize */
1064 param_uint_set_default, /* value_set_default */
1065 param_uint_validate, /* value_validate */
1066 param_uint_values_cmp, /* values_cmp */
1068 type = g_param_type_register_static ("GParamUInt", &pspec_info);
1069 *spec_types++ = type;
1070 g_assert (type == G_TYPE_PARAM_UINT);
1073 /* G_TYPE_PARAM_LONG
1076 static const GParamSpecTypeInfo pspec_info = {
1077 sizeof (GParamSpecLong), /* instance_size */
1078 16, /* n_preallocs */
1079 param_long_init, /* instance_init */
1080 G_TYPE_LONG, /* value_type */
1081 NULL, /* finalize */
1082 param_long_set_default, /* value_set_default */
1083 param_long_validate, /* value_validate */
1084 param_long_values_cmp, /* values_cmp */
1086 type = g_param_type_register_static ("GParamLong", &pspec_info);
1087 *spec_types++ = type;
1088 g_assert (type == G_TYPE_PARAM_LONG);
1091 /* G_TYPE_PARAM_ULONG
1094 static const GParamSpecTypeInfo pspec_info = {
1095 sizeof (GParamSpecULong), /* instance_size */
1096 16, /* n_preallocs */
1097 param_ulong_init, /* instance_init */
1098 G_TYPE_ULONG, /* value_type */
1099 NULL, /* finalize */
1100 param_ulong_set_default, /* value_set_default */
1101 param_ulong_validate, /* value_validate */
1102 param_ulong_values_cmp, /* values_cmp */
1104 type = g_param_type_register_static ("GParamULong", &pspec_info);
1105 *spec_types++ = type;
1106 g_assert (type == G_TYPE_PARAM_ULONG);
1109 /* G_TYPE_PARAM_INT64
1112 static const GParamSpecTypeInfo pspec_info = {
1113 sizeof (GParamSpecInt64), /* instance_size */
1114 16, /* n_preallocs */
1115 param_int64_init, /* instance_init */
1116 G_TYPE_INT64, /* value_type */
1117 NULL, /* finalize */
1118 param_int64_set_default, /* value_set_default */
1119 param_int64_validate, /* value_validate */
1120 param_int64_values_cmp, /* values_cmp */
1122 type = g_param_type_register_static ("GParamInt64", &pspec_info);
1123 *spec_types++ = type;
1124 g_assert (type == G_TYPE_PARAM_INT64);
1127 /* G_TYPE_PARAM_UINT64
1130 static const GParamSpecTypeInfo pspec_info = {
1131 sizeof (GParamSpecUInt64), /* instance_size */
1132 16, /* n_preallocs */
1133 param_uint64_init, /* instance_init */
1134 G_TYPE_UINT64, /* value_type */
1135 NULL, /* finalize */
1136 param_uint64_set_default, /* value_set_default */
1137 param_uint64_validate, /* value_validate */
1138 param_uint64_values_cmp, /* values_cmp */
1140 type = g_param_type_register_static ("GParamUInt64", &pspec_info);
1141 *spec_types++ = type;
1142 g_assert (type == G_TYPE_PARAM_UINT64);
1145 /* G_TYPE_PARAM_UNICHAR
1148 static const GParamSpecTypeInfo pspec_info = {
1149 sizeof (GParamSpecUnichar), /* instance_size */
1150 16, /* n_preallocs */
1151 param_unichar_init, /* instance_init */
1152 G_TYPE_UINT, /* value_type */
1153 NULL, /* finalize */
1154 param_unichar_set_default, /* value_set_default */
1155 param_unichar_validate, /* value_validate */
1156 param_unichar_values_cmp, /* values_cmp */
1158 type = g_param_type_register_static ("GParamUnichar", &pspec_info);
1159 *spec_types++ = type;
1160 g_assert (type == G_TYPE_PARAM_UNICHAR);
1163 /* G_TYPE_PARAM_ENUM
1166 static const GParamSpecTypeInfo pspec_info = {
1167 sizeof (GParamSpecEnum), /* instance_size */
1168 16, /* n_preallocs */
1169 param_enum_init, /* instance_init */
1170 G_TYPE_ENUM, /* value_type */
1171 param_enum_finalize, /* finalize */
1172 param_enum_set_default, /* value_set_default */
1173 param_enum_validate, /* value_validate */
1174 param_long_values_cmp, /* values_cmp */
1176 type = g_param_type_register_static ("GParamEnum", &pspec_info);
1177 *spec_types++ = type;
1178 g_assert (type == G_TYPE_PARAM_ENUM);
1181 /* G_TYPE_PARAM_FLAGS
1184 static const GParamSpecTypeInfo pspec_info = {
1185 sizeof (GParamSpecFlags), /* instance_size */
1186 16, /* n_preallocs */
1187 param_flags_init, /* instance_init */
1188 G_TYPE_FLAGS, /* value_type */
1189 param_flags_finalize, /* finalize */
1190 param_flags_set_default, /* value_set_default */
1191 param_flags_validate, /* value_validate */
1192 param_ulong_values_cmp, /* values_cmp */
1194 type = g_param_type_register_static ("GParamFlags", &pspec_info);
1195 *spec_types++ = type;
1196 g_assert (type == G_TYPE_PARAM_FLAGS);
1199 /* G_TYPE_PARAM_FLOAT
1202 static const GParamSpecTypeInfo pspec_info = {
1203 sizeof (GParamSpecFloat), /* instance_size */
1204 16, /* n_preallocs */
1205 param_float_init, /* instance_init */
1206 G_TYPE_FLOAT, /* value_type */
1207 NULL, /* finalize */
1208 param_float_set_default, /* value_set_default */
1209 param_float_validate, /* value_validate */
1210 param_float_values_cmp, /* values_cmp */
1212 type = g_param_type_register_static ("GParamFloat", &pspec_info);
1213 *spec_types++ = type;
1214 g_assert (type == G_TYPE_PARAM_FLOAT);
1217 /* G_TYPE_PARAM_DOUBLE
1220 static const GParamSpecTypeInfo pspec_info = {
1221 sizeof (GParamSpecDouble), /* instance_size */
1222 16, /* n_preallocs */
1223 param_double_init, /* instance_init */
1224 G_TYPE_DOUBLE, /* value_type */
1225 NULL, /* finalize */
1226 param_double_set_default, /* value_set_default */
1227 param_double_validate, /* value_validate */
1228 param_double_values_cmp, /* values_cmp */
1230 type = g_param_type_register_static ("GParamDouble", &pspec_info);
1231 *spec_types++ = type;
1232 g_assert (type == G_TYPE_PARAM_DOUBLE);
1235 /* G_TYPE_PARAM_STRING
1238 static const GParamSpecTypeInfo pspec_info = {
1239 sizeof (GParamSpecString), /* instance_size */
1240 16, /* n_preallocs */
1241 param_string_init, /* instance_init */
1242 G_TYPE_STRING, /* value_type */
1243 param_string_finalize, /* finalize */
1244 param_string_set_default, /* value_set_default */
1245 param_string_validate, /* value_validate */
1246 param_string_values_cmp, /* values_cmp */
1248 type = g_param_type_register_static ("GParamString", &pspec_info);
1249 *spec_types++ = type;
1250 g_assert (type == G_TYPE_PARAM_STRING);
1253 /* G_TYPE_PARAM_PARAM
1256 static const GParamSpecTypeInfo pspec_info = {
1257 sizeof (GParamSpecParam), /* instance_size */
1258 16, /* n_preallocs */
1259 param_param_init, /* instance_init */
1260 G_TYPE_PARAM, /* value_type */
1261 NULL, /* finalize */
1262 param_param_set_default, /* value_set_default */
1263 param_param_validate, /* value_validate */
1264 param_pointer_values_cmp, /* values_cmp */
1266 type = g_param_type_register_static ("GParamParam", &pspec_info);
1267 *spec_types++ = type;
1268 g_assert (type == G_TYPE_PARAM_PARAM);
1271 /* G_TYPE_PARAM_BOXED
1274 static const GParamSpecTypeInfo pspec_info = {
1275 sizeof (GParamSpecBoxed), /* instance_size */
1276 4, /* n_preallocs */
1277 param_boxed_init, /* instance_init */
1278 G_TYPE_BOXED, /* value_type */
1279 NULL, /* finalize */
1280 param_boxed_set_default, /* value_set_default */
1281 param_boxed_validate, /* value_validate */
1282 param_boxed_values_cmp, /* values_cmp */
1284 type = g_param_type_register_static ("GParamBoxed", &pspec_info);
1285 *spec_types++ = type;
1286 g_assert (type == G_TYPE_PARAM_BOXED);
1289 /* G_TYPE_PARAM_POINTER
1292 static const GParamSpecTypeInfo pspec_info = {
1293 sizeof (GParamSpecPointer), /* instance_size */
1294 0, /* n_preallocs */
1295 param_pointer_init, /* instance_init */
1296 G_TYPE_POINTER, /* value_type */
1297 NULL, /* finalize */
1298 param_pointer_set_default, /* value_set_default */
1299 param_pointer_validate, /* value_validate */
1300 param_pointer_values_cmp, /* values_cmp */
1302 type = g_param_type_register_static ("GParamPointer", &pspec_info);
1303 *spec_types++ = type;
1304 g_assert (type == G_TYPE_PARAM_POINTER);
1307 /* G_TYPE_PARAM_VALUE_ARRAY
1310 static /* const */ GParamSpecTypeInfo pspec_info = {
1311 sizeof (GParamSpecValueArray), /* instance_size */
1312 0, /* n_preallocs */
1313 param_value_array_init, /* instance_init */
1314 0xdeadbeef, /* value_type, assigned further down */
1315 param_value_array_finalize, /* finalize */
1316 param_value_array_set_default, /* value_set_default */
1317 param_value_array_validate, /* value_validate */
1318 param_value_array_values_cmp, /* values_cmp */
1320 pspec_info.value_type = G_TYPE_VALUE_ARRAY;
1321 type = g_param_type_register_static ("GParamValueArray", &pspec_info);
1322 *spec_types++ = type;
1323 g_assert (type == G_TYPE_PARAM_VALUE_ARRAY);
1326 /* G_TYPE_PARAM_OBJECT
1329 static const GParamSpecTypeInfo pspec_info = {
1330 sizeof (GParamSpecObject), /* instance_size */
1331 16, /* n_preallocs */
1332 param_object_init, /* instance_init */
1333 G_TYPE_OBJECT, /* value_type */
1334 NULL, /* finalize */
1335 param_object_set_default, /* value_set_default */
1336 param_object_validate, /* value_validate */
1337 param_object_values_cmp, /* values_cmp */
1339 type = g_param_type_register_static ("GParamObject", &pspec_info);
1340 *spec_types++ = type;
1341 g_assert (type == G_TYPE_PARAM_OBJECT);
1344 g_assert (spec_types == spec_types_bound);
1347 /* --- GParamSpec initialization --- */
1350 g_param_spec_char (const gchar *name,
1355 gint8 default_value,
1358 GParamSpecChar *cspec;
1360 g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1362 cspec = g_param_spec_internal (G_TYPE_PARAM_CHAR,
1368 cspec->minimum = minimum;
1369 cspec->maximum = maximum;
1370 cspec->default_value = default_value;
1372 return G_PARAM_SPEC (cspec);
1376 g_param_spec_uchar (const gchar *name,
1381 guint8 default_value,
1384 GParamSpecUChar *uspec;
1386 g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1388 uspec = g_param_spec_internal (G_TYPE_PARAM_UCHAR,
1394 uspec->minimum = minimum;
1395 uspec->maximum = maximum;
1396 uspec->default_value = default_value;
1398 return G_PARAM_SPEC (uspec);
1402 g_param_spec_boolean (const gchar *name,
1405 gboolean default_value,
1408 GParamSpecBoolean *bspec;
1410 g_return_val_if_fail (default_value == TRUE || default_value == FALSE, NULL);
1412 bspec = g_param_spec_internal (G_TYPE_PARAM_BOOLEAN,
1418 bspec->default_value = default_value;
1420 return G_PARAM_SPEC (bspec);
1424 g_param_spec_int (const gchar *name,
1432 GParamSpecInt *ispec;
1434 g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1436 ispec = g_param_spec_internal (G_TYPE_PARAM_INT,
1442 ispec->minimum = minimum;
1443 ispec->maximum = maximum;
1444 ispec->default_value = default_value;
1446 return G_PARAM_SPEC (ispec);
1450 g_param_spec_uint (const gchar *name,
1455 guint default_value,
1458 GParamSpecUInt *uspec;
1460 g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1462 uspec = g_param_spec_internal (G_TYPE_PARAM_UINT,
1468 uspec->minimum = minimum;
1469 uspec->maximum = maximum;
1470 uspec->default_value = default_value;
1472 return G_PARAM_SPEC (uspec);
1476 g_param_spec_long (const gchar *name,
1481 glong default_value,
1484 GParamSpecLong *lspec;
1486 g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1488 lspec = g_param_spec_internal (G_TYPE_PARAM_LONG,
1494 lspec->minimum = minimum;
1495 lspec->maximum = maximum;
1496 lspec->default_value = default_value;
1498 return G_PARAM_SPEC (lspec);
1502 g_param_spec_ulong (const gchar *name,
1507 gulong default_value,
1510 GParamSpecULong *uspec;
1512 g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1514 uspec = g_param_spec_internal (G_TYPE_PARAM_ULONG,
1520 uspec->minimum = minimum;
1521 uspec->maximum = maximum;
1522 uspec->default_value = default_value;
1524 return G_PARAM_SPEC (uspec);
1528 g_param_spec_int64 (const gchar *name,
1533 gint64 default_value,
1536 GParamSpecInt64 *lspec;
1538 g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1540 lspec = g_param_spec_internal (G_TYPE_PARAM_INT64,
1546 lspec->minimum = minimum;
1547 lspec->maximum = maximum;
1548 lspec->default_value = default_value;
1550 return G_PARAM_SPEC (lspec);
1554 g_param_spec_uint64 (const gchar *name,
1559 guint64 default_value,
1562 GParamSpecUInt64 *uspec;
1564 g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1566 uspec = g_param_spec_internal (G_TYPE_PARAM_UINT64,
1572 uspec->minimum = minimum;
1573 uspec->maximum = maximum;
1574 uspec->default_value = default_value;
1576 return G_PARAM_SPEC (uspec);
1580 g_param_spec_unichar (const gchar *name,
1583 gunichar default_value,
1586 GParamSpecUnichar *uspec;
1588 uspec = g_param_spec_internal (G_TYPE_PARAM_UNICHAR,
1594 uspec->default_value = default_value;
1596 return G_PARAM_SPEC (uspec);
1600 g_param_spec_enum (const gchar *name,
1607 GParamSpecEnum *espec;
1608 GEnumClass *enum_class;
1610 g_return_val_if_fail (G_TYPE_IS_ENUM (enum_type), NULL);
1612 enum_class = g_type_class_ref (enum_type);
1614 g_return_val_if_fail (g_enum_get_value (enum_class, default_value) != NULL, NULL);
1616 espec = g_param_spec_internal (G_TYPE_PARAM_ENUM,
1622 espec->enum_class = enum_class;
1623 espec->default_value = default_value;
1624 G_PARAM_SPEC (espec)->value_type = enum_type;
1626 return G_PARAM_SPEC (espec);
1630 g_param_spec_flags (const gchar *name,
1634 guint default_value,
1637 GParamSpecFlags *fspec;
1638 GFlagsClass *flags_class;
1640 g_return_val_if_fail (G_TYPE_IS_FLAGS (flags_type), NULL);
1642 flags_class = g_type_class_ref (flags_type);
1644 g_return_val_if_fail ((default_value & flags_class->mask) == default_value, NULL);
1646 fspec = g_param_spec_internal (G_TYPE_PARAM_FLAGS,
1652 fspec->flags_class = flags_class;
1653 fspec->default_value = default_value;
1654 G_PARAM_SPEC (fspec)->value_type = flags_type;
1656 return G_PARAM_SPEC (fspec);
1660 g_param_spec_float (const gchar *name,
1665 gfloat default_value,
1668 GParamSpecFloat *fspec;
1670 g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1672 fspec = g_param_spec_internal (G_TYPE_PARAM_FLOAT,
1678 fspec->minimum = minimum;
1679 fspec->maximum = maximum;
1680 fspec->default_value = default_value;
1682 return G_PARAM_SPEC (fspec);
1686 g_param_spec_double (const gchar *name,
1691 gdouble default_value,
1694 GParamSpecDouble *dspec;
1696 g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1698 dspec = g_param_spec_internal (G_TYPE_PARAM_DOUBLE,
1704 dspec->minimum = minimum;
1705 dspec->maximum = maximum;
1706 dspec->default_value = default_value;
1708 return G_PARAM_SPEC (dspec);
1712 g_param_spec_string (const gchar *name,
1715 const gchar *default_value,
1718 GParamSpecString *sspec = g_param_spec_internal (G_TYPE_PARAM_STRING,
1723 g_free (sspec->default_value);
1724 sspec->default_value = g_strdup (default_value);
1726 return G_PARAM_SPEC (sspec);
1730 g_param_spec_param (const gchar *name,
1736 GParamSpecParam *pspec;
1738 g_return_val_if_fail (G_TYPE_IS_PARAM (param_type), NULL);
1740 pspec = g_param_spec_internal (G_TYPE_PARAM_PARAM,
1745 G_PARAM_SPEC (pspec)->value_type = param_type;
1747 return G_PARAM_SPEC (pspec);
1751 g_param_spec_boxed (const gchar *name,
1757 GParamSpecBoxed *bspec;
1759 g_return_val_if_fail (G_TYPE_IS_BOXED (boxed_type), NULL);
1760 g_return_val_if_fail (G_TYPE_IS_VALUE_TYPE (boxed_type), NULL);
1762 bspec = g_param_spec_internal (G_TYPE_PARAM_BOXED,
1767 G_PARAM_SPEC (bspec)->value_type = boxed_type;
1769 return G_PARAM_SPEC (bspec);
1773 g_param_spec_pointer (const gchar *name,
1778 GParamSpecPointer *pspec;
1780 pspec = g_param_spec_internal (G_TYPE_PARAM_POINTER,
1785 return G_PARAM_SPEC (pspec);
1789 g_param_spec_value_array (const gchar *name,
1792 GParamSpec *element_spec,
1795 GParamSpecValueArray *aspec;
1798 g_return_val_if_fail (G_IS_PARAM_SPEC (element_spec), NULL);
1800 aspec = g_param_spec_internal (G_TYPE_PARAM_VALUE_ARRAY,
1807 aspec->element_spec = g_param_spec_ref (element_spec);
1808 g_param_spec_sink (element_spec);
1811 return G_PARAM_SPEC (aspec);
1815 g_param_spec_object (const gchar *name,
1821 GParamSpecObject *ospec;
1823 g_return_val_if_fail (g_type_is_a (object_type, G_TYPE_OBJECT), NULL);
1825 ospec = g_param_spec_internal (G_TYPE_PARAM_OBJECT,
1830 G_PARAM_SPEC (ospec)->value_type = object_type;
1832 return G_PARAM_SPEC (ospec);