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