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