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