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 --- */
63static void
64param_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
73static void
74param_char_set_default (GParamSpec *pspec,
75 GValue *value)
76{
77 value->data[0].v_int = G_PARAM_SPEC_CHAR (pspec)->default_value;
78}
79
80static gboolean
81param_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
92static void
93param_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
102static void
103param_uchar_set_default (GParamSpec *pspec,
104 GValue *value)
105{
106 value->data[0].v_uint = G_PARAM_SPEC_UCHAR (pspec)->default_value;
107}
108
109static gboolean
110param_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
121static void
122param_boolean_set_default (GParamSpec *pspec,
123 GValue *value)
124{
125 value->data[0].v_int = G_PARAM_SPEC_BOOLEAN (pspec)->default_value;
126}
127
128static gboolean
129param_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
139static void
140param_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
149static void
150param_int_set_default (GParamSpec *pspec,
151 GValue *value)
152{
153 value->data[0].v_int = G_PARAM_SPEC_INT (pspec)->default_value;
154}
155
156static gboolean
157param_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
168static gint
169param_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
179static void
180param_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
189static void
190param_uint_set_default (GParamSpec *pspec,
191 GValue *value)
192{
193 value->data[0].v_uint = G_PARAM_SPEC_UINT (pspec)->default_value;
194}
195
196static gboolean
197param_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
208static gint
209param_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
219static void
220param_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
234static void
235param_long_set_default (GParamSpec *pspec,
236 GValue *value)
237{
238 value->data[0].v_long = G_PARAM_SPEC_LONG (pspec)->default_value;
239}
240
241static gboolean
242param_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
253static gint
254param_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
264static void
265param_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
278static void
279param_ulong_set_default (GParamSpec *pspec,
280 GValue *value)
281{
282 value->data[0].v_ulong = G_PARAM_SPEC_ULONG (pspec)->default_value;
283}
284
285static gboolean
286param_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
297static gint
298param_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
308static void
309param_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
318static void
319param_int64_set_default (GParamSpec *pspec,
320 GValue *value)
321{
322 value->data[0].v_int64 = G_PARAM_SPEC_INT64 (pspec)->default_value;
323}
324
325static gboolean
326param_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
337static gint
338param_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
348static void
349param_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
358static void
359param_uint64_set_default (GParamSpec *pspec,
360 GValue *value)
361{
362 value->data[0].v_uint64 = G_PARAM_SPEC_UINT64 (pspec)->default_value;
363}
364
365static gboolean
366param_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
377static gint
378param_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
388static void
389param_unichar_init (GParamSpec *pspec)
390{
391 GParamSpecUnichar *uspec = G_PARAM_SPEC_UNICHAR (pspec);
392
393 uspec->default_value = 0;
394}
395
396static void
397param_unichar_set_default (GParamSpec *pspec,
398 GValue *value)
399{
400 value->data[0].v_uint = G_PARAM_SPEC_UNICHAR (pspec)->default_value;
401}
402
403static gboolean
404param_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 (ch: oval))
411 {
412 value->data[0].v_uint = 0;
413 changed = TRUE;
414 }
415
416 return changed;
417}
418
419static gint
420param_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
430static void
431param_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
439static void
440param_enum_finalize (GParamSpec *pspec)
441{
442 GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec);
443 GParamSpecClass *parent_class = g_type_class_peek (type: g_type_parent (G_TYPE_PARAM_ENUM));
444
445 if (espec->enum_class)
446 {
447 g_type_class_unref (g_class: espec->enum_class);
448 espec->enum_class = NULL;
449 }
450
451 parent_class->finalize (pspec);
452}
453
454static void
455param_enum_set_default (GParamSpec *pspec,
456 GValue *value)
457{
458 value->data[0].v_long = G_PARAM_SPEC_ENUM (pspec)->default_value;
459}
460
461static gboolean
462param_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 (enum_class: espec->enum_class, value: 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
475static void
476param_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
484static void
485param_flags_finalize (GParamSpec *pspec)
486{
487 GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec);
488 GParamSpecClass *parent_class = g_type_class_peek (type: g_type_parent (G_TYPE_PARAM_FLAGS));
489
490 if (fspec->flags_class)
491 {
492 g_type_class_unref (g_class: fspec->flags_class);
493 fspec->flags_class = NULL;
494 }
495
496 parent_class->finalize (pspec);
497}
498
499static void
500param_flags_set_default (GParamSpec *pspec,
501 GValue *value)
502{
503 value->data[0].v_ulong = G_PARAM_SPEC_FLAGS (pspec)->default_value;
504}
505
506static gboolean
507param_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
521static void
522param_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
532static void
533param_float_set_default (GParamSpec *pspec,
534 GValue *value)
535{
536 value->data[0].v_float = G_PARAM_SPEC_FLOAT (pspec)->default_value;
537}
538
539static gboolean
540param_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
551static gint
552param_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
564static void
565param_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
575static void
576param_double_set_default (GParamSpec *pspec,
577 GValue *value)
578{
579 value->data[0].v_double = G_PARAM_SPEC_DOUBLE (pspec)->default_value;
580}
581
582static gboolean
583param_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
594static gint
595param_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
607static void
608param_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
620static void
621param_string_finalize (GParamSpec *pspec)
622{
623 GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec);
624 GParamSpecClass *parent_class = g_type_class_peek (type: g_type_parent (G_TYPE_PARAM_STRING));
625
626 g_free (mem: sspec->default_value);
627 g_free (mem: sspec->cset_first);
628 g_free (mem: 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
636static void
637param_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
643static gboolean
644param_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 (s: sspec->cset_first, c: string[0]))
656 {
657 if (value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS)
658 {
659 value->data[0].v_pointer = g_strdup (str: 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 (s: sspec->cset_nth, c: *s))
669 {
670 if (value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS)
671 {
672 value->data[0].v_pointer = g_strdup (str: 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 (mem: 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 (str: "");
695 changed++;
696 string = value->data[0].v_pointer;
697 }
698
699 return changed;
700}
701
702static gint
703param_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 (s1: value1->data[0].v_pointer, s2: value2->data[0].v_pointer);
713}
714
715static void
716param_param_init (GParamSpec *pspec)
717{
718 /* GParamSpecParam *spec = G_PARAM_SPEC_PARAM (pspec); */
719}
720
721static void
722param_param_set_default (GParamSpec *pspec,
723 GValue *value)
724{
725 value->data[0].v_pointer = NULL;
726}
727
728static gboolean
729param_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 (pspec: param);
739 value->data[0].v_pointer = NULL;
740 changed++;
741 }
742
743 return changed;
744}
745
746static void
747param_boxed_init (GParamSpec *pspec)
748{
749 /* GParamSpecBoxed *bspec = G_PARAM_SPEC_BOXED (pspec); */
750}
751
752static void
753param_boxed_set_default (GParamSpec *pspec,
754 GValue *value)
755{
756 value->data[0].v_pointer = NULL;
757}
758
759static gboolean
760param_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
771static gint
772param_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
784static void
785param_pointer_init (GParamSpec *pspec)
786{
787 /* GParamSpecPointer *spec = G_PARAM_SPEC_POINTER (pspec); */
788}
789
790static void
791param_pointer_set_default (GParamSpec *pspec,
792 GValue *value)
793{
794 value->data[0].v_pointer = NULL;
795}
796
797static gboolean
798param_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
807static gint
808param_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
820static void
821param_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
829static inline guint
830value_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, index_: value_array->n_values - 1);
845 changed++;
846 }
847 }
848 return changed;
849}
850
851static void
852param_value_array_finalize (GParamSpec *pspec)
853{
854 GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
855 GParamSpecClass *parent_class = g_type_class_peek (type: g_type_parent (G_TYPE_PARAM_VALUE_ARRAY));
856
857 if (aspec->element_spec)
858 {
859 g_param_spec_unref (pspec: aspec->element_spec);
860 aspec->element_spec = NULL;
861 }
862
863 parent_class->finalize (pspec);
864}
865
866static void
867param_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 (n_prealloced: 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_array: value->data[0].v_pointer, fixed_n_elements: aspec->fixed_n_elements);
879 }
880}
881
882static gboolean
883param_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 (n_prealloced: 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, fixed_n_elements: 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 (value: element);
913 g_value_init (value: element, G_PARAM_SPEC_VALUE_TYPE (element_spec));
914 g_param_value_set_default (pspec: element_spec, value: element);
915 changed++;
916 }
917 else
918 {
919 /* validate array value against element_spec */
920 changed += g_param_value_validate (pspec: element_spec, value: element);
921 }
922 }
923 }
924 }
925
926 return changed;
927}
928
929static gint
930param_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 (pspec: aspec->element_spec, value1: element1, value2: element2);
964 if (cmp)
965 return cmp;
966 }
967 return 0;
968 }
969}
970
971static void
972param_object_init (GParamSpec *pspec)
973{
974 /* GParamSpecObject *ospec = G_PARAM_SPEC_OBJECT (pspec); */
975}
976
977static void
978param_object_set_default (GParamSpec *pspec,
979 GValue *value)
980{
981 value->data[0].v_pointer = NULL;
982}
983
984static gboolean
985param_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
1002static gint
1003param_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
1015static void
1016param_override_init (GParamSpec *pspec)
1017{
1018 /* GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec); */
1019}
1020
1021static void
1022param_override_finalize (GParamSpec *pspec)
1023{
1024 GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec);
1025 GParamSpecClass *parent_class = g_type_class_peek (type: g_type_parent (G_TYPE_PARAM_OVERRIDE));
1026
1027 if (ospec->overridden)
1028 {
1029 g_param_spec_unref (pspec: ospec->overridden);
1030 ospec->overridden = NULL;
1031 }
1032
1033 parent_class->finalize (pspec);
1034}
1035
1036static void
1037param_override_set_default (GParamSpec *pspec,
1038 GValue *value)
1039{
1040 GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec);
1041
1042 g_param_value_set_default (pspec: ospec->overridden, value);
1043}
1044
1045static gboolean
1046param_override_validate (GParamSpec *pspec,
1047 GValue *value)
1048{
1049 GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec);
1050
1051 return g_param_value_validate (pspec: ospec->overridden, value);
1052}
1053
1054static gint
1055param_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 (pspec: ospec->overridden, value1, value2);
1062}
1063
1064static void
1065param_gtype_init (GParamSpec *pspec)
1066{
1067}
1068
1069static void
1070param_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
1078static gboolean
1079param_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 (type: gtype, is_a_type: 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
1095static gint
1096param_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
1108static void
1109param_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
1117static void
1118param_variant_finalize (GParamSpec *pspec)
1119{
1120 GParamSpecVariant *vspec = G_PARAM_SPEC_VARIANT (pspec);
1121 GParamSpecClass *parent_class = g_type_class_peek (type: g_type_parent (G_TYPE_PARAM_VARIANT));
1122
1123 if (vspec->default_value)
1124 g_variant_unref (value: vspec->default_value);
1125 g_variant_type_free (type: vspec->type);
1126
1127 parent_class->finalize (pspec);
1128}
1129
1130static void
1131param_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
1138static gboolean
1139param_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 (value: variant, type: 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. */
1156static gboolean
1157variant_is_incomparable (GVariant *v)
1158{
1159 GVariantClass v_class = g_variant_classify (value: 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
1169static gint
1170param_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 (type1: g_variant_get_type (value: v1), type2: g_variant_get_type (value: v2)) ||
1185 variant_is_incomparable (v: v1) ||
1186 variant_is_incomparable (v: v2))
1187 return g_variant_equal (one: v1, two: v2) ? 0 : (v1 < v2 ? -1 : 1);
1188
1189 return g_variant_compare (one: v1, two: v2);
1190}
1191
1192/* --- type initialization --- */
1193GType *g_param_spec_types = NULL;
1194
1195void
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 (name: g_intern_static_string (string: "GParamChar"), pspec_info: &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 (name: g_intern_static_string (string: "GParamUChar"), pspec_info: &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 (name: g_intern_static_string (string: "GParamBoolean"), pspec_info: &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 (name: g_intern_static_string (string: "GParamInt"), pspec_info: &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 (name: g_intern_static_string (string: "GParamUInt"), pspec_info: &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 (name: g_intern_static_string (string: "GParamLong"), pspec_info: &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 (name: g_intern_static_string (string: "GParamULong"), pspec_info: &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 (name: g_intern_static_string (string: "GParamInt64"), pspec_info: &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 (name: g_intern_static_string (string: "GParamUInt64"), pspec_info: &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 (name: g_intern_static_string (string: "GParamUnichar"), pspec_info: &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 (name: g_intern_static_string (string: "GParamEnum"), pspec_info: &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 (name: g_intern_static_string (string: "GParamFlags"), pspec_info: &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 (name: g_intern_static_string (string: "GParamFloat"), pspec_info: &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 (name: g_intern_static_string (string: "GParamDouble"), pspec_info: &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 (name: g_intern_static_string (string: "GParamString"), pspec_info: &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 (name: g_intern_static_string (string: "GParamParam"), pspec_info: &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 (name: g_intern_static_string (string: "GParamBoxed"), pspec_info: &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 (name: g_intern_static_string (string: "GParamPointer"), pspec_info: &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 (name: g_intern_static_string (string: "GParamValueArray"), pspec_info: &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 (name: g_intern_static_string (string: "GParamObject"), pspec_info: &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 (name: g_intern_static_string (string: "GParamOverride"), pspec_info: &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 (name: g_intern_static_string (string: "GParamGType"), pspec_info: &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 (name: g_intern_static_string (string: "GParamVariant"), pspec_info: &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 */
1645GParamSpec*
1646g_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 */
1687GParamSpec*
1688g_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 */
1733GParamSpec*
1734g_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 */
1773GParamSpec*
1774g_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 */
1817GParamSpec*
1818g_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 */
1861GParamSpec*
1862g_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 */
1906GParamSpec*
1907g_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 */
1950GParamSpec*
1951g_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 */
1995GParamSpec*
1996g_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 */
2039GParamSpec*
2040g_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 */
2077GParamSpec*
2078g_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 (type: 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 (g_class: 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 */
2128GParamSpec*
2129g_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 (type: 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 (g_class: 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 */
2179GParamSpec*
2180g_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 */
2224GParamSpec*
2225g_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 */
2266GParamSpec*
2267g_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 (mem: sspec->default_value);
2282 sspec->default_value = g_strdup (str: 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 */
2302GParamSpec*
2303g_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 */
2341GParamSpec*
2342g_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 */
2381GParamSpec*
2382g_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 */
2418GParamSpec*
2419g_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 */
2458GParamSpec*
2459g_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 (pspec: element_spec);
2481 g_param_spec_sink (pspec: 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 */
2502GParamSpec*
2503g_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 */
2539GParamSpec*
2540g_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 (pspec: 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 flags: 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 (pspec: 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 */
2592GParamSpec*
2593g_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 (value: default_value);
2617
2618 return G_PARAM_SPEC (vspec);
2619}
2620

source code of gtk/subprojects/glib/gobject/gparamspecs.c