2.13.1
[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  *
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.
8  *
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.
13  *
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.
18  */
19
20 /*
21  * MT safe
22  */
23
24 #include        "../config.h"
25
26 #include        "gparamspecs.h"
27
28 #include        "gvaluecollector.h"
29 #include        "gvaluearray.h"
30 #include        "gobjectalias.h"
31 #include        <string.h>
32
33 #define G_FLOAT_EPSILON         (1e-30)
34 #define G_DOUBLE_EPSILON        (1e-90)
35
36
37 /* --- param spec functions --- */
38 static void
39 param_char_init (GParamSpec *pspec)
40 {
41   GParamSpecChar *cspec = G_PARAM_SPEC_CHAR (pspec);
42   
43   cspec->minimum = 0x7f;
44   cspec->maximum = 0x80;
45   cspec->default_value = 0;
46 }
47
48 static void
49 param_char_set_default (GParamSpec *pspec,
50                         GValue     *value)
51 {
52   value->data[0].v_int = G_PARAM_SPEC_CHAR (pspec)->default_value;
53 }
54
55 static gboolean
56 param_char_validate (GParamSpec *pspec,
57                      GValue     *value)
58 {
59   GParamSpecChar *cspec = G_PARAM_SPEC_CHAR (pspec);
60   gint oval = value->data[0].v_int;
61   
62   value->data[0].v_int = CLAMP (value->data[0].v_int, cspec->minimum, cspec->maximum);
63   
64   return value->data[0].v_int != oval;
65 }
66
67 static void
68 param_uchar_init (GParamSpec *pspec)
69 {
70   GParamSpecUChar *uspec = G_PARAM_SPEC_UCHAR (pspec);
71   
72   uspec->minimum = 0;
73   uspec->maximum = 0xff;
74   uspec->default_value = 0;
75 }
76
77 static void
78 param_uchar_set_default (GParamSpec *pspec,
79                          GValue     *value)
80 {
81   value->data[0].v_uint = G_PARAM_SPEC_UCHAR (pspec)->default_value;
82 }
83
84 static gboolean
85 param_uchar_validate (GParamSpec *pspec,
86                       GValue     *value)
87 {
88   GParamSpecUChar *uspec = G_PARAM_SPEC_UCHAR (pspec);
89   guint oval = value->data[0].v_uint;
90   
91   value->data[0].v_uint = CLAMP (value->data[0].v_uint, uspec->minimum, uspec->maximum);
92   
93   return value->data[0].v_uint != oval;
94 }
95
96 static void
97 param_boolean_set_default (GParamSpec *pspec,
98                            GValue     *value)
99 {
100   value->data[0].v_int = G_PARAM_SPEC_BOOLEAN (pspec)->default_value;
101 }
102
103 static gboolean
104 param_boolean_validate (GParamSpec *pspec,
105                         GValue     *value)
106 {
107   gint oval = value->data[0].v_int;
108   
109   value->data[0].v_int = value->data[0].v_int != FALSE;
110   
111   return value->data[0].v_int != oval;
112 }
113
114 static void
115 param_int_init (GParamSpec *pspec)
116 {
117   GParamSpecInt *ispec = G_PARAM_SPEC_INT (pspec);
118   
119   ispec->minimum = 0x7fffffff;
120   ispec->maximum = 0x80000000;
121   ispec->default_value = 0;
122 }
123
124 static void
125 param_int_set_default (GParamSpec *pspec,
126                        GValue     *value)
127 {
128   value->data[0].v_int = G_PARAM_SPEC_INT (pspec)->default_value;
129 }
130
131 static gboolean
132 param_int_validate (GParamSpec *pspec,
133                     GValue     *value)
134 {
135   GParamSpecInt *ispec = G_PARAM_SPEC_INT (pspec);
136   gint oval = value->data[0].v_int;
137   
138   value->data[0].v_int = CLAMP (value->data[0].v_int, ispec->minimum, ispec->maximum);
139   
140   return value->data[0].v_int != oval;
141 }
142
143 static gint
144 param_int_values_cmp (GParamSpec   *pspec,
145                       const GValue *value1,
146                       const GValue *value2)
147 {
148   if (value1->data[0].v_int < value2->data[0].v_int)
149     return -1;
150   else
151     return value1->data[0].v_int > value2->data[0].v_int;
152 }
153
154 static void
155 param_uint_init (GParamSpec *pspec)
156 {
157   GParamSpecUInt *uspec = G_PARAM_SPEC_UINT (pspec);
158   
159   uspec->minimum = 0;
160   uspec->maximum = 0xffffffff;
161   uspec->default_value = 0;
162 }
163
164 static void
165 param_uint_set_default (GParamSpec *pspec,
166                         GValue     *value)
167 {
168   value->data[0].v_uint = G_PARAM_SPEC_UINT (pspec)->default_value;
169 }
170
171 static gboolean
172 param_uint_validate (GParamSpec *pspec,
173                      GValue     *value)
174 {
175   GParamSpecUInt *uspec = G_PARAM_SPEC_UINT (pspec);
176   guint oval = value->data[0].v_uint;
177   
178   value->data[0].v_uint = CLAMP (value->data[0].v_uint, uspec->minimum, uspec->maximum);
179   
180   return value->data[0].v_uint != oval;
181 }
182
183 static gint
184 param_uint_values_cmp (GParamSpec   *pspec,
185                        const GValue *value1,
186                        const GValue *value2)
187 {
188   if (value1->data[0].v_uint < value2->data[0].v_uint)
189     return -1;
190   else
191     return value1->data[0].v_uint > value2->data[0].v_uint;
192 }
193
194 static void
195 param_long_init (GParamSpec *pspec)
196 {
197   GParamSpecLong *lspec = G_PARAM_SPEC_LONG (pspec);
198   
199 #if SIZEOF_LONG == 4
200   lspec->minimum = 0x7fffffff;
201   lspec->maximum = 0x80000000;
202 #else /* SIZEOF_LONG != 4 (8) */
203   lspec->minimum = 0x7fffffffffffffff;
204   lspec->maximum = 0x8000000000000000;
205 #endif
206   lspec->default_value = 0;
207 }
208
209 static void
210 param_long_set_default (GParamSpec *pspec,
211                         GValue     *value)
212 {
213   value->data[0].v_long = G_PARAM_SPEC_LONG (pspec)->default_value;
214 }
215
216 static gboolean
217 param_long_validate (GParamSpec *pspec,
218                      GValue     *value)
219 {
220   GParamSpecLong *lspec = G_PARAM_SPEC_LONG (pspec);
221   glong oval = value->data[0].v_long;
222   
223   value->data[0].v_long = CLAMP (value->data[0].v_long, lspec->minimum, lspec->maximum);
224   
225   return value->data[0].v_long != oval;
226 }
227
228 static gint
229 param_long_values_cmp (GParamSpec   *pspec,
230                        const GValue *value1,
231                        const GValue *value2)
232 {
233   if (value1->data[0].v_long < value2->data[0].v_long)
234     return -1;
235   else
236     return value1->data[0].v_long > value2->data[0].v_long;
237 }
238
239 static void
240 param_ulong_init (GParamSpec *pspec)
241 {
242   GParamSpecULong *uspec = G_PARAM_SPEC_ULONG (pspec);
243   
244   uspec->minimum = 0;
245 #if SIZEOF_LONG == 4
246   uspec->maximum = 0xffffffff;
247 #else /* SIZEOF_LONG != 4 (8) */
248   uspec->maximum = 0xffffffffffffffff;
249 #endif
250   uspec->default_value = 0;
251 }
252
253 static void
254 param_ulong_set_default (GParamSpec *pspec,
255                          GValue     *value)
256 {
257   value->data[0].v_ulong = G_PARAM_SPEC_ULONG (pspec)->default_value;
258 }
259
260 static gboolean
261 param_ulong_validate (GParamSpec *pspec,
262                       GValue     *value)
263 {
264   GParamSpecULong *uspec = G_PARAM_SPEC_ULONG (pspec);
265   gulong oval = value->data[0].v_ulong;
266   
267   value->data[0].v_ulong = CLAMP (value->data[0].v_ulong, uspec->minimum, uspec->maximum);
268   
269   return value->data[0].v_ulong != oval;
270 }
271
272 static gint
273 param_ulong_values_cmp (GParamSpec   *pspec,
274                         const GValue *value1,
275                         const GValue *value2)
276 {
277   if (value1->data[0].v_ulong < value2->data[0].v_ulong)
278     return -1;
279   else
280     return value1->data[0].v_ulong > value2->data[0].v_ulong;
281 }
282
283 static void
284 param_int64_init (GParamSpec *pspec)
285 {
286   GParamSpecInt64 *lspec = G_PARAM_SPEC_INT64 (pspec);
287   
288   lspec->minimum = G_MININT64;
289   lspec->maximum = G_MAXINT64;
290   lspec->default_value = 0;
291 }
292
293 static void
294 param_int64_set_default (GParamSpec *pspec,
295                         GValue     *value)
296 {
297   value->data[0].v_int64 = G_PARAM_SPEC_INT64 (pspec)->default_value;
298 }
299
300 static gboolean
301 param_int64_validate (GParamSpec *pspec,
302                      GValue     *value)
303 {
304   GParamSpecInt64 *lspec = G_PARAM_SPEC_INT64 (pspec);
305   gint64 oval = value->data[0].v_int64;
306   
307   value->data[0].v_int64 = CLAMP (value->data[0].v_int64, lspec->minimum, lspec->maximum);
308   
309   return value->data[0].v_int64 != oval;
310 }
311
312 static gint
313 param_int64_values_cmp (GParamSpec   *pspec,
314                        const GValue *value1,
315                        const GValue *value2)
316 {
317   if (value1->data[0].v_int64 < value2->data[0].v_int64)
318     return -1;
319   else
320     return value1->data[0].v_int64 > value2->data[0].v_int64;
321 }
322
323 static void
324 param_uint64_init (GParamSpec *pspec)
325 {
326   GParamSpecUInt64 *uspec = G_PARAM_SPEC_UINT64 (pspec);
327   
328   uspec->minimum = 0;
329   uspec->maximum = G_MAXUINT64;
330   uspec->default_value = 0;
331 }
332
333 static void
334 param_uint64_set_default (GParamSpec *pspec,
335                          GValue     *value)
336 {
337   value->data[0].v_uint64 = G_PARAM_SPEC_UINT64 (pspec)->default_value;
338 }
339
340 static gboolean
341 param_uint64_validate (GParamSpec *pspec,
342                       GValue     *value)
343 {
344   GParamSpecUInt64 *uspec = G_PARAM_SPEC_UINT64 (pspec);
345   guint64 oval = value->data[0].v_uint64;
346   
347   value->data[0].v_uint64 = CLAMP (value->data[0].v_uint64, uspec->minimum, uspec->maximum);
348   
349   return value->data[0].v_uint64 != oval;
350 }
351
352 static gint
353 param_uint64_values_cmp (GParamSpec   *pspec,
354                         const GValue *value1,
355                         const GValue *value2)
356 {
357   if (value1->data[0].v_uint64 < value2->data[0].v_uint64)
358     return -1;
359   else
360     return value1->data[0].v_uint64 > value2->data[0].v_uint64;
361 }
362
363 static void
364 param_unichar_init (GParamSpec *pspec)
365 {
366   GParamSpecUnichar *uspec = G_PARAM_SPEC_UNICHAR (pspec);
367   
368   uspec->default_value = 0;
369 }
370
371 static void
372 param_unichar_set_default (GParamSpec *pspec,
373                          GValue     *value)
374 {
375   value->data[0].v_uint = G_PARAM_SPEC_UNICHAR (pspec)->default_value;
376 }
377
378 static gboolean
379 param_unichar_validate (GParamSpec *pspec,
380                         GValue     *value)
381 {
382   gunichar oval = value->data[0].v_uint;
383   gboolean changed = FALSE;
384
385   if (!g_unichar_validate (oval))
386     {
387       value->data[0].v_uint = 0;
388       changed = TRUE;
389     }
390
391   return changed;
392 }
393
394 static gint
395 param_unichar_values_cmp (GParamSpec   *pspec,
396                         const GValue *value1,
397                         const GValue *value2)
398 {
399   if (value1->data[0].v_uint < value2->data[0].v_uint)
400     return -1;
401   else
402     return value1->data[0].v_uint > value2->data[0].v_uint;
403 }
404
405 static void
406 param_enum_init (GParamSpec *pspec)
407 {
408   GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec);
409   
410   espec->enum_class = NULL;
411   espec->default_value = 0;
412 }
413
414 static void
415 param_enum_finalize (GParamSpec *pspec)
416 {
417   GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec);
418   GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_ENUM));
419   
420   if (espec->enum_class)
421     {
422       g_type_class_unref (espec->enum_class);
423       espec->enum_class = NULL;
424     }
425   
426   parent_class->finalize (pspec);
427 }
428
429 static void
430 param_enum_set_default (GParamSpec *pspec,
431                         GValue     *value)
432 {
433   value->data[0].v_long = G_PARAM_SPEC_ENUM (pspec)->default_value;
434 }
435
436 static gboolean
437 param_enum_validate (GParamSpec *pspec,
438                      GValue     *value)
439 {
440   GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec);
441   glong oval = value->data[0].v_long;
442   
443   if (!espec->enum_class ||
444       !g_enum_get_value (espec->enum_class, value->data[0].v_long))
445     value->data[0].v_long = espec->default_value;
446   
447   return value->data[0].v_long != oval;
448 }
449
450 static void
451 param_flags_init (GParamSpec *pspec)
452 {
453   GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec);
454   
455   fspec->flags_class = NULL;
456   fspec->default_value = 0;
457 }
458
459 static void
460 param_flags_finalize (GParamSpec *pspec)
461 {
462   GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec);
463   GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_FLAGS));
464   
465   if (fspec->flags_class)
466     {
467       g_type_class_unref (fspec->flags_class);
468       fspec->flags_class = NULL;
469     }
470   
471   parent_class->finalize (pspec);
472 }
473
474 static void
475 param_flags_set_default (GParamSpec *pspec,
476                          GValue     *value)
477 {
478   value->data[0].v_ulong = G_PARAM_SPEC_FLAGS (pspec)->default_value;
479 }
480
481 static gboolean
482 param_flags_validate (GParamSpec *pspec,
483                       GValue     *value)
484 {
485   GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec);
486   gulong oval = value->data[0].v_ulong;
487   
488   if (fspec->flags_class)
489     value->data[0].v_ulong &= fspec->flags_class->mask;
490   else
491     value->data[0].v_ulong = fspec->default_value;
492   
493   return value->data[0].v_ulong != oval;
494 }
495
496 static void
497 param_float_init (GParamSpec *pspec)
498 {
499   GParamSpecFloat *fspec = G_PARAM_SPEC_FLOAT (pspec);
500   
501   fspec->minimum = -G_MAXFLOAT;
502   fspec->maximum = G_MAXFLOAT;
503   fspec->default_value = 0;
504   fspec->epsilon = G_FLOAT_EPSILON;
505 }
506
507 static void
508 param_float_set_default (GParamSpec *pspec,
509                          GValue     *value)
510 {
511   value->data[0].v_float = G_PARAM_SPEC_FLOAT (pspec)->default_value;
512 }
513
514 static gboolean
515 param_float_validate (GParamSpec *pspec,
516                       GValue     *value)
517 {
518   GParamSpecFloat *fspec = G_PARAM_SPEC_FLOAT (pspec);
519   gfloat oval = value->data[0].v_float;
520   
521   value->data[0].v_float = CLAMP (value->data[0].v_float, fspec->minimum, fspec->maximum);
522   
523   return value->data[0].v_float != oval;
524 }
525
526 static gint
527 param_float_values_cmp (GParamSpec   *pspec,
528                         const GValue *value1,
529                         const GValue *value2)
530 {
531   gfloat epsilon = G_PARAM_SPEC_FLOAT (pspec)->epsilon;
532   
533   if (value1->data[0].v_float < value2->data[0].v_float)
534     return - (value2->data[0].v_float - value1->data[0].v_float > epsilon);
535   else
536     return value1->data[0].v_float - value2->data[0].v_float > epsilon;
537 }
538
539 static void
540 param_double_init (GParamSpec *pspec)
541 {
542   GParamSpecDouble *dspec = G_PARAM_SPEC_DOUBLE (pspec);
543   
544   dspec->minimum = -G_MAXDOUBLE;
545   dspec->maximum = G_MAXDOUBLE;
546   dspec->default_value = 0;
547   dspec->epsilon = G_DOUBLE_EPSILON;
548 }
549
550 static void
551 param_double_set_default (GParamSpec *pspec,
552                           GValue     *value)
553 {
554   value->data[0].v_double = G_PARAM_SPEC_DOUBLE (pspec)->default_value;
555 }
556
557 static gboolean
558 param_double_validate (GParamSpec *pspec,
559                        GValue     *value)
560 {
561   GParamSpecDouble *dspec = G_PARAM_SPEC_DOUBLE (pspec);
562   gdouble oval = value->data[0].v_double;
563   
564   value->data[0].v_double = CLAMP (value->data[0].v_double, dspec->minimum, dspec->maximum);
565   
566   return value->data[0].v_double != oval;
567 }
568
569 static gint
570 param_double_values_cmp (GParamSpec   *pspec,
571                          const GValue *value1,
572                          const GValue *value2)
573 {
574   gdouble epsilon = G_PARAM_SPEC_DOUBLE (pspec)->epsilon;
575   
576   if (value1->data[0].v_double < value2->data[0].v_double)
577     return - (value2->data[0].v_double - value1->data[0].v_double > epsilon);
578   else
579     return value1->data[0].v_double - value2->data[0].v_double > epsilon;
580 }
581
582 static void
583 param_string_init (GParamSpec *pspec)
584 {
585   GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec);
586   
587   sspec->default_value = NULL;
588   sspec->cset_first = NULL;
589   sspec->cset_nth = NULL;
590   sspec->substitutor = '_';
591   sspec->null_fold_if_empty = FALSE;
592   sspec->ensure_non_null = FALSE;
593 }
594
595 static void
596 param_string_finalize (GParamSpec *pspec)
597 {
598   GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec);
599   GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_STRING));
600   
601   g_free (sspec->default_value);
602   g_free (sspec->cset_first);
603   g_free (sspec->cset_nth);
604   sspec->default_value = NULL;
605   sspec->cset_first = NULL;
606   sspec->cset_nth = NULL;
607   
608   parent_class->finalize (pspec);
609 }
610
611 static void
612 param_string_set_default (GParamSpec *pspec,
613                           GValue     *value)
614 {
615   value->data[0].v_pointer = g_strdup (G_PARAM_SPEC_STRING (pspec)->default_value);
616 }
617
618 static gboolean
619 param_string_validate (GParamSpec *pspec,
620                        GValue     *value)
621 {
622   GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec);
623   gchar *string = value->data[0].v_pointer;
624   guint changed = 0;
625   
626   if (string && string[0])
627     {
628       gchar *s;
629       
630       if (sspec->cset_first && !strchr (sspec->cset_first, string[0]))
631         {
632           if (value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS)
633             {
634               value->data[0].v_pointer = g_strdup (string);
635               string = value->data[0].v_pointer;
636               value->data[1].v_uint &= ~G_VALUE_NOCOPY_CONTENTS;
637             }
638           string[0] = sspec->substitutor;
639           changed++;
640         }
641       if (sspec->cset_nth)
642         for (s = string + 1; *s; s++)
643           if (!strchr (sspec->cset_nth, *s))
644             {
645               if (value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS)
646                 {
647                   value->data[0].v_pointer = g_strdup (string);
648                   s = (gchar*) value->data[0].v_pointer + (s - string);
649                   string = value->data[0].v_pointer;
650                   value->data[1].v_uint &= ~G_VALUE_NOCOPY_CONTENTS;
651                 }
652               *s = sspec->substitutor;
653               changed++;
654             }
655     }
656   if (sspec->null_fold_if_empty && string && string[0] == 0)
657     {
658       if (!(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS))
659         g_free (value->data[0].v_pointer);
660       else
661         value->data[1].v_uint &= ~G_VALUE_NOCOPY_CONTENTS;
662       value->data[0].v_pointer = NULL;
663       changed++;
664       string = value->data[0].v_pointer;
665     }
666   if (sspec->ensure_non_null && !string)
667     {
668       value->data[1].v_uint &= ~G_VALUE_NOCOPY_CONTENTS;
669       value->data[0].v_pointer = g_strdup ("");
670       changed++;
671       string = value->data[0].v_pointer;
672     }
673
674   return changed;
675 }
676
677 static gint
678 param_string_values_cmp (GParamSpec   *pspec,
679                          const GValue *value1,
680                          const GValue *value2)
681 {
682   if (!value1->data[0].v_pointer)
683     return value2->data[0].v_pointer != NULL ? -1 : 0;
684   else if (!value2->data[0].v_pointer)
685     return value1->data[0].v_pointer != NULL;
686   else
687     return strcmp (value1->data[0].v_pointer, value2->data[0].v_pointer);
688 }
689
690 static void
691 param_param_init (GParamSpec *pspec)
692 {
693   /* GParamSpecParam *spec = G_PARAM_SPEC_PARAM (pspec); */
694 }
695
696 static void
697 param_param_set_default (GParamSpec *pspec,
698                          GValue     *value)
699 {
700   value->data[0].v_pointer = NULL;
701 }
702
703 static gboolean
704 param_param_validate (GParamSpec *pspec,
705                       GValue     *value)
706 {
707   /* GParamSpecParam *spec = G_PARAM_SPEC_PARAM (pspec); */
708   GParamSpec *param = value->data[0].v_pointer;
709   guint changed = 0;
710   
711   if (param && !g_value_type_compatible (G_PARAM_SPEC_TYPE (param), G_PARAM_SPEC_VALUE_TYPE (pspec)))
712     {
713       g_param_spec_unref (param);
714       value->data[0].v_pointer = NULL;
715       changed++;
716     }
717   
718   return changed;
719 }
720
721 static void
722 param_boxed_init (GParamSpec *pspec)
723 {
724   /* GParamSpecBoxed *bspec = G_PARAM_SPEC_BOXED (pspec); */
725 }
726
727 static void
728 param_boxed_set_default (GParamSpec *pspec,
729                          GValue     *value)
730 {
731   value->data[0].v_pointer = NULL;
732 }
733
734 static gboolean
735 param_boxed_validate (GParamSpec *pspec,
736                       GValue     *value)
737 {
738   /* GParamSpecBoxed *bspec = G_PARAM_SPEC_BOXED (pspec); */
739   guint changed = 0;
740
741   /* can't do a whole lot here since we haven't even G_BOXED_TYPE() */
742   
743   return changed;
744 }
745
746 static gint
747 param_boxed_values_cmp (GParamSpec    *pspec,
748                          const GValue *value1,
749                          const GValue *value2)
750 {
751   guint8 *p1 = value1->data[0].v_pointer;
752   guint8 *p2 = value2->data[0].v_pointer;
753
754   /* not much to compare here, try to at least provide stable lesser/greater result */
755
756   return p1 < p2 ? -1 : p1 > p2;
757 }
758
759 static void
760 param_pointer_init (GParamSpec *pspec)
761 {
762   /* GParamSpecPointer *spec = G_PARAM_SPEC_POINTER (pspec); */
763 }
764
765 static void
766 param_pointer_set_default (GParamSpec *pspec,
767                            GValue     *value)
768 {
769   value->data[0].v_pointer = NULL;
770 }
771
772 static gboolean
773 param_pointer_validate (GParamSpec *pspec,
774                         GValue     *value)
775 {
776   /* GParamSpecPointer *spec = G_PARAM_SPEC_POINTER (pspec); */
777   guint changed = 0;
778   
779   return changed;
780 }
781
782 static gint
783 param_pointer_values_cmp (GParamSpec   *pspec,
784                           const GValue *value1,
785                           const GValue *value2)
786 {
787   guint8 *p1 = value1->data[0].v_pointer;
788   guint8 *p2 = value2->data[0].v_pointer;
789
790   /* not much to compare here, try to at least provide stable lesser/greater result */
791
792   return p1 < p2 ? -1 : p1 > p2;
793 }
794
795 static void
796 param_value_array_init (GParamSpec *pspec)
797 {
798   GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
799
800   aspec->element_spec = NULL;
801   aspec->fixed_n_elements = 0; /* disable */
802 }
803
804 static inline guint
805 value_array_ensure_size (GValueArray *value_array,
806                          guint        fixed_n_elements)
807 {
808   guint changed = 0;
809
810   if (fixed_n_elements)
811     {
812       while (value_array->n_values < fixed_n_elements)
813         {
814           g_value_array_append (value_array, NULL);
815           changed++;
816         }
817       while (value_array->n_values > fixed_n_elements)
818         {
819           g_value_array_remove (value_array, value_array->n_values - 1);
820           changed++;
821         }
822     }
823   return changed;
824 }
825
826 static void
827 param_value_array_finalize (GParamSpec *pspec)
828 {
829   GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
830   GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_VALUE_ARRAY));
831
832   if (aspec->element_spec)
833     {
834       g_param_spec_unref (aspec->element_spec);
835       aspec->element_spec = NULL;
836     }
837
838   parent_class->finalize (pspec);
839 }
840
841 static void
842 param_value_array_set_default (GParamSpec *pspec,
843                                GValue     *value)
844 {
845   GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
846
847   if (!value->data[0].v_pointer && aspec->fixed_n_elements)
848     value->data[0].v_pointer = g_value_array_new (aspec->fixed_n_elements);
849
850   if (value->data[0].v_pointer)
851     {
852       /* g_value_reset (value);  already done */
853       value_array_ensure_size (value->data[0].v_pointer, aspec->fixed_n_elements);
854     }
855 }
856
857 static gboolean
858 param_value_array_validate (GParamSpec *pspec,
859                             GValue     *value)
860 {
861   GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
862   GValueArray *value_array = value->data[0].v_pointer;
863   guint changed = 0;
864
865   if (!value->data[0].v_pointer && aspec->fixed_n_elements)
866     value->data[0].v_pointer = g_value_array_new (aspec->fixed_n_elements);
867
868   if (value->data[0].v_pointer)
869     {
870       /* ensure array size validity */
871       changed += value_array_ensure_size (value_array, aspec->fixed_n_elements);
872       
873       /* ensure array values validity against a present element spec */
874       if (aspec->element_spec)
875         {
876           GParamSpec *element_spec = aspec->element_spec;
877           guint i;
878           
879           for (i = 0; i < value_array->n_values; i++)
880             {
881               GValue *element = value_array->values + i;
882               
883               /* need to fixup value type, or ensure that the array value is initialized at all */
884               if (!g_value_type_compatible (G_VALUE_TYPE (element), G_PARAM_SPEC_VALUE_TYPE (element_spec)))
885                 {
886                   if (G_VALUE_TYPE (element) != 0)
887                     g_value_unset (element);
888                   g_value_init (element, G_PARAM_SPEC_VALUE_TYPE (element_spec));
889                   g_param_value_set_default (element_spec, element);
890                   changed++;
891                 }
892               /* validate array value against element_spec */
893               changed += g_param_value_validate (element_spec, element);
894             }
895         }
896     }
897
898   return changed;
899 }
900
901 static gint
902 param_value_array_values_cmp (GParamSpec   *pspec,
903                               const GValue *value1,
904                               const GValue *value2)
905 {
906   GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
907   GValueArray *value_array1 = value1->data[0].v_pointer;
908   GValueArray *value_array2 = value2->data[0].v_pointer;
909
910   if (!value_array1 || !value_array2)
911     return value_array2 ? -1 : value_array1 != value_array2;
912
913   if (value_array1->n_values != value_array2->n_values)
914     return value_array1->n_values < value_array2->n_values ? -1 : 1;
915   else if (!aspec->element_spec)
916     {
917       /* we need an element specification for comparisons, so there's not much
918        * to compare here, try to at least provide stable lesser/greater result
919        */
920       return value_array1->n_values < value_array2->n_values ? -1 : value_array1->n_values > value_array2->n_values;
921     }
922   else /* value_array1->n_values == value_array2->n_values */
923     {
924       guint i;
925
926       for (i = 0; i < value_array1->n_values; i++)
927         {
928           GValue *element1 = value_array1->values + i;
929           GValue *element2 = value_array2->values + i;
930           gint cmp;
931
932           /* need corresponding element types, provide stable result otherwise */
933           if (G_VALUE_TYPE (element1) != G_VALUE_TYPE (element2))
934             return G_VALUE_TYPE (element1) < G_VALUE_TYPE (element2) ? -1 : 1;
935           cmp = g_param_values_cmp (aspec->element_spec, element1, element2);
936           if (cmp)
937             return cmp;
938         }
939       return 0;
940     }
941 }
942
943 static void
944 param_object_init (GParamSpec *pspec)
945 {
946   /* GParamSpecObject *ospec = G_PARAM_SPEC_OBJECT (pspec); */
947 }
948
949 static void
950 param_object_set_default (GParamSpec *pspec,
951                           GValue     *value)
952 {
953   value->data[0].v_pointer = NULL;
954 }
955
956 static gboolean
957 param_object_validate (GParamSpec *pspec,
958                        GValue     *value)
959 {
960   GParamSpecObject *ospec = G_PARAM_SPEC_OBJECT (pspec);
961   GObject *object = value->data[0].v_pointer;
962   guint changed = 0;
963   
964   if (object && !g_value_type_compatible (G_OBJECT_TYPE (object), G_PARAM_SPEC_VALUE_TYPE (ospec)))
965     {
966       g_object_unref (object);
967       value->data[0].v_pointer = NULL;
968       changed++;
969     }
970   
971   return changed;
972 }
973
974 static gint
975 param_object_values_cmp (GParamSpec   *pspec,
976                          const GValue *value1,
977                          const GValue *value2)
978 {
979   guint8 *p1 = value1->data[0].v_pointer;
980   guint8 *p2 = value2->data[0].v_pointer;
981
982   /* not much to compare here, try to at least provide stable lesser/greater result */
983
984   return p1 < p2 ? -1 : p1 > p2;
985 }
986
987 static void
988 param_override_init (GParamSpec *pspec)
989 {
990   /* GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec); */
991 }
992
993 static void
994 param_override_finalize (GParamSpec *pspec)
995 {
996   GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec);
997   GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_OVERRIDE));
998   
999   if (ospec->overridden)
1000     {
1001       g_param_spec_unref (ospec->overridden);
1002       ospec->overridden = NULL;
1003     }
1004   
1005   parent_class->finalize (pspec);
1006 }
1007
1008 static void
1009 param_override_set_default (GParamSpec *pspec,
1010                             GValue     *value)
1011 {
1012   GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec);
1013
1014   g_param_value_set_default (ospec->overridden, value);
1015 }
1016
1017 static gboolean
1018 param_override_validate (GParamSpec *pspec,
1019                          GValue     *value)
1020 {
1021   GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec);
1022   
1023   return g_param_value_validate (ospec->overridden, value);
1024 }
1025
1026 static gint
1027 param_override_values_cmp (GParamSpec   *pspec,
1028                            const GValue *value1,
1029                            const GValue *value2)
1030 {
1031   GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec);
1032
1033   return g_param_values_cmp (ospec->overridden, value1, value2);
1034 }
1035
1036 static void
1037 param_gtype_init (GParamSpec *pspec)
1038 {
1039 }
1040
1041 static void
1042 param_gtype_set_default (GParamSpec *pspec,
1043                          GValue     *value)
1044 {
1045   value->data[0].v_long = G_TYPE_NONE;
1046 }
1047
1048 static gboolean
1049 param_gtype_validate (GParamSpec *pspec,
1050                       GValue     *value)
1051 {
1052   GParamSpecGType *tspec = G_PARAM_SPEC_GTYPE (pspec);
1053   GType gtype = value->data[0].v_long;
1054   guint changed = 0;
1055   
1056   if (tspec->is_a_type != G_TYPE_NONE && !g_type_is_a (gtype, tspec->is_a_type))
1057     {
1058       value->data[0].v_long = G_TYPE_NONE;
1059       changed++;
1060     }
1061   
1062   return changed;
1063 }
1064
1065 static gint
1066 param_gtype_values_cmp (GParamSpec   *pspec,
1067                         const GValue *value1,
1068                         const GValue *value2)
1069 {
1070   GType p1 = value1->data[0].v_long;
1071   GType p2 = value2->data[0].v_long;
1072
1073   /* not much to compare here, try to at least provide stable lesser/greater result */
1074
1075   return p1 < p2 ? -1 : p1 > p2;
1076 }
1077
1078 /* --- type initialization --- */
1079 GType *g_param_spec_types = NULL;
1080
1081 void
1082 g_param_spec_types_init (void)  
1083 {
1084   const guint n_types = 22;
1085   GType type, *spec_types, *spec_types_bound;
1086
1087   g_param_spec_types = g_new0 (GType, n_types);
1088   spec_types = g_param_spec_types;
1089   spec_types_bound = g_param_spec_types + n_types;
1090   
1091   /* G_TYPE_PARAM_CHAR
1092    */
1093   {
1094     static const GParamSpecTypeInfo pspec_info = {
1095       sizeof (GParamSpecChar),  /* instance_size */
1096       16,                       /* n_preallocs */
1097       param_char_init,          /* instance_init */
1098       G_TYPE_CHAR,              /* value_type */
1099       NULL,                     /* finalize */
1100       param_char_set_default,   /* value_set_default */
1101       param_char_validate,      /* value_validate */
1102       param_int_values_cmp,     /* values_cmp */
1103     };
1104     type = g_param_type_register_static (g_intern_static_string ("GParamChar"), &pspec_info);
1105     *spec_types++ = type;
1106     g_assert (type == G_TYPE_PARAM_CHAR);
1107   }
1108   
1109   /* G_TYPE_PARAM_UCHAR
1110    */
1111   {
1112     static const GParamSpecTypeInfo pspec_info = {
1113       sizeof (GParamSpecUChar), /* instance_size */
1114       16,                       /* n_preallocs */
1115       param_uchar_init,         /* instance_init */
1116       G_TYPE_UCHAR,             /* value_type */
1117       NULL,                     /* finalize */
1118       param_uchar_set_default,  /* value_set_default */
1119       param_uchar_validate,     /* value_validate */
1120       param_uint_values_cmp,    /* values_cmp */
1121     };
1122     type = g_param_type_register_static (g_intern_static_string ("GParamUChar"), &pspec_info);
1123     *spec_types++ = type;
1124     g_assert (type == G_TYPE_PARAM_UCHAR);
1125   }
1126   
1127   /* G_TYPE_PARAM_BOOLEAN
1128    */
1129   {
1130     static const GParamSpecTypeInfo pspec_info = {
1131       sizeof (GParamSpecBoolean), /* instance_size */
1132       16,                         /* n_preallocs */
1133       NULL,                       /* instance_init */
1134       G_TYPE_BOOLEAN,             /* value_type */
1135       NULL,                       /* finalize */
1136       param_boolean_set_default,  /* value_set_default */
1137       param_boolean_validate,     /* value_validate */
1138       param_int_values_cmp,       /* values_cmp */
1139     };
1140     type = g_param_type_register_static (g_intern_static_string ("GParamBoolean"), &pspec_info);
1141     *spec_types++ = type;
1142     g_assert (type == G_TYPE_PARAM_BOOLEAN);
1143   }
1144   
1145   /* G_TYPE_PARAM_INT
1146    */
1147   {
1148     static const GParamSpecTypeInfo pspec_info = {
1149       sizeof (GParamSpecInt),   /* instance_size */
1150       16,                       /* n_preallocs */
1151       param_int_init,           /* instance_init */
1152       G_TYPE_INT,               /* value_type */
1153       NULL,                     /* finalize */
1154       param_int_set_default,    /* value_set_default */
1155       param_int_validate,       /* value_validate */
1156       param_int_values_cmp,     /* values_cmp */
1157     };
1158     type = g_param_type_register_static (g_intern_static_string ("GParamInt"), &pspec_info);
1159     *spec_types++ = type;
1160     g_assert (type == G_TYPE_PARAM_INT);
1161   }
1162   
1163   /* G_TYPE_PARAM_UINT
1164    */
1165   {
1166     static const GParamSpecTypeInfo pspec_info = {
1167       sizeof (GParamSpecUInt),  /* instance_size */
1168       16,                       /* n_preallocs */
1169       param_uint_init,          /* instance_init */
1170       G_TYPE_UINT,              /* value_type */
1171       NULL,                     /* finalize */
1172       param_uint_set_default,   /* value_set_default */
1173       param_uint_validate,      /* value_validate */
1174       param_uint_values_cmp,    /* values_cmp */
1175     };
1176     type = g_param_type_register_static (g_intern_static_string ("GParamUInt"), &pspec_info);
1177     *spec_types++ = type;
1178     g_assert (type == G_TYPE_PARAM_UINT);
1179   }
1180   
1181   /* G_TYPE_PARAM_LONG
1182    */
1183   {
1184     static const GParamSpecTypeInfo pspec_info = {
1185       sizeof (GParamSpecLong),  /* instance_size */
1186       16,                       /* n_preallocs */
1187       param_long_init,          /* instance_init */
1188       G_TYPE_LONG,              /* value_type */
1189       NULL,                     /* finalize */
1190       param_long_set_default,   /* value_set_default */
1191       param_long_validate,      /* value_validate */
1192       param_long_values_cmp,    /* values_cmp */
1193     };
1194     type = g_param_type_register_static (g_intern_static_string ("GParamLong"), &pspec_info);
1195     *spec_types++ = type;
1196     g_assert (type == G_TYPE_PARAM_LONG);
1197   }
1198   
1199   /* G_TYPE_PARAM_ULONG
1200    */
1201   {
1202     static const GParamSpecTypeInfo pspec_info = {
1203       sizeof (GParamSpecULong), /* instance_size */
1204       16,                       /* n_preallocs */
1205       param_ulong_init,         /* instance_init */
1206       G_TYPE_ULONG,             /* value_type */
1207       NULL,                     /* finalize */
1208       param_ulong_set_default,  /* value_set_default */
1209       param_ulong_validate,     /* value_validate */
1210       param_ulong_values_cmp,   /* values_cmp */
1211     };
1212     type = g_param_type_register_static (g_intern_static_string ("GParamULong"), &pspec_info);
1213     *spec_types++ = type;
1214     g_assert (type == G_TYPE_PARAM_ULONG);
1215   }
1216
1217   /* G_TYPE_PARAM_INT64
1218    */
1219   {
1220     static const GParamSpecTypeInfo pspec_info = {
1221       sizeof (GParamSpecInt64),  /* instance_size */
1222       16,                       /* n_preallocs */
1223       param_int64_init,         /* instance_init */
1224       G_TYPE_INT64,             /* value_type */
1225       NULL,                     /* finalize */
1226       param_int64_set_default,  /* value_set_default */
1227       param_int64_validate,     /* value_validate */
1228       param_int64_values_cmp,   /* values_cmp */
1229     };
1230     type = g_param_type_register_static (g_intern_static_string ("GParamInt64"), &pspec_info);
1231     *spec_types++ = type;
1232     g_assert (type == G_TYPE_PARAM_INT64);
1233   }
1234   
1235   /* G_TYPE_PARAM_UINT64
1236    */
1237   {
1238     static const GParamSpecTypeInfo pspec_info = {
1239       sizeof (GParamSpecUInt64), /* instance_size */
1240       16,                       /* n_preallocs */
1241       param_uint64_init,        /* instance_init */
1242       G_TYPE_UINT64,            /* value_type */
1243       NULL,                     /* finalize */
1244       param_uint64_set_default, /* value_set_default */
1245       param_uint64_validate,    /* value_validate */
1246       param_uint64_values_cmp,  /* values_cmp */
1247     };
1248     type = g_param_type_register_static (g_intern_static_string ("GParamUInt64"), &pspec_info);
1249     *spec_types++ = type;
1250     g_assert (type == G_TYPE_PARAM_UINT64);
1251   }
1252
1253   /* G_TYPE_PARAM_UNICHAR
1254    */
1255   {
1256     static const GParamSpecTypeInfo pspec_info = {
1257       sizeof (GParamSpecUnichar), /* instance_size */
1258       16,                        /* n_preallocs */
1259       param_unichar_init,        /* instance_init */
1260       G_TYPE_UINT,               /* value_type */
1261       NULL,                      /* finalize */
1262       param_unichar_set_default, /* value_set_default */
1263       param_unichar_validate,    /* value_validate */
1264       param_unichar_values_cmp,  /* values_cmp */
1265     };
1266     type = g_param_type_register_static (g_intern_static_string ("GParamUnichar"), &pspec_info);
1267     *spec_types++ = type;
1268     g_assert (type == G_TYPE_PARAM_UNICHAR);
1269   }
1270
1271  /* G_TYPE_PARAM_ENUM
1272    */
1273   {
1274     static const GParamSpecTypeInfo pspec_info = {
1275       sizeof (GParamSpecEnum),  /* instance_size */
1276       16,                       /* n_preallocs */
1277       param_enum_init,          /* instance_init */
1278       G_TYPE_ENUM,              /* value_type */
1279       param_enum_finalize,      /* finalize */
1280       param_enum_set_default,   /* value_set_default */
1281       param_enum_validate,      /* value_validate */
1282       param_long_values_cmp,    /* values_cmp */
1283     };
1284     type = g_param_type_register_static (g_intern_static_string ("GParamEnum"), &pspec_info);
1285     *spec_types++ = type;
1286     g_assert (type == G_TYPE_PARAM_ENUM);
1287   }
1288   
1289   /* G_TYPE_PARAM_FLAGS
1290    */
1291   {
1292     static const GParamSpecTypeInfo pspec_info = {
1293       sizeof (GParamSpecFlags), /* instance_size */
1294       16,                       /* n_preallocs */
1295       param_flags_init,         /* instance_init */
1296       G_TYPE_FLAGS,             /* value_type */
1297       param_flags_finalize,     /* finalize */
1298       param_flags_set_default,  /* value_set_default */
1299       param_flags_validate,     /* value_validate */
1300       param_ulong_values_cmp,   /* values_cmp */
1301     };
1302     type = g_param_type_register_static (g_intern_static_string ("GParamFlags"), &pspec_info);
1303     *spec_types++ = type;
1304     g_assert (type == G_TYPE_PARAM_FLAGS);
1305   }
1306   
1307   /* G_TYPE_PARAM_FLOAT
1308    */
1309   {
1310     static const GParamSpecTypeInfo pspec_info = {
1311       sizeof (GParamSpecFloat), /* instance_size */
1312       16,                       /* n_preallocs */
1313       param_float_init,         /* instance_init */
1314       G_TYPE_FLOAT,             /* value_type */
1315       NULL,                     /* finalize */
1316       param_float_set_default,  /* value_set_default */
1317       param_float_validate,     /* value_validate */
1318       param_float_values_cmp,   /* values_cmp */
1319     };
1320     type = g_param_type_register_static (g_intern_static_string ("GParamFloat"), &pspec_info);
1321     *spec_types++ = type;
1322     g_assert (type == G_TYPE_PARAM_FLOAT);
1323   }
1324   
1325   /* G_TYPE_PARAM_DOUBLE
1326    */
1327   {
1328     static const GParamSpecTypeInfo pspec_info = {
1329       sizeof (GParamSpecDouble),        /* instance_size */
1330       16,                               /* n_preallocs */
1331       param_double_init,                /* instance_init */
1332       G_TYPE_DOUBLE,                    /* value_type */
1333       NULL,                             /* finalize */
1334       param_double_set_default,         /* value_set_default */
1335       param_double_validate,            /* value_validate */
1336       param_double_values_cmp,          /* values_cmp */
1337     };
1338     type = g_param_type_register_static (g_intern_static_string ("GParamDouble"), &pspec_info);
1339     *spec_types++ = type;
1340     g_assert (type == G_TYPE_PARAM_DOUBLE);
1341   }
1342   
1343   /* G_TYPE_PARAM_STRING
1344    */
1345   {
1346     static const GParamSpecTypeInfo pspec_info = {
1347       sizeof (GParamSpecString),        /* instance_size */
1348       16,                               /* n_preallocs */
1349       param_string_init,                /* instance_init */
1350       G_TYPE_STRING,                    /* value_type */
1351       param_string_finalize,            /* finalize */
1352       param_string_set_default,         /* value_set_default */
1353       param_string_validate,            /* value_validate */
1354       param_string_values_cmp,          /* values_cmp */
1355     };
1356     type = g_param_type_register_static (g_intern_static_string ("GParamString"), &pspec_info);
1357     *spec_types++ = type;
1358     g_assert (type == G_TYPE_PARAM_STRING);
1359   }
1360   
1361   /* G_TYPE_PARAM_PARAM
1362    */
1363   {
1364     static const GParamSpecTypeInfo pspec_info = {
1365       sizeof (GParamSpecParam), /* instance_size */
1366       16,                       /* n_preallocs */
1367       param_param_init,         /* instance_init */
1368       G_TYPE_PARAM,             /* value_type */
1369       NULL,                     /* finalize */
1370       param_param_set_default,  /* value_set_default */
1371       param_param_validate,     /* value_validate */
1372       param_pointer_values_cmp, /* values_cmp */
1373     };
1374     type = g_param_type_register_static (g_intern_static_string ("GParamParam"), &pspec_info);
1375     *spec_types++ = type;
1376     g_assert (type == G_TYPE_PARAM_PARAM);
1377   }
1378   
1379   /* G_TYPE_PARAM_BOXED
1380    */
1381   {
1382     static const GParamSpecTypeInfo pspec_info = {
1383       sizeof (GParamSpecBoxed), /* instance_size */
1384       4,                        /* n_preallocs */
1385       param_boxed_init,         /* instance_init */
1386       G_TYPE_BOXED,             /* value_type */
1387       NULL,                     /* finalize */
1388       param_boxed_set_default,  /* value_set_default */
1389       param_boxed_validate,     /* value_validate */
1390       param_boxed_values_cmp,   /* values_cmp */
1391     };
1392     type = g_param_type_register_static (g_intern_static_string ("GParamBoxed"), &pspec_info);
1393     *spec_types++ = type;
1394     g_assert (type == G_TYPE_PARAM_BOXED);
1395   }
1396
1397   /* G_TYPE_PARAM_POINTER
1398    */
1399   {
1400     static const GParamSpecTypeInfo pspec_info = {
1401       sizeof (GParamSpecPointer),  /* instance_size */
1402       0,                           /* n_preallocs */
1403       param_pointer_init,          /* instance_init */
1404       G_TYPE_POINTER,              /* value_type */
1405       NULL,                        /* finalize */
1406       param_pointer_set_default,   /* value_set_default */
1407       param_pointer_validate,      /* value_validate */
1408       param_pointer_values_cmp,    /* values_cmp */
1409     };
1410     type = g_param_type_register_static (g_intern_static_string ("GParamPointer"), &pspec_info);
1411     *spec_types++ = type;
1412     g_assert (type == G_TYPE_PARAM_POINTER);
1413   }
1414   
1415   /* G_TYPE_PARAM_VALUE_ARRAY
1416    */
1417   {
1418     static /* const */ GParamSpecTypeInfo pspec_info = {
1419       sizeof (GParamSpecValueArray),    /* instance_size */
1420       0,                                /* n_preallocs */
1421       param_value_array_init,           /* instance_init */
1422       0xdeadbeef,                       /* value_type, assigned further down */
1423       param_value_array_finalize,       /* finalize */
1424       param_value_array_set_default,    /* value_set_default */
1425       param_value_array_validate,       /* value_validate */
1426       param_value_array_values_cmp,     /* values_cmp */
1427     };
1428     pspec_info.value_type = G_TYPE_VALUE_ARRAY;
1429     type = g_param_type_register_static (g_intern_static_string ("GParamValueArray"), &pspec_info);
1430     *spec_types++ = type;
1431     g_assert (type == G_TYPE_PARAM_VALUE_ARRAY);
1432   }
1433
1434   /* G_TYPE_PARAM_OBJECT
1435    */
1436   {
1437     static const GParamSpecTypeInfo pspec_info = {
1438       sizeof (GParamSpecObject), /* instance_size */
1439       16,                        /* n_preallocs */
1440       param_object_init,         /* instance_init */
1441       G_TYPE_OBJECT,             /* value_type */
1442       NULL,                      /* finalize */
1443       param_object_set_default,  /* value_set_default */
1444       param_object_validate,     /* value_validate */
1445       param_object_values_cmp,   /* values_cmp */
1446     };
1447     type = g_param_type_register_static (g_intern_static_string ("GParamObject"), &pspec_info);
1448     *spec_types++ = type;
1449     g_assert (type == G_TYPE_PARAM_OBJECT);
1450   }
1451
1452   /* G_TYPE_PARAM_OVERRIDE
1453    */
1454   {
1455     static const GParamSpecTypeInfo pspec_info = {
1456       sizeof (GParamSpecOverride), /* instance_size */
1457       16,                        /* n_preallocs */
1458       param_override_init,       /* instance_init */
1459       G_TYPE_NONE,               /* value_type */
1460       param_override_finalize,   /* finalize */
1461       param_override_set_default, /* value_set_default */
1462       param_override_validate,    /* value_validate */
1463       param_override_values_cmp,  /* values_cmp */
1464     };
1465     type = g_param_type_register_static (g_intern_static_string ("GParamOverride"), &pspec_info);
1466     *spec_types++ = type;
1467     g_assert (type == G_TYPE_PARAM_OVERRIDE);
1468   }
1469
1470   /* G_TYPE_PARAM_GTYPE
1471    */
1472   {
1473     GType value_type = G_TYPE_GTYPE;
1474     GParamSpecTypeInfo pspec_info = {
1475       sizeof (GParamSpecGType), /* instance_size */
1476       0,                        /* n_preallocs */
1477       param_gtype_init,         /* instance_init */
1478       value_type,               /* value_type */
1479       NULL,                     /* finalize */
1480       param_gtype_set_default,  /* value_set_default */
1481       param_gtype_validate,     /* value_validate */
1482       param_gtype_values_cmp,   /* values_cmp */
1483     };
1484     type = g_param_type_register_static (g_intern_static_string ("GParamGType"), &pspec_info);
1485     *spec_types++ = type;
1486     g_assert (type == G_TYPE_PARAM_GTYPE);
1487   }
1488
1489   g_assert (spec_types == spec_types_bound);
1490 }
1491
1492 /* --- GParamSpec initialization --- */
1493
1494 GParamSpec*
1495 g_param_spec_char (const gchar *name,
1496                    const gchar *nick,
1497                    const gchar *blurb,
1498                    gint8        minimum,
1499                    gint8        maximum,
1500                    gint8        default_value,
1501                    GParamFlags  flags)
1502 {
1503   GParamSpecChar *cspec;
1504
1505   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1506
1507   cspec = g_param_spec_internal (G_TYPE_PARAM_CHAR,
1508                                  name,
1509                                  nick,
1510                                  blurb,
1511                                  flags);
1512   
1513   cspec->minimum = minimum;
1514   cspec->maximum = maximum;
1515   cspec->default_value = default_value;
1516   
1517   return G_PARAM_SPEC (cspec);
1518 }
1519
1520 GParamSpec*
1521 g_param_spec_uchar (const gchar *name,
1522                     const gchar *nick,
1523                     const gchar *blurb,
1524                     guint8       minimum,
1525                     guint8       maximum,
1526                     guint8       default_value,
1527                     GParamFlags  flags)
1528 {
1529   GParamSpecUChar *uspec;
1530
1531   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1532
1533   uspec = g_param_spec_internal (G_TYPE_PARAM_UCHAR,
1534                                  name,
1535                                  nick,
1536                                  blurb,
1537                                  flags);
1538   
1539   uspec->minimum = minimum;
1540   uspec->maximum = maximum;
1541   uspec->default_value = default_value;
1542   
1543   return G_PARAM_SPEC (uspec);
1544 }
1545
1546 GParamSpec*
1547 g_param_spec_boolean (const gchar *name,
1548                       const gchar *nick,
1549                       const gchar *blurb,
1550                       gboolean     default_value,
1551                       GParamFlags  flags)
1552 {
1553   GParamSpecBoolean *bspec;
1554
1555   g_return_val_if_fail (default_value == TRUE || default_value == FALSE, NULL);
1556
1557   bspec = g_param_spec_internal (G_TYPE_PARAM_BOOLEAN,
1558                                  name,
1559                                  nick,
1560                                  blurb,
1561                                  flags);
1562   
1563   bspec->default_value = default_value;
1564   
1565   return G_PARAM_SPEC (bspec);
1566 }
1567
1568 GParamSpec*
1569 g_param_spec_int (const gchar *name,
1570                   const gchar *nick,
1571                   const gchar *blurb,
1572                   gint         minimum,
1573                   gint         maximum,
1574                   gint         default_value,
1575                   GParamFlags  flags)
1576 {
1577   GParamSpecInt *ispec;
1578
1579   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1580
1581   ispec = g_param_spec_internal (G_TYPE_PARAM_INT,
1582                                  name,
1583                                  nick,
1584                                  blurb,
1585                                  flags);
1586   
1587   ispec->minimum = minimum;
1588   ispec->maximum = maximum;
1589   ispec->default_value = default_value;
1590   
1591   return G_PARAM_SPEC (ispec);
1592 }
1593
1594 GParamSpec*
1595 g_param_spec_uint (const gchar *name,
1596                    const gchar *nick,
1597                    const gchar *blurb,
1598                    guint        minimum,
1599                    guint        maximum,
1600                    guint        default_value,
1601                    GParamFlags  flags)
1602 {
1603   GParamSpecUInt *uspec;
1604
1605   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1606
1607   uspec = g_param_spec_internal (G_TYPE_PARAM_UINT,
1608                                  name,
1609                                  nick,
1610                                  blurb,
1611                                  flags);
1612   
1613   uspec->minimum = minimum;
1614   uspec->maximum = maximum;
1615   uspec->default_value = default_value;
1616   
1617   return G_PARAM_SPEC (uspec);
1618 }
1619
1620 GParamSpec*
1621 g_param_spec_long (const gchar *name,
1622                    const gchar *nick,
1623                    const gchar *blurb,
1624                    glong        minimum,
1625                    glong        maximum,
1626                    glong        default_value,
1627                    GParamFlags  flags)
1628 {
1629   GParamSpecLong *lspec;
1630
1631   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1632
1633   lspec = g_param_spec_internal (G_TYPE_PARAM_LONG,
1634                                  name,
1635                                  nick,
1636                                  blurb,
1637                                  flags);
1638   
1639   lspec->minimum = minimum;
1640   lspec->maximum = maximum;
1641   lspec->default_value = default_value;
1642   
1643   return G_PARAM_SPEC (lspec);
1644 }
1645
1646 GParamSpec*
1647 g_param_spec_ulong (const gchar *name,
1648                     const gchar *nick,
1649                     const gchar *blurb,
1650                     gulong       minimum,
1651                     gulong       maximum,
1652                     gulong       default_value,
1653                     GParamFlags  flags)
1654 {
1655   GParamSpecULong *uspec;
1656
1657   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1658
1659   uspec = g_param_spec_internal (G_TYPE_PARAM_ULONG,
1660                                  name,
1661                                  nick,
1662                                  blurb,
1663                                  flags);
1664   
1665   uspec->minimum = minimum;
1666   uspec->maximum = maximum;
1667   uspec->default_value = default_value;
1668   
1669   return G_PARAM_SPEC (uspec);
1670 }
1671
1672 GParamSpec*
1673 g_param_spec_int64 (const gchar *name,
1674                     const gchar *nick,
1675                     const gchar *blurb,
1676                     gint64       minimum,
1677                     gint64       maximum,
1678                     gint64       default_value,
1679                     GParamFlags  flags)
1680 {
1681   GParamSpecInt64 *lspec;
1682   
1683   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1684
1685   lspec = g_param_spec_internal (G_TYPE_PARAM_INT64,
1686                                  name,
1687                                  nick,
1688                                  blurb,
1689                                  flags);
1690   
1691   lspec->minimum = minimum;
1692   lspec->maximum = maximum;
1693   lspec->default_value = default_value;
1694   
1695   return G_PARAM_SPEC (lspec);
1696 }
1697
1698 GParamSpec*
1699 g_param_spec_uint64 (const gchar *name,
1700                      const gchar *nick,
1701                      const gchar *blurb,
1702                      guint64      minimum,
1703                      guint64      maximum,
1704                      guint64      default_value,
1705                      GParamFlags  flags)
1706 {
1707   GParamSpecUInt64 *uspec;
1708   
1709   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1710   
1711   uspec = g_param_spec_internal (G_TYPE_PARAM_UINT64,
1712                                  name,
1713                                  nick,
1714                                  blurb,
1715                                  flags);
1716   
1717   uspec->minimum = minimum;
1718   uspec->maximum = maximum;
1719   uspec->default_value = default_value;
1720   
1721   return G_PARAM_SPEC (uspec);
1722 }
1723
1724 GParamSpec*
1725 g_param_spec_unichar (const gchar *name,
1726                       const gchar *nick,
1727                       const gchar *blurb,
1728                       gunichar     default_value,
1729                       GParamFlags  flags)
1730 {
1731   GParamSpecUnichar *uspec;
1732
1733   uspec = g_param_spec_internal (G_TYPE_PARAM_UNICHAR,
1734                                  name,
1735                                  nick,
1736                                  blurb,
1737                                  flags);
1738   
1739   uspec->default_value = default_value;
1740   
1741   return G_PARAM_SPEC (uspec);
1742 }
1743
1744 GParamSpec*
1745 g_param_spec_enum (const gchar *name,
1746                    const gchar *nick,
1747                    const gchar *blurb,
1748                    GType        enum_type,
1749                    gint         default_value,
1750                    GParamFlags  flags)
1751 {
1752   GParamSpecEnum *espec;
1753   GEnumClass *enum_class;
1754   
1755   g_return_val_if_fail (G_TYPE_IS_ENUM (enum_type), NULL);
1756
1757   enum_class = g_type_class_ref (enum_type);
1758
1759   g_return_val_if_fail (g_enum_get_value (enum_class, default_value) != NULL, NULL);
1760   
1761   espec = g_param_spec_internal (G_TYPE_PARAM_ENUM,
1762                                  name,
1763                                  nick,
1764                                  blurb,
1765                                  flags);
1766   
1767   espec->enum_class = enum_class;
1768   espec->default_value = default_value;
1769   G_PARAM_SPEC (espec)->value_type = enum_type;
1770   
1771   return G_PARAM_SPEC (espec);
1772 }
1773
1774 GParamSpec*
1775 g_param_spec_flags (const gchar *name,
1776                     const gchar *nick,
1777                     const gchar *blurb,
1778                     GType        flags_type,
1779                     guint        default_value,
1780                     GParamFlags  flags)
1781 {
1782   GParamSpecFlags *fspec;
1783   GFlagsClass *flags_class;
1784   
1785   g_return_val_if_fail (G_TYPE_IS_FLAGS (flags_type), NULL);
1786
1787   flags_class = g_type_class_ref (flags_type);
1788
1789   g_return_val_if_fail ((default_value & flags_class->mask) == default_value, NULL);
1790   
1791   fspec = g_param_spec_internal (G_TYPE_PARAM_FLAGS,
1792                                  name,
1793                                  nick,
1794                                  blurb,
1795                                  flags);
1796   
1797   fspec->flags_class = flags_class;
1798   fspec->default_value = default_value;
1799   G_PARAM_SPEC (fspec)->value_type = flags_type;
1800   
1801   return G_PARAM_SPEC (fspec);
1802 }
1803
1804 GParamSpec*
1805 g_param_spec_float (const gchar *name,
1806                     const gchar *nick,
1807                     const gchar *blurb,
1808                     gfloat       minimum,
1809                     gfloat       maximum,
1810                     gfloat       default_value,
1811                     GParamFlags  flags)
1812 {
1813   GParamSpecFloat *fspec;
1814
1815   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1816
1817   fspec = g_param_spec_internal (G_TYPE_PARAM_FLOAT,
1818                                  name,
1819                                  nick,
1820                                  blurb,
1821                                  flags);
1822   
1823   fspec->minimum = minimum;
1824   fspec->maximum = maximum;
1825   fspec->default_value = default_value;
1826   
1827   return G_PARAM_SPEC (fspec);
1828 }
1829
1830 GParamSpec*
1831 g_param_spec_double (const gchar *name,
1832                      const gchar *nick,
1833                      const gchar *blurb,
1834                      gdouble      minimum,
1835                      gdouble      maximum,
1836                      gdouble      default_value,
1837                      GParamFlags  flags)
1838 {
1839   GParamSpecDouble *dspec;
1840
1841   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1842
1843   dspec = g_param_spec_internal (G_TYPE_PARAM_DOUBLE,
1844                                  name,
1845                                  nick,
1846                                  blurb,
1847                                  flags);
1848   
1849   dspec->minimum = minimum;
1850   dspec->maximum = maximum;
1851   dspec->default_value = default_value;
1852   
1853   return G_PARAM_SPEC (dspec);
1854 }
1855
1856 GParamSpec*
1857 g_param_spec_string (const gchar *name,
1858                      const gchar *nick,
1859                      const gchar *blurb,
1860                      const gchar *default_value,
1861                      GParamFlags  flags)
1862 {
1863   GParamSpecString *sspec = g_param_spec_internal (G_TYPE_PARAM_STRING,
1864                                                    name,
1865                                                    nick,
1866                                                    blurb,
1867                                                    flags);
1868   g_free (sspec->default_value);
1869   sspec->default_value = g_strdup (default_value);
1870   
1871   return G_PARAM_SPEC (sspec);
1872 }
1873
1874 GParamSpec*
1875 g_param_spec_param (const gchar *name,
1876                     const gchar *nick,
1877                     const gchar *blurb,
1878                     GType        param_type,
1879                     GParamFlags  flags)
1880 {
1881   GParamSpecParam *pspec;
1882   
1883   g_return_val_if_fail (G_TYPE_IS_PARAM (param_type), NULL);
1884   
1885   pspec = g_param_spec_internal (G_TYPE_PARAM_PARAM,
1886                                  name,
1887                                  nick,
1888                                  blurb,
1889                                  flags);
1890   G_PARAM_SPEC (pspec)->value_type = param_type;
1891   
1892   return G_PARAM_SPEC (pspec);
1893 }
1894
1895 GParamSpec*
1896 g_param_spec_boxed (const gchar *name,
1897                     const gchar *nick,
1898                     const gchar *blurb,
1899                     GType        boxed_type,
1900                     GParamFlags  flags)
1901 {
1902   GParamSpecBoxed *bspec;
1903   
1904   g_return_val_if_fail (G_TYPE_IS_BOXED (boxed_type), NULL);
1905   g_return_val_if_fail (G_TYPE_IS_VALUE_TYPE (boxed_type), NULL);
1906   
1907   bspec = g_param_spec_internal (G_TYPE_PARAM_BOXED,
1908                                  name,
1909                                  nick,
1910                                  blurb,
1911                                  flags);
1912   G_PARAM_SPEC (bspec)->value_type = boxed_type;
1913   
1914   return G_PARAM_SPEC (bspec);
1915 }
1916
1917 GParamSpec*
1918 g_param_spec_pointer (const gchar *name,
1919                       const gchar *nick,
1920                       const gchar *blurb,
1921                       GParamFlags  flags)
1922 {
1923   GParamSpecPointer *pspec;
1924   
1925   pspec = g_param_spec_internal (G_TYPE_PARAM_POINTER,
1926                                  name,
1927                                  nick,
1928                                  blurb,
1929                                  flags);
1930   return G_PARAM_SPEC (pspec);
1931 }
1932
1933 GParamSpec*
1934 g_param_spec_gtype (const gchar *name,
1935                     const gchar *nick,
1936                     const gchar *blurb,
1937                     GType        is_a_type,
1938                     GParamFlags  flags)
1939 {
1940   GParamSpecGType *tspec;
1941   
1942   tspec = g_param_spec_internal (G_TYPE_PARAM_GTYPE,
1943                                  name,
1944                                  nick,
1945                                  blurb,
1946                                  flags);
1947
1948   tspec->is_a_type = is_a_type;
1949
1950   return G_PARAM_SPEC (tspec);
1951 }
1952
1953 GParamSpec*
1954 g_param_spec_value_array (const gchar *name,
1955                           const gchar *nick,
1956                           const gchar *blurb,
1957                           GParamSpec  *element_spec,
1958                           GParamFlags  flags)
1959 {
1960   GParamSpecValueArray *aspec;
1961   
1962   if (element_spec)
1963     g_return_val_if_fail (G_IS_PARAM_SPEC (element_spec), NULL);
1964   
1965   aspec = g_param_spec_internal (G_TYPE_PARAM_VALUE_ARRAY,
1966                                  name,
1967                                  nick,
1968                                  blurb,
1969                                  flags);
1970   if (element_spec)
1971     {
1972       aspec->element_spec = g_param_spec_ref (element_spec);
1973       g_param_spec_sink (element_spec);
1974     }
1975
1976   return G_PARAM_SPEC (aspec);
1977 }
1978
1979 GParamSpec*
1980 g_param_spec_object (const gchar *name,
1981                      const gchar *nick,
1982                      const gchar *blurb,
1983                      GType        object_type,
1984                      GParamFlags  flags)
1985 {
1986   GParamSpecObject *ospec;
1987   
1988   g_return_val_if_fail (g_type_is_a (object_type, G_TYPE_OBJECT), NULL);
1989   
1990   ospec = g_param_spec_internal (G_TYPE_PARAM_OBJECT,
1991                                  name,
1992                                  nick,
1993                                  blurb,
1994                                  flags);
1995   G_PARAM_SPEC (ospec)->value_type = object_type;
1996   
1997   return G_PARAM_SPEC (ospec);
1998 }
1999
2000 GParamSpec*
2001 g_param_spec_override (const gchar *name,
2002                        GParamSpec  *overridden)
2003 {
2004   GParamSpec *pspec;
2005   
2006   g_return_val_if_fail (name != NULL, NULL);
2007   g_return_val_if_fail (G_IS_PARAM_SPEC (overridden), NULL);
2008   
2009   /* Dereference further redirections for property that was passed in
2010    */
2011   while (TRUE)
2012     {
2013       GParamSpec *indirect = g_param_spec_get_redirect_target (overridden);
2014       if (indirect)
2015         overridden = indirect;
2016       else
2017         break;
2018     }
2019
2020   pspec = g_param_spec_internal (G_TYPE_PARAM_OVERRIDE,
2021                                  name, NULL, NULL,
2022                                  overridden->flags);
2023   
2024   pspec->value_type = G_PARAM_SPEC_VALUE_TYPE (overridden);
2025   G_PARAM_SPEC_OVERRIDE (pspec)->overridden = g_param_spec_ref (overridden);
2026
2027   return pspec;
2028 }
2029
2030 #define __G_PARAMSPECS_C__
2031 #include "gobjectaliasdef.c"