glib/gobject/gparamspecs.c
Emmanuele Bassi 3c53fb8790 Move the GLib type system into libglib
The type system should have never been relegated to libgobject: it's a low
level API to register types at run time.

Having GType inside libglib allows us to use the type system information
everywhere:

- generic but type safe storage data types
- explicit memory management semantics for all data types
- enumeration types for all flags

Having the type system inside libglib also allows us to create new and
better fundamental types in the future, like sum types, option types,
tuples, and generic types.

Moved:

- gatomicarray
- gboxed
- genums
- gtype
- gtypeplugin
- gvalue

The move is mostly Git surgery, but given the amount of internal API
surface, it results in a single commit to avoid breaking bisectability.

We need to maintain `gobject/gvaluecollector.h` as a publicly installed
header but, to avoid issues in case of excessive inclusions, we make it
conflict with `glib/gvaluecollector.h`.

See: #2370

See: https://discourse.gnome.org/t/straw-man-moving-the-gtype-api-down-to-libglib-2-0/11169
2025-01-03 22:56:56 +00:00

2768 lines
75 KiB
C

/* GObject - GLib Type, Object, Parameter and Signal Library
* Copyright (C) 1997-1999, 2000-2001 Tim Janik and Red Hat, Inc.
* Copyright (C) 2010 Christian Persch
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
/*
* MT safe
*/
#include "config.h"
#include <string.h>
#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS
#define GLIB_DISABLE_DEPRECATION_WARNINGS
#endif
#include "gparamspecs.h"
#include "gobject-private.h"
#include "gvaluecollector.h"
#include "gvaluearray.h"
#define G_FLOAT_EPSILON (1e-30f)
#define G_DOUBLE_EPSILON (1e-90)
/* --- param spec functions --- */
static void
param_char_init (GParamSpec *pspec)
{
GParamSpecChar *cspec = G_PARAM_SPEC_CHAR (pspec);
cspec->minimum = 0x7f;
cspec->maximum = 0x80;
cspec->default_value = 0;
}
static void
param_char_set_default (GParamSpec *pspec,
GValue *value)
{
value->data[0].v_int = G_PARAM_SPEC_CHAR (pspec)->default_value;
}
static gboolean
param_char_is_valid (GParamSpec *pspec,
const GValue *value)
{
GParamSpecChar *cspec = G_PARAM_SPEC_CHAR (pspec);
gint oval = value->data[0].v_int;
return cspec->minimum <= oval && oval <= cspec->maximum;
}
static gboolean
param_char_validate (GParamSpec *pspec,
GValue *value)
{
GParamSpecChar *cspec = G_PARAM_SPEC_CHAR (pspec);
gint oval = value->data[0].v_int;
value->data[0].v_int = CLAMP (value->data[0].v_int, cspec->minimum, cspec->maximum);
return value->data[0].v_int != oval;
}
static void
param_uchar_init (GParamSpec *pspec)
{
GParamSpecUChar *uspec = G_PARAM_SPEC_UCHAR (pspec);
uspec->minimum = 0;
uspec->maximum = 0xff;
uspec->default_value = 0;
}
static void
param_uchar_set_default (GParamSpec *pspec,
GValue *value)
{
value->data[0].v_uint = G_PARAM_SPEC_UCHAR (pspec)->default_value;
}
static gboolean
param_uchar_is_valid (GParamSpec *pspec,
const GValue *value)
{
GParamSpecUChar *uspec = G_PARAM_SPEC_UCHAR (pspec);
guint oval = value->data[0].v_uint;
return uspec->minimum <= oval && oval <= uspec->maximum;
}
static gboolean
param_uchar_validate (GParamSpec *pspec,
GValue *value)
{
GParamSpecUChar *uspec = G_PARAM_SPEC_UCHAR (pspec);
guint oval = value->data[0].v_uint;
value->data[0].v_uint = CLAMP (value->data[0].v_uint, uspec->minimum, uspec->maximum);
return value->data[0].v_uint != oval;
}
static void
param_boolean_set_default (GParamSpec *pspec,
GValue *value)
{
value->data[0].v_int = G_PARAM_SPEC_BOOLEAN (pspec)->default_value;
}
static gboolean
param_boolean_is_valid (GParamSpec *pspec,
const GValue *value)
{
int oval = value->data[0].v_int;
return oval == FALSE || oval == TRUE;
}
static gboolean
param_boolean_validate (GParamSpec *pspec,
GValue *value)
{
gint oval = value->data[0].v_int;
value->data[0].v_int = value->data[0].v_int != FALSE;
return value->data[0].v_int != oval;
}
static void
param_int_init (GParamSpec *pspec)
{
GParamSpecInt *ispec = G_PARAM_SPEC_INT (pspec);
ispec->minimum = 0x7fffffff;
ispec->maximum = 0x80000000;
ispec->default_value = 0;
}
static void
param_int_set_default (GParamSpec *pspec,
GValue *value)
{
value->data[0].v_int = G_PARAM_SPEC_INT (pspec)->default_value;
}
static gboolean
param_int_is_valid (GParamSpec *pspec,
const GValue *value)
{
GParamSpecInt *ispec = G_PARAM_SPEC_INT (pspec);
int oval = value->data[0].v_int;
return ispec->minimum <= oval && oval <= ispec->maximum;
}
static gboolean
param_int_validate (GParamSpec *pspec,
GValue *value)
{
GParamSpecInt *ispec = G_PARAM_SPEC_INT (pspec);
gint oval = value->data[0].v_int;
value->data[0].v_int = CLAMP (value->data[0].v_int, ispec->minimum, ispec->maximum);
return value->data[0].v_int != oval;
}
static gint
param_int_values_cmp (GParamSpec *pspec,
const GValue *value1,
const GValue *value2)
{
if (value1->data[0].v_int < value2->data[0].v_int)
return -1;
else
return value1->data[0].v_int > value2->data[0].v_int;
}
static void
param_uint_init (GParamSpec *pspec)
{
GParamSpecUInt *uspec = G_PARAM_SPEC_UINT (pspec);
uspec->minimum = 0;
uspec->maximum = 0xffffffff;
uspec->default_value = 0;
}
static void
param_uint_set_default (GParamSpec *pspec,
GValue *value)
{
value->data[0].v_uint = G_PARAM_SPEC_UINT (pspec)->default_value;
}
static gboolean
param_uint_is_valid (GParamSpec *pspec,
const GValue *value)
{
GParamSpecUInt *uspec = G_PARAM_SPEC_UINT (pspec);
guint oval = value->data[0].v_uint;
return uspec->minimum <= oval && oval <= uspec->maximum;
}
static gboolean
param_uint_validate (GParamSpec *pspec,
GValue *value)
{
GParamSpecUInt *uspec = G_PARAM_SPEC_UINT (pspec);
guint oval = value->data[0].v_uint;
value->data[0].v_uint = CLAMP (value->data[0].v_uint, uspec->minimum, uspec->maximum);
return value->data[0].v_uint != oval;
}
static gint
param_uint_values_cmp (GParamSpec *pspec,
const GValue *value1,
const GValue *value2)
{
if (value1->data[0].v_uint < value2->data[0].v_uint)
return -1;
else
return value1->data[0].v_uint > value2->data[0].v_uint;
}
static void
param_long_init (GParamSpec *pspec)
{
GParamSpecLong *lspec = G_PARAM_SPEC_LONG (pspec);
#if SIZEOF_LONG == 4
lspec->minimum = 0x7fffffff;
lspec->maximum = 0x80000000;
#else /* SIZEOF_LONG != 4 (8) */
lspec->minimum = 0x7fffffffffffffff;
lspec->maximum = 0x8000000000000000;
#endif
lspec->default_value = 0;
}
static void
param_long_set_default (GParamSpec *pspec,
GValue *value)
{
value->data[0].v_long = G_PARAM_SPEC_LONG (pspec)->default_value;
}
static gboolean
param_long_is_valid (GParamSpec *pspec,
const GValue *value)
{
GParamSpecLong *lspec = G_PARAM_SPEC_LONG (pspec);
glong oval = value->data[0].v_long;
return lspec->minimum <= oval && oval <= lspec->maximum;
}
static gboolean
param_long_validate (GParamSpec *pspec,
GValue *value)
{
GParamSpecLong *lspec = G_PARAM_SPEC_LONG (pspec);
glong oval = value->data[0].v_long;
value->data[0].v_long = CLAMP (value->data[0].v_long, lspec->minimum, lspec->maximum);
return value->data[0].v_long != oval;
}
static gint
param_long_values_cmp (GParamSpec *pspec,
const GValue *value1,
const GValue *value2)
{
if (value1->data[0].v_long < value2->data[0].v_long)
return -1;
else
return value1->data[0].v_long > value2->data[0].v_long;
}
static void
param_ulong_init (GParamSpec *pspec)
{
GParamSpecULong *uspec = G_PARAM_SPEC_ULONG (pspec);
uspec->minimum = 0;
#if SIZEOF_LONG == 4
uspec->maximum = 0xffffffff;
#else /* SIZEOF_LONG != 4 (8) */
uspec->maximum = 0xffffffffffffffff;
#endif
uspec->default_value = 0;
}
static void
param_ulong_set_default (GParamSpec *pspec,
GValue *value)
{
value->data[0].v_ulong = G_PARAM_SPEC_ULONG (pspec)->default_value;
}
static gboolean
param_ulong_is_valid (GParamSpec *pspec,
const GValue *value)
{
GParamSpecULong *uspec = G_PARAM_SPEC_ULONG (pspec);
gulong oval = value->data[0].v_ulong;
return uspec->minimum <= oval && oval <= uspec->maximum;
}
static gboolean
param_ulong_validate (GParamSpec *pspec,
GValue *value)
{
GParamSpecULong *uspec = G_PARAM_SPEC_ULONG (pspec);
gulong oval = value->data[0].v_ulong;
value->data[0].v_ulong = CLAMP (value->data[0].v_ulong, uspec->minimum, uspec->maximum);
return value->data[0].v_ulong != oval;
}
static gint
param_ulong_values_cmp (GParamSpec *pspec,
const GValue *value1,
const GValue *value2)
{
if (value1->data[0].v_ulong < value2->data[0].v_ulong)
return -1;
else
return value1->data[0].v_ulong > value2->data[0].v_ulong;
}
static void
param_int64_init (GParamSpec *pspec)
{
GParamSpecInt64 *lspec = G_PARAM_SPEC_INT64 (pspec);
lspec->minimum = G_MININT64;
lspec->maximum = G_MAXINT64;
lspec->default_value = 0;
}
static void
param_int64_set_default (GParamSpec *pspec,
GValue *value)
{
value->data[0].v_int64 = G_PARAM_SPEC_INT64 (pspec)->default_value;
}
static gboolean
param_int64_is_valid (GParamSpec *pspec,
const GValue *value)
{
GParamSpecInt64 *lspec = G_PARAM_SPEC_INT64 (pspec);
gint64 oval = value->data[0].v_int64;
return lspec->minimum <= oval && oval <= lspec->maximum;
}
static gboolean
param_int64_validate (GParamSpec *pspec,
GValue *value)
{
GParamSpecInt64 *lspec = G_PARAM_SPEC_INT64 (pspec);
gint64 oval = value->data[0].v_int64;
value->data[0].v_int64 = CLAMP (value->data[0].v_int64, lspec->minimum, lspec->maximum);
return value->data[0].v_int64 != oval;
}
static gint
param_int64_values_cmp (GParamSpec *pspec,
const GValue *value1,
const GValue *value2)
{
if (value1->data[0].v_int64 < value2->data[0].v_int64)
return -1;
else
return value1->data[0].v_int64 > value2->data[0].v_int64;
}
static void
param_uint64_init (GParamSpec *pspec)
{
GParamSpecUInt64 *uspec = G_PARAM_SPEC_UINT64 (pspec);
uspec->minimum = 0;
uspec->maximum = G_MAXUINT64;
uspec->default_value = 0;
}
static void
param_uint64_set_default (GParamSpec *pspec,
GValue *value)
{
value->data[0].v_uint64 = G_PARAM_SPEC_UINT64 (pspec)->default_value;
}
static gboolean
param_uint64_is_valid (GParamSpec *pspec,
const GValue *value)
{
GParamSpecUInt64 *uspec = G_PARAM_SPEC_UINT64 (pspec);
guint64 oval = value->data[0].v_uint64;
return uspec->minimum <= oval && oval <= uspec->maximum;
}
static gboolean
param_uint64_validate (GParamSpec *pspec,
GValue *value)
{
GParamSpecUInt64 *uspec = G_PARAM_SPEC_UINT64 (pspec);
guint64 oval = value->data[0].v_uint64;
value->data[0].v_uint64 = CLAMP (value->data[0].v_uint64, uspec->minimum, uspec->maximum);
return value->data[0].v_uint64 != oval;
}
static gint
param_uint64_values_cmp (GParamSpec *pspec,
const GValue *value1,
const GValue *value2)
{
if (value1->data[0].v_uint64 < value2->data[0].v_uint64)
return -1;
else
return value1->data[0].v_uint64 > value2->data[0].v_uint64;
}
static void
param_unichar_init (GParamSpec *pspec)
{
GParamSpecUnichar *uspec = G_PARAM_SPEC_UNICHAR (pspec);
uspec->default_value = 0;
}
static void
param_unichar_set_default (GParamSpec *pspec,
GValue *value)
{
value->data[0].v_uint = G_PARAM_SPEC_UNICHAR (pspec)->default_value;
}
static gboolean
param_unichar_is_valid (GParamSpec *pspec,
const GValue *value)
{
return g_unichar_validate (value->data[0].v_uint);
}
static gboolean
param_unichar_validate (GParamSpec *pspec,
GValue *value)
{
gunichar oval = value->data[0].v_uint;
gboolean changed = FALSE;
if (!g_unichar_validate (oval))
{
value->data[0].v_uint = 0;
changed = TRUE;
}
return changed;
}
static gint
param_unichar_values_cmp (GParamSpec *pspec,
const GValue *value1,
const GValue *value2)
{
if (value1->data[0].v_uint < value2->data[0].v_uint)
return -1;
else
return value1->data[0].v_uint > value2->data[0].v_uint;
}
static void
param_enum_init (GParamSpec *pspec)
{
GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec);
espec->enum_class = NULL;
espec->default_value = 0;
}
static void
param_enum_finalize (GParamSpec *pspec)
{
GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec);
GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_ENUM));
if (espec->enum_class)
{
g_type_class_unref (espec->enum_class);
espec->enum_class = NULL;
}
parent_class->finalize (pspec);
}
static void
param_enum_set_default (GParamSpec *pspec,
GValue *value)
{
value->data[0].v_long = G_PARAM_SPEC_ENUM (pspec)->default_value;
}
static gboolean
param_enum_is_valid (GParamSpec *pspec,
const GValue *value)
{
GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec);
glong oval = value->data[0].v_long;
return g_enum_get_value (espec->enum_class, oval) != NULL;
}
static gboolean
param_enum_validate (GParamSpec *pspec,
GValue *value)
{
GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec);
glong oval = value->data[0].v_long;
if (!espec->enum_class ||
!g_enum_get_value (espec->enum_class, value->data[0].v_long))
value->data[0].v_long = espec->default_value;
return value->data[0].v_long != oval;
}
static void
param_flags_init (GParamSpec *pspec)
{
GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec);
fspec->flags_class = NULL;
fspec->default_value = 0;
}
static void
param_flags_finalize (GParamSpec *pspec)
{
GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec);
GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_FLAGS));
if (fspec->flags_class)
{
g_type_class_unref (fspec->flags_class);
fspec->flags_class = NULL;
}
parent_class->finalize (pspec);
}
static void
param_flags_set_default (GParamSpec *pspec,
GValue *value)
{
value->data[0].v_ulong = G_PARAM_SPEC_FLAGS (pspec)->default_value;
}
static gboolean
param_flags_is_valid (GParamSpec *pspec,
const GValue *value)
{
GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec);
gulong oval = value->data[0].v_ulong;
return (oval & ~fspec->flags_class->mask) == 0;
}
static gboolean
param_flags_validate (GParamSpec *pspec,
GValue *value)
{
GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec);
gulong oval = value->data[0].v_ulong;
if (fspec->flags_class)
value->data[0].v_ulong &= fspec->flags_class->mask;
else
value->data[0].v_ulong = fspec->default_value;
return value->data[0].v_ulong != oval;
}
static void
param_float_init (GParamSpec *pspec)
{
GParamSpecFloat *fspec = G_PARAM_SPEC_FLOAT (pspec);
fspec->minimum = -G_MAXFLOAT;
fspec->maximum = G_MAXFLOAT;
fspec->default_value = 0;
fspec->epsilon = G_FLOAT_EPSILON;
}
static void
param_float_set_default (GParamSpec *pspec,
GValue *value)
{
value->data[0].v_float = G_PARAM_SPEC_FLOAT (pspec)->default_value;
}
static gboolean
param_float_is_valid (GParamSpec *pspec,
const GValue *value)
{
GParamSpecFloat *fspec = G_PARAM_SPEC_FLOAT (pspec);
gfloat oval = value->data[0].v_float;
return fspec->minimum <= oval && oval <= fspec->maximum;
}
static gboolean
param_float_validate (GParamSpec *pspec,
GValue *value)
{
GParamSpecFloat *fspec = G_PARAM_SPEC_FLOAT (pspec);
gfloat oval = value->data[0].v_float;
value->data[0].v_float = CLAMP (value->data[0].v_float, fspec->minimum, fspec->maximum);
return value->data[0].v_float != oval;
}
static gint
param_float_values_cmp (GParamSpec *pspec,
const GValue *value1,
const GValue *value2)
{
gfloat epsilon = G_PARAM_SPEC_FLOAT (pspec)->epsilon;
if (value1->data[0].v_float < value2->data[0].v_float)
return - (value2->data[0].v_float - value1->data[0].v_float > epsilon);
else
return value1->data[0].v_float - value2->data[0].v_float > epsilon;
}
static void
param_double_init (GParamSpec *pspec)
{
GParamSpecDouble *dspec = G_PARAM_SPEC_DOUBLE (pspec);
dspec->minimum = -G_MAXDOUBLE;
dspec->maximum = G_MAXDOUBLE;
dspec->default_value = 0;
dspec->epsilon = G_DOUBLE_EPSILON;
}
static void
param_double_set_default (GParamSpec *pspec,
GValue *value)
{
value->data[0].v_double = G_PARAM_SPEC_DOUBLE (pspec)->default_value;
}
static gboolean
param_double_is_valid (GParamSpec *pspec,
const GValue *value)
{
GParamSpecDouble *dspec = G_PARAM_SPEC_DOUBLE (pspec);
gdouble oval = value->data[0].v_double;
return dspec->minimum <= oval && oval <= dspec->maximum;
}
static gboolean
param_double_validate (GParamSpec *pspec,
GValue *value)
{
GParamSpecDouble *dspec = G_PARAM_SPEC_DOUBLE (pspec);
gdouble oval = value->data[0].v_double;
value->data[0].v_double = CLAMP (value->data[0].v_double, dspec->minimum, dspec->maximum);
return value->data[0].v_double != oval;
}
static gint
param_double_values_cmp (GParamSpec *pspec,
const GValue *value1,
const GValue *value2)
{
gdouble epsilon = G_PARAM_SPEC_DOUBLE (pspec)->epsilon;
if (value1->data[0].v_double < value2->data[0].v_double)
return - (value2->data[0].v_double - value1->data[0].v_double > epsilon);
else
return value1->data[0].v_double - value2->data[0].v_double > epsilon;
}
static void
param_string_init (GParamSpec *pspec)
{
GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec);
sspec->default_value = NULL;
sspec->cset_first = NULL;
sspec->cset_nth = NULL;
sspec->substitutor = '_';
sspec->null_fold_if_empty = FALSE;
sspec->ensure_non_null = FALSE;
}
static void
param_string_finalize (GParamSpec *pspec)
{
GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec);
GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_STRING));
g_free (sspec->default_value);
g_free (sspec->cset_first);
g_free (sspec->cset_nth);
sspec->default_value = NULL;
sspec->cset_first = NULL;
sspec->cset_nth = NULL;
parent_class->finalize (pspec);
}
static void
param_string_set_default (GParamSpec *pspec,
GValue *value)
{
value->data[0].v_pointer = g_strdup (G_PARAM_SPEC_STRING (pspec)->default_value);
}
static gboolean
param_string_validate (GParamSpec *pspec,
GValue *value)
{
GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec);
gchar *string = value->data[0].v_pointer;
guint changed = 0;
if (string && string[0])
{
gchar *s;
if (sspec->cset_first && !strchr (sspec->cset_first, string[0]))
{
if (value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS)
{
value->data[0].v_pointer = g_strdup (string);
string = value->data[0].v_pointer;
value->data[1].v_uint &= ~G_VALUE_NOCOPY_CONTENTS;
}
string[0] = sspec->substitutor;
changed++;
}
if (sspec->cset_nth)
for (s = string + 1; *s; s++)
if (!strchr (sspec->cset_nth, *s))
{
if (value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS)
{
value->data[0].v_pointer = g_strdup (string);
s = (gchar*) value->data[0].v_pointer + (s - string);
string = value->data[0].v_pointer;
value->data[1].v_uint &= ~G_VALUE_NOCOPY_CONTENTS;
}
*s = sspec->substitutor;
changed++;
}
}
if (sspec->null_fold_if_empty && string && string[0] == 0)
{
if (!(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS))
g_free (value->data[0].v_pointer);
else
value->data[1].v_uint &= ~G_VALUE_NOCOPY_CONTENTS;
value->data[0].v_pointer = NULL;
changed++;
string = value->data[0].v_pointer;
}
if (sspec->ensure_non_null && !string)
{
value->data[1].v_uint &= ~G_VALUE_NOCOPY_CONTENTS;
value->data[0].v_pointer = g_strdup ("");
changed++;
string = value->data[0].v_pointer;
}
return changed;
}
static gboolean
param_string_is_valid (GParamSpec *pspec,
const GValue *value)
{
GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec);
gboolean ret = TRUE;
if (sspec->cset_first != NULL || sspec->cset_nth != NULL ||
sspec->ensure_non_null || sspec->null_fold_if_empty)
{
GValue tmp_value = G_VALUE_INIT;
g_value_init (&tmp_value, G_VALUE_TYPE (value));
g_value_copy (value, &tmp_value);
ret = !param_string_validate (pspec, &tmp_value);
g_value_unset (&tmp_value);
}
return ret;
}
static gint
param_string_values_cmp (GParamSpec *pspec,
const GValue *value1,
const GValue *value2)
{
if (!value1->data[0].v_pointer)
return value2->data[0].v_pointer != NULL ? -1 : 0;
else if (!value2->data[0].v_pointer)
return value1->data[0].v_pointer != NULL;
else
return strcmp (value1->data[0].v_pointer, value2->data[0].v_pointer);
}
static void
param_param_init (GParamSpec *pspec)
{
/* GParamSpecParam *spec = G_PARAM_SPEC_PARAM (pspec); */
}
static void
param_param_set_default (GParamSpec *pspec,
GValue *value)
{
value->data[0].v_pointer = NULL;
}
static gboolean
param_param_is_valid (GParamSpec *pspec,
const GValue *value)
{
GParamSpec *param = value->data[0].v_pointer;
if (param == NULL)
return FALSE;
return g_value_type_compatible (G_PARAM_SPEC_TYPE (param), G_PARAM_SPEC_VALUE_TYPE (pspec));
}
static gboolean
param_param_validate (GParamSpec *pspec,
GValue *value)
{
/* GParamSpecParam *spec = G_PARAM_SPEC_PARAM (pspec); */
GParamSpec *param = value->data[0].v_pointer;
guint changed = 0;
if (param && !g_value_type_compatible (G_PARAM_SPEC_TYPE (param), G_PARAM_SPEC_VALUE_TYPE (pspec)))
{
g_param_spec_unref (param);
value->data[0].v_pointer = NULL;
changed++;
}
return changed;
}
static void
param_boxed_init (GParamSpec *pspec)
{
/* GParamSpecBoxed *bspec = G_PARAM_SPEC_BOXED (pspec); */
}
static void
param_boxed_set_default (GParamSpec *pspec,
GValue *value)
{
value->data[0].v_pointer = NULL;
}
static gint
param_boxed_values_cmp (GParamSpec *pspec,
const GValue *value1,
const GValue *value2)
{
guint8 *p1 = value1->data[0].v_pointer;
guint8 *p2 = value2->data[0].v_pointer;
/* not much to compare here, try to at least provide stable lesser/greater result */
return p1 < p2 ? -1 : p1 > p2;
}
static void
param_pointer_init (GParamSpec *pspec)
{
/* GParamSpecPointer *spec = G_PARAM_SPEC_POINTER (pspec); */
}
static void
param_pointer_set_default (GParamSpec *pspec,
GValue *value)
{
value->data[0].v_pointer = NULL;
}
static gint
param_pointer_values_cmp (GParamSpec *pspec,
const GValue *value1,
const GValue *value2)
{
guint8 *p1 = value1->data[0].v_pointer;
guint8 *p2 = value2->data[0].v_pointer;
/* not much to compare here, try to at least provide stable lesser/greater result */
return p1 < p2 ? -1 : p1 > p2;
}
static void
param_value_array_init (GParamSpec *pspec)
{
GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
aspec->element_spec = NULL;
aspec->fixed_n_elements = 0; /* disable */
}
static inline guint
value_array_ensure_size (GValueArray *value_array,
guint fixed_n_elements)
{
guint changed = 0;
if (fixed_n_elements)
{
while (value_array->n_values < fixed_n_elements)
{
g_value_array_append (value_array, NULL);
changed++;
}
while (value_array->n_values > fixed_n_elements)
{
g_value_array_remove (value_array, value_array->n_values - 1);
changed++;
}
}
return changed;
}
static void
param_value_array_finalize (GParamSpec *pspec)
{
GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_VALUE_ARRAY));
if (aspec->element_spec)
{
g_param_spec_unref (aspec->element_spec);
aspec->element_spec = NULL;
}
parent_class->finalize (pspec);
}
static void
param_value_array_set_default (GParamSpec *pspec,
GValue *value)
{
GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
if (!value->data[0].v_pointer && aspec->fixed_n_elements)
value->data[0].v_pointer = g_value_array_new (aspec->fixed_n_elements);
if (value->data[0].v_pointer)
{
/* g_value_reset (value); already done */
value_array_ensure_size (value->data[0].v_pointer, aspec->fixed_n_elements);
}
}
static gboolean
param_value_array_validate (GParamSpec *pspec,
GValue *value)
{
GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
GValueArray *value_array = value->data[0].v_pointer;
guint changed = 0;
if (!value->data[0].v_pointer && aspec->fixed_n_elements)
value_array = value->data[0].v_pointer = g_value_array_new (aspec->fixed_n_elements);
if (value->data[0].v_pointer)
{
/* ensure array size validity */
changed += value_array_ensure_size (value_array, aspec->fixed_n_elements);
/* ensure array values validity against a present element spec */
if (aspec->element_spec)
{
GParamSpec *element_spec = aspec->element_spec;
guint i;
for (i = 0; i < value_array->n_values; i++)
{
GValue *element = value_array->values + i;
/* need to fixup value type, or ensure that the array value is initialized at all */
if (!g_value_type_compatible (G_VALUE_TYPE (element), G_PARAM_SPEC_VALUE_TYPE (element_spec)))
{
if (G_VALUE_TYPE (element) != 0)
g_value_unset (element);
g_value_init (element, G_PARAM_SPEC_VALUE_TYPE (element_spec));
g_param_value_set_default (element_spec, element);
changed++;
}
else
{
/* validate array value against element_spec */
changed += g_param_value_validate (element_spec, element);
}
}
}
}
return changed;
}
static gint
param_value_array_values_cmp (GParamSpec *pspec,
const GValue *value1,
const GValue *value2)
{
GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
GValueArray *value_array1 = value1->data[0].v_pointer;
GValueArray *value_array2 = value2->data[0].v_pointer;
if (!value_array1 || !value_array2)
return value_array2 ? -1 : value_array1 != value_array2;
if (value_array1->n_values != value_array2->n_values)
return value_array1->n_values < value_array2->n_values ? -1 : 1;
else if (!aspec->element_spec)
{
/* we need an element specification for comparisons, so there's not much
* to compare here, try to at least provide stable lesser/greater result
*/
return value_array1->n_values < value_array2->n_values ? -1 : value_array1->n_values > value_array2->n_values;
}
else /* value_array1->n_values == value_array2->n_values */
{
guint i;
for (i = 0; i < value_array1->n_values; i++)
{
GValue *element1 = value_array1->values + i;
GValue *element2 = value_array2->values + i;
gint cmp;
/* need corresponding element types, provide stable result otherwise */
if (G_VALUE_TYPE (element1) != G_VALUE_TYPE (element2))
return G_VALUE_TYPE (element1) < G_VALUE_TYPE (element2) ? -1 : 1;
cmp = g_param_values_cmp (aspec->element_spec, element1, element2);
if (cmp)
return cmp;
}
return 0;
}
}
static void
param_object_init (GParamSpec *pspec)
{
/* GParamSpecObject *ospec = G_PARAM_SPEC_OBJECT (pspec); */
}
static void
param_object_set_default (GParamSpec *pspec,
GValue *value)
{
value->data[0].v_pointer = NULL;
}
static gboolean
param_object_is_valid (GParamSpec *pspec,
const GValue *value)
{
GParamSpecObject *ospec = G_PARAM_SPEC_OBJECT (pspec);
GObject *object = value->data[0].v_pointer;
return object &&
g_value_type_compatible (G_OBJECT_TYPE (object), G_PARAM_SPEC_VALUE_TYPE (ospec));
}
static gboolean
param_object_validate (GParamSpec *pspec,
GValue *value)
{
GParamSpecObject *ospec = G_PARAM_SPEC_OBJECT (pspec);
GObject *object = value->data[0].v_pointer;
guint changed = 0;
if (object && !g_value_type_compatible (G_OBJECT_TYPE (object), G_PARAM_SPEC_VALUE_TYPE (ospec)))
{
g_object_unref (object);
value->data[0].v_pointer = NULL;
changed++;
}
return changed;
}
static gint
param_object_values_cmp (GParamSpec *pspec,
const GValue *value1,
const GValue *value2)
{
guint8 *p1 = value1->data[0].v_pointer;
guint8 *p2 = value2->data[0].v_pointer;
/* not much to compare here, try to at least provide stable lesser/greater result */
return p1 < p2 ? -1 : p1 > p2;
}
static void
param_override_init (GParamSpec *pspec)
{
/* GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec); */
}
static void
param_override_finalize (GParamSpec *pspec)
{
GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec);
GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_OVERRIDE));
if (ospec->overridden)
{
g_param_spec_unref (ospec->overridden);
ospec->overridden = NULL;
}
parent_class->finalize (pspec);
}
static void
param_override_set_default (GParamSpec *pspec,
GValue *value)
{
GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec);
g_param_value_set_default (ospec->overridden, value);
}
static gboolean
param_override_is_valid (GParamSpec *pspec,
const GValue *value)
{
GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec);
return g_param_value_is_valid (ospec->overridden, value);
}
static gboolean
param_override_validate (GParamSpec *pspec,
GValue *value)
{
GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec);
return g_param_value_validate (ospec->overridden, value);
}
static gint
param_override_values_cmp (GParamSpec *pspec,
const GValue *value1,
const GValue *value2)
{
GParamSpecOverride *ospec = G_PARAM_SPEC_OVERRIDE (pspec);
return g_param_values_cmp (ospec->overridden, value1, value2);
}
static void
param_gtype_init (GParamSpec *pspec)
{
}
static void
param_gtype_set_default (GParamSpec *pspec,
GValue *value)
{
GParamSpecGType *tspec = G_PARAM_SPEC_GTYPE (pspec);
value->data[0].v_pointer = GTYPE_TO_POINTER (tspec->is_a_type);
}
static gboolean
param_gtype_is_valid (GParamSpec *pspec,
const GValue *value)
{
GParamSpecGType *tspec = G_PARAM_SPEC_GTYPE (pspec);
GType gtype = GPOINTER_TO_TYPE (value->data[0].v_pointer);
return tspec->is_a_type == G_TYPE_NONE ||
g_type_is_a (gtype, tspec->is_a_type);
}
static gboolean
param_gtype_validate (GParamSpec *pspec,
GValue *value)
{
GParamSpecGType *tspec = G_PARAM_SPEC_GTYPE (pspec);
GType gtype = GPOINTER_TO_TYPE (value->data[0].v_pointer);
guint changed = 0;
if (tspec->is_a_type != G_TYPE_NONE && !g_type_is_a (gtype, tspec->is_a_type))
{
value->data[0].v_pointer = GTYPE_TO_POINTER (tspec->is_a_type);
changed++;
}
return changed;
}
static gint
param_gtype_values_cmp (GParamSpec *pspec,
const GValue *value1,
const GValue *value2)
{
GType p1 = GPOINTER_TO_TYPE (value1->data[0].v_pointer);
GType p2 = GPOINTER_TO_TYPE (value2->data[0].v_pointer);
/* not much to compare here, try to at least provide stable lesser/greater result */
return p1 < p2 ? -1 : p1 > p2;
}
static void
param_variant_init (GParamSpec *pspec)
{
GParamSpecVariant *vspec = G_PARAM_SPEC_VARIANT (pspec);
vspec->type = NULL;
vspec->default_value = NULL;
}
static void
param_variant_finalize (GParamSpec *pspec)
{
GParamSpecVariant *vspec = G_PARAM_SPEC_VARIANT (pspec);
GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_VARIANT));
if (vspec->default_value)
g_variant_unref (vspec->default_value);
g_variant_type_free (vspec->type);
parent_class->finalize (pspec);
}
static void
param_variant_set_default (GParamSpec *pspec,
GValue *value)
{
value->data[0].v_pointer = G_PARAM_SPEC_VARIANT (pspec)->default_value;
value->data[1].v_uint |= G_VALUE_NOCOPY_CONTENTS;
}
static gboolean
param_variant_is_valid (GParamSpec *pspec,
const GValue *value)
{
GParamSpecVariant *vspec = G_PARAM_SPEC_VARIANT (pspec);
GVariant *variant = value->data[0].v_pointer;
if (variant == NULL)
return vspec->default_value == NULL;
else
return g_variant_is_of_type (variant, vspec->type);
}
static gboolean
param_variant_validate (GParamSpec *pspec,
GValue *value)
{
GParamSpecVariant *vspec = G_PARAM_SPEC_VARIANT (pspec);
GVariant *variant = value->data[0].v_pointer;
if ((variant == NULL && vspec->default_value != NULL) ||
(variant != NULL && !g_variant_is_of_type (variant, vspec->type)))
{
g_param_value_set_default (pspec, value);
return TRUE;
}
return FALSE;
}
/* g_variant_compare() can only be used with scalar types. */
static gboolean
variant_is_incomparable (GVariant *v)
{
GVariantClass v_class = g_variant_classify (v);
return (v_class == G_VARIANT_CLASS_HANDLE ||
v_class == G_VARIANT_CLASS_VARIANT ||
v_class == G_VARIANT_CLASS_MAYBE||
v_class == G_VARIANT_CLASS_ARRAY ||
v_class == G_VARIANT_CLASS_TUPLE ||
v_class == G_VARIANT_CLASS_DICT_ENTRY);
}
static gint
param_variant_values_cmp (GParamSpec *pspec,
const GValue *value1,
const GValue *value2)
{
GVariant *v1 = value1->data[0].v_pointer;
GVariant *v2 = value2->data[0].v_pointer;
if (v1 == NULL && v2 == NULL)
return 0;
else if (v1 == NULL && v2 != NULL)
return -1;
else if (v1 != NULL && v2 == NULL)
return 1;
if (!g_variant_type_equal (g_variant_get_type (v1), g_variant_get_type (v2)) ||
variant_is_incomparable (v1) ||
variant_is_incomparable (v2))
return g_variant_equal (v1, v2) ? 0 : (v1 < v2 ? -1 : 1);
return g_variant_compare (v1, v2);
}
/* --- type initialization --- */
#define set_is_valid_vfunc(type,func) { \
GParamSpecClass *class = g_type_class_ref (type); \
class->value_is_valid = func; \
g_type_class_unref (class); \
}
GType *g_param_spec_types = NULL;
void
_g_param_spec_types_init (void)
{
const guint n_types = 23;
GType type, *spec_types;
#ifndef G_DISABLE_ASSERT
GType *spec_types_bound;
#endif
g_param_spec_types = g_new0 (GType, n_types);
spec_types = g_param_spec_types;
#ifndef G_DISABLE_ASSERT
spec_types_bound = g_param_spec_types + n_types;
#endif
/* G_TYPE_PARAM_CHAR
*/
{
const GParamSpecTypeInfo pspec_info = {
sizeof (GParamSpecChar), /* instance_size */
16, /* n_preallocs */
param_char_init, /* instance_init */
G_TYPE_CHAR, /* value_type */
NULL, /* finalize */
param_char_set_default, /* value_set_default */
param_char_validate, /* value_validate */
param_int_values_cmp, /* values_cmp */
};
type = g_param_type_register_static (g_intern_static_string ("GParamChar"), &pspec_info);
set_is_valid_vfunc (type, param_char_is_valid);
*spec_types++ = type;
g_assert (type == G_TYPE_PARAM_CHAR);
}
/* G_TYPE_PARAM_UCHAR
*/
{
const GParamSpecTypeInfo pspec_info = {
sizeof (GParamSpecUChar), /* instance_size */
16, /* n_preallocs */
param_uchar_init, /* instance_init */
G_TYPE_UCHAR, /* value_type */
NULL, /* finalize */
param_uchar_set_default, /* value_set_default */
param_uchar_validate, /* value_validate */
param_uint_values_cmp, /* values_cmp */
};
type = g_param_type_register_static (g_intern_static_string ("GParamUChar"), &pspec_info);
set_is_valid_vfunc (type, param_uchar_is_valid);
*spec_types++ = type;
g_assert (type == G_TYPE_PARAM_UCHAR);
}
/* G_TYPE_PARAM_BOOLEAN
*/
{
const GParamSpecTypeInfo pspec_info = {
sizeof (GParamSpecBoolean), /* instance_size */
16, /* n_preallocs */
NULL, /* instance_init */
G_TYPE_BOOLEAN, /* value_type */
NULL, /* finalize */
param_boolean_set_default, /* value_set_default */
param_boolean_validate, /* value_validate */
param_int_values_cmp, /* values_cmp */
};
type = g_param_type_register_static (g_intern_static_string ("GParamBoolean"), &pspec_info);
set_is_valid_vfunc (type, param_boolean_is_valid);
*spec_types++ = type;
g_assert (type == G_TYPE_PARAM_BOOLEAN);
}
/* G_TYPE_PARAM_INT
*/
{
const GParamSpecTypeInfo pspec_info = {
sizeof (GParamSpecInt), /* instance_size */
16, /* n_preallocs */
param_int_init, /* instance_init */
G_TYPE_INT, /* value_type */
NULL, /* finalize */
param_int_set_default, /* value_set_default */
param_int_validate, /* value_validate */
param_int_values_cmp, /* values_cmp */
};
type = g_param_type_register_static (g_intern_static_string ("GParamInt"), &pspec_info);
set_is_valid_vfunc (type, param_int_is_valid);
*spec_types++ = type;
g_assert (type == G_TYPE_PARAM_INT);
}
/* G_TYPE_PARAM_UINT
*/
{
const GParamSpecTypeInfo pspec_info = {
sizeof (GParamSpecUInt), /* instance_size */
16, /* n_preallocs */
param_uint_init, /* instance_init */
G_TYPE_UINT, /* value_type */
NULL, /* finalize */
param_uint_set_default, /* value_set_default */
param_uint_validate, /* value_validate */
param_uint_values_cmp, /* values_cmp */
};
type = g_param_type_register_static (g_intern_static_string ("GParamUInt"), &pspec_info);
set_is_valid_vfunc (type, param_uint_is_valid);
*spec_types++ = type;
g_assert (type == G_TYPE_PARAM_UINT);
}
/* G_TYPE_PARAM_LONG
*/
{
const GParamSpecTypeInfo pspec_info = {
sizeof (GParamSpecLong), /* instance_size */
16, /* n_preallocs */
param_long_init, /* instance_init */
G_TYPE_LONG, /* value_type */
NULL, /* finalize */
param_long_set_default, /* value_set_default */
param_long_validate, /* value_validate */
param_long_values_cmp, /* values_cmp */
};
type = g_param_type_register_static (g_intern_static_string ("GParamLong"), &pspec_info);
set_is_valid_vfunc (type, param_long_is_valid);
*spec_types++ = type;
g_assert (type == G_TYPE_PARAM_LONG);
}
/* G_TYPE_PARAM_ULONG
*/
{
const GParamSpecTypeInfo pspec_info = {
sizeof (GParamSpecULong), /* instance_size */
16, /* n_preallocs */
param_ulong_init, /* instance_init */
G_TYPE_ULONG, /* value_type */
NULL, /* finalize */
param_ulong_set_default, /* value_set_default */
param_ulong_validate, /* value_validate */
param_ulong_values_cmp, /* values_cmp */
};
type = g_param_type_register_static (g_intern_static_string ("GParamULong"), &pspec_info);
set_is_valid_vfunc (type, param_ulong_is_valid);
*spec_types++ = type;
g_assert (type == G_TYPE_PARAM_ULONG);
}
/* G_TYPE_PARAM_INT64
*/
{
const GParamSpecTypeInfo pspec_info = {
sizeof (GParamSpecInt64), /* instance_size */
16, /* n_preallocs */
param_int64_init, /* instance_init */
G_TYPE_INT64, /* value_type */
NULL, /* finalize */
param_int64_set_default, /* value_set_default */
param_int64_validate, /* value_validate */
param_int64_values_cmp, /* values_cmp */
};
type = g_param_type_register_static (g_intern_static_string ("GParamInt64"), &pspec_info);
set_is_valid_vfunc (type, param_int64_is_valid);
*spec_types++ = type;
g_assert (type == G_TYPE_PARAM_INT64);
}
/* G_TYPE_PARAM_UINT64
*/
{
const GParamSpecTypeInfo pspec_info = {
sizeof (GParamSpecUInt64), /* instance_size */
16, /* n_preallocs */
param_uint64_init, /* instance_init */
G_TYPE_UINT64, /* value_type */
NULL, /* finalize */
param_uint64_set_default, /* value_set_default */
param_uint64_validate, /* value_validate */
param_uint64_values_cmp, /* values_cmp */
};
type = g_param_type_register_static (g_intern_static_string ("GParamUInt64"), &pspec_info);
set_is_valid_vfunc (type, param_uint64_is_valid);
*spec_types++ = type;
g_assert (type == G_TYPE_PARAM_UINT64);
}
/* G_TYPE_PARAM_UNICHAR
*/
{
const GParamSpecTypeInfo pspec_info = {
sizeof (GParamSpecUnichar), /* instance_size */
16, /* n_preallocs */
param_unichar_init, /* instance_init */
G_TYPE_UINT, /* value_type */
NULL, /* finalize */
param_unichar_set_default, /* value_set_default */
param_unichar_validate, /* value_validate */
param_unichar_values_cmp, /* values_cmp */
};
type = g_param_type_register_static (g_intern_static_string ("GParamUnichar"), &pspec_info);
set_is_valid_vfunc (type, param_unichar_is_valid);
*spec_types++ = type;
g_assert (type == G_TYPE_PARAM_UNICHAR);
}
/* G_TYPE_PARAM_ENUM
*/
{
const GParamSpecTypeInfo pspec_info = {
sizeof (GParamSpecEnum), /* instance_size */
16, /* n_preallocs */
param_enum_init, /* instance_init */
G_TYPE_ENUM, /* value_type */
param_enum_finalize, /* finalize */
param_enum_set_default, /* value_set_default */
param_enum_validate, /* value_validate */
param_long_values_cmp, /* values_cmp */
};
type = g_param_type_register_static (g_intern_static_string ("GParamEnum"), &pspec_info);
set_is_valid_vfunc (type, param_enum_is_valid);
*spec_types++ = type;
g_assert (type == G_TYPE_PARAM_ENUM);
}
/* G_TYPE_PARAM_FLAGS
*/
{
const GParamSpecTypeInfo pspec_info = {
sizeof (GParamSpecFlags), /* instance_size */
16, /* n_preallocs */
param_flags_init, /* instance_init */
G_TYPE_FLAGS, /* value_type */
param_flags_finalize, /* finalize */
param_flags_set_default, /* value_set_default */
param_flags_validate, /* value_validate */
param_ulong_values_cmp, /* values_cmp */
};
type = g_param_type_register_static (g_intern_static_string ("GParamFlags"), &pspec_info);
set_is_valid_vfunc (type, param_flags_is_valid);
*spec_types++ = type;
g_assert (type == G_TYPE_PARAM_FLAGS);
}
/* G_TYPE_PARAM_FLOAT
*/
{
const GParamSpecTypeInfo pspec_info = {
sizeof (GParamSpecFloat), /* instance_size */
16, /* n_preallocs */
param_float_init, /* instance_init */
G_TYPE_FLOAT, /* value_type */
NULL, /* finalize */
param_float_set_default, /* value_set_default */
param_float_validate, /* value_validate */
param_float_values_cmp, /* values_cmp */
};
type = g_param_type_register_static (g_intern_static_string ("GParamFloat"), &pspec_info);
set_is_valid_vfunc (type, param_float_is_valid);
*spec_types++ = type;
g_assert (type == G_TYPE_PARAM_FLOAT);
}
/* G_TYPE_PARAM_DOUBLE
*/
{
const GParamSpecTypeInfo pspec_info = {
sizeof (GParamSpecDouble), /* instance_size */
16, /* n_preallocs */
param_double_init, /* instance_init */
G_TYPE_DOUBLE, /* value_type */
NULL, /* finalize */
param_double_set_default, /* value_set_default */
param_double_validate, /* value_validate */
param_double_values_cmp, /* values_cmp */
};
type = g_param_type_register_static (g_intern_static_string ("GParamDouble"), &pspec_info);
set_is_valid_vfunc (type, param_double_is_valid);
*spec_types++ = type;
g_assert (type == G_TYPE_PARAM_DOUBLE);
}
/* G_TYPE_PARAM_STRING
*/
{
const GParamSpecTypeInfo pspec_info = {
sizeof (GParamSpecString), /* instance_size */
16, /* n_preallocs */
param_string_init, /* instance_init */
G_TYPE_STRING, /* value_type */
param_string_finalize, /* finalize */
param_string_set_default, /* value_set_default */
param_string_validate, /* value_validate */
param_string_values_cmp, /* values_cmp */
};
type = g_param_type_register_static (g_intern_static_string ("GParamString"), &pspec_info);
set_is_valid_vfunc (type, param_string_is_valid);
*spec_types++ = type;
g_assert (type == G_TYPE_PARAM_STRING);
}
/* G_TYPE_PARAM_PARAM
*/
{
const GParamSpecTypeInfo pspec_info = {
sizeof (GParamSpecParam), /* instance_size */
16, /* n_preallocs */
param_param_init, /* instance_init */
G_TYPE_PARAM, /* value_type */
NULL, /* finalize */
param_param_set_default, /* value_set_default */
param_param_validate, /* value_validate */
param_pointer_values_cmp, /* values_cmp */
};
type = g_param_type_register_static (g_intern_static_string ("GParamParam"), &pspec_info);
set_is_valid_vfunc (type, param_param_is_valid);
*spec_types++ = type;
g_assert (type == G_TYPE_PARAM_PARAM);
}
/* G_TYPE_PARAM_BOXED
*/
{
const GParamSpecTypeInfo pspec_info = {
sizeof (GParamSpecBoxed), /* instance_size */
4, /* n_preallocs */
param_boxed_init, /* instance_init */
G_TYPE_BOXED, /* value_type */
NULL, /* finalize */
param_boxed_set_default, /* value_set_default */
NULL, /* value_validate */
param_boxed_values_cmp, /* values_cmp */
};
type = g_param_type_register_static (g_intern_static_string ("GParamBoxed"), &pspec_info);
*spec_types++ = type;
g_assert (type == G_TYPE_PARAM_BOXED);
}
/* G_TYPE_PARAM_POINTER
*/
{
const GParamSpecTypeInfo pspec_info = {
sizeof (GParamSpecPointer), /* instance_size */
0, /* n_preallocs */
param_pointer_init, /* instance_init */
G_TYPE_POINTER, /* value_type */
NULL, /* finalize */
param_pointer_set_default, /* value_set_default */
NULL,
param_pointer_values_cmp, /* values_cmp */
};
type = g_param_type_register_static (g_intern_static_string ("GParamPointer"), &pspec_info);
*spec_types++ = type;
g_assert (type == G_TYPE_PARAM_POINTER);
}
/* G_TYPE_PARAM_VALUE_ARRAY
*/
{
/* const */ GParamSpecTypeInfo pspec_info = {
sizeof (GParamSpecValueArray), /* instance_size */
0, /* n_preallocs */
param_value_array_init, /* instance_init */
0xdeadbeef, /* value_type, assigned further down */
param_value_array_finalize, /* finalize */
param_value_array_set_default, /* value_set_default */
param_value_array_validate, /* value_validate */
param_value_array_values_cmp, /* values_cmp */
};
pspec_info.value_type = G_TYPE_VALUE_ARRAY;
type = g_param_type_register_static (g_intern_static_string ("GParamValueArray"), &pspec_info);
*spec_types++ = type;
g_assert (type == G_TYPE_PARAM_VALUE_ARRAY);
}
/* G_TYPE_PARAM_OBJECT
*/
{
const GParamSpecTypeInfo pspec_info = {
sizeof (GParamSpecObject), /* instance_size */
16, /* n_preallocs */
param_object_init, /* instance_init */
G_TYPE_OBJECT, /* value_type */
NULL, /* finalize */
param_object_set_default, /* value_set_default */
param_object_validate, /* value_validate */
param_object_values_cmp, /* values_cmp */
};
type = g_param_type_register_static (g_intern_static_string ("GParamObject"), &pspec_info);
set_is_valid_vfunc (type, param_object_is_valid);
*spec_types++ = type;
g_assert (type == G_TYPE_PARAM_OBJECT);
}
/* G_TYPE_PARAM_OVERRIDE
*/
{
const GParamSpecTypeInfo pspec_info = {
sizeof (GParamSpecOverride), /* instance_size */
16, /* n_preallocs */
param_override_init, /* instance_init */
G_TYPE_NONE, /* value_type */
param_override_finalize, /* finalize */
param_override_set_default, /* value_set_default */
param_override_validate, /* value_validate */
param_override_values_cmp, /* values_cmp */
};
type = g_param_type_register_static (g_intern_static_string ("GParamOverride"), &pspec_info);
set_is_valid_vfunc (type, param_override_is_valid);
*spec_types++ = type;
g_assert (type == G_TYPE_PARAM_OVERRIDE);
}
/* G_TYPE_PARAM_GTYPE
*/
{
GParamSpecTypeInfo pspec_info = {
sizeof (GParamSpecGType), /* instance_size */
0, /* n_preallocs */
param_gtype_init, /* instance_init */
0xdeadbeef, /* value_type, assigned further down */
NULL, /* finalize */
param_gtype_set_default, /* value_set_default */
param_gtype_validate, /* value_validate */
param_gtype_values_cmp, /* values_cmp */
};
pspec_info.value_type = G_TYPE_GTYPE;
type = g_param_type_register_static (g_intern_static_string ("GParamGType"), &pspec_info);
set_is_valid_vfunc (type, param_gtype_is_valid);
*spec_types++ = type;
g_assert (type == G_TYPE_PARAM_GTYPE);
}
/* G_TYPE_PARAM_VARIANT
*/
{
const GParamSpecTypeInfo pspec_info = {
sizeof (GParamSpecVariant), /* instance_size */
0, /* n_preallocs */
param_variant_init, /* instance_init */
G_TYPE_VARIANT, /* value_type */
param_variant_finalize, /* finalize */
param_variant_set_default, /* value_set_default */
param_variant_validate, /* value_validate */
param_variant_values_cmp, /* values_cmp */
};
type = g_param_type_register_static (g_intern_static_string ("GParamVariant"), &pspec_info);
set_is_valid_vfunc (type, param_variant_is_valid);
*spec_types++ = type;
g_assert (type == G_TYPE_PARAM_VARIANT);
}
g_assert (spec_types == spec_types_bound);
}
/* --- GParamSpec initialization --- */
/**
* g_param_spec_char:
* @name: canonical name of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @minimum: minimum value for the property specified
* @maximum: maximum value for the property specified
* @default_value: default value for the property specified
* @flags: flags for the property specified
*
* Creates a new #GParamSpecChar instance specifying a %G_TYPE_CHAR property.
*
* Returns: (transfer full): a newly created parameter specification
*/
GParamSpec*
g_param_spec_char (const gchar *name,
const gchar *nick,
const gchar *blurb,
gint8 minimum,
gint8 maximum,
gint8 default_value,
GParamFlags flags)
{
GParamSpecChar *cspec;
g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
cspec = g_param_spec_internal (G_TYPE_PARAM_CHAR,
name,
nick,
blurb,
flags);
cspec->minimum = minimum;
cspec->maximum = maximum;
cspec->default_value = default_value;
return G_PARAM_SPEC (cspec);
}
/**
* g_param_spec_uchar:
* @name: canonical name of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @minimum: minimum value for the property specified
* @maximum: maximum value for the property specified
* @default_value: default value for the property specified
* @flags: flags for the property specified
*
* Creates a new #GParamSpecUChar instance specifying a %G_TYPE_UCHAR property.
*
* Returns: (transfer full): a newly created parameter specification
*/
GParamSpec*
g_param_spec_uchar (const gchar *name,
const gchar *nick,
const gchar *blurb,
guint8 minimum,
guint8 maximum,
guint8 default_value,
GParamFlags flags)
{
GParamSpecUChar *uspec;
g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
uspec = g_param_spec_internal (G_TYPE_PARAM_UCHAR,
name,
nick,
blurb,
flags);
uspec->minimum = minimum;
uspec->maximum = maximum;
uspec->default_value = default_value;
return G_PARAM_SPEC (uspec);
}
/**
* g_param_spec_boolean:
* @name: canonical name of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @default_value: default value for the property specified
* @flags: flags for the property specified
*
* Creates a new #GParamSpecBoolean instance specifying a %G_TYPE_BOOLEAN
* property. In many cases, it may be more appropriate to use an enum with
* g_param_spec_enum(), both to improve code clarity by using explicitly named
* values, and to allow for more values to be added in future without breaking
* API.
*
* See g_param_spec_internal() for details on property names.
*
* Returns: (transfer full): a newly created parameter specification
*/
GParamSpec*
g_param_spec_boolean (const gchar *name,
const gchar *nick,
const gchar *blurb,
gboolean default_value,
GParamFlags flags)
{
GParamSpecBoolean *bspec;
g_return_val_if_fail (default_value == TRUE || default_value == FALSE, NULL);
bspec = g_param_spec_internal (G_TYPE_PARAM_BOOLEAN,
name,
nick,
blurb,
flags);
bspec->default_value = default_value;
return G_PARAM_SPEC (bspec);
}
/**
* g_param_spec_int:
* @name: canonical name of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @minimum: minimum value for the property specified
* @maximum: maximum value for the property specified
* @default_value: default value for the property specified
* @flags: flags for the property specified
*
* Creates a new #GParamSpecInt instance specifying a %G_TYPE_INT property.
*
* See g_param_spec_internal() for details on property names.
*
* Returns: (transfer full): a newly created parameter specification
*/
GParamSpec*
g_param_spec_int (const gchar *name,
const gchar *nick,
const gchar *blurb,
gint minimum,
gint maximum,
gint default_value,
GParamFlags flags)
{
GParamSpecInt *ispec;
g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
ispec = g_param_spec_internal (G_TYPE_PARAM_INT,
name,
nick,
blurb,
flags);
ispec->minimum = minimum;
ispec->maximum = maximum;
ispec->default_value = default_value;
return G_PARAM_SPEC (ispec);
}
/**
* g_param_spec_uint:
* @name: canonical name of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @minimum: minimum value for the property specified
* @maximum: maximum value for the property specified
* @default_value: default value for the property specified
* @flags: flags for the property specified
*
* Creates a new #GParamSpecUInt instance specifying a %G_TYPE_UINT property.
*
* See g_param_spec_internal() for details on property names.
*
* Returns: (transfer full): a newly created parameter specification
*/
GParamSpec*
g_param_spec_uint (const gchar *name,
const gchar *nick,
const gchar *blurb,
guint minimum,
guint maximum,
guint default_value,
GParamFlags flags)
{
GParamSpecUInt *uspec;
g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
uspec = g_param_spec_internal (G_TYPE_PARAM_UINT,
name,
nick,
blurb,
flags);
uspec->minimum = minimum;
uspec->maximum = maximum;
uspec->default_value = default_value;
return G_PARAM_SPEC (uspec);
}
/**
* g_param_spec_long:
* @name: canonical name of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @minimum: minimum value for the property specified
* @maximum: maximum value for the property specified
* @default_value: default value for the property specified
* @flags: flags for the property specified
*
* Creates a new #GParamSpecLong instance specifying a %G_TYPE_LONG property.
*
* See g_param_spec_internal() for details on property names.
*
* Returns: (transfer full): a newly created parameter specification
*/
GParamSpec*
g_param_spec_long (const gchar *name,
const gchar *nick,
const gchar *blurb,
glong minimum,
glong maximum,
glong default_value,
GParamFlags flags)
{
GParamSpecLong *lspec;
g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
lspec = g_param_spec_internal (G_TYPE_PARAM_LONG,
name,
nick,
blurb,
flags);
lspec->minimum = minimum;
lspec->maximum = maximum;
lspec->default_value = default_value;
return G_PARAM_SPEC (lspec);
}
/**
* g_param_spec_ulong:
* @name: canonical name of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @minimum: minimum value for the property specified
* @maximum: maximum value for the property specified
* @default_value: default value for the property specified
* @flags: flags for the property specified
*
* Creates a new #GParamSpecULong instance specifying a %G_TYPE_ULONG
* property.
*
* See g_param_spec_internal() for details on property names.
*
* Returns: (transfer full): a newly created parameter specification
*/
GParamSpec*
g_param_spec_ulong (const gchar *name,
const gchar *nick,
const gchar *blurb,
gulong minimum,
gulong maximum,
gulong default_value,
GParamFlags flags)
{
GParamSpecULong *uspec;
g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
uspec = g_param_spec_internal (G_TYPE_PARAM_ULONG,
name,
nick,
blurb,
flags);
uspec->minimum = minimum;
uspec->maximum = maximum;
uspec->default_value = default_value;
return G_PARAM_SPEC (uspec);
}
/**
* g_param_spec_int64:
* @name: canonical name of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @minimum: minimum value for the property specified
* @maximum: maximum value for the property specified
* @default_value: default value for the property specified
* @flags: flags for the property specified
*
* Creates a new #GParamSpecInt64 instance specifying a %G_TYPE_INT64 property.
*
* See g_param_spec_internal() for details on property names.
*
* Returns: (transfer full): a newly created parameter specification
*/
GParamSpec*
g_param_spec_int64 (const gchar *name,
const gchar *nick,
const gchar *blurb,
gint64 minimum,
gint64 maximum,
gint64 default_value,
GParamFlags flags)
{
GParamSpecInt64 *lspec;
g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
lspec = g_param_spec_internal (G_TYPE_PARAM_INT64,
name,
nick,
blurb,
flags);
lspec->minimum = minimum;
lspec->maximum = maximum;
lspec->default_value = default_value;
return G_PARAM_SPEC (lspec);
}
/**
* g_param_spec_uint64:
* @name: canonical name of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @minimum: minimum value for the property specified
* @maximum: maximum value for the property specified
* @default_value: default value for the property specified
* @flags: flags for the property specified
*
* Creates a new #GParamSpecUInt64 instance specifying a %G_TYPE_UINT64
* property.
*
* See g_param_spec_internal() for details on property names.
*
* Returns: (transfer full): a newly created parameter specification
*/
GParamSpec*
g_param_spec_uint64 (const gchar *name,
const gchar *nick,
const gchar *blurb,
guint64 minimum,
guint64 maximum,
guint64 default_value,
GParamFlags flags)
{
GParamSpecUInt64 *uspec;
g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
uspec = g_param_spec_internal (G_TYPE_PARAM_UINT64,
name,
nick,
blurb,
flags);
uspec->minimum = minimum;
uspec->maximum = maximum;
uspec->default_value = default_value;
return G_PARAM_SPEC (uspec);
}
/**
* g_param_spec_unichar:
* @name: canonical name of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @default_value: default value for the property specified
* @flags: flags for the property specified
*
* Creates a new #GParamSpecUnichar instance specifying a %G_TYPE_UINT
* property. #GValue structures for this property can be accessed with
* g_value_set_uint() and g_value_get_uint().
*
* See g_param_spec_internal() for details on property names.
*
* Returns: (transfer full): a newly created parameter specification
*/
GParamSpec*
g_param_spec_unichar (const gchar *name,
const gchar *nick,
const gchar *blurb,
gunichar default_value,
GParamFlags flags)
{
GParamSpecUnichar *uspec;
uspec = g_param_spec_internal (G_TYPE_PARAM_UNICHAR,
name,
nick,
blurb,
flags);
uspec->default_value = default_value;
return G_PARAM_SPEC (uspec);
}
/**
* g_param_spec_enum:
* @name: canonical name of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @enum_type: a #GType derived from %G_TYPE_ENUM
* @default_value: default value for the property specified
* @flags: flags for the property specified
*
* Creates a new #GParamSpecEnum instance specifying a %G_TYPE_ENUM
* property.
*
* See g_param_spec_internal() for details on property names.
*
* Returns: (transfer full): a newly created parameter specification
*/
GParamSpec*
g_param_spec_enum (const gchar *name,
const gchar *nick,
const gchar *blurb,
GType enum_type,
gint default_value,
GParamFlags flags)
{
GParamSpecEnum *espec;
GEnumClass *enum_class;
g_return_val_if_fail (G_TYPE_IS_ENUM (enum_type), NULL);
enum_class = g_type_class_ref (enum_type);
g_return_val_if_fail (g_enum_get_value (enum_class, default_value) != NULL, NULL);
espec = g_param_spec_internal (G_TYPE_PARAM_ENUM,
name,
nick,
blurb,
flags);
espec->enum_class = enum_class;
espec->default_value = default_value;
G_PARAM_SPEC (espec)->value_type = enum_type;
return G_PARAM_SPEC (espec);
}
/**
* g_param_spec_flags:
* @name: canonical name of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @flags_type: a #GType derived from %G_TYPE_FLAGS
* @default_value: default value for the property specified
* @flags: flags for the property specified
*
* Creates a new #GParamSpecFlags instance specifying a %G_TYPE_FLAGS
* property.
*
* See g_param_spec_internal() for details on property names.
*
* Returns: (transfer full): a newly created parameter specification
*/
GParamSpec*
g_param_spec_flags (const gchar *name,
const gchar *nick,
const gchar *blurb,
GType flags_type,
guint default_value,
GParamFlags flags)
{
GParamSpecFlags *fspec;
GFlagsClass *flags_class;
g_return_val_if_fail (G_TYPE_IS_FLAGS (flags_type), NULL);
flags_class = g_type_class_ref (flags_type);
g_return_val_if_fail ((default_value & flags_class->mask) == default_value, NULL);
fspec = g_param_spec_internal (G_TYPE_PARAM_FLAGS,
name,
nick,
blurb,
flags);
fspec->flags_class = flags_class;
fspec->default_value = default_value;
G_PARAM_SPEC (fspec)->value_type = flags_type;
return G_PARAM_SPEC (fspec);
}
/**
* g_param_spec_float:
* @name: canonical name of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @minimum: minimum value for the property specified
* @maximum: maximum value for the property specified
* @default_value: default value for the property specified
* @flags: flags for the property specified
*
* Creates a new #GParamSpecFloat instance specifying a %G_TYPE_FLOAT property.
*
* See g_param_spec_internal() for details on property names.
*
* Returns: (transfer full): a newly created parameter specification
*/
GParamSpec*
g_param_spec_float (const gchar *name,
const gchar *nick,
const gchar *blurb,
gfloat minimum,
gfloat maximum,
gfloat default_value,
GParamFlags flags)
{
GParamSpecFloat *fspec;
g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
fspec = g_param_spec_internal (G_TYPE_PARAM_FLOAT,
name,
nick,
blurb,
flags);
fspec->minimum = minimum;
fspec->maximum = maximum;
fspec->default_value = default_value;
return G_PARAM_SPEC (fspec);
}
/**
* g_param_spec_double:
* @name: canonical name of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @minimum: minimum value for the property specified
* @maximum: maximum value for the property specified
* @default_value: default value for the property specified
* @flags: flags for the property specified
*
* Creates a new #GParamSpecDouble instance specifying a %G_TYPE_DOUBLE
* property.
*
* See g_param_spec_internal() for details on property names.
*
* Returns: (transfer full): a newly created parameter specification
*/
GParamSpec*
g_param_spec_double (const gchar *name,
const gchar *nick,
const gchar *blurb,
gdouble minimum,
gdouble maximum,
gdouble default_value,
GParamFlags flags)
{
GParamSpecDouble *dspec;
g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
dspec = g_param_spec_internal (G_TYPE_PARAM_DOUBLE,
name,
nick,
blurb,
flags);
dspec->minimum = minimum;
dspec->maximum = maximum;
dspec->default_value = default_value;
return G_PARAM_SPEC (dspec);
}
/**
* g_param_spec_string:
* @name: canonical name of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @default_value: (nullable): default value for the property specified
* @flags: flags for the property specified
*
* Creates a new #GParamSpecString instance.
*
* See g_param_spec_internal() for details on property names.
*
* Returns: (transfer full): a newly created parameter specification
*/
GParamSpec*
g_param_spec_string (const gchar *name,
const gchar *nick,
const gchar *blurb,
const gchar *default_value,
GParamFlags flags)
{
GParamSpecString *sspec = g_param_spec_internal (G_TYPE_PARAM_STRING,
name,
nick,
blurb,
flags);
g_free (sspec->default_value);
sspec->default_value = g_strdup (default_value);
return G_PARAM_SPEC (sspec);
}
/**
* g_param_spec_param:
* @name: canonical name of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @param_type: a #GType derived from %G_TYPE_PARAM
* @flags: flags for the property specified
*
* Creates a new #GParamSpecParam instance specifying a %G_TYPE_PARAM
* property.
*
* See g_param_spec_internal() for details on property names.
*
* Returns: (transfer full): a newly created parameter specification
*/
GParamSpec*
g_param_spec_param (const gchar *name,
const gchar *nick,
const gchar *blurb,
GType param_type,
GParamFlags flags)
{
GParamSpecParam *pspec;
g_return_val_if_fail (G_TYPE_IS_PARAM (param_type), NULL);
pspec = g_param_spec_internal (G_TYPE_PARAM_PARAM,
name,
nick,
blurb,
flags);
G_PARAM_SPEC (pspec)->value_type = param_type;
return G_PARAM_SPEC (pspec);
}
/**
* g_param_spec_boxed:
* @name: canonical name of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @boxed_type: %G_TYPE_BOXED derived type of this property
* @flags: flags for the property specified
*
* Creates a new #GParamSpecBoxed instance specifying a %G_TYPE_BOXED
* derived property.
*
* See g_param_spec_internal() for details on property names.
*
* Returns: (transfer full): a newly created parameter specification
*/
GParamSpec*
g_param_spec_boxed (const gchar *name,
const gchar *nick,
const gchar *blurb,
GType boxed_type,
GParamFlags flags)
{
GParamSpecBoxed *bspec;
g_return_val_if_fail (G_TYPE_IS_BOXED (boxed_type), NULL);
g_return_val_if_fail (G_TYPE_IS_VALUE_TYPE (boxed_type), NULL);
bspec = g_param_spec_internal (G_TYPE_PARAM_BOXED,
name,
nick,
blurb,
flags);
G_PARAM_SPEC (bspec)->value_type = boxed_type;
return G_PARAM_SPEC (bspec);
}
/**
* g_param_spec_pointer:
* @name: canonical name of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @flags: flags for the property specified
*
* Creates a new #GParamSpecPointer instance specifying a pointer property.
* Where possible, it is better to use g_param_spec_object() or
* g_param_spec_boxed() to expose memory management information.
*
* See g_param_spec_internal() for details on property names.
*
* Returns: (transfer full): a newly created parameter specification
*/
GParamSpec*
g_param_spec_pointer (const gchar *name,
const gchar *nick,
const gchar *blurb,
GParamFlags flags)
{
GParamSpecPointer *pspec;
pspec = g_param_spec_internal (G_TYPE_PARAM_POINTER,
name,
nick,
blurb,
flags);
return G_PARAM_SPEC (pspec);
}
/**
* g_param_spec_gtype:
* @name: canonical name of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @is_a_type: a #GType whose subtypes are allowed as values
* of the property (use %G_TYPE_NONE for any type)
* @flags: flags for the property specified
*
* Creates a new #GParamSpecGType instance specifying a
* %G_TYPE_GTYPE property.
*
* See g_param_spec_internal() for details on property names.
*
* Since: 2.10
*
* Returns: (transfer full): a newly created parameter specification
*/
GParamSpec*
g_param_spec_gtype (const gchar *name,
const gchar *nick,
const gchar *blurb,
GType is_a_type,
GParamFlags flags)
{
GParamSpecGType *tspec;
tspec = g_param_spec_internal (G_TYPE_PARAM_GTYPE,
name,
nick,
blurb,
flags);
tspec->is_a_type = is_a_type;
return G_PARAM_SPEC (tspec);
}
/**
* g_param_spec_value_array: (skip)
* @name: canonical name of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @element_spec: a #GParamSpec describing the elements contained in
* arrays of this property, may be %NULL
* @flags: flags for the property specified
*
* Creates a new #GParamSpecValueArray instance specifying a
* %G_TYPE_VALUE_ARRAY property. %G_TYPE_VALUE_ARRAY is a
* %G_TYPE_BOXED type, as such, #GValue structures for this property
* can be accessed with g_value_set_boxed() and g_value_get_boxed().
*
* See g_param_spec_internal() for details on property names.
*
* Returns: a newly created parameter specification
*/
GParamSpec*
g_param_spec_value_array (const gchar *name,
const gchar *nick,
const gchar *blurb,
GParamSpec *element_spec,
GParamFlags flags)
{
GParamSpecValueArray *aspec;
g_return_val_if_fail (element_spec == NULL || G_IS_PARAM_SPEC (element_spec), NULL);
aspec = g_param_spec_internal (G_TYPE_PARAM_VALUE_ARRAY,
name,
nick,
blurb,
flags);
if (element_spec)
{
aspec->element_spec = g_param_spec_ref (element_spec);
g_param_spec_sink (element_spec);
}
return G_PARAM_SPEC (aspec);
}
/**
* g_param_spec_object:
* @name: canonical name of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @object_type: %G_TYPE_OBJECT derived type of this property
* @flags: flags for the property specified
*
* Creates a new #GParamSpecBoxed instance specifying a %G_TYPE_OBJECT
* derived property.
*
* See g_param_spec_internal() for details on property names.
*
* Returns: (transfer full): a newly created parameter specification
*/
GParamSpec*
g_param_spec_object (const gchar *name,
const gchar *nick,
const gchar *blurb,
GType object_type,
GParamFlags flags)
{
GParamSpecObject *ospec;
g_return_val_if_fail (g_type_is_a (object_type, G_TYPE_OBJECT), NULL);
ospec = g_param_spec_internal (G_TYPE_PARAM_OBJECT,
name,
nick,
blurb,
flags);
G_PARAM_SPEC (ospec)->value_type = object_type;
return G_PARAM_SPEC (ospec);
}
/**
* g_param_spec_override: (skip)
* @name: the name of the property.
* @overridden: The property that is being overridden
*
* Creates a new property of type #GParamSpecOverride. This is used
* to direct operations to another paramspec, and will not be directly
* useful unless you are implementing a new base type similar to GObject.
*
* Since: 2.4
*
* Returns: the newly created #GParamSpec
*/
GParamSpec*
g_param_spec_override (const gchar *name,
GParamSpec *overridden)
{
GParamSpec *pspec;
g_return_val_if_fail (name != NULL, NULL);
g_return_val_if_fail (G_IS_PARAM_SPEC (overridden), NULL);
/* Dereference further redirections for property that was passed in
*/
while (TRUE)
{
GParamSpec *indirect = g_param_spec_get_redirect_target (overridden);
if (indirect)
overridden = indirect;
else
break;
}
pspec = g_param_spec_internal (G_TYPE_PARAM_OVERRIDE,
name, NULL, NULL,
overridden->flags);
pspec->value_type = G_PARAM_SPEC_VALUE_TYPE (overridden);
G_PARAM_SPEC_OVERRIDE (pspec)->overridden = g_param_spec_ref (overridden);
return pspec;
}
/**
* g_param_spec_variant:
* @name: canonical name of the property specified
* @nick: (nullable): nick name for the property specified
* @blurb: (nullable): description of the property specified
* @type: a #GVariantType
* @default_value: (nullable) (transfer full): a #GVariant of type @type to
* use as the default value, or %NULL
* @flags: flags for the property specified
*
* Creates a new #GParamSpecVariant instance specifying a #GVariant
* property.
*
* If @default_value is floating, it is consumed.
*
* See g_param_spec_internal() for details on property names.
*
* Returns: (transfer full): the newly created #GParamSpec
*
* Since: 2.26
*/
GParamSpec*
g_param_spec_variant (const gchar *name,
const gchar *nick,
const gchar *blurb,
const GVariantType *type,
GVariant *default_value,
GParamFlags flags)
{
GParamSpecVariant *vspec;
g_return_val_if_fail (type != NULL, NULL);
g_return_val_if_fail (default_value == NULL ||
g_variant_is_of_type (default_value, type), NULL);
vspec = g_param_spec_internal (G_TYPE_PARAM_VARIANT,
name,
nick,
blurb,
flags);
vspec->type = g_variant_type_copy (type);
if (default_value)
vspec->default_value = g_variant_ref_sink (default_value);
return G_PARAM_SPEC (vspec);
}