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