gparamspecs.c revision 617332234d4426ed0941ec1e2cb9f0736bd796c3
1/* GObject - GLib Type, Object, Parameter and Signal Library 2 * Copyright (C) 1997-1999, 2000-2001 Tim Janik and Red Hat, Inc. 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General 15 * Public License along with this library; if not, write to the 16 * Free Software Foundation, Inc., 59 Temple Place, Suite 330, 17 * Boston, MA 02111-1307, USA. 18 */ 19 20/* 21 * MT safe 22 */ 23 24#include "gparamspecs.h" 25 26#include "gvaluecollector.h" 27#include "gvaluearray.h" 28#include <string.h> 29#include "../config.h" /* for SIZEOF_LONG */ 30 31#define G_FLOAT_EPSILON (1e-30) 32#define G_DOUBLE_EPSILON (1e-90) 33 34 35/* --- param spec functions --- */ 36static void 37param_char_init (GParamSpec *pspec) 38{ 39 GParamSpecChar *cspec = G_PARAM_SPEC_CHAR (pspec); 40 41 cspec->minimum = 0x7f; 42 cspec->maximum = 0x80; 43 cspec->default_value = 0; 44} 45 46static void 47param_char_set_default (GParamSpec *pspec, 48 GValue *value) 49{ 50 value->data[0].v_int = G_PARAM_SPEC_CHAR (pspec)->default_value; 51} 52 53static gboolean 54param_char_validate (GParamSpec *pspec, 55 GValue *value) 56{ 57 GParamSpecChar *cspec = G_PARAM_SPEC_CHAR (pspec); 58 gint oval = value->data[0].v_int; 59 60 value->data[0].v_int = CLAMP (value->data[0].v_int, cspec->minimum, cspec->maximum); 61 62 return value->data[0].v_int != oval; 63} 64 65static void 66param_uchar_init (GParamSpec *pspec) 67{ 68 GParamSpecUChar *uspec = G_PARAM_SPEC_UCHAR (pspec); 69 70 uspec->minimum = 0; 71 uspec->maximum = 0xff; 72 uspec->default_value = 0; 73} 74 75static void 76param_uchar_set_default (GParamSpec *pspec, 77 GValue *value) 78{ 79 value->data[0].v_uint = G_PARAM_SPEC_UCHAR (pspec)->default_value; 80} 81 82static gboolean 83param_uchar_validate (GParamSpec *pspec, 84 GValue *value) 85{ 86 GParamSpecUChar *uspec = G_PARAM_SPEC_UCHAR (pspec); 87 guint oval = value->data[0].v_uint; 88 89 value->data[0].v_uint = CLAMP (value->data[0].v_uint, uspec->minimum, uspec->maximum); 90 91 return value->data[0].v_uint != oval; 92} 93 94static void 95param_boolean_set_default (GParamSpec *pspec, 96 GValue *value) 97{ 98 value->data[0].v_int = G_PARAM_SPEC_BOOLEAN (pspec)->default_value; 99} 100 101static gboolean 102param_boolean_validate (GParamSpec *pspec, 103 GValue *value) 104{ 105 gint oval = value->data[0].v_int; 106 107 value->data[0].v_int = value->data[0].v_int != FALSE; 108 109 return value->data[0].v_int != oval; 110} 111 112static void 113param_int_init (GParamSpec *pspec) 114{ 115 GParamSpecInt *ispec = G_PARAM_SPEC_INT (pspec); 116 117 ispec->minimum = 0x7fffffff; 118 ispec->maximum = 0x80000000; 119 ispec->default_value = 0; 120} 121 122static void 123param_int_set_default (GParamSpec *pspec, 124 GValue *value) 125{ 126 value->data[0].v_int = G_PARAM_SPEC_INT (pspec)->default_value; 127} 128 129static gboolean 130param_int_validate (GParamSpec *pspec, 131 GValue *value) 132{ 133 GParamSpecInt *ispec = G_PARAM_SPEC_INT (pspec); 134 gint oval = value->data[0].v_int; 135 136 value->data[0].v_int = CLAMP (value->data[0].v_int, ispec->minimum, ispec->maximum); 137 138 return value->data[0].v_int != oval; 139} 140 141static gint 142param_int_values_cmp (GParamSpec *pspec, 143 const GValue *value1, 144 const GValue *value2) 145{ 146 if (value1->data[0].v_int < value2->data[0].v_int) 147 return -1; 148 else 149 return value1->data[0].v_int > value2->data[0].v_int; 150} 151 152static void 153param_uint_init (GParamSpec *pspec) 154{ 155 GParamSpecUInt *uspec = G_PARAM_SPEC_UINT (pspec); 156 157 uspec->minimum = 0; 158 uspec->maximum = 0xffffffff; 159 uspec->default_value = 0; 160} 161 162static void 163param_uint_set_default (GParamSpec *pspec, 164 GValue *value) 165{ 166 value->data[0].v_uint = G_PARAM_SPEC_UINT (pspec)->default_value; 167} 168 169static gboolean 170param_uint_validate (GParamSpec *pspec, 171 GValue *value) 172{ 173 GParamSpecUInt *uspec = G_PARAM_SPEC_UINT (pspec); 174 guint oval = value->data[0].v_uint; 175 176 value->data[0].v_uint = CLAMP (value->data[0].v_uint, uspec->minimum, uspec->maximum); 177 178 return value->data[0].v_uint != oval; 179} 180 181static gint 182param_uint_values_cmp (GParamSpec *pspec, 183 const GValue *value1, 184 const GValue *value2) 185{ 186 if (value1->data[0].v_uint < value2->data[0].v_uint) 187 return -1; 188 else 189 return value1->data[0].v_uint > value2->data[0].v_uint; 190} 191 192static void 193param_long_init (GParamSpec *pspec) 194{ 195 GParamSpecLong *lspec = G_PARAM_SPEC_LONG (pspec); 196 197#if SIZEOF_LONG == 4 198 lspec->minimum = 0x7fffffff; 199 lspec->maximum = 0x80000000; 200#else /* SIZEOF_LONG != 4 (8) */ 201 lspec->minimum = 0x7fffffffffffffff; 202 lspec->maximum = 0x8000000000000000; 203#endif 204 lspec->default_value = 0; 205} 206 207static void 208param_long_set_default (GParamSpec *pspec, 209 GValue *value) 210{ 211 value->data[0].v_long = G_PARAM_SPEC_LONG (pspec)->default_value; 212} 213 214static gboolean 215param_long_validate (GParamSpec *pspec, 216 GValue *value) 217{ 218 GParamSpecLong *lspec = G_PARAM_SPEC_LONG (pspec); 219 glong oval = value->data[0].v_long; 220 221 value->data[0].v_long = CLAMP (value->data[0].v_long, lspec->minimum, lspec->maximum); 222 223 return value->data[0].v_long != oval; 224} 225 226static gint 227param_long_values_cmp (GParamSpec *pspec, 228 const GValue *value1, 229 const GValue *value2) 230{ 231 if (value1->data[0].v_long < value2->data[0].v_long) 232 return -1; 233 else 234 return value1->data[0].v_long > value2->data[0].v_long; 235} 236 237static void 238param_ulong_init (GParamSpec *pspec) 239{ 240 GParamSpecULong *uspec = G_PARAM_SPEC_ULONG (pspec); 241 242 uspec->minimum = 0; 243#if SIZEOF_LONG == 4 244 uspec->maximum = 0xffffffff; 245#else /* SIZEOF_LONG != 4 (8) */ 246 uspec->maximum = 0xffffffffffffffff; 247#endif 248 uspec->default_value = 0; 249} 250 251static void 252param_ulong_set_default (GParamSpec *pspec, 253 GValue *value) 254{ 255 value->data[0].v_ulong = G_PARAM_SPEC_ULONG (pspec)->default_value; 256} 257 258static gboolean 259param_ulong_validate (GParamSpec *pspec, 260 GValue *value) 261{ 262 GParamSpecULong *uspec = G_PARAM_SPEC_ULONG (pspec); 263 gulong oval = value->data[0].v_ulong; 264 265 value->data[0].v_ulong = CLAMP (value->data[0].v_ulong, uspec->minimum, uspec->maximum); 266 267 return value->data[0].v_ulong != oval; 268} 269 270static gint 271param_ulong_values_cmp (GParamSpec *pspec, 272 const GValue *value1, 273 const GValue *value2) 274{ 275 if (value1->data[0].v_ulong < value2->data[0].v_ulong) 276 return -1; 277 else 278 return value1->data[0].v_ulong > value2->data[0].v_ulong; 279} 280 281static void 282param_enum_init (GParamSpec *pspec) 283{ 284 GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec); 285 286 espec->enum_class = NULL; 287 espec->default_value = 0; 288} 289 290static void 291param_enum_finalize (GParamSpec *pspec) 292{ 293 GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec); 294 GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_ENUM)); 295 296 if (espec->enum_class) 297 { 298 g_type_class_unref (espec->enum_class); 299 espec->enum_class = NULL; 300 } 301 302 parent_class->finalize (pspec); 303} 304 305static void 306param_enum_set_default (GParamSpec *pspec, 307 GValue *value) 308{ 309 value->data[0].v_long = G_PARAM_SPEC_ENUM (pspec)->default_value; 310} 311 312static gboolean 313param_enum_validate (GParamSpec *pspec, 314 GValue *value) 315{ 316 GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec); 317 glong oval = value->data[0].v_long; 318 319 if (!espec->enum_class || 320 !g_enum_get_value (espec->enum_class, value->data[0].v_long)) 321 value->data[0].v_long = espec->default_value; 322 323 return value->data[0].v_long != oval; 324} 325 326static void 327param_flags_init (GParamSpec *pspec) 328{ 329 GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec); 330 331 fspec->flags_class = NULL; 332 fspec->default_value = 0; 333} 334 335static void 336param_flags_finalize (GParamSpec *pspec) 337{ 338 GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec); 339 GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_FLAGS)); 340 341 if (fspec->flags_class) 342 { 343 g_type_class_unref (fspec->flags_class); 344 fspec->flags_class = NULL; 345 } 346 347 parent_class->finalize (pspec); 348} 349 350static void 351param_flags_set_default (GParamSpec *pspec, 352 GValue *value) 353{ 354 value->data[0].v_ulong = G_PARAM_SPEC_FLAGS (pspec)->default_value; 355} 356 357static gboolean 358param_flags_validate (GParamSpec *pspec, 359 GValue *value) 360{ 361 GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec); 362 gulong oval = value->data[0].v_ulong; 363 364 if (fspec->flags_class) 365 value->data[0].v_ulong &= fspec->flags_class->mask; 366 else 367 value->data[0].v_ulong = fspec->default_value; 368 369 return value->data[0].v_ulong != oval; 370} 371 372static void 373param_float_init (GParamSpec *pspec) 374{ 375 GParamSpecFloat *fspec = G_PARAM_SPEC_FLOAT (pspec); 376 377 fspec->minimum = G_MINFLOAT; 378 fspec->maximum = G_MAXFLOAT; 379 fspec->default_value = 0; 380 fspec->epsilon = G_FLOAT_EPSILON; 381} 382 383static void 384param_float_set_default (GParamSpec *pspec, 385 GValue *value) 386{ 387 value->data[0].v_float = G_PARAM_SPEC_FLOAT (pspec)->default_value; 388} 389 390static gboolean 391param_float_validate (GParamSpec *pspec, 392 GValue *value) 393{ 394 GParamSpecFloat *fspec = G_PARAM_SPEC_FLOAT (pspec); 395 gfloat oval = value->data[0].v_float; 396 397 value->data[0].v_float = CLAMP (value->data[0].v_float, fspec->minimum, fspec->maximum); 398 399 return value->data[0].v_float != oval; 400} 401 402static gint 403param_float_values_cmp (GParamSpec *pspec, 404 const GValue *value1, 405 const GValue *value2) 406{ 407 gfloat epsilon = G_PARAM_SPEC_FLOAT (pspec)->epsilon; 408 409 if (value1->data[0].v_float < value2->data[0].v_float) 410 return - (value2->data[0].v_float - value1->data[0].v_float > epsilon); 411 else 412 return value1->data[0].v_float - value2->data[0].v_float > epsilon; 413} 414 415static void 416param_double_init (GParamSpec *pspec) 417{ 418 GParamSpecDouble *dspec = G_PARAM_SPEC_DOUBLE (pspec); 419 420 dspec->minimum = G_MINDOUBLE; 421 dspec->maximum = G_MAXDOUBLE; 422 dspec->default_value = 0; 423 dspec->epsilon = G_DOUBLE_EPSILON; 424} 425 426static void 427param_double_set_default (GParamSpec *pspec, 428 GValue *value) 429{ 430 value->data[0].v_double = G_PARAM_SPEC_DOUBLE (pspec)->default_value; 431} 432 433static gboolean 434param_double_validate (GParamSpec *pspec, 435 GValue *value) 436{ 437 GParamSpecDouble *dspec = G_PARAM_SPEC_DOUBLE (pspec); 438 gdouble oval = value->data[0].v_double; 439 440 value->data[0].v_double = CLAMP (value->data[0].v_double, dspec->minimum, dspec->maximum); 441 442 return value->data[0].v_double != oval; 443} 444 445static gint 446param_double_values_cmp (GParamSpec *pspec, 447 const GValue *value1, 448 const GValue *value2) 449{ 450 gdouble epsilon = G_PARAM_SPEC_DOUBLE (pspec)->epsilon; 451 452 if (value1->data[0].v_double < value2->data[0].v_double) 453 return - (value2->data[0].v_double - value1->data[0].v_double > epsilon); 454 else 455 return value1->data[0].v_double - value2->data[0].v_double > epsilon; 456} 457 458static void 459param_string_init (GParamSpec *pspec) 460{ 461 GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec); 462 463 sspec->default_value = NULL; 464 sspec->cset_first = NULL; 465 sspec->cset_nth = NULL; 466 sspec->substitutor = '_'; 467 sspec->null_fold_if_empty = FALSE; 468 sspec->ensure_non_null = FALSE; 469} 470 471static void 472param_string_finalize (GParamSpec *pspec) 473{ 474 GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec); 475 GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_STRING)); 476 477 g_free (sspec->default_value); 478 g_free (sspec->cset_first); 479 g_free (sspec->cset_nth); 480 sspec->default_value = NULL; 481 sspec->cset_first = NULL; 482 sspec->cset_nth = NULL; 483 484 parent_class->finalize (pspec); 485} 486 487static void 488param_string_set_default (GParamSpec *pspec, 489 GValue *value) 490{ 491 value->data[0].v_pointer = g_strdup (G_PARAM_SPEC_STRING (pspec)->default_value); 492} 493 494static gboolean 495param_string_validate (GParamSpec *pspec, 496 GValue *value) 497{ 498 GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec); 499 gchar *string = value->data[0].v_pointer; 500 guint changed = 0; 501 502 if (string && string[0]) 503 { 504 gchar *s; 505 506 if (sspec->cset_first && !strchr (sspec->cset_first, string[0])) 507 { 508 string[0] = sspec->substitutor; 509 changed++; 510 } 511 if (sspec->cset_nth) 512 for (s = string + 1; *s; s++) 513 if (!strchr (sspec->cset_nth, *s)) 514 { 515 *s = sspec->substitutor; 516 changed++; 517 } 518 } 519 if (sspec->null_fold_if_empty && string && string[0] == 0) 520 { 521 g_free (value->data[0].v_pointer); 522 value->data[0].v_pointer = NULL; 523 changed++; 524 string = value->data[0].v_pointer; 525 } 526 if (sspec->ensure_non_null && !string) 527 { 528 value->data[0].v_pointer = g_strdup (""); 529 changed++; 530 string = value->data[0].v_pointer; 531 } 532 533 return changed; 534} 535 536static gint 537param_string_values_cmp (GParamSpec *pspec, 538 const GValue *value1, 539 const GValue *value2) 540{ 541 if (!value1->data[0].v_pointer) 542 return value2->data[0].v_pointer != NULL ? -1 : 0; 543 else if (!value2->data[0].v_pointer) 544 return value1->data[0].v_pointer != NULL; 545 else 546 return strcmp (value1->data[0].v_pointer, value2->data[0].v_pointer); 547} 548 549static void 550param_param_init (GParamSpec *pspec) 551{ 552 /* GParamSpecParam *spec = G_PARAM_SPEC_PARAM (pspec); */ 553} 554 555static void 556param_param_set_default (GParamSpec *pspec, 557 GValue *value) 558{ 559 value->data[0].v_pointer = NULL; 560} 561 562static gboolean 563param_param_validate (GParamSpec *pspec, 564 GValue *value) 565{ 566 /* GParamSpecParam *spec = G_PARAM_SPEC_PARAM (pspec); */ 567 GParamSpec *param = value->data[0].v_pointer; 568 guint changed = 0; 569 570 if (param && !g_value_type_compatible (G_PARAM_SPEC_TYPE (param), G_PARAM_SPEC_VALUE_TYPE (pspec))) 571 { 572 g_param_spec_unref (param); 573 value->data[0].v_pointer = NULL; 574 changed++; 575 } 576 577 return changed; 578} 579 580static void 581param_boxed_init (GParamSpec *pspec) 582{ 583 /* GParamSpecBoxed *bspec = G_PARAM_SPEC_BOXED (pspec); */ 584} 585 586static void 587param_boxed_set_default (GParamSpec *pspec, 588 GValue *value) 589{ 590 value->data[0].v_pointer = NULL; 591} 592 593static gboolean 594param_boxed_validate (GParamSpec *pspec, 595 GValue *value) 596{ 597 /* GParamSpecBoxed *bspec = G_PARAM_SPEC_BOXED (pspec); */ 598 guint changed = 0; 599 600 /* can't do a whole lot here since we haven't even G_BOXED_TYPE() */ 601 602 return changed; 603} 604 605static gint 606param_boxed_values_cmp (GParamSpec *pspec, 607 const GValue *value1, 608 const GValue *value2) 609{ 610 guint8 *p1 = value1->data[0].v_pointer; 611 guint8 *p2 = value2->data[0].v_pointer; 612 613 /* not much to compare here, try to at least provide stable lesser/greater result */ 614 615 return p1 < p2 ? -1 : p1 > p2; 616} 617 618static void 619param_pointer_init (GParamSpec *pspec) 620{ 621 /* GParamSpecPointer *spec = G_PARAM_SPEC_POINTER (pspec); */ 622} 623 624static void 625param_pointer_set_default (GParamSpec *pspec, 626 GValue *value) 627{ 628 value->data[0].v_pointer = NULL; 629} 630 631static gboolean 632param_pointer_validate (GParamSpec *pspec, 633 GValue *value) 634{ 635 /* GParamSpecPointer *spec = G_PARAM_SPEC_POINTER (pspec); */ 636 guint changed = 0; 637 638 return changed; 639} 640 641static gint 642param_pointer_values_cmp (GParamSpec *pspec, 643 const GValue *value1, 644 const GValue *value2) 645{ 646 guint8 *p1 = value1->data[0].v_pointer; 647 guint8 *p2 = value2->data[0].v_pointer; 648 649 /* not much to compare here, try to at least provide stable lesser/greater result */ 650 651 return p1 < p2 ? -1 : p1 > p2; 652} 653 654static void 655param_closure_init (GParamSpec *pspec) 656{ 657 /* GParamSpecClosure *cspec = G_PARAM_SPEC_CLOSURE (pspec); */ 658} 659 660static void 661param_closure_set_default (GParamSpec *pspec, 662 GValue *value) 663{ 664 value->data[0].v_pointer = NULL; 665} 666 667static gboolean 668param_closure_validate (GParamSpec *pspec, 669 GValue *value) 670{ 671 /* GParamSpecClosure *cspec = G_PARAM_SPEC_CLOSURE (pspec); */ 672 /* GClosure *closure = value->data[0].v_pointer; */ 673 guint changed = 0; 674 675 /* we don't actually have necessary means to ensure closure validity */ 676 677 return changed; 678} 679 680static gint 681param_closure_values_cmp (GParamSpec *pspec, 682 const GValue *value1, 683 const GValue *value2) 684{ 685 guint8 *p1 = value1->data[0].v_pointer; 686 guint8 *p2 = value2->data[0].v_pointer; 687 688 /* not much to compare here, try to at least provide stable lesser/greater result */ 689 690 return p1 < p2 ? -1 : p1 > p2; 691} 692 693static void 694param_value_array_init (GParamSpec *pspec) 695{ 696 GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec); 697 698 aspec->element_spec = NULL; 699 aspec->fixed_n_elements = 0; /* disable */ 700} 701 702static inline guint 703value_array_ensure_size (GValueArray *value_array, 704 guint fixed_n_elements) 705{ 706 guint changed = 0; 707 708 if (fixed_n_elements) 709 { 710 while (value_array->n_values < fixed_n_elements) 711 { 712 g_value_array_append (value_array, NULL); 713 changed++; 714 } 715 while (value_array->n_values > fixed_n_elements) 716 { 717 g_value_array_remove (value_array, value_array->n_values - 1); 718 changed++; 719 } 720 } 721 return changed; 722} 723 724static void 725param_value_array_finalize (GParamSpec *pspec) 726{ 727 GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec); 728 GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_VALUE_ARRAY)); 729 730 if (aspec->element_spec) 731 { 732 g_param_spec_unref (aspec->element_spec); 733 aspec->element_spec = NULL; 734 } 735 736 parent_class->finalize (pspec); 737} 738 739static void 740param_value_array_set_default (GParamSpec *pspec, 741 GValue *value) 742{ 743 GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec); 744 745 g_return_if_fail (value->data[0].v_pointer != NULL); /* paranoid */ 746 747 /* g_value_reset (value); already done */ 748 value_array_ensure_size (value->data[0].v_pointer, aspec->fixed_n_elements); 749} 750 751static gboolean 752param_value_array_validate (GParamSpec *pspec, 753 GValue *value) 754{ 755 GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec); 756 GValueArray *value_array = value->data[0].v_pointer; 757 guint changed = 0; 758 759 g_return_val_if_fail (value->data[0].v_pointer != NULL, FALSE); /* paranoid */ 760 761 /* ensure array size validity */ 762 changed += value_array_ensure_size (value_array, aspec->fixed_n_elements); 763 764 /* ensure array values validity against a present element spec */ 765 if (aspec->element_spec) 766 { 767 GParamSpec *element_spec = aspec->element_spec; 768 guint i; 769 770 for (i = 0; i < value_array->n_values; i++) 771 { 772 GValue *element = value_array->values + i; 773 774 /* need to fixup value type, or ensure that the array value is initialized at all */ 775 if (!g_value_type_compatible (G_VALUE_TYPE (element), G_PARAM_SPEC_VALUE_TYPE (element_spec))) 776 { 777 if (G_VALUE_TYPE (element) != 0) 778 g_value_unset (element); 779 g_value_init (element, G_PARAM_SPEC_VALUE_TYPE (element_spec)); 780 g_param_value_set_default (element_spec, element); 781 changed++; 782 } 783 /* validate array value against element_spec */ 784 changed += g_param_value_validate (element_spec, element); 785 } 786 } 787 788 return changed; 789} 790 791static gint 792param_value_array_values_cmp (GParamSpec *pspec, 793 const GValue *value1, 794 const GValue *value2) 795{ 796 GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec); 797 GValueArray *value_array1 = value1->data[0].v_pointer; 798 GValueArray *value_array2 = value2->data[0].v_pointer; 799 800 g_return_val_if_fail (value1->data[0].v_pointer != NULL, -1); /* paranoid */ 801 g_return_val_if_fail (value2->data[0].v_pointer != NULL, 1); /* paranoid */ 802 803 if (value_array1->n_values != value_array2->n_values) 804 return value_array1->n_values < value_array2->n_values ? -1 : 1; 805 else if (!aspec->element_spec) 806 { 807 /* we need an element specification for comparisons, so there's not much 808 * to compare here, try to at least provide stable lesser/greater result 809 */ 810 return value_array1->n_values < value_array2->n_values ? -1 : value_array1->n_values > value_array2->n_values; 811 } 812 else /* value_array1->n_values == value_array2->n_values */ 813 { 814 guint i; 815 816 for (i = 0; i < value_array1->n_values; i++) 817 { 818 GValue *element1 = value_array1->values + i; 819 GValue *element2 = value_array2->values + i; 820 gint cmp; 821 822 /* need corresponding element types, provide stable result otherwise */ 823 if (G_VALUE_TYPE (element1) != G_VALUE_TYPE (element2)) 824 return G_VALUE_TYPE (element1) < G_VALUE_TYPE (element2) ? -1 : 1; 825 cmp = g_param_values_cmp (aspec->element_spec, element1, element2); 826 if (cmp) 827 return cmp; 828 } 829 return 0; 830 } 831} 832 833static void 834param_object_init (GParamSpec *pspec) 835{ 836 /* GParamSpecObject *ospec = G_PARAM_SPEC_OBJECT (pspec); */ 837} 838 839static void 840param_object_set_default (GParamSpec *pspec, 841 GValue *value) 842{ 843 value->data[0].v_pointer = NULL; 844} 845 846static gboolean 847param_object_validate (GParamSpec *pspec, 848 GValue *value) 849{ 850 GParamSpecObject *ospec = G_PARAM_SPEC_OBJECT (pspec); 851 GObject *object = value->data[0].v_pointer; 852 guint changed = 0; 853 854 if (object && !g_value_type_compatible (G_OBJECT_TYPE (object), G_PARAM_SPEC_VALUE_TYPE (ospec))) 855 { 856 g_object_unref (object); 857 value->data[0].v_pointer = NULL; 858 changed++; 859 } 860 861 return changed; 862} 863 864static gint 865param_object_values_cmp (GParamSpec *pspec, 866 const GValue *value1, 867 const GValue *value2) 868{ 869 guint8 *p1 = value1->data[0].v_pointer; 870 guint8 *p2 = value2->data[0].v_pointer; 871 872 /* not much to compare here, try to at least provide stable lesser/greater result */ 873 874 return p1 < p2 ? -1 : p1 > p2; 875} 876 877 878/* --- type initialization --- */ 879void 880g_param_spec_types_init (void) /* sync with gtype.c */ 881{ 882 GType type; 883 884 /* G_TYPE_PARAM_CHAR 885 */ 886 { 887 static const GParamSpecTypeInfo pspec_info = { 888 sizeof (GParamSpecChar), /* instance_size */ 889 16, /* n_preallocs */ 890 param_char_init, /* instance_init */ 891 G_TYPE_CHAR, /* value_type */ 892 NULL, /* finalize */ 893 param_char_set_default, /* value_set_default */ 894 param_char_validate, /* value_validate */ 895 param_int_values_cmp, /* values_cmp */ 896 }; 897 type = g_param_type_register_static ("GParamChar", &pspec_info); 898 g_assert (type == G_TYPE_PARAM_CHAR); 899 } 900 901 /* G_TYPE_PARAM_UCHAR 902 */ 903 { 904 static const GParamSpecTypeInfo pspec_info = { 905 sizeof (GParamSpecUChar), /* instance_size */ 906 16, /* n_preallocs */ 907 param_uchar_init, /* instance_init */ 908 G_TYPE_UCHAR, /* value_type */ 909 NULL, /* finalize */ 910 param_uchar_set_default, /* value_set_default */ 911 param_uchar_validate, /* value_validate */ 912 param_uint_values_cmp, /* values_cmp */ 913 }; 914 type = g_param_type_register_static ("GParamUChar", &pspec_info); 915 g_assert (type == G_TYPE_PARAM_UCHAR); 916 } 917 918 /* G_TYPE_PARAM_BOOLEAN 919 */ 920 { 921 static const GParamSpecTypeInfo pspec_info = { 922 sizeof (GParamSpecBoolean), /* instance_size */ 923 16, /* n_preallocs */ 924 NULL, /* instance_init */ 925 G_TYPE_BOOLEAN, /* value_type */ 926 NULL, /* finalize */ 927 param_boolean_set_default, /* value_set_default */ 928 param_boolean_validate, /* value_validate */ 929 param_int_values_cmp, /* values_cmp */ 930 }; 931 type = g_param_type_register_static ("GParamBoolean", &pspec_info); 932 g_assert (type == G_TYPE_PARAM_BOOLEAN); 933 } 934 935 /* G_TYPE_PARAM_INT 936 */ 937 { 938 static const GParamSpecTypeInfo pspec_info = { 939 sizeof (GParamSpecInt), /* instance_size */ 940 16, /* n_preallocs */ 941 param_int_init, /* instance_init */ 942 G_TYPE_INT, /* value_type */ 943 NULL, /* finalize */ 944 param_int_set_default, /* value_set_default */ 945 param_int_validate, /* value_validate */ 946 param_int_values_cmp, /* values_cmp */ 947 }; 948 type = g_param_type_register_static ("GParamInt", &pspec_info); 949 g_assert (type == G_TYPE_PARAM_INT); 950 } 951 952 /* G_TYPE_PARAM_UINT 953 */ 954 { 955 static const GParamSpecTypeInfo pspec_info = { 956 sizeof (GParamSpecUInt), /* instance_size */ 957 16, /* n_preallocs */ 958 param_uint_init, /* instance_init */ 959 G_TYPE_UINT, /* value_type */ 960 NULL, /* finalize */ 961 param_uint_set_default, /* value_set_default */ 962 param_uint_validate, /* value_validate */ 963 param_uint_values_cmp, /* values_cmp */ 964 }; 965 type = g_param_type_register_static ("GParamUInt", &pspec_info); 966 g_assert (type == G_TYPE_PARAM_UINT); 967 } 968 969 /* G_TYPE_PARAM_LONG 970 */ 971 { 972 static const GParamSpecTypeInfo pspec_info = { 973 sizeof (GParamSpecLong), /* instance_size */ 974 16, /* n_preallocs */ 975 param_long_init, /* instance_init */ 976 G_TYPE_LONG, /* value_type */ 977 NULL, /* finalize */ 978 param_long_set_default, /* value_set_default */ 979 param_long_validate, /* value_validate */ 980 param_long_values_cmp, /* values_cmp */ 981 }; 982 type = g_param_type_register_static ("GParamLong", &pspec_info); 983 g_assert (type == G_TYPE_PARAM_LONG); 984 } 985 986 /* G_TYPE_PARAM_ULONG 987 */ 988 { 989 static const GParamSpecTypeInfo pspec_info = { 990 sizeof (GParamSpecULong), /* instance_size */ 991 16, /* n_preallocs */ 992 param_ulong_init, /* instance_init */ 993 G_TYPE_ULONG, /* value_type */ 994 NULL, /* finalize */ 995 param_ulong_set_default, /* value_set_default */ 996 param_ulong_validate, /* value_validate */ 997 param_ulong_values_cmp, /* values_cmp */ 998 }; 999 type = g_param_type_register_static ("GParamULong", &pspec_info); 1000 g_assert (type == G_TYPE_PARAM_ULONG); 1001 } 1002 1003 /* G_TYPE_PARAM_ENUM 1004 */ 1005 { 1006 static const GParamSpecTypeInfo pspec_info = { 1007 sizeof (GParamSpecEnum), /* instance_size */ 1008 16, /* n_preallocs */ 1009 param_enum_init, /* instance_init */ 1010 G_TYPE_ENUM, /* value_type */ 1011 param_enum_finalize, /* finalize */ 1012 param_enum_set_default, /* value_set_default */ 1013 param_enum_validate, /* value_validate */ 1014 param_long_values_cmp, /* values_cmp */ 1015 }; 1016 type = g_param_type_register_static ("GParamEnum", &pspec_info); 1017 g_assert (type == G_TYPE_PARAM_ENUM); 1018 } 1019 1020 /* G_TYPE_PARAM_FLAGS 1021 */ 1022 { 1023 static const GParamSpecTypeInfo pspec_info = { 1024 sizeof (GParamSpecFlags), /* instance_size */ 1025 16, /* n_preallocs */ 1026 param_flags_init, /* instance_init */ 1027 G_TYPE_FLAGS, /* value_type */ 1028 param_flags_finalize, /* finalize */ 1029 param_flags_set_default, /* value_set_default */ 1030 param_flags_validate, /* value_validate */ 1031 param_ulong_values_cmp, /* values_cmp */ 1032 }; 1033 type = g_param_type_register_static ("GParamFlags", &pspec_info); 1034 g_assert (type == G_TYPE_PARAM_FLAGS); 1035 } 1036 1037 /* G_TYPE_PARAM_FLOAT 1038 */ 1039 { 1040 static const GParamSpecTypeInfo pspec_info = { 1041 sizeof (GParamSpecFloat), /* instance_size */ 1042 16, /* n_preallocs */ 1043 param_float_init, /* instance_init */ 1044 G_TYPE_FLOAT, /* value_type */ 1045 NULL, /* finalize */ 1046 param_float_set_default, /* value_set_default */ 1047 param_float_validate, /* value_validate */ 1048 param_float_values_cmp, /* values_cmp */ 1049 }; 1050 type = g_param_type_register_static ("GParamFloat", &pspec_info); 1051 g_assert (type == G_TYPE_PARAM_FLOAT); 1052 } 1053 1054 /* G_TYPE_PARAM_DOUBLE 1055 */ 1056 { 1057 static const GParamSpecTypeInfo pspec_info = { 1058 sizeof (GParamSpecDouble), /* instance_size */ 1059 16, /* n_preallocs */ 1060 param_double_init, /* instance_init */ 1061 G_TYPE_DOUBLE, /* value_type */ 1062 NULL, /* finalize */ 1063 param_double_set_default, /* value_set_default */ 1064 param_double_validate, /* value_validate */ 1065 param_double_values_cmp, /* values_cmp */ 1066 }; 1067 type = g_param_type_register_static ("GParamDouble", &pspec_info); 1068 g_assert (type == G_TYPE_PARAM_DOUBLE); 1069 } 1070 1071 /* G_TYPE_PARAM_STRING 1072 */ 1073 { 1074 static const GParamSpecTypeInfo pspec_info = { 1075 sizeof (GParamSpecString), /* instance_size */ 1076 16, /* n_preallocs */ 1077 param_string_init, /* instance_init */ 1078 G_TYPE_STRING, /* value_type */ 1079 param_string_finalize, /* finalize */ 1080 param_string_set_default, /* value_set_default */ 1081 param_string_validate, /* value_validate */ 1082 param_string_values_cmp, /* values_cmp */ 1083 }; 1084 type = g_param_type_register_static ("GParamString", &pspec_info); 1085 g_assert (type == G_TYPE_PARAM_STRING); 1086 } 1087 1088 /* G_TYPE_PARAM_PARAM 1089 */ 1090 { 1091 static const GParamSpecTypeInfo pspec_info = { 1092 sizeof (GParamSpecParam), /* instance_size */ 1093 16, /* n_preallocs */ 1094 param_param_init, /* instance_init */ 1095 G_TYPE_PARAM, /* value_type */ 1096 NULL, /* finalize */ 1097 param_param_set_default, /* value_set_default */ 1098 param_param_validate, /* value_validate */ 1099 param_pointer_values_cmp, /* values_cmp */ 1100 }; 1101 type = g_param_type_register_static ("GParamParam", &pspec_info); 1102 g_assert (type == G_TYPE_PARAM_PARAM); 1103 } 1104 1105 /* G_TYPE_PARAM_BOXED 1106 */ 1107 { 1108 static const GParamSpecTypeInfo pspec_info = { 1109 sizeof (GParamSpecBoxed), /* instance_size */ 1110 4, /* n_preallocs */ 1111 param_boxed_init, /* instance_init */ 1112 G_TYPE_BOXED, /* value_type */ 1113 NULL, /* finalize */ 1114 param_boxed_set_default, /* value_set_default */ 1115 param_boxed_validate, /* value_validate */ 1116 param_boxed_values_cmp, /* values_cmp */ 1117 }; 1118 type = g_param_type_register_static ("GParamBoxed", &pspec_info); 1119 g_assert (type == G_TYPE_PARAM_BOXED); 1120 } 1121 1122 /* G_TYPE_PARAM_POINTER 1123 */ 1124 { 1125 static const GParamSpecTypeInfo pspec_info = { 1126 sizeof (GParamSpecPointer), /* instance_size */ 1127 0, /* n_preallocs */ 1128 param_pointer_init, /* instance_init */ 1129 G_TYPE_POINTER, /* value_type */ 1130 NULL, /* finalize */ 1131 param_pointer_set_default, /* value_set_default */ 1132 param_pointer_validate, /* value_validate */ 1133 param_pointer_values_cmp, /* values_cmp */ 1134 }; 1135 type = g_param_type_register_static ("GParamPointer", &pspec_info); 1136 g_assert (type == G_TYPE_PARAM_POINTER); 1137 } 1138 1139 /* G_TYPE_PARAM_VALUE_ARRAY 1140 */ 1141 { 1142 static const GParamSpecTypeInfo pspec_info = { 1143 sizeof (GParamSpecValueArray), /* instance_size */ 1144 0, /* n_preallocs */ 1145 param_value_array_init, /* instance_init */ 1146 G_TYPE_VALUE_ARRAY, /* value_type */ 1147 param_value_array_finalize, /* finalize */ 1148 param_value_array_set_default, /* value_set_default */ 1149 param_value_array_validate, /* value_validate */ 1150 param_value_array_values_cmp, /* values_cmp */ 1151 }; 1152 type = g_param_type_register_static ("GParamValueArray", &pspec_info); 1153 g_assert (type == G_TYPE_PARAM_VALUE_ARRAY); 1154 } 1155 1156 /* G_TYPE_PARAM_CLOSURE 1157 */ 1158 { 1159 static const GParamSpecTypeInfo pspec_info = { 1160 sizeof (GParamSpecClosure), /* instance_size */ 1161 0, /* n_preallocs */ 1162 param_closure_init, /* instance_init */ 1163 G_TYPE_CLOSURE, /* value_type */ 1164 NULL, /* finalize */ 1165 param_closure_set_default, /* value_set_default */ 1166 param_closure_validate, /* value_validate */ 1167 param_closure_values_cmp, /* values_cmp */ 1168 }; 1169 type = g_param_type_register_static ("GParamClosure", &pspec_info); 1170 g_assert (type == G_TYPE_PARAM_CLOSURE); 1171 } 1172 1173 /* G_TYPE_PARAM_OBJECT 1174 */ 1175 { 1176 static const GParamSpecTypeInfo pspec_info = { 1177 sizeof (GParamSpecObject), /* instance_size */ 1178 16, /* n_preallocs */ 1179 param_object_init, /* instance_init */ 1180 G_TYPE_OBJECT, /* value_type */ 1181 NULL, /* finalize */ 1182 param_object_set_default, /* value_set_default */ 1183 param_object_validate, /* value_validate */ 1184 param_object_values_cmp, /* values_cmp */ 1185 }; 1186 type = g_param_type_register_static ("GParamObject", &pspec_info); 1187 g_assert (type == G_TYPE_PARAM_OBJECT); 1188 } 1189} 1190 1191 1192/* --- GParamSpec initialization --- */ 1193GParamSpec* 1194g_param_spec_char (const gchar *name, 1195 const gchar *nick, 1196 const gchar *blurb, 1197 gint8 minimum, 1198 gint8 maximum, 1199 gint8 default_value, 1200 GParamFlags flags) 1201{ 1202 GParamSpecChar *cspec = g_param_spec_internal (G_TYPE_PARAM_CHAR, 1203 name, 1204 nick, 1205 blurb, 1206 flags); 1207 1208 cspec->minimum = minimum; 1209 cspec->maximum = maximum; 1210 cspec->default_value = default_value; 1211 1212 return G_PARAM_SPEC (cspec); 1213} 1214 1215GParamSpec* 1216g_param_spec_uchar (const gchar *name, 1217 const gchar *nick, 1218 const gchar *blurb, 1219 guint8 minimum, 1220 guint8 maximum, 1221 guint8 default_value, 1222 GParamFlags flags) 1223{ 1224 GParamSpecUChar *uspec = g_param_spec_internal (G_TYPE_PARAM_UCHAR, 1225 name, 1226 nick, 1227 blurb, 1228 flags); 1229 1230 uspec->minimum = minimum; 1231 uspec->maximum = maximum; 1232 uspec->default_value = default_value; 1233 1234 return G_PARAM_SPEC (uspec); 1235} 1236 1237GParamSpec* 1238g_param_spec_boolean (const gchar *name, 1239 const gchar *nick, 1240 const gchar *blurb, 1241 gboolean default_value, 1242 GParamFlags flags) 1243{ 1244 GParamSpecBoolean *bspec = g_param_spec_internal (G_TYPE_PARAM_BOOLEAN, 1245 name, 1246 nick, 1247 blurb, 1248 flags); 1249 1250 bspec->default_value = default_value; 1251 1252 return G_PARAM_SPEC (bspec); 1253} 1254 1255GParamSpec* 1256g_param_spec_int (const gchar *name, 1257 const gchar *nick, 1258 const gchar *blurb, 1259 gint minimum, 1260 gint maximum, 1261 gint default_value, 1262 GParamFlags flags) 1263{ 1264 GParamSpecInt *ispec = g_param_spec_internal (G_TYPE_PARAM_INT, 1265 name, 1266 nick, 1267 blurb, 1268 flags); 1269 1270 ispec->minimum = minimum; 1271 ispec->maximum = maximum; 1272 ispec->default_value = default_value; 1273 1274 return G_PARAM_SPEC (ispec); 1275} 1276 1277GParamSpec* 1278g_param_spec_uint (const gchar *name, 1279 const gchar *nick, 1280 const gchar *blurb, 1281 guint minimum, 1282 guint maximum, 1283 guint default_value, 1284 GParamFlags flags) 1285{ 1286 GParamSpecUInt *uspec = g_param_spec_internal (G_TYPE_PARAM_UINT, 1287 name, 1288 nick, 1289 blurb, 1290 flags); 1291 1292 uspec->minimum = minimum; 1293 uspec->maximum = maximum; 1294 uspec->default_value = default_value; 1295 1296 return G_PARAM_SPEC (uspec); 1297} 1298 1299GParamSpec* 1300g_param_spec_long (const gchar *name, 1301 const gchar *nick, 1302 const gchar *blurb, 1303 glong minimum, 1304 glong maximum, 1305 glong default_value, 1306 GParamFlags flags) 1307{ 1308 GParamSpecLong *lspec = g_param_spec_internal (G_TYPE_PARAM_LONG, 1309 name, 1310 nick, 1311 blurb, 1312 flags); 1313 1314 lspec->minimum = minimum; 1315 lspec->maximum = maximum; 1316 lspec->default_value = default_value; 1317 1318 return G_PARAM_SPEC (lspec); 1319} 1320 1321GParamSpec* 1322g_param_spec_ulong (const gchar *name, 1323 const gchar *nick, 1324 const gchar *blurb, 1325 gulong minimum, 1326 gulong maximum, 1327 gulong default_value, 1328 GParamFlags flags) 1329{ 1330 GParamSpecULong *uspec = g_param_spec_internal (G_TYPE_PARAM_ULONG, 1331 name, 1332 nick, 1333 blurb, 1334 flags); 1335 1336 uspec->minimum = minimum; 1337 uspec->maximum = maximum; 1338 uspec->default_value = default_value; 1339 1340 return G_PARAM_SPEC (uspec); 1341} 1342 1343GParamSpec* 1344g_param_spec_enum (const gchar *name, 1345 const gchar *nick, 1346 const gchar *blurb, 1347 GType enum_type, 1348 gint default_value, 1349 GParamFlags flags) 1350{ 1351 GParamSpecEnum *espec; 1352 1353 g_return_val_if_fail (G_TYPE_IS_ENUM (enum_type), NULL); 1354 1355 espec = g_param_spec_internal (G_TYPE_PARAM_ENUM, 1356 name, 1357 nick, 1358 blurb, 1359 flags); 1360 1361 espec->enum_class = g_type_class_ref (enum_type); 1362 espec->default_value = default_value; 1363 G_PARAM_SPEC (espec)->value_type = enum_type; 1364 1365 return G_PARAM_SPEC (espec); 1366} 1367 1368GParamSpec* 1369g_param_spec_flags (const gchar *name, 1370 const gchar *nick, 1371 const gchar *blurb, 1372 GType flags_type, 1373 guint default_value, 1374 GParamFlags flags) 1375{ 1376 GParamSpecFlags *fspec; 1377 1378 g_return_val_if_fail (G_TYPE_IS_FLAGS (flags_type), NULL); 1379 1380 fspec = g_param_spec_internal (G_TYPE_PARAM_FLAGS, 1381 name, 1382 nick, 1383 blurb, 1384 flags); 1385 1386 fspec->flags_class = g_type_class_ref (flags_type); 1387 fspec->default_value = default_value; 1388 G_PARAM_SPEC (fspec)->value_type = flags_type; 1389 1390 return G_PARAM_SPEC (fspec); 1391} 1392 1393GParamSpec* 1394g_param_spec_float (const gchar *name, 1395 const gchar *nick, 1396 const gchar *blurb, 1397 gfloat minimum, 1398 gfloat maximum, 1399 gfloat default_value, 1400 GParamFlags flags) 1401{ 1402 GParamSpecFloat *fspec = g_param_spec_internal (G_TYPE_PARAM_FLOAT, 1403 name, 1404 nick, 1405 blurb, 1406 flags); 1407 1408 fspec->minimum = minimum; 1409 fspec->maximum = maximum; 1410 fspec->default_value = default_value; 1411 1412 return G_PARAM_SPEC (fspec); 1413} 1414 1415GParamSpec* 1416g_param_spec_double (const gchar *name, 1417 const gchar *nick, 1418 const gchar *blurb, 1419 gdouble minimum, 1420 gdouble maximum, 1421 gdouble default_value, 1422 GParamFlags flags) 1423{ 1424 GParamSpecDouble *dspec = g_param_spec_internal (G_TYPE_PARAM_DOUBLE, 1425 name, 1426 nick, 1427 blurb, 1428 flags); 1429 1430 dspec->minimum = minimum; 1431 dspec->maximum = maximum; 1432 dspec->default_value = default_value; 1433 1434 return G_PARAM_SPEC (dspec); 1435} 1436 1437GParamSpec* 1438g_param_spec_string (const gchar *name, 1439 const gchar *nick, 1440 const gchar *blurb, 1441 const gchar *default_value, 1442 GParamFlags flags) 1443{ 1444 GParamSpecString *sspec = g_param_spec_internal (G_TYPE_PARAM_STRING, 1445 name, 1446 nick, 1447 blurb, 1448 flags); 1449 g_free (sspec->default_value); 1450 sspec->default_value = g_strdup (default_value); 1451 1452 return G_PARAM_SPEC (sspec); 1453} 1454 1455GParamSpec* 1456g_param_spec_stringc (const gchar *name, 1457 const gchar *nick, 1458 const gchar *blurb, 1459 const gchar *default_value, 1460 GParamFlags flags) 1461{ 1462 GParamSpecString *sspec = g_param_spec_internal (G_TYPE_PARAM_STRING, 1463 name, 1464 nick, 1465 blurb, 1466 flags); 1467 g_free (sspec->default_value); 1468 sspec->default_value = g_strdup (default_value); 1469 g_free (sspec->cset_first); 1470 sspec->cset_first = g_strdup (G_CSET_a_2_z "_" G_CSET_A_2_Z); 1471 g_free (sspec->cset_nth); 1472 sspec->cset_nth = g_strdup (G_CSET_a_2_z 1473 "_0123456789" 1474 /* G_CSET_LATINS G_CSET_LATINC */ 1475 G_CSET_A_2_Z); 1476 1477 return G_PARAM_SPEC (sspec); 1478} 1479 1480GParamSpec* 1481g_param_spec_param (const gchar *name, 1482 const gchar *nick, 1483 const gchar *blurb, 1484 GType param_type, 1485 GParamFlags flags) 1486{ 1487 GParamSpecParam *pspec; 1488 1489 g_return_val_if_fail (G_TYPE_IS_PARAM (param_type), NULL); 1490 1491 pspec = g_param_spec_internal (G_TYPE_PARAM_PARAM, 1492 name, 1493 nick, 1494 blurb, 1495 flags); 1496 G_PARAM_SPEC (pspec)->value_type = param_type; 1497 1498 return G_PARAM_SPEC (pspec); 1499} 1500 1501GParamSpec* 1502g_param_spec_boxed (const gchar *name, 1503 const gchar *nick, 1504 const gchar *blurb, 1505 GType boxed_type, 1506 GParamFlags flags) 1507{ 1508 GParamSpecBoxed *bspec; 1509 1510 g_return_val_if_fail (G_TYPE_IS_BOXED (boxed_type), NULL); 1511 g_return_val_if_fail (G_TYPE_IS_DERIVED (boxed_type), NULL); 1512 1513 bspec = g_param_spec_internal (G_TYPE_PARAM_BOXED, 1514 name, 1515 nick, 1516 blurb, 1517 flags); 1518 G_PARAM_SPEC (bspec)->value_type = boxed_type; 1519 1520 return G_PARAM_SPEC (bspec); 1521} 1522 1523GParamSpec* 1524g_param_spec_pointer (const gchar *name, 1525 const gchar *nick, 1526 const gchar *blurb, 1527 GParamFlags flags) 1528{ 1529 GParamSpecPointer *pspec; 1530 1531 pspec = g_param_spec_internal (G_TYPE_PARAM_POINTER, 1532 name, 1533 nick, 1534 blurb, 1535 flags); 1536 return G_PARAM_SPEC (pspec); 1537} 1538 1539GParamSpec* 1540g_param_spec_value_array (const gchar *name, 1541 const gchar *nick, 1542 const gchar *blurb, 1543 GParamSpec *element_spec, 1544 GParamFlags flags) 1545{ 1546 GParamSpecValueArray *aspec; 1547 1548 if (element_spec) 1549 g_return_val_if_fail (G_IS_PARAM_SPEC (element_spec), NULL); 1550 1551 aspec = g_param_spec_internal (G_TYPE_PARAM_VALUE_ARRAY, 1552 name, 1553 nick, 1554 blurb, 1555 flags); 1556 if (element_spec) 1557 { 1558 aspec->element_spec = g_param_spec_ref (element_spec); 1559 g_param_spec_sink (element_spec); 1560 } 1561 1562 return G_PARAM_SPEC (aspec); 1563} 1564 1565GParamSpec* 1566g_param_spec_closure (const gchar *name, 1567 const gchar *nick, 1568 const gchar *blurb, 1569 GParamFlags flags) 1570{ 1571 GParamSpecClosure *cspec; 1572 1573 cspec = g_param_spec_internal (G_TYPE_PARAM_CLOSURE, 1574 name, 1575 nick, 1576 blurb, 1577 flags); 1578 return G_PARAM_SPEC (cspec); 1579} 1580 1581GParamSpec* 1582g_param_spec_object (const gchar *name, 1583 const gchar *nick, 1584 const gchar *blurb, 1585 GType object_type, 1586 GParamFlags flags) 1587{ 1588 GParamSpecObject *ospec; 1589 1590 g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type), NULL); 1591 1592 ospec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, 1593 name, 1594 nick, 1595 blurb, 1596 flags); 1597 G_PARAM_SPEC (ospec)->value_type = object_type; 1598 1599 return G_PARAM_SPEC (ospec); 1600} 1601