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