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