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