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