Use <malloc.h> also with Digital Mars compiler on Win32. (#346808, Serhat
[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           string[0] = sspec->substitutor;
633           changed++;
634         }
635       if (sspec->cset_nth)
636         for (s = string + 1; *s; s++)
637           if (!strchr (sspec->cset_nth, *s))
638             {
639               *s = sspec->substitutor;
640               changed++;
641             }
642     }
643   if (sspec->null_fold_if_empty && string && string[0] == 0)
644     {
645       g_free (value->data[0].v_pointer);
646       value->data[0].v_pointer = NULL;
647       changed++;
648       string = value->data[0].v_pointer;
649     }
650   if (sspec->ensure_non_null && !string)
651     {
652       value->data[0].v_pointer = g_strdup ("");
653       changed++;
654       string = value->data[0].v_pointer;
655     }
656   
657   return changed;
658 }
659
660 static gint
661 param_string_values_cmp (GParamSpec   *pspec,
662                          const GValue *value1,
663                          const GValue *value2)
664 {
665   if (!value1->data[0].v_pointer)
666     return value2->data[0].v_pointer != NULL ? -1 : 0;
667   else if (!value2->data[0].v_pointer)
668     return value1->data[0].v_pointer != NULL;
669   else
670     return strcmp (value1->data[0].v_pointer, value2->data[0].v_pointer);
671 }
672
673 static void
674 param_param_init (GParamSpec *pspec)
675 {
676   /* GParamSpecParam *spec = G_PARAM_SPEC_PARAM (pspec); */
677 }
678
679 static void
680 param_param_set_default (GParamSpec *pspec,
681                          GValue     *value)
682 {
683   value->data[0].v_pointer = NULL;
684 }
685
686 static gboolean
687 param_param_validate (GParamSpec *pspec,
688                       GValue     *value)
689 {
690   /* GParamSpecParam *spec = G_PARAM_SPEC_PARAM (pspec); */
691   GParamSpec *param = value->data[0].v_pointer;
692   guint changed = 0;
693   
694   if (param && !g_value_type_compatible (G_PARAM_SPEC_TYPE (param), G_PARAM_SPEC_VALUE_TYPE (pspec)))
695     {
696       g_param_spec_unref (param);
697       value->data[0].v_pointer = NULL;
698       changed++;
699     }
700   
701   return changed;
702 }
703
704 static void
705 param_boxed_init (GParamSpec *pspec)
706 {
707   /* GParamSpecBoxed *bspec = G_PARAM_SPEC_BOXED (pspec); */
708 }
709
710 static void
711 param_boxed_set_default (GParamSpec *pspec,
712                          GValue     *value)
713 {
714   value->data[0].v_pointer = NULL;
715 }
716
717 static gboolean
718 param_boxed_validate (GParamSpec *pspec,
719                       GValue     *value)
720 {
721   /* GParamSpecBoxed *bspec = G_PARAM_SPEC_BOXED (pspec); */
722   guint changed = 0;
723
724   /* can't do a whole lot here since we haven't even G_BOXED_TYPE() */
725   
726   return changed;
727 }
728
729 static gint
730 param_boxed_values_cmp (GParamSpec    *pspec,
731                          const GValue *value1,
732                          const GValue *value2)
733 {
734   guint8 *p1 = value1->data[0].v_pointer;
735   guint8 *p2 = value2->data[0].v_pointer;
736
737   /* not much to compare here, try to at least provide stable lesser/greater result */
738
739   return p1 < p2 ? -1 : p1 > p2;
740 }
741
742 static void
743 param_pointer_init (GParamSpec *pspec)
744 {
745   /* GParamSpecPointer *spec = G_PARAM_SPEC_POINTER (pspec); */
746 }
747
748 static void
749 param_pointer_set_default (GParamSpec *pspec,
750                            GValue     *value)
751 {
752   value->data[0].v_pointer = NULL;
753 }
754
755 static gboolean
756 param_pointer_validate (GParamSpec *pspec,
757                         GValue     *value)
758 {
759   /* GParamSpecPointer *spec = G_PARAM_SPEC_POINTER (pspec); */
760   guint changed = 0;
761   
762   return changed;
763 }
764
765 static gint
766 param_pointer_values_cmp (GParamSpec   *pspec,
767                           const GValue *value1,
768                           const GValue *value2)
769 {
770   guint8 *p1 = value1->data[0].v_pointer;
771   guint8 *p2 = value2->data[0].v_pointer;
772
773   /* not much to compare here, try to at least provide stable lesser/greater result */
774
775   return p1 < p2 ? -1 : p1 > p2;
776 }
777
778 static void
779 param_value_array_init (GParamSpec *pspec)
780 {
781   GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
782
783   aspec->element_spec = NULL;
784   aspec->fixed_n_elements = 0; /* disable */
785 }
786
787 static inline guint
788 value_array_ensure_size (GValueArray *value_array,
789                          guint        fixed_n_elements)
790 {
791   guint changed = 0;
792
793   if (fixed_n_elements)
794     {
795       while (value_array->n_values < fixed_n_elements)
796         {
797           g_value_array_append (value_array, NULL);
798           changed++;
799         }
800       while (value_array->n_values > fixed_n_elements)
801         {
802           g_value_array_remove (value_array, value_array->n_values - 1);
803           changed++;
804         }
805     }
806   return changed;
807 }
808
809 static void
810 param_value_array_finalize (GParamSpec *pspec)
811 {
812   GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
813   GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_VALUE_ARRAY));
814
815   if (aspec->element_spec)
816     {
817       g_param_spec_unref (aspec->element_spec);
818       aspec->element_spec = NULL;
819     }
820
821   parent_class->finalize (pspec);
822 }
823
824 static void
825 param_value_array_set_default (GParamSpec *pspec,
826                                GValue     *value)
827 {
828   GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
829
830   if (!value->data[0].v_pointer && aspec->fixed_n_elements)
831     value->data[0].v_pointer = g_value_array_new (aspec->fixed_n_elements);
832
833   if (value->data[0].v_pointer)
834     {
835       /* g_value_reset (value);  already done */
836       value_array_ensure_size (value->data[0].v_pointer, aspec->fixed_n_elements);
837     }
838 }
839
840 static gboolean
841 param_value_array_validate (GParamSpec *pspec,
842                             GValue     *value)
843 {
844   GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
845   GValueArray *value_array = value->data[0].v_pointer;
846   guint changed = 0;
847
848   if (!value->data[0].v_pointer && aspec->fixed_n_elements)
849     value->data[0].v_pointer = g_value_array_new (aspec->fixed_n_elements);
850
851   if (value->data[0].v_pointer)
852     {
853       /* ensure array size validity */
854       changed += value_array_ensure_size (value_array, aspec->fixed_n_elements);
855       
856       /* ensure array values validity against a present element spec */
857       if (aspec->element_spec)
858         {
859           GParamSpec *element_spec = aspec->element_spec;
860           guint i;
861           
862           for (i = 0; i < value_array->n_values; i++)
863             {
864               GValue *element = value_array->values + i;
865               
866               /* need to fixup value type, or ensure that the array value is initialized at all */
867               if (!g_value_type_compatible (G_VALUE_TYPE (element), G_PARAM_SPEC_VALUE_TYPE (element_spec)))
868                 {
869                   if (G_VALUE_TYPE (element) != 0)
870                     g_value_unset (element);
871                   g_value_init (element, G_PARAM_SPEC_VALUE_TYPE (element_spec));
872                   g_param_value_set_default (element_spec, element);
873                   changed++;
874                 }
875               /* validate array value against element_spec */
876               changed += g_param_value_validate (element_spec, element);
877             }
878         }
879     }
880
881   return changed;
882 }
883
884 static gint
885 param_value_array_values_cmp (GParamSpec   *pspec,
886                               const GValue *value1,
887                               const GValue *value2)
888 {
889   GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
890   GValueArray *value_array1 = value1->data[0].v_pointer;
891   GValueArray *value_array2 = value2->data[0].v_pointer;
892
893   if (!value_array1 || !value_array2)
894     return value_array2 ? -1 : value_array1 != value_array2;
895
896   if (value_array1->n_values != value_array2->n_values)
897     return value_array1->n_values < value_array2->n_values ? -1 : 1;
898   else if (!aspec->element_spec)
899     {
900       /* we need an element specification for comparisons, so there's not much
901        * to compare here, try to at least provide stable lesser/greater result
902        */
903       return value_array1->n_values < value_array2->n_values ? -1 : value_array1->n_values > value_array2->n_values;
904     }
905   else /* value_array1->n_values == value_array2->n_values */
906     {
907       guint i;
908
909       for (i = 0; i < value_array1->n_values; i++)
910         {
911           GValue *element1 = value_array1->values + i;
912           GValue *element2 = value_array2->values + i;
913           gint cmp;
914
915           /* need corresponding element types, provide stable result otherwise */
916           if (G_VALUE_TYPE (element1) != G_VALUE_TYPE (element2))
917             return G_VALUE_TYPE (element1) < G_VALUE_TYPE (element2) ? -1 : 1;
918           cmp = g_param_values_cmp (aspec->element_spec, element1, element2);
919           if (cmp)
920             return cmp;
921         }
922       return 0;
923     }
924 }
925
926 static void
927 param_object_init (GParamSpec *pspec)
928 {
929   /* GParamSpecObject *ospec = G_PARAM_SPEC_OBJECT (pspec); */
930 }
931
932 static void
933 param_object_set_default (GParamSpec *pspec,
934                           GValue     *value)
935 {
936   value->data[0].v_pointer = NULL;
937 }
938
939 static gboolean
940 param_object_validate (GParamSpec *pspec,
941                        GValue     *value)
942 {
943   GParamSpecObject *ospec = G_PARAM_SPEC_OBJECT (pspec);
944   GObject *object = value->data[0].v_pointer;
945   guint changed = 0;
946   
947   if (object && !g_value_type_compatible (G_OBJECT_TYPE (object), G_PARAM_SPEC_VALUE_TYPE (ospec)))
948     {
949       g_object_unref (object);
950       value->data[0].v_pointer = NULL;
951       changed++;
952     }
953   
954   return changed;
955 }
956
957 static gint
958 param_object_values_cmp (GParamSpec   *pspec,
959                          const GValue *value1,
960                          const GValue *value2)
961 {
962   guint8 *p1 = value1->data[0].v_pointer;
963   guint8 *p2 = value2->data[0].v_pointer;
964
965   /* not much to compare here, try to at least provide stable lesser/greater result */
966
967   return p1 < p2 ? -1 : p1 > p2;
968 }
969
970 static void
971 param_override_init (GParamSpec *pspec)
972 {
973   /* GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec); */
974 }
975
976 static void
977 param_override_finalize (GParamSpec *pspec)
978 {
979   GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec);
980   GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_OVERRIDE));
981   
982   if (ospec->overridden)
983     {
984       g_param_spec_unref (ospec->overridden);
985       ospec->overridden = NULL;
986     }
987   
988   parent_class->finalize (pspec);
989 }
990
991 static void
992 param_override_set_default (GParamSpec *pspec,
993                             GValue     *value)
994 {
995   GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec);
996
997   g_param_value_set_default (ospec->overridden, value);
998 }
999
1000 static gboolean
1001 param_override_validate (GParamSpec *pspec,
1002                          GValue     *value)
1003 {
1004   GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec);
1005   
1006   return g_param_value_validate (ospec->overridden, value);
1007 }
1008
1009 static gint
1010 param_override_values_cmp (GParamSpec   *pspec,
1011                            const GValue *value1,
1012                            const GValue *value2)
1013 {
1014   GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec);
1015
1016   return g_param_values_cmp (ospec->overridden, value1, value2);
1017 }
1018
1019 static void
1020 param_gtype_init (GParamSpec *pspec)
1021 {
1022 }
1023
1024 static void
1025 param_gtype_set_default (GParamSpec *pspec,
1026                          GValue     *value)
1027 {
1028   value->data[0].v_long = G_TYPE_NONE;
1029 }
1030
1031 static gboolean
1032 param_gtype_validate (GParamSpec *pspec,
1033                       GValue     *value)
1034 {
1035   GParamSpecGType *tspec = G_PARAM_SPEC_GTYPE (pspec);
1036   GType gtype = value->data[0].v_long;
1037   guint changed = 0;
1038   
1039   if (tspec->is_a_type != G_TYPE_NONE && !g_type_is_a (gtype, tspec->is_a_type))
1040     {
1041       value->data[0].v_long = G_TYPE_NONE;
1042       changed++;
1043     }
1044   
1045   return changed;
1046 }
1047
1048 static gint
1049 param_gtype_values_cmp (GParamSpec   *pspec,
1050                         const GValue *value1,
1051                         const GValue *value2)
1052 {
1053   GType p1 = value1->data[0].v_long;
1054   GType p2 = value2->data[0].v_long;
1055
1056   /* not much to compare here, try to at least provide stable lesser/greater result */
1057
1058   return p1 < p2 ? -1 : p1 > p2;
1059 }
1060
1061 /* --- type initialization --- */
1062 GType *g_param_spec_types = NULL;
1063
1064 void
1065 g_param_spec_types_init (void)  
1066 {
1067   const guint n_types = 22;
1068   GType type, *spec_types, *spec_types_bound;
1069
1070   g_param_spec_types = g_new0 (GType, n_types);
1071   spec_types = g_param_spec_types;
1072   spec_types_bound = g_param_spec_types + n_types;
1073   
1074   /* G_TYPE_PARAM_CHAR
1075    */
1076   {
1077     static const GParamSpecTypeInfo pspec_info = {
1078       sizeof (GParamSpecChar),  /* instance_size */
1079       16,                       /* n_preallocs */
1080       param_char_init,          /* instance_init */
1081       G_TYPE_CHAR,              /* value_type */
1082       NULL,                     /* finalize */
1083       param_char_set_default,   /* value_set_default */
1084       param_char_validate,      /* value_validate */
1085       param_int_values_cmp,     /* values_cmp */
1086     };
1087     type = g_param_type_register_static (g_intern_static_string ("GParamChar"), &pspec_info);
1088     *spec_types++ = type;
1089     g_assert (type == G_TYPE_PARAM_CHAR);
1090   }
1091   
1092   /* G_TYPE_PARAM_UCHAR
1093    */
1094   {
1095     static const GParamSpecTypeInfo pspec_info = {
1096       sizeof (GParamSpecUChar), /* instance_size */
1097       16,                       /* n_preallocs */
1098       param_uchar_init,         /* instance_init */
1099       G_TYPE_UCHAR,             /* value_type */
1100       NULL,                     /* finalize */
1101       param_uchar_set_default,  /* value_set_default */
1102       param_uchar_validate,     /* value_validate */
1103       param_uint_values_cmp,    /* values_cmp */
1104     };
1105     type = g_param_type_register_static (g_intern_static_string ("GParamUChar"), &pspec_info);
1106     *spec_types++ = type;
1107     g_assert (type == G_TYPE_PARAM_UCHAR);
1108   }
1109   
1110   /* G_TYPE_PARAM_BOOLEAN
1111    */
1112   {
1113     static const GParamSpecTypeInfo pspec_info = {
1114       sizeof (GParamSpecBoolean), /* instance_size */
1115       16,                         /* n_preallocs */
1116       NULL,                       /* instance_init */
1117       G_TYPE_BOOLEAN,             /* value_type */
1118       NULL,                       /* finalize */
1119       param_boolean_set_default,  /* value_set_default */
1120       param_boolean_validate,     /* value_validate */
1121       param_int_values_cmp,       /* values_cmp */
1122     };
1123     type = g_param_type_register_static (g_intern_static_string ("GParamBoolean"), &pspec_info);
1124     *spec_types++ = type;
1125     g_assert (type == G_TYPE_PARAM_BOOLEAN);
1126   }
1127   
1128   /* G_TYPE_PARAM_INT
1129    */
1130   {
1131     static const GParamSpecTypeInfo pspec_info = {
1132       sizeof (GParamSpecInt),   /* instance_size */
1133       16,                       /* n_preallocs */
1134       param_int_init,           /* instance_init */
1135       G_TYPE_INT,               /* value_type */
1136       NULL,                     /* finalize */
1137       param_int_set_default,    /* value_set_default */
1138       param_int_validate,       /* value_validate */
1139       param_int_values_cmp,     /* values_cmp */
1140     };
1141     type = g_param_type_register_static (g_intern_static_string ("GParamInt"), &pspec_info);
1142     *spec_types++ = type;
1143     g_assert (type == G_TYPE_PARAM_INT);
1144   }
1145   
1146   /* G_TYPE_PARAM_UINT
1147    */
1148   {
1149     static const GParamSpecTypeInfo pspec_info = {
1150       sizeof (GParamSpecUInt),  /* instance_size */
1151       16,                       /* n_preallocs */
1152       param_uint_init,          /* instance_init */
1153       G_TYPE_UINT,              /* value_type */
1154       NULL,                     /* finalize */
1155       param_uint_set_default,   /* value_set_default */
1156       param_uint_validate,      /* value_validate */
1157       param_uint_values_cmp,    /* values_cmp */
1158     };
1159     type = g_param_type_register_static (g_intern_static_string ("GParamUInt"), &pspec_info);
1160     *spec_types++ = type;
1161     g_assert (type == G_TYPE_PARAM_UINT);
1162   }
1163   
1164   /* G_TYPE_PARAM_LONG
1165    */
1166   {
1167     static const GParamSpecTypeInfo pspec_info = {
1168       sizeof (GParamSpecLong),  /* instance_size */
1169       16,                       /* n_preallocs */
1170       param_long_init,          /* instance_init */
1171       G_TYPE_LONG,              /* value_type */
1172       NULL,                     /* finalize */
1173       param_long_set_default,   /* value_set_default */
1174       param_long_validate,      /* value_validate */
1175       param_long_values_cmp,    /* values_cmp */
1176     };
1177     type = g_param_type_register_static (g_intern_static_string ("GParamLong"), &pspec_info);
1178     *spec_types++ = type;
1179     g_assert (type == G_TYPE_PARAM_LONG);
1180   }
1181   
1182   /* G_TYPE_PARAM_ULONG
1183    */
1184   {
1185     static const GParamSpecTypeInfo pspec_info = {
1186       sizeof (GParamSpecULong), /* instance_size */
1187       16,                       /* n_preallocs */
1188       param_ulong_init,         /* instance_init */
1189       G_TYPE_ULONG,             /* value_type */
1190       NULL,                     /* finalize */
1191       param_ulong_set_default,  /* value_set_default */
1192       param_ulong_validate,     /* value_validate */
1193       param_ulong_values_cmp,   /* values_cmp */
1194     };
1195     type = g_param_type_register_static (g_intern_static_string ("GParamULong"), &pspec_info);
1196     *spec_types++ = type;
1197     g_assert (type == G_TYPE_PARAM_ULONG);
1198   }
1199
1200   /* G_TYPE_PARAM_INT64
1201    */
1202   {
1203     static const GParamSpecTypeInfo pspec_info = {
1204       sizeof (GParamSpecInt64),  /* instance_size */
1205       16,                       /* n_preallocs */
1206       param_int64_init,         /* instance_init */
1207       G_TYPE_INT64,             /* value_type */
1208       NULL,                     /* finalize */
1209       param_int64_set_default,  /* value_set_default */
1210       param_int64_validate,     /* value_validate */
1211       param_int64_values_cmp,   /* values_cmp */
1212     };
1213     type = g_param_type_register_static (g_intern_static_string ("GParamInt64"), &pspec_info);
1214     *spec_types++ = type;
1215     g_assert (type == G_TYPE_PARAM_INT64);
1216   }
1217   
1218   /* G_TYPE_PARAM_UINT64
1219    */
1220   {
1221     static const GParamSpecTypeInfo pspec_info = {
1222       sizeof (GParamSpecUInt64), /* instance_size */
1223       16,                       /* n_preallocs */
1224       param_uint64_init,        /* instance_init */
1225       G_TYPE_UINT64,            /* value_type */
1226       NULL,                     /* finalize */
1227       param_uint64_set_default, /* value_set_default */
1228       param_uint64_validate,    /* value_validate */
1229       param_uint64_values_cmp,  /* values_cmp */
1230     };
1231     type = g_param_type_register_static (g_intern_static_string ("GParamUInt64"), &pspec_info);
1232     *spec_types++ = type;
1233     g_assert (type == G_TYPE_PARAM_UINT64);
1234   }
1235
1236   /* G_TYPE_PARAM_UNICHAR
1237    */
1238   {
1239     static const GParamSpecTypeInfo pspec_info = {
1240       sizeof (GParamSpecUnichar), /* instance_size */
1241       16,                        /* n_preallocs */
1242       param_unichar_init,        /* instance_init */
1243       G_TYPE_UINT,               /* value_type */
1244       NULL,                      /* finalize */
1245       param_unichar_set_default, /* value_set_default */
1246       param_unichar_validate,    /* value_validate */
1247       param_unichar_values_cmp,  /* values_cmp */
1248     };
1249     type = g_param_type_register_static (g_intern_static_string ("GParamUnichar"), &pspec_info);
1250     *spec_types++ = type;
1251     g_assert (type == G_TYPE_PARAM_UNICHAR);
1252   }
1253
1254  /* G_TYPE_PARAM_ENUM
1255    */
1256   {
1257     static const GParamSpecTypeInfo pspec_info = {
1258       sizeof (GParamSpecEnum),  /* instance_size */
1259       16,                       /* n_preallocs */
1260       param_enum_init,          /* instance_init */
1261       G_TYPE_ENUM,              /* value_type */
1262       param_enum_finalize,      /* finalize */
1263       param_enum_set_default,   /* value_set_default */
1264       param_enum_validate,      /* value_validate */
1265       param_long_values_cmp,    /* values_cmp */
1266     };
1267     type = g_param_type_register_static (g_intern_static_string ("GParamEnum"), &pspec_info);
1268     *spec_types++ = type;
1269     g_assert (type == G_TYPE_PARAM_ENUM);
1270   }
1271   
1272   /* G_TYPE_PARAM_FLAGS
1273    */
1274   {
1275     static const GParamSpecTypeInfo pspec_info = {
1276       sizeof (GParamSpecFlags), /* instance_size */
1277       16,                       /* n_preallocs */
1278       param_flags_init,         /* instance_init */
1279       G_TYPE_FLAGS,             /* value_type */
1280       param_flags_finalize,     /* finalize */
1281       param_flags_set_default,  /* value_set_default */
1282       param_flags_validate,     /* value_validate */
1283       param_ulong_values_cmp,   /* values_cmp */
1284     };
1285     type = g_param_type_register_static (g_intern_static_string ("GParamFlags"), &pspec_info);
1286     *spec_types++ = type;
1287     g_assert (type == G_TYPE_PARAM_FLAGS);
1288   }
1289   
1290   /* G_TYPE_PARAM_FLOAT
1291    */
1292   {
1293     static const GParamSpecTypeInfo pspec_info = {
1294       sizeof (GParamSpecFloat), /* instance_size */
1295       16,                       /* n_preallocs */
1296       param_float_init,         /* instance_init */
1297       G_TYPE_FLOAT,             /* value_type */
1298       NULL,                     /* finalize */
1299       param_float_set_default,  /* value_set_default */
1300       param_float_validate,     /* value_validate */
1301       param_float_values_cmp,   /* values_cmp */
1302     };
1303     type = g_param_type_register_static (g_intern_static_string ("GParamFloat"), &pspec_info);
1304     *spec_types++ = type;
1305     g_assert (type == G_TYPE_PARAM_FLOAT);
1306   }
1307   
1308   /* G_TYPE_PARAM_DOUBLE
1309    */
1310   {
1311     static const GParamSpecTypeInfo pspec_info = {
1312       sizeof (GParamSpecDouble),        /* instance_size */
1313       16,                               /* n_preallocs */
1314       param_double_init,                /* instance_init */
1315       G_TYPE_DOUBLE,                    /* value_type */
1316       NULL,                             /* finalize */
1317       param_double_set_default,         /* value_set_default */
1318       param_double_validate,            /* value_validate */
1319       param_double_values_cmp,          /* values_cmp */
1320     };
1321     type = g_param_type_register_static (g_intern_static_string ("GParamDouble"), &pspec_info);
1322     *spec_types++ = type;
1323     g_assert (type == G_TYPE_PARAM_DOUBLE);
1324   }
1325   
1326   /* G_TYPE_PARAM_STRING
1327    */
1328   {
1329     static const GParamSpecTypeInfo pspec_info = {
1330       sizeof (GParamSpecString),        /* instance_size */
1331       16,                               /* n_preallocs */
1332       param_string_init,                /* instance_init */
1333       G_TYPE_STRING,                    /* value_type */
1334       param_string_finalize,            /* finalize */
1335       param_string_set_default,         /* value_set_default */
1336       param_string_validate,            /* value_validate */
1337       param_string_values_cmp,          /* values_cmp */
1338     };
1339     type = g_param_type_register_static (g_intern_static_string ("GParamString"), &pspec_info);
1340     *spec_types++ = type;
1341     g_assert (type == G_TYPE_PARAM_STRING);
1342   }
1343   
1344   /* G_TYPE_PARAM_PARAM
1345    */
1346   {
1347     static const GParamSpecTypeInfo pspec_info = {
1348       sizeof (GParamSpecParam), /* instance_size */
1349       16,                       /* n_preallocs */
1350       param_param_init,         /* instance_init */
1351       G_TYPE_PARAM,             /* value_type */
1352       NULL,                     /* finalize */
1353       param_param_set_default,  /* value_set_default */
1354       param_param_validate,     /* value_validate */
1355       param_pointer_values_cmp, /* values_cmp */
1356     };
1357     type = g_param_type_register_static (g_intern_static_string ("GParamParam"), &pspec_info);
1358     *spec_types++ = type;
1359     g_assert (type == G_TYPE_PARAM_PARAM);
1360   }
1361   
1362   /* G_TYPE_PARAM_BOXED
1363    */
1364   {
1365     static const GParamSpecTypeInfo pspec_info = {
1366       sizeof (GParamSpecBoxed), /* instance_size */
1367       4,                        /* n_preallocs */
1368       param_boxed_init,         /* instance_init */
1369       G_TYPE_BOXED,             /* value_type */
1370       NULL,                     /* finalize */
1371       param_boxed_set_default,  /* value_set_default */
1372       param_boxed_validate,     /* value_validate */
1373       param_boxed_values_cmp,   /* values_cmp */
1374     };
1375     type = g_param_type_register_static (g_intern_static_string ("GParamBoxed"), &pspec_info);
1376     *spec_types++ = type;
1377     g_assert (type == G_TYPE_PARAM_BOXED);
1378   }
1379
1380   /* G_TYPE_PARAM_POINTER
1381    */
1382   {
1383     static const GParamSpecTypeInfo pspec_info = {
1384       sizeof (GParamSpecPointer),  /* instance_size */
1385       0,                           /* n_preallocs */
1386       param_pointer_init,          /* instance_init */
1387       G_TYPE_POINTER,              /* value_type */
1388       NULL,                        /* finalize */
1389       param_pointer_set_default,   /* value_set_default */
1390       param_pointer_validate,      /* value_validate */
1391       param_pointer_values_cmp,    /* values_cmp */
1392     };
1393     type = g_param_type_register_static (g_intern_static_string ("GParamPointer"), &pspec_info);
1394     *spec_types++ = type;
1395     g_assert (type == G_TYPE_PARAM_POINTER);
1396   }
1397   
1398   /* G_TYPE_PARAM_VALUE_ARRAY
1399    */
1400   {
1401     static /* const */ GParamSpecTypeInfo pspec_info = {
1402       sizeof (GParamSpecValueArray),    /* instance_size */
1403       0,                                /* n_preallocs */
1404       param_value_array_init,           /* instance_init */
1405       0xdeadbeef,                       /* value_type, assigned further down */
1406       param_value_array_finalize,       /* finalize */
1407       param_value_array_set_default,    /* value_set_default */
1408       param_value_array_validate,       /* value_validate */
1409       param_value_array_values_cmp,     /* values_cmp */
1410     };
1411     pspec_info.value_type = G_TYPE_VALUE_ARRAY;
1412     type = g_param_type_register_static (g_intern_static_string ("GParamValueArray"), &pspec_info);
1413     *spec_types++ = type;
1414     g_assert (type == G_TYPE_PARAM_VALUE_ARRAY);
1415   }
1416
1417   /* G_TYPE_PARAM_OBJECT
1418    */
1419   {
1420     static const GParamSpecTypeInfo pspec_info = {
1421       sizeof (GParamSpecObject), /* instance_size */
1422       16,                        /* n_preallocs */
1423       param_object_init,         /* instance_init */
1424       G_TYPE_OBJECT,             /* value_type */
1425       NULL,                      /* finalize */
1426       param_object_set_default,  /* value_set_default */
1427       param_object_validate,     /* value_validate */
1428       param_object_values_cmp,   /* values_cmp */
1429     };
1430     type = g_param_type_register_static (g_intern_static_string ("GParamObject"), &pspec_info);
1431     *spec_types++ = type;
1432     g_assert (type == G_TYPE_PARAM_OBJECT);
1433   }
1434
1435   /* G_TYPE_PARAM_OVERRIDE
1436    */
1437   {
1438     static const GParamSpecTypeInfo pspec_info = {
1439       sizeof (GParamSpecOverride), /* instance_size */
1440       16,                        /* n_preallocs */
1441       param_override_init,       /* instance_init */
1442       G_TYPE_NONE,               /* value_type */
1443       param_override_finalize,   /* finalize */
1444       param_override_set_default, /* value_set_default */
1445       param_override_validate,    /* value_validate */
1446       param_override_values_cmp,  /* values_cmp */
1447     };
1448     type = g_param_type_register_static (g_intern_static_string ("GParamOverride"), &pspec_info);
1449     *spec_types++ = type;
1450     g_assert (type == G_TYPE_PARAM_OVERRIDE);
1451   }
1452
1453   /* G_TYPE_PARAM_GTYPE
1454    */
1455   {
1456     GType value_type = G_TYPE_GTYPE;
1457     GParamSpecTypeInfo pspec_info = {
1458       sizeof (GParamSpecGType), /* instance_size */
1459       0,                        /* n_preallocs */
1460       param_gtype_init,         /* instance_init */
1461       value_type,               /* value_type */
1462       NULL,                     /* finalize */
1463       param_gtype_set_default,  /* value_set_default */
1464       param_gtype_validate,     /* value_validate */
1465       param_gtype_values_cmp,   /* values_cmp */
1466     };
1467     type = g_param_type_register_static (g_intern_static_string ("GParamGType"), &pspec_info);
1468     *spec_types++ = type;
1469     g_assert (type == G_TYPE_PARAM_GTYPE);
1470   }
1471
1472   g_assert (spec_types == spec_types_bound);
1473 }
1474
1475 /* --- GParamSpec initialization --- */
1476
1477 GParamSpec*
1478 g_param_spec_char (const gchar *name,
1479                    const gchar *nick,
1480                    const gchar *blurb,
1481                    gint8        minimum,
1482                    gint8        maximum,
1483                    gint8        default_value,
1484                    GParamFlags  flags)
1485 {
1486   GParamSpecChar *cspec;
1487
1488   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1489
1490   cspec = g_param_spec_internal (G_TYPE_PARAM_CHAR,
1491                                  name,
1492                                  nick,
1493                                  blurb,
1494                                  flags);
1495   
1496   cspec->minimum = minimum;
1497   cspec->maximum = maximum;
1498   cspec->default_value = default_value;
1499   
1500   return G_PARAM_SPEC (cspec);
1501 }
1502
1503 GParamSpec*
1504 g_param_spec_uchar (const gchar *name,
1505                     const gchar *nick,
1506                     const gchar *blurb,
1507                     guint8       minimum,
1508                     guint8       maximum,
1509                     guint8       default_value,
1510                     GParamFlags  flags)
1511 {
1512   GParamSpecUChar *uspec;
1513
1514   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1515
1516   uspec = g_param_spec_internal (G_TYPE_PARAM_UCHAR,
1517                                  name,
1518                                  nick,
1519                                  blurb,
1520                                  flags);
1521   
1522   uspec->minimum = minimum;
1523   uspec->maximum = maximum;
1524   uspec->default_value = default_value;
1525   
1526   return G_PARAM_SPEC (uspec);
1527 }
1528
1529 GParamSpec*
1530 g_param_spec_boolean (const gchar *name,
1531                       const gchar *nick,
1532                       const gchar *blurb,
1533                       gboolean     default_value,
1534                       GParamFlags  flags)
1535 {
1536   GParamSpecBoolean *bspec;
1537
1538   g_return_val_if_fail (default_value == TRUE || default_value == FALSE, NULL);
1539
1540   bspec = g_param_spec_internal (G_TYPE_PARAM_BOOLEAN,
1541                                  name,
1542                                  nick,
1543                                  blurb,
1544                                  flags);
1545   
1546   bspec->default_value = default_value;
1547   
1548   return G_PARAM_SPEC (bspec);
1549 }
1550
1551 GParamSpec*
1552 g_param_spec_int (const gchar *name,
1553                   const gchar *nick,
1554                   const gchar *blurb,
1555                   gint         minimum,
1556                   gint         maximum,
1557                   gint         default_value,
1558                   GParamFlags  flags)
1559 {
1560   GParamSpecInt *ispec;
1561
1562   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1563
1564   ispec = g_param_spec_internal (G_TYPE_PARAM_INT,
1565                                  name,
1566                                  nick,
1567                                  blurb,
1568                                  flags);
1569   
1570   ispec->minimum = minimum;
1571   ispec->maximum = maximum;
1572   ispec->default_value = default_value;
1573   
1574   return G_PARAM_SPEC (ispec);
1575 }
1576
1577 GParamSpec*
1578 g_param_spec_uint (const gchar *name,
1579                    const gchar *nick,
1580                    const gchar *blurb,
1581                    guint        minimum,
1582                    guint        maximum,
1583                    guint        default_value,
1584                    GParamFlags  flags)
1585 {
1586   GParamSpecUInt *uspec;
1587
1588   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1589
1590   uspec = g_param_spec_internal (G_TYPE_PARAM_UINT,
1591                                  name,
1592                                  nick,
1593                                  blurb,
1594                                  flags);
1595   
1596   uspec->minimum = minimum;
1597   uspec->maximum = maximum;
1598   uspec->default_value = default_value;
1599   
1600   return G_PARAM_SPEC (uspec);
1601 }
1602
1603 GParamSpec*
1604 g_param_spec_long (const gchar *name,
1605                    const gchar *nick,
1606                    const gchar *blurb,
1607                    glong        minimum,
1608                    glong        maximum,
1609                    glong        default_value,
1610                    GParamFlags  flags)
1611 {
1612   GParamSpecLong *lspec;
1613
1614   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1615
1616   lspec = g_param_spec_internal (G_TYPE_PARAM_LONG,
1617                                  name,
1618                                  nick,
1619                                  blurb,
1620                                  flags);
1621   
1622   lspec->minimum = minimum;
1623   lspec->maximum = maximum;
1624   lspec->default_value = default_value;
1625   
1626   return G_PARAM_SPEC (lspec);
1627 }
1628
1629 GParamSpec*
1630 g_param_spec_ulong (const gchar *name,
1631                     const gchar *nick,
1632                     const gchar *blurb,
1633                     gulong       minimum,
1634                     gulong       maximum,
1635                     gulong       default_value,
1636                     GParamFlags  flags)
1637 {
1638   GParamSpecULong *uspec;
1639
1640   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1641
1642   uspec = g_param_spec_internal (G_TYPE_PARAM_ULONG,
1643                                  name,
1644                                  nick,
1645                                  blurb,
1646                                  flags);
1647   
1648   uspec->minimum = minimum;
1649   uspec->maximum = maximum;
1650   uspec->default_value = default_value;
1651   
1652   return G_PARAM_SPEC (uspec);
1653 }
1654
1655 GParamSpec*
1656 g_param_spec_int64 (const gchar *name,
1657                     const gchar *nick,
1658                     const gchar *blurb,
1659                     gint64       minimum,
1660                     gint64       maximum,
1661                     gint64       default_value,
1662                     GParamFlags  flags)
1663 {
1664   GParamSpecInt64 *lspec;
1665   
1666   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1667
1668   lspec = g_param_spec_internal (G_TYPE_PARAM_INT64,
1669                                  name,
1670                                  nick,
1671                                  blurb,
1672                                  flags);
1673   
1674   lspec->minimum = minimum;
1675   lspec->maximum = maximum;
1676   lspec->default_value = default_value;
1677   
1678   return G_PARAM_SPEC (lspec);
1679 }
1680
1681 GParamSpec*
1682 g_param_spec_uint64 (const gchar *name,
1683                      const gchar *nick,
1684                      const gchar *blurb,
1685                      guint64      minimum,
1686                      guint64      maximum,
1687                      guint64      default_value,
1688                      GParamFlags  flags)
1689 {
1690   GParamSpecUInt64 *uspec;
1691   
1692   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1693   
1694   uspec = g_param_spec_internal (G_TYPE_PARAM_UINT64,
1695                                  name,
1696                                  nick,
1697                                  blurb,
1698                                  flags);
1699   
1700   uspec->minimum = minimum;
1701   uspec->maximum = maximum;
1702   uspec->default_value = default_value;
1703   
1704   return G_PARAM_SPEC (uspec);
1705 }
1706
1707 GParamSpec*
1708 g_param_spec_unichar (const gchar *name,
1709                       const gchar *nick,
1710                       const gchar *blurb,
1711                       gunichar     default_value,
1712                       GParamFlags  flags)
1713 {
1714   GParamSpecUnichar *uspec;
1715
1716   uspec = g_param_spec_internal (G_TYPE_PARAM_UNICHAR,
1717                                  name,
1718                                  nick,
1719                                  blurb,
1720                                  flags);
1721   
1722   uspec->default_value = default_value;
1723   
1724   return G_PARAM_SPEC (uspec);
1725 }
1726
1727 GParamSpec*
1728 g_param_spec_enum (const gchar *name,
1729                    const gchar *nick,
1730                    const gchar *blurb,
1731                    GType        enum_type,
1732                    gint         default_value,
1733                    GParamFlags  flags)
1734 {
1735   GParamSpecEnum *espec;
1736   GEnumClass *enum_class;
1737   
1738   g_return_val_if_fail (G_TYPE_IS_ENUM (enum_type), NULL);
1739
1740   enum_class = g_type_class_ref (enum_type);
1741
1742   g_return_val_if_fail (g_enum_get_value (enum_class, default_value) != NULL, NULL);
1743   
1744   espec = g_param_spec_internal (G_TYPE_PARAM_ENUM,
1745                                  name,
1746                                  nick,
1747                                  blurb,
1748                                  flags);
1749   
1750   espec->enum_class = enum_class;
1751   espec->default_value = default_value;
1752   G_PARAM_SPEC (espec)->value_type = enum_type;
1753   
1754   return G_PARAM_SPEC (espec);
1755 }
1756
1757 GParamSpec*
1758 g_param_spec_flags (const gchar *name,
1759                     const gchar *nick,
1760                     const gchar *blurb,
1761                     GType        flags_type,
1762                     guint        default_value,
1763                     GParamFlags  flags)
1764 {
1765   GParamSpecFlags *fspec;
1766   GFlagsClass *flags_class;
1767   
1768   g_return_val_if_fail (G_TYPE_IS_FLAGS (flags_type), NULL);
1769
1770   flags_class = g_type_class_ref (flags_type);
1771
1772   g_return_val_if_fail ((default_value & flags_class->mask) == default_value, NULL);
1773   
1774   fspec = g_param_spec_internal (G_TYPE_PARAM_FLAGS,
1775                                  name,
1776                                  nick,
1777                                  blurb,
1778                                  flags);
1779   
1780   fspec->flags_class = flags_class;
1781   fspec->default_value = default_value;
1782   G_PARAM_SPEC (fspec)->value_type = flags_type;
1783   
1784   return G_PARAM_SPEC (fspec);
1785 }
1786
1787 GParamSpec*
1788 g_param_spec_float (const gchar *name,
1789                     const gchar *nick,
1790                     const gchar *blurb,
1791                     gfloat       minimum,
1792                     gfloat       maximum,
1793                     gfloat       default_value,
1794                     GParamFlags  flags)
1795 {
1796   GParamSpecFloat *fspec;
1797
1798   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1799
1800   fspec = g_param_spec_internal (G_TYPE_PARAM_FLOAT,
1801                                  name,
1802                                  nick,
1803                                  blurb,
1804                                  flags);
1805   
1806   fspec->minimum = minimum;
1807   fspec->maximum = maximum;
1808   fspec->default_value = default_value;
1809   
1810   return G_PARAM_SPEC (fspec);
1811 }
1812
1813 GParamSpec*
1814 g_param_spec_double (const gchar *name,
1815                      const gchar *nick,
1816                      const gchar *blurb,
1817                      gdouble      minimum,
1818                      gdouble      maximum,
1819                      gdouble      default_value,
1820                      GParamFlags  flags)
1821 {
1822   GParamSpecDouble *dspec;
1823
1824   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1825
1826   dspec = g_param_spec_internal (G_TYPE_PARAM_DOUBLE,
1827                                  name,
1828                                  nick,
1829                                  blurb,
1830                                  flags);
1831   
1832   dspec->minimum = minimum;
1833   dspec->maximum = maximum;
1834   dspec->default_value = default_value;
1835   
1836   return G_PARAM_SPEC (dspec);
1837 }
1838
1839 GParamSpec*
1840 g_param_spec_string (const gchar *name,
1841                      const gchar *nick,
1842                      const gchar *blurb,
1843                      const gchar *default_value,
1844                      GParamFlags  flags)
1845 {
1846   GParamSpecString *sspec = g_param_spec_internal (G_TYPE_PARAM_STRING,
1847                                                    name,
1848                                                    nick,
1849                                                    blurb,
1850                                                    flags);
1851   g_free (sspec->default_value);
1852   sspec->default_value = g_strdup (default_value);
1853   
1854   return G_PARAM_SPEC (sspec);
1855 }
1856
1857 GParamSpec*
1858 g_param_spec_param (const gchar *name,
1859                     const gchar *nick,
1860                     const gchar *blurb,
1861                     GType        param_type,
1862                     GParamFlags  flags)
1863 {
1864   GParamSpecParam *pspec;
1865   
1866   g_return_val_if_fail (G_TYPE_IS_PARAM (param_type), NULL);
1867   
1868   pspec = g_param_spec_internal (G_TYPE_PARAM_PARAM,
1869                                  name,
1870                                  nick,
1871                                  blurb,
1872                                  flags);
1873   G_PARAM_SPEC (pspec)->value_type = param_type;
1874   
1875   return G_PARAM_SPEC (pspec);
1876 }
1877
1878 GParamSpec*
1879 g_param_spec_boxed (const gchar *name,
1880                     const gchar *nick,
1881                     const gchar *blurb,
1882                     GType        boxed_type,
1883                     GParamFlags  flags)
1884 {
1885   GParamSpecBoxed *bspec;
1886   
1887   g_return_val_if_fail (G_TYPE_IS_BOXED (boxed_type), NULL);
1888   g_return_val_if_fail (G_TYPE_IS_VALUE_TYPE (boxed_type), NULL);
1889   
1890   bspec = g_param_spec_internal (G_TYPE_PARAM_BOXED,
1891                                  name,
1892                                  nick,
1893                                  blurb,
1894                                  flags);
1895   G_PARAM_SPEC (bspec)->value_type = boxed_type;
1896   
1897   return G_PARAM_SPEC (bspec);
1898 }
1899
1900 GParamSpec*
1901 g_param_spec_pointer (const gchar *name,
1902                       const gchar *nick,
1903                       const gchar *blurb,
1904                       GParamFlags  flags)
1905 {
1906   GParamSpecPointer *pspec;
1907   
1908   pspec = g_param_spec_internal (G_TYPE_PARAM_POINTER,
1909                                  name,
1910                                  nick,
1911                                  blurb,
1912                                  flags);
1913   return G_PARAM_SPEC (pspec);
1914 }
1915
1916 GParamSpec*
1917 g_param_spec_gtype (const gchar *name,
1918                     const gchar *nick,
1919                     const gchar *blurb,
1920                     GType        is_a_type,
1921                     GParamFlags  flags)
1922 {
1923   GParamSpecGType *tspec;
1924   
1925   tspec = g_param_spec_internal (G_TYPE_PARAM_GTYPE,
1926                                  name,
1927                                  nick,
1928                                  blurb,
1929                                  flags);
1930
1931   tspec->is_a_type = is_a_type;
1932
1933   return G_PARAM_SPEC (tspec);
1934 }
1935
1936 GParamSpec*
1937 g_param_spec_value_array (const gchar *name,
1938                           const gchar *nick,
1939                           const gchar *blurb,
1940                           GParamSpec  *element_spec,
1941                           GParamFlags  flags)
1942 {
1943   GParamSpecValueArray *aspec;
1944   
1945   if (element_spec)
1946     g_return_val_if_fail (G_IS_PARAM_SPEC (element_spec), NULL);
1947   
1948   aspec = g_param_spec_internal (G_TYPE_PARAM_VALUE_ARRAY,
1949                                  name,
1950                                  nick,
1951                                  blurb,
1952                                  flags);
1953   if (element_spec)
1954     {
1955       aspec->element_spec = g_param_spec_ref (element_spec);
1956       g_param_spec_sink (element_spec);
1957     }
1958
1959   return G_PARAM_SPEC (aspec);
1960 }
1961
1962 GParamSpec*
1963 g_param_spec_object (const gchar *name,
1964                      const gchar *nick,
1965                      const gchar *blurb,
1966                      GType        object_type,
1967                      GParamFlags  flags)
1968 {
1969   GParamSpecObject *ospec;
1970   
1971   g_return_val_if_fail (g_type_is_a (object_type, G_TYPE_OBJECT), NULL);
1972   
1973   ospec = g_param_spec_internal (G_TYPE_PARAM_OBJECT,
1974                                  name,
1975                                  nick,
1976                                  blurb,
1977                                  flags);
1978   G_PARAM_SPEC (ospec)->value_type = object_type;
1979   
1980   return G_PARAM_SPEC (ospec);
1981 }
1982
1983 GParamSpec*
1984 g_param_spec_override (const gchar *name,
1985                        GParamSpec  *overridden)
1986 {
1987   GParamSpec *pspec;
1988   
1989   g_return_val_if_fail (name != NULL, NULL);
1990   g_return_val_if_fail (G_IS_PARAM_SPEC (overridden), NULL);
1991   
1992   /* Dereference further redirections for property that was passed in
1993    */
1994   while (TRUE)
1995     {
1996       GParamSpec *indirect = g_param_spec_get_redirect_target (overridden);
1997       if (indirect)
1998         overridden = indirect;
1999       else
2000         break;
2001     }
2002
2003   pspec = g_param_spec_internal (G_TYPE_PARAM_OVERRIDE,
2004                                  name, NULL, NULL,
2005                                  overridden->flags);
2006   
2007   pspec->value_type = G_PARAM_SPEC_VALUE_TYPE (overridden);
2008   G_PARAM_SPEC_OVERRIDE (pspec)->overridden = g_param_spec_ref (overridden);
2009
2010   return pspec;
2011 }
2012
2013 #define __G_PARAMSPECS_C__
2014 #include "gobjectaliasdef.c"