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