+<!-- ##### SECTION ./tmpl/closures.sgml:Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/closures.sgml:See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/closures.sgml:Short_Description ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/closures.sgml:Title ##### -->
+Closures
+
+
+<!-- ##### SECTION ./tmpl/enumerations_flags.sgml:Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/enumerations_flags.sgml:See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/enumerations_flags.sgml:Short_Description ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/enumerations_flags.sgml:Title ##### -->
+Enumeration and Flag Types
+
+
+<!-- ##### SECTION ./tmpl/gboxed.sgml:Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/gboxed.sgml:See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/gboxed.sgml:Short_Description ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/gboxed.sgml:Title ##### -->
+gboxed
+
+
+<!-- ##### SECTION ./tmpl/generic_values.sgml:Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/generic_values.sgml:See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/generic_values.sgml:Short_Description ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/generic_values.sgml:Title ##### -->
+Generic values
+
+
<!-- ##### SECTION ./tmpl/gtypemodule.sgml.sgml:Long_Description ##### -->
<para>
gtypemodule.sgml
+<!-- ##### SECTION ./tmpl/gtypemodule.sgml:Long_Description ##### -->
+<para>
+#GTypeModule provides a simple implementation of the #GTypePlugin
+interface. The model of #GTypeModule is a dynamically loaded module
+which implements some number of types and interface
+implementations. When the module is loaded, it registerse its types
+and interfaces using g_type_module_register_type() and
+g_type_module_add_interface(). As long as any instances of these
+types and interface implementations are in use, the module is kept
+loaded. When the types and interfaces are gone, the module may be
+unloaded. If the types and interfaces become used again, the module
+will be reloaded.
+</para>
+<para>
+Keeping track of whether the module should be loaded or not is done by
+using a use count - it starts at zero, and whenever it is greater than
+zero, the module is loaded. The use count is maintained internally by
+the type system, but also can be explicitely controlled by
+g_type_module_use() and g_type_module_unuse(). Typically, when loading
+a module for the first type, g_type_module_use() will be used to load
+it so that it can initialize its types. At some later point, when the
+module no longer needs to be loaded except for the type
+implementations it contains, g_type_module_unuse() is called.
+</para>
+<para>
+#GTypeModule does not actually provide any implementation of module
+loading and unloading. To create a particular module type you must
+derive from #GTypeModule and implement the load and unload functions
+in #GTypeModuleClass.
+</para>
+
+
+<!-- ##### SECTION ./tmpl/gtypemodule.sgml:See_Also ##### -->
+<para>
+<variablelist>
+
+<varlistentry>
+<term>#GTypePlugin</term>
+<listitem><para>The abstract type loader interface.</para></listitem>
+</varlistentry>
+
+<varlistentry>
+<term>#GModule</term>
+<listitem><para>Portable mechanism for dynamically loaded modules.</para></listitem>
+</varlistentry>
+
+</variablelist>
+</para>
+
+
+<!-- ##### SECTION ./tmpl/gtypemodule.sgml:Short_Description ##### -->
+Type Loading Modules
+
+
+<!-- ##### SECTION ./tmpl/gtypemodule.sgml:Title ##### -->
+GTypeModule
+
+
+<!-- ##### SECTION ./tmpl/gtypeplugin.sgml:Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/gtypeplugin.sgml:See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/gtypeplugin.sgml:Short_Description ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/gtypeplugin.sgml:Title ##### -->
+GTypePlugin
+
+
+<!-- ##### SECTION ./tmpl/objects.sgml:Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/objects.sgml:See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/objects.sgml:Short_Description ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/objects.sgml:Title ##### -->
+The Base Object Type
+
+
+<!-- ##### SECTION ./tmpl/param_specs.sgml:Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/param_specs.sgml:See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/param_specs.sgml:Short_Description ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/param_specs.sgml:Title ##### -->
+Parameter Specifications
+
+
+<!-- ##### SECTION ./tmpl/signals.sgml:Long_Description ##### -->
+<para>
+The basic concept of the signal system is that of the <emphasis>emission</emphasis>
+of a signal.
+Signals are introduced per-type and are identified through strings.
+Signals introduced for a parent type are availale in derived types as well,
+so basically they are a per-type facility that is inherited.
+A signal emission mainly involves invocation of a certain set of callbacks in
+precisely defined manner. There are two main categories of such callbacks,
+per-object
+ <footnote><para> Although signals can deal with any kind of type, i'm
+ referring to those types as "object types" in the following, simply
+ because that is the context most users will encounter signals in.
+ </para></footnote>
+ones and user provided ones.
+The per-object callbacks are most often referred to as "object method
+handler" or "default (signal) handler", while user provided callbacks are
+usually just called "signal handler".
+The object method handler is provided at signal creation time (this most
+frequently happens at the end of an object class' creation), while user
+provided handlers are frequently connected and disconnected to/from a certain
+signal on certain object instances.
+</para>
+<para>
+A signal emission consists of five stages, unless prematurely stopped:
+<variablelist>
+ <varlistentry><term></term><listitem><para>
+ 1 - Invocation of the object method handler for %G_SIGNAL_RUN_FIRST signals
+ </para></listitem></varlistentry>
+ <varlistentry><term></term><listitem><para>
+ 2 - Invocation of normal user-provided signal handlers (<emphasis>after</emphasis> flag %FALSE)
+ </para></listitem></varlistentry>
+ <varlistentry><term></term><listitem><para>
+ 3 - Invocation of the object method handler for %G_SIGNAL_RUN_LAST signals
+ </para></listitem></varlistentry>
+ <varlistentry><term></term><listitem><para>
+ 4 - Invocation of user provided signal handlers, connected with an <emphasis>after</emphasis> flag of %TRUE
+ </para></listitem></varlistentry>
+ <varlistentry><term></term><listitem><para>
+ 5 - Invocation of the object method handler for %G_SIGNAL_RUN_CLEANUP signals
+ </para></listitem></varlistentry>
+</variablelist>
+The user provided signal handlers are called in the order they were
+connected in.
+All handlers may prematurely stop a signal emission, and any number of
+handlers may be connected, disconnected, blocked or unblocked during
+a signal emission.
+There are certain criteria for skipping user handlers in stages 2 and 4
+of a signal emission.
+First, user handlers may be <emphasis>blocked</emphasis>, blocked handlers are omitted
+during callback invocation, to return from the "blocked" state, a
+handler has to get unblocked exactly the same amount of times
+it has been blocked before.
+Second, upon emission of a %G_SIGNAL_DETAILED signal, an additional
+"detail" argument passed in to g_signal_emit() has to match the detail
+argument of the signal handler currently subject to invocation.
+Specification of no detail argument for signal handlers (omission of the
+detail part of the signal specification upon connection) serves as a
+wildcard and matches any detail argument passed in to emission.
+</para>
+
+
+<!-- ##### SECTION ./tmpl/signals.sgml:See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/signals.sgml:Short_Description ##### -->
+Signals provide a means for customization of object behaviour and are used
+as general purpose notification mechanism.
+
+
+<!-- ##### SECTION ./tmpl/signals.sgml:Title ##### -->
+Signals
+
+
+<!-- ##### SECTION ./tmpl/standard_params.sgml:Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/standard_params.sgml:See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/standard_params.sgml:Short_Description ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/standard_params.sgml:Title ##### -->
+Standard Parameter Types
+
+
+<!-- ##### SECTION ./tmpl/value_collection.sgml:Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/value_collection.sgml:See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/value_collection.sgml:Short_Description ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/value_collection.sgml:Title ##### -->
+Varargs Value Collection
+
+
+<!-- ##### SECTION ./tmpl/value_types.sgml:Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/value_types.sgml:See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/value_types.sgml:Short_Description ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/value_types.sgml:Title ##### -->
+Standard value types
+
+
<!-- ##### USER_FUNCTION GObjectGetParamFunc ##### -->
<para>
@value_free:
@value_copy:
@value_peek_pointer:
-@collect_type:
+@collect_format:
@collect_value:
-@lcopy_type:
+@lcopy_format:
@lcopy_value:
<!-- ##### MACRO G_TYPE_FROM_INSTANCE ##### -->
+Sat Feb 17 04:55:35 2001 Tim Janik <timj@gtk.org>
+
+ * gtype.[hc]: changed collect_format, collect_value() and lcopy_format,
+ lcopy_value() in the GTypeValueTable. the collect functions are now
+ called only once per value, collect_format/lcopy_format are strings
+ that enlist all necessary GTypeCValues to be varargs-collected.
+
+ * gvalue.h: ranamed STATIC_TAG to G_VALUE_NOCOPY_CONTENTS to indicate that
+ a value shouldn't copy its contents.
+
+ * gvaluecollector.h: changed G_VALUE_COLLECT() and G_VALUE_LCOPY()
+ macros to carry an additional argument (flags) that can be used
+ to pass G_VALUE_NOCOPY_CONTENTS along to the collection functions.
+
+ * *.c: adapted collect_value() and lcopy_value() functions to the new
+ prototypes, support G_VALUE_NOCOPY_CONTENTS where apropriate.
+
+ * gsignal.[hc]: introduced a G_SIGNAL_TYPE_STATIC_SCOPE flag that can
+ be passed along (ORed) with the parameter types, indicating that the
+ emission arguments are to be considered static for the scope of the
+ emission. should be used with care and only if the caller knows that
+ a parameter cannot be destroyed/freed from signal handlers connected
+ to an emission.
+
Fri Feb 16 07:10:44 2001 Tim Janik <timj@gtk.org>
* gclosure.c:
static void
boxed_proxy_value_free (GValue *value)
{
- if (value->data[0].v_pointer && !(value->data[1].v_uint & G_VALUE_STATIC_TAG))
+ if (value->data[0].v_pointer && !(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS))
{
BoxedNode key, *node;
static gchar*
boxed_proxy_collect_value (GValue *value,
- guint nth_value,
- GType *collect_type,
- GTypeCValue *collect_value)
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags)
{
- BoxedNode key, *node;
-
- key.type = value->g_type;
- node = g_bsearch_array_lookup (&boxed_bsa, &key);
- value->data[0].v_pointer = collect_value->v_pointer ? node->copy (collect_value->v_pointer) : NULL;
+ if (!collect_values[0].v_pointer)
+ value->data[0].v_pointer = NULL;
+ else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
+ {
+ value->data[0].v_pointer = collect_values[0].v_pointer;
+ value->data[1].v_uint = G_VALUE_NOCOPY_CONTENTS;
+ }
+ else
+ {
+ BoxedNode key, *node;
+
+ key.type = value->g_type;
+ node = g_bsearch_array_lookup (&boxed_bsa, &key);
+ value->data[0].v_pointer = node->copy (collect_values[0].v_pointer);
+ }
- *collect_type = 0;
return NULL;
}
static gchar*
boxed_proxy_lcopy_value (const GValue *value,
- guint nth_value,
- GType *collect_type,
- GTypeCValue *collect_value)
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags)
{
- BoxedNode key, *node;
- gpointer *boxed_p = collect_value->v_pointer;
+ gpointer *boxed_p = collect_values[0].v_pointer;
if (!boxed_p)
return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
- key.type = value->g_type;
- node = g_bsearch_array_lookup (&boxed_bsa, &key);
- *boxed_p = value->data[0].v_pointer ? node->copy (value->data[0].v_pointer) : NULL;
+ if (!value->data[0].v_pointer)
+ *boxed_p = NULL;
+ else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
+ *boxed_p = value->data[0].v_pointer;
+ else
+ {
+ BoxedNode key, *node;
+
+ key.type = value->g_type;
+ node = g_bsearch_array_lookup (&boxed_bsa, &key);
+ *boxed_p = node->copy (value->data[0].v_pointer);
+ }
- *collect_type = 0;
return NULL;
}
boxed_proxy_value_free,
boxed_proxy_value_copy,
boxed_proxy_value_peek_pointer,
- G_VALUE_COLLECT_POINTER,
+ "p",
boxed_proxy_collect_value,
- G_VALUE_COLLECT_POINTER,
+ "p",
boxed_proxy_lcopy_value,
};
static const GTypeInfo type_info = {
g_return_if_fail (G_IS_VALUE_BOXED (value));
g_return_if_fail (G_TYPE_IS_VALUE (G_VALUE_TYPE (value)));
- if (value->data[0].v_pointer && !(value->data[1].v_uint & G_VALUE_STATIC_TAG))
+ if (value->data[0].v_pointer && !(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS))
g_boxed_free (G_VALUE_TYPE (value), value->data[0].v_pointer);
value->data[0].v_pointer = boxed ? g_boxed_copy (G_VALUE_TYPE (value), boxed) : NULL;
value->data[1].v_uint = 0;
g_return_if_fail (G_IS_VALUE_BOXED (value));
g_return_if_fail (G_TYPE_IS_VALUE (G_VALUE_TYPE (value)));
- if (value->data[0].v_pointer && !(value->data[1].v_uint & G_VALUE_STATIC_TAG))
+ if (value->data[0].v_pointer && !(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS))
g_boxed_free (G_VALUE_TYPE (value), value->data[0].v_pointer);
value->data[0].v_pointer = (gpointer) boxed;
- value->data[1].v_uint = boxed ? G_VALUE_STATIC_TAG : 0;
+ value->data[1].v_uint = boxed ? G_VALUE_NOCOPY_CONTENTS : 0;
}
gpointer
static void value_flags_enum_init (GValue *value);
static void value_flags_enum_copy_value (const GValue *src_value,
GValue *dest_value);
-static gchar* value_flags_enum_collect_value (GValue *value,
- guint nth_value,
- GType *collect_type,
- GTypeCValue *collect_value);
+static gchar* value_flags_enum_collect_value (GValue *value,
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags);
static gchar* value_flags_enum_lcopy_value (const GValue *value,
- guint nth_value,
- GType *collect_type,
- GTypeCValue *collect_value);
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags);
/* --- functions --- */
{
static gboolean initialized = FALSE;
static const GTypeValueTable flags_enum_value_table = {
- value_flags_enum_init, /* value_init */
- NULL, /* value_free */
+ value_flags_enum_init, /* value_init */
+ NULL, /* value_free */
value_flags_enum_copy_value, /* value_copy */
- NULL, /* value_peek_pointer */
- G_VALUE_COLLECT_INT, /* collect_type */
+ NULL, /* value_peek_pointer */
+ "i", /* collect_format */
value_flags_enum_collect_value, /* collect_value */
- G_VALUE_COLLECT_POINTER, /* lcopy_type */
+ "p", /* lcopy_format */
value_flags_enum_lcopy_value, /* lcopy_value */
};
static GTypeInfo info = {
static gchar*
value_flags_enum_collect_value (GValue *value,
- guint nth_value,
- GType *collect_type,
- GTypeCValue *collect_value)
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags)
{
- value->data[0].v_long = collect_value->v_int;
-
- *collect_type = 0;
+ value->data[0].v_long = collect_values[0].v_int;
+
return NULL;
}
static gchar*
value_flags_enum_lcopy_value (const GValue *value,
- guint nth_value,
- GType *collect_type,
- GTypeCValue *collect_value)
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags)
{
- gint *int_p = collect_value->v_pointer;
+ gint *int_p = collect_values[0].v_pointer;
if (!int_p)
return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
*int_p = value->data[0].v_long;
- *collect_type = 0;
return NULL;
}
GValue *dest_value);
static gpointer g_value_object_peek_pointer (const GValue *value);
static gchar* g_value_object_collect_value (GValue *value,
- guint nth_value,
- GType *collect_type,
- GTypeCValue *collect_value);
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags);
static gchar* g_value_object_lcopy_value (const GValue *value,
- guint nth_value,
- GType *collect_type,
- GTypeCValue *collect_value);
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags);
static void g_object_dispatch_properties_changed (GObject *object,
guint n_pspecs,
GParamSpec **pspecs);
g_value_object_free_value, /* value_free */
g_value_object_copy_value, /* value_copy */
g_value_object_peek_pointer, /* value_peek_pointer */
- G_VALUE_COLLECT_POINTER, /* collect_type */
+ "p", /* collect_format */
g_value_object_collect_value, /* collect_value */
- G_VALUE_COLLECT_POINTER, /* lcopy_type */
+ "p", /* lcopy_format */
g_value_object_lcopy_value, /* lcopy_value */
};
GType type;
value = g_new (GValue, 1);
value->g_type = 0;
g_value_init (value, G_PARAM_SPEC_VALUE_TYPE (pspec));
- G_VALUE_COLLECT (value, var_args, &error);
+ G_VALUE_COLLECT (value, var_args, 0, &error);
if (error)
{
g_warning ("%s: %s", G_STRLOC, error);
g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
- G_VALUE_COLLECT (&value, var_args, &error);
+ G_VALUE_COLLECT (&value, var_args, 0, &error);
if (error)
{
g_warning ("%s: %s", G_STRLOC, error);
object_get_property (object, &value, pspec, trailer);
- G_VALUE_LCOPY (&value, var_args, &error);
+ G_VALUE_LCOPY (&value, var_args, 0, &error);
if (error)
{
g_warning ("%s: %s", G_STRLOC, error);
static gchar*
g_value_object_collect_value (GValue *value,
- guint nth_value,
- GType *collect_type,
- GTypeCValue *collect_value)
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags)
{
- if (collect_value->v_pointer)
+ if (collect_values[0].v_pointer)
{
- GObject *object = collect_value->v_pointer;
+ GObject *object = collect_values[0].v_pointer;
if (object->g_type_instance.g_class == NULL)
return g_strconcat ("invalid unclassed object pointer for value type `",
else
value->data[0].v_pointer = NULL;
- *collect_type = 0;
return NULL;
}
static gchar*
g_value_object_lcopy_value (const GValue *value,
- guint nth_value,
- GType *collect_type,
- GTypeCValue *collect_value)
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags)
{
- GObject **object_p = collect_value->v_pointer;
+ GObject **object_p = collect_values[0].v_pointer;
if (!object_p)
return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
+
+ if (!value->data[0].v_pointer)
+ *object_p = NULL;
+ else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
+ *object_p = value->data[0].v_pointer;
+ else
+ *object_p = g_object_ref (value->data[0].v_pointer);
- *object_p = value->data[0].v_pointer ? g_object_ref (value->data[0].v_pointer) : NULL;
-
- *collect_type = 0;
return NULL;
}
GValue *dest_value);
static gpointer value_param_peek_pointer (const GValue *value);
static gchar* value_param_collect_value (GValue *value,
- guint nth_value,
- GType *collect_type,
- GTypeCValue *collect_value);
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags);
static gchar* value_param_lcopy_value (const GValue *value,
- guint nth_value,
- GType *collect_type,
- GTypeCValue *collect_value);
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags);
/* --- variables --- */
value_param_free_value, /* value_free */
value_param_copy_value, /* value_copy */
value_param_peek_pointer, /* value_peek_pointer */
- G_VALUE_COLLECT_POINTER, /* collect_type */
+ "p", /* collect_format */
value_param_collect_value, /* collect_value */
- G_VALUE_COLLECT_POINTER, /* lcopy_type */
+ "p", /* lcopy_format */
value_param_lcopy_value, /* lcopy_value */
};
static const GTypeInfo param_spec_info = {
static gchar*
value_param_collect_value (GValue *value,
- guint nth_value,
- GType *collect_type,
- GTypeCValue *collect_value)
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags)
{
- if (collect_value->v_pointer)
+ if (collect_values[0].v_pointer)
{
- GParamSpec *param = collect_value->v_pointer;
+ GParamSpec *param = collect_values[0].v_pointer;
if (param->g_type_instance.g_class == NULL)
return g_strconcat ("invalid unclassed param spec pointer for value type `",
else
value->data[0].v_pointer = NULL;
- *collect_type = 0;
return NULL;
}
static gchar*
value_param_lcopy_value (const GValue *value,
- guint nth_value,
- GType *collect_type,
- GTypeCValue *collect_value)
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags)
{
- GParamSpec **param_p = collect_value->v_pointer;
+ GParamSpec **param_p = collect_values[0].v_pointer;
if (!param_p)
return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
- *param_p = value->data[0].v_pointer ? g_param_spec_ref (value->data[0].v_pointer) : NULL;
+ if (!value->data[0].v_pointer)
+ *param_p = NULL;
+ else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
+ *param_p = value->data[0].v_pointer;
+ else
+ *param_p = g_param_spec_ref (value->data[0].v_pointer);
- *collect_type = 0;
return NULL;
}
/* reinitializable portion */
guint flags : 8;
guint n_params : 8;
- GType *param_types;
- GType return_type;
+ GType *param_types; /* mangled with G_SIGNAL_TYPE_STATIC_SCOPE flag */
+ GType return_type; /* mangled with G_SIGNAL_TYPE_STATIC_SCOPE flag */
GClosure *class_closure;
GSignalAccumulator accumulator;
GSignalCMarshaller c_marshaller;
va_start (args, n_params);
signal_id = g_signal_new_valist (signal_name, itype, signal_flags,
- g_signal_type_cclosure_new (itype,
- class_offset),
+ g_signal_type_cclosure_new (itype, class_offset),
accumulator, c_marshaller,
return_type, n_params, args);
return 0;
}
for (i = 0; i < n_params; i++)
- if (!G_TYPE_IS_VALUE (param_types[i]) ||
- param_types[i] == G_TYPE_ENUM || param_types[i] == G_TYPE_FLAGS) /* FIXME: kludge */
+ if (!G_TYPE_IS_VALUE (param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE) ||
+ (param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE) == G_TYPE_ENUM ||
+ (param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE) == G_TYPE_FLAGS) /* FIXME: kludge */
{
g_warning (G_STRLOC ": parameter %d of type `%s' for signal \"%s::%s\" is not a value type",
- i + 1, g_type_name (param_types[i]), g_type_name (itype), name);
+ i + 1, g_type_name (param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE), g_type_name (itype), name);
g_free (name);
G_UNLOCK (g_signal_mutex);
return 0;
}
- if (return_type != G_TYPE_NONE && !G_TYPE_IS_VALUE (return_type))
+ if (return_type != G_TYPE_NONE && !G_TYPE_IS_VALUE (return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE))
{
g_warning (G_STRLOC ": return value of type `%s' for signal \"%s::%s\" is not a value type",
- g_type_name (param_types[i]), g_type_name (itype), name);
+ g_type_name (return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE), g_type_name (itype), name);
g_free (name);
G_UNLOCK (g_signal_mutex);
return 0;
return;
}
for (i = 0; i < node->n_params; i++)
- if (!G_VALUE_HOLDS (param_values + i, node->param_types[i]))
+ if (!G_VALUE_HOLDS (param_values + i, node->param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE))
{
g_critical ("%s: value for `%s' parameter %u for signal \"%s\" is of type `%s'",
G_STRLOC,
- g_type_name (node->param_types[i]),
+ g_type_name (node->param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE),
i,
node->name,
G_VALUE_TYPE_NAME (param_values + i));
{
g_critical ("%s: return value `%s' for signal \"%s\" is (NULL)",
G_STRLOC,
- g_type_name (node->return_type),
+ g_type_name (node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE),
node->name);
G_UNLOCK (g_signal_mutex);
return;
}
- else if (!node->accumulator && !G_VALUE_HOLDS (return_value, node->return_type))
+ else if (!node->accumulator && !G_VALUE_HOLDS (return_value, node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE))
{
g_critical ("%s: return value `%s' for signal \"%s\" is of type `%s'",
G_STRLOC,
- g_type_name (node->return_type),
+ g_type_name (node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE),
node->name,
G_VALUE_TYPE_NAME (return_value));
G_UNLOCK (g_signal_mutex);
gchar *error;
param_values[i].g_type = 0;
- g_value_init (param_values + i, node->param_types[i]);
- G_VALUE_COLLECT (param_values + i, var_args, &error);
+ g_value_init (param_values + i, node->param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE);
+ G_VALUE_COLLECT (param_values + i,
+ var_args,
+ node->param_types[i] & G_SIGNAL_TYPE_STATIC_SCOPE ? G_VALUE_NOCOPY_CONTENTS : 0,
+ &error);
if (error)
{
g_warning ("%s: %s", G_STRLOC, error);
GValue return_value = { 0, };
gchar *error = NULL;
- g_value_init (&return_value, node->return_type);
+ g_value_init (&return_value, node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
if (signal_emit_R (node, detail, instance, &return_value, instance_and_params))
- G_VALUE_LCOPY (&return_value, var_args, &error);
+ G_VALUE_LCOPY (&return_value,
+ var_args,
+ node->return_type & G_SIGNAL_TYPE_STATIC_SCOPE ? G_VALUE_NOCOPY_CONTENTS : 0,
+ &error);
if (!error)
g_value_unset (&return_value);
else
ihint.detail = detail;
accumulator = node->accumulator;
if (accumulator)
- g_value_init (&accu, node->return_type);
+ g_value_init (&accu, node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
emission_push ((node->flags & G_SIGNAL_NO_RECURSE) ? &g_restart_emissions : &g_recursive_emissions,
signal_id, detail, instance, &emission_state);
class_closure = node->class_closure;
{
if (!accumulator)
{
- g_value_init (&accu, node->return_type);
+ g_value_init (&accu, node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
need_unset = TRUE;
}
else if (accu_used)
G_SIGNAL_DETAILED = 1 << 4,
G_SIGNAL_ACTION = 1 << 5,
G_SIGNAL_NO_HOOKS = 1 << 6
-#define G_SIGNAL_FLAGS_MASK 0x7f
} GSignalFlags;
+#define G_SIGNAL_FLAGS_MASK 0x7f
typedef enum
{
G_SIGNAL_MATCH_ID = 1 << 0,
G_SIGNAL_MATCH_FUNC = 1 << 3,
G_SIGNAL_MATCH_DATA = 1 << 4,
G_SIGNAL_MATCH_UNBLOCKED = 1 << 5
-#define G_SIGNAL_MATCH_MASK 0x3f
} GSignalMatchType;
+#define G_SIGNAL_MATCH_MASK 0x3f
+#define G_SIGNAL_TYPE_STATIC_SCOPE (G_TYPE_FLAG_RESERVED_ID_BIT)
/* --- signal information --- */
{
guint signal_id;
const gchar *signal_name;
- GType itype;
+ GType itype; /* mangled with G_SIGNAL_TYPE_STATIC_SCOPE flag */
GSignalFlags signal_flags;
- GType return_type;
+ GType return_type; /* mangled with G_SIGNAL_TYPE_STATIC_SCOPE flag */
guint n_params;
const GType *param_types;
};
*/
#include "gtype.h"
+/*
+ * MT safe
+ */
+
#include "gtypeplugin.h"
+#include "gvaluecollector.h"
#include <string.h>
}
static gboolean
+check_collect_format_I (const gchar *collect_format)
+{
+ const gchar *p = collect_format;
+ gchar valid_format[] = { G_VALUE_COLLECT_INT, G_VALUE_COLLECT_LONG,
+ G_VALUE_COLLECT_DOUBLE, G_VALUE_COLLECT_POINTER,
+ 0 };
+
+ while (*p)
+ if (!strchr (valid_format, *p++))
+ return FALSE;
+ return p - collect_format <= G_VALUE_COLLECT_FORMAT_MAX_LENGTH;
+}
+
+static gboolean
check_value_table_I (const gchar *type_name,
const GTypeValueTable *value_table)
{
{
if (value_table->value_free || value_table->value_copy ||
value_table->value_peek_pointer ||
- value_table->collect_type || value_table->collect_value ||
- value_table->lcopy_type || value_table->lcopy_value)
+ value_table->collect_format || value_table->collect_value ||
+ value_table->lcopy_format || value_table->lcopy_value)
g_warning ("cannot handle uninitializable values of type `%s'",
type_name);
return FALSE;
g_warning ("missing `value_copy()' for type `%s'", type_name);
return FALSE;
}
- if ((value_table->collect_type || value_table->collect_value) &&
- (!value_table->collect_type || !value_table->collect_value))
+ if ((value_table->collect_format || value_table->collect_value) &&
+ (!value_table->collect_format || !value_table->collect_value))
+ {
+ g_warning ("one of `collect_format' and `collect_value()' is unspecified for type `%s'",
+ type_name);
+ return FALSE;
+ }
+ if (value_table->collect_format && !check_collect_format_I (value_table->collect_format))
+ {
+ g_warning ("the `%s' specification for type `%s' is too long or invalid",
+ "collect_format",
+ type_name);
+ return FALSE;
+ }
+ if ((value_table->lcopy_format || value_table->lcopy_value) &&
+ (!value_table->lcopy_format || !value_table->lcopy_value))
{
- g_warning ("one of `collect_type' and `collect_value()' is unspecified for type `%s'",
+ g_warning ("one of `lcopy_format' and `lcopy_value()' is unspecified for type `%s'",
type_name);
return FALSE;
}
- if ((value_table->lcopy_type || value_table->lcopy_value) &&
- (!value_table->lcopy_type || !value_table->lcopy_value))
+ if (value_table->lcopy_format && !check_collect_format_I (value_table->lcopy_format))
{
- g_warning ("one of `lcopy_type' and `lcopy_value()' is unspecified for type `%s'",
+ g_warning ("the `%s' specification for type `%s' is too long or invalid",
+ "lcopy_format",
type_name);
return FALSE;
}
node->data->common.ref_count = 1;
if (vtable_size)
- *vtable = *value_table;
+ {
+ *vtable = *value_table;
+ vtable->collect_format = g_strdup (value_table->collect_format ? value_table->collect_format : "");
+ vtable->lcopy_format = g_strdup (value_table->lcopy_format ? value_table->lcopy_format : "");
+ }
node->data->common.value_table = vtable;
g_assert (node->data->common.value_table != NULL); /* paranoid */
}
else
node->data = NULL;
-
+
+ if (tdata->common.value_table)
+ {
+ g_free (tdata->common.value_table->collect_format);
+ g_free (tdata->common.value_table->lcopy_format);
+ }
g_free (tdata);
if (ptype)
GValue *dest_value);
/* varargs functionality (optional) */
gpointer (*value_peek_pointer) (const GValue *value);
- guint collect_type;
+ gchar *collect_format;
gchar* (*collect_value) (GValue *value,
- guint nth_value,
- GType *collect_type,
- GTypeCValue *collect_value);
- guint lcopy_type;
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags);
+ gchar *lcopy_format;
gchar* (*lcopy_value) (const GValue *value,
- guint nth_value,
- GType *collect_type,
- GTypeCValue *collect_value);
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags);
};
GType g_type_register_static (GType parent_type,
const gchar *type_name,
GType g_type = G_VALUE_TYPE (value);
GTypeValueTable *value_table = g_type_value_table_peek (g_type);
GTypeCValue cvalue = { 0, };
- guint nth_value = 0;
- guint collect_type = value_table->collect_type;
gchar *error_msg;
g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
g_return_if_fail (g_type_is_a (G_TYPE_FROM_INSTANCE (instance), G_VALUE_TYPE (value)));
- g_return_if_fail (value_table->collect_type == G_VALUE_COLLECT_POINTER);
+ g_return_if_fail (strcmp (value_table->collect_format, "p") == 0);
cvalue.v_pointer = instance;
- error_msg = value_table->collect_value (value, nth_value++, &collect_type, &cvalue);
-
- /* this shouldn't be triggered, instance types should collect just one pointer,
- * but since we have to follow the calling conventions for collect_value(),
- * we can attempt to feed them with 0s if they insist on extra args.
- */
- while (collect_type && !error_msg)
- {
- memset (&cvalue, 0, sizeof (cvalue));
- error_msg = value_table->collect_value (value, nth_value++, &collect_type, &cvalue);
- }
+ error_msg = value_table->collect_value (value, 1, &cvalue, 0);
if (error_msg)
{
void g_value_register_exchange_func (GType value_type1,
GType value_type2,
GValueExchange func);
-#define G_VALUE_STATIC_TAG (1 << 27)
+#define G_VALUE_NOCOPY_CONTENTS (1 << 27)
+
#ifdef __cplusplus
}
*/
enum /*< skip >*/
{
- G_VALUE_COLLECT_NONE,
- G_VALUE_COLLECT_INT,
- G_VALUE_COLLECT_LONG,
- G_VALUE_COLLECT_DOUBLE,
- G_VALUE_COLLECT_POINTER
+ G_VALUE_COLLECT_INT = 'i',
+ G_VALUE_COLLECT_LONG = 'l',
+ G_VALUE_COLLECT_DOUBLE = 'd',
+ G_VALUE_COLLECT_POINTER = 'p'
};
+
+/* vararg union holding actuall values collected
+ */
union _GTypeCValue
{
gint v_int;
* __error is a gchar** variable that will be modified to hold a g_new()
* allocated error messages if something fails.
*/
-#define G_VALUE_COLLECT(value, var_args, __error) \
+#define G_VALUE_COLLECT(value, var_args, flags, __error) \
G_STMT_START { \
GValue *_value = (value); \
+ guint _flags = (flags); \
GTypeValueTable *_vtable = g_type_value_table_peek (G_VALUE_TYPE (_value)); \
- gchar *_error_msg = NULL; \
- guint _collect_type = _vtable->collect_type; \
- guint _nth_value = 0; \
+ gchar *_collect_format = _vtable->collect_format; \
+ GTypeCValue _cvalues[G_VALUE_COLLECT_FORMAT_MAX_LENGTH] = { { 0, }, }; \
+ guint _n_values = 0; \
\
g_value_reset (_value); \
- while (_collect_type && !_error_msg) \
+ while (*_collect_format) \
{ \
- GTypeCValue _cvalue = { 0, }; \
+ GTypeCValue *_cvalue = _cvalues + _n_values++; \
\
- switch (_collect_type) \
+ switch (*_collect_format++) \
{ \
case G_VALUE_COLLECT_INT: \
- _cvalue.v_int = va_arg ((var_args), gint); \
+ _cvalue->v_int = va_arg ((var_args), gint); \
break; \
case G_VALUE_COLLECT_LONG: \
- _cvalue.v_long = va_arg ((var_args), glong); \
+ _cvalue->v_long = va_arg ((var_args), glong); \
break; \
case G_VALUE_COLLECT_DOUBLE: \
- _cvalue.v_double = va_arg ((var_args), gdouble); \
+ _cvalue->v_double = va_arg ((var_args), gdouble); \
break; \
case G_VALUE_COLLECT_POINTER: \
- _cvalue.v_pointer = va_arg ((var_args), gpointer); \
+ _cvalue->v_pointer = va_arg ((var_args), gpointer); \
break; \
default: \
- _error_msg = g_strdup_printf ("%s: invalid collect type (%d) used for %s", \
- G_STRLOC, \
- _collect_type, \
- "G_VALUE_COLLECT()"); \
- continue; \
+ g_assert_not_reached (); \
} \
- _error_msg = _vtable->collect_value (_value, \
- _nth_value++, \
- &_collect_type, \
- &_cvalue); \
} \
- *(__error) = _error_msg; \
+ *(__error) = _vtable->collect_value (_value, \
+ _n_values, \
+ _cvalues, \
+ _flags); \
} G_STMT_END
/* G_VALUE_LCOPY() collects a value's variable argument
* locations from a va_list. usage is analogous to G_VALUE_COLLECT().
*/
-#define G_VALUE_LCOPY(value, var_args, __error) \
+#define G_VALUE_LCOPY(value, var_args, flags, __error) \
G_STMT_START { \
GValue *_value = (value); \
+ guint _flags = (flags); \
GTypeValueTable *_vtable = g_type_value_table_peek (G_VALUE_TYPE (_value)); \
- gchar *_error_msg = NULL; \
- guint _lcopy_type = _vtable->lcopy_type; \
- guint _nth_value = 0; \
+ gchar *_lcopy_format = _vtable->lcopy_format; \
+ GTypeCValue _cvalues[G_VALUE_COLLECT_FORMAT_MAX_LENGTH] = { { 0, }, }; \
+ guint _n_values = 0; \
\
- while (_lcopy_type && !_error_msg) \
+ while (*_lcopy_format) \
{ \
- GTypeCValue _cvalue = { 0, }; \
+ GTypeCValue *_cvalue = _cvalues + _n_values++; \
\
- switch (_lcopy_type) \
+ switch (*_lcopy_format++) \
{ \
case G_VALUE_COLLECT_INT: \
- _cvalue.v_int = va_arg ((var_args), gint); \
+ _cvalue->v_int = va_arg ((var_args), gint); \
break; \
case G_VALUE_COLLECT_LONG: \
- _cvalue.v_long = va_arg ((var_args), glong); \
+ _cvalue->v_long = va_arg ((var_args), glong); \
break; \
case G_VALUE_COLLECT_DOUBLE: \
- _cvalue.v_double = va_arg ((var_args), gdouble); \
+ _cvalue->v_double = va_arg ((var_args), gdouble); \
break; \
case G_VALUE_COLLECT_POINTER: \
- _cvalue.v_pointer = va_arg ((var_args), gpointer); \
+ _cvalue->v_pointer = va_arg ((var_args), gpointer); \
break; \
default: \
- _error_msg = g_strdup_printf ("%s: invalid collect type (%d) used for %s", \
- G_STRLOC, \
- _lcopy_type, \
- "G_VALUE_LCOPY()"); \
- continue; \
+ g_assert_not_reached (); \
} \
- _error_msg = _vtable->lcopy_value (_value, \
- _nth_value++, \
- &_lcopy_type, \
- &_cvalue); \
} \
- *(__error) = _error_msg; \
+ *(__error) = _vtable->lcopy_value (_value, \
+ _n_values, \
+ _cvalues, \
+ _flags); \
} G_STMT_END
+#define G_VALUE_COLLECT_FORMAT_MAX_LENGTH (8)
+
+
#ifdef __cplusplus
}
static gchar*
value_char_lcopy_value (const GValue *value,
- guint nth_value,
- GType *collect_type,
- GTypeCValue *collect_value)
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags)
{
- gint8 *int8_p = collect_value->v_pointer;
+ gint8 *int8_p = collect_values[0].v_pointer;
if (!int8_p)
return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
*int8_p = value->data[0].v_int;
- *collect_type = 0;
return NULL;
}
static gchar*
value_boolean_lcopy_value (const GValue *value,
- guint nth_value,
- GType *collect_type,
- GTypeCValue *collect_value)
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags)
{
- gboolean *bool_p = collect_value->v_pointer;
+ gboolean *bool_p = collect_values[0].v_pointer;
if (!bool_p)
return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
*bool_p = value->data[0].v_int;
- *collect_type = 0;
return NULL;
}
static gchar*
value_int_collect_value (GValue *value,
- guint nth_value,
- GType *collect_type,
- GTypeCValue *collect_value)
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags)
{
- value->data[0].v_int = collect_value->v_int;
+ value->data[0].v_int = collect_values[0].v_int;
- *collect_type = 0;
return NULL;
}
static gchar*
value_int_lcopy_value (const GValue *value,
- guint nth_value,
- GType *collect_type,
- GTypeCValue *collect_value)
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags)
{
- gint *int_p = collect_value->v_pointer;
+ gint *int_p = collect_values[0].v_pointer;
if (!int_p)
return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
*int_p = value->data[0].v_int;
- *collect_type = 0;
return NULL;
}
static gchar*
value_long_collect_value (GValue *value,
- guint nth_value,
- GType *collect_type,
- GTypeCValue *collect_value)
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags)
{
- value->data[0].v_long = collect_value->v_long;
+ value->data[0].v_long = collect_values[0].v_long;
- *collect_type = 0;
return NULL;
}
static gchar*
value_long_lcopy_value (const GValue *value,
- guint nth_value,
- GType *collect_type,
- GTypeCValue *collect_value)
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags)
{
- glong *long_p = collect_value->v_pointer;
+ glong *long_p = collect_values[0].v_pointer;
if (!long_p)
return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
*long_p = value->data[0].v_long;
- *collect_type = 0;
return NULL;
}
static gchar*
value_float_collect_value (GValue *value,
- guint nth_value,
- GType *collect_type,
- GTypeCValue *collect_value)
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags)
{
- value->data[0].v_float = collect_value->v_double;
+ value->data[0].v_float = collect_values[0].v_double;
- *collect_type = 0;
return NULL;
}
static gchar*
value_float_lcopy_value (const GValue *value,
- guint nth_value,
- GType *collect_type,
- GTypeCValue *collect_value)
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags)
{
- gfloat *float_p = collect_value->v_pointer;
+ gfloat *float_p = collect_values[0].v_pointer;
if (!float_p)
return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
*float_p = value->data[0].v_float;
- *collect_type = 0;
return NULL;
}
static gchar*
value_double_collect_value (GValue *value,
- guint nth_value,
- GType *collect_type,
- GTypeCValue *collect_value)
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags)
{
- value->data[0].v_double = collect_value->v_double;
+ value->data[0].v_double = collect_values[0].v_double;
- *collect_type = 0;
return NULL;
}
static gchar*
value_double_lcopy_value (const GValue *value,
- guint nth_value,
- GType *collect_type,
- GTypeCValue *collect_value)
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags)
{
- gdouble *double_p = collect_value->v_pointer;
+ gdouble *double_p = collect_values[0].v_pointer;
if (!double_p)
return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
*double_p = value->data[0].v_double;
- *collect_type = 0;
return NULL;
}
static void
value_string_free_value (GValue *value)
{
- if (!(value->data[1].v_uint & G_VALUE_STATIC_TAG))
+ if (!(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS))
g_free (value->data[0].v_pointer);
}
static gchar*
value_string_collect_value (GValue *value,
- guint nth_value,
- GType *collect_type,
- GTypeCValue *collect_value)
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags)
{
- value->data[0].v_pointer = g_strdup (collect_value->v_pointer);
+ if (!collect_values[0].v_pointer)
+ value->data[0].v_pointer = NULL;
+ else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
+ {
+ value->data[0].v_pointer = collect_values[0].v_pointer;
+ value->data[1].v_uint = G_VALUE_NOCOPY_CONTENTS;
+ }
+ else
+ value->data[0].v_pointer = g_strdup (collect_values[0].v_pointer);
- *collect_type = 0;
return NULL;
}
static gchar*
value_string_lcopy_value (const GValue *value,
- guint nth_value,
- GType *collect_type,
- GTypeCValue *collect_value)
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags)
{
- gchar **string_p = collect_value->v_pointer;
+ gchar **string_p = collect_values[0].v_pointer;
if (!string_p)
return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
- *string_p = g_strdup (value->data[0].v_pointer);
+ if (!value->data[0].v_pointer)
+ *string_p = NULL;
+ else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
+ *string_p = value->data[0].v_pointer;
+ else
+ *string_p = g_strdup (value->data[0].v_pointer);
- *collect_type = 0;
return NULL;
}
static gchar*
value_pointer_collect_value (GValue *value,
- guint nth_value,
- GType *collect_type,
- GTypeCValue *collect_value)
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags)
{
- value->data[0].v_pointer = collect_value->v_pointer;
+ value->data[0].v_pointer = collect_values[0].v_pointer;
- *collect_type = 0;
return NULL;
}
static gchar*
value_pointer_lcopy_value (const GValue *value,
- guint nth_value,
- GType *collect_type,
- GTypeCValue *collect_value)
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags)
{
- gpointer *pointer_p = collect_value->v_pointer;
+ gpointer *pointer_p = collect_values[0].v_pointer;
if (!pointer_p)
return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
*pointer_p = value->data[0].v_pointer;
- *collect_type = 0;
return NULL;
}
static gchar*
value_ccallback_collect_value (GValue *value,
- guint nth_value,
- GType *collect_type,
- GTypeCValue *collect_value)
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags)
{
gchar *error = NULL;
- switch (nth_value)
- {
- case 0:
- value->data[0].v_pointer = collect_value->v_pointer;
- *collect_type = G_VALUE_COLLECT_POINTER;
- if (!value->data[0].v_pointer)
- error = g_strconcat ("invalid (NULL) pointer callback function for value type `",
- G_VALUE_TYPE_NAME (value),
- "'",
- NULL);
- break;
- case 1:
- value->data[1].v_pointer = collect_value->v_pointer;
- *collect_type = 0;
- break;
- }
+ if (!collect_values[0].v_pointer)
+ error = g_strconcat ("invalid (NULL) pointer callback function for value type `",
+ G_VALUE_TYPE_NAME (value),
+ "'",
+ NULL);
+ value->data[0].v_pointer = collect_values[0].v_pointer;
+ value->data[1].v_pointer = collect_values[1].v_pointer;
return error;
}
static gchar*
value_ccallback_lcopy_value (const GValue *value,
- guint nth_value,
- GType *collect_type,
- GTypeCValue *collect_value)
+ guint n_collect_values,
+ GTypeCValue *collect_values,
+ guint collect_flags)
{
- gpointer *pointer_p = collect_value->v_pointer;
+ gpointer *callback_p = collect_values[0].v_pointer;
+ gpointer *data_p = collect_values[1].v_pointer;
- if (!pointer_p)
+ if (!callback_p || !data_p)
return g_strdup_printf ("%s location for `%s' passed as NULL",
- nth_value ? "data" : "callback",
+ callback_p ? "data" : "callback",
G_VALUE_TYPE_NAME (value));
- switch (nth_value)
- {
- case 0:
- *pointer_p = value->data[0].v_pointer;
- *collect_type = G_VALUE_COLLECT_POINTER;
- break;
- case 1:
- *pointer_p = value->data[1].v_pointer;
- *collect_type = 0;
- break;
- }
+ *callback_p = value->data[0].v_pointer;
+ *data_p = value->data[1].v_pointer;
return NULL;
}
NULL, /* value_free */
value_long0_copy, /* value_copy */
NULL, /* value_peek_pointer */
- G_VALUE_COLLECT_INT, /* collect_type */
+ "i", /* collect_format */
value_int_collect_value, /* collect_value */
- G_VALUE_COLLECT_POINTER, /* lcopy_type */
+ "p", /* lcopy_format */
value_char_lcopy_value, /* lcopy_value */
};
info.value_table = &value_table;
NULL, /* value_free */
value_long0_copy, /* value_copy */
NULL, /* value_peek_pointer */
- G_VALUE_COLLECT_INT, /* collect_type */
+ "i", /* collect_format */
value_int_collect_value, /* collect_value */
- G_VALUE_COLLECT_POINTER, /* lcopy_type */
+ "p", /* lcopy_format */
value_boolean_lcopy_value, /* lcopy_value */
};
info.value_table = &value_table;
NULL, /* value_free */
value_long0_copy, /* value_copy */
NULL, /* value_peek_pointer */
- G_VALUE_COLLECT_INT, /* collect_type */
+ "i", /* collect_format */
value_int_collect_value, /* collect_value */
- G_VALUE_COLLECT_POINTER, /* lcopy_type */
+ "p", /* lcopy_format */
value_int_lcopy_value, /* lcopy_value */
};
info.value_table = &value_table;
NULL, /* value_free */
value_long0_copy, /* value_copy */
NULL, /* value_peek_pointer */
- G_VALUE_COLLECT_LONG, /* collect_type */
+ "l", /* collect_format */
value_long_collect_value, /* collect_value */
- G_VALUE_COLLECT_POINTER, /* lcopy_type */
+ "p", /* lcopy_format */
value_long_lcopy_value, /* lcopy_value */
};
info.value_table = &value_table;
NULL, /* value_free */
value_float_copy, /* value_copy */
NULL, /* value_peek_pointer */
- G_VALUE_COLLECT_DOUBLE, /* collect_type */
+ "d", /* collect_format */
value_float_collect_value, /* collect_value */
- G_VALUE_COLLECT_POINTER, /* lcopy_type */
+ "p", /* lcopy_format */
value_float_lcopy_value, /* lcopy_value */
};
info.value_table = &value_table;
NULL, /* value_free */
value_double_copy, /* value_copy */
NULL, /* value_peek_pointer */
- G_VALUE_COLLECT_DOUBLE, /* collect_type */
+ "d", /* collect_format */
value_double_collect_value, /* collect_value */
- G_VALUE_COLLECT_POINTER, /* lcopy_type */
+ "p", /* lcopy_format */
value_double_lcopy_value, /* lcopy_value */
};
info.value_table = &value_table;
value_string_free_value, /* value_free */
value_string_copy_value, /* value_copy */
value_pointer_peek_pointer, /* value_peek_pointer */
- G_VALUE_COLLECT_POINTER, /* collect_type */
+ "p", /* collect_format */
value_string_collect_value, /* collect_value */
- G_VALUE_COLLECT_POINTER, /* lcopy_type */
+ "p", /* lcopy_format */
value_string_lcopy_value, /* lcopy_value */
};
info.value_table = &value_table;
NULL, /* value_free */
value_pointer_copy, /* value_copy */
value_pointer_peek_pointer, /* value_peek_pointer */
- G_VALUE_COLLECT_POINTER, /* collect_type */
+ "p", /* collect_format */
value_pointer_collect_value, /* collect_value */
- G_VALUE_COLLECT_POINTER, /* lcopy_type */
+ "p", /* lcopy_format */
value_pointer_lcopy_value, /* lcopy_value */
};
info.value_table = &value_table;
NULL, /* value_free */
value_ccallback_copy, /* value_copy */
NULL, /* value_peek_pointer */
- G_VALUE_COLLECT_POINTER, /* collect_type */
+ "pp", /* collect_format */
value_ccallback_collect_value, /* collect_value */
- G_VALUE_COLLECT_POINTER, /* lcopy_type */
+ "pp", /* lcopy_format */
value_ccallback_lcopy_value, /* lcopy_value */
};
info.value_table = &value_table;
{
g_return_if_fail (G_IS_VALUE_STRING (value));
- if (value->data[1].v_uint & G_VALUE_STATIC_TAG)
+ if (value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS)
value->data[1].v_uint = 0;
else
g_free (value->data[0].v_pointer);
{
g_return_if_fail (G_IS_VALUE_STRING (value));
- if (!(value->data[1].v_uint & G_VALUE_STATIC_TAG))
+ if (!(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS))
g_free (value->data[0].v_pointer);
- value->data[1].v_uint = G_VALUE_STATIC_TAG;
+ value->data[1].v_uint = G_VALUE_NOCOPY_CONTENTS;
value->data[0].v_pointer = (gchar*) v_string;
}