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