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 "gparamspecs.h"
26 #include "gvaluecollector.h"
27 #include "gvaluearray.h"
29 #include "../config.h" /* for SIZEOF_LONG */
31 #define G_FLOAT_EPSILON (1e-30)
32 #define G_DOUBLE_EPSILON (1e-90)
35 /* --- param spec functions --- */
37 param_char_init (GParamSpec *pspec)
39 GParamSpecChar *cspec = G_PARAM_SPEC_CHAR (pspec);
41 cspec->minimum = 0x7f;
42 cspec->maximum = 0x80;
43 cspec->default_value = 0;
47 param_char_set_default (GParamSpec *pspec,
50 value->data[0].v_int = G_PARAM_SPEC_CHAR (pspec)->default_value;
54 param_char_validate (GParamSpec *pspec,
57 GParamSpecChar *cspec = G_PARAM_SPEC_CHAR (pspec);
58 gint oval = value->data[0].v_int;
60 value->data[0].v_int = CLAMP (value->data[0].v_int, cspec->minimum, cspec->maximum);
62 return value->data[0].v_int != oval;
66 param_uchar_init (GParamSpec *pspec)
68 GParamSpecUChar *uspec = G_PARAM_SPEC_UCHAR (pspec);
71 uspec->maximum = 0xff;
72 uspec->default_value = 0;
76 param_uchar_set_default (GParamSpec *pspec,
79 value->data[0].v_uint = G_PARAM_SPEC_UCHAR (pspec)->default_value;
83 param_uchar_validate (GParamSpec *pspec,
86 GParamSpecUChar *uspec = G_PARAM_SPEC_UCHAR (pspec);
87 guint oval = value->data[0].v_uint;
89 value->data[0].v_uint = CLAMP (value->data[0].v_uint, uspec->minimum, uspec->maximum);
91 return value->data[0].v_uint != oval;
95 param_boolean_set_default (GParamSpec *pspec,
98 value->data[0].v_int = G_PARAM_SPEC_BOOLEAN (pspec)->default_value;
102 param_boolean_validate (GParamSpec *pspec,
105 gint oval = value->data[0].v_int;
107 value->data[0].v_int = value->data[0].v_int != FALSE;
109 return value->data[0].v_int != oval;
113 param_int_init (GParamSpec *pspec)
115 GParamSpecInt *ispec = G_PARAM_SPEC_INT (pspec);
117 ispec->minimum = 0x7fffffff;
118 ispec->maximum = 0x80000000;
119 ispec->default_value = 0;
123 param_int_set_default (GParamSpec *pspec,
126 value->data[0].v_int = G_PARAM_SPEC_INT (pspec)->default_value;
130 param_int_validate (GParamSpec *pspec,
133 GParamSpecInt *ispec = G_PARAM_SPEC_INT (pspec);
134 gint oval = value->data[0].v_int;
136 value->data[0].v_int = CLAMP (value->data[0].v_int, ispec->minimum, ispec->maximum);
138 return value->data[0].v_int != oval;
142 param_int_values_cmp (GParamSpec *pspec,
143 const GValue *value1,
144 const GValue *value2)
146 if (value1->data[0].v_int < value2->data[0].v_int)
149 return value1->data[0].v_int > value2->data[0].v_int;
153 param_uint_init (GParamSpec *pspec)
155 GParamSpecUInt *uspec = G_PARAM_SPEC_UINT (pspec);
158 uspec->maximum = 0xffffffff;
159 uspec->default_value = 0;
163 param_uint_set_default (GParamSpec *pspec,
166 value->data[0].v_uint = G_PARAM_SPEC_UINT (pspec)->default_value;
170 param_uint_validate (GParamSpec *pspec,
173 GParamSpecUInt *uspec = G_PARAM_SPEC_UINT (pspec);
174 guint oval = value->data[0].v_uint;
176 value->data[0].v_uint = CLAMP (value->data[0].v_uint, uspec->minimum, uspec->maximum);
178 return value->data[0].v_uint != oval;
182 param_uint_values_cmp (GParamSpec *pspec,
183 const GValue *value1,
184 const GValue *value2)
186 if (value1->data[0].v_uint < value2->data[0].v_uint)
189 return value1->data[0].v_uint > value2->data[0].v_uint;
193 param_long_init (GParamSpec *pspec)
195 GParamSpecLong *lspec = G_PARAM_SPEC_LONG (pspec);
198 lspec->minimum = 0x7fffffff;
199 lspec->maximum = 0x80000000;
200 #else /* SIZEOF_LONG != 4 (8) */
201 lspec->minimum = 0x7fffffffffffffff;
202 lspec->maximum = 0x8000000000000000;
204 lspec->default_value = 0;
208 param_long_set_default (GParamSpec *pspec,
211 value->data[0].v_long = G_PARAM_SPEC_LONG (pspec)->default_value;
215 param_long_validate (GParamSpec *pspec,
218 GParamSpecLong *lspec = G_PARAM_SPEC_LONG (pspec);
219 glong oval = value->data[0].v_long;
221 value->data[0].v_long = CLAMP (value->data[0].v_long, lspec->minimum, lspec->maximum);
223 return value->data[0].v_long != oval;
227 param_long_values_cmp (GParamSpec *pspec,
228 const GValue *value1,
229 const GValue *value2)
231 if (value1->data[0].v_long < value2->data[0].v_long)
234 return value1->data[0].v_long > value2->data[0].v_long;
238 param_ulong_init (GParamSpec *pspec)
240 GParamSpecULong *uspec = G_PARAM_SPEC_ULONG (pspec);
244 uspec->maximum = 0xffffffff;
245 #else /* SIZEOF_LONG != 4 (8) */
246 uspec->maximum = 0xffffffffffffffff;
248 uspec->default_value = 0;
252 param_ulong_set_default (GParamSpec *pspec,
255 value->data[0].v_ulong = G_PARAM_SPEC_ULONG (pspec)->default_value;
259 param_ulong_validate (GParamSpec *pspec,
262 GParamSpecULong *uspec = G_PARAM_SPEC_ULONG (pspec);
263 gulong oval = value->data[0].v_ulong;
265 value->data[0].v_ulong = CLAMP (value->data[0].v_ulong, uspec->minimum, uspec->maximum);
267 return value->data[0].v_ulong != oval;
271 param_ulong_values_cmp (GParamSpec *pspec,
272 const GValue *value1,
273 const GValue *value2)
275 if (value1->data[0].v_ulong < value2->data[0].v_ulong)
278 return value1->data[0].v_ulong > value2->data[0].v_ulong;
282 param_int64_init (GParamSpec *pspec)
284 GParamSpecInt64 *lspec = G_PARAM_SPEC_INT64 (pspec);
286 lspec->minimum = G_MININT64;
287 lspec->maximum = G_MAXINT64;
288 lspec->default_value = 0;
292 param_int64_set_default (GParamSpec *pspec,
295 value->data[0].v_int64 = G_PARAM_SPEC_INT64 (pspec)->default_value;
299 param_int64_validate (GParamSpec *pspec,
302 GParamSpecInt64 *lspec = G_PARAM_SPEC_INT64 (pspec);
303 gint64 oval = value->data[0].v_int64;
305 value->data[0].v_int64 = CLAMP (value->data[0].v_int64, lspec->minimum, lspec->maximum);
307 return value->data[0].v_int64 != oval;
311 param_int64_values_cmp (GParamSpec *pspec,
312 const GValue *value1,
313 const GValue *value2)
315 if (value1->data[0].v_int64 < value2->data[0].v_int64)
318 return value1->data[0].v_int64 > value2->data[0].v_int64;
322 param_uint64_init (GParamSpec *pspec)
324 GParamSpecUInt64 *uspec = G_PARAM_SPEC_UINT64 (pspec);
327 uspec->maximum = G_MAXUINT64;
328 uspec->default_value = 0;
332 param_uint64_set_default (GParamSpec *pspec,
335 value->data[0].v_uint64 = G_PARAM_SPEC_UINT64 (pspec)->default_value;
339 param_uint64_validate (GParamSpec *pspec,
342 GParamSpecUInt64 *uspec = G_PARAM_SPEC_UINT64 (pspec);
343 guint64 oval = value->data[0].v_uint64;
345 value->data[0].v_uint64 = CLAMP (value->data[0].v_uint64, uspec->minimum, uspec->maximum);
347 return value->data[0].v_uint64 != oval;
351 param_uint64_values_cmp (GParamSpec *pspec,
352 const GValue *value1,
353 const GValue *value2)
355 if (value1->data[0].v_uint64 < value2->data[0].v_uint64)
358 return value1->data[0].v_uint64 > value2->data[0].v_uint64;
362 param_unichar_init (GParamSpec *pspec)
364 GParamSpecUnichar *uspec = G_PARAM_SPEC_UNICHAR (pspec);
366 uspec->default_value = 0;
370 param_unichar_set_default (GParamSpec *pspec,
373 value->data[0].v_uint = G_PARAM_SPEC_UNICHAR (pspec)->default_value;
377 param_unichar_validate (GParamSpec *pspec,
380 gunichar oval = value->data[0].v_uint;
381 gboolean changed = FALSE;
383 if (!g_unichar_validate (oval))
385 value->data[0].v_uint = 0;
393 param_unichar_values_cmp (GParamSpec *pspec,
394 const GValue *value1,
395 const GValue *value2)
397 if (value1->data[0].v_uint < value2->data[0].v_uint)
400 return value1->data[0].v_uint > value2->data[0].v_uint;
404 param_enum_init (GParamSpec *pspec)
406 GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec);
408 espec->enum_class = NULL;
409 espec->default_value = 0;
413 param_enum_finalize (GParamSpec *pspec)
415 GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec);
416 GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_ENUM));
418 if (espec->enum_class)
420 g_type_class_unref (espec->enum_class);
421 espec->enum_class = NULL;
424 parent_class->finalize (pspec);
428 param_enum_set_default (GParamSpec *pspec,
431 value->data[0].v_long = G_PARAM_SPEC_ENUM (pspec)->default_value;
435 param_enum_validate (GParamSpec *pspec,
438 GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec);
439 glong oval = value->data[0].v_long;
441 if (!espec->enum_class ||
442 !g_enum_get_value (espec->enum_class, value->data[0].v_long))
443 value->data[0].v_long = espec->default_value;
445 return value->data[0].v_long != oval;
449 param_flags_init (GParamSpec *pspec)
451 GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec);
453 fspec->flags_class = NULL;
454 fspec->default_value = 0;
458 param_flags_finalize (GParamSpec *pspec)
460 GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec);
461 GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_FLAGS));
463 if (fspec->flags_class)
465 g_type_class_unref (fspec->flags_class);
466 fspec->flags_class = NULL;
469 parent_class->finalize (pspec);
473 param_flags_set_default (GParamSpec *pspec,
476 value->data[0].v_ulong = G_PARAM_SPEC_FLAGS (pspec)->default_value;
480 param_flags_validate (GParamSpec *pspec,
483 GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec);
484 gulong oval = value->data[0].v_ulong;
486 if (fspec->flags_class)
487 value->data[0].v_ulong &= fspec->flags_class->mask;
489 value->data[0].v_ulong = fspec->default_value;
491 return value->data[0].v_ulong != oval;
495 param_float_init (GParamSpec *pspec)
497 GParamSpecFloat *fspec = G_PARAM_SPEC_FLOAT (pspec);
499 fspec->minimum = G_MINFLOAT;
500 fspec->maximum = G_MAXFLOAT;
501 fspec->default_value = 0;
502 fspec->epsilon = G_FLOAT_EPSILON;
506 param_float_set_default (GParamSpec *pspec,
509 value->data[0].v_float = G_PARAM_SPEC_FLOAT (pspec)->default_value;
513 param_float_validate (GParamSpec *pspec,
516 GParamSpecFloat *fspec = G_PARAM_SPEC_FLOAT (pspec);
517 gfloat oval = value->data[0].v_float;
519 value->data[0].v_float = CLAMP (value->data[0].v_float, fspec->minimum, fspec->maximum);
521 return value->data[0].v_float != oval;
525 param_float_values_cmp (GParamSpec *pspec,
526 const GValue *value1,
527 const GValue *value2)
529 gfloat epsilon = G_PARAM_SPEC_FLOAT (pspec)->epsilon;
531 if (value1->data[0].v_float < value2->data[0].v_float)
532 return - (value2->data[0].v_float - value1->data[0].v_float > epsilon);
534 return value1->data[0].v_float - value2->data[0].v_float > epsilon;
538 param_double_init (GParamSpec *pspec)
540 GParamSpecDouble *dspec = G_PARAM_SPEC_DOUBLE (pspec);
542 dspec->minimum = G_MINDOUBLE;
543 dspec->maximum = G_MAXDOUBLE;
544 dspec->default_value = 0;
545 dspec->epsilon = G_DOUBLE_EPSILON;
549 param_double_set_default (GParamSpec *pspec,
552 value->data[0].v_double = G_PARAM_SPEC_DOUBLE (pspec)->default_value;
556 param_double_validate (GParamSpec *pspec,
559 GParamSpecDouble *dspec = G_PARAM_SPEC_DOUBLE (pspec);
560 gdouble oval = value->data[0].v_double;
562 value->data[0].v_double = CLAMP (value->data[0].v_double, dspec->minimum, dspec->maximum);
564 return value->data[0].v_double != oval;
568 param_double_values_cmp (GParamSpec *pspec,
569 const GValue *value1,
570 const GValue *value2)
572 gdouble epsilon = G_PARAM_SPEC_DOUBLE (pspec)->epsilon;
574 if (value1->data[0].v_double < value2->data[0].v_double)
575 return - (value2->data[0].v_double - value1->data[0].v_double > epsilon);
577 return value1->data[0].v_double - value2->data[0].v_double > epsilon;
581 param_string_init (GParamSpec *pspec)
583 GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec);
585 sspec->default_value = NULL;
586 sspec->cset_first = NULL;
587 sspec->cset_nth = NULL;
588 sspec->substitutor = '_';
589 sspec->null_fold_if_empty = FALSE;
590 sspec->ensure_non_null = FALSE;
594 param_string_finalize (GParamSpec *pspec)
596 GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec);
597 GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_STRING));
599 g_free (sspec->default_value);
600 g_free (sspec->cset_first);
601 g_free (sspec->cset_nth);
602 sspec->default_value = NULL;
603 sspec->cset_first = NULL;
604 sspec->cset_nth = NULL;
606 parent_class->finalize (pspec);
610 param_string_set_default (GParamSpec *pspec,
613 value->data[0].v_pointer = g_strdup (G_PARAM_SPEC_STRING (pspec)->default_value);
617 param_string_validate (GParamSpec *pspec,
620 GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec);
621 gchar *string = value->data[0].v_pointer;
624 if (string && string[0])
628 if (sspec->cset_first && !strchr (sspec->cset_first, string[0]))
630 string[0] = sspec->substitutor;
634 for (s = string + 1; *s; s++)
635 if (!strchr (sspec->cset_nth, *s))
637 *s = sspec->substitutor;
641 if (sspec->null_fold_if_empty && string && string[0] == 0)
643 g_free (value->data[0].v_pointer);
644 value->data[0].v_pointer = NULL;
646 string = value->data[0].v_pointer;
648 if (sspec->ensure_non_null && !string)
650 value->data[0].v_pointer = g_strdup ("");
652 string = value->data[0].v_pointer;
659 param_string_values_cmp (GParamSpec *pspec,
660 const GValue *value1,
661 const GValue *value2)
663 if (!value1->data[0].v_pointer)
664 return value2->data[0].v_pointer != NULL ? -1 : 0;
665 else if (!value2->data[0].v_pointer)
666 return value1->data[0].v_pointer != NULL;
668 return strcmp (value1->data[0].v_pointer, value2->data[0].v_pointer);
672 param_param_init (GParamSpec *pspec)
674 /* GParamSpecParam *spec = G_PARAM_SPEC_PARAM (pspec); */
678 param_param_set_default (GParamSpec *pspec,
681 value->data[0].v_pointer = NULL;
685 param_param_validate (GParamSpec *pspec,
688 /* GParamSpecParam *spec = G_PARAM_SPEC_PARAM (pspec); */
689 GParamSpec *param = value->data[0].v_pointer;
692 if (param && !g_value_type_compatible (G_PARAM_SPEC_TYPE (param), G_PARAM_SPEC_VALUE_TYPE (pspec)))
694 g_param_spec_unref (param);
695 value->data[0].v_pointer = NULL;
703 param_boxed_init (GParamSpec *pspec)
705 /* GParamSpecBoxed *bspec = G_PARAM_SPEC_BOXED (pspec); */
709 param_boxed_set_default (GParamSpec *pspec,
712 value->data[0].v_pointer = NULL;
716 param_boxed_validate (GParamSpec *pspec,
719 /* GParamSpecBoxed *bspec = G_PARAM_SPEC_BOXED (pspec); */
722 /* can't do a whole lot here since we haven't even G_BOXED_TYPE() */
728 param_boxed_values_cmp (GParamSpec *pspec,
729 const GValue *value1,
730 const GValue *value2)
732 guint8 *p1 = value1->data[0].v_pointer;
733 guint8 *p2 = value2->data[0].v_pointer;
735 /* not much to compare here, try to at least provide stable lesser/greater result */
737 return p1 < p2 ? -1 : p1 > p2;
741 param_pointer_init (GParamSpec *pspec)
743 /* GParamSpecPointer *spec = G_PARAM_SPEC_POINTER (pspec); */
747 param_pointer_set_default (GParamSpec *pspec,
750 value->data[0].v_pointer = NULL;
754 param_pointer_validate (GParamSpec *pspec,
757 /* GParamSpecPointer *spec = G_PARAM_SPEC_POINTER (pspec); */
764 param_pointer_values_cmp (GParamSpec *pspec,
765 const GValue *value1,
766 const GValue *value2)
768 guint8 *p1 = value1->data[0].v_pointer;
769 guint8 *p2 = value2->data[0].v_pointer;
771 /* not much to compare here, try to at least provide stable lesser/greater result */
773 return p1 < p2 ? -1 : p1 > p2;
777 param_closure_init (GParamSpec *pspec)
779 /* GParamSpecClosure *cspec = G_PARAM_SPEC_CLOSURE (pspec); */
783 param_closure_set_default (GParamSpec *pspec,
786 value->data[0].v_pointer = NULL;
790 param_closure_validate (GParamSpec *pspec,
793 /* GParamSpecClosure *cspec = G_PARAM_SPEC_CLOSURE (pspec); */
794 /* GClosure *closure = value->data[0].v_pointer; */
797 /* we don't actually have necessary means to ensure closure validity */
803 param_closure_values_cmp (GParamSpec *pspec,
804 const GValue *value1,
805 const GValue *value2)
807 guint8 *p1 = value1->data[0].v_pointer;
808 guint8 *p2 = value2->data[0].v_pointer;
810 /* not much to compare here, try to at least provide stable lesser/greater result */
812 return p1 < p2 ? -1 : p1 > p2;
816 param_value_array_init (GParamSpec *pspec)
818 GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
820 aspec->element_spec = NULL;
821 aspec->fixed_n_elements = 0; /* disable */
825 value_array_ensure_size (GValueArray *value_array,
826 guint fixed_n_elements)
830 if (fixed_n_elements)
832 while (value_array->n_values < fixed_n_elements)
834 g_value_array_append (value_array, NULL);
837 while (value_array->n_values > fixed_n_elements)
839 g_value_array_remove (value_array, value_array->n_values - 1);
847 param_value_array_finalize (GParamSpec *pspec)
849 GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
850 GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_VALUE_ARRAY));
852 if (aspec->element_spec)
854 g_param_spec_unref (aspec->element_spec);
855 aspec->element_spec = NULL;
858 parent_class->finalize (pspec);
862 param_value_array_set_default (GParamSpec *pspec,
865 GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
867 g_return_if_fail (value->data[0].v_pointer != NULL); /* paranoid */
869 /* g_value_reset (value); already done */
870 value_array_ensure_size (value->data[0].v_pointer, aspec->fixed_n_elements);
874 param_value_array_validate (GParamSpec *pspec,
877 GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
878 GValueArray *value_array = value->data[0].v_pointer;
881 g_return_val_if_fail (value->data[0].v_pointer != NULL, FALSE); /* paranoid */
883 /* ensure array size validity */
884 changed += value_array_ensure_size (value_array, aspec->fixed_n_elements);
886 /* ensure array values validity against a present element spec */
887 if (aspec->element_spec)
889 GParamSpec *element_spec = aspec->element_spec;
892 for (i = 0; i < value_array->n_values; i++)
894 GValue *element = value_array->values + i;
896 /* need to fixup value type, or ensure that the array value is initialized at all */
897 if (!g_value_type_compatible (G_VALUE_TYPE (element), G_PARAM_SPEC_VALUE_TYPE (element_spec)))
899 if (G_VALUE_TYPE (element) != 0)
900 g_value_unset (element);
901 g_value_init (element, G_PARAM_SPEC_VALUE_TYPE (element_spec));
902 g_param_value_set_default (element_spec, element);
905 /* validate array value against element_spec */
906 changed += g_param_value_validate (element_spec, element);
914 param_value_array_values_cmp (GParamSpec *pspec,
915 const GValue *value1,
916 const GValue *value2)
918 GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
919 GValueArray *value_array1 = value1->data[0].v_pointer;
920 GValueArray *value_array2 = value2->data[0].v_pointer;
922 g_return_val_if_fail (value1->data[0].v_pointer != NULL, -1); /* paranoid */
923 g_return_val_if_fail (value2->data[0].v_pointer != NULL, 1); /* paranoid */
925 if (value_array1->n_values != value_array2->n_values)
926 return value_array1->n_values < value_array2->n_values ? -1 : 1;
927 else if (!aspec->element_spec)
929 /* we need an element specification for comparisons, so there's not much
930 * to compare here, try to at least provide stable lesser/greater result
932 return value_array1->n_values < value_array2->n_values ? -1 : value_array1->n_values > value_array2->n_values;
934 else /* value_array1->n_values == value_array2->n_values */
938 for (i = 0; i < value_array1->n_values; i++)
940 GValue *element1 = value_array1->values + i;
941 GValue *element2 = value_array2->values + i;
944 /* need corresponding element types, provide stable result otherwise */
945 if (G_VALUE_TYPE (element1) != G_VALUE_TYPE (element2))
946 return G_VALUE_TYPE (element1) < G_VALUE_TYPE (element2) ? -1 : 1;
947 cmp = g_param_values_cmp (aspec->element_spec, element1, element2);
956 param_object_init (GParamSpec *pspec)
958 /* GParamSpecObject *ospec = G_PARAM_SPEC_OBJECT (pspec); */
962 param_object_set_default (GParamSpec *pspec,
965 value->data[0].v_pointer = NULL;
969 param_object_validate (GParamSpec *pspec,
972 GParamSpecObject *ospec = G_PARAM_SPEC_OBJECT (pspec);
973 GObject *object = value->data[0].v_pointer;
976 if (object && !g_value_type_compatible (G_OBJECT_TYPE (object), G_PARAM_SPEC_VALUE_TYPE (ospec)))
978 g_object_unref (object);
979 value->data[0].v_pointer = NULL;
987 param_object_values_cmp (GParamSpec *pspec,
988 const GValue *value1,
989 const GValue *value2)
991 guint8 *p1 = value1->data[0].v_pointer;
992 guint8 *p2 = value2->data[0].v_pointer;
994 /* not much to compare here, try to at least provide stable lesser/greater result */
996 return p1 < p2 ? -1 : p1 > p2;
1000 /* --- type initialization --- */
1002 g_param_spec_types_init (void) /* sync with gtype.c */
1006 /* G_TYPE_PARAM_CHAR
1009 static const GParamSpecTypeInfo pspec_info = {
1010 sizeof (GParamSpecChar), /* instance_size */
1011 16, /* n_preallocs */
1012 param_char_init, /* instance_init */
1013 G_TYPE_CHAR, /* value_type */
1014 NULL, /* finalize */
1015 param_char_set_default, /* value_set_default */
1016 param_char_validate, /* value_validate */
1017 param_int_values_cmp, /* values_cmp */
1019 type = g_param_type_register_static ("GParamChar", &pspec_info);
1020 g_assert (type == G_TYPE_PARAM_CHAR);
1023 /* G_TYPE_PARAM_UCHAR
1026 static const GParamSpecTypeInfo pspec_info = {
1027 sizeof (GParamSpecUChar), /* instance_size */
1028 16, /* n_preallocs */
1029 param_uchar_init, /* instance_init */
1030 G_TYPE_UCHAR, /* value_type */
1031 NULL, /* finalize */
1032 param_uchar_set_default, /* value_set_default */
1033 param_uchar_validate, /* value_validate */
1034 param_uint_values_cmp, /* values_cmp */
1036 type = g_param_type_register_static ("GParamUChar", &pspec_info);
1037 g_assert (type == G_TYPE_PARAM_UCHAR);
1040 /* G_TYPE_PARAM_BOOLEAN
1043 static const GParamSpecTypeInfo pspec_info = {
1044 sizeof (GParamSpecBoolean), /* instance_size */
1045 16, /* n_preallocs */
1046 NULL, /* instance_init */
1047 G_TYPE_BOOLEAN, /* value_type */
1048 NULL, /* finalize */
1049 param_boolean_set_default, /* value_set_default */
1050 param_boolean_validate, /* value_validate */
1051 param_int_values_cmp, /* values_cmp */
1053 type = g_param_type_register_static ("GParamBoolean", &pspec_info);
1054 g_assert (type == G_TYPE_PARAM_BOOLEAN);
1060 static const GParamSpecTypeInfo pspec_info = {
1061 sizeof (GParamSpecInt), /* instance_size */
1062 16, /* n_preallocs */
1063 param_int_init, /* instance_init */
1064 G_TYPE_INT, /* value_type */
1065 NULL, /* finalize */
1066 param_int_set_default, /* value_set_default */
1067 param_int_validate, /* value_validate */
1068 param_int_values_cmp, /* values_cmp */
1070 type = g_param_type_register_static ("GParamInt", &pspec_info);
1071 g_assert (type == G_TYPE_PARAM_INT);
1074 /* G_TYPE_PARAM_UINT
1077 static const GParamSpecTypeInfo pspec_info = {
1078 sizeof (GParamSpecUInt), /* instance_size */
1079 16, /* n_preallocs */
1080 param_uint_init, /* instance_init */
1081 G_TYPE_UINT, /* value_type */
1082 NULL, /* finalize */
1083 param_uint_set_default, /* value_set_default */
1084 param_uint_validate, /* value_validate */
1085 param_uint_values_cmp, /* values_cmp */
1087 type = g_param_type_register_static ("GParamUInt", &pspec_info);
1088 g_assert (type == G_TYPE_PARAM_UINT);
1091 /* G_TYPE_PARAM_LONG
1094 static const GParamSpecTypeInfo pspec_info = {
1095 sizeof (GParamSpecLong), /* instance_size */
1096 16, /* n_preallocs */
1097 param_long_init, /* instance_init */
1098 G_TYPE_LONG, /* value_type */
1099 NULL, /* finalize */
1100 param_long_set_default, /* value_set_default */
1101 param_long_validate, /* value_validate */
1102 param_long_values_cmp, /* values_cmp */
1104 type = g_param_type_register_static ("GParamLong", &pspec_info);
1105 g_assert (type == G_TYPE_PARAM_LONG);
1108 /* G_TYPE_PARAM_ULONG
1111 static const GParamSpecTypeInfo pspec_info = {
1112 sizeof (GParamSpecULong), /* instance_size */
1113 16, /* n_preallocs */
1114 param_ulong_init, /* instance_init */
1115 G_TYPE_ULONG, /* value_type */
1116 NULL, /* finalize */
1117 param_ulong_set_default, /* value_set_default */
1118 param_ulong_validate, /* value_validate */
1119 param_ulong_values_cmp, /* values_cmp */
1121 type = g_param_type_register_static ("GParamULong", &pspec_info);
1122 g_assert (type == G_TYPE_PARAM_ULONG);
1125 /* G_TYPE_PARAM_INT64
1128 static const GParamSpecTypeInfo pspec_info = {
1129 sizeof (GParamSpecInt64), /* instance_size */
1130 16, /* n_preallocs */
1131 param_int64_init, /* instance_init */
1132 G_TYPE_INT64, /* value_type */
1133 NULL, /* finalize */
1134 param_int64_set_default, /* value_set_default */
1135 param_int64_validate, /* value_validate */
1136 param_int64_values_cmp, /* values_cmp */
1138 type = g_param_type_register_static ("GParamInt64", &pspec_info);
1139 g_assert (type == G_TYPE_PARAM_INT64);
1142 /* G_TYPE_PARAM_UINT64
1145 static const GParamSpecTypeInfo pspec_info = {
1146 sizeof (GParamSpecUInt64), /* instance_size */
1147 16, /* n_preallocs */
1148 param_uint64_init, /* instance_init */
1149 G_TYPE_UINT64, /* value_type */
1150 NULL, /* finalize */
1151 param_uint64_set_default, /* value_set_default */
1152 param_uint64_validate, /* value_validate */
1153 param_uint64_values_cmp, /* values_cmp */
1155 type = g_param_type_register_static ("GParamUInt64", &pspec_info);
1156 g_assert (type == G_TYPE_PARAM_UINT64);
1159 /* G_TYPE_PARAM_UNICHAR
1162 static const GParamSpecTypeInfo pspec_info = {
1163 sizeof (GParamSpecUnichar), /* instance_size */
1164 16, /* n_preallocs */
1165 param_unichar_init, /* instance_init */
1166 G_TYPE_UINT, /* value_type */
1167 NULL, /* finalize */
1168 param_unichar_set_default, /* value_set_default */
1169 param_unichar_validate, /* value_validate */
1170 param_unichar_values_cmp, /* values_cmp */
1172 type = g_param_type_register_static ("GParamUnichar", &pspec_info);
1173 g_assert (type == G_TYPE_PARAM_UNICHAR);
1176 /* G_TYPE_PARAM_ENUM
1179 static const GParamSpecTypeInfo pspec_info = {
1180 sizeof (GParamSpecEnum), /* instance_size */
1181 16, /* n_preallocs */
1182 param_enum_init, /* instance_init */
1183 G_TYPE_ENUM, /* value_type */
1184 param_enum_finalize, /* finalize */
1185 param_enum_set_default, /* value_set_default */
1186 param_enum_validate, /* value_validate */
1187 param_long_values_cmp, /* values_cmp */
1189 type = g_param_type_register_static ("GParamEnum", &pspec_info);
1190 g_assert (type == G_TYPE_PARAM_ENUM);
1193 /* G_TYPE_PARAM_FLAGS
1196 static const GParamSpecTypeInfo pspec_info = {
1197 sizeof (GParamSpecFlags), /* instance_size */
1198 16, /* n_preallocs */
1199 param_flags_init, /* instance_init */
1200 G_TYPE_FLAGS, /* value_type */
1201 param_flags_finalize, /* finalize */
1202 param_flags_set_default, /* value_set_default */
1203 param_flags_validate, /* value_validate */
1204 param_ulong_values_cmp, /* values_cmp */
1206 type = g_param_type_register_static ("GParamFlags", &pspec_info);
1207 g_assert (type == G_TYPE_PARAM_FLAGS);
1210 /* G_TYPE_PARAM_FLOAT
1213 static const GParamSpecTypeInfo pspec_info = {
1214 sizeof (GParamSpecFloat), /* instance_size */
1215 16, /* n_preallocs */
1216 param_float_init, /* instance_init */
1217 G_TYPE_FLOAT, /* value_type */
1218 NULL, /* finalize */
1219 param_float_set_default, /* value_set_default */
1220 param_float_validate, /* value_validate */
1221 param_float_values_cmp, /* values_cmp */
1223 type = g_param_type_register_static ("GParamFloat", &pspec_info);
1224 g_assert (type == G_TYPE_PARAM_FLOAT);
1227 /* G_TYPE_PARAM_DOUBLE
1230 static const GParamSpecTypeInfo pspec_info = {
1231 sizeof (GParamSpecDouble), /* instance_size */
1232 16, /* n_preallocs */
1233 param_double_init, /* instance_init */
1234 G_TYPE_DOUBLE, /* value_type */
1235 NULL, /* finalize */
1236 param_double_set_default, /* value_set_default */
1237 param_double_validate, /* value_validate */
1238 param_double_values_cmp, /* values_cmp */
1240 type = g_param_type_register_static ("GParamDouble", &pspec_info);
1241 g_assert (type == G_TYPE_PARAM_DOUBLE);
1244 /* G_TYPE_PARAM_STRING
1247 static const GParamSpecTypeInfo pspec_info = {
1248 sizeof (GParamSpecString), /* instance_size */
1249 16, /* n_preallocs */
1250 param_string_init, /* instance_init */
1251 G_TYPE_STRING, /* value_type */
1252 param_string_finalize, /* finalize */
1253 param_string_set_default, /* value_set_default */
1254 param_string_validate, /* value_validate */
1255 param_string_values_cmp, /* values_cmp */
1257 type = g_param_type_register_static ("GParamString", &pspec_info);
1258 g_assert (type == G_TYPE_PARAM_STRING);
1261 /* G_TYPE_PARAM_PARAM
1264 static const GParamSpecTypeInfo pspec_info = {
1265 sizeof (GParamSpecParam), /* instance_size */
1266 16, /* n_preallocs */
1267 param_param_init, /* instance_init */
1268 G_TYPE_PARAM, /* value_type */
1269 NULL, /* finalize */
1270 param_param_set_default, /* value_set_default */
1271 param_param_validate, /* value_validate */
1272 param_pointer_values_cmp, /* values_cmp */
1274 type = g_param_type_register_static ("GParamParam", &pspec_info);
1275 g_assert (type == G_TYPE_PARAM_PARAM);
1278 /* G_TYPE_PARAM_BOXED
1281 static const GParamSpecTypeInfo pspec_info = {
1282 sizeof (GParamSpecBoxed), /* instance_size */
1283 4, /* n_preallocs */
1284 param_boxed_init, /* instance_init */
1285 G_TYPE_BOXED, /* value_type */
1286 NULL, /* finalize */
1287 param_boxed_set_default, /* value_set_default */
1288 param_boxed_validate, /* value_validate */
1289 param_boxed_values_cmp, /* values_cmp */
1291 type = g_param_type_register_static ("GParamBoxed", &pspec_info);
1292 g_assert (type == G_TYPE_PARAM_BOXED);
1295 /* G_TYPE_PARAM_POINTER
1298 static const GParamSpecTypeInfo pspec_info = {
1299 sizeof (GParamSpecPointer), /* instance_size */
1300 0, /* n_preallocs */
1301 param_pointer_init, /* instance_init */
1302 G_TYPE_POINTER, /* value_type */
1303 NULL, /* finalize */
1304 param_pointer_set_default, /* value_set_default */
1305 param_pointer_validate, /* value_validate */
1306 param_pointer_values_cmp, /* values_cmp */
1308 type = g_param_type_register_static ("GParamPointer", &pspec_info);
1309 g_assert (type == G_TYPE_PARAM_POINTER);
1312 /* G_TYPE_PARAM_VALUE_ARRAY
1315 static const GParamSpecTypeInfo pspec_info = {
1316 sizeof (GParamSpecValueArray), /* instance_size */
1317 0, /* n_preallocs */
1318 param_value_array_init, /* instance_init */
1319 G_TYPE_VALUE_ARRAY, /* value_type */
1320 param_value_array_finalize, /* finalize */
1321 param_value_array_set_default, /* value_set_default */
1322 param_value_array_validate, /* value_validate */
1323 param_value_array_values_cmp, /* values_cmp */
1325 type = g_param_type_register_static ("GParamValueArray", &pspec_info);
1326 g_assert (type == G_TYPE_PARAM_VALUE_ARRAY);
1329 /* G_TYPE_PARAM_CLOSURE
1332 static const GParamSpecTypeInfo pspec_info = {
1333 sizeof (GParamSpecClosure), /* instance_size */
1334 0, /* n_preallocs */
1335 param_closure_init, /* instance_init */
1336 G_TYPE_CLOSURE, /* value_type */
1337 NULL, /* finalize */
1338 param_closure_set_default, /* value_set_default */
1339 param_closure_validate, /* value_validate */
1340 param_closure_values_cmp, /* values_cmp */
1342 type = g_param_type_register_static ("GParamClosure", &pspec_info);
1343 g_assert (type == G_TYPE_PARAM_CLOSURE);
1346 /* G_TYPE_PARAM_OBJECT
1349 static const GParamSpecTypeInfo pspec_info = {
1350 sizeof (GParamSpecObject), /* instance_size */
1351 16, /* n_preallocs */
1352 param_object_init, /* instance_init */
1353 G_TYPE_OBJECT, /* value_type */
1354 NULL, /* finalize */
1355 param_object_set_default, /* value_set_default */
1356 param_object_validate, /* value_validate */
1357 param_object_values_cmp, /* values_cmp */
1359 type = g_param_type_register_static ("GParamObject", &pspec_info);
1360 g_assert (type == G_TYPE_PARAM_OBJECT);
1365 /* --- GParamSpec initialization --- */
1367 g_param_spec_char (const gchar *name,
1372 gint8 default_value,
1375 GParamSpecChar *cspec;
1377 g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1379 cspec = g_param_spec_internal (G_TYPE_PARAM_CHAR,
1385 cspec->minimum = minimum;
1386 cspec->maximum = maximum;
1387 cspec->default_value = default_value;
1389 return G_PARAM_SPEC (cspec);
1393 g_param_spec_uchar (const gchar *name,
1398 guint8 default_value,
1401 GParamSpecUChar *uspec;
1403 g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1405 uspec = g_param_spec_internal (G_TYPE_PARAM_UCHAR,
1411 uspec->minimum = minimum;
1412 uspec->maximum = maximum;
1413 uspec->default_value = default_value;
1415 return G_PARAM_SPEC (uspec);
1419 g_param_spec_boolean (const gchar *name,
1422 gboolean default_value,
1425 GParamSpecBoolean *bspec;
1427 g_return_val_if_fail (default_value == TRUE || default_value == FALSE, NULL);
1429 bspec = g_param_spec_internal (G_TYPE_PARAM_BOOLEAN,
1435 bspec->default_value = default_value;
1437 return G_PARAM_SPEC (bspec);
1441 g_param_spec_int (const gchar *name,
1449 GParamSpecInt *ispec;
1451 g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1453 ispec = g_param_spec_internal (G_TYPE_PARAM_INT,
1459 ispec->minimum = minimum;
1460 ispec->maximum = maximum;
1461 ispec->default_value = default_value;
1463 return G_PARAM_SPEC (ispec);
1467 g_param_spec_uint (const gchar *name,
1472 guint default_value,
1475 GParamSpecUInt *uspec;
1477 g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1479 uspec = g_param_spec_internal (G_TYPE_PARAM_UINT,
1485 uspec->minimum = minimum;
1486 uspec->maximum = maximum;
1487 uspec->default_value = default_value;
1489 return G_PARAM_SPEC (uspec);
1493 g_param_spec_long (const gchar *name,
1498 glong default_value,
1501 GParamSpecLong *lspec;
1503 g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1505 lspec = g_param_spec_internal (G_TYPE_PARAM_LONG,
1511 lspec->minimum = minimum;
1512 lspec->maximum = maximum;
1513 lspec->default_value = default_value;
1515 return G_PARAM_SPEC (lspec);
1519 g_param_spec_ulong (const gchar *name,
1524 gulong default_value,
1527 GParamSpecULong *uspec;
1529 g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1531 uspec = g_param_spec_internal (G_TYPE_PARAM_ULONG,
1537 uspec->minimum = minimum;
1538 uspec->maximum = maximum;
1539 uspec->default_value = default_value;
1541 return G_PARAM_SPEC (uspec);
1545 g_param_spec_int64 (const gchar *name,
1550 gint64 default_value,
1553 GParamSpecInt64 *lspec;
1555 g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1557 lspec = g_param_spec_internal (G_TYPE_PARAM_INT64,
1563 lspec->minimum = minimum;
1564 lspec->maximum = maximum;
1565 lspec->default_value = default_value;
1567 return G_PARAM_SPEC (lspec);
1571 g_param_spec_uint64 (const gchar *name,
1576 guint64 default_value,
1579 GParamSpecUInt64 *uspec;
1581 g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1583 uspec = g_param_spec_internal (G_TYPE_PARAM_UINT64,
1589 uspec->minimum = minimum;
1590 uspec->maximum = maximum;
1591 uspec->default_value = default_value;
1593 return G_PARAM_SPEC (uspec);
1597 g_param_spec_unichar (const gchar *name,
1600 gunichar default_value,
1603 GParamSpecUnichar *uspec;
1605 uspec = g_param_spec_internal (G_TYPE_PARAM_UNICHAR,
1611 uspec->default_value = default_value;
1613 return G_PARAM_SPEC (uspec);
1617 g_param_spec_enum (const gchar *name,
1624 GParamSpecEnum *espec;
1625 GEnumClass *enum_class;
1627 g_return_val_if_fail (G_TYPE_IS_ENUM (enum_type), NULL);
1629 enum_class = g_type_class_ref (enum_type);
1631 g_return_val_if_fail (g_enum_get_value (enum_class, default_value) != NULL, NULL);
1633 espec = g_param_spec_internal (G_TYPE_PARAM_ENUM,
1639 espec->enum_class = enum_class;
1640 espec->default_value = default_value;
1641 G_PARAM_SPEC (espec)->value_type = enum_type;
1643 return G_PARAM_SPEC (espec);
1647 g_param_spec_flags (const gchar *name,
1651 guint default_value,
1654 GParamSpecFlags *fspec;
1655 GFlagsClass *flags_class;
1657 g_return_val_if_fail (G_TYPE_IS_FLAGS (flags_type), NULL);
1659 flags_class = g_type_class_ref (flags_type);
1661 g_return_val_if_fail ((default_value & flags_class->mask) == default_value, NULL);
1663 fspec = g_param_spec_internal (G_TYPE_PARAM_FLAGS,
1669 fspec->flags_class = flags_class;
1670 fspec->default_value = default_value;
1671 G_PARAM_SPEC (fspec)->value_type = flags_type;
1673 return G_PARAM_SPEC (fspec);
1677 g_param_spec_float (const gchar *name,
1682 gfloat default_value,
1685 GParamSpecFloat *fspec;
1687 g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1689 fspec = g_param_spec_internal (G_TYPE_PARAM_FLOAT,
1695 fspec->minimum = minimum;
1696 fspec->maximum = maximum;
1697 fspec->default_value = default_value;
1699 return G_PARAM_SPEC (fspec);
1703 g_param_spec_double (const gchar *name,
1708 gdouble default_value,
1711 GParamSpecDouble *dspec;
1713 g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1715 dspec = g_param_spec_internal (G_TYPE_PARAM_DOUBLE,
1721 dspec->minimum = minimum;
1722 dspec->maximum = maximum;
1723 dspec->default_value = default_value;
1725 return G_PARAM_SPEC (dspec);
1729 g_param_spec_string (const gchar *name,
1732 const gchar *default_value,
1735 GParamSpecString *sspec = g_param_spec_internal (G_TYPE_PARAM_STRING,
1740 g_free (sspec->default_value);
1741 sspec->default_value = g_strdup (default_value);
1743 return G_PARAM_SPEC (sspec);
1747 g_param_spec_param (const gchar *name,
1753 GParamSpecParam *pspec;
1755 g_return_val_if_fail (G_TYPE_IS_PARAM (param_type), NULL);
1757 pspec = g_param_spec_internal (G_TYPE_PARAM_PARAM,
1762 G_PARAM_SPEC (pspec)->value_type = param_type;
1764 return G_PARAM_SPEC (pspec);
1768 g_param_spec_boxed (const gchar *name,
1774 GParamSpecBoxed *bspec;
1776 g_return_val_if_fail (G_TYPE_IS_BOXED (boxed_type), NULL);
1777 g_return_val_if_fail (G_TYPE_IS_VALUE_TYPE (boxed_type), NULL);
1779 bspec = g_param_spec_internal (G_TYPE_PARAM_BOXED,
1784 G_PARAM_SPEC (bspec)->value_type = boxed_type;
1786 return G_PARAM_SPEC (bspec);
1790 g_param_spec_pointer (const gchar *name,
1795 GParamSpecPointer *pspec;
1797 pspec = g_param_spec_internal (G_TYPE_PARAM_POINTER,
1802 return G_PARAM_SPEC (pspec);
1806 g_param_spec_value_array (const gchar *name,
1809 GParamSpec *element_spec,
1812 GParamSpecValueArray *aspec;
1815 g_return_val_if_fail (G_IS_PARAM_SPEC (element_spec), NULL);
1817 aspec = g_param_spec_internal (G_TYPE_PARAM_VALUE_ARRAY,
1824 aspec->element_spec = g_param_spec_ref (element_spec);
1825 g_param_spec_sink (element_spec);
1828 return G_PARAM_SPEC (aspec);
1832 g_param_spec_closure (const gchar *name,
1837 GParamSpecClosure *cspec;
1839 cspec = g_param_spec_internal (G_TYPE_PARAM_CLOSURE,
1844 return G_PARAM_SPEC (cspec);
1848 g_param_spec_object (const gchar *name,
1854 GParamSpecObject *ospec;
1856 g_return_val_if_fail (g_type_is_a (object_type, G_TYPE_OBJECT), NULL);
1858 ospec = g_param_spec_internal (G_TYPE_PARAM_OBJECT,
1863 G_PARAM_SPEC (ospec)->value_type = object_type;
1865 return G_PARAM_SPEC (ospec);