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