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