Imported Upstream version 2.57.2
[platform/upstream/glib.git] / gobject / gparamspecs.c
1 /* GObject - GLib Type, Object, Parameter and Signal Library
2  * Copyright (C) 1997-1999, 2000-2001 Tim Janik and Red Hat, Inc.
3  * Copyright (C) 2010 Christian Persch
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
17  */
18
19 /*
20  * MT safe
21  */
22
23 #include "config.h"
24
25 #include <string.h>
26
27 #define GLIB_DISABLE_DEPRECATION_WARNINGS
28
29 #include "gparamspecs.h"
30 #include "gtype-private.h"
31 #include "gvaluecollector.h"
32
33 #include "gvaluearray.h"
34
35
36 /**
37  * SECTION:param_value_types
38  * @short_description: Standard Parameter and Value Types
39  * @see_also: #GParamSpec, #GValue, g_object_class_install_property().
40  * @title: Parameters and Values
41  *
42  * #GValue provides an abstract container structure which can be
43  * copied, transformed and compared while holding a value of any
44  * (derived) type, which is registered as a #GType with a
45  * #GTypeValueTable in its #GTypeInfo structure.  Parameter
46  * specifications for most value types can be created as #GParamSpec
47  * derived instances, to implement e.g. #GObject properties which
48  * operate on #GValue containers.
49  *
50  * Parameter names need to start with a letter (a-z or A-Z). Subsequent
51  * characters can be letters, numbers or a '-'.
52  * All other characters are replaced by a '-' during construction.
53  */
54
55
56 #define G_FLOAT_EPSILON         (1e-30)
57 #define G_DOUBLE_EPSILON        (1e-90)
58
59
60 /* --- param spec functions --- */
61 static void
62 param_char_init (GParamSpec *pspec)
63 {
64   GParamSpecChar *cspec = G_PARAM_SPEC_CHAR (pspec);
65   
66   cspec->minimum = 0x7f;
67   cspec->maximum = 0x80;
68   cspec->default_value = 0;
69 }
70
71 static void
72 param_char_set_default (GParamSpec *pspec,
73                         GValue     *value)
74 {
75   value->data[0].v_int = G_PARAM_SPEC_CHAR (pspec)->default_value;
76 }
77
78 static gboolean
79 param_char_validate (GParamSpec *pspec,
80                      GValue     *value)
81 {
82   GParamSpecChar *cspec = G_PARAM_SPEC_CHAR (pspec);
83   gint oval = value->data[0].v_int;
84   
85   value->data[0].v_int = CLAMP (value->data[0].v_int, cspec->minimum, cspec->maximum);
86   
87   return value->data[0].v_int != oval;
88 }
89
90 static void
91 param_uchar_init (GParamSpec *pspec)
92 {
93   GParamSpecUChar *uspec = G_PARAM_SPEC_UCHAR (pspec);
94   
95   uspec->minimum = 0;
96   uspec->maximum = 0xff;
97   uspec->default_value = 0;
98 }
99
100 static void
101 param_uchar_set_default (GParamSpec *pspec,
102                          GValue     *value)
103 {
104   value->data[0].v_uint = G_PARAM_SPEC_UCHAR (pspec)->default_value;
105 }
106
107 static gboolean
108 param_uchar_validate (GParamSpec *pspec,
109                       GValue     *value)
110 {
111   GParamSpecUChar *uspec = G_PARAM_SPEC_UCHAR (pspec);
112   guint oval = value->data[0].v_uint;
113   
114   value->data[0].v_uint = CLAMP (value->data[0].v_uint, uspec->minimum, uspec->maximum);
115   
116   return value->data[0].v_uint != oval;
117 }
118
119 static void
120 param_boolean_set_default (GParamSpec *pspec,
121                            GValue     *value)
122 {
123   value->data[0].v_int = G_PARAM_SPEC_BOOLEAN (pspec)->default_value;
124 }
125
126 static gboolean
127 param_boolean_validate (GParamSpec *pspec,
128                         GValue     *value)
129 {
130   gint oval = value->data[0].v_int;
131   
132   value->data[0].v_int = value->data[0].v_int != FALSE;
133   
134   return value->data[0].v_int != oval;
135 }
136
137 static void
138 param_int_init (GParamSpec *pspec)
139 {
140   GParamSpecInt *ispec = G_PARAM_SPEC_INT (pspec);
141   
142   ispec->minimum = 0x7fffffff;
143   ispec->maximum = 0x80000000;
144   ispec->default_value = 0;
145 }
146
147 static void
148 param_int_set_default (GParamSpec *pspec,
149                        GValue     *value)
150 {
151   value->data[0].v_int = G_PARAM_SPEC_INT (pspec)->default_value;
152 }
153
154 static gboolean
155 param_int_validate (GParamSpec *pspec,
156                     GValue     *value)
157 {
158   GParamSpecInt *ispec = G_PARAM_SPEC_INT (pspec);
159   gint oval = value->data[0].v_int;
160   
161   value->data[0].v_int = CLAMP (value->data[0].v_int, ispec->minimum, ispec->maximum);
162   
163   return value->data[0].v_int != oval;
164 }
165
166 static gint
167 param_int_values_cmp (GParamSpec   *pspec,
168                       const GValue *value1,
169                       const GValue *value2)
170 {
171   if (value1->data[0].v_int < value2->data[0].v_int)
172     return -1;
173   else
174     return value1->data[0].v_int > value2->data[0].v_int;
175 }
176
177 static void
178 param_uint_init (GParamSpec *pspec)
179 {
180   GParamSpecUInt *uspec = G_PARAM_SPEC_UINT (pspec);
181   
182   uspec->minimum = 0;
183   uspec->maximum = 0xffffffff;
184   uspec->default_value = 0;
185 }
186
187 static void
188 param_uint_set_default (GParamSpec *pspec,
189                         GValue     *value)
190 {
191   value->data[0].v_uint = G_PARAM_SPEC_UINT (pspec)->default_value;
192 }
193
194 static gboolean
195 param_uint_validate (GParamSpec *pspec,
196                      GValue     *value)
197 {
198   GParamSpecUInt *uspec = G_PARAM_SPEC_UINT (pspec);
199   guint oval = value->data[0].v_uint;
200   
201   value->data[0].v_uint = CLAMP (value->data[0].v_uint, uspec->minimum, uspec->maximum);
202   
203   return value->data[0].v_uint != oval;
204 }
205
206 static gint
207 param_uint_values_cmp (GParamSpec   *pspec,
208                        const GValue *value1,
209                        const GValue *value2)
210 {
211   if (value1->data[0].v_uint < value2->data[0].v_uint)
212     return -1;
213   else
214     return value1->data[0].v_uint > value2->data[0].v_uint;
215 }
216
217 static void
218 param_long_init (GParamSpec *pspec)
219 {
220   GParamSpecLong *lspec = G_PARAM_SPEC_LONG (pspec);
221   
222 #if SIZEOF_LONG == 4
223   lspec->minimum = 0x7fffffff;
224   lspec->maximum = 0x80000000;
225 #else /* SIZEOF_LONG != 4 (8) */
226   lspec->minimum = 0x7fffffffffffffff;
227   lspec->maximum = 0x8000000000000000;
228 #endif
229   lspec->default_value = 0;
230 }
231
232 static void
233 param_long_set_default (GParamSpec *pspec,
234                         GValue     *value)
235 {
236   value->data[0].v_long = G_PARAM_SPEC_LONG (pspec)->default_value;
237 }
238
239 static gboolean
240 param_long_validate (GParamSpec *pspec,
241                      GValue     *value)
242 {
243   GParamSpecLong *lspec = G_PARAM_SPEC_LONG (pspec);
244   glong oval = value->data[0].v_long;
245   
246   value->data[0].v_long = CLAMP (value->data[0].v_long, lspec->minimum, lspec->maximum);
247   
248   return value->data[0].v_long != oval;
249 }
250
251 static gint
252 param_long_values_cmp (GParamSpec   *pspec,
253                        const GValue *value1,
254                        const GValue *value2)
255 {
256   if (value1->data[0].v_long < value2->data[0].v_long)
257     return -1;
258   else
259     return value1->data[0].v_long > value2->data[0].v_long;
260 }
261
262 static void
263 param_ulong_init (GParamSpec *pspec)
264 {
265   GParamSpecULong *uspec = G_PARAM_SPEC_ULONG (pspec);
266   
267   uspec->minimum = 0;
268 #if SIZEOF_LONG == 4
269   uspec->maximum = 0xffffffff;
270 #else /* SIZEOF_LONG != 4 (8) */
271   uspec->maximum = 0xffffffffffffffff;
272 #endif
273   uspec->default_value = 0;
274 }
275
276 static void
277 param_ulong_set_default (GParamSpec *pspec,
278                          GValue     *value)
279 {
280   value->data[0].v_ulong = G_PARAM_SPEC_ULONG (pspec)->default_value;
281 }
282
283 static gboolean
284 param_ulong_validate (GParamSpec *pspec,
285                       GValue     *value)
286 {
287   GParamSpecULong *uspec = G_PARAM_SPEC_ULONG (pspec);
288   gulong oval = value->data[0].v_ulong;
289   
290   value->data[0].v_ulong = CLAMP (value->data[0].v_ulong, uspec->minimum, uspec->maximum);
291   
292   return value->data[0].v_ulong != oval;
293 }
294
295 static gint
296 param_ulong_values_cmp (GParamSpec   *pspec,
297                         const GValue *value1,
298                         const GValue *value2)
299 {
300   if (value1->data[0].v_ulong < value2->data[0].v_ulong)
301     return -1;
302   else
303     return value1->data[0].v_ulong > value2->data[0].v_ulong;
304 }
305
306 static void
307 param_int64_init (GParamSpec *pspec)
308 {
309   GParamSpecInt64 *lspec = G_PARAM_SPEC_INT64 (pspec);
310   
311   lspec->minimum = G_MININT64;
312   lspec->maximum = G_MAXINT64;
313   lspec->default_value = 0;
314 }
315
316 static void
317 param_int64_set_default (GParamSpec *pspec,
318                         GValue     *value)
319 {
320   value->data[0].v_int64 = G_PARAM_SPEC_INT64 (pspec)->default_value;
321 }
322
323 static gboolean
324 param_int64_validate (GParamSpec *pspec,
325                      GValue     *value)
326 {
327   GParamSpecInt64 *lspec = G_PARAM_SPEC_INT64 (pspec);
328   gint64 oval = value->data[0].v_int64;
329   
330   value->data[0].v_int64 = CLAMP (value->data[0].v_int64, lspec->minimum, lspec->maximum);
331   
332   return value->data[0].v_int64 != oval;
333 }
334
335 static gint
336 param_int64_values_cmp (GParamSpec   *pspec,
337                        const GValue *value1,
338                        const GValue *value2)
339 {
340   if (value1->data[0].v_int64 < value2->data[0].v_int64)
341     return -1;
342   else
343     return value1->data[0].v_int64 > value2->data[0].v_int64;
344 }
345
346 static void
347 param_uint64_init (GParamSpec *pspec)
348 {
349   GParamSpecUInt64 *uspec = G_PARAM_SPEC_UINT64 (pspec);
350   
351   uspec->minimum = 0;
352   uspec->maximum = G_MAXUINT64;
353   uspec->default_value = 0;
354 }
355
356 static void
357 param_uint64_set_default (GParamSpec *pspec,
358                          GValue     *value)
359 {
360   value->data[0].v_uint64 = G_PARAM_SPEC_UINT64 (pspec)->default_value;
361 }
362
363 static gboolean
364 param_uint64_validate (GParamSpec *pspec,
365                       GValue     *value)
366 {
367   GParamSpecUInt64 *uspec = G_PARAM_SPEC_UINT64 (pspec);
368   guint64 oval = value->data[0].v_uint64;
369   
370   value->data[0].v_uint64 = CLAMP (value->data[0].v_uint64, uspec->minimum, uspec->maximum);
371   
372   return value->data[0].v_uint64 != oval;
373 }
374
375 static gint
376 param_uint64_values_cmp (GParamSpec   *pspec,
377                         const GValue *value1,
378                         const GValue *value2)
379 {
380   if (value1->data[0].v_uint64 < value2->data[0].v_uint64)
381     return -1;
382   else
383     return value1->data[0].v_uint64 > value2->data[0].v_uint64;
384 }
385
386 static void
387 param_unichar_init (GParamSpec *pspec)
388 {
389   GParamSpecUnichar *uspec = G_PARAM_SPEC_UNICHAR (pspec);
390   
391   uspec->default_value = 0;
392 }
393
394 static void
395 param_unichar_set_default (GParamSpec *pspec,
396                          GValue     *value)
397 {
398   value->data[0].v_uint = G_PARAM_SPEC_UNICHAR (pspec)->default_value;
399 }
400
401 static gboolean
402 param_unichar_validate (GParamSpec *pspec,
403                         GValue     *value)
404 {
405   gunichar oval = value->data[0].v_uint;
406   gboolean changed = FALSE;
407
408   if (!g_unichar_validate (oval))
409     {
410       value->data[0].v_uint = 0;
411       changed = TRUE;
412     }
413
414   return changed;
415 }
416
417 static gint
418 param_unichar_values_cmp (GParamSpec   *pspec,
419                         const GValue *value1,
420                         const GValue *value2)
421 {
422   if (value1->data[0].v_uint < value2->data[0].v_uint)
423     return -1;
424   else
425     return value1->data[0].v_uint > value2->data[0].v_uint;
426 }
427
428 static void
429 param_enum_init (GParamSpec *pspec)
430 {
431   GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec);
432   
433   espec->enum_class = NULL;
434   espec->default_value = 0;
435 }
436
437 static void
438 param_enum_finalize (GParamSpec *pspec)
439 {
440   GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec);
441   GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_ENUM));
442   
443   if (espec->enum_class)
444     {
445       g_type_class_unref (espec->enum_class);
446       espec->enum_class = NULL;
447     }
448   
449   parent_class->finalize (pspec);
450 }
451
452 static void
453 param_enum_set_default (GParamSpec *pspec,
454                         GValue     *value)
455 {
456   value->data[0].v_long = G_PARAM_SPEC_ENUM (pspec)->default_value;
457 }
458
459 static gboolean
460 param_enum_validate (GParamSpec *pspec,
461                      GValue     *value)
462 {
463   GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec);
464   glong oval = value->data[0].v_long;
465   
466   if (!espec->enum_class ||
467       !g_enum_get_value (espec->enum_class, value->data[0].v_long))
468     value->data[0].v_long = espec->default_value;
469   
470   return value->data[0].v_long != oval;
471 }
472
473 static void
474 param_flags_init (GParamSpec *pspec)
475 {
476   GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec);
477   
478   fspec->flags_class = NULL;
479   fspec->default_value = 0;
480 }
481
482 static void
483 param_flags_finalize (GParamSpec *pspec)
484 {
485   GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec);
486   GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_FLAGS));
487   
488   if (fspec->flags_class)
489     {
490       g_type_class_unref (fspec->flags_class);
491       fspec->flags_class = NULL;
492     }
493   
494   parent_class->finalize (pspec);
495 }
496
497 static void
498 param_flags_set_default (GParamSpec *pspec,
499                          GValue     *value)
500 {
501   value->data[0].v_ulong = G_PARAM_SPEC_FLAGS (pspec)->default_value;
502 }
503
504 static gboolean
505 param_flags_validate (GParamSpec *pspec,
506                       GValue     *value)
507 {
508   GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec);
509   gulong oval = value->data[0].v_ulong;
510   
511   if (fspec->flags_class)
512     value->data[0].v_ulong &= fspec->flags_class->mask;
513   else
514     value->data[0].v_ulong = fspec->default_value;
515   
516   return value->data[0].v_ulong != oval;
517 }
518
519 static void
520 param_float_init (GParamSpec *pspec)
521 {
522   GParamSpecFloat *fspec = G_PARAM_SPEC_FLOAT (pspec);
523   
524   fspec->minimum = -G_MAXFLOAT;
525   fspec->maximum = G_MAXFLOAT;
526   fspec->default_value = 0;
527   fspec->epsilon = G_FLOAT_EPSILON;
528 }
529
530 static void
531 param_float_set_default (GParamSpec *pspec,
532                          GValue     *value)
533 {
534   value->data[0].v_float = G_PARAM_SPEC_FLOAT (pspec)->default_value;
535 }
536
537 static gboolean
538 param_float_validate (GParamSpec *pspec,
539                       GValue     *value)
540 {
541   GParamSpecFloat *fspec = G_PARAM_SPEC_FLOAT (pspec);
542   gfloat oval = value->data[0].v_float;
543   
544   value->data[0].v_float = CLAMP (value->data[0].v_float, fspec->minimum, fspec->maximum);
545   
546   return value->data[0].v_float != oval;
547 }
548
549 static gint
550 param_float_values_cmp (GParamSpec   *pspec,
551                         const GValue *value1,
552                         const GValue *value2)
553 {
554   gfloat epsilon = G_PARAM_SPEC_FLOAT (pspec)->epsilon;
555   
556   if (value1->data[0].v_float < value2->data[0].v_float)
557     return - (value2->data[0].v_float - value1->data[0].v_float > epsilon);
558   else
559     return value1->data[0].v_float - value2->data[0].v_float > epsilon;
560 }
561
562 static void
563 param_double_init (GParamSpec *pspec)
564 {
565   GParamSpecDouble *dspec = G_PARAM_SPEC_DOUBLE (pspec);
566   
567   dspec->minimum = -G_MAXDOUBLE;
568   dspec->maximum = G_MAXDOUBLE;
569   dspec->default_value = 0;
570   dspec->epsilon = G_DOUBLE_EPSILON;
571 }
572
573 static void
574 param_double_set_default (GParamSpec *pspec,
575                           GValue     *value)
576 {
577   value->data[0].v_double = G_PARAM_SPEC_DOUBLE (pspec)->default_value;
578 }
579
580 static gboolean
581 param_double_validate (GParamSpec *pspec,
582                        GValue     *value)
583 {
584   GParamSpecDouble *dspec = G_PARAM_SPEC_DOUBLE (pspec);
585   gdouble oval = value->data[0].v_double;
586   
587   value->data[0].v_double = CLAMP (value->data[0].v_double, dspec->minimum, dspec->maximum);
588   
589   return value->data[0].v_double != oval;
590 }
591
592 static gint
593 param_double_values_cmp (GParamSpec   *pspec,
594                          const GValue *value1,
595                          const GValue *value2)
596 {
597   gdouble epsilon = G_PARAM_SPEC_DOUBLE (pspec)->epsilon;
598   
599   if (value1->data[0].v_double < value2->data[0].v_double)
600     return - (value2->data[0].v_double - value1->data[0].v_double > epsilon);
601   else
602     return value1->data[0].v_double - value2->data[0].v_double > epsilon;
603 }
604
605 static void
606 param_string_init (GParamSpec *pspec)
607 {
608   GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec);
609   
610   sspec->default_value = NULL;
611   sspec->cset_first = NULL;
612   sspec->cset_nth = NULL;
613   sspec->substitutor = '_';
614   sspec->null_fold_if_empty = FALSE;
615   sspec->ensure_non_null = FALSE;
616 }
617
618 static void
619 param_string_finalize (GParamSpec *pspec)
620 {
621   GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec);
622   GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_STRING));
623   
624   g_free (sspec->default_value);
625   g_free (sspec->cset_first);
626   g_free (sspec->cset_nth);
627   sspec->default_value = NULL;
628   sspec->cset_first = NULL;
629   sspec->cset_nth = NULL;
630   
631   parent_class->finalize (pspec);
632 }
633
634 static void
635 param_string_set_default (GParamSpec *pspec,
636                           GValue     *value)
637 {
638   value->data[0].v_pointer = g_strdup (G_PARAM_SPEC_STRING (pspec)->default_value);
639 }
640
641 static gboolean
642 param_string_validate (GParamSpec *pspec,
643                        GValue     *value)
644 {
645   GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec);
646   gchar *string = value->data[0].v_pointer;
647   guint changed = 0;
648   
649   if (string && string[0])
650     {
651       gchar *s;
652       
653       if (sspec->cset_first && !strchr (sspec->cset_first, string[0]))
654         {
655           if (value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS)
656             {
657               value->data[0].v_pointer = g_strdup (string);
658               string = value->data[0].v_pointer;
659               value->data[1].v_uint &= ~G_VALUE_NOCOPY_CONTENTS;
660             }
661           string[0] = sspec->substitutor;
662           changed++;
663         }
664       if (sspec->cset_nth)
665         for (s = string + 1; *s; s++)
666           if (!strchr (sspec->cset_nth, *s))
667             {
668               if (value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS)
669                 {
670                   value->data[0].v_pointer = g_strdup (string);
671                   s = (gchar*) value->data[0].v_pointer + (s - string);
672                   string = value->data[0].v_pointer;
673                   value->data[1].v_uint &= ~G_VALUE_NOCOPY_CONTENTS;
674                 }
675               *s = sspec->substitutor;
676               changed++;
677             }
678     }
679   if (sspec->null_fold_if_empty && string && string[0] == 0)
680     {
681       if (!(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS))
682         g_free (value->data[0].v_pointer);
683       else
684         value->data[1].v_uint &= ~G_VALUE_NOCOPY_CONTENTS;
685       value->data[0].v_pointer = NULL;
686       changed++;
687       string = value->data[0].v_pointer;
688     }
689   if (sspec->ensure_non_null && !string)
690     {
691       value->data[1].v_uint &= ~G_VALUE_NOCOPY_CONTENTS;
692       value->data[0].v_pointer = g_strdup ("");
693       changed++;
694       string = value->data[0].v_pointer;
695     }
696
697   return changed;
698 }
699
700 static gint
701 param_string_values_cmp (GParamSpec   *pspec,
702                          const GValue *value1,
703                          const GValue *value2)
704 {
705   if (!value1->data[0].v_pointer)
706     return value2->data[0].v_pointer != NULL ? -1 : 0;
707   else if (!value2->data[0].v_pointer)
708     return value1->data[0].v_pointer != NULL;
709   else
710     return strcmp (value1->data[0].v_pointer, value2->data[0].v_pointer);
711 }
712
713 static void
714 param_param_init (GParamSpec *pspec)
715 {
716   /* GParamSpecParam *spec = G_PARAM_SPEC_PARAM (pspec); */
717 }
718
719 static void
720 param_param_set_default (GParamSpec *pspec,
721                          GValue     *value)
722 {
723   value->data[0].v_pointer = NULL;
724 }
725
726 static gboolean
727 param_param_validate (GParamSpec *pspec,
728                       GValue     *value)
729 {
730   /* GParamSpecParam *spec = G_PARAM_SPEC_PARAM (pspec); */
731   GParamSpec *param = value->data[0].v_pointer;
732   guint changed = 0;
733   
734   if (param && !g_value_type_compatible (G_PARAM_SPEC_TYPE (param), G_PARAM_SPEC_VALUE_TYPE (pspec)))
735     {
736       g_param_spec_unref (param);
737       value->data[0].v_pointer = NULL;
738       changed++;
739     }
740   
741   return changed;
742 }
743
744 static void
745 param_boxed_init (GParamSpec *pspec)
746 {
747   /* GParamSpecBoxed *bspec = G_PARAM_SPEC_BOXED (pspec); */
748 }
749
750 static void
751 param_boxed_set_default (GParamSpec *pspec,
752                          GValue     *value)
753 {
754   value->data[0].v_pointer = NULL;
755 }
756
757 static gboolean
758 param_boxed_validate (GParamSpec *pspec,
759                       GValue     *value)
760 {
761   /* GParamSpecBoxed *bspec = G_PARAM_SPEC_BOXED (pspec); */
762   guint changed = 0;
763
764   /* can't do a whole lot here since we haven't even G_BOXED_TYPE() */
765   
766   return changed;
767 }
768
769 static gint
770 param_boxed_values_cmp (GParamSpec    *pspec,
771                          const GValue *value1,
772                          const GValue *value2)
773 {
774   guint8 *p1 = value1->data[0].v_pointer;
775   guint8 *p2 = value2->data[0].v_pointer;
776
777   /* not much to compare here, try to at least provide stable lesser/greater result */
778
779   return p1 < p2 ? -1 : p1 > p2;
780 }
781
782 static void
783 param_pointer_init (GParamSpec *pspec)
784 {
785   /* GParamSpecPointer *spec = G_PARAM_SPEC_POINTER (pspec); */
786 }
787
788 static void
789 param_pointer_set_default (GParamSpec *pspec,
790                            GValue     *value)
791 {
792   value->data[0].v_pointer = NULL;
793 }
794
795 static gboolean
796 param_pointer_validate (GParamSpec *pspec,
797                         GValue     *value)
798 {
799   /* GParamSpecPointer *spec = G_PARAM_SPEC_POINTER (pspec); */
800   guint changed = 0;
801   
802   return changed;
803 }
804
805 static gint
806 param_pointer_values_cmp (GParamSpec   *pspec,
807                           const GValue *value1,
808                           const GValue *value2)
809 {
810   guint8 *p1 = value1->data[0].v_pointer;
811   guint8 *p2 = value2->data[0].v_pointer;
812
813   /* not much to compare here, try to at least provide stable lesser/greater result */
814
815   return p1 < p2 ? -1 : p1 > p2;
816 }
817
818 static void
819 param_value_array_init (GParamSpec *pspec)
820 {
821   GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
822
823   aspec->element_spec = NULL;
824   aspec->fixed_n_elements = 0; /* disable */
825 }
826
827 static inline guint
828 value_array_ensure_size (GValueArray *value_array,
829                          guint        fixed_n_elements)
830 {
831   guint changed = 0;
832
833   if (fixed_n_elements)
834     {
835       while (value_array->n_values < fixed_n_elements)
836         {
837           g_value_array_append (value_array, NULL);
838           changed++;
839         }
840       while (value_array->n_values > fixed_n_elements)
841         {
842           g_value_array_remove (value_array, value_array->n_values - 1);
843           changed++;
844         }
845     }
846   return changed;
847 }
848
849 static void
850 param_value_array_finalize (GParamSpec *pspec)
851 {
852   GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
853   GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_VALUE_ARRAY));
854
855   if (aspec->element_spec)
856     {
857       g_param_spec_unref (aspec->element_spec);
858       aspec->element_spec = NULL;
859     }
860
861   parent_class->finalize (pspec);
862 }
863
864 static void
865 param_value_array_set_default (GParamSpec *pspec,
866                                GValue     *value)
867 {
868   GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
869
870   if (!value->data[0].v_pointer && aspec->fixed_n_elements)
871     value->data[0].v_pointer = g_value_array_new (aspec->fixed_n_elements);
872
873   if (value->data[0].v_pointer)
874     {
875       /* g_value_reset (value);  already done */
876       value_array_ensure_size (value->data[0].v_pointer, aspec->fixed_n_elements);
877     }
878 }
879
880 static gboolean
881 param_value_array_validate (GParamSpec *pspec,
882                             GValue     *value)
883 {
884   GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
885   GValueArray *value_array = value->data[0].v_pointer;
886   guint changed = 0;
887
888   if (!value->data[0].v_pointer && aspec->fixed_n_elements)
889     value->data[0].v_pointer = g_value_array_new (aspec->fixed_n_elements);
890
891   if (value->data[0].v_pointer)
892     {
893       /* ensure array size validity */
894       changed += value_array_ensure_size (value_array, aspec->fixed_n_elements);
895       
896       /* ensure array values validity against a present element spec */
897       if (aspec->element_spec)
898         {
899           GParamSpec *element_spec = aspec->element_spec;
900           guint i;
901           
902           for (i = 0; i < value_array->n_values; i++)
903             {
904               GValue *element = value_array->values + i;
905               
906               /* need to fixup value type, or ensure that the array value is initialized at all */
907               if (!g_value_type_compatible (G_VALUE_TYPE (element), G_PARAM_SPEC_VALUE_TYPE (element_spec)))
908                 {
909                   if (G_VALUE_TYPE (element) != 0)
910                     g_value_unset (element);
911                   g_value_init (element, G_PARAM_SPEC_VALUE_TYPE (element_spec));
912                   g_param_value_set_default (element_spec, element);
913                   changed++;
914                 }
915               /* validate array value against element_spec */
916               changed += g_param_value_validate (element_spec, element);
917             }
918         }
919     }
920
921   return changed;
922 }
923
924 static gint
925 param_value_array_values_cmp (GParamSpec   *pspec,
926                               const GValue *value1,
927                               const GValue *value2)
928 {
929   GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
930   GValueArray *value_array1 = value1->data[0].v_pointer;
931   GValueArray *value_array2 = value2->data[0].v_pointer;
932
933   if (!value_array1 || !value_array2)
934     return value_array2 ? -1 : value_array1 != value_array2;
935
936   if (value_array1->n_values != value_array2->n_values)
937     return value_array1->n_values < value_array2->n_values ? -1 : 1;
938   else if (!aspec->element_spec)
939     {
940       /* we need an element specification for comparisons, so there's not much
941        * to compare here, try to at least provide stable lesser/greater result
942        */
943       return value_array1->n_values < value_array2->n_values ? -1 : value_array1->n_values > value_array2->n_values;
944     }
945   else /* value_array1->n_values == value_array2->n_values */
946     {
947       guint i;
948
949       for (i = 0; i < value_array1->n_values; i++)
950         {
951           GValue *element1 = value_array1->values + i;
952           GValue *element2 = value_array2->values + i;
953           gint cmp;
954
955           /* need corresponding element types, provide stable result otherwise */
956           if (G_VALUE_TYPE (element1) != G_VALUE_TYPE (element2))
957             return G_VALUE_TYPE (element1) < G_VALUE_TYPE (element2) ? -1 : 1;
958           cmp = g_param_values_cmp (aspec->element_spec, element1, element2);
959           if (cmp)
960             return cmp;
961         }
962       return 0;
963     }
964 }
965
966 static void
967 param_object_init (GParamSpec *pspec)
968 {
969   /* GParamSpecObject *ospec = G_PARAM_SPEC_OBJECT (pspec); */
970 }
971
972 static void
973 param_object_set_default (GParamSpec *pspec,
974                           GValue     *value)
975 {
976   value->data[0].v_pointer = NULL;
977 }
978
979 static gboolean
980 param_object_validate (GParamSpec *pspec,
981                        GValue     *value)
982 {
983   GParamSpecObject *ospec = G_PARAM_SPEC_OBJECT (pspec);
984   GObject *object = value->data[0].v_pointer;
985   guint changed = 0;
986   
987   if (object && !g_value_type_compatible (G_OBJECT_TYPE (object), G_PARAM_SPEC_VALUE_TYPE (ospec)))
988     {
989       g_object_unref (object);
990       value->data[0].v_pointer = NULL;
991       changed++;
992     }
993   
994   return changed;
995 }
996
997 static gint
998 param_object_values_cmp (GParamSpec   *pspec,
999                          const GValue *value1,
1000                          const GValue *value2)
1001 {
1002   guint8 *p1 = value1->data[0].v_pointer;
1003   guint8 *p2 = value2->data[0].v_pointer;
1004
1005   /* not much to compare here, try to at least provide stable lesser/greater result */
1006
1007   return p1 < p2 ? -1 : p1 > p2;
1008 }
1009
1010 static void
1011 param_override_init (GParamSpec *pspec)
1012 {
1013   /* GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec); */
1014 }
1015
1016 static void
1017 param_override_finalize (GParamSpec *pspec)
1018 {
1019   GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec);
1020   GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_OVERRIDE));
1021   
1022   if (ospec->overridden)
1023     {
1024       g_param_spec_unref (ospec->overridden);
1025       ospec->overridden = NULL;
1026     }
1027   
1028   parent_class->finalize (pspec);
1029 }
1030
1031 static void
1032 param_override_set_default (GParamSpec *pspec,
1033                             GValue     *value)
1034 {
1035   GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec);
1036
1037   g_param_value_set_default (ospec->overridden, value);
1038 }
1039
1040 static gboolean
1041 param_override_validate (GParamSpec *pspec,
1042                          GValue     *value)
1043 {
1044   GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec);
1045   
1046   return g_param_value_validate (ospec->overridden, value);
1047 }
1048
1049 static gint
1050 param_override_values_cmp (GParamSpec   *pspec,
1051                            const GValue *value1,
1052                            const GValue *value2)
1053 {
1054   GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec);
1055
1056   return g_param_values_cmp (ospec->overridden, value1, value2);
1057 }
1058
1059 static void
1060 param_gtype_init (GParamSpec *pspec)
1061 {
1062 }
1063
1064 static void
1065 param_gtype_set_default (GParamSpec *pspec,
1066                          GValue     *value)
1067 {
1068   GParamSpecGType *tspec = G_PARAM_SPEC_GTYPE (pspec);
1069
1070   value->data[0].v_pointer = GSIZE_TO_POINTER (tspec->is_a_type);
1071 }
1072
1073 static gboolean
1074 param_gtype_validate (GParamSpec *pspec,
1075                       GValue     *value)
1076 {
1077   GParamSpecGType *tspec = G_PARAM_SPEC_GTYPE (pspec);
1078   GType gtype = GPOINTER_TO_SIZE (value->data[0].v_pointer);
1079   guint changed = 0;
1080   
1081   if (tspec->is_a_type != G_TYPE_NONE && !g_type_is_a (gtype, tspec->is_a_type))
1082     {
1083       value->data[0].v_pointer = GSIZE_TO_POINTER (tspec->is_a_type);
1084       changed++;
1085     }
1086   
1087   return changed;
1088 }
1089
1090 static gint
1091 param_gtype_values_cmp (GParamSpec   *pspec,
1092                         const GValue *value1,
1093                         const GValue *value2)
1094 {
1095   GType p1 = GPOINTER_TO_SIZE (value1->data[0].v_pointer);
1096   GType p2 = GPOINTER_TO_SIZE (value2->data[0].v_pointer);
1097
1098   /* not much to compare here, try to at least provide stable lesser/greater result */
1099
1100   return p1 < p2 ? -1 : p1 > p2;
1101 }
1102
1103 static void
1104 param_variant_init (GParamSpec *pspec)
1105 {
1106   GParamSpecVariant *vspec = G_PARAM_SPEC_VARIANT (pspec);
1107
1108   vspec->type = NULL;
1109   vspec->default_value = NULL;
1110 }
1111
1112 static void
1113 param_variant_finalize (GParamSpec *pspec)
1114 {
1115   GParamSpecVariant *vspec = G_PARAM_SPEC_VARIANT (pspec);
1116   GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_VARIANT));
1117
1118   if (vspec->default_value)
1119     g_variant_unref (vspec->default_value);
1120   g_variant_type_free (vspec->type);
1121
1122   parent_class->finalize (pspec);
1123 }
1124
1125 static void
1126 param_variant_set_default (GParamSpec *pspec,
1127                            GValue     *value)
1128 {
1129   value->data[0].v_pointer = G_PARAM_SPEC_VARIANT (pspec)->default_value;
1130   value->data[1].v_uint |= G_VALUE_NOCOPY_CONTENTS;
1131 }
1132
1133 static gboolean
1134 param_variant_validate (GParamSpec *pspec,
1135                         GValue     *value)
1136 {
1137   GParamSpecVariant *vspec = G_PARAM_SPEC_VARIANT (pspec);
1138   GVariant *variant = value->data[0].v_pointer;
1139
1140   if ((variant == NULL && vspec->default_value != NULL) ||
1141       (variant != NULL && !g_variant_is_of_type (variant, vspec->type)))
1142     {
1143       g_param_value_set_default (pspec, value);
1144       return TRUE;
1145     }
1146
1147   return FALSE;
1148 }
1149
1150 /* g_variant_compare() can only be used with scalar types. */
1151 static gboolean
1152 variant_is_incomparable (GVariant *v)
1153 {
1154   GVariantClass v_class = g_variant_classify (v);
1155
1156   return (v_class == G_VARIANT_CLASS_HANDLE ||
1157           v_class == G_VARIANT_CLASS_VARIANT ||
1158           v_class ==  G_VARIANT_CLASS_MAYBE||
1159           v_class == G_VARIANT_CLASS_ARRAY ||
1160           v_class ==  G_VARIANT_CLASS_TUPLE ||
1161           v_class == G_VARIANT_CLASS_DICT_ENTRY);
1162 }
1163
1164 static gint
1165 param_variant_values_cmp (GParamSpec   *pspec,
1166                           const GValue *value1,
1167                           const GValue *value2)
1168 {
1169   GVariant *v1 = value1->data[0].v_pointer;
1170   GVariant *v2 = value2->data[0].v_pointer;
1171
1172   if (v1 == NULL && v2 == NULL)
1173     return 0;
1174   else if (v1 == NULL && v2 != NULL)
1175     return -1;
1176   else if (v1 != NULL && v2 == NULL)
1177     return 1;
1178
1179   if (!g_variant_type_equal (g_variant_get_type (v1), g_variant_get_type (v2)) ||
1180       variant_is_incomparable (v1) ||
1181       variant_is_incomparable (v2))
1182     return g_variant_equal (v1, v2) ? 0 : (v1 < v2 ? -1 : 1);
1183
1184   return g_variant_compare (v1, v2);
1185 }
1186
1187 /* --- type initialization --- */
1188 GType *g_param_spec_types = NULL;
1189
1190 void
1191 _g_param_spec_types_init (void) 
1192 {
1193   const guint n_types = 23;
1194   GType type, *spec_types, *spec_types_bound;
1195
1196   g_param_spec_types = g_new0 (GType, n_types);
1197   spec_types = g_param_spec_types;
1198   spec_types_bound = g_param_spec_types + n_types;
1199   
1200   /* G_TYPE_PARAM_CHAR
1201    */
1202   {
1203     const GParamSpecTypeInfo pspec_info = {
1204       sizeof (GParamSpecChar),  /* instance_size */
1205       16,                       /* n_preallocs */
1206       param_char_init,          /* instance_init */
1207       G_TYPE_CHAR,              /* value_type */
1208       NULL,                     /* finalize */
1209       param_char_set_default,   /* value_set_default */
1210       param_char_validate,      /* value_validate */
1211       param_int_values_cmp,     /* values_cmp */
1212     };
1213     type = g_param_type_register_static (g_intern_static_string ("GParamChar"), &pspec_info);
1214     *spec_types++ = type;
1215     g_assert (type == G_TYPE_PARAM_CHAR);
1216   }
1217   
1218   /* G_TYPE_PARAM_UCHAR
1219    */
1220   {
1221     const GParamSpecTypeInfo pspec_info = {
1222       sizeof (GParamSpecUChar), /* instance_size */
1223       16,                       /* n_preallocs */
1224       param_uchar_init,         /* instance_init */
1225       G_TYPE_UCHAR,             /* value_type */
1226       NULL,                     /* finalize */
1227       param_uchar_set_default,  /* value_set_default */
1228       param_uchar_validate,     /* value_validate */
1229       param_uint_values_cmp,    /* values_cmp */
1230     };
1231     type = g_param_type_register_static (g_intern_static_string ("GParamUChar"), &pspec_info);
1232     *spec_types++ = type;
1233     g_assert (type == G_TYPE_PARAM_UCHAR);
1234   }
1235   
1236   /* G_TYPE_PARAM_BOOLEAN
1237    */
1238   {
1239     const GParamSpecTypeInfo pspec_info = {
1240       sizeof (GParamSpecBoolean), /* instance_size */
1241       16,                         /* n_preallocs */
1242       NULL,                       /* instance_init */
1243       G_TYPE_BOOLEAN,             /* value_type */
1244       NULL,                       /* finalize */
1245       param_boolean_set_default,  /* value_set_default */
1246       param_boolean_validate,     /* value_validate */
1247       param_int_values_cmp,       /* values_cmp */
1248     };
1249     type = g_param_type_register_static (g_intern_static_string ("GParamBoolean"), &pspec_info);
1250     *spec_types++ = type;
1251     g_assert (type == G_TYPE_PARAM_BOOLEAN);
1252   }
1253   
1254   /* G_TYPE_PARAM_INT
1255    */
1256   {
1257     const GParamSpecTypeInfo pspec_info = {
1258       sizeof (GParamSpecInt),   /* instance_size */
1259       16,                       /* n_preallocs */
1260       param_int_init,           /* instance_init */
1261       G_TYPE_INT,               /* value_type */
1262       NULL,                     /* finalize */
1263       param_int_set_default,    /* value_set_default */
1264       param_int_validate,       /* value_validate */
1265       param_int_values_cmp,     /* values_cmp */
1266     };
1267     type = g_param_type_register_static (g_intern_static_string ("GParamInt"), &pspec_info);
1268     *spec_types++ = type;
1269     g_assert (type == G_TYPE_PARAM_INT);
1270   }
1271   
1272   /* G_TYPE_PARAM_UINT
1273    */
1274   {
1275     const GParamSpecTypeInfo pspec_info = {
1276       sizeof (GParamSpecUInt),  /* instance_size */
1277       16,                       /* n_preallocs */
1278       param_uint_init,          /* instance_init */
1279       G_TYPE_UINT,              /* value_type */
1280       NULL,                     /* finalize */
1281       param_uint_set_default,   /* value_set_default */
1282       param_uint_validate,      /* value_validate */
1283       param_uint_values_cmp,    /* values_cmp */
1284     };
1285     type = g_param_type_register_static (g_intern_static_string ("GParamUInt"), &pspec_info);
1286     *spec_types++ = type;
1287     g_assert (type == G_TYPE_PARAM_UINT);
1288   }
1289   
1290   /* G_TYPE_PARAM_LONG
1291    */
1292   {
1293     const GParamSpecTypeInfo pspec_info = {
1294       sizeof (GParamSpecLong),  /* instance_size */
1295       16,                       /* n_preallocs */
1296       param_long_init,          /* instance_init */
1297       G_TYPE_LONG,              /* value_type */
1298       NULL,                     /* finalize */
1299       param_long_set_default,   /* value_set_default */
1300       param_long_validate,      /* value_validate */
1301       param_long_values_cmp,    /* values_cmp */
1302     };
1303     type = g_param_type_register_static (g_intern_static_string ("GParamLong"), &pspec_info);
1304     *spec_types++ = type;
1305     g_assert (type == G_TYPE_PARAM_LONG);
1306   }
1307   
1308   /* G_TYPE_PARAM_ULONG
1309    */
1310   {
1311     const GParamSpecTypeInfo pspec_info = {
1312       sizeof (GParamSpecULong), /* instance_size */
1313       16,                       /* n_preallocs */
1314       param_ulong_init,         /* instance_init */
1315       G_TYPE_ULONG,             /* value_type */
1316       NULL,                     /* finalize */
1317       param_ulong_set_default,  /* value_set_default */
1318       param_ulong_validate,     /* value_validate */
1319       param_ulong_values_cmp,   /* values_cmp */
1320     };
1321     type = g_param_type_register_static (g_intern_static_string ("GParamULong"), &pspec_info);
1322     *spec_types++ = type;
1323     g_assert (type == G_TYPE_PARAM_ULONG);
1324   }
1325
1326   /* G_TYPE_PARAM_INT64
1327    */
1328   {
1329     const GParamSpecTypeInfo pspec_info = {
1330       sizeof (GParamSpecInt64),  /* instance_size */
1331       16,                       /* n_preallocs */
1332       param_int64_init,         /* instance_init */
1333       G_TYPE_INT64,             /* value_type */
1334       NULL,                     /* finalize */
1335       param_int64_set_default,  /* value_set_default */
1336       param_int64_validate,     /* value_validate */
1337       param_int64_values_cmp,   /* values_cmp */
1338     };
1339     type = g_param_type_register_static (g_intern_static_string ("GParamInt64"), &pspec_info);
1340     *spec_types++ = type;
1341     g_assert (type == G_TYPE_PARAM_INT64);
1342   }
1343   
1344   /* G_TYPE_PARAM_UINT64
1345    */
1346   {
1347     const GParamSpecTypeInfo pspec_info = {
1348       sizeof (GParamSpecUInt64), /* instance_size */
1349       16,                       /* n_preallocs */
1350       param_uint64_init,        /* instance_init */
1351       G_TYPE_UINT64,            /* value_type */
1352       NULL,                     /* finalize */
1353       param_uint64_set_default, /* value_set_default */
1354       param_uint64_validate,    /* value_validate */
1355       param_uint64_values_cmp,  /* values_cmp */
1356     };
1357     type = g_param_type_register_static (g_intern_static_string ("GParamUInt64"), &pspec_info);
1358     *spec_types++ = type;
1359     g_assert (type == G_TYPE_PARAM_UINT64);
1360   }
1361
1362   /* G_TYPE_PARAM_UNICHAR
1363    */
1364   {
1365     const GParamSpecTypeInfo pspec_info = {
1366       sizeof (GParamSpecUnichar), /* instance_size */
1367       16,                        /* n_preallocs */
1368       param_unichar_init,        /* instance_init */
1369       G_TYPE_UINT,               /* value_type */
1370       NULL,                      /* finalize */
1371       param_unichar_set_default, /* value_set_default */
1372       param_unichar_validate,    /* value_validate */
1373       param_unichar_values_cmp,  /* values_cmp */
1374     };
1375     type = g_param_type_register_static (g_intern_static_string ("GParamUnichar"), &pspec_info);
1376     *spec_types++ = type;
1377     g_assert (type == G_TYPE_PARAM_UNICHAR);
1378   }
1379
1380  /* G_TYPE_PARAM_ENUM
1381    */
1382   {
1383     const GParamSpecTypeInfo pspec_info = {
1384       sizeof (GParamSpecEnum),  /* instance_size */
1385       16,                       /* n_preallocs */
1386       param_enum_init,          /* instance_init */
1387       G_TYPE_ENUM,              /* value_type */
1388       param_enum_finalize,      /* finalize */
1389       param_enum_set_default,   /* value_set_default */
1390       param_enum_validate,      /* value_validate */
1391       param_long_values_cmp,    /* values_cmp */
1392     };
1393     type = g_param_type_register_static (g_intern_static_string ("GParamEnum"), &pspec_info);
1394     *spec_types++ = type;
1395     g_assert (type == G_TYPE_PARAM_ENUM);
1396   }
1397   
1398   /* G_TYPE_PARAM_FLAGS
1399    */
1400   {
1401     const GParamSpecTypeInfo pspec_info = {
1402       sizeof (GParamSpecFlags), /* instance_size */
1403       16,                       /* n_preallocs */
1404       param_flags_init,         /* instance_init */
1405       G_TYPE_FLAGS,             /* value_type */
1406       param_flags_finalize,     /* finalize */
1407       param_flags_set_default,  /* value_set_default */
1408       param_flags_validate,     /* value_validate */
1409       param_ulong_values_cmp,   /* values_cmp */
1410     };
1411     type = g_param_type_register_static (g_intern_static_string ("GParamFlags"), &pspec_info);
1412     *spec_types++ = type;
1413     g_assert (type == G_TYPE_PARAM_FLAGS);
1414   }
1415   
1416   /* G_TYPE_PARAM_FLOAT
1417    */
1418   {
1419     const GParamSpecTypeInfo pspec_info = {
1420       sizeof (GParamSpecFloat), /* instance_size */
1421       16,                       /* n_preallocs */
1422       param_float_init,         /* instance_init */
1423       G_TYPE_FLOAT,             /* value_type */
1424       NULL,                     /* finalize */
1425       param_float_set_default,  /* value_set_default */
1426       param_float_validate,     /* value_validate */
1427       param_float_values_cmp,   /* values_cmp */
1428     };
1429     type = g_param_type_register_static (g_intern_static_string ("GParamFloat"), &pspec_info);
1430     *spec_types++ = type;
1431     g_assert (type == G_TYPE_PARAM_FLOAT);
1432   }
1433   
1434   /* G_TYPE_PARAM_DOUBLE
1435    */
1436   {
1437     const GParamSpecTypeInfo pspec_info = {
1438       sizeof (GParamSpecDouble),        /* instance_size */
1439       16,                               /* n_preallocs */
1440       param_double_init,                /* instance_init */
1441       G_TYPE_DOUBLE,                    /* value_type */
1442       NULL,                             /* finalize */
1443       param_double_set_default,         /* value_set_default */
1444       param_double_validate,            /* value_validate */
1445       param_double_values_cmp,          /* values_cmp */
1446     };
1447     type = g_param_type_register_static (g_intern_static_string ("GParamDouble"), &pspec_info);
1448     *spec_types++ = type;
1449     g_assert (type == G_TYPE_PARAM_DOUBLE);
1450   }
1451   
1452   /* G_TYPE_PARAM_STRING
1453    */
1454   {
1455     const GParamSpecTypeInfo pspec_info = {
1456       sizeof (GParamSpecString),        /* instance_size */
1457       16,                               /* n_preallocs */
1458       param_string_init,                /* instance_init */
1459       G_TYPE_STRING,                    /* value_type */
1460       param_string_finalize,            /* finalize */
1461       param_string_set_default,         /* value_set_default */
1462       param_string_validate,            /* value_validate */
1463       param_string_values_cmp,          /* values_cmp */
1464     };
1465     type = g_param_type_register_static (g_intern_static_string ("GParamString"), &pspec_info);
1466     *spec_types++ = type;
1467     g_assert (type == G_TYPE_PARAM_STRING);
1468   }
1469   
1470   /* G_TYPE_PARAM_PARAM
1471    */
1472   {
1473     const GParamSpecTypeInfo pspec_info = {
1474       sizeof (GParamSpecParam), /* instance_size */
1475       16,                       /* n_preallocs */
1476       param_param_init,         /* instance_init */
1477       G_TYPE_PARAM,             /* value_type */
1478       NULL,                     /* finalize */
1479       param_param_set_default,  /* value_set_default */
1480       param_param_validate,     /* value_validate */
1481       param_pointer_values_cmp, /* values_cmp */
1482     };
1483     type = g_param_type_register_static (g_intern_static_string ("GParamParam"), &pspec_info);
1484     *spec_types++ = type;
1485     g_assert (type == G_TYPE_PARAM_PARAM);
1486   }
1487   
1488   /* G_TYPE_PARAM_BOXED
1489    */
1490   {
1491     const GParamSpecTypeInfo pspec_info = {
1492       sizeof (GParamSpecBoxed), /* instance_size */
1493       4,                        /* n_preallocs */
1494       param_boxed_init,         /* instance_init */
1495       G_TYPE_BOXED,             /* value_type */
1496       NULL,                     /* finalize */
1497       param_boxed_set_default,  /* value_set_default */
1498       param_boxed_validate,     /* value_validate */
1499       param_boxed_values_cmp,   /* values_cmp */
1500     };
1501     type = g_param_type_register_static (g_intern_static_string ("GParamBoxed"), &pspec_info);
1502     *spec_types++ = type;
1503     g_assert (type == G_TYPE_PARAM_BOXED);
1504   }
1505
1506   /* G_TYPE_PARAM_POINTER
1507    */
1508   {
1509     const GParamSpecTypeInfo pspec_info = {
1510       sizeof (GParamSpecPointer),  /* instance_size */
1511       0,                           /* n_preallocs */
1512       param_pointer_init,          /* instance_init */
1513       G_TYPE_POINTER,              /* value_type */
1514       NULL,                        /* finalize */
1515       param_pointer_set_default,   /* value_set_default */
1516       param_pointer_validate,      /* value_validate */
1517       param_pointer_values_cmp,    /* values_cmp */
1518     };
1519     type = g_param_type_register_static (g_intern_static_string ("GParamPointer"), &pspec_info);
1520     *spec_types++ = type;
1521     g_assert (type == G_TYPE_PARAM_POINTER);
1522   }
1523   
1524   /* G_TYPE_PARAM_VALUE_ARRAY
1525    */
1526   {
1527     /* const */ GParamSpecTypeInfo pspec_info = {
1528       sizeof (GParamSpecValueArray),    /* instance_size */
1529       0,                                /* n_preallocs */
1530       param_value_array_init,           /* instance_init */
1531       0xdeadbeef,                       /* value_type, assigned further down */
1532       param_value_array_finalize,       /* finalize */
1533       param_value_array_set_default,    /* value_set_default */
1534       param_value_array_validate,       /* value_validate */
1535       param_value_array_values_cmp,     /* values_cmp */
1536     };
1537     pspec_info.value_type = G_TYPE_VALUE_ARRAY;
1538     type = g_param_type_register_static (g_intern_static_string ("GParamValueArray"), &pspec_info);
1539     *spec_types++ = type;
1540     g_assert (type == G_TYPE_PARAM_VALUE_ARRAY);
1541   }
1542
1543   /* G_TYPE_PARAM_OBJECT
1544    */
1545   {
1546     const GParamSpecTypeInfo pspec_info = {
1547       sizeof (GParamSpecObject), /* instance_size */
1548       16,                        /* n_preallocs */
1549       param_object_init,         /* instance_init */
1550       G_TYPE_OBJECT,             /* value_type */
1551       NULL,                      /* finalize */
1552       param_object_set_default,  /* value_set_default */
1553       param_object_validate,     /* value_validate */
1554       param_object_values_cmp,   /* values_cmp */
1555     };
1556     type = g_param_type_register_static (g_intern_static_string ("GParamObject"), &pspec_info);
1557     *spec_types++ = type;
1558     g_assert (type == G_TYPE_PARAM_OBJECT);
1559   }
1560
1561   /* G_TYPE_PARAM_OVERRIDE
1562    */
1563   {
1564     const GParamSpecTypeInfo pspec_info = {
1565       sizeof (GParamSpecOverride), /* instance_size */
1566       16,                        /* n_preallocs */
1567       param_override_init,       /* instance_init */
1568       G_TYPE_NONE,               /* value_type */
1569       param_override_finalize,   /* finalize */
1570       param_override_set_default, /* value_set_default */
1571       param_override_validate,    /* value_validate */
1572       param_override_values_cmp,  /* values_cmp */
1573     };
1574     type = g_param_type_register_static (g_intern_static_string ("GParamOverride"), &pspec_info);
1575     *spec_types++ = type;
1576     g_assert (type == G_TYPE_PARAM_OVERRIDE);
1577   }
1578
1579   /* G_TYPE_PARAM_GTYPE
1580    */
1581   {
1582     GParamSpecTypeInfo pspec_info = {
1583       sizeof (GParamSpecGType), /* instance_size */
1584       0,                        /* n_preallocs */
1585       param_gtype_init,         /* instance_init */
1586       0xdeadbeef,               /* value_type, assigned further down */
1587       NULL,                     /* finalize */
1588       param_gtype_set_default,  /* value_set_default */
1589       param_gtype_validate,     /* value_validate */
1590       param_gtype_values_cmp,   /* values_cmp */
1591     };
1592     pspec_info.value_type = G_TYPE_GTYPE;
1593     type = g_param_type_register_static (g_intern_static_string ("GParamGType"), &pspec_info);
1594     *spec_types++ = type;
1595     g_assert (type == G_TYPE_PARAM_GTYPE);
1596   }
1597
1598   /* G_TYPE_PARAM_VARIANT
1599    */
1600   {
1601     const GParamSpecTypeInfo pspec_info = {
1602       sizeof (GParamSpecVariant), /* instance_size */
1603       0,                          /* n_preallocs */
1604       param_variant_init,         /* instance_init */
1605       G_TYPE_VARIANT,             /* value_type */
1606       param_variant_finalize,     /* finalize */
1607       param_variant_set_default,  /* value_set_default */
1608       param_variant_validate,     /* value_validate */
1609       param_variant_values_cmp,   /* values_cmp */
1610     };
1611     type = g_param_type_register_static (g_intern_static_string ("GParamVariant"), &pspec_info);
1612     *spec_types++ = type;
1613     g_assert (type == G_TYPE_PARAM_VARIANT);
1614   }
1615
1616   g_assert (spec_types == spec_types_bound);
1617 }
1618
1619 /* --- GParamSpec initialization --- */
1620
1621 /**
1622  * g_param_spec_char:
1623  * @name: canonical name of the property specified
1624  * @nick: nick name for the property specified
1625  * @blurb: description of the property specified
1626  * @minimum: minimum value for the property specified
1627  * @maximum: maximum value for the property specified
1628  * @default_value: default value for the property specified
1629  * @flags: flags for the property specified
1630  *
1631  * Creates a new #GParamSpecChar instance specifying a %G_TYPE_CHAR property.
1632  *
1633  * Returns: (transfer full): a newly created parameter specification
1634  */
1635 GParamSpec*
1636 g_param_spec_char (const gchar *name,
1637                    const gchar *nick,
1638                    const gchar *blurb,
1639                    gint8        minimum,
1640                    gint8        maximum,
1641                    gint8        default_value,
1642                    GParamFlags  flags)
1643 {
1644   GParamSpecChar *cspec;
1645
1646   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1647
1648   cspec = g_param_spec_internal (G_TYPE_PARAM_CHAR,
1649                                  name,
1650                                  nick,
1651                                  blurb,
1652                                  flags);
1653   if (cspec == NULL)
1654     return NULL;
1655   
1656   cspec->minimum = minimum;
1657   cspec->maximum = maximum;
1658   cspec->default_value = default_value;
1659   
1660   return G_PARAM_SPEC (cspec);
1661 }
1662
1663 /**
1664  * g_param_spec_uchar:
1665  * @name: canonical name of the property specified
1666  * @nick: nick name for the property specified
1667  * @blurb: description of the property specified
1668  * @minimum: minimum value for the property specified
1669  * @maximum: maximum value for the property specified
1670  * @default_value: default value for the property specified
1671  * @flags: flags for the property specified
1672  *
1673  * Creates a new #GParamSpecUChar instance specifying a %G_TYPE_UCHAR property.
1674  *
1675  * Returns: (transfer full): a newly created parameter specification
1676  */
1677 GParamSpec*
1678 g_param_spec_uchar (const gchar *name,
1679                     const gchar *nick,
1680                     const gchar *blurb,
1681                     guint8       minimum,
1682                     guint8       maximum,
1683                     guint8       default_value,
1684                     GParamFlags  flags)
1685 {
1686   GParamSpecUChar *uspec;
1687
1688   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1689
1690   uspec = g_param_spec_internal (G_TYPE_PARAM_UCHAR,
1691                                  name,
1692                                  nick,
1693                                  blurb,
1694                                  flags);
1695   if (uspec == NULL)
1696     return NULL;
1697   
1698   uspec->minimum = minimum;
1699   uspec->maximum = maximum;
1700   uspec->default_value = default_value;
1701   
1702   return G_PARAM_SPEC (uspec);
1703 }
1704
1705 /**
1706  * g_param_spec_boolean:
1707  * @name: canonical name of the property specified
1708  * @nick: nick name for the property specified
1709  * @blurb: description of the property specified
1710  * @default_value: default value for the property specified
1711  * @flags: flags for the property specified
1712  *
1713  * Creates a new #GParamSpecBoolean instance specifying a %G_TYPE_BOOLEAN
1714  * property. In many cases, it may be more appropriate to use an enum with
1715  * g_param_spec_enum(), both to improve code clarity by using explicitly named
1716  * values, and to allow for more values to be added in future without breaking
1717  * API.
1718  *
1719  * See g_param_spec_internal() for details on property names.
1720  *
1721  * Returns: (transfer full): a newly created parameter specification
1722  */
1723 GParamSpec*
1724 g_param_spec_boolean (const gchar *name,
1725                       const gchar *nick,
1726                       const gchar *blurb,
1727                       gboolean     default_value,
1728                       GParamFlags  flags)
1729 {
1730   GParamSpecBoolean *bspec;
1731
1732   g_return_val_if_fail (default_value == TRUE || default_value == FALSE, NULL);
1733
1734   bspec = g_param_spec_internal (G_TYPE_PARAM_BOOLEAN,
1735                                  name,
1736                                  nick,
1737                                  blurb,
1738                                  flags);
1739   if (bspec == NULL)
1740     return NULL;
1741   
1742   bspec->default_value = default_value;
1743   
1744   return G_PARAM_SPEC (bspec);
1745 }
1746
1747 /**
1748  * g_param_spec_int:
1749  * @name: canonical name of the property specified
1750  * @nick: nick name for the property specified
1751  * @blurb: description of the property specified
1752  * @minimum: minimum value for the property specified
1753  * @maximum: maximum value for the property specified
1754  * @default_value: default value for the property specified
1755  * @flags: flags for the property specified
1756  *
1757  * Creates a new #GParamSpecInt instance specifying a %G_TYPE_INT property.
1758  *
1759  * See g_param_spec_internal() for details on property names.
1760  *
1761  * Returns: (transfer full): a newly created parameter specification
1762  */
1763 GParamSpec*
1764 g_param_spec_int (const gchar *name,
1765                   const gchar *nick,
1766                   const gchar *blurb,
1767                   gint         minimum,
1768                   gint         maximum,
1769                   gint         default_value,
1770                   GParamFlags  flags)
1771 {
1772   GParamSpecInt *ispec;
1773
1774   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1775
1776   ispec = g_param_spec_internal (G_TYPE_PARAM_INT,
1777                                  name,
1778                                  nick,
1779                                  blurb,
1780                                  flags);
1781   if (ispec == NULL)
1782     return NULL;
1783   
1784   ispec->minimum = minimum;
1785   ispec->maximum = maximum;
1786   ispec->default_value = default_value;
1787   
1788   return G_PARAM_SPEC (ispec);
1789 }
1790
1791 /**
1792  * g_param_spec_uint:
1793  * @name: canonical name of the property specified
1794  * @nick: nick name for the property specified
1795  * @blurb: description of the property specified
1796  * @minimum: minimum value for the property specified
1797  * @maximum: maximum value for the property specified
1798  * @default_value: default value for the property specified
1799  * @flags: flags for the property specified
1800  *
1801  * Creates a new #GParamSpecUInt instance specifying a %G_TYPE_UINT property.
1802  *
1803  * See g_param_spec_internal() for details on property names.
1804  *
1805  * Returns: (transfer full): a newly created parameter specification
1806  */
1807 GParamSpec*
1808 g_param_spec_uint (const gchar *name,
1809                    const gchar *nick,
1810                    const gchar *blurb,
1811                    guint        minimum,
1812                    guint        maximum,
1813                    guint        default_value,
1814                    GParamFlags  flags)
1815 {
1816   GParamSpecUInt *uspec;
1817
1818   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1819
1820   uspec = g_param_spec_internal (G_TYPE_PARAM_UINT,
1821                                  name,
1822                                  nick,
1823                                  blurb,
1824                                  flags);
1825   if (uspec == NULL)
1826     return NULL;
1827   
1828   uspec->minimum = minimum;
1829   uspec->maximum = maximum;
1830   uspec->default_value = default_value;
1831   
1832   return G_PARAM_SPEC (uspec);
1833 }
1834
1835 /**
1836  * g_param_spec_long:
1837  * @name: canonical name of the property specified
1838  * @nick: nick name for the property specified
1839  * @blurb: description of the property specified
1840  * @minimum: minimum value for the property specified
1841  * @maximum: maximum value for the property specified
1842  * @default_value: default value for the property specified
1843  * @flags: flags for the property specified
1844  *
1845  * Creates a new #GParamSpecLong instance specifying a %G_TYPE_LONG property.
1846  *
1847  * See g_param_spec_internal() for details on property names.
1848  *
1849  * Returns: (transfer full): a newly created parameter specification
1850  */
1851 GParamSpec*
1852 g_param_spec_long (const gchar *name,
1853                    const gchar *nick,
1854                    const gchar *blurb,
1855                    glong        minimum,
1856                    glong        maximum,
1857                    glong        default_value,
1858                    GParamFlags  flags)
1859 {
1860   GParamSpecLong *lspec;
1861
1862   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1863
1864   lspec = g_param_spec_internal (G_TYPE_PARAM_LONG,
1865                                  name,
1866                                  nick,
1867                                  blurb,
1868                                  flags);
1869   if (lspec == NULL)
1870     return NULL;
1871   
1872   lspec->minimum = minimum;
1873   lspec->maximum = maximum;
1874   lspec->default_value = default_value;
1875   
1876   return G_PARAM_SPEC (lspec);
1877 }
1878
1879 /**
1880  * g_param_spec_ulong:
1881  * @name: canonical name of the property specified
1882  * @nick: nick name for the property specified
1883  * @blurb: description of the property specified
1884  * @minimum: minimum value for the property specified
1885  * @maximum: maximum value for the property specified
1886  * @default_value: default value for the property specified
1887  * @flags: flags for the property specified
1888  *
1889  * Creates a new #GParamSpecULong instance specifying a %G_TYPE_ULONG
1890  * property.
1891  *
1892  * See g_param_spec_internal() for details on property names.
1893  *
1894  * Returns: (transfer full): a newly created parameter specification
1895  */
1896 GParamSpec*
1897 g_param_spec_ulong (const gchar *name,
1898                     const gchar *nick,
1899                     const gchar *blurb,
1900                     gulong       minimum,
1901                     gulong       maximum,
1902                     gulong       default_value,
1903                     GParamFlags  flags)
1904 {
1905   GParamSpecULong *uspec;
1906
1907   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1908
1909   uspec = g_param_spec_internal (G_TYPE_PARAM_ULONG,
1910                                  name,
1911                                  nick,
1912                                  blurb,
1913                                  flags);
1914   if (uspec == NULL)
1915     return NULL;
1916   
1917   uspec->minimum = minimum;
1918   uspec->maximum = maximum;
1919   uspec->default_value = default_value;
1920   
1921   return G_PARAM_SPEC (uspec);
1922 }
1923
1924 /**
1925  * g_param_spec_int64:
1926  * @name: canonical name of the property specified
1927  * @nick: nick name for the property specified
1928  * @blurb: description of the property specified
1929  * @minimum: minimum value for the property specified
1930  * @maximum: maximum value for the property specified
1931  * @default_value: default value for the property specified
1932  * @flags: flags for the property specified
1933  *
1934  * Creates a new #GParamSpecInt64 instance specifying a %G_TYPE_INT64 property.
1935  *
1936  * See g_param_spec_internal() for details on property names.
1937  *
1938  * Returns: (transfer full): a newly created parameter specification
1939  */
1940 GParamSpec*
1941 g_param_spec_int64 (const gchar *name,
1942                     const gchar *nick,
1943                     const gchar *blurb,
1944                     gint64       minimum,
1945                     gint64       maximum,
1946                     gint64       default_value,
1947                     GParamFlags  flags)
1948 {
1949   GParamSpecInt64 *lspec;
1950   
1951   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1952
1953   lspec = g_param_spec_internal (G_TYPE_PARAM_INT64,
1954                                  name,
1955                                  nick,
1956                                  blurb,
1957                                  flags);
1958   if (lspec == NULL)
1959     return NULL;
1960   
1961   lspec->minimum = minimum;
1962   lspec->maximum = maximum;
1963   lspec->default_value = default_value;
1964   
1965   return G_PARAM_SPEC (lspec);
1966 }
1967
1968 /**
1969  * g_param_spec_uint64:
1970  * @name: canonical name of the property specified
1971  * @nick: nick name for the property specified
1972  * @blurb: description of the property specified
1973  * @minimum: minimum value for the property specified
1974  * @maximum: maximum value for the property specified
1975  * @default_value: default value for the property specified
1976  * @flags: flags for the property specified
1977  *
1978  * Creates a new #GParamSpecUInt64 instance specifying a %G_TYPE_UINT64
1979  * property.
1980  *
1981  * See g_param_spec_internal() for details on property names.
1982  *
1983  * Returns: (transfer full): a newly created parameter specification
1984  */
1985 GParamSpec*
1986 g_param_spec_uint64 (const gchar *name,
1987                      const gchar *nick,
1988                      const gchar *blurb,
1989                      guint64      minimum,
1990                      guint64      maximum,
1991                      guint64      default_value,
1992                      GParamFlags  flags)
1993 {
1994   GParamSpecUInt64 *uspec;
1995   
1996   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1997   
1998   uspec = g_param_spec_internal (G_TYPE_PARAM_UINT64,
1999                                  name,
2000                                  nick,
2001                                  blurb,
2002                                  flags);
2003   if (uspec == NULL)
2004     return NULL;
2005   
2006   uspec->minimum = minimum;
2007   uspec->maximum = maximum;
2008   uspec->default_value = default_value;
2009   
2010   return G_PARAM_SPEC (uspec);
2011 }
2012
2013 /**
2014  * g_param_spec_unichar:
2015  * @name: canonical name of the property specified
2016  * @nick: nick name for the property specified
2017  * @blurb: description of the property specified
2018  * @default_value: default value for the property specified
2019  * @flags: flags for the property specified
2020  *
2021  * Creates a new #GParamSpecUnichar instance specifying a %G_TYPE_UINT
2022  * property. #GValue structures for this property can be accessed with
2023  * g_value_set_uint() and g_value_get_uint().
2024  *
2025  * See g_param_spec_internal() for details on property names.
2026  *
2027  * Returns: (transfer full): a newly created parameter specification
2028  */
2029 GParamSpec*
2030 g_param_spec_unichar (const gchar *name,
2031                       const gchar *nick,
2032                       const gchar *blurb,
2033                       gunichar     default_value,
2034                       GParamFlags  flags)
2035 {
2036   GParamSpecUnichar *uspec;
2037
2038   uspec = g_param_spec_internal (G_TYPE_PARAM_UNICHAR,
2039                                  name,
2040                                  nick,
2041                                  blurb,
2042                                  flags);
2043   if (uspec == NULL)
2044     return NULL;
2045   
2046   uspec->default_value = default_value;
2047   
2048   return G_PARAM_SPEC (uspec);
2049 }
2050
2051 /**
2052  * g_param_spec_enum:
2053  * @name: canonical name of the property specified
2054  * @nick: nick name for the property specified
2055  * @blurb: description of the property specified
2056  * @enum_type: a #GType derived from %G_TYPE_ENUM
2057  * @default_value: default value for the property specified
2058  * @flags: flags for the property specified
2059  *
2060  * Creates a new #GParamSpecEnum instance specifying a %G_TYPE_ENUM
2061  * property.
2062  *
2063  * See g_param_spec_internal() for details on property names.
2064  *
2065  * Returns: (transfer full): a newly created parameter specification
2066  */
2067 GParamSpec*
2068 g_param_spec_enum (const gchar *name,
2069                    const gchar *nick,
2070                    const gchar *blurb,
2071                    GType        enum_type,
2072                    gint         default_value,
2073                    GParamFlags  flags)
2074 {
2075   GParamSpecEnum *espec;
2076   GEnumClass *enum_class;
2077   
2078   g_return_val_if_fail (G_TYPE_IS_ENUM (enum_type), NULL);
2079
2080   enum_class = g_type_class_ref (enum_type);
2081
2082   g_return_val_if_fail (g_enum_get_value (enum_class, default_value) != NULL, NULL);
2083   
2084   espec = g_param_spec_internal (G_TYPE_PARAM_ENUM,
2085                                  name,
2086                                  nick,
2087                                  blurb,
2088                                  flags);
2089   if (espec == NULL)
2090     return NULL;
2091   
2092   espec->enum_class = enum_class;
2093   espec->default_value = default_value;
2094   G_PARAM_SPEC (espec)->value_type = enum_type;
2095   
2096   return G_PARAM_SPEC (espec);
2097 }
2098
2099 /**
2100  * g_param_spec_flags:
2101  * @name: canonical name of the property specified
2102  * @nick: nick name for the property specified
2103  * @blurb: description of the property specified
2104  * @flags_type: a #GType derived from %G_TYPE_FLAGS
2105  * @default_value: default value for the property specified
2106  * @flags: flags for the property specified
2107  *
2108  * Creates a new #GParamSpecFlags instance specifying a %G_TYPE_FLAGS
2109  * property.
2110  *
2111  * See g_param_spec_internal() for details on property names.
2112  *
2113  * Returns: (transfer full): a newly created parameter specification
2114  */
2115 GParamSpec*
2116 g_param_spec_flags (const gchar *name,
2117                     const gchar *nick,
2118                     const gchar *blurb,
2119                     GType        flags_type,
2120                     guint        default_value,
2121                     GParamFlags  flags)
2122 {
2123   GParamSpecFlags *fspec;
2124   GFlagsClass *flags_class;
2125   
2126   g_return_val_if_fail (G_TYPE_IS_FLAGS (flags_type), NULL);
2127
2128   flags_class = g_type_class_ref (flags_type);
2129
2130   g_return_val_if_fail ((default_value & flags_class->mask) == default_value, NULL);
2131   
2132   fspec = g_param_spec_internal (G_TYPE_PARAM_FLAGS,
2133                                  name,
2134                                  nick,
2135                                  blurb,
2136                                  flags);
2137   if (fspec == NULL)
2138     return NULL;
2139   
2140   fspec->flags_class = flags_class;
2141   fspec->default_value = default_value;
2142   G_PARAM_SPEC (fspec)->value_type = flags_type;
2143   
2144   return G_PARAM_SPEC (fspec);
2145 }
2146
2147 /**
2148  * g_param_spec_float:
2149  * @name: canonical name of the property specified
2150  * @nick: nick name for the property specified
2151  * @blurb: description of the property specified
2152  * @minimum: minimum value for the property specified
2153  * @maximum: maximum value for the property specified
2154  * @default_value: default value for the property specified
2155  * @flags: flags for the property specified
2156  *
2157  * Creates a new #GParamSpecFloat instance specifying a %G_TYPE_FLOAT property.
2158  *
2159  * See g_param_spec_internal() for details on property names.
2160  *
2161  * Returns: (transfer full): a newly created parameter specification
2162  */
2163 GParamSpec*
2164 g_param_spec_float (const gchar *name,
2165                     const gchar *nick,
2166                     const gchar *blurb,
2167                     gfloat       minimum,
2168                     gfloat       maximum,
2169                     gfloat       default_value,
2170                     GParamFlags  flags)
2171 {
2172   GParamSpecFloat *fspec;
2173
2174   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
2175
2176   fspec = g_param_spec_internal (G_TYPE_PARAM_FLOAT,
2177                                  name,
2178                                  nick,
2179                                  blurb,
2180                                  flags);
2181   if (fspec == NULL)
2182     return NULL;
2183   
2184   fspec->minimum = minimum;
2185   fspec->maximum = maximum;
2186   fspec->default_value = default_value;
2187   
2188   return G_PARAM_SPEC (fspec);
2189 }
2190
2191 /**
2192  * g_param_spec_double:
2193  * @name: canonical name of the property specified
2194  * @nick: nick name for the property specified
2195  * @blurb: description of the property specified
2196  * @minimum: minimum value for the property specified
2197  * @maximum: maximum value for the property specified
2198  * @default_value: default value for the property specified
2199  * @flags: flags for the property specified
2200  *
2201  * Creates a new #GParamSpecDouble instance specifying a %G_TYPE_DOUBLE
2202  * property.
2203  *
2204  * See g_param_spec_internal() for details on property names.
2205  *
2206  * Returns: (transfer full): a newly created parameter specification
2207  */
2208 GParamSpec*
2209 g_param_spec_double (const gchar *name,
2210                      const gchar *nick,
2211                      const gchar *blurb,
2212                      gdouble      minimum,
2213                      gdouble      maximum,
2214                      gdouble      default_value,
2215                      GParamFlags  flags)
2216 {
2217   GParamSpecDouble *dspec;
2218
2219   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
2220
2221   dspec = g_param_spec_internal (G_TYPE_PARAM_DOUBLE,
2222                                  name,
2223                                  nick,
2224                                  blurb,
2225                                  flags);
2226   if (dspec == NULL)
2227     return NULL;
2228   
2229   dspec->minimum = minimum;
2230   dspec->maximum = maximum;
2231   dspec->default_value = default_value;
2232   
2233   return G_PARAM_SPEC (dspec);
2234 }
2235
2236 /**
2237  * g_param_spec_string:
2238  * @name: canonical name of the property specified
2239  * @nick: nick name for the property specified
2240  * @blurb: description of the property specified
2241  * @default_value: (nullable): default value for the property specified
2242  * @flags: flags for the property specified
2243  *
2244  * Creates a new #GParamSpecString instance.
2245  *
2246  * See g_param_spec_internal() for details on property names.
2247  *
2248  * Returns: (transfer full): a newly created parameter specification
2249  */
2250 GParamSpec*
2251 g_param_spec_string (const gchar *name,
2252                      const gchar *nick,
2253                      const gchar *blurb,
2254                      const gchar *default_value,
2255                      GParamFlags  flags)
2256 {
2257   GParamSpecString *sspec = g_param_spec_internal (G_TYPE_PARAM_STRING,
2258                                                    name,
2259                                                    nick,
2260                                                    blurb,
2261                                                    flags);
2262   if (sspec == NULL)
2263     return NULL;
2264
2265   g_free (sspec->default_value);
2266   sspec->default_value = g_strdup (default_value);
2267   
2268   return G_PARAM_SPEC (sspec);
2269 }
2270
2271 /**
2272  * g_param_spec_param:
2273  * @name: canonical name of the property specified
2274  * @nick: nick name for the property specified
2275  * @blurb: description of the property specified
2276  * @param_type: a #GType derived from %G_TYPE_PARAM
2277  * @flags: flags for the property specified
2278  *
2279  * Creates a new #GParamSpecParam instance specifying a %G_TYPE_PARAM
2280  * property.
2281  *
2282  * See g_param_spec_internal() for details on property names.
2283  *
2284  * Returns: (transfer full): a newly created parameter specification
2285  */
2286 GParamSpec*
2287 g_param_spec_param (const gchar *name,
2288                     const gchar *nick,
2289                     const gchar *blurb,
2290                     GType        param_type,
2291                     GParamFlags  flags)
2292 {
2293   GParamSpecParam *pspec;
2294   
2295   g_return_val_if_fail (G_TYPE_IS_PARAM (param_type), NULL);
2296   
2297   pspec = g_param_spec_internal (G_TYPE_PARAM_PARAM,
2298                                  name,
2299                                  nick,
2300                                  blurb,
2301                                  flags);
2302   if (pspec == NULL)
2303     return NULL;
2304
2305   G_PARAM_SPEC (pspec)->value_type = param_type;
2306   
2307   return G_PARAM_SPEC (pspec);
2308 }
2309
2310 /**
2311  * g_param_spec_boxed:
2312  * @name: canonical name of the property specified
2313  * @nick: nick name for the property specified
2314  * @blurb: description of the property specified
2315  * @boxed_type: %G_TYPE_BOXED derived type of this property
2316  * @flags: flags for the property specified
2317  *
2318  * Creates a new #GParamSpecBoxed instance specifying a %G_TYPE_BOXED
2319  * derived property.
2320  *
2321  * See g_param_spec_internal() for details on property names.
2322  *
2323  * Returns: (transfer full): a newly created parameter specification
2324  */
2325 GParamSpec*
2326 g_param_spec_boxed (const gchar *name,
2327                     const gchar *nick,
2328                     const gchar *blurb,
2329                     GType        boxed_type,
2330                     GParamFlags  flags)
2331 {
2332   GParamSpecBoxed *bspec;
2333   
2334   g_return_val_if_fail (G_TYPE_IS_BOXED (boxed_type), NULL);
2335   g_return_val_if_fail (G_TYPE_IS_VALUE_TYPE (boxed_type), NULL);
2336   
2337   bspec = g_param_spec_internal (G_TYPE_PARAM_BOXED,
2338                                  name,
2339                                  nick,
2340                                  blurb,
2341                                  flags);
2342   if (bspec == NULL)
2343     return NULL;
2344
2345   G_PARAM_SPEC (bspec)->value_type = boxed_type;
2346   
2347   return G_PARAM_SPEC (bspec);
2348 }
2349
2350 /**
2351  * g_param_spec_pointer:
2352  * @name: canonical name of the property specified
2353  * @nick: nick name for the property specified
2354  * @blurb: description of the property specified
2355  * @flags: flags for the property specified
2356  *
2357  * Creates a new #GParamSpecPointer instance specifying a pointer property.
2358  * Where possible, it is better to use g_param_spec_object() or
2359  * g_param_spec_boxed() to expose memory management information.
2360  *
2361  * See g_param_spec_internal() for details on property names.
2362  *
2363  * Returns: (transfer full): a newly created parameter specification
2364  */
2365 GParamSpec*
2366 g_param_spec_pointer (const gchar *name,
2367                       const gchar *nick,
2368                       const gchar *blurb,
2369                       GParamFlags  flags)
2370 {
2371   GParamSpecPointer *pspec;
2372   
2373   pspec = g_param_spec_internal (G_TYPE_PARAM_POINTER,
2374                                  name,
2375                                  nick,
2376                                  blurb,
2377                                  flags);
2378   if (pspec == NULL)
2379     return NULL;
2380
2381   return G_PARAM_SPEC (pspec);
2382 }
2383
2384 /**
2385  * g_param_spec_gtype:
2386  * @name: canonical name of the property specified
2387  * @nick: nick name for the property specified
2388  * @blurb: description of the property specified
2389  * @is_a_type: a #GType whose subtypes are allowed as values
2390  *  of the property (use %G_TYPE_NONE for any type)
2391  * @flags: flags for the property specified
2392  *
2393  * Creates a new #GParamSpecGType instance specifying a
2394  * %G_TYPE_GTYPE property.
2395  *
2396  * See g_param_spec_internal() for details on property names.
2397  *
2398  * Since: 2.10
2399  *
2400  * Returns: (transfer full): a newly created parameter specification
2401  */
2402 GParamSpec*
2403 g_param_spec_gtype (const gchar *name,
2404                     const gchar *nick,
2405                     const gchar *blurb,
2406                     GType        is_a_type,
2407                     GParamFlags  flags)
2408 {
2409   GParamSpecGType *tspec;
2410   
2411   tspec = g_param_spec_internal (G_TYPE_PARAM_GTYPE,
2412                                  name,
2413                                  nick,
2414                                  blurb,
2415                                  flags);
2416   if (tspec == NULL)
2417     return NULL;
2418
2419   tspec->is_a_type = is_a_type;
2420
2421   return G_PARAM_SPEC (tspec);
2422 }
2423
2424 /**
2425  * g_param_spec_value_array: (skip)
2426  * @name: canonical name of the property specified
2427  * @nick: nick name for the property specified
2428  * @blurb: description of the property specified
2429  * @element_spec: a #GParamSpec describing the elements contained in
2430  *  arrays of this property, may be %NULL
2431  * @flags: flags for the property specified
2432  *
2433  * Creates a new #GParamSpecValueArray instance specifying a
2434  * %G_TYPE_VALUE_ARRAY property. %G_TYPE_VALUE_ARRAY is a
2435  * %G_TYPE_BOXED type, as such, #GValue structures for this property
2436  * can be accessed with g_value_set_boxed() and g_value_get_boxed().
2437  *
2438  * See g_param_spec_internal() for details on property names.
2439  *
2440  * Returns: a newly created parameter specification
2441  */
2442 GParamSpec*
2443 g_param_spec_value_array (const gchar *name,
2444                           const gchar *nick,
2445                           const gchar *blurb,
2446                           GParamSpec  *element_spec,
2447                           GParamFlags  flags)
2448 {
2449   GParamSpecValueArray *aspec;
2450   
2451   if (element_spec)
2452     g_return_val_if_fail (G_IS_PARAM_SPEC (element_spec), NULL);
2453   
2454   aspec = g_param_spec_internal (G_TYPE_PARAM_VALUE_ARRAY,
2455                                  name,
2456                                  nick,
2457                                  blurb,
2458                                  flags);
2459   if (aspec == NULL)
2460     return NULL;
2461
2462   if (element_spec)
2463     {
2464       aspec->element_spec = g_param_spec_ref (element_spec);
2465       g_param_spec_sink (element_spec);
2466     }
2467
2468   return G_PARAM_SPEC (aspec);
2469 }
2470
2471 /**
2472  * g_param_spec_object:
2473  * @name: canonical name of the property specified
2474  * @nick: nick name for the property specified
2475  * @blurb: description of the property specified
2476  * @object_type: %G_TYPE_OBJECT derived type of this property
2477  * @flags: flags for the property specified
2478  *
2479  * Creates a new #GParamSpecBoxed instance specifying a %G_TYPE_OBJECT
2480  * derived property.
2481  *
2482  * See g_param_spec_internal() for details on property names.
2483  *
2484  * Returns: (transfer full): a newly created parameter specification
2485  */
2486 GParamSpec*
2487 g_param_spec_object (const gchar *name,
2488                      const gchar *nick,
2489                      const gchar *blurb,
2490                      GType        object_type,
2491                      GParamFlags  flags)
2492 {
2493   GParamSpecObject *ospec;
2494   
2495   g_return_val_if_fail (g_type_is_a (object_type, G_TYPE_OBJECT), NULL);
2496   
2497   ospec = g_param_spec_internal (G_TYPE_PARAM_OBJECT,
2498                                  name,
2499                                  nick,
2500                                  blurb,
2501                                  flags);
2502   if (ospec == NULL)
2503     return NULL;
2504
2505   G_PARAM_SPEC (ospec)->value_type = object_type;
2506   
2507   return G_PARAM_SPEC (ospec);
2508 }
2509
2510 /**
2511  * g_param_spec_override: (skip)
2512  * @name: the name of the property.
2513  * @overridden: The property that is being overridden
2514  *
2515  * Creates a new property of type #GParamSpecOverride. This is used
2516  * to direct operations to another paramspec, and will not be directly
2517  * useful unless you are implementing a new base type similar to GObject.
2518  *
2519  * Since: 2.4
2520  *
2521  * Returns: the newly created #GParamSpec
2522  */
2523 GParamSpec*
2524 g_param_spec_override (const gchar *name,
2525                        GParamSpec  *overridden)
2526 {
2527   GParamSpec *pspec;
2528   
2529   g_return_val_if_fail (name != NULL, NULL);
2530   g_return_val_if_fail (G_IS_PARAM_SPEC (overridden), NULL);
2531   
2532   /* Dereference further redirections for property that was passed in
2533    */
2534   while (TRUE)
2535     {
2536       GParamSpec *indirect = g_param_spec_get_redirect_target (overridden);
2537       if (indirect)
2538         overridden = indirect;
2539       else
2540         break;
2541     }
2542
2543   pspec = g_param_spec_internal (G_TYPE_PARAM_OVERRIDE,
2544                                  name, NULL, NULL,
2545                                  overridden->flags);
2546   if (pspec == NULL)
2547     return NULL;
2548   
2549   pspec->value_type = G_PARAM_SPEC_VALUE_TYPE (overridden);
2550   G_PARAM_SPEC_OVERRIDE (pspec)->overridden = g_param_spec_ref (overridden);
2551
2552   return pspec;
2553 }
2554
2555 /**
2556  * g_param_spec_variant:
2557  * @name: canonical name of the property specified
2558  * @nick: nick name for the property specified
2559  * @blurb: description of the property specified
2560  * @type: a #GVariantType
2561  * @default_value: (nullable) (transfer full): a #GVariant of type @type to
2562  *                 use as the default value, or %NULL
2563  * @flags: flags for the property specified
2564  *
2565  * Creates a new #GParamSpecVariant instance specifying a #GVariant
2566  * property.
2567  *
2568  * If @default_value is floating, it is consumed.
2569  *
2570  * See g_param_spec_internal() for details on property names.
2571  *
2572  * Returns: (transfer full): the newly created #GParamSpec
2573  *
2574  * Since: 2.26
2575  */
2576 GParamSpec*
2577 g_param_spec_variant (const gchar        *name,
2578                       const gchar        *nick,
2579                       const gchar        *blurb,
2580                       const GVariantType *type,
2581                       GVariant           *default_value,
2582                       GParamFlags         flags)
2583 {
2584   GParamSpecVariant *vspec;
2585
2586   g_return_val_if_fail (type != NULL, NULL);
2587   g_return_val_if_fail (default_value == NULL ||
2588                         g_variant_is_of_type (default_value, type), NULL);
2589
2590   vspec = g_param_spec_internal (G_TYPE_PARAM_VARIANT,
2591                                  name,
2592                                  nick,
2593                                  blurb,
2594                                  flags);
2595   if (vspec == NULL)
2596     return NULL;
2597
2598   vspec->type = g_variant_type_copy (type);
2599   if (default_value)
2600     vspec->default_value = g_variant_ref_sink (default_value);
2601
2602   return G_PARAM_SPEC (vspec);
2603 }