10b8ab3c6b6c082aa658b798d8e689c7df326d7c
[platform/upstream/glib.git] / gobject / gparamspecs.c
1 /* GObject - GLib Type, Object, Parameter and Signal Library
2  * Copyright (C) 1997, 1998, 1999, 2000 Tim Janik and Red Hat, Inc.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General
15  * Public License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19 #include        "gparamspecs.h"
20
21 #include        "gvaluecollector.h"
22 #include        <string.h>
23 #include        "../config.h"   /* for SIZEOF_LONG */
24
25 #define G_FLOAT_EPSILON         (1e-30)
26 #define G_DOUBLE_EPSILON        (1e-90)
27
28
29 /* --- param spec functions --- */
30 static void
31 param_spec_char_init (GParamSpec *pspec)
32 {
33   GParamSpecChar *cspec = G_PARAM_SPEC_CHAR (pspec);
34   
35   cspec->minimum = 0x7f;
36   cspec->maximum = 0x80;
37   cspec->default_value = 0;
38 }
39
40 static void
41 param_char_set_default (GParamSpec *pspec,
42                         GValue     *value)
43 {
44   value->data[0].v_int = G_PARAM_SPEC_CHAR (pspec)->default_value;
45 }
46
47 static gboolean
48 param_char_validate (GParamSpec *pspec,
49                      GValue     *value)
50 {
51   GParamSpecChar *cspec = G_PARAM_SPEC_CHAR (pspec);
52   gint oval = value->data[0].v_int;
53   
54   value->data[0].v_int = CLAMP (value->data[0].v_int, cspec->minimum, cspec->maximum);
55   
56   return value->data[0].v_int != oval;
57 }
58
59 static void
60 param_spec_uchar_init (GParamSpec *pspec)
61 {
62   GParamSpecUChar *uspec = G_PARAM_SPEC_UCHAR (pspec);
63   
64   uspec->minimum = 0;
65   uspec->maximum = 0xff;
66   uspec->default_value = 0;
67 }
68
69 static void
70 param_uchar_set_default (GParamSpec *pspec,
71                          GValue     *value)
72 {
73   value->data[0].v_uint = G_PARAM_SPEC_UCHAR (pspec)->default_value;
74 }
75
76 static gboolean
77 param_uchar_validate (GParamSpec *pspec,
78                       GValue     *value)
79 {
80   GParamSpecUChar *uspec = G_PARAM_SPEC_UCHAR (pspec);
81   guint oval = value->data[0].v_uint;
82   
83   value->data[0].v_uint = CLAMP (value->data[0].v_uint, uspec->minimum, uspec->maximum);
84   
85   return value->data[0].v_uint != oval;
86 }
87
88 static void
89 param_boolean_set_default (GParamSpec *pspec,
90                            GValue     *value)
91 {
92   value->data[0].v_int = G_PARAM_SPEC_BOOLEAN (pspec)->default_value;
93 }
94
95 static gboolean
96 param_boolean_validate (GParamSpec *pspec,
97                         GValue     *value)
98 {
99   gint oval = value->data[0].v_int;
100   
101   value->data[0].v_int = value->data[0].v_int != FALSE;
102   
103   return value->data[0].v_int != oval;
104 }
105
106 static void
107 param_spec_int_init (GParamSpec *pspec)
108 {
109   GParamSpecInt *ispec = G_PARAM_SPEC_INT (pspec);
110   
111   ispec->minimum = 0x7fffffff;
112   ispec->maximum = 0x80000000;
113   ispec->default_value = 0;
114 }
115
116 static void
117 param_int_set_default (GParamSpec *pspec,
118                        GValue     *value)
119 {
120   value->data[0].v_int = G_PARAM_SPEC_INT (pspec)->default_value;
121 }
122
123 static gboolean
124 param_int_validate (GParamSpec *pspec,
125                     GValue     *value)
126 {
127   GParamSpecInt *ispec = G_PARAM_SPEC_INT (pspec);
128   gint oval = value->data[0].v_int;
129   
130   value->data[0].v_int = CLAMP (value->data[0].v_int, ispec->minimum, ispec->maximum);
131   
132   return value->data[0].v_int != oval;
133 }
134
135 static gint
136 param_int_values_cmp (GParamSpec   *pspec,
137                       const GValue *value1,
138                       const GValue *value2)
139 {
140   if (value1->data[0].v_int < value2->data[0].v_int)
141     return -1;
142   else
143     return value1->data[0].v_int > value2->data[0].v_int;
144 }
145
146 static void
147 param_spec_uint_init (GParamSpec *pspec)
148 {
149   GParamSpecUInt *uspec = G_PARAM_SPEC_UINT (pspec);
150   
151   uspec->minimum = 0;
152   uspec->maximum = 0xffffffff;
153   uspec->default_value = 0;
154 }
155
156 static void
157 param_uint_set_default (GParamSpec *pspec,
158                         GValue     *value)
159 {
160   value->data[0].v_uint = G_PARAM_SPEC_UINT (pspec)->default_value;
161 }
162
163 static gboolean
164 param_uint_validate (GParamSpec *pspec,
165                      GValue     *value)
166 {
167   GParamSpecUInt *uspec = G_PARAM_SPEC_UINT (pspec);
168   guint oval = value->data[0].v_uint;
169   
170   value->data[0].v_uint = CLAMP (value->data[0].v_uint, uspec->minimum, uspec->maximum);
171   
172   return value->data[0].v_uint != oval;
173 }
174
175 static gint
176 param_uint_values_cmp (GParamSpec   *pspec,
177                        const GValue *value1,
178                        const GValue *value2)
179 {
180   if (value1->data[0].v_uint < value2->data[0].v_uint)
181     return -1;
182   else
183     return value1->data[0].v_uint > value2->data[0].v_uint;
184 }
185
186 static void
187 param_spec_long_init (GParamSpec *pspec)
188 {
189   GParamSpecLong *lspec = G_PARAM_SPEC_LONG (pspec);
190   
191 #if SIZEOF_LONG == 4
192   lspec->minimum = 0x7fffffff;
193   lspec->maximum = 0x80000000;
194 #else /* SIZEOF_LONG != 4 (8) */
195   lspec->minimum = 0x7fffffffffffffff;
196   lspec->maximum = 0x8000000000000000;
197 #endif
198   lspec->default_value = 0;
199 }
200
201 static void
202 param_long_set_default (GParamSpec *pspec,
203                         GValue     *value)
204 {
205   value->data[0].v_long = G_PARAM_SPEC_LONG (pspec)->default_value;
206 }
207
208 static gboolean
209 param_long_validate (GParamSpec *pspec,
210                      GValue     *value)
211 {
212   GParamSpecLong *lspec = G_PARAM_SPEC_LONG (pspec);
213   glong oval = value->data[0].v_long;
214   
215   value->data[0].v_long = CLAMP (value->data[0].v_long, lspec->minimum, lspec->maximum);
216   
217   return value->data[0].v_long != oval;
218 }
219
220 static gint
221 param_long_values_cmp (GParamSpec   *pspec,
222                        const GValue *value1,
223                        const GValue *value2)
224 {
225   if (value1->data[0].v_long < value2->data[0].v_long)
226     return -1;
227   else
228     return value1->data[0].v_long > value2->data[0].v_long;
229 }
230
231 static void
232 param_spec_ulong_init (GParamSpec *pspec)
233 {
234   GParamSpecULong *uspec = G_PARAM_SPEC_ULONG (pspec);
235   
236   uspec->minimum = 0;
237 #if SIZEOF_LONG == 4
238   uspec->maximum = 0xffffffff;
239 #else /* SIZEOF_LONG != 4 (8) */
240   uspec->maximum = 0xffffffffffffffff;
241 #endif
242   uspec->default_value = 0;
243 }
244
245 static void
246 param_ulong_set_default (GParamSpec *pspec,
247                          GValue     *value)
248 {
249   value->data[0].v_ulong = G_PARAM_SPEC_ULONG (pspec)->default_value;
250 }
251
252 static gboolean
253 param_ulong_validate (GParamSpec *pspec,
254                       GValue     *value)
255 {
256   GParamSpecULong *uspec = G_PARAM_SPEC_ULONG (pspec);
257   gulong oval = value->data[0].v_ulong;
258   
259   value->data[0].v_ulong = CLAMP (value->data[0].v_ulong, uspec->minimum, uspec->maximum);
260   
261   return value->data[0].v_ulong != oval;
262 }
263
264 static gint
265 param_ulong_values_cmp (GParamSpec   *pspec,
266                         const GValue *value1,
267                         const GValue *value2)
268 {
269   if (value1->data[0].v_ulong < value2->data[0].v_ulong)
270     return -1;
271   else
272     return value1->data[0].v_ulong > value2->data[0].v_ulong;
273 }
274
275 static void
276 param_spec_enum_init (GParamSpec *pspec)
277 {
278   GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec);
279   
280   espec->enum_class = NULL;
281   espec->default_value = 0;
282 }
283
284 static void
285 param_spec_enum_finalize (GParamSpec *pspec)
286 {
287   GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec);
288   GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_ENUM));
289   
290   if (espec->enum_class)
291     {
292       g_type_class_unref (espec->enum_class);
293       espec->enum_class = NULL;
294     }
295   
296   parent_class->finalize (pspec);
297 }
298
299 static void
300 param_enum_set_default (GParamSpec *pspec,
301                         GValue     *value)
302 {
303   value->data[0].v_long = G_PARAM_SPEC_ENUM (pspec)->default_value;
304 }
305
306 static gboolean
307 param_enum_validate (GParamSpec *pspec,
308                      GValue     *value)
309 {
310   GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec);
311   glong oval = value->data[0].v_long;
312   
313   if (!espec->enum_class ||
314       !g_enum_get_value (espec->enum_class, value->data[0].v_long))
315     value->data[0].v_long = espec->default_value;
316   
317   return value->data[0].v_long != oval;
318 }
319
320 static void
321 param_spec_flags_init (GParamSpec *pspec)
322 {
323   GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec);
324   
325   fspec->flags_class = NULL;
326   fspec->default_value = 0;
327 }
328
329 static void
330 param_spec_flags_finalize (GParamSpec *pspec)
331 {
332   GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec);
333   GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_FLAGS));
334   
335   if (fspec->flags_class)
336     {
337       g_type_class_unref (fspec->flags_class);
338       fspec->flags_class = NULL;
339     }
340   
341   parent_class->finalize (pspec);
342 }
343
344 static void
345 param_flags_set_default (GParamSpec *pspec,
346                          GValue     *value)
347 {
348   value->data[0].v_ulong = G_PARAM_SPEC_FLAGS (pspec)->default_value;
349 }
350
351 static gboolean
352 param_flags_validate (GParamSpec *pspec,
353                       GValue     *value)
354 {
355   GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec);
356   gulong oval = value->data[0].v_ulong;
357   
358   if (fspec->flags_class)
359     value->data[0].v_ulong &= fspec->flags_class->mask;
360   else
361     value->data[0].v_ulong = fspec->default_value;
362   
363   return value->data[0].v_ulong != oval;
364 }
365
366 static void
367 param_spec_float_init (GParamSpec *pspec)
368 {
369   GParamSpecFloat *fspec = G_PARAM_SPEC_FLOAT (pspec);
370   
371   fspec->minimum = G_MINFLOAT;
372   fspec->maximum = G_MAXFLOAT;
373   fspec->default_value = 0;
374   fspec->epsilon = G_FLOAT_EPSILON;
375 }
376
377 static void
378 param_float_set_default (GParamSpec *pspec,
379                          GValue     *value)
380 {
381   value->data[0].v_float = G_PARAM_SPEC_FLOAT (pspec)->default_value;
382 }
383
384 static gboolean
385 param_float_validate (GParamSpec *pspec,
386                       GValue     *value)
387 {
388   GParamSpecFloat *fspec = G_PARAM_SPEC_FLOAT (pspec);
389   gfloat oval = value->data[0].v_float;
390   
391   value->data[0].v_float = CLAMP (value->data[0].v_float, fspec->minimum, fspec->maximum);
392   
393   return value->data[0].v_float != oval;
394 }
395
396 static gint
397 param_float_values_cmp (GParamSpec   *pspec,
398                         const GValue *value1,
399                         const GValue *value2)
400 {
401   gfloat epsilon = G_PARAM_SPEC_FLOAT (pspec)->epsilon;
402   
403   if (value1->data[0].v_float < value2->data[0].v_float)
404     return - (value2->data[0].v_float - value1->data[0].v_float > epsilon);
405   else
406     return value1->data[0].v_float - value2->data[0].v_float > epsilon;
407 }
408
409 static void
410 param_spec_double_init (GParamSpec *pspec)
411 {
412   GParamSpecDouble *dspec = G_PARAM_SPEC_DOUBLE (pspec);
413   
414   dspec->minimum = G_MINDOUBLE;
415   dspec->maximum = G_MAXDOUBLE;
416   dspec->default_value = 0;
417   dspec->epsilon = G_DOUBLE_EPSILON;
418 }
419
420 static void
421 param_double_set_default (GParamSpec *pspec,
422                           GValue     *value)
423 {
424   value->data[0].v_double = G_PARAM_SPEC_DOUBLE (pspec)->default_value;
425 }
426
427 static gboolean
428 param_double_validate (GParamSpec *pspec,
429                        GValue     *value)
430 {
431   GParamSpecDouble *dspec = G_PARAM_SPEC_DOUBLE (pspec);
432   gdouble oval = value->data[0].v_double;
433   
434   value->data[0].v_double = CLAMP (value->data[0].v_double, dspec->minimum, dspec->maximum);
435   
436   return value->data[0].v_double != oval;
437 }
438
439 static gint
440 param_double_values_cmp (GParamSpec   *pspec,
441                          const GValue *value1,
442                          const GValue *value2)
443 {
444   gdouble epsilon = G_PARAM_SPEC_DOUBLE (pspec)->epsilon;
445   
446   if (value1->data[0].v_double < value2->data[0].v_double)
447     return - (value2->data[0].v_double - value1->data[0].v_double > epsilon);
448   else
449     return value1->data[0].v_double - value2->data[0].v_double > epsilon;
450 }
451
452 static void
453 param_spec_string_init (GParamSpec *pspec)
454 {
455   GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec);
456   
457   sspec->default_value = NULL;
458   sspec->cset_first = NULL;
459   sspec->cset_nth = NULL;
460   sspec->substitutor = '_';
461   sspec->null_fold_if_empty = FALSE;
462   sspec->ensure_non_null = FALSE;
463 }
464
465 static void
466 param_spec_string_finalize (GParamSpec *pspec)
467 {
468   GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec);
469   GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_STRING));
470   
471   g_free (sspec->default_value);
472   g_free (sspec->cset_first);
473   g_free (sspec->cset_nth);
474   sspec->default_value = NULL;
475   sspec->cset_first = NULL;
476   sspec->cset_nth = NULL;
477   
478   parent_class->finalize (pspec);
479 }
480
481 static void
482 param_string_set_default (GParamSpec *pspec,
483                           GValue     *value)
484 {
485   value->data[0].v_pointer = g_strdup (G_PARAM_SPEC_STRING (pspec)->default_value);
486 }
487
488 static gboolean
489 param_string_validate (GParamSpec *pspec,
490                        GValue     *value)
491 {
492   GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec);
493   gchar *string = value->data[0].v_pointer;
494   guint changed = 0;
495   
496   if (string && string[0])
497     {
498       gchar *s;
499       
500       if (sspec->cset_first && !strchr (sspec->cset_first, string[0]))
501         {
502           string[0] = sspec->substitutor;
503           changed++;
504         }
505       if (sspec->cset_nth)
506         for (s = string + 1; *s; s++)
507           if (!strchr (sspec->cset_nth, *s))
508             {
509               *s = sspec->substitutor;
510               changed++;
511             }
512     }
513   if (sspec->null_fold_if_empty && string && string[0] == 0)
514     {
515       g_free (value->data[0].v_pointer);
516       value->data[0].v_pointer = NULL;
517       changed++;
518       string = value->data[0].v_pointer;
519     }
520   if (sspec->ensure_non_null && !string)
521     {
522       value->data[0].v_pointer = g_strdup ("");
523       changed++;
524       string = value->data[0].v_pointer;
525     }
526   
527   return changed;
528 }
529
530 static gint
531 param_string_values_cmp (GParamSpec   *pspec,
532                          const GValue *value1,
533                          const GValue *value2)
534 {
535   if (!value1->data[0].v_pointer)
536     return value2->data[0].v_pointer != NULL ? -1 : 0;
537   else if (!value2->data[0].v_pointer)
538     return value1->data[0].v_pointer != NULL;
539   else
540     return strcmp (value1->data[0].v_pointer, value2->data[0].v_pointer);
541 }
542
543 static void
544 param_spec_object_init (GParamSpec *pspec)
545 {
546   GParamSpecObject *ospec = G_PARAM_SPEC_OBJECT (pspec);
547   
548   ospec->object_type = G_TYPE_OBJECT;
549 }
550
551 static void
552 param_object_set_default (GParamSpec *pspec,
553                           GValue     *value)
554 {
555   value->data[0].v_pointer = NULL;
556 }
557
558 static gboolean
559 param_object_validate (GParamSpec *pspec,
560                        GValue     *value)
561 {
562   GParamSpecObject *ospec = G_PARAM_SPEC_OBJECT (pspec);
563   GObject *object = value->data[0].v_pointer;
564   guint changed = 0;
565   
566   if (object && !g_type_is_a (G_OBJECT_TYPE (object), ospec->object_type))
567     {
568       g_object_unref (object);
569       value->data[0].v_pointer = NULL;
570       changed++;
571     }
572   
573   return changed;
574 }
575
576 static gint
577 param_object_values_cmp (GParamSpec   *pspec,
578                          const GValue *value1,
579                          const GValue *value2)
580 {
581   return value1->data[0].v_pointer != value2->data[0].v_pointer;
582 }
583
584 static void
585 value_exch_memcpy (GValue *value1,
586                    GValue *value2)
587 {
588   GValue tmp_value;
589   memcpy (&tmp_value.data, &value1->data, sizeof (value1->data));
590   memcpy (&value1->data, &value2->data, sizeof (value1->data));
591   memcpy (&value2->data, &tmp_value.data, sizeof (value2->data));
592 }
593
594 static void
595 value_exch_long_int (GValue *value1,
596                      GValue *value2)
597 {
598   glong tmp = value1->data[0].v_long;
599   value1->data[0].v_long = value2->data[0].v_int;
600   value2->data[0].v_int = tmp;
601 }
602
603 static void
604 value_exch_long_uint (GValue *value1,
605                       GValue *value2)
606 {
607   glong tmp = value1->data[0].v_long;
608   value1->data[0].v_long = value2->data[0].v_uint;
609   value2->data[0].v_uint = tmp;
610 }
611
612 static void
613 value_exch_ulong_int (GValue *value1,
614                       GValue *value2)
615 {
616   gulong tmp = value1->data[0].v_ulong;
617   value1->data[0].v_ulong = value2->data[0].v_int;
618   value2->data[0].v_int = tmp;
619 }
620
621 static void
622 value_exch_ulong_uint (GValue *value1,
623                        GValue *value2)
624 {
625   gulong tmp = value1->data[0].v_ulong;
626   value1->data[0].v_ulong = value2->data[0].v_uint;
627   value2->data[0].v_uint = tmp;
628 }
629
630 static void
631 value_exch_float_int (GValue *value1,
632                       GValue *value2)
633 {
634   gfloat tmp = value1->data[0].v_float;
635   value1->data[0].v_float = value2->data[0].v_int;
636   value2->data[0].v_int = 0.5 + tmp;
637 }
638
639 static void
640 value_exch_float_uint (GValue *value1,
641                        GValue *value2)
642 {
643   gfloat tmp = value1->data[0].v_float;
644   value1->data[0].v_float = value2->data[0].v_uint;
645   value2->data[0].v_uint = 0.5 + tmp;
646 }
647
648 static void
649 value_exch_float_long (GValue *value1,
650                        GValue *value2)
651 {
652   gfloat tmp = value1->data[0].v_float;
653   value1->data[0].v_float = value2->data[0].v_long;
654   value2->data[0].v_long = 0.5 + tmp;
655 }
656
657 static void
658 value_exch_float_ulong (GValue *value1,
659                         GValue *value2)
660 {
661   gfloat tmp = value1->data[0].v_float;
662   value1->data[0].v_float = value2->data[0].v_ulong;
663   value2->data[0].v_ulong = 0.5 + tmp;
664 }
665
666 static void
667 value_exch_double_int (GValue *value1,
668                        GValue *value2)
669 {
670   gdouble tmp = value1->data[0].v_double;
671   value1->data[0].v_double = value2->data[0].v_int;
672   value2->data[0].v_int = 0.5 + tmp;
673 }
674
675 static void
676 value_exch_double_uint (GValue *value1,
677                         GValue *value2)
678 {
679   gdouble tmp = value1->data[0].v_double;
680   value1->data[0].v_double = value2->data[0].v_uint;
681   value2->data[0].v_uint = 0.5 + tmp;
682 }
683
684 static void
685 value_exch_double_long (GValue *value1,
686                         GValue *value2)
687 {
688   gdouble tmp = value1->data[0].v_double;
689   value1->data[0].v_double = value2->data[0].v_long;
690   value2->data[0].v_long = 0.5 + tmp;
691 }
692
693 static void
694 value_exch_double_ulong (GValue *value1,
695                          GValue *value2)
696 {
697   gdouble tmp = value1->data[0].v_double;
698   value1->data[0].v_double = value2->data[0].v_ulong;
699   value2->data[0].v_ulong = 0.5 + tmp;
700 }
701
702 static void
703 value_exch_double_float (GValue *value1,
704                          GValue *value2)
705 {
706   gdouble tmp = value1->data[0].v_double;
707   value1->data[0].v_double = value2->data[0].v_float;
708   value2->data[0].v_float = tmp;
709 }
710
711
712 /* --- type initialization --- */
713 void
714 g_param_spec_types_init (void)  /* sync with gtype.c */
715 {
716   GType type;
717   
718   /* G_TYPE_PARAM_CHAR
719    */
720   {
721     static const GParamSpecTypeInfo pspec_info = {
722       sizeof (GParamSpecChar),  /* instance_size */
723       16,                       /* n_preallocs */
724       param_spec_char_init,     /* instance_init */
725       G_TYPE_CHAR,              /* value_type */
726       NULL,                     /* finalize */
727       param_char_set_default,   /* value_set_default */
728       param_char_validate,      /* value_validate */
729       param_int_values_cmp,     /* values_cmp */
730     };
731     type = g_param_type_register_static ("GParamChar", &pspec_info);
732     g_assert (type == G_TYPE_PARAM_CHAR);
733   }
734   
735   /* G_TYPE_PARAM_UCHAR
736    */
737   {
738     static const GParamSpecTypeInfo pspec_info = {
739       sizeof (GParamSpecUChar), /* instance_size */
740       16,                       /* n_preallocs */
741       param_spec_uchar_init,    /* instance_init */
742       G_TYPE_UCHAR,             /* value_type */
743       NULL,                     /* finalize */
744       param_uchar_set_default,  /* value_set_default */
745       param_uchar_validate,     /* value_validate */
746       param_uint_values_cmp,    /* values_cmp */
747     };
748     type = g_param_type_register_static ("GParamUChar", &pspec_info);
749     g_assert (type == G_TYPE_PARAM_UCHAR);
750   }
751   
752   /* G_TYPE_PARAM_BOOLEAN
753    */
754   {
755     static const GParamSpecTypeInfo pspec_info = {
756       sizeof (GParamSpecBoolean), /* instance_size */
757       16,                         /* n_preallocs */
758       NULL,                       /* instance_init */
759       G_TYPE_BOOLEAN,             /* value_type */
760       NULL,                       /* finalize */
761       param_boolean_set_default,  /* value_set_default */
762       param_boolean_validate,     /* value_validate */
763       param_int_values_cmp,       /* values_cmp */
764     };
765     type = g_param_type_register_static ("GParamBoolean", &pspec_info);
766     g_assert (type == G_TYPE_PARAM_BOOLEAN);
767   }
768   
769   /* G_TYPE_PARAM_INT
770    */
771   {
772     static const GParamSpecTypeInfo pspec_info = {
773       sizeof (GParamSpecInt),   /* instance_size */
774       16,                       /* n_preallocs */
775       param_spec_int_init,      /* instance_init */
776       G_TYPE_INT,               /* value_type */
777       NULL,                     /* finalize */
778       param_int_set_default,    /* value_set_default */
779       param_int_validate,       /* value_validate */
780       param_int_values_cmp,     /* values_cmp */
781     };
782     type = g_param_type_register_static ("GParamInt", &pspec_info);
783     g_assert (type == G_TYPE_PARAM_INT);
784   }
785   
786   /* G_TYPE_PARAM_UINT
787    */
788   {
789     static const GParamSpecTypeInfo pspec_info = {
790       sizeof (GParamSpecUInt),  /* instance_size */
791       16,                       /* n_preallocs */
792       param_spec_uint_init,     /* instance_init */
793       G_TYPE_UINT,              /* value_type */
794       NULL,                     /* finalize */
795       param_uint_set_default,   /* value_set_default */
796       param_uint_validate,      /* value_validate */
797       param_uint_values_cmp,    /* values_cmp */
798     };
799     type = g_param_type_register_static ("GParamUInt", &pspec_info);
800     g_assert (type == G_TYPE_PARAM_UINT);
801   }
802   
803   /* G_TYPE_PARAM_LONG
804    */
805   {
806     static const GParamSpecTypeInfo pspec_info = {
807       sizeof (GParamSpecLong),  /* instance_size */
808       16,                       /* n_preallocs */
809       param_spec_long_init,     /* instance_init */
810       G_TYPE_LONG,              /* value_type */
811       NULL,                     /* finalize */
812       param_long_set_default,   /* value_set_default */
813       param_long_validate,      /* value_validate */
814       param_long_values_cmp,    /* values_cmp */
815     };
816     type = g_param_type_register_static ("GParamLong", &pspec_info);
817     g_assert (type == G_TYPE_PARAM_LONG);
818   }
819   
820   /* G_TYPE_PARAM_ULONG
821    */
822   {
823     static const GParamSpecTypeInfo pspec_info = {
824       sizeof (GParamSpecULong), /* instance_size */
825       16,                       /* n_preallocs */
826       param_spec_ulong_init,    /* instance_init */
827       G_TYPE_ULONG,             /* value_type */
828       NULL,                     /* finalize */
829       param_ulong_set_default,  /* value_set_default */
830       param_ulong_validate,     /* value_validate */
831       param_ulong_values_cmp,   /* values_cmp */
832     };
833     type = g_param_type_register_static ("GParamULong", &pspec_info);
834     g_assert (type == G_TYPE_PARAM_ULONG);
835   }
836   
837   /* G_TYPE_PARAM_ENUM
838    */
839   {
840     static const GParamSpecTypeInfo pspec_info = {
841       sizeof (GParamSpecEnum),  /* instance_size */
842       16,                       /* n_preallocs */
843       param_spec_enum_init,     /* instance_init */
844       G_TYPE_ENUM,              /* value_type */
845       param_spec_enum_finalize, /* finalize */
846       param_enum_set_default,   /* value_set_default */
847       param_enum_validate,      /* value_validate */
848       param_long_values_cmp,    /* values_cmp */
849     };
850     type = g_param_type_register_static ("GParamEnum", &pspec_info);
851     g_assert (type == G_TYPE_PARAM_ENUM);
852   }
853   
854   /* G_TYPE_PARAM_FLAGS
855    */
856   {
857     static const GParamSpecTypeInfo pspec_info = {
858       sizeof (GParamSpecFlags), /* instance_size */
859       16,                       /* n_preallocs */
860       param_spec_flags_init,    /* instance_init */
861       G_TYPE_FLAGS,             /* value_type */
862       param_spec_flags_finalize,/* finalize */
863       param_flags_set_default,  /* value_set_default */
864       param_flags_validate,     /* value_validate */
865       param_ulong_values_cmp,   /* values_cmp */
866     };
867     type = g_param_type_register_static ("GParamFlags", &pspec_info);
868     g_assert (type == G_TYPE_PARAM_FLAGS);
869   }
870   
871   /* G_TYPE_PARAM_FLOAT
872    */
873   {
874     static const GParamSpecTypeInfo pspec_info = {
875       sizeof (GParamSpecFloat), /* instance_size */
876       16,                       /* n_preallocs */
877       param_spec_float_init,    /* instance_init */
878       G_TYPE_FLOAT,             /* value_type */
879       NULL,                     /* finalize */
880       param_float_set_default,  /* value_set_default */
881       param_float_validate,     /* value_validate */
882       param_float_values_cmp,   /* values_cmp */
883     };
884     type = g_param_type_register_static ("GParamFloat", &pspec_info);
885     g_assert (type == G_TYPE_PARAM_FLOAT);
886   }
887   
888   /* G_TYPE_PARAM_DOUBLE
889    */
890   {
891     static const GParamSpecTypeInfo pspec_info = {
892       sizeof (GParamSpecDouble), /* instance_size */
893       16,                        /* n_preallocs */
894       param_spec_double_init,    /* instance_init */
895       G_TYPE_DOUBLE,             /* value_type */
896       NULL,                      /* finalize */
897       param_double_set_default,  /* value_set_default */
898       param_double_validate,     /* value_validate */
899       param_double_values_cmp,   /* values_cmp */
900     };
901     type = g_param_type_register_static ("GParamDouble", &pspec_info);
902     g_assert (type == G_TYPE_PARAM_DOUBLE);
903   }
904   
905   /* G_TYPE_PARAM_STRING
906    */
907   {
908     static const GParamSpecTypeInfo pspec_info = {
909       sizeof (GParamSpecString),  /* instance_size */
910       16,                         /* n_preallocs */
911       param_spec_string_init,     /* instance_init */
912       G_TYPE_STRING,              /* value_type */
913       param_spec_string_finalize, /* finalize */
914       param_string_set_default,   /* value_set_default */
915       param_string_validate,      /* value_validate */
916       param_string_values_cmp,    /* values_cmp */
917     };
918     type = g_param_type_register_static ("GParamString", &pspec_info);
919     g_assert (type == G_TYPE_PARAM_STRING);
920   }
921   
922   /* G_TYPE_PARAM_OBJECT
923    */
924   {
925     static const GParamSpecTypeInfo pspec_info = {
926       sizeof (GParamSpecObject), /* instance_size */
927       16,                        /* n_preallocs */
928       param_spec_object_init,    /* instance_init */
929       G_TYPE_OBJECT,             /* value_type */
930       NULL,                      /* finalize */
931       param_object_set_default,  /* value_set_default */
932       param_object_validate,     /* value_validate */
933       param_object_values_cmp,   /* values_cmp */
934     };
935     type = g_param_type_register_static ("GParamObject", &pspec_info);
936     g_assert (type == G_TYPE_PARAM_OBJECT);
937   }
938   
939   g_value_register_exchange_func (G_TYPE_CHAR,    G_TYPE_UCHAR,   value_exch_memcpy);
940   g_value_register_exchange_func (G_TYPE_CHAR,    G_TYPE_BOOLEAN, value_exch_memcpy);
941   g_value_register_exchange_func (G_TYPE_CHAR,    G_TYPE_INT,     value_exch_memcpy);
942   g_value_register_exchange_func (G_TYPE_CHAR,    G_TYPE_UINT,    value_exch_memcpy);
943   g_value_register_exchange_func (G_TYPE_CHAR,    G_TYPE_ENUM,    value_exch_memcpy);
944   g_value_register_exchange_func (G_TYPE_CHAR,    G_TYPE_FLAGS,   value_exch_memcpy); 
945   g_value_register_exchange_func (G_TYPE_UCHAR,   G_TYPE_BOOLEAN, value_exch_memcpy);
946   g_value_register_exchange_func (G_TYPE_UCHAR,   G_TYPE_INT,     value_exch_memcpy);
947   g_value_register_exchange_func (G_TYPE_UCHAR,   G_TYPE_UINT,    value_exch_memcpy);
948   g_value_register_exchange_func (G_TYPE_UCHAR,   G_TYPE_ENUM,    value_exch_memcpy);
949   g_value_register_exchange_func (G_TYPE_UCHAR,   G_TYPE_FLAGS,   value_exch_memcpy); 
950   g_value_register_exchange_func (G_TYPE_BOOLEAN, G_TYPE_INT,     value_exch_memcpy);
951   g_value_register_exchange_func (G_TYPE_BOOLEAN, G_TYPE_UINT,    value_exch_memcpy);
952   g_value_register_exchange_func (G_TYPE_BOOLEAN, G_TYPE_ENUM,    value_exch_memcpy);
953   g_value_register_exchange_func (G_TYPE_BOOLEAN, G_TYPE_FLAGS,   value_exch_memcpy); 
954   g_value_register_exchange_func (G_TYPE_INT,     G_TYPE_UINT,    value_exch_memcpy); 
955   g_value_register_exchange_func (G_TYPE_INT,     G_TYPE_ENUM,    value_exch_memcpy); 
956   g_value_register_exchange_func (G_TYPE_INT,     G_TYPE_FLAGS,   value_exch_memcpy); 
957   g_value_register_exchange_func (G_TYPE_UINT,    G_TYPE_ENUM,    value_exch_memcpy); 
958   g_value_register_exchange_func (G_TYPE_UINT,    G_TYPE_FLAGS,   value_exch_memcpy); 
959   g_value_register_exchange_func (G_TYPE_LONG,    G_TYPE_CHAR,    value_exch_long_int); 
960   g_value_register_exchange_func (G_TYPE_LONG,    G_TYPE_UCHAR,   value_exch_long_uint); 
961   g_value_register_exchange_func (G_TYPE_LONG,    G_TYPE_BOOLEAN, value_exch_long_int); 
962   g_value_register_exchange_func (G_TYPE_LONG,    G_TYPE_INT,     value_exch_long_int); 
963   g_value_register_exchange_func (G_TYPE_LONG,    G_TYPE_UINT,    value_exch_long_uint); 
964   g_value_register_exchange_func (G_TYPE_LONG,    G_TYPE_ULONG,   value_exch_memcpy); 
965   g_value_register_exchange_func (G_TYPE_LONG,    G_TYPE_ENUM,    value_exch_long_int); 
966   g_value_register_exchange_func (G_TYPE_LONG,    G_TYPE_FLAGS,   value_exch_long_uint); 
967   g_value_register_exchange_func (G_TYPE_ULONG,   G_TYPE_CHAR,    value_exch_ulong_int); 
968   g_value_register_exchange_func (G_TYPE_ULONG,   G_TYPE_UCHAR,   value_exch_ulong_uint); 
969   g_value_register_exchange_func (G_TYPE_ULONG,   G_TYPE_BOOLEAN, value_exch_ulong_int); 
970   g_value_register_exchange_func (G_TYPE_ULONG,   G_TYPE_INT,     value_exch_ulong_int); 
971   g_value_register_exchange_func (G_TYPE_ULONG,   G_TYPE_UINT,    value_exch_ulong_uint); 
972   g_value_register_exchange_func (G_TYPE_ULONG,   G_TYPE_ENUM,    value_exch_ulong_int); 
973   g_value_register_exchange_func (G_TYPE_ULONG,   G_TYPE_FLAGS,   value_exch_ulong_uint); 
974   g_value_register_exchange_func (G_TYPE_ENUM,    G_TYPE_FLAGS,   value_exch_memcpy); 
975   g_value_register_exchange_func (G_TYPE_FLOAT,   G_TYPE_CHAR,    value_exch_float_int); 
976   g_value_register_exchange_func (G_TYPE_FLOAT,   G_TYPE_UCHAR,   value_exch_float_uint); 
977   g_value_register_exchange_func (G_TYPE_FLOAT,   G_TYPE_BOOLEAN, value_exch_float_int); 
978   g_value_register_exchange_func (G_TYPE_FLOAT,   G_TYPE_INT,     value_exch_float_int); 
979   g_value_register_exchange_func (G_TYPE_FLOAT,   G_TYPE_UINT,    value_exch_float_uint); 
980   g_value_register_exchange_func (G_TYPE_FLOAT,   G_TYPE_LONG,    value_exch_float_long); 
981   g_value_register_exchange_func (G_TYPE_FLOAT,   G_TYPE_ULONG,   value_exch_float_ulong);
982   g_value_register_exchange_func (G_TYPE_FLOAT,   G_TYPE_ENUM,    value_exch_float_int); 
983   g_value_register_exchange_func (G_TYPE_FLOAT,   G_TYPE_FLAGS,   value_exch_float_uint); 
984   g_value_register_exchange_func (G_TYPE_DOUBLE,  G_TYPE_CHAR,    value_exch_double_int); 
985   g_value_register_exchange_func (G_TYPE_DOUBLE,  G_TYPE_UCHAR,   value_exch_double_uint); 
986   g_value_register_exchange_func (G_TYPE_DOUBLE,  G_TYPE_BOOLEAN, value_exch_double_int); 
987   g_value_register_exchange_func (G_TYPE_DOUBLE,  G_TYPE_INT,     value_exch_double_int); 
988   g_value_register_exchange_func (G_TYPE_DOUBLE,  G_TYPE_UINT,    value_exch_double_uint); 
989   g_value_register_exchange_func (G_TYPE_DOUBLE,  G_TYPE_LONG,    value_exch_double_long);
990   g_value_register_exchange_func (G_TYPE_DOUBLE,  G_TYPE_ULONG,   value_exch_double_ulong);
991   g_value_register_exchange_func (G_TYPE_DOUBLE,  G_TYPE_ENUM,    value_exch_double_int); 
992   g_value_register_exchange_func (G_TYPE_DOUBLE,  G_TYPE_FLAGS,   value_exch_double_uint);
993   g_value_register_exchange_func (G_TYPE_DOUBLE,  G_TYPE_FLOAT,   value_exch_double_float); 
994 }
995
996
997 /* --- GParamSpec initialization --- */
998 GParamSpec*
999 g_param_spec_char (const gchar *name,
1000                    const gchar *nick,
1001                    const gchar *blurb,
1002                    gint8        minimum,
1003                    gint8        maximum,
1004                    gint8        default_value,
1005                    GParamFlags  flags)
1006 {
1007   GParamSpecChar *cspec = g_param_spec_internal (G_TYPE_PARAM_CHAR,
1008                                                  name,
1009                                                  nick,
1010                                                  blurb,
1011                                                  flags);
1012   
1013   cspec->minimum = minimum;
1014   cspec->maximum = maximum;
1015   cspec->default_value = default_value;
1016   
1017   return G_PARAM_SPEC (cspec);
1018 }
1019
1020 GParamSpec*
1021 g_param_spec_uchar (const gchar *name,
1022                     const gchar *nick,
1023                     const gchar *blurb,
1024                     guint8       minimum,
1025                     guint8       maximum,
1026                     guint8       default_value,
1027                     GParamFlags  flags)
1028 {
1029   GParamSpecUChar *uspec = g_param_spec_internal (G_TYPE_PARAM_UCHAR,
1030                                                   name,
1031                                                   nick,
1032                                                   blurb,
1033                                                   flags);
1034   
1035   uspec->minimum = minimum;
1036   uspec->maximum = maximum;
1037   uspec->default_value = default_value;
1038   
1039   return G_PARAM_SPEC (uspec);
1040 }
1041
1042 GParamSpec*
1043 g_param_spec_boolean (const gchar *name,
1044                       const gchar *nick,
1045                       const gchar *blurb,
1046                       gboolean     default_value,
1047                       GParamFlags  flags)
1048 {
1049   GParamSpecBoolean *bspec = g_param_spec_internal (G_TYPE_PARAM_BOOLEAN,
1050                                                     name,
1051                                                     nick,
1052                                                     blurb,
1053                                                     flags);
1054   
1055   bspec->default_value = default_value;
1056   
1057   return G_PARAM_SPEC (bspec);
1058 }
1059
1060 GParamSpec*
1061 g_param_spec_int (const gchar *name,
1062                   const gchar *nick,
1063                   const gchar *blurb,
1064                   gint         minimum,
1065                   gint         maximum,
1066                   gint         default_value,
1067                   GParamFlags  flags)
1068 {
1069   GParamSpecInt *ispec = g_param_spec_internal (G_TYPE_PARAM_INT,
1070                                                 name,
1071                                                 nick,
1072                                                 blurb,
1073                                                 flags);
1074   
1075   ispec->minimum = minimum;
1076   ispec->maximum = maximum;
1077   ispec->default_value = default_value;
1078   
1079   return G_PARAM_SPEC (ispec);
1080 }
1081
1082 GParamSpec*
1083 g_param_spec_uint (const gchar *name,
1084                    const gchar *nick,
1085                    const gchar *blurb,
1086                    guint        minimum,
1087                    guint        maximum,
1088                    guint        default_value,
1089                    GParamFlags  flags)
1090 {
1091   GParamSpecUInt *uspec = g_param_spec_internal (G_TYPE_PARAM_UINT,
1092                                                  name,
1093                                                  nick,
1094                                                  blurb,
1095                                                  flags);
1096   
1097   uspec->minimum = minimum;
1098   uspec->maximum = maximum;
1099   uspec->default_value = default_value;
1100   
1101   return G_PARAM_SPEC (uspec);
1102 }
1103
1104 GParamSpec*
1105 g_param_spec_long (const gchar *name,
1106                    const gchar *nick,
1107                    const gchar *blurb,
1108                    glong        minimum,
1109                    glong        maximum,
1110                    glong        default_value,
1111                    GParamFlags  flags)
1112 {
1113   GParamSpecLong *lspec = g_param_spec_internal (G_TYPE_PARAM_LONG,
1114                                                  name,
1115                                                  nick,
1116                                                  blurb,
1117                                                  flags);
1118   
1119   lspec->minimum = minimum;
1120   lspec->maximum = maximum;
1121   lspec->default_value = default_value;
1122   
1123   return G_PARAM_SPEC (lspec);
1124 }
1125
1126 GParamSpec*
1127 g_param_spec_ulong (const gchar *name,
1128                     const gchar *nick,
1129                     const gchar *blurb,
1130                     gulong       minimum,
1131                     gulong       maximum,
1132                     gulong       default_value,
1133                     GParamFlags  flags)
1134 {
1135   GParamSpecULong *uspec = g_param_spec_internal (G_TYPE_PARAM_ULONG,
1136                                                   name,
1137                                                   nick,
1138                                                   blurb,
1139                                                   flags);
1140   
1141   uspec->minimum = minimum;
1142   uspec->maximum = maximum;
1143   uspec->default_value = default_value;
1144   
1145   return G_PARAM_SPEC (uspec);
1146 }
1147
1148 GParamSpec*
1149 g_param_spec_enum (const gchar *name,
1150                    const gchar *nick,
1151                    const gchar *blurb,
1152                    GType        enum_type,
1153                    gint         default_value,
1154                    GParamFlags  flags)
1155 {
1156   GParamSpecEnum *espec;
1157   
1158   g_return_val_if_fail (G_TYPE_IS_ENUM (enum_type), NULL);
1159   
1160   espec = g_param_spec_internal (G_TYPE_PARAM_ENUM,
1161                                  name,
1162                                  nick,
1163                                  blurb,
1164                                  flags);
1165   
1166   espec->enum_class = g_type_class_ref (enum_type);
1167   espec->default_value = default_value;
1168   
1169   return G_PARAM_SPEC (espec);
1170 }
1171
1172 GParamSpec*
1173 g_param_spec_flags (const gchar *name,
1174                     const gchar *nick,
1175                     const gchar *blurb,
1176                     GType        flags_type,
1177                     guint        default_value,
1178                     GParamFlags  flags)
1179 {
1180   GParamSpecFlags *fspec;
1181   
1182   g_return_val_if_fail (G_TYPE_IS_FLAGS (flags_type), NULL);
1183   
1184   fspec = g_param_spec_internal (G_TYPE_PARAM_FLAGS,
1185                                  name,
1186                                  nick,
1187                                  blurb,
1188                                  flags);
1189   
1190   fspec->flags_class = g_type_class_ref (flags_type);
1191   fspec->default_value = default_value;
1192   
1193   return G_PARAM_SPEC (fspec);
1194 }
1195
1196 GParamSpec*
1197 g_param_spec_float (const gchar *name,
1198                     const gchar *nick,
1199                     const gchar *blurb,
1200                     gfloat       minimum,
1201                     gfloat       maximum,
1202                     gfloat       default_value,
1203                     GParamFlags  flags)
1204 {
1205   GParamSpecFloat *fspec = g_param_spec_internal (G_TYPE_PARAM_FLOAT,
1206                                                   name,
1207                                                   nick,
1208                                                   blurb,
1209                                                   flags);
1210   
1211   fspec->minimum = minimum;
1212   fspec->maximum = maximum;
1213   fspec->default_value = default_value;
1214   
1215   return G_PARAM_SPEC (fspec);
1216 }
1217
1218 GParamSpec*
1219 g_param_spec_double (const gchar *name,
1220                      const gchar *nick,
1221                      const gchar *blurb,
1222                      gdouble      minimum,
1223                      gdouble      maximum,
1224                      gdouble      default_value,
1225                      GParamFlags  flags)
1226 {
1227   GParamSpecDouble *dspec = g_param_spec_internal (G_TYPE_PARAM_DOUBLE,
1228                                                    name,
1229                                                    nick,
1230                                                    blurb,
1231                                                    flags);
1232   
1233   dspec->minimum = minimum;
1234   dspec->maximum = maximum;
1235   dspec->default_value = default_value;
1236   
1237   return G_PARAM_SPEC (dspec);
1238 }
1239
1240 GParamSpec*
1241 g_param_spec_string (const gchar *name,
1242                      const gchar *nick,
1243                      const gchar *blurb,
1244                      const gchar *default_value,
1245                      GParamFlags  flags)
1246 {
1247   GParamSpecString *sspec = g_param_spec_internal (G_TYPE_PARAM_STRING,
1248                                                    name,
1249                                                    nick,
1250                                                    blurb,
1251                                                    flags);
1252   g_free (sspec->default_value);
1253   sspec->default_value = g_strdup (default_value);
1254   
1255   return G_PARAM_SPEC (sspec);
1256 }
1257
1258 GParamSpec*
1259 g_param_spec_string_c (const gchar *name,
1260                        const gchar *nick,
1261                        const gchar *blurb,
1262                        const gchar *default_value,
1263                        GParamFlags  flags)
1264 {
1265   GParamSpecString *sspec = g_param_spec_internal (G_TYPE_PARAM_STRING,
1266                                                    name,
1267                                                    nick,
1268                                                    blurb,
1269                                                    flags);
1270   g_free (sspec->default_value);
1271   sspec->default_value = g_strdup (default_value);
1272   g_free (sspec->cset_first);
1273   sspec->cset_first = g_strdup (G_CSET_a_2_z "_" G_CSET_A_2_Z);
1274   g_free (sspec->cset_nth);
1275   sspec->cset_nth = g_strdup (G_CSET_a_2_z
1276                               "_0123456789"
1277                               /* G_CSET_LATINS G_CSET_LATINC */
1278                               G_CSET_A_2_Z);
1279   
1280   return G_PARAM_SPEC (sspec);
1281 }
1282
1283 GParamSpec*
1284 g_param_spec_object (const gchar *name,
1285                      const gchar *nick,
1286                      const gchar *blurb,
1287                      GType        object_type,
1288                      GParamFlags  flags)
1289 {
1290   GParamSpecObject *ospec;
1291   
1292   g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type), NULL);
1293   
1294   ospec = g_param_spec_internal (G_TYPE_PARAM_OBJECT,
1295                                  name,
1296                                  nick,
1297                                  blurb,
1298                                  flags);
1299   ospec->object_type = object_type;
1300   
1301   return G_PARAM_SPEC (ospec);
1302 }