Commit the vanila glib 2.27.5 with old debian directory
[external/glib2.0.git] / gobject / gparamspecs.c
1 /* GObject - GLib Type, Object, Parameter and Signal Library
2  * Copyright (C) 1997-1999, 2000-2001 Tim Janik and Red Hat, Inc.
3  * Copyright (C) 2010 Christian Persch
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 /*
22  * MT safe
23  */
24
25 #include "config.h"
26
27 #include <string.h>
28
29 #include "gparamspecs.h"
30 #include "gvaluecollector.h"
31 #include "gvaluearray.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 static void
1102 param_variant_init (GParamSpec *pspec)
1103 {
1104   GParamSpecVariant *vspec = G_PARAM_SPEC_VARIANT (pspec);
1105
1106   vspec->type = NULL;
1107   vspec->default_value = NULL;
1108 }
1109
1110 static void
1111 param_variant_finalize (GParamSpec *pspec)
1112 {
1113   GParamSpecVariant *vspec = G_PARAM_SPEC_VARIANT (pspec);
1114   GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_VARIANT));
1115
1116   if (vspec->default_value)
1117     g_variant_unref (vspec->default_value);
1118   g_variant_type_free (vspec->type);
1119
1120   parent_class->finalize (pspec);
1121 }
1122
1123 static void
1124 param_variant_set_default (GParamSpec *pspec,
1125                            GValue     *value)
1126 {
1127   value->data[0].v_pointer = G_PARAM_SPEC_VARIANT (pspec)->default_value;
1128   value->data[1].v_uint |= G_VALUE_NOCOPY_CONTENTS;
1129 }
1130
1131 static gboolean
1132 param_variant_validate (GParamSpec *pspec,
1133                         GValue     *value)
1134 {
1135   GParamSpecVariant *vspec = G_PARAM_SPEC_VARIANT (pspec);
1136   GVariant *variant = value->data[0].v_pointer;
1137
1138   if ((variant == NULL && vspec->default_value != NULL) ||
1139       (variant != NULL && !g_variant_is_of_type (variant, vspec->type)))
1140     {
1141       g_param_value_set_default (pspec, value);
1142       return TRUE;
1143     }
1144
1145   return FALSE;
1146 }
1147
1148 static gint
1149 param_variant_values_cmp (GParamSpec   *pspec,
1150                           const GValue *value1,
1151                           const GValue *value2)
1152 {
1153   GVariant *v1 = value1->data[0].v_pointer;
1154   GVariant *v2 = value2->data[0].v_pointer;
1155
1156   return v1 < v2 ? -1 : v2 > v1;
1157 }
1158
1159 /* --- type initialization --- */
1160 GType *g_param_spec_types = NULL;
1161
1162 void
1163 g_param_spec_types_init (void)  
1164 {
1165   const guint n_types = 23;
1166   GType type, *spec_types, *spec_types_bound;
1167
1168   g_param_spec_types = g_new0 (GType, n_types);
1169   spec_types = g_param_spec_types;
1170   spec_types_bound = g_param_spec_types + n_types;
1171   
1172   /* G_TYPE_PARAM_CHAR
1173    */
1174   {
1175     static const GParamSpecTypeInfo pspec_info = {
1176       sizeof (GParamSpecChar),  /* instance_size */
1177       16,                       /* n_preallocs */
1178       param_char_init,          /* instance_init */
1179       G_TYPE_CHAR,              /* value_type */
1180       NULL,                     /* finalize */
1181       param_char_set_default,   /* value_set_default */
1182       param_char_validate,      /* value_validate */
1183       param_int_values_cmp,     /* values_cmp */
1184     };
1185     type = g_param_type_register_static (g_intern_static_string ("GParamChar"), &pspec_info);
1186     *spec_types++ = type;
1187     g_assert (type == G_TYPE_PARAM_CHAR);
1188   }
1189   
1190   /* G_TYPE_PARAM_UCHAR
1191    */
1192   {
1193     static const GParamSpecTypeInfo pspec_info = {
1194       sizeof (GParamSpecUChar), /* instance_size */
1195       16,                       /* n_preallocs */
1196       param_uchar_init,         /* instance_init */
1197       G_TYPE_UCHAR,             /* value_type */
1198       NULL,                     /* finalize */
1199       param_uchar_set_default,  /* value_set_default */
1200       param_uchar_validate,     /* value_validate */
1201       param_uint_values_cmp,    /* values_cmp */
1202     };
1203     type = g_param_type_register_static (g_intern_static_string ("GParamUChar"), &pspec_info);
1204     *spec_types++ = type;
1205     g_assert (type == G_TYPE_PARAM_UCHAR);
1206   }
1207   
1208   /* G_TYPE_PARAM_BOOLEAN
1209    */
1210   {
1211     static const GParamSpecTypeInfo pspec_info = {
1212       sizeof (GParamSpecBoolean), /* instance_size */
1213       16,                         /* n_preallocs */
1214       NULL,                       /* instance_init */
1215       G_TYPE_BOOLEAN,             /* value_type */
1216       NULL,                       /* finalize */
1217       param_boolean_set_default,  /* value_set_default */
1218       param_boolean_validate,     /* value_validate */
1219       param_int_values_cmp,       /* values_cmp */
1220     };
1221     type = g_param_type_register_static (g_intern_static_string ("GParamBoolean"), &pspec_info);
1222     *spec_types++ = type;
1223     g_assert (type == G_TYPE_PARAM_BOOLEAN);
1224   }
1225   
1226   /* G_TYPE_PARAM_INT
1227    */
1228   {
1229     static const GParamSpecTypeInfo pspec_info = {
1230       sizeof (GParamSpecInt),   /* instance_size */
1231       16,                       /* n_preallocs */
1232       param_int_init,           /* instance_init */
1233       G_TYPE_INT,               /* value_type */
1234       NULL,                     /* finalize */
1235       param_int_set_default,    /* value_set_default */
1236       param_int_validate,       /* value_validate */
1237       param_int_values_cmp,     /* values_cmp */
1238     };
1239     type = g_param_type_register_static (g_intern_static_string ("GParamInt"), &pspec_info);
1240     *spec_types++ = type;
1241     g_assert (type == G_TYPE_PARAM_INT);
1242   }
1243   
1244   /* G_TYPE_PARAM_UINT
1245    */
1246   {
1247     static const GParamSpecTypeInfo pspec_info = {
1248       sizeof (GParamSpecUInt),  /* instance_size */
1249       16,                       /* n_preallocs */
1250       param_uint_init,          /* instance_init */
1251       G_TYPE_UINT,              /* value_type */
1252       NULL,                     /* finalize */
1253       param_uint_set_default,   /* value_set_default */
1254       param_uint_validate,      /* value_validate */
1255       param_uint_values_cmp,    /* values_cmp */
1256     };
1257     type = g_param_type_register_static (g_intern_static_string ("GParamUInt"), &pspec_info);
1258     *spec_types++ = type;
1259     g_assert (type == G_TYPE_PARAM_UINT);
1260   }
1261   
1262   /* G_TYPE_PARAM_LONG
1263    */
1264   {
1265     static const GParamSpecTypeInfo pspec_info = {
1266       sizeof (GParamSpecLong),  /* instance_size */
1267       16,                       /* n_preallocs */
1268       param_long_init,          /* instance_init */
1269       G_TYPE_LONG,              /* value_type */
1270       NULL,                     /* finalize */
1271       param_long_set_default,   /* value_set_default */
1272       param_long_validate,      /* value_validate */
1273       param_long_values_cmp,    /* values_cmp */
1274     };
1275     type = g_param_type_register_static (g_intern_static_string ("GParamLong"), &pspec_info);
1276     *spec_types++ = type;
1277     g_assert (type == G_TYPE_PARAM_LONG);
1278   }
1279   
1280   /* G_TYPE_PARAM_ULONG
1281    */
1282   {
1283     static const GParamSpecTypeInfo pspec_info = {
1284       sizeof (GParamSpecULong), /* instance_size */
1285       16,                       /* n_preallocs */
1286       param_ulong_init,         /* instance_init */
1287       G_TYPE_ULONG,             /* value_type */
1288       NULL,                     /* finalize */
1289       param_ulong_set_default,  /* value_set_default */
1290       param_ulong_validate,     /* value_validate */
1291       param_ulong_values_cmp,   /* values_cmp */
1292     };
1293     type = g_param_type_register_static (g_intern_static_string ("GParamULong"), &pspec_info);
1294     *spec_types++ = type;
1295     g_assert (type == G_TYPE_PARAM_ULONG);
1296   }
1297
1298   /* G_TYPE_PARAM_INT64
1299    */
1300   {
1301     static const GParamSpecTypeInfo pspec_info = {
1302       sizeof (GParamSpecInt64),  /* instance_size */
1303       16,                       /* n_preallocs */
1304       param_int64_init,         /* instance_init */
1305       G_TYPE_INT64,             /* value_type */
1306       NULL,                     /* finalize */
1307       param_int64_set_default,  /* value_set_default */
1308       param_int64_validate,     /* value_validate */
1309       param_int64_values_cmp,   /* values_cmp */
1310     };
1311     type = g_param_type_register_static (g_intern_static_string ("GParamInt64"), &pspec_info);
1312     *spec_types++ = type;
1313     g_assert (type == G_TYPE_PARAM_INT64);
1314   }
1315   
1316   /* G_TYPE_PARAM_UINT64
1317    */
1318   {
1319     static const GParamSpecTypeInfo pspec_info = {
1320       sizeof (GParamSpecUInt64), /* instance_size */
1321       16,                       /* n_preallocs */
1322       param_uint64_init,        /* instance_init */
1323       G_TYPE_UINT64,            /* value_type */
1324       NULL,                     /* finalize */
1325       param_uint64_set_default, /* value_set_default */
1326       param_uint64_validate,    /* value_validate */
1327       param_uint64_values_cmp,  /* values_cmp */
1328     };
1329     type = g_param_type_register_static (g_intern_static_string ("GParamUInt64"), &pspec_info);
1330     *spec_types++ = type;
1331     g_assert (type == G_TYPE_PARAM_UINT64);
1332   }
1333
1334   /* G_TYPE_PARAM_UNICHAR
1335    */
1336   {
1337     static const GParamSpecTypeInfo pspec_info = {
1338       sizeof (GParamSpecUnichar), /* instance_size */
1339       16,                        /* n_preallocs */
1340       param_unichar_init,        /* instance_init */
1341       G_TYPE_UINT,               /* value_type */
1342       NULL,                      /* finalize */
1343       param_unichar_set_default, /* value_set_default */
1344       param_unichar_validate,    /* value_validate */
1345       param_unichar_values_cmp,  /* values_cmp */
1346     };
1347     type = g_param_type_register_static (g_intern_static_string ("GParamUnichar"), &pspec_info);
1348     *spec_types++ = type;
1349     g_assert (type == G_TYPE_PARAM_UNICHAR);
1350   }
1351
1352  /* G_TYPE_PARAM_ENUM
1353    */
1354   {
1355     static const GParamSpecTypeInfo pspec_info = {
1356       sizeof (GParamSpecEnum),  /* instance_size */
1357       16,                       /* n_preallocs */
1358       param_enum_init,          /* instance_init */
1359       G_TYPE_ENUM,              /* value_type */
1360       param_enum_finalize,      /* finalize */
1361       param_enum_set_default,   /* value_set_default */
1362       param_enum_validate,      /* value_validate */
1363       param_long_values_cmp,    /* values_cmp */
1364     };
1365     type = g_param_type_register_static (g_intern_static_string ("GParamEnum"), &pspec_info);
1366     *spec_types++ = type;
1367     g_assert (type == G_TYPE_PARAM_ENUM);
1368   }
1369   
1370   /* G_TYPE_PARAM_FLAGS
1371    */
1372   {
1373     static const GParamSpecTypeInfo pspec_info = {
1374       sizeof (GParamSpecFlags), /* instance_size */
1375       16,                       /* n_preallocs */
1376       param_flags_init,         /* instance_init */
1377       G_TYPE_FLAGS,             /* value_type */
1378       param_flags_finalize,     /* finalize */
1379       param_flags_set_default,  /* value_set_default */
1380       param_flags_validate,     /* value_validate */
1381       param_ulong_values_cmp,   /* values_cmp */
1382     };
1383     type = g_param_type_register_static (g_intern_static_string ("GParamFlags"), &pspec_info);
1384     *spec_types++ = type;
1385     g_assert (type == G_TYPE_PARAM_FLAGS);
1386   }
1387   
1388   /* G_TYPE_PARAM_FLOAT
1389    */
1390   {
1391     static const GParamSpecTypeInfo pspec_info = {
1392       sizeof (GParamSpecFloat), /* instance_size */
1393       16,                       /* n_preallocs */
1394       param_float_init,         /* instance_init */
1395       G_TYPE_FLOAT,             /* value_type */
1396       NULL,                     /* finalize */
1397       param_float_set_default,  /* value_set_default */
1398       param_float_validate,     /* value_validate */
1399       param_float_values_cmp,   /* values_cmp */
1400     };
1401     type = g_param_type_register_static (g_intern_static_string ("GParamFloat"), &pspec_info);
1402     *spec_types++ = type;
1403     g_assert (type == G_TYPE_PARAM_FLOAT);
1404   }
1405   
1406   /* G_TYPE_PARAM_DOUBLE
1407    */
1408   {
1409     static const GParamSpecTypeInfo pspec_info = {
1410       sizeof (GParamSpecDouble),        /* instance_size */
1411       16,                               /* n_preallocs */
1412       param_double_init,                /* instance_init */
1413       G_TYPE_DOUBLE,                    /* value_type */
1414       NULL,                             /* finalize */
1415       param_double_set_default,         /* value_set_default */
1416       param_double_validate,            /* value_validate */
1417       param_double_values_cmp,          /* values_cmp */
1418     };
1419     type = g_param_type_register_static (g_intern_static_string ("GParamDouble"), &pspec_info);
1420     *spec_types++ = type;
1421     g_assert (type == G_TYPE_PARAM_DOUBLE);
1422   }
1423   
1424   /* G_TYPE_PARAM_STRING
1425    */
1426   {
1427     static const GParamSpecTypeInfo pspec_info = {
1428       sizeof (GParamSpecString),        /* instance_size */
1429       16,                               /* n_preallocs */
1430       param_string_init,                /* instance_init */
1431       G_TYPE_STRING,                    /* value_type */
1432       param_string_finalize,            /* finalize */
1433       param_string_set_default,         /* value_set_default */
1434       param_string_validate,            /* value_validate */
1435       param_string_values_cmp,          /* values_cmp */
1436     };
1437     type = g_param_type_register_static (g_intern_static_string ("GParamString"), &pspec_info);
1438     *spec_types++ = type;
1439     g_assert (type == G_TYPE_PARAM_STRING);
1440   }
1441   
1442   /* G_TYPE_PARAM_PARAM
1443    */
1444   {
1445     static const GParamSpecTypeInfo pspec_info = {
1446       sizeof (GParamSpecParam), /* instance_size */
1447       16,                       /* n_preallocs */
1448       param_param_init,         /* instance_init */
1449       G_TYPE_PARAM,             /* value_type */
1450       NULL,                     /* finalize */
1451       param_param_set_default,  /* value_set_default */
1452       param_param_validate,     /* value_validate */
1453       param_pointer_values_cmp, /* values_cmp */
1454     };
1455     type = g_param_type_register_static (g_intern_static_string ("GParamParam"), &pspec_info);
1456     *spec_types++ = type;
1457     g_assert (type == G_TYPE_PARAM_PARAM);
1458   }
1459   
1460   /* G_TYPE_PARAM_BOXED
1461    */
1462   {
1463     static const GParamSpecTypeInfo pspec_info = {
1464       sizeof (GParamSpecBoxed), /* instance_size */
1465       4,                        /* n_preallocs */
1466       param_boxed_init,         /* instance_init */
1467       G_TYPE_BOXED,             /* value_type */
1468       NULL,                     /* finalize */
1469       param_boxed_set_default,  /* value_set_default */
1470       param_boxed_validate,     /* value_validate */
1471       param_boxed_values_cmp,   /* values_cmp */
1472     };
1473     type = g_param_type_register_static (g_intern_static_string ("GParamBoxed"), &pspec_info);
1474     *spec_types++ = type;
1475     g_assert (type == G_TYPE_PARAM_BOXED);
1476   }
1477
1478   /* G_TYPE_PARAM_POINTER
1479    */
1480   {
1481     static const GParamSpecTypeInfo pspec_info = {
1482       sizeof (GParamSpecPointer),  /* instance_size */
1483       0,                           /* n_preallocs */
1484       param_pointer_init,          /* instance_init */
1485       G_TYPE_POINTER,              /* value_type */
1486       NULL,                        /* finalize */
1487       param_pointer_set_default,   /* value_set_default */
1488       param_pointer_validate,      /* value_validate */
1489       param_pointer_values_cmp,    /* values_cmp */
1490     };
1491     type = g_param_type_register_static (g_intern_static_string ("GParamPointer"), &pspec_info);
1492     *spec_types++ = type;
1493     g_assert (type == G_TYPE_PARAM_POINTER);
1494   }
1495   
1496   /* G_TYPE_PARAM_VALUE_ARRAY
1497    */
1498   {
1499     static /* const */ GParamSpecTypeInfo pspec_info = {
1500       sizeof (GParamSpecValueArray),    /* instance_size */
1501       0,                                /* n_preallocs */
1502       param_value_array_init,           /* instance_init */
1503       0xdeadbeef,                       /* value_type, assigned further down */
1504       param_value_array_finalize,       /* finalize */
1505       param_value_array_set_default,    /* value_set_default */
1506       param_value_array_validate,       /* value_validate */
1507       param_value_array_values_cmp,     /* values_cmp */
1508     };
1509     pspec_info.value_type = G_TYPE_VALUE_ARRAY;
1510     type = g_param_type_register_static (g_intern_static_string ("GParamValueArray"), &pspec_info);
1511     *spec_types++ = type;
1512     g_assert (type == G_TYPE_PARAM_VALUE_ARRAY);
1513   }
1514
1515   /* G_TYPE_PARAM_OBJECT
1516    */
1517   {
1518     static const GParamSpecTypeInfo pspec_info = {
1519       sizeof (GParamSpecObject), /* instance_size */
1520       16,                        /* n_preallocs */
1521       param_object_init,         /* instance_init */
1522       G_TYPE_OBJECT,             /* value_type */
1523       NULL,                      /* finalize */
1524       param_object_set_default,  /* value_set_default */
1525       param_object_validate,     /* value_validate */
1526       param_object_values_cmp,   /* values_cmp */
1527     };
1528     type = g_param_type_register_static (g_intern_static_string ("GParamObject"), &pspec_info);
1529     *spec_types++ = type;
1530     g_assert (type == G_TYPE_PARAM_OBJECT);
1531   }
1532
1533   /* G_TYPE_PARAM_OVERRIDE
1534    */
1535   {
1536     static const GParamSpecTypeInfo pspec_info = {
1537       sizeof (GParamSpecOverride), /* instance_size */
1538       16,                        /* n_preallocs */
1539       param_override_init,       /* instance_init */
1540       G_TYPE_NONE,               /* value_type */
1541       param_override_finalize,   /* finalize */
1542       param_override_set_default, /* value_set_default */
1543       param_override_validate,    /* value_validate */
1544       param_override_values_cmp,  /* values_cmp */
1545     };
1546     type = g_param_type_register_static (g_intern_static_string ("GParamOverride"), &pspec_info);
1547     *spec_types++ = type;
1548     g_assert (type == G_TYPE_PARAM_OVERRIDE);
1549   }
1550
1551   /* G_TYPE_PARAM_GTYPE
1552    */
1553   {
1554     GParamSpecTypeInfo pspec_info = {
1555       sizeof (GParamSpecGType), /* instance_size */
1556       0,                        /* n_preallocs */
1557       param_gtype_init,         /* instance_init */
1558       0xdeadbeef,               /* value_type, assigned further down */
1559       NULL,                     /* finalize */
1560       param_gtype_set_default,  /* value_set_default */
1561       param_gtype_validate,     /* value_validate */
1562       param_gtype_values_cmp,   /* values_cmp */
1563     };
1564     pspec_info.value_type = G_TYPE_GTYPE;
1565     type = g_param_type_register_static (g_intern_static_string ("GParamGType"), &pspec_info);
1566     *spec_types++ = type;
1567     g_assert (type == G_TYPE_PARAM_GTYPE);
1568   }
1569
1570   /* G_TYPE_PARAM_VARIANT
1571    */
1572   {
1573     const GParamSpecTypeInfo pspec_info = {
1574       sizeof (GParamSpecVariant), /* instance_size */
1575       0,                          /* n_preallocs */
1576       param_variant_init,         /* instance_init */
1577       G_TYPE_VARIANT,             /* value_type */
1578       param_variant_finalize,     /* finalize */
1579       param_variant_set_default,  /* value_set_default */
1580       param_variant_validate,     /* value_validate */
1581       param_variant_values_cmp,   /* values_cmp */
1582     };
1583     type = g_param_type_register_static (g_intern_static_string ("GParamVariant"), &pspec_info);
1584     *spec_types++ = type;
1585     g_assert (type == G_TYPE_PARAM_VARIANT);
1586   }
1587
1588   g_assert (spec_types == spec_types_bound);
1589 }
1590
1591 /* --- GParamSpec initialization --- */
1592
1593 /**
1594  * g_param_spec_char:
1595  * @name: canonical name of the property specified
1596  * @nick: nick name for the property specified
1597  * @blurb: description of the property specified
1598  * @minimum: minimum value for the property specified
1599  * @maximum: maximum value for the property specified
1600  * @default_value: default value for the property specified
1601  * @flags: flags for the property specified
1602  *
1603  * Creates a new #GParamSpecChar instance specifying a %G_TYPE_CHAR property.
1604  *
1605  * Returns: a newly created parameter specification
1606  */
1607 GParamSpec*
1608 g_param_spec_char (const gchar *name,
1609                    const gchar *nick,
1610                    const gchar *blurb,
1611                    gint8        minimum,
1612                    gint8        maximum,
1613                    gint8        default_value,
1614                    GParamFlags  flags)
1615 {
1616   GParamSpecChar *cspec;
1617
1618   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1619
1620   cspec = g_param_spec_internal (G_TYPE_PARAM_CHAR,
1621                                  name,
1622                                  nick,
1623                                  blurb,
1624                                  flags);
1625   
1626   cspec->minimum = minimum;
1627   cspec->maximum = maximum;
1628   cspec->default_value = default_value;
1629   
1630   return G_PARAM_SPEC (cspec);
1631 }
1632
1633 /**
1634  * g_param_spec_uchar:
1635  * @name: canonical name of the property specified
1636  * @nick: nick name for the property specified
1637  * @blurb: description of the property specified
1638  * @minimum: minimum value for the property specified
1639  * @maximum: maximum value for the property specified
1640  * @default_value: default value for the property specified
1641  * @flags: flags for the property specified
1642  *
1643  * Creates a new #GParamSpecUChar instance specifying a %G_TYPE_UCHAR property.
1644  *
1645  * Returns: a newly created parameter specification
1646  */
1647 GParamSpec*
1648 g_param_spec_uchar (const gchar *name,
1649                     const gchar *nick,
1650                     const gchar *blurb,
1651                     guint8       minimum,
1652                     guint8       maximum,
1653                     guint8       default_value,
1654                     GParamFlags  flags)
1655 {
1656   GParamSpecUChar *uspec;
1657
1658   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1659
1660   uspec = g_param_spec_internal (G_TYPE_PARAM_UCHAR,
1661                                  name,
1662                                  nick,
1663                                  blurb,
1664                                  flags);
1665   
1666   uspec->minimum = minimum;
1667   uspec->maximum = maximum;
1668   uspec->default_value = default_value;
1669   
1670   return G_PARAM_SPEC (uspec);
1671 }
1672
1673 /**
1674  * g_param_spec_boolean:
1675  * @name: canonical name of the property specified
1676  * @nick: nick name for the property specified
1677  * @blurb: description of the property specified
1678  * @default_value: default value for the property specified
1679  * @flags: flags for the property specified
1680  *
1681  * Creates a new #GParamSpecBoolean instance specifying a %G_TYPE_BOOLEAN
1682  * property.
1683  *
1684  * See g_param_spec_internal() for details on property names.
1685  *
1686  * Returns: a newly created parameter specification
1687  */
1688 GParamSpec*
1689 g_param_spec_boolean (const gchar *name,
1690                       const gchar *nick,
1691                       const gchar *blurb,
1692                       gboolean     default_value,
1693                       GParamFlags  flags)
1694 {
1695   GParamSpecBoolean *bspec;
1696
1697   g_return_val_if_fail (default_value == TRUE || default_value == FALSE, NULL);
1698
1699   bspec = g_param_spec_internal (G_TYPE_PARAM_BOOLEAN,
1700                                  name,
1701                                  nick,
1702                                  blurb,
1703                                  flags);
1704   
1705   bspec->default_value = default_value;
1706   
1707   return G_PARAM_SPEC (bspec);
1708 }
1709
1710 /**
1711  * g_param_spec_int:
1712  * @name: canonical name of the property specified
1713  * @nick: nick name for the property specified
1714  * @blurb: description of the property specified
1715  * @minimum: minimum value for the property specified
1716  * @maximum: maximum value for the property specified
1717  * @default_value: default value for the property specified
1718  * @flags: flags for the property specified
1719  *
1720  * Creates a new #GParamSpecInt instance specifying a %G_TYPE_INT property.
1721  *
1722  * See g_param_spec_internal() for details on property names.
1723  *
1724  * Returns: a newly created parameter specification
1725  */
1726 GParamSpec*
1727 g_param_spec_int (const gchar *name,
1728                   const gchar *nick,
1729                   const gchar *blurb,
1730                   gint         minimum,
1731                   gint         maximum,
1732                   gint         default_value,
1733                   GParamFlags  flags)
1734 {
1735   GParamSpecInt *ispec;
1736
1737   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1738
1739   ispec = g_param_spec_internal (G_TYPE_PARAM_INT,
1740                                  name,
1741                                  nick,
1742                                  blurb,
1743                                  flags);
1744   
1745   ispec->minimum = minimum;
1746   ispec->maximum = maximum;
1747   ispec->default_value = default_value;
1748   
1749   return G_PARAM_SPEC (ispec);
1750 }
1751
1752 /**
1753  * g_param_spec_uint:
1754  * @name: canonical name of the property specified
1755  * @nick: nick name for the property specified
1756  * @blurb: description of the property specified
1757  * @minimum: minimum value for the property specified
1758  * @maximum: maximum value for the property specified
1759  * @default_value: default value for the property specified
1760  * @flags: flags for the property specified
1761  *
1762  * Creates a new #GParamSpecUInt instance specifying a %G_TYPE_UINT property.
1763  *
1764  * See g_param_spec_internal() for details on property names.
1765  *
1766  * Returns: a newly created parameter specification
1767  */
1768 GParamSpec*
1769 g_param_spec_uint (const gchar *name,
1770                    const gchar *nick,
1771                    const gchar *blurb,
1772                    guint        minimum,
1773                    guint        maximum,
1774                    guint        default_value,
1775                    GParamFlags  flags)
1776 {
1777   GParamSpecUInt *uspec;
1778
1779   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1780
1781   uspec = g_param_spec_internal (G_TYPE_PARAM_UINT,
1782                                  name,
1783                                  nick,
1784                                  blurb,
1785                                  flags);
1786   
1787   uspec->minimum = minimum;
1788   uspec->maximum = maximum;
1789   uspec->default_value = default_value;
1790   
1791   return G_PARAM_SPEC (uspec);
1792 }
1793
1794 /**
1795  * g_param_spec_long:
1796  * @name: canonical name of the property specified
1797  * @nick: nick name for the property specified
1798  * @blurb: description of the property specified
1799  * @minimum: minimum value for the property specified
1800  * @maximum: maximum value for the property specified
1801  * @default_value: default value for the property specified
1802  * @flags: flags for the property specified
1803  *
1804  * Creates a new #GParamSpecLong instance specifying a %G_TYPE_LONG property.
1805  *
1806  * See g_param_spec_internal() for details on property names.
1807  *
1808  * Returns: a newly created parameter specification
1809  */
1810 GParamSpec*
1811 g_param_spec_long (const gchar *name,
1812                    const gchar *nick,
1813                    const gchar *blurb,
1814                    glong        minimum,
1815                    glong        maximum,
1816                    glong        default_value,
1817                    GParamFlags  flags)
1818 {
1819   GParamSpecLong *lspec;
1820
1821   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1822
1823   lspec = g_param_spec_internal (G_TYPE_PARAM_LONG,
1824                                  name,
1825                                  nick,
1826                                  blurb,
1827                                  flags);
1828   
1829   lspec->minimum = minimum;
1830   lspec->maximum = maximum;
1831   lspec->default_value = default_value;
1832   
1833   return G_PARAM_SPEC (lspec);
1834 }
1835
1836 /**
1837  * g_param_spec_ulong:
1838  * @name: canonical name of the property specified
1839  * @nick: nick name for the property specified
1840  * @blurb: description of the property specified
1841  * @minimum: minimum value for the property specified
1842  * @maximum: maximum value for the property specified
1843  * @default_value: default value for the property specified
1844  * @flags: flags for the property specified
1845  *
1846  * Creates a new #GParamSpecULong instance specifying a %G_TYPE_ULONG
1847  * property.
1848  *
1849  * See g_param_spec_internal() for details on property names.
1850  *
1851  * Returns: a newly created parameter specification
1852  */
1853 GParamSpec*
1854 g_param_spec_ulong (const gchar *name,
1855                     const gchar *nick,
1856                     const gchar *blurb,
1857                     gulong       minimum,
1858                     gulong       maximum,
1859                     gulong       default_value,
1860                     GParamFlags  flags)
1861 {
1862   GParamSpecULong *uspec;
1863
1864   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1865
1866   uspec = g_param_spec_internal (G_TYPE_PARAM_ULONG,
1867                                  name,
1868                                  nick,
1869                                  blurb,
1870                                  flags);
1871   
1872   uspec->minimum = minimum;
1873   uspec->maximum = maximum;
1874   uspec->default_value = default_value;
1875   
1876   return G_PARAM_SPEC (uspec);
1877 }
1878
1879 /**
1880  * g_param_spec_int64:
1881  * @name: canonical name of the property specified
1882  * @nick: nick name for the property specified
1883  * @blurb: description of the property specified
1884  * @minimum: minimum value for the property specified
1885  * @maximum: maximum value for the property specified
1886  * @default_value: default value for the property specified
1887  * @flags: flags for the property specified
1888  *
1889  * Creates a new #GParamSpecInt64 instance specifying a %G_TYPE_INT64 property.
1890  *
1891  * See g_param_spec_internal() for details on property names.
1892  *
1893  * Returns: a newly created parameter specification
1894  */
1895 GParamSpec*
1896 g_param_spec_int64 (const gchar *name,
1897                     const gchar *nick,
1898                     const gchar *blurb,
1899                     gint64       minimum,
1900                     gint64       maximum,
1901                     gint64       default_value,
1902                     GParamFlags  flags)
1903 {
1904   GParamSpecInt64 *lspec;
1905   
1906   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1907
1908   lspec = g_param_spec_internal (G_TYPE_PARAM_INT64,
1909                                  name,
1910                                  nick,
1911                                  blurb,
1912                                  flags);
1913   
1914   lspec->minimum = minimum;
1915   lspec->maximum = maximum;
1916   lspec->default_value = default_value;
1917   
1918   return G_PARAM_SPEC (lspec);
1919 }
1920
1921 /**
1922  * g_param_spec_uint64:
1923  * @name: canonical name of the property specified
1924  * @nick: nick name for the property specified
1925  * @blurb: description of the property specified
1926  * @minimum: minimum value for the property specified
1927  * @maximum: maximum value for the property specified
1928  * @default_value: default value for the property specified
1929  * @flags: flags for the property specified
1930  *
1931  * Creates a new #GParamSpecUInt64 instance specifying a %G_TYPE_UINT64
1932  * property.
1933  *
1934  * See g_param_spec_internal() for details on property names.
1935  *
1936  * Returns: a newly created parameter specification
1937  */
1938 GParamSpec*
1939 g_param_spec_uint64 (const gchar *name,
1940                      const gchar *nick,
1941                      const gchar *blurb,
1942                      guint64      minimum,
1943                      guint64      maximum,
1944                      guint64      default_value,
1945                      GParamFlags  flags)
1946 {
1947   GParamSpecUInt64 *uspec;
1948   
1949   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
1950   
1951   uspec = g_param_spec_internal (G_TYPE_PARAM_UINT64,
1952                                  name,
1953                                  nick,
1954                                  blurb,
1955                                  flags);
1956   
1957   uspec->minimum = minimum;
1958   uspec->maximum = maximum;
1959   uspec->default_value = default_value;
1960   
1961   return G_PARAM_SPEC (uspec);
1962 }
1963
1964 /**
1965  * g_param_spec_unichar:
1966  * @name: canonical name of the property specified
1967  * @nick: nick name for the property specified
1968  * @blurb: description of the property specified
1969  * @default_value: default value for the property specified
1970  * @flags: flags for the property specified
1971  *
1972  * Creates a new #GParamSpecUnichar instance specifying a %G_TYPE_UINT
1973  * property. #GValue structures for this property can be accessed with
1974  * g_value_set_uint() and g_value_get_uint().
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_unichar (const gchar *name,
1982                       const gchar *nick,
1983                       const gchar *blurb,
1984                       gunichar     default_value,
1985                       GParamFlags  flags)
1986 {
1987   GParamSpecUnichar *uspec;
1988
1989   uspec = g_param_spec_internal (G_TYPE_PARAM_UNICHAR,
1990                                  name,
1991                                  nick,
1992                                  blurb,
1993                                  flags);
1994   
1995   uspec->default_value = default_value;
1996   
1997   return G_PARAM_SPEC (uspec);
1998 }
1999
2000 /**
2001  * g_param_spec_enum:
2002  * @name: canonical name of the property specified
2003  * @nick: nick name for the property specified
2004  * @blurb: description of the property specified
2005  * @enum_type: a #GType derived from %G_TYPE_ENUM
2006  * @default_value: default value for the property specified
2007  * @flags: flags for the property specified
2008  *
2009  * Creates a new #GParamSpecEnum instance specifying a %G_TYPE_ENUM
2010  * property.
2011  *
2012  * See g_param_spec_internal() for details on property names.
2013  *
2014  * Returns: a newly created parameter specification
2015  */
2016 GParamSpec*
2017 g_param_spec_enum (const gchar *name,
2018                    const gchar *nick,
2019                    const gchar *blurb,
2020                    GType        enum_type,
2021                    gint         default_value,
2022                    GParamFlags  flags)
2023 {
2024   GParamSpecEnum *espec;
2025   GEnumClass *enum_class;
2026   
2027   g_return_val_if_fail (G_TYPE_IS_ENUM (enum_type), NULL);
2028
2029   enum_class = g_type_class_ref (enum_type);
2030
2031   g_return_val_if_fail (g_enum_get_value (enum_class, default_value) != NULL, NULL);
2032   
2033   espec = g_param_spec_internal (G_TYPE_PARAM_ENUM,
2034                                  name,
2035                                  nick,
2036                                  blurb,
2037                                  flags);
2038   
2039   espec->enum_class = enum_class;
2040   espec->default_value = default_value;
2041   G_PARAM_SPEC (espec)->value_type = enum_type;
2042   
2043   return G_PARAM_SPEC (espec);
2044 }
2045
2046 /**
2047  * g_param_spec_flags:
2048  * @name: canonical name of the property specified
2049  * @nick: nick name for the property specified
2050  * @blurb: description of the property specified
2051  * @flags_type: a #GType derived from %G_TYPE_FLAGS
2052  * @default_value: default value for the property specified
2053  * @flags: flags for the property specified
2054  *
2055  * Creates a new #GParamSpecFlags instance specifying a %G_TYPE_FLAGS
2056  * property.
2057  *
2058  * See g_param_spec_internal() for details on property names.
2059  *
2060  * Returns: a newly created parameter specification
2061  */
2062 GParamSpec*
2063 g_param_spec_flags (const gchar *name,
2064                     const gchar *nick,
2065                     const gchar *blurb,
2066                     GType        flags_type,
2067                     guint        default_value,
2068                     GParamFlags  flags)
2069 {
2070   GParamSpecFlags *fspec;
2071   GFlagsClass *flags_class;
2072   
2073   g_return_val_if_fail (G_TYPE_IS_FLAGS (flags_type), NULL);
2074
2075   flags_class = g_type_class_ref (flags_type);
2076
2077   g_return_val_if_fail ((default_value & flags_class->mask) == default_value, NULL);
2078   
2079   fspec = g_param_spec_internal (G_TYPE_PARAM_FLAGS,
2080                                  name,
2081                                  nick,
2082                                  blurb,
2083                                  flags);
2084   
2085   fspec->flags_class = flags_class;
2086   fspec->default_value = default_value;
2087   G_PARAM_SPEC (fspec)->value_type = flags_type;
2088   
2089   return G_PARAM_SPEC (fspec);
2090 }
2091
2092 /**
2093  * g_param_spec_float:
2094  * @name: canonical name of the property specified
2095  * @nick: nick name for the property specified
2096  * @blurb: description of the property specified
2097  * @minimum: minimum value for the property specified
2098  * @maximum: maximum value for the property specified
2099  * @default_value: default value for the property specified
2100  * @flags: flags for the property specified
2101  *
2102  * Creates a new #GParamSpecFloat instance specifying a %G_TYPE_FLOAT property.
2103  *
2104  * See g_param_spec_internal() for details on property names.
2105  *
2106  * Returns: a newly created parameter specification
2107  */
2108 GParamSpec*
2109 g_param_spec_float (const gchar *name,
2110                     const gchar *nick,
2111                     const gchar *blurb,
2112                     gfloat       minimum,
2113                     gfloat       maximum,
2114                     gfloat       default_value,
2115                     GParamFlags  flags)
2116 {
2117   GParamSpecFloat *fspec;
2118
2119   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
2120
2121   fspec = g_param_spec_internal (G_TYPE_PARAM_FLOAT,
2122                                  name,
2123                                  nick,
2124                                  blurb,
2125                                  flags);
2126   
2127   fspec->minimum = minimum;
2128   fspec->maximum = maximum;
2129   fspec->default_value = default_value;
2130   
2131   return G_PARAM_SPEC (fspec);
2132 }
2133
2134 /**
2135  * g_param_spec_double:
2136  * @name: canonical name of the property specified
2137  * @nick: nick name for the property specified
2138  * @blurb: description of the property specified
2139  * @minimum: minimum value for the property specified
2140  * @maximum: maximum value for the property specified
2141  * @default_value: default value for the property specified
2142  * @flags: flags for the property specified
2143  *
2144  * Creates a new #GParamSpecDouble instance specifying a %G_TYPE_DOUBLE
2145  * property.
2146  *
2147  * See g_param_spec_internal() for details on property names.
2148  *
2149  * Returns: a newly created parameter specification
2150  */
2151 GParamSpec*
2152 g_param_spec_double (const gchar *name,
2153                      const gchar *nick,
2154                      const gchar *blurb,
2155                      gdouble      minimum,
2156                      gdouble      maximum,
2157                      gdouble      default_value,
2158                      GParamFlags  flags)
2159 {
2160   GParamSpecDouble *dspec;
2161
2162   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
2163
2164   dspec = g_param_spec_internal (G_TYPE_PARAM_DOUBLE,
2165                                  name,
2166                                  nick,
2167                                  blurb,
2168                                  flags);
2169   
2170   dspec->minimum = minimum;
2171   dspec->maximum = maximum;
2172   dspec->default_value = default_value;
2173   
2174   return G_PARAM_SPEC (dspec);
2175 }
2176
2177 /**
2178  * g_param_spec_string:
2179  * @name: canonical name of the property specified
2180  * @nick: nick name for the property specified
2181  * @blurb: description of the property specified
2182  * @default_value: default value for the property specified
2183  * @flags: flags for the property specified
2184  *
2185  * Creates a new #GParamSpecString instance.
2186  *
2187  * See g_param_spec_internal() for details on property names.
2188  *
2189  * Returns: a newly created parameter specification
2190  */
2191 GParamSpec*
2192 g_param_spec_string (const gchar *name,
2193                      const gchar *nick,
2194                      const gchar *blurb,
2195                      const gchar *default_value,
2196                      GParamFlags  flags)
2197 {
2198   GParamSpecString *sspec = g_param_spec_internal (G_TYPE_PARAM_STRING,
2199                                                    name,
2200                                                    nick,
2201                                                    blurb,
2202                                                    flags);
2203   g_free (sspec->default_value);
2204   sspec->default_value = g_strdup (default_value);
2205   
2206   return G_PARAM_SPEC (sspec);
2207 }
2208
2209 /**
2210  * g_param_spec_param:
2211  * @name: canonical name of the property specified
2212  * @nick: nick name for the property specified
2213  * @blurb: description of the property specified
2214  * @param_type: a #GType derived from %G_TYPE_PARAM
2215  * @flags: flags for the property specified
2216  *
2217  * Creates a new #GParamSpecParam instance specifying a %G_TYPE_PARAM
2218  * property.
2219  *
2220  * See g_param_spec_internal() for details on property names.
2221  *
2222  * Returns: a newly created parameter specification
2223  */
2224 GParamSpec*
2225 g_param_spec_param (const gchar *name,
2226                     const gchar *nick,
2227                     const gchar *blurb,
2228                     GType        param_type,
2229                     GParamFlags  flags)
2230 {
2231   GParamSpecParam *pspec;
2232   
2233   g_return_val_if_fail (G_TYPE_IS_PARAM (param_type), NULL);
2234   
2235   pspec = g_param_spec_internal (G_TYPE_PARAM_PARAM,
2236                                  name,
2237                                  nick,
2238                                  blurb,
2239                                  flags);
2240   G_PARAM_SPEC (pspec)->value_type = param_type;
2241   
2242   return G_PARAM_SPEC (pspec);
2243 }
2244
2245 /**
2246  * g_param_spec_boxed:
2247  * @name: canonical name of the property specified
2248  * @nick: nick name for the property specified
2249  * @blurb: description of the property specified
2250  * @boxed_type: %G_TYPE_BOXED derived type of this property
2251  * @flags: flags for the property specified
2252  *
2253  * Creates a new #GParamSpecBoxed instance specifying a %G_TYPE_BOXED
2254  * derived property.
2255  *
2256  * See g_param_spec_internal() for details on property names.
2257  *
2258  * Returns: a newly created parameter specification
2259  */
2260 GParamSpec*
2261 g_param_spec_boxed (const gchar *name,
2262                     const gchar *nick,
2263                     const gchar *blurb,
2264                     GType        boxed_type,
2265                     GParamFlags  flags)
2266 {
2267   GParamSpecBoxed *bspec;
2268   
2269   g_return_val_if_fail (G_TYPE_IS_BOXED (boxed_type), NULL);
2270   g_return_val_if_fail (G_TYPE_IS_VALUE_TYPE (boxed_type), NULL);
2271   
2272   bspec = g_param_spec_internal (G_TYPE_PARAM_BOXED,
2273                                  name,
2274                                  nick,
2275                                  blurb,
2276                                  flags);
2277   G_PARAM_SPEC (bspec)->value_type = boxed_type;
2278   
2279   return G_PARAM_SPEC (bspec);
2280 }
2281
2282 /**
2283  * g_param_spec_pointer:
2284  * @name: canonical name of the property specified
2285  * @nick: nick name for the property specified
2286  * @blurb: description of the property specified
2287  * @flags: flags for the property specified
2288  *
2289  * Creates a new #GParamSpecPoiner instance specifying a pointer property.
2290  *
2291  * See g_param_spec_internal() for details on property names.
2292  *
2293  * Returns: a newly created parameter specification
2294  */
2295 GParamSpec*
2296 g_param_spec_pointer (const gchar *name,
2297                       const gchar *nick,
2298                       const gchar *blurb,
2299                       GParamFlags  flags)
2300 {
2301   GParamSpecPointer *pspec;
2302   
2303   pspec = g_param_spec_internal (G_TYPE_PARAM_POINTER,
2304                                  name,
2305                                  nick,
2306                                  blurb,
2307                                  flags);
2308   return G_PARAM_SPEC (pspec);
2309 }
2310
2311 /**
2312  * g_param_spec_gtype:
2313  * @name: canonical name of the property specified
2314  * @nick: nick name for the property specified
2315  * @blurb: description of the property specified
2316  * @is_a_type: a #GType whose subtypes are allowed as values
2317  *  of the property (use %G_TYPE_NONE for any type)
2318  * @flags: flags for the property specified
2319  *
2320  * Creates a new #GParamSpecGType instance specifying a
2321  * %G_TYPE_GTYPE property.
2322  *
2323  * See g_param_spec_internal() for details on property names.
2324  *
2325  * Since: 2.10
2326  *
2327  * Returns: a newly created parameter specification
2328  */
2329 GParamSpec*
2330 g_param_spec_gtype (const gchar *name,
2331                     const gchar *nick,
2332                     const gchar *blurb,
2333                     GType        is_a_type,
2334                     GParamFlags  flags)
2335 {
2336   GParamSpecGType *tspec;
2337   
2338   tspec = g_param_spec_internal (G_TYPE_PARAM_GTYPE,
2339                                  name,
2340                                  nick,
2341                                  blurb,
2342                                  flags);
2343
2344   tspec->is_a_type = is_a_type;
2345
2346   return G_PARAM_SPEC (tspec);
2347 }
2348
2349 /**
2350  * g_param_spec_value_array:
2351  * @name: canonical name of the property specified
2352  * @nick: nick name for the property specified
2353  * @blurb: description of the property specified
2354  * @element_spec: a #GParamSpec describing the elements contained in
2355  *  arrays of this property, may be %NULL
2356  * @flags: flags for the property specified
2357  *
2358  * Creates a new #GParamSpecValueArray instance specifying a
2359  * %G_TYPE_VALUE_ARRAY property. %G_TYPE_VALUE_ARRAY is a
2360  * %G_TYPE_BOXED type, as such, #GValue structures for this property
2361  * can be accessed with g_value_set_boxed() and g_value_get_boxed().
2362  *
2363  * See g_param_spec_internal() for details on property names.
2364  *
2365  * Returns: a newly created parameter specification
2366  */
2367 GParamSpec*
2368 g_param_spec_value_array (const gchar *name,
2369                           const gchar *nick,
2370                           const gchar *blurb,
2371                           GParamSpec  *element_spec,
2372                           GParamFlags  flags)
2373 {
2374   GParamSpecValueArray *aspec;
2375   
2376   if (element_spec)
2377     g_return_val_if_fail (G_IS_PARAM_SPEC (element_spec), NULL);
2378   
2379   aspec = g_param_spec_internal (G_TYPE_PARAM_VALUE_ARRAY,
2380                                  name,
2381                                  nick,
2382                                  blurb,
2383                                  flags);
2384   if (element_spec)
2385     {
2386       aspec->element_spec = g_param_spec_ref (element_spec);
2387       g_param_spec_sink (element_spec);
2388     }
2389
2390   return G_PARAM_SPEC (aspec);
2391 }
2392
2393 /**
2394  * g_param_spec_object:
2395  * @name: canonical name of the property specified
2396  * @nick: nick name for the property specified
2397  * @blurb: description of the property specified
2398  * @object_type: %G_TYPE_OBJECT derived type of this property
2399  * @flags: flags for the property specified
2400  *
2401  * Creates a new #GParamSpecBoxed instance specifying a %G_TYPE_OBJECT
2402  * derived property.
2403  *
2404  * See g_param_spec_internal() for details on property names.
2405  *
2406  * Returns: a newly created parameter specification
2407  */
2408 GParamSpec*
2409 g_param_spec_object (const gchar *name,
2410                      const gchar *nick,
2411                      const gchar *blurb,
2412                      GType        object_type,
2413                      GParamFlags  flags)
2414 {
2415   GParamSpecObject *ospec;
2416   
2417   g_return_val_if_fail (g_type_is_a (object_type, G_TYPE_OBJECT), NULL);
2418   
2419   ospec = g_param_spec_internal (G_TYPE_PARAM_OBJECT,
2420                                  name,
2421                                  nick,
2422                                  blurb,
2423                                  flags);
2424   G_PARAM_SPEC (ospec)->value_type = object_type;
2425   
2426   return G_PARAM_SPEC (ospec);
2427 }
2428
2429 /**
2430  * g_param_spec_override:
2431  * @name: the name of the property.
2432  * @overridden: The property that is being overridden
2433  *
2434  * Creates a new property of type #GParamSpecOverride. This is used
2435  * to direct operations to another paramspec, and will not be directly
2436  * useful unless you are implementing a new base type similar to GObject.
2437  *
2438  * Since: 2.4
2439  *
2440  * Returns: the newly created #GParamSpec
2441  */
2442 GParamSpec*
2443 g_param_spec_override (const gchar *name,
2444                        GParamSpec  *overridden)
2445 {
2446   GParamSpec *pspec;
2447   
2448   g_return_val_if_fail (name != NULL, NULL);
2449   g_return_val_if_fail (G_IS_PARAM_SPEC (overridden), NULL);
2450   
2451   /* Dereference further redirections for property that was passed in
2452    */
2453   while (TRUE)
2454     {
2455       GParamSpec *indirect = g_param_spec_get_redirect_target (overridden);
2456       if (indirect)
2457         overridden = indirect;
2458       else
2459         break;
2460     }
2461
2462   pspec = g_param_spec_internal (G_TYPE_PARAM_OVERRIDE,
2463                                  name, NULL, NULL,
2464                                  overridden->flags);
2465   
2466   pspec->value_type = G_PARAM_SPEC_VALUE_TYPE (overridden);
2467   G_PARAM_SPEC_OVERRIDE (pspec)->overridden = g_param_spec_ref (overridden);
2468
2469   return pspec;
2470 }
2471
2472 /**
2473  * g_param_spec_variant:
2474  * @name: canonical name of the property specified
2475  * @nick: nick name for the property specified
2476  * @blurb: description of the property specified
2477  * @type: a #GVariantType
2478  * @default_value: (allow-none): a #GVariant of type @type to use as the
2479  *                 default value, or %NULL
2480  * @flags: flags for the property specified
2481  *
2482  * Creates a new #GParamSpecVariant instance specifying a #GVariant
2483  * property.
2484  *
2485  * If @default_value is floating, it is consumed.
2486  *
2487  * See g_param_spec_internal() for details on property names.
2488  *
2489  * Returns: the newly created #GParamSpec
2490  *
2491  * Since: 2.26
2492  */
2493 GParamSpec*
2494 g_param_spec_variant (const gchar        *name,
2495                       const gchar        *nick,
2496                       const gchar        *blurb,
2497                       const GVariantType *type,
2498                       GVariant           *default_value,
2499                       GParamFlags         flags)
2500 {
2501   GParamSpecVariant *vspec;
2502
2503   g_return_val_if_fail (type != NULL, NULL);
2504   g_return_val_if_fail (default_value == NULL ||
2505                         g_variant_is_of_type (default_value, type), NULL);
2506
2507   vspec = g_param_spec_internal (G_TYPE_PARAM_VARIANT,
2508                                  name,
2509                                  nick,
2510                                  blurb,
2511                                  flags);
2512
2513   vspec->type = g_variant_type_copy (type);
2514   if (default_value)
2515     vspec->default_value = g_variant_ref_sink (default_value);
2516
2517   return G_PARAM_SPEC (vspec);
2518 }