add reserved fundamental ids for gtk types (for transition time). added

Fri May  5 01:15:48 2000  Tim Janik  <timj@gtk.org>

	* gtype.h: add reserved fundamental ids for gtk types (for transition
	time). added G_TYPE_FUNDAMENTAL_MAX for gtk.

Mon Apr 17 20:45:50 2000  Tim Janik  <timj@gtk.org>

	* glib-gobject.c (g_object_base_class_finalize): oops, don't unset
	n_params prior to destructing them.

Tue Apr 11 04:28:10 2000  Tim Janik  <timj@gtk.org>

	* fixed a couple of bugs in the initial parameter/object
	implementations, after getting beast running on GObject and GValue.

Fri Apr  7 04:27:49 2000  Tim Janik  <timj@gtk.org>

	* glib-gobject.[hc]: completed parameter set/get implementations,
	along with asyncronous parameter changed notification queue.

Sun Apr  2 04:54:36 2000  Tim Janik  <timj@gtk.org>

	* glib-gobject.[hc]: GObject implementation, that is facilities
	for setting/getting quarked data and reference counting.

	* glib-gparamspecs.[hc]: first actuall parameter implementations
	for GLib, so far we have: char, uchar, bool, int, uint, long,
	ulong, enum, flags, float, double, string and object. each of these
	GParamSpecs is a new instantiatable type in its own respect,
	so the .c file derives 13 new types from G_TYPE_PARAM and
	defines over 50 (*2) conversion facilities.

	* glib-gvaluecollector.h: generic varargs handling stubs for
	GParamSpecs, private header file (does get installed for
	inclusion into user code though).

	* glib-gvalue.[hc]: GValue functionality implementation.

	* glib-gparam.[hc]: basis GParamSpec implementation for
	the virtual base type G_TYPE_PARAM.

        * glib-genums.[hc]: enum/flags type implementation, based on
	bseenum.[hc].

	* glib-extra.[hc]: GLib additions, including 1.3 compatibility
	routines and various other functions, from string manipulation
	over list manipulation up to a unix signal GSource.

	* glib-gtype.[hc]: GLib Type System implementation, heavily
	based on BSE's dynamic type system.
This commit is contained in:
Tim Janik 2000-05-12 15:22:31 +00:00 committed by Tim Janik
parent 5947f92d3a
commit 397ad5881e
16 changed files with 7304 additions and 0 deletions

50
gobject/ChangeLog Normal file
View File

@ -0,0 +1,50 @@
Fri May 5 01:15:48 2000 Tim Janik <timj@gtk.org>
* gtype.h: add reserved fundamental ids for gtk types (for transition
time). added G_TYPE_FUNDAMENTAL_MAX for gtk.
Mon Apr 17 20:45:50 2000 Tim Janik <timj@gtk.org>
* glib-gobject.c (g_object_base_class_finalize): oops, don't unset
n_params prior to destructing them.
Tue Apr 11 04:28:10 2000 Tim Janik <timj@gtk.org>
* fixed a couple of bugs in the initial parameter/object
implementations, after getting beast running on GObject and GValue.
Fri Apr 7 04:27:49 2000 Tim Janik <timj@gtk.org>
* glib-gobject.[hc]: completed parameter set/get implementations,
along with asyncronous parameter changed notification queue.
Sun Apr 2 04:54:36 2000 Tim Janik <timj@gtk.org>
* glib-gobject.[hc]: GObject implementation, that is facilities
for setting/getting quarked data and reference counting.
* glib-gparamspecs.[hc]: first actuall parameter implementations
for GLib, so far we have: char, uchar, bool, int, uint, long,
ulong, enum, flags, float, double, string and object. each of these
GParamSpecs is a new instantiatable type in its own respect,
so the .c file derives 13 new types from G_TYPE_PARAM and
defines over 50 (*2) conversion facilities.
* glib-gvaluecollector.h: generic varargs handling stubs for
GParamSpecs, private header file (does get installed for
inclusion into user code though).
* glib-gvalue.[hc]: GValue functionality implementation.
* glib-gparam.[hc]: basis GParamSpec implementation for
the virtual base type G_TYPE_PARAM.
* glib-genums.[hc]: enum/flags type implementation, based on
bseenum.[hc].
* glib-extra.[hc]: GLib additions, including 1.3 compatibility
routines and various other functions, from string manipulation
over list manipulation up to a unix signal GSource.
* glib-gtype.[hc]: GLib Type System implementation, heavily
based on BSE's dynamic type system.

83
gobject/Makefile.am Normal file
View File

@ -0,0 +1,83 @@
# GObject - GLib Type, Object, Parameter and Signal Library
# Copyright (C) 1997,98,99,2000 Tim Janik and Red Hat, Inc.
#
## Process this file with automake to produce Makefile.in
SUBDIRS =
INCLUDES = -I$(top_srcdir) @GLIB_DEBUG_FLAGS@
# libraries to compile and install
lib_LTLIBRARIES = libgobject.la
# provide g_logv() domain
DEFS += -DG_LOG_DOMAIN=g_log_domain_gobject
# libtool stuff: set version and export symbols for resolving
libgobjectincludedir = $(includedir)/gobject
libgobject_la_LDFLAGS = @STRIP_BEGIN@ \
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \
-release $(LT_RELEASE) \
-export-dynamic \
@STRIP_END@
libgobject_la_LIBADD = # $(libglib)
#
# setup source file variables
#
# GObject header files for public installation (non-generated)
gobject_public_h_sources = @STRIP_BEGIN@ \
gvalue.h \
gparam.h \
gparamspecs.h \
genums.h \
gobject.h \
gtype.h \
gvaluecollector.h \
@STRIP_END@
# private GObject header files
gobject_private_h_sources = @STRIP_BEGIN@ \
@STRIP_END@
# GObject C sources to build the library from
gobject_c_sources = @STRIP_BEGIN@ \
gvalue.c \
gparam.c \
gparamspecs.c \
genums.c \
gobject.c \
gtype.c \
@STRIP_END@
# non-header sources (headers should be specified in the above variables)
# that don't serve as direct make target sources, i.e. they don't have
# their own .lo rules and don't get publically installed
gobject_extra_sources = @STRIP_BEGIN@ \
@STRIP_END@
#
# setup GObject sources and their dependancies
#
gobject_h_sources = $(gobject_private_h_sources) $(gobject_public_h_sources) # $(gobject_built_public_sources)
libgobjectinclude_HEADERS = $(gobject_public_h_sources) # $(gobject_built_public_sources)
libgobject_la_SOURCES = $(gobject_c_sources)
MAINTAINERCLEANFILES += # $(gobject_built_public_sources) $(gobject_built_sources)
EXTRA_HEADERS +=
EXTRA_DIST += $(gobject_private_h_sources)
EXTRA_DIST += $(gobject_extra_sources) # $(gobject_built_sources) $(gobject_built_public_sources)
#
# programs to compile and install
#
bin_PROGRAMS = gobject-query
# source files
gobject_query_SOURCES = gobject-query.c
# link programs against libgobject
progs_LDADD = ../libglib.la libgobject.la
gobject_query_LDADD = $(progs_LDADD)
#
# auxillary files
#
EXTRA_DIST += \
TODO

306
gobject/genums.c Normal file
View File

@ -0,0 +1,306 @@
/* GObject - GLib Type, Object, Parameter and Signal Library
* Copyright (C) 1998, 1999, 2000 Tim Janik and Red Hat, Inc.
*
* 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 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, write to the
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "genums.h"
/* --- prototypes --- */
extern void g_enum_types_init (void);
static void g_enum_class_init (GEnumClass *class,
gpointer class_data);
static void g_flags_class_init (GFlagsClass *class,
gpointer class_data);
/* --- functions --- */
void
g_enum_types_init (void) /* sync with glib-gtype.c */
{
static gboolean initialized = FALSE;
static const GTypeFundamentalInfo finfo = {
G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_DERIVABLE,
0 /* n_collect_bytes */,
NULL /* GTypeParamCollector */,
};
static GTypeInfo info = {
0 /* class_size */,
NULL /* base_init */,
NULL /* base_finalize */,
NULL /* class_init */,
NULL /* class_finalize */,
NULL /* class_data */,
};
GType type;
g_return_if_fail (initialized == FALSE);
initialized = TRUE;
/* G_TYPE_ENUM
*/
info.class_size = sizeof (GEnumClass);
type = g_type_register_fundamental (G_TYPE_ENUM, "GEnum", &finfo, &info);
g_assert (type == G_TYPE_ENUM);
/* G_TYPE_FLAGS
*/
info.class_size = sizeof (GFlagsClass);
type = g_type_register_fundamental (G_TYPE_FLAGS, "GFlags", &finfo, &info);
g_assert (type == G_TYPE_FLAGS);
}
GType
g_enum_register_static (const gchar *name,
const GEnumValue *const_static_values)
{
GTypeInfo enum_type_info = {
sizeof (GEnumClass),
NULL /* base_init */,
NULL /* base_finalize */,
(GClassInitFunc) g_enum_class_init,
NULL /* class_finalize */,
NULL /* class_data */,
};
GType type;
g_return_val_if_fail (name != NULL, 0);
g_return_val_if_fail (const_static_values != NULL, 0);
enum_type_info.class_data = const_static_values;
type = g_type_register_static (G_TYPE_ENUM, name, &enum_type_info);
return type;
}
GType
g_flags_register_static (const gchar *name,
const GFlagsValue *const_static_values)
{
GTypeInfo flags_type_info = {
sizeof (GFlagsClass),
NULL /* base_init */,
NULL /* base_finalize */,
(GClassInitFunc) g_flags_class_init,
NULL /* class_finalize */,
NULL /* class_data */,
};
GType type;
g_return_val_if_fail (name != NULL, 0);
g_return_val_if_fail (const_static_values != NULL, 0);
flags_type_info.class_data = const_static_values;
type = g_type_register_static (G_TYPE_FLAGS, name, &flags_type_info);
return type;
}
void
g_enum_complete_type_info (GType g_enum_type,
GTypeInfo *info,
const GEnumValue *const_values)
{
g_return_if_fail (G_TYPE_IS_ENUM (g_enum_type));
g_return_if_fail (info != NULL);
g_return_if_fail (const_values != NULL);
info->class_size = sizeof (GEnumClass);
info->base_init = NULL;
info->base_finalize = NULL;
info->class_init = (GClassInitFunc) g_enum_class_init;
info->class_finalize = NULL;
info->class_data = const_values;
}
void
g_flags_complete_type_info (GType g_flags_type,
GTypeInfo *info,
const GFlagsValue *const_values)
{
g_return_if_fail (G_TYPE_IS_FLAGS (g_flags_type));
g_return_if_fail (info != NULL);
g_return_if_fail (const_values != NULL);
info->class_size = sizeof (GFlagsClass);
info->base_init = NULL;
info->base_finalize = NULL;
info->class_init = (GClassInitFunc) g_flags_class_init;
info->class_finalize = NULL;
info->class_data = const_values;
}
static void
g_enum_class_init (GEnumClass *class,
gpointer class_data)
{
g_return_if_fail (G_IS_ENUM_CLASS (class));
class->minimum = 0;
class->maximum = 0;
class->n_values = 0;
class->values = class_data;
if (class->values)
{
GEnumValue *values;
class->minimum = class->values->value;
class->maximum = class->values->value;
for (values = class->values; values->value_name; values++)
{
class->minimum = MIN (class->minimum, values->value);
class->maximum = MAX (class->maximum, values->value);
class->n_values++;
}
}
}
static void
g_flags_class_init (GFlagsClass *class,
gpointer class_data)
{
g_return_if_fail (G_IS_FLAGS_CLASS (class));
class->mask = 0;
class->n_values = 0;
class->values = class_data;
if (class->values)
{
GFlagsValue *values;
for (values = class->values; values->value_name; values++)
{
class->mask |= values->value;
class->n_values++;
}
}
}
GEnumValue*
g_enum_get_value_by_name (GEnumClass *enum_class,
const gchar *name)
{
g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL);
g_return_val_if_fail (name != NULL, NULL);
if (enum_class->n_values)
{
GEnumValue *enum_value;
for (enum_value = enum_class->values; enum_value->value_name; enum_value++)
if (strcmp (name, enum_value->value_name) == 0)
return enum_value;
}
return NULL;
}
GFlagsValue*
g_flags_get_value_by_name (GFlagsClass *flags_class,
const gchar *name)
{
g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL);
g_return_val_if_fail (name != NULL, NULL);
if (flags_class->n_values)
{
GFlagsValue *flags_value;
for (flags_value = flags_class->values; flags_value->value_name; flags_value++)
if (strcmp (name, flags_value->value_name) == 0)
return flags_value;
}
return NULL;
}
GEnumValue*
g_enum_get_value_by_nick (GEnumClass *enum_class,
const gchar *nick)
{
g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL);
g_return_val_if_fail (nick != NULL, NULL);
if (enum_class->n_values)
{
GEnumValue *enum_value;
for (enum_value = enum_class->values; enum_value->value_name; enum_value++)
if (enum_value->value_nick && strcmp (nick, enum_value->value_nick) == 0)
return enum_value;
}
return NULL;
}
GFlagsValue*
g_flags_get_value_by_nick (GFlagsClass *flags_class,
const gchar *nick)
{
g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL);
g_return_val_if_fail (nick != NULL, NULL);
if (flags_class->n_values)
{
GFlagsValue *flags_value;
for (flags_value = flags_class->values; flags_value->value_nick; flags_value++)
if (flags_value->value_nick && strcmp (nick, flags_value->value_nick) == 0)
return flags_value;
}
return NULL;
}
GEnumValue*
g_enum_get_value (GEnumClass *enum_class,
gint value)
{
g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL);
if (enum_class->n_values)
{
GEnumValue *enum_value;
for (enum_value = enum_class->values; enum_value->value_name; enum_value++)
if (enum_value->value == value)
return enum_value;
}
return NULL;
}
GFlagsValue*
g_flags_get_first_value (GFlagsClass *flags_class,
guint value)
{
g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL);
if (flags_class->n_values)
{
GFlagsValue *flags_value;
for (flags_value = flags_class->values; flags_value->value_name; flags_value++)
if ((flags_value->value & value) > 0)
return flags_value;
}
return NULL;
}

118
gobject/genums.h Normal file
View File

@ -0,0 +1,118 @@
/* GObject - GLib Type, Object, Parameter and Signal Library
* Copyright (C) 1998, 1999, 2000 Tim Janik and Red Hat, Inc.
*
* 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 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, write to the
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __G_ENUMS_H__
#define __G_ENUMS_H__
#include <gobject/gtype.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* --- type macros --- */
#define G_TYPE_IS_ENUM(type) (G_TYPE_FUNDAMENTAL (type) == G_TYPE_ENUM)
#define G_ENUM_TYPE(class) (G_TYPE_FROM_CLASS (class))
#define G_ENUM_NAME(class) (g_type_name (G_ENUM_TYPE (class)))
#define G_ENUM_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), G_TYPE_ENUM, GEnumClass))
#define G_IS_ENUM_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), G_TYPE_ENUM))
#define G_TYPE_IS_FLAGS(type) (G_TYPE_FUNDAMENTAL (type) == G_TYPE_FLAGS)
#define G_FLAGS_TYPE(class) (G_TYPE_FROM_CLASS (class))
#define G_FLAGS_NAME(class) (g_type_name (G_FLAGS_TYPE (class)))
#define G_FLAGS_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), G_TYPE_FLAGS, GFlagsClass))
#define G_IS_FLAGS_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), G_TYPE_FLAGS))
/* --- enum/flag values & classes --- */
typedef struct _GEnumClass GEnumClass;
typedef struct _GFlagsClass GFlagsClass;
typedef struct _GEnumValue GEnumValue;
typedef struct _GFlagsValue GFlagsValue;
struct _GEnumClass
{
GTypeClass g_type_class;
gint minimum;
gint maximum;
guint n_values;
GEnumValue *values;
};
struct _GFlagsClass
{
GTypeClass g_type_class;
guint mask;
guint n_values;
GFlagsValue *values;
};
struct _GEnumValue
{
gint value;
gchar *value_name;
gchar *value_nick;
};
struct _GFlagsValue
{
guint value;
gchar *value_name;
gchar *value_nick;
};
/* --- prototypes --- */
GEnumValue* g_enum_get_value (GEnumClass *enum_class,
gint value);
GEnumValue* g_enum_get_value_by_name (GEnumClass *enum_class,
const gchar *name);
GEnumValue* g_enum_get_value_by_nick (GEnumClass *enum_class,
const gchar *nick);
GFlagsValue* g_flags_get_first_value (GFlagsClass *flags_class,
guint value);
GFlagsValue* g_flags_get_value_by_name (GFlagsClass *flags_class,
const gchar *name);
GFlagsValue* g_flags_get_value_by_nick (GFlagsClass *flags_class,
const gchar *nick);
/* --- registration functions --- */
/* const_static_values is a NULL terminated array of enum/flags
* values that is taken over!
*/
GType g_enum_register_static (const gchar *name,
const GEnumValue *const_static_values);
GType g_flags_register_static (const gchar *name,
const GFlagsValue *const_static_values);
/* functions to complete the type information
* for enums/flags implemented by plugins
*/
void g_enum_complete_type_info (GType g_enum_type,
GTypeInfo *info,
const GEnumValue *const_values);
void g_flags_complete_type_info (GType g_flags_type,
GTypeInfo *info,
const GFlagsValue *const_values);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __G_ENUMS_H__ */

219
gobject/gobject-query.c Normal file
View File

@ -0,0 +1,219 @@
/* GObject - GLib Type, Object, Parameter and Signal Library
* Copyright (C) 1998, 1999, 2000 Tim Janik and Red Hat, Inc.
*
* 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 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, write to the
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <glib-object.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
static gchar *indent_inc = NULL;
static guint spacing = 1;
static FILE *f_out = NULL;
static GType root = 0;
static gboolean recursion = TRUE;
#if 0
# define O_SPACE "\\as"
# define O_ESPACE " "
# define O_BRANCH "\\aE"
# define O_VLINE "\\al"
# define O_LLEAF "\\aL"
# define O_KEY_FILL "_"
#else
# define O_SPACE " "
# define O_ESPACE ""
# define O_BRANCH "+"
# define O_VLINE "|"
# define O_LLEAF "`"
# define O_KEY_FILL "_"
#endif
static void
show_nodes (GType type,
GType sibling,
const gchar *indent)
{
GType *children;
guint i;
if (!type)
return;
children = g_type_children (type, NULL);
if (type != root)
for (i = 0; i < spacing; i++)
fprintf (f_out, "%s%s\n", indent, O_VLINE);
fprintf (f_out, "%s%s%s%s",
indent,
sibling ? O_BRANCH : (type != root ? O_LLEAF : O_SPACE),
O_ESPACE,
g_type_name (type));
for (i = strlen (g_type_name (type)); i <= strlen (indent_inc); i++)
fputs (O_KEY_FILL, f_out);
fputc ('\n', f_out);
if (children && recursion)
{
gchar *new_indent;
GType *child;
if (sibling)
new_indent = g_strconcat (indent, O_VLINE, indent_inc, NULL);
else
new_indent = g_strconcat (indent, O_SPACE, indent_inc, NULL);
for (child = children; *child; child++)
show_nodes (child[0], child[1], new_indent);
g_free (new_indent);
}
g_free (children);
}
static gint
help (gchar *arg)
{
fprintf (stderr, "usage: query <qualifier> [-r <type>] [-{i|b} \"\"] [-s #] [-{h|x|y}]\n");
fprintf (stderr, " -r specifiy root type\n");
fprintf (stderr, " -n don't descend type tree\n");
fprintf (stderr, " -h guess what ;)\n");
fprintf (stderr, " -b specifiy indent string\n");
fprintf (stderr, " -i specifiy incremental indent string\n");
fprintf (stderr, " -s specifiy line spacing\n");
fprintf (stderr, "qualifiers:\n");
fprintf (stderr, " froots iterate over fundamental roots\n");
fprintf (stderr, " tree print BSE type tree\n");
return arg != NULL;
}
int
main (gint argc,
gchar *argv[])
{
gboolean gen_froots = 0;
gboolean gen_tree = 0;
guint i;
gchar *iindent = "";
f_out = stdout;
g_type_init ();
root = G_TYPE_OBJECT;
for (i = 1; i < argc; i++)
{
if (strcmp ("-s", argv[i]) == 0)
{
i++;
if (i < argc)
spacing = atoi (argv[i]);
}
else if (strcmp ("-i", argv[i]) == 0)
{
i++;
if (i < argc)
{
char *p;
guint n;
p = argv[i];
while (*p)
p++;
n = p - argv[i];
indent_inc = g_new (gchar, n * strlen (O_SPACE) + 1);
*indent_inc = 0;
while (n)
{
n--;
strcpy (indent_inc, O_SPACE);
}
}
}
else if (strcmp ("-b", argv[i]) == 0)
{
i++;
if (i < argc)
iindent = argv[i];
}
else if (strcmp ("-r", argv[i]) == 0)
{
i++;
if (i < argc)
root = g_type_from_name (argv[i]);
}
else if (strcmp ("-n", argv[i]) == 0)
{
recursion = FALSE;
}
else if (strcmp ("froots", argv[i]) == 0)
{
gen_froots = 1;
}
else if (strcmp ("tree", argv[i]) == 0)
{
gen_tree = 1;
}
else if (strcmp ("-h", argv[i]) == 0)
{
return help (NULL);
}
else if (strcmp ("--help", argv[i]) == 0)
{
return help (NULL);
}
else
return help (argv[i]);
}
if (!gen_froots && !gen_tree)
return help (argv[i-1]);
if (!indent_inc)
{
indent_inc = g_new (gchar, strlen (O_SPACE) + 1);
*indent_inc = 0;
strcpy (indent_inc, O_SPACE);
strcpy (indent_inc, O_SPACE);
strcpy (indent_inc, O_SPACE);
}
if (gen_tree)
show_nodes (root, 0, iindent);
if (gen_froots)
{
root = ~0;
for (i = 0; i < 256; i++)
{
gchar *name = g_type_name (i);
if (name)
show_nodes (i, 0, iindent);
}
}
return 0;
}

751
gobject/gobject.c Normal file
View File

@ -0,0 +1,751 @@
/* GObject - GLib Type, Object, Parameter and Signal Library
* Copyright (C) 1998, 1999, 2000 Tim Janik and Red Hat, Inc.
*
* 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 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, write to the
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "gobject.h"
#include "gvalue.h"
#include "gvaluecollector.h"
#define DEBUG_OBJECTS
/* --- macros --- */
#define PARAM_SPEC_PARAM_ID(pspec) (GPOINTER_TO_UINT (g_param_spec_get_qdata ((pspec), quark_param_id)))
/* --- prototypes --- */
extern void g_object_type_init (void);
static void g_object_base_class_init (GObjectClass *class);
static void g_object_base_class_finalize (GObjectClass *class);
static void g_object_do_class_init (GObjectClass *class);
static void g_object_do_init (GObject *object);
static void g_object_do_queue_param_changed (GObject *object,
GParamSpec *pspec);
static void g_object_do_dispatch_param_changed (GObject *object,
GParamSpec *pspec);
static void g_object_last_unref (GObject *object);
static void g_object_do_shutdown (GObject *object);
static void g_object_do_finalize (GObject *object);
/* --- variables --- */
static GQuark quark_param_id = 0;
static GQuark quark_param_changed_queue = 0;
static GHashTable *param_spec_hash_table = NULL;
/* --- functions --- */
#ifdef DEBUG_OBJECTS
static guint debug_objects_count = 0;
static GHashTable *debug_objects_ht = NULL;
static void
debug_objects_foreach (gpointer key,
gpointer value,
gpointer user_data)
{
GObject *object = value;
g_message ("[%p] stale %s\tref_count=%u",
object,
G_OBJECT_TYPE_NAME (object),
object->ref_count);
}
static void
debug_objects_atexit (void)
{
if (debug_objects_ht)
{
g_message ("stale GObjects: %u", debug_objects_count);
g_hash_table_foreach (debug_objects_ht, debug_objects_foreach, NULL);
}
}
#endif DEBUG_OBJECTS
void
g_object_type_init (void) /* sync with glib-gtype.c */
{
static gboolean initialized = FALSE;
static const GTypeFundamentalInfo finfo = {
G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE,
0 /* n_collect_bytes */,
NULL /* GTypeParamCollector */,
};
static GTypeInfo info = {
sizeof (GObjectClass),
(GBaseInitFunc) g_object_base_class_init,
(GBaseFinalizeFunc) g_object_base_class_finalize,
(GClassInitFunc) g_object_do_class_init,
NULL /* class_destroy */,
NULL /* class_data */,
sizeof (GObject),
0 /* n_preallocs */,
(GInstanceInitFunc) g_object_do_init,
};
GType type;
g_return_if_fail (initialized == FALSE);
initialized = TRUE;
/* G_TYPE_OBJECT
*/
type = g_type_register_fundamental (G_TYPE_OBJECT, "GObject", &finfo, &info);
g_assert (type == G_TYPE_OBJECT);
#ifdef DEBUG_OBJECTS
g_atexit (debug_objects_atexit);
#endif DEBUG_OBJECTS
}
static void
g_object_base_class_init (GObjectClass *class)
{
/* reset instance specific fields and methods that don't get inherited */
class->n_param_specs = 0;
class->param_specs = NULL;
class->get_param = NULL;
class->set_param = NULL;
}
static void
g_object_base_class_finalize (GObjectClass *class)
{
guint i;
g_message ("finallizing base class of %s", G_OBJECT_CLASS_NAME (class));
for (i = 0; i < class->n_param_specs; i++)
{
GParamSpec *pspec = class->param_specs[i];
g_param_spec_hash_table_remove (param_spec_hash_table, pspec);
g_param_spec_set_qdata (pspec, quark_param_id, NULL);
g_param_spec_unref (pspec);
}
class->n_param_specs = 0;
g_free (class->param_specs);
class->param_specs = NULL;
}
static void
g_object_do_class_init (GObjectClass *class)
{
quark_param_id = g_quark_from_static_string ("glib-object-param-id");
quark_param_changed_queue = g_quark_from_static_string ("glib-object-param-changed-queue");
param_spec_hash_table = g_param_spec_hash_table_new ();
class->queue_param_changed = g_object_do_queue_param_changed;
class->dispatch_param_changed = g_object_do_dispatch_param_changed;
class->shutdown = g_object_do_shutdown;
class->finalize = g_object_do_finalize;
}
void
g_object_class_install_param (GObjectClass *class,
guint param_id,
GParamSpec *pspec /* 1 ref_count taken over */)
{
guint i;
g_return_if_fail (G_IS_OBJECT_CLASS (class));
g_return_if_fail (G_IS_PARAM_SPEC (pspec));
if (pspec->flags & G_PARAM_WRITABLE)
g_return_if_fail (class->set_param != NULL);
if (pspec->flags & G_PARAM_READABLE)
g_return_if_fail (class->get_param != NULL);
g_return_if_fail (param_id > 0);
g_return_if_fail (PARAM_SPEC_PARAM_ID (pspec) == 0); /* paranoid */
/* expensive paranoia checks ;( */
for (i = 0; i < class->n_param_specs; i++)
if (PARAM_SPEC_PARAM_ID (class->param_specs[i]) == param_id)
{
g_warning (G_STRLOC ": class `%s' already contains a parameter `%s' with id %u, "
"cannot install parameter `%s'",
G_OBJECT_CLASS_NAME (class),
class->param_specs[i]->name,
param_id,
pspec->name);
return;
}
if (g_object_class_find_param_spec (class, pspec->name))
{
g_warning (G_STRLOC ": class `%s' already contains a parameter named `%s'",
G_OBJECT_CLASS_NAME (class),
pspec->name);
return;
}
g_param_spec_set_qdata (pspec, quark_param_id, GUINT_TO_POINTER (param_id));
g_param_spec_hash_table_insert (param_spec_hash_table, pspec, G_OBJECT_CLASS_TYPE (class));
i = class->n_param_specs++;
class->param_specs = g_renew (GParamSpec*, class->param_specs, class->n_param_specs);
class->param_specs[i] = pspec;
}
GParamSpec*
g_object_class_find_param_spec (GObjectClass *class,
const gchar *param_name)
{
g_return_val_if_fail (G_IS_OBJECT_CLASS (class), NULL);
g_return_val_if_fail (param_name != NULL, NULL);
return g_param_spec_hash_table_lookup (param_spec_hash_table,
param_name,
G_OBJECT_CLASS_TYPE (class),
TRUE, NULL);
}
static void
g_object_do_init (GObject *object)
{
object->ref_count = 1;
object->qdata = NULL;
#ifdef DEBUG_OBJECTS
if (!debug_objects_ht)
debug_objects_ht = g_hash_table_new (g_direct_hash, NULL);
debug_objects_count++;
g_hash_table_insert (debug_objects_ht, object, object);
#endif DEBUG_OBJECTS
}
static void
g_object_last_unref (GObject *object)
{
g_return_if_fail (object->ref_count > 0);
if (object->ref_count == 1) /* may have been re-referenced meanwhile */
G_OBJECT_GET_CLASS (object)->shutdown (object);
object->ref_count -= 1;
if (object->ref_count == 0) /* may have been re-referenced meanwhile */
G_OBJECT_GET_CLASS (object)->finalize (object);
}
static void
g_object_do_shutdown (GObject *object)
{
/* this function needs to be always present for unconditional
* chaining, we also might add some code here later.
* beware though, subclasses may invoke shutdown() arbitrarily.
*/
}
static void
g_object_do_finalize (GObject *object)
{
g_datalist_clear (&object->qdata);
#ifdef DEBUG_OBJECTS
g_assert (g_hash_table_lookup (debug_objects_ht, object) == object);
g_hash_table_remove (debug_objects_ht, object);
debug_objects_count--;
#endif DEBUG_OBJECTS
g_type_free_instance ((GTypeInstance*) object);
}
gpointer
g_object_new (GType object_type,
const gchar *first_param_name,
...)
{
GObject *object;
va_list var_args;
g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type), NULL);
va_start (var_args, first_param_name);
object = g_object_new_valist (object_type, first_param_name, var_args);
va_end (var_args);
return object;
}
gpointer
g_object_new_valist (GType object_type,
const gchar *first_param_name,
va_list var_args)
{
GObject *object;
g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type), NULL);
object = (GObject*) g_type_create_instance (object_type);
if (first_param_name)
g_object_set_valist (object, first_param_name, var_args);
return object;
}
static void
g_object_do_dispatch_param_changed (GObject *object,
GParamSpec *pspec)
{
g_message ("NOTIFICATION: parameter `%s' changed on object `%s'",
pspec->name,
G_OBJECT_TYPE_NAME (object));
}
static gboolean
notify_param_changed_handler (gpointer data)
{
GObject *object;
GObjectClass *class;
GSList *slist;
/* FIXME: need GDK_THREADS lock */
object = G_OBJECT (data);
class = G_OBJECT_GET_CLASS (object);
slist = g_datalist_id_get_data (&object->qdata, quark_param_changed_queue);
/* a reference count is still being held */
for (; slist; slist = slist->next)
if (slist->data)
{
GParamSpec *pspec = slist->data;
slist->data = NULL;
class->dispatch_param_changed (object, pspec);
}
g_datalist_id_set_data (&object->qdata, quark_param_changed_queue, NULL);
return FALSE;
}
static void
g_object_do_queue_param_changed (GObject *object,
GParamSpec *pspec)
{
GSList *slist, *last = NULL;
/* if this is a recursive call on this object (i.e. pspecs are queued
* for notification, while param_changed notification is currently in
* progress), we simply add them to the queue that is currently being
* dispatched. otherwise, we later dispatch parameter changed notification
* asyncronously from an idle handler untill the queue is completely empty.
*/
slist = g_datalist_id_get_data (&object->qdata, quark_param_changed_queue);
for (; slist; last = slist, slist = last->next)
if (slist->data == pspec)
return;
if (!last)
{
g_object_ref (object);
g_idle_add_full (G_NOTIFY_PRIORITY,
notify_param_changed_handler,
object,
(GDestroyNotify) g_object_unref);
g_object_set_qdata_full (object,
quark_param_changed_queue,
g_slist_prepend (NULL, pspec),
(GDestroyNotify) g_slist_free);
}
else
last->next = g_slist_prepend (NULL, pspec);
}
static inline void
object_get_param (GObject *object,
GValue *value,
GParamSpec *pspec,
const gchar *trailer)
{
GObjectClass *class;
g_return_if_fail (g_type_is_a (G_OBJECT_TYPE (object), pspec->owner_type)); /* paranoid */
class = g_type_class_peek (pspec->owner_type);
class->get_param (object, PARAM_SPEC_PARAM_ID (pspec), value, pspec, trailer);
}
static inline void
object_set_param (GObject *object,
GValue *value,
GParamSpec *pspec,
const gchar *trailer)
{
GObjectClass *class;
g_return_if_fail (g_type_is_a (G_OBJECT_TYPE (object), pspec->owner_type)); /* paranoid */
class = g_type_class_peek (pspec->owner_type);
class->set_param (object, PARAM_SPEC_PARAM_ID (pspec), value, pspec, trailer);
class->queue_param_changed (object, pspec);
}
void
g_object_set_valist (GObject *object,
const gchar *first_param_name,
va_list var_args)
{
const gchar *name;
g_return_if_fail (G_IS_OBJECT (object));
g_object_ref (object);
name = first_param_name;
while (name)
{
const gchar *trailer = NULL;
GValue value = { 0, };
GParamSpec *pspec;
gchar *error = NULL;
pspec = g_param_spec_hash_table_lookup (param_spec_hash_table,
name,
G_OBJECT_TYPE (object),
TRUE,
&trailer);
if (!pspec)
{
g_warning ("%s: object class `%s' has no parameter named `%s'",
G_STRLOC,
G_OBJECT_TYPE_NAME (object),
name);
break;
}
if (!(pspec->flags & G_PARAM_WRITABLE))
{
g_warning ("%s: parameter `%s' of object class `%s' is not writable",
G_STRLOC,
pspec->name,
G_OBJECT_TYPE_NAME (object));
break;
}
g_value_init (&value, G_PARAM_SPEC_TYPE (pspec));
G_PARAM_COLLECT_VALUE (&value, pspec, var_args, &error);
if (error)
{
g_warning ("%s: %s", G_STRLOC, error);
g_free (error);
/* we purposely leak the value here, it might not be
* in a sane state if an error condition occoured
*/
break;
}
object_set_param (object, &value, pspec, trailer);
g_value_unset (&value);
name = va_arg (var_args, gchar*);
}
g_object_unref (object);
}
void
g_object_get_valist (GObject *object,
const gchar *first_param_name,
va_list var_args)
{
const gchar *name;
g_return_if_fail (G_IS_OBJECT (object));
g_object_ref (object);
name = first_param_name;
while (name)
{
const gchar *trailer = NULL;
GValue value = { 0, };
GParamSpec *pspec;
gchar *error = NULL;
pspec = g_param_spec_hash_table_lookup (param_spec_hash_table,
name,
G_OBJECT_TYPE (object),
TRUE,
&trailer);
if (!pspec)
{
g_warning ("%s: object class `%s' has no parameter named `%s'",
G_STRLOC,
G_OBJECT_TYPE_NAME (object),
name);
break;
}
if (!(pspec->flags & G_PARAM_READABLE))
{
g_warning ("%s: parameter `%s' of object class `%s' is not readable",
G_STRLOC,
pspec->name,
G_OBJECT_TYPE_NAME (object));
break;
}
g_value_init (&value, G_PARAM_SPEC_TYPE (pspec));
object_get_param (object, &value, pspec, trailer);
G_PARAM_LCOPY_VALUE (&value, pspec, var_args, &error);
if (error)
{
g_warning ("%s: %s", G_STRLOC, error);
g_free (error);
/* we purposely leak the value here, it might not be
* in a sane state if an error condition occoured
*/
break;
}
g_value_unset (&value);
name = va_arg (var_args, gchar*);
}
g_object_unref (object);
}
void
g_object_set (GObject *object,
const gchar *first_param_name,
...)
{
va_list var_args;
g_return_if_fail (G_IS_OBJECT (object));
va_start (var_args, first_param_name);
g_object_set_valist (object, first_param_name, var_args);
va_end (var_args);
}
void
g_object_get (GObject *object,
const gchar *first_param_name,
...)
{
va_list var_args;
g_return_if_fail (G_IS_OBJECT (object));
va_start (var_args, first_param_name);
g_object_get_valist (object, first_param_name, var_args);
va_end (var_args);
}
void
g_object_set_param (GObject *object,
const gchar *param_name,
const GValue *value)
{
GParamSpec *pspec;
const gchar *trailer;
g_return_if_fail (G_IS_OBJECT (object));
g_return_if_fail (param_name != NULL);
g_return_if_fail (G_IS_VALUE (value));
g_object_ref (object);
pspec = g_param_spec_hash_table_lookup (param_spec_hash_table,
param_name,
G_OBJECT_TYPE (object),
TRUE,
&trailer);
if (!pspec)
g_warning ("%s: object class `%s' has no parameter named `%s'",
G_STRLOC,
G_OBJECT_TYPE_NAME (object),
param_name);
else
{
GValue tmp_value = { 0, };
/* provide a copy to work from and convert if necessary */
g_value_init (&tmp_value, G_PARAM_SPEC_TYPE (pspec));
if (!g_value_convert (value, &tmp_value) ||
g_value_validate (&tmp_value, pspec))
g_warning ("%s: can't convert `%s' value to parameter `%s' of type `%s'",
G_STRLOC,
G_VALUE_TYPE_NAME (value),
pspec->name,
G_PARAM_SPEC_TYPE_NAME (pspec));
else
object_set_param (object, &tmp_value, pspec, trailer);
g_value_unset (&tmp_value);
}
g_object_unref (object);
}
void
g_object_get_param (GObject *object,
const gchar *param_name,
GValue *value)
{
GParamSpec *pspec;
const gchar *trailer;
g_return_if_fail (G_IS_OBJECT (object));
g_return_if_fail (param_name != NULL);
g_return_if_fail (G_IS_VALUE (value));
g_object_ref (object);
pspec = g_param_spec_hash_table_lookup (param_spec_hash_table,
param_name,
G_OBJECT_TYPE (object),
TRUE,
&trailer);
if (!pspec)
g_warning ("%s: object class `%s' has no parameter named `%s'",
G_STRLOC,
G_OBJECT_TYPE_NAME (object),
param_name);
else
{
GValue tmp_value = { 0, };
/* provide a copy to work from and later convert if necessary, so
* _get_param() implementations need *not* care about freeing values
* that might be already set in the parameter to get.
* (though, at this point, GValue should exclusively be modified
* through the accessor functions anyways)
*/
g_value_init (&tmp_value, G_PARAM_SPEC_TYPE (pspec));
if (!g_value_types_exchangable (G_VALUE_TYPE (value), G_PARAM_SPEC_TYPE (pspec)))
g_warning ("%s: can't retrive parameter `%s' of type `%s' as value of type `%s'",
G_STRLOC,
pspec->name,
G_PARAM_SPEC_TYPE_NAME (pspec),
G_VALUE_TYPE_NAME (value));
else
{
object_get_param (object, &tmp_value, pspec, trailer);
g_value_convert (&tmp_value, value);
/* g_value_validate (value, pspec); */
}
g_value_unset (&tmp_value);
}
g_object_unref (object);
}
void
g_object_queue_param_changed (GObject *object,
const gchar *param_name)
{
GParamSpec *pspec;
g_return_if_fail (G_IS_OBJECT (object));
g_return_if_fail (param_name != NULL);
pspec = g_param_spec_hash_table_lookup (param_spec_hash_table,
param_name,
G_OBJECT_TYPE (object),
TRUE, NULL);
if (!pspec)
g_warning ("%s: object class `%s' has no parameter named `%s'",
G_STRLOC,
G_OBJECT_TYPE_NAME (object),
param_name);
else
G_OBJECT_GET_CLASS (object)->queue_param_changed (object, pspec);
}
GObject*
g_object_ref (GObject *object)
{
g_return_val_if_fail (G_IS_OBJECT (object), NULL);
g_return_val_if_fail (object->ref_count > 0, NULL);
object->ref_count += 1;
return object;
}
void
g_object_unref (GObject *object)
{
g_return_if_fail (G_IS_OBJECT (object));
g_return_if_fail (object->ref_count > 0);
if (object->ref_count > 1)
object->ref_count -= 1;
else
g_object_last_unref (object);
}
gpointer
g_object_get_qdata (GObject *object,
GQuark quark)
{
g_return_val_if_fail (G_IS_OBJECT (object), NULL);
return quark ? g_datalist_id_get_data (&object->qdata, quark) : NULL;
}
void
g_object_set_qdata (GObject *object,
GQuark quark,
gpointer data)
{
g_return_if_fail (G_IS_OBJECT (object));
g_return_if_fail (quark > 0);
g_datalist_id_set_data (&object->qdata, quark, data);
}
void
g_object_set_qdata_full (GObject *object,
GQuark quark,
gpointer data,
GDestroyNotify destroy)
{
g_return_if_fail (G_IS_OBJECT (object));
g_return_if_fail (quark > 0);
g_datalist_id_set_data_full (&object->qdata, quark, data, data ? destroy : NULL);
}
gpointer
g_object_steal_qdata (GObject *object,
GQuark quark)
{
g_return_val_if_fail (G_IS_OBJECT (object), NULL);
g_return_val_if_fail (quark > 0, NULL);
return g_datalist_id_remove_no_notify (&object->qdata, quark);
}

165
gobject/gobject.h Normal file
View File

@ -0,0 +1,165 @@
/* GObject - GLib Type, Object, Parameter and Signal Library
* Copyright (C) 1998, 1999, 2000 Tim Janik and Red Hat, Inc.
*
* 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 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, write to the
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __G_GOBJECT_H__
#define __G_GOBJECT_H__
#include <gobject/gtype.h>
#include <gobject/gparam.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* --- type macros --- */
#define G_TYPE_IS_OBJECT(type) (G_TYPE_FUNDAMENTAL (type) == G_TYPE_OBJECT)
#define G_OBJECT(object) (G_IS_OBJECT (object) ? ((GObject*) (object)) : \
G_TYPE_CHECK_INSTANCE_CAST ((object), G_TYPE_OBJECT, GObject))
#define G_OBJECT_CLASS(class) (G_IS_OBJECT_CLASS (class) ? ((GObjectClass*) (class)) : \
G_TYPE_CHECK_CLASS_CAST ((class), G_TYPE_OBJECT, GObjectClass))
#define G_IS_OBJECT(object) (((GObject*) (object)) != NULL && \
G_IS_OBJECT_CLASS (((GTypeInstance*) (object))->g_class))
#define G_IS_OBJECT_CLASS(class) (((GTypeClass*) (class)) != NULL && \
G_TYPE_IS_OBJECT (((GTypeClass*) (class))->g_type))
#define G_OBJECT_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS ((object), G_TYPE_OBJECT, GObjectClass))
#define G_OBJECT_TYPE(object) (G_TYPE_FROM_INSTANCE (object))
#define G_OBJECT_TYPE_NAME(object) (g_type_name (G_OBJECT_TYPE (object)))
#define G_OBJECT_CLASS_TYPE(class) (G_TYPE_FROM_CLASS (class))
#define G_OBJECT_CLASS_NAME(class) (g_type_name (G_OBJECT_CLASS_TYPE (class)))
#define G_NOTIFY_PRIORITY (G_PRIORITY_HIGH_IDLE + 20)
/* --- typedefs & structures --- */
typedef struct _GObject GObject;
typedef struct _GObjectClass GObjectClass;
typedef void (*GObjectGetParamFunc) (GObject *object,
guint param_id,
GValue *value,
GParamSpec *pspec,
const gchar *trailer);
typedef void (*GObjectSetParamFunc) (GObject *object,
guint param_id,
GValue *value,
GParamSpec *pspec,
const gchar *trailer);
typedef void (*GObjectFinalizeFunc) (GObject *object);
struct _GObject
{
GTypeInstance g_type_instance;
/*< private >*/
guint ref_count;
GData *qdata;
};
struct _GObjectClass
{
GTypeClass g_type_class;
guint n_param_specs;
GParamSpec **param_specs;
void (*get_param) (GObject *object,
guint param_id,
GValue *value,
GParamSpec *pspec,
const gchar *trailer);
void (*set_param) (GObject *object,
guint param_id,
GValue *value,
GParamSpec *pspec,
const gchar *trailer);
void (*queue_param_changed) (GObject *object,
GParamSpec *pspec);
void (*dispatch_param_changed) (GObject *object,
GParamSpec *pspec);
void (*shutdown) (GObject *object);
void (*finalize) (GObject *object);
};
/* --- prototypes --- */
void g_object_class_install_param (GObjectClass *oclass,
guint param_id,
GParamSpec *pspec /* +1 ref */);
GParamSpec* g_object_class_find_param_spec (GObjectClass *oclass,
const gchar *param_name);
gpointer g_object_new (GType object_type,
const gchar *first_param_name,
...);
gpointer g_object_new_valist (GType object_type,
const gchar *first_param_name,
va_list var_args);
void g_object_set (GObject *object,
const gchar *first_param_name,
...);
void g_object_get (GObject *object,
const gchar *first_param_name,
...);
void g_object_set_valist (GObject *object,
const gchar *first_param_name,
va_list var_args);
void g_object_get_valist (GObject *object,
const gchar *first_param_name,
va_list var_args);
void g_object_set_param (GObject *object,
const gchar *param_name,
const GValue *value);
void g_object_get_param (GObject *object,
const gchar *param_name,
GValue *value);
void g_object_queue_param_changed (GObject *object,
const gchar *param_name);
GObject* g_object_ref (GObject *object);
void g_object_unref (GObject *object);
gpointer g_object_get_qdata (GObject *object,
GQuark quark);
void g_object_set_qdata (GObject *object,
GQuark quark,
gpointer data);
void g_object_set_qdata_full (GObject *object,
GQuark quark,
gpointer data,
GDestroyNotify destroy);
gpointer g_object_steal_qdata (GObject *object,
GQuark quark);
/* --- implementation macros --- */
#define G_WARN_INVALID_PARAM_ID(object, param_id, pspec) \
G_STMT_START { \
GObject *_object = (GObject*) (object); \
GParamSpec *_pspec = (GParamSpec*) (pspec); \
guint _param_id = (param_id); \
g_warning ("%s: invalid parameter id %u for \"%s\" of type `%s' in `%s'", \
G_STRLOC, \
_param_id, \
_pspec->name, \
g_type_name (G_PARAM_SPEC_TYPE (_pspec)), \
BSE_OBJECT_TYPE_NAME (_object)); \
} G_STMT_END
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __G_GOBJECT_H__ */

318
gobject/gparam.c Normal file
View File

@ -0,0 +1,318 @@
/* GObject - GLib Type, Object, Parameter and Signal Library
* Copyright (C) 1997, 1998, 1999, 2000 Tim Janik and Red Hat, Inc.
*
* 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 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, write to the
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "gparam.h"
#include <string.h>
/* --- defines --- */
#define G_PARAM_SPEC_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), G_TYPE_PARAM, GParamSpecClass))
/* --- prototypes --- */
extern void g_param_types_init (void);
extern void g_param_spec_types_init (void); /* sync with glib-gparamspecs.c */
static void g_param_spec_class_base_init (GParamSpecClass *class);
static void g_param_spec_class_base_finalize (GParamSpecClass *class);
static void g_param_spec_class_init (GParamSpecClass *class,
gpointer class_data);
static void g_param_spec_init (GParamSpec *pspec);
static void g_param_spec_finalize (GParamSpec *pspec);
/* --- functions --- */
void
g_param_types_init (void) /* sync with glib-gtype.c */
{
static const GTypeFundamentalInfo finfo = {
(G_TYPE_FLAG_CLASSED |
G_TYPE_FLAG_INSTANTIATABLE |
G_TYPE_FLAG_DERIVABLE |
G_TYPE_FLAG_DEEP_DERIVABLE),
0 /* n_collect_bytes */,
NULL /* GTypeParamCollector */,
};
static const GTypeInfo param_spec_info = {
sizeof (GParamSpecClass),
(GBaseInitFunc) g_param_spec_class_base_init,
(GBaseFinalizeFunc) g_param_spec_class_base_finalize,
(GClassInitFunc) g_param_spec_class_init,
(GClassFinalizeFunc) NULL,
NULL /* class_data */,
sizeof (GParamSpec),
0 /* n_preallocs */,
(GInstanceInitFunc) g_param_spec_init,
};
GType type;
type = g_type_register_fundamental (G_TYPE_PARAM, "GParam", &finfo, &param_spec_info);
g_assert (type == G_TYPE_PARAM);
/* derived param specs
*/
g_param_spec_types_init ();
}
static void
g_param_spec_class_base_init (GParamSpecClass *class)
{
}
static void
g_param_spec_class_base_finalize (GParamSpecClass *class)
{
}
static void
g_param_spec_class_init (GParamSpecClass *class,
gpointer class_data)
{
class->finalize = g_param_spec_finalize;
class->param_init = NULL;
class->param_free_value = NULL;
class->param_validate = NULL;
class->param_values_cmp = NULL;
class->param_copy_value = NULL;
class->collect_type = 0;
class->param_collect_value = NULL;
class->lcopy_type = 0;
class->param_lcopy_value = NULL;
}
static void
g_param_spec_init (GParamSpec *pspec)
{
pspec->name = NULL;
pspec->nick = NULL;
pspec->blurb = NULL;
pspec->flags = 0;
pspec->owner_type = 0;
pspec->qdata = NULL;
pspec->ref_count = 1;
}
static void
g_param_spec_finalize (GParamSpec *pspec)
{
g_datalist_clear (&pspec->qdata);
g_free (pspec->name);
g_free (pspec->nick);
g_free (pspec->blurb);
g_type_free_instance ((GTypeInstance*) pspec);
}
GParamSpec*
g_param_spec_ref (GParamSpec *pspec)
{
g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL);
g_return_val_if_fail (pspec->ref_count > 0, NULL);
pspec->ref_count += 1;
return pspec;
}
void
g_param_spec_unref (GParamSpec *pspec)
{
g_return_if_fail (G_IS_PARAM_SPEC (pspec));
g_return_if_fail (pspec->ref_count > 0);
pspec->ref_count -= 1;
if (pspec->ref_count == 0)
G_PARAM_SPEC_GET_CLASS (pspec)->finalize (pspec);
}
gpointer
g_param_spec_internal (GType param_type,
const gchar *name,
const gchar *nick,
const gchar *blurb,
GParamFlags flags)
{
GParamSpec *pspec;
g_return_val_if_fail (G_TYPE_IS_PARAM (param_type) && param_type != G_TYPE_PARAM, NULL);
g_return_val_if_fail (name != NULL, NULL);
pspec = (gpointer) g_type_create_instance (param_type);
pspec->name = g_strdup (name);
g_strcanon (pspec->name, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-", '-');
pspec->nick = g_strdup (nick ? nick : pspec->name);
pspec->blurb = g_strdup (blurb);
pspec->flags = (flags & G_PARAM_USER_MASK) | (flags & G_PARAM_MASK);
return pspec;
}
gpointer
g_param_spec_get_qdata (GParamSpec *pspec,
GQuark quark)
{
g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL);
return quark ? g_datalist_id_get_data (&pspec->qdata, quark) : NULL;
}
void
g_param_spec_set_qdata (GParamSpec *pspec,
GQuark quark,
gpointer data)
{
g_return_if_fail (G_IS_PARAM_SPEC (pspec));
g_return_if_fail (quark > 0);
g_datalist_id_set_data (&pspec->qdata, quark, data);
}
void
g_param_spec_set_qdata_full (GParamSpec *pspec,
GQuark quark,
gpointer data,
GDestroyNotify destroy)
{
g_return_if_fail (G_IS_PARAM_SPEC (pspec));
g_return_if_fail (quark > 0);
g_datalist_id_set_data_full (&pspec->qdata, quark, data, data ? destroy : NULL);
}
gpointer
g_param_spec_steal_qdata (GParamSpec *pspec,
GQuark quark)
{
g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL);
g_return_val_if_fail (quark > 0, NULL);
return g_datalist_id_remove_no_notify (&pspec->qdata, quark);
}
static guint
param_spec_hash (gconstpointer key_spec)
{
const GParamSpec *key = key_spec;
const gchar *p;
guint h = key->owner_type;
for (p = key->name; *p; p++)
h = (h << 5) - h + *p;
return h;
}
static gint
param_spec_equals (gconstpointer key_spec_1,
gconstpointer key_spec_2)
{
const GParamSpec *key1 = key_spec_1;
const GParamSpec *key2 = key_spec_2;
return (key1->owner_type == key2->owner_type &&
strcmp (key1->name, key2->name) == 0);
}
GHashTable*
g_param_spec_hash_table_new (void)
{
return g_hash_table_new (param_spec_hash, param_spec_equals);
}
void
g_param_spec_hash_table_insert (GHashTable *hash_table,
GParamSpec *pspec,
GType owner_type)
{
g_return_if_fail (hash_table != NULL);
g_return_if_fail (G_IS_PARAM_SPEC (pspec));
g_return_if_fail (pspec->name != NULL);
if (pspec->owner_type != owner_type)
g_return_if_fail (pspec->owner_type == 0);
if (strchr (pspec->name, ':'))
g_warning (G_STRLOC ": parameter name `%s' contains field-delimeter",
pspec->name);
else
{
pspec->owner_type = owner_type;
g_hash_table_insert (hash_table, pspec, pspec);
}
}
void
g_param_spec_hash_table_remove (GHashTable *hash_table,
GParamSpec *pspec)
{
g_return_if_fail (hash_table != NULL);
g_return_if_fail (G_IS_PARAM_SPEC (pspec));
g_assert (g_param_spec_hash_table_lookup (hash_table, pspec->name, pspec->owner_type, FALSE, NULL) != NULL); // FIXME: paranoid
g_hash_table_remove (hash_table, pspec);
g_assert (g_param_spec_hash_table_lookup (hash_table, pspec->name, pspec->owner_type, FALSE, NULL) == NULL); // FIXME: paranoid
pspec->owner_type = 0;
}
GParamSpec*
g_param_spec_hash_table_lookup (GHashTable *hash_table,
const gchar *param_name,
GType owner_type,
gboolean try_ancestors,
const gchar **trailer)
{
GParamSpec *pspec;
GParamSpec key;
gchar *delim;
g_return_val_if_fail (hash_table != NULL, NULL);
g_return_val_if_fail (param_name != NULL, NULL);
key.owner_type = owner_type;
delim = strchr (param_name, ':');
if (delim)
key.name = g_strndup (param_name, delim - param_name);
else
key.name = g_strdup (param_name);
g_strcanon (key.name, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-", '-');
if (trailer)
*trailer = delim;
pspec = g_hash_table_lookup (hash_table, &key);
if (!pspec && try_ancestors)
{
key.owner_type = g_type_parent (key.owner_type);
while (key.owner_type)
{
pspec = g_hash_table_lookup (hash_table, &key);
if (pspec)
break;
key.owner_type = g_type_parent (key.owner_type);
}
}
g_free (key.name);
return pspec;
}

186
gobject/gparam.h Normal file
View File

@ -0,0 +1,186 @@
/* GObject - GLib Type, Object, Parameter and Signal Library
* Copyright (C) 1997, 1998, 1999, 2000 Tim Janik and Red Hat, Inc.
*
* 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 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, write to the
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* gparam.h: GParamSpec base class implementation
*/
#ifndef __G_PARAM_H__
#define __G_PARAM_H__
#include <gobject/gtype.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* --- type macros --- */
#define G_TYPE_IS_PARAM(type) (G_TYPE_FUNDAMENTAL (type) == G_TYPE_PARAM)
#define G_PARAM_SPEC_TYPE(pspec) (G_TYPE_FROM_INSTANCE (pspec))
#define G_PARAM_SPEC_TYPE_NAME(pspec) (g_type_name (G_PARAM_SPEC_TYPE (pspec)))
#define G_PARAM_SPEC(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM, GParamSpec))
#define G_IS_PARAM_SPEC(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM))
#define G_PARAM_SPEC_GET_CLASS(pspec) (G_TYPE_INSTANCE_GET_CLASS ((pspec), G_TYPE_PARAM, GParamSpecClass))
#define G_IS_VALUE(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM))
/* --- flags --- */
typedef enum
{
G_PARAM_READABLE = 1 << 0,
G_PARAM_WRITABLE = 1 << 1,
G_PARAM_MASK = 0x000f,
/* bits in the range 0xfff0 are reserved for 3rd party usage */
G_PARAM_USER_MASK = 0xfff0
} GParamFlags;
/* --- typedefs & structures --- */
typedef struct _GParamSpecClass GParamSpecClass;
typedef struct _GParamSpec GParamSpec;
typedef struct _GValue GValue;
typedef union _GParamCValue GParamCValue;
typedef void (*GValueExchange) (GValue*, GValue*);
struct _GParamSpecClass
{
GTypeClass g_type_class;
void (*finalize) (GParamSpec *pspec);
/* GParam methods */
void (*param_init) (GValue *value,
GParamSpec *pspec);
void (*param_free_value) (GValue *value);
gboolean (*param_validate) (GValue *value,
GParamSpec *pspec);
gint (*param_values_cmp) (const GValue *value1,
const GValue *value2,
GParamSpec *pspec);
void (*param_copy_value) (const GValue *src_value,
GValue *dest_value);
/* varargs functionality (optional) */
guint collect_type;
gchar* (*param_collect_value) (GValue *value,
GParamSpec *pspec,
guint nth_value,
GType *collect_type,
GParamCValue *collect_value);
guint lcopy_type;
gchar* (*param_lcopy_value) (const GValue *value,
GParamSpec *pspec,
guint nth_value,
GType *collect_type,
GParamCValue *collect_value);
};
struct _GParamSpec
{
GTypeInstance g_instance;
gchar *name;
gchar *nick;
gchar *blurb;
GParamFlags flags;
/*< private >*/
GType owner_type;
GData *qdata;
guint ref_count;
};
/* --- prototypes --- */
GParamSpec* g_param_spec_ref (GParamSpec *pspec);
void g_param_spec_unref (GParamSpec *pspec);
gpointer g_param_spec_get_qdata (GParamSpec *pspec,
GQuark quark);
void g_param_spec_set_qdata (GParamSpec *pspec,
GQuark quark,
gpointer data);
void g_param_spec_set_qdata_full (GParamSpec *pspec,
GQuark quark,
gpointer data,
GDestroyNotify destroy);
gpointer g_param_spec_steal_qdata (GParamSpec *pspec,
GQuark quark);
/* --- private --- */
gpointer g_param_spec_internal (GType param_type,
const gchar *name,
const gchar *nick,
const gchar *blurb,
GParamFlags flags);
GHashTable* g_param_spec_hash_table_new (void);
void g_param_spec_hash_table_insert (GHashTable *hash_table,
GParamSpec *pspec,
GType owner_type);
void g_param_spec_hash_table_remove (GHashTable *hash_table,
GParamSpec *pspec);
GParamSpec* g_param_spec_hash_table_lookup (GHashTable *hash_table,
const gchar *param_name,
GType owner_type,
gboolean try_ancestors,
const gchar **trailer);
/* contracts:
*
* class functions may not evaluate param->pspec directly,
* instead, pspec will be passed as argument if required.
*
* void param_init (GParam *param, GParamSpec *pspec):
* initialize param's value to default if pspec is given,
* and to zero-equivalent (a value that doesn't need to be
* free()ed later on) otherwise.
*
* void param_free_value (GParam *param):
* free param's value if required, zero-reinitialization
* of the value is not required. (this class function
* may be NULL for param types that don't need to free
* values, such as ints or floats).
*
* gboolean param_validate (GParam *param, GParamSpec *pspec):
* modify param's value in the least destructive way, so
* that it complies with pspec's requirements (i.e.
* according to minimum/maximum ranges etc...). return
* whether modification was necessary.
*
* gint param_values_cmp (GParam *param1, GParam *param2, GParamSpec*):
* return param1 - param2, i.e. <0 if param1 < param2,
* >0 if param1 > param2, and 0 if they are equal
* (passing pspec is optional, but recommended)
*
* void param_copy_value (GParam *param_src, GParam *param_dest):
* copy value from param_src to param_dest, param_dest is
* already free()d and zero-initialized, so its value can
* simply be overwritten. (may be NULL for memcpy)
*
* gchar* param_collect_value ():
* class function may be NULL.
*
* gchar* param_lcopy_value ():
* class function may be NULL.
*
*/
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __G_PARAM_H__ */

2004
gobject/gparamspecs.c Normal file

File diff suppressed because it is too large Load Diff

335
gobject/gparamspecs.h Normal file
View File

@ -0,0 +1,335 @@
/* GObject - GLib Type, Object, Parameter and Signal Library
* Copyright (C) 1997, 1998, 1999, 2000 Tim Janik and Red Hat, Inc.
*
* 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 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, write to the
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* gparamspecs.h: GLib default param specs
*/
#ifndef __G_PARAMSPECS_H__
#define __G_PARAMSPECS_H__
#include <gobject/gvalue.h>
#include <gobject/genums.h>
#include <gobject/gobject.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* --- type macros --- */
#define G_IS_VALUE_CHAR(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_CHAR))
#define G_IS_PARAM_SPEC_CHAR(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_CHAR))
#define G_PARAM_SPEC_CHAR(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_CHAR, GParamSpecChar))
#define G_IS_VALUE_UCHAR(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_UCHAR))
#define G_IS_PARAM_SPEC_UCHAR(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_UCHAR))
#define G_PARAM_SPEC_UCHAR(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_UCHAR, GParamSpecUChar))
#define G_IS_VALUE_BOOL(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_BOOL))
#define G_IS_PARAM_SPEC_BOOL(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_BOOL))
#define G_PARAM_SPEC_BOOL(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_BOOL, GParamSpecBool))
#define G_IS_VALUE_INT(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_INT))
#define G_IS_PARAM_SPEC_INT(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_INT))
#define G_PARAM_SPEC_INT(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_INT, GParamSpecInt))
#define G_IS_VALUE_UINT(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_UINT))
#define G_IS_PARAM_SPEC_UINT(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_UINT))
#define G_PARAM_SPEC_UINT(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_UINT, GParamSpecUInt))
#define G_IS_VALUE_LONG(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_LONG))
#define G_IS_PARAM_SPEC_LONG(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_LONG))
#define G_PARAM_SPEC_LONG(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_LONG, GParamSpecLong))
#define G_IS_VALUE_ULONG(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_ULONG))
#define G_IS_PARAM_SPEC_ULONG(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_ULONG))
#define G_PARAM_SPEC_ULONG(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_ULONG, GParamSpecULong))
#define G_IS_VALUE_ENUM(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_ENUM))
#define G_IS_PARAM_SPEC_ENUM(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_ENUM))
#define G_PARAM_SPEC_ENUM(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_ENUM, GParamSpecEnum))
#define G_IS_VALUE_FLAGS(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_FLAGS))
#define G_IS_PARAM_SPEC_FLAGS(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_FLAGS))
#define G_PARAM_SPEC_FLAGS(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_FLAGS, GParamSpecFlags))
#define G_IS_VALUE_FLOAT(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_FLOAT))
#define G_IS_PARAM_SPEC_FLOAT(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_FLOAT))
#define G_PARAM_SPEC_FLOAT(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_FLOAT, GParamSpecFloat))
#define G_IS_VALUE_DOUBLE(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_DOUBLE))
#define G_IS_PARAM_SPEC_DOUBLE(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_DOUBLE))
#define G_PARAM_SPEC_DOUBLE(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_DOUBLE, GParamSpecDouble))
#define G_IS_VALUE_STRING(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_STRING))
#define G_IS_PARAM_SPEC_STRING(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_STRING))
#define G_PARAM_SPEC_STRING(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_STRING, GParamSpecString))
#define G_IS_VALUE_OBJECT(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_OBJECT))
#define G_IS_PARAM_SPEC_OBJECT(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_OBJECT))
#define G_PARAM_SPEC_OBJECT(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_OBJECT, GParamSpecObject))
/* --- typedefs & structures --- */
typedef struct _GParamSpecChar GParamSpecChar;
typedef struct _GParamSpecUChar GParamSpecUChar;
typedef struct _GParamSpecBool GParamSpecBool;
typedef struct _GParamSpecInt GParamSpecInt;
typedef struct _GParamSpecUInt GParamSpecUInt;
typedef struct _GParamSpecLong GParamSpecLong;
typedef struct _GParamSpecULong GParamSpecULong;
typedef struct _GParamSpecEnum GParamSpecEnum;
typedef struct _GParamSpecFlags GParamSpecFlags;
typedef struct _GParamSpecFloat GParamSpecFloat;
typedef struct _GParamSpecDouble GParamSpecDouble;
typedef struct _GParamSpecString GParamSpecString;
typedef struct _GParamSpecObject GParamSpecObject;
struct _GParamSpecChar
{
GParamSpec parent_instance;
gint8 minimum;
gint8 maximum;
gint8 default_value;
};
struct _GParamSpecUChar
{
GParamSpec parent_instance;
guint8 minimum;
guint8 maximum;
guint8 default_value;
};
struct _GParamSpecBool
{
GParamSpec parent_instance;
gboolean default_value;
};
struct _GParamSpecInt
{
GParamSpec parent_instance;
gint minimum;
gint maximum;
gint default_value;
};
struct _GParamSpecUInt
{
GParamSpec parent_instance;
guint minimum;
guint maximum;
guint default_value;
};
struct _GParamSpecLong
{
GParamSpec parent_instance;
glong minimum;
glong maximum;
glong default_value;
};
struct _GParamSpecULong
{
GParamSpec parent_instance;
gulong minimum;
gulong maximum;
gulong default_value;
};
struct _GParamSpecEnum
{
GParamSpec parent_instance;
GEnumClass *enum_class;
glong default_value;
};
struct _GParamSpecFlags
{
GParamSpec parent_instance;
GFlagsClass *flags_class;
gulong default_value;
};
struct _GParamSpecFloat
{
GParamSpec parent_instance;
gfloat minimum;
gfloat maximum;
gfloat default_value;
gfloat epsilon;
};
struct _GParamSpecDouble
{
GParamSpec parent_instance;
gdouble minimum;
gdouble maximum;
gdouble default_value;
gdouble epsilon;
};
struct _GParamSpecString
{
GParamSpec parent_instance;
gchar *default_value;
gchar *cset_first;
gchar *cset_nth;
gchar substitutor;
guint null_fold_if_empty : 1;
guint ensure_non_null : 1;
};
struct _GParamSpecObject
{
GParamSpec parent_instance;
GType object_type;
};
/* --- GValue prototypes --- */
void g_value_set_char (GValue *value,
gint8 v_char);
gint8 g_value_get_char (GValue *value);
void g_value_set_uchar (GValue *value,
guint8 v_uchar);
guint8 g_value_get_uchar (GValue *value);
void g_value_set_bool (GValue *value,
gboolean v_bool);
gboolean g_value_get_bool (GValue *value);
void g_value_set_int (GValue *value,
gint v_int);
gint g_value_get_int (GValue *value);
void g_value_set_uint (GValue *value,
guint v_uint);
guint g_value_get_uint (GValue *value);
void g_value_set_long (GValue *value,
glong v_long);
glong g_value_get_long (GValue *value);
void g_value_set_ulong (GValue *value,
gulong v_ulong);
gulong g_value_get_ulong (GValue *value);
void g_value_set_enum (GValue *value,
gint v_enum);
gint g_value_get_enum (GValue *value);
void g_value_set_flags (GValue *value,
guint v_flags);
guint g_value_get_flags (GValue *value);
void g_value_set_float (GValue *value,
gfloat v_float);
gfloat g_value_get_float (GValue *value);
void g_value_set_double (GValue *value,
gdouble v_double);
gdouble g_value_get_double (GValue *value);
void g_value_set_string (GValue *value,
const gchar *v_string);
gchar* g_value_get_string (GValue *value);
gchar* g_value_dup_string (GValue *value);
void g_value_set_object (GValue *value,
GObject *v_object);
GObject* g_value_get_object (GValue *value);
GObject* g_value_dup_object (GValue *value);
/* --- GParamSpec prototypes --- */
GParamSpec* g_param_spec_char (const gchar *name,
const gchar *nick,
const gchar *blurb,
gint8 minimum,
gint8 maximum,
gint8 default_value,
GParamFlags flags);
GParamSpec* g_param_spec_uchar (const gchar *name,
const gchar *nick,
const gchar *blurb,
guint8 minimum,
guint8 maximum,
guint8 default_value,
GParamFlags flags);
GParamSpec* g_param_spec_bool (const gchar *name,
const gchar *nick,
const gchar *blurb,
gboolean default_value,
GParamFlags flags);
GParamSpec* g_param_spec_int (const gchar *name,
const gchar *nick,
const gchar *blurb,
gint minimum,
gint maximum,
gint default_value,
GParamFlags flags);
GParamSpec* g_param_spec_uint (const gchar *name,
const gchar *nick,
const gchar *blurb,
guint minimum,
guint maximum,
guint default_value,
GParamFlags flags);
GParamSpec* g_param_spec_long (const gchar *name,
const gchar *nick,
const gchar *blurb,
glong minimum,
glong maximum,
glong default_value,
GParamFlags flags);
GParamSpec* g_param_spec_ulong (const gchar *name,
const gchar *nick,
const gchar *blurb,
gulong minimum,
gulong maximum,
gulong default_value,
GParamFlags flags);
GParamSpec* g_param_spec_enum (const gchar *name,
const gchar *nick,
const gchar *blurb,
GType enum_type,
gint default_value,
GParamFlags flags);
GParamSpec* g_param_spec_flags (const gchar *name,
const gchar *nick,
const gchar *blurb,
GType flags_type,
guint default_value,
GParamFlags flags);
GParamSpec* g_param_spec_float (const gchar *name,
const gchar *nick,
const gchar *blurb,
gfloat minimum,
gfloat maximum,
gfloat default_value,
GParamFlags flags);
GParamSpec* g_param_spec_double (const gchar *name,
const gchar *nick,
const gchar *blurb,
gdouble minimum,
gdouble maximum,
gdouble default_value,
GParamFlags flags);
GParamSpec* g_param_spec_string (const gchar *name,
const gchar *nick,
const gchar *blurb,
const gchar *default_value,
GParamFlags flags);
GParamSpec* g_param_spec_string_c (const gchar *name,
const gchar *nick,
const gchar *blurb,
const gchar *default_value,
GParamFlags flags);
GParamSpec* g_param_spec_object (const gchar *name,
const gchar *nick,
const gchar *blurb,
GType object_type,
GParamFlags flags);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __G_PARAMSPECS_H__ */

1825
gobject/gtype.c Normal file

File diff suppressed because it is too large Load Diff

304
gobject/gtype.h Normal file
View File

@ -0,0 +1,304 @@
/* GObject - GLib Type, Object, Parameter and Signal Library
* Copyright (C) 1998, 1999, 2000 Tim Janik and Red Hat, Inc.
*
* 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 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, write to the
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __G_TYPE_H__
#define __G_TYPE_H__
extern const char *g_log_domain_gobject;
#include <glib.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* Basic Type Macros
*/
#define G_TYPE_FUNDAMENTAL(type) ((type) & 0xff)
#define G_TYPE_FUNDAMENTAL_MAX (0xff)
#define G_TYPE_DERIVE_ID(ptype, branch_seqno) (G_TYPE_FUNDAMENTAL (ptype) | ((branch_seqno) << 8))
#define G_TYPE_BRANCH_SEQNO(type) ((type) >> 8)
#define G_TYPE_FUNDAMENTAL_LAST ((GType) _g_type_fundamental_last)
/* predefined fundamental and derived types
*/
typedef enum /*< skip >*/
{
/* standard types, introduced by g_type_init() */
G_TYPE_INVALID,
G_TYPE_NONE,
G_TYPE_INTERFACE,
/* GLib type ids */
G_TYPE_ENUM,
G_TYPE_FLAGS,
G_TYPE_PARAM,
G_TYPE_OBJECT,
/* reserved type ids, mail gtk-devel-list@redhat.com for reservations */
G_TYPE_BSE_PROCEDURE,
G_TYPE_GLE_GOBJECT,
/* the following reserved ids should vanish soon */
G_TYPE_GTK_CHAR,
G_TYPE_GTK_UCHAR,
G_TYPE_GTK_BOOL,
G_TYPE_GTK_INT,
G_TYPE_GTK_UINT,
G_TYPE_GTK_LONG,
G_TYPE_GTK_ULONG,
G_TYPE_GTK_FLOAT,
G_TYPE_GTK_DOUBLE,
G_TYPE_GTK_STRING,
G_TYPE_GTK_BOXED,
G_TYPE_GTK_POINTER,
G_TYPE_GTK_SIGNAL,
G_TYPE_LAST_RESERVED_FUNDAMENTAL,
/* derived type ids */
G_TYPE_PARAM_CHAR = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 1),
G_TYPE_PARAM_UCHAR = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 2),
G_TYPE_PARAM_BOOL = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 3),
G_TYPE_PARAM_INT = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 4),
G_TYPE_PARAM_UINT = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 5),
G_TYPE_PARAM_LONG = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 6),
G_TYPE_PARAM_ULONG = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 7),
G_TYPE_PARAM_ENUM = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 8),
G_TYPE_PARAM_FLAGS = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 9),
G_TYPE_PARAM_FLOAT = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 10),
G_TYPE_PARAM_DOUBLE = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 11),
G_TYPE_PARAM_STRING = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 12),
G_TYPE_PARAM_OBJECT = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 13)
} GTypeFundamentals;
/* Type Checking Macros
*/
#define G_TYPE_IS_INTERFACE(type) (G_TYPE_FUNDAMENTAL (type) == G_TYPE_INTERFACE)
#define G_TYPE_IS_CLASSED(type) (g_type_check_flags ((type), G_TYPE_FLAG_CLASSED))
#define G_TYPE_IS_INSTANTIATABLE(type) (g_type_check_flags ((type), G_TYPE_FLAG_INSTANTIATABLE))
#define G_TYPE_IS_DERIVABLE(type) (g_type_check_flags ((type), G_TYPE_FLAG_DERIVABLE))
#define G_TYPE_IS_DEEP_DERIVABLE(type) (g_type_check_flags ((type), G_TYPE_FLAG_DEEP_DERIVABLE))
#define G_TYPE_IS_PARAM(type) (G_TYPE_FUNDAMENTAL (type) == G_TYPE_PARAM)
/* Typedefs
*/
typedef guint32 GType;
typedef struct _GParam GParam;
typedef struct _GTypePlugin GTypePlugin;
typedef struct _GTypePluginVTable GTypePluginVTable;
typedef struct _GTypeClass GTypeClass;
typedef struct _GTypeInterface GTypeInterface;
typedef struct _GTypeInstance GTypeInstance;
typedef struct _GTypeInfo GTypeInfo;
typedef struct _GTypeFundamentalInfo GTypeFundamentalInfo;
typedef struct _GInterfaceInfo GInterfaceInfo;
/* Basic Type Structures
*/
struct _GTypeClass
{
GType g_type;
};
struct _GTypeInstance
{
GTypeClass *g_class;
};
struct _GTypeInterface
{
GType g_type; /* iface type */
GType g_instance_type;
};
/* Casts, Checks And Convenience Macros For Structured Types
*/
#define G_TYPE_CHECK_INSTANCE_CAST(instance, g_type, c_type) (_G_TYPE_CIC ((instance), (g_type), c_type))
#define G_TYPE_CHECK_CLASS_CAST(g_class, g_type, c_type) (_G_TYPE_CCC ((g_class), (g_type), c_type))
#define G_TYPE_CHECK_INSTANCE_TYPE(instance, g_type) (_G_TYPE_CIT ((instance), (g_type)))
#define G_TYPE_CHECK_CLASS_TYPE(g_class, g_type) (_G_TYPE_CCT ((g_class), (g_type)))
#define G_TYPE_INSTANCE_GET_CLASS(instance, g_type, c_type) (_G_TYPE_IGC ((instance), c_type))
#define G_TYPE_FROM_INSTANCE(instance) (G_TYPE_FROM_CLASS (((GTypeInstance*) (instance))->g_class))
#define G_TYPE_FROM_CLASS(g_class) (((GTypeClass*) (g_class))->g_type)
/* --- prototypes --- */
void g_type_init (void);
gchar* g_type_name (GType type);
GQuark g_type_qname (GType type);
GType g_type_from_name (const gchar *name);
GType g_type_parent (GType type);
GType g_type_next_base (GType type,
GType base_type);
gboolean g_type_is_a (GType type,
GType is_a_type);
gboolean g_type_conforms_to (GType type,
GType iface_type);
guint g_type_fundamental_branch_last (GType type);
gpointer g_type_class_ref (GType type);
gpointer g_type_class_peek (GType type);
void g_type_class_unref (gpointer g_class);
gpointer g_type_class_peek_parent (gpointer g_class);
gpointer g_type_interface_peek (gpointer instance_class,
GType iface_type);
/* g_free() the returned arrays */
GType* g_type_children (GType type,
guint *n_children);
GType* g_type_interfaces (GType type,
guint *n_interfaces);
/* per-type *static* data */
void g_type_set_qdata (GType type,
GQuark quark,
gpointer data);
gpointer g_type_get_qdata (GType type,
GQuark quark);
/* --- type registration --- */
typedef void (*GBaseInitFunc) (gpointer g_class);
typedef void (*GBaseFinalizeFunc) (gpointer g_class);
typedef void (*GClassInitFunc) (gpointer g_class,
gpointer class_data);
typedef void (*GClassFinalizeFunc) (gpointer g_class,
gpointer class_data);
typedef void (*GInstanceInitFunc) (GTypeInstance *instance,
gpointer g_class);
typedef void (*GInterfaceInitFunc) (gpointer g_iface,
gpointer iface_data);
typedef void (*GInterfaceFinalizeFunc) (gpointer g_iface,
gpointer iface_data);
typedef gchar* (*GTypeParamCollector) (GParam *param,
guint n_bytes,
guint8 *bytes);
typedef void (*GTypePluginRef) (GTypePlugin *plugin);
typedef void (*GTypePluginUnRef) (GTypePlugin *plugin);
typedef void (*GTypePluginFillTypeInfo) (GTypePlugin *plugin,
GType g_type,
GTypeInfo *info);
typedef void (*GTypePluginFillInterfaceInfo) (GTypePlugin *plugin,
GType interface_type,
GType instance_type,
GInterfaceInfo *info);
struct _GTypePlugin
{
GTypePluginVTable *vtable;
};
struct _GTypePluginVTable
{
GTypePluginRef plugin_ref;
GTypePluginUnRef plugin_unref;
GTypePluginFillTypeInfo complete_type_info;
GTypePluginFillInterfaceInfo complete_interface_info;
};
typedef enum /*< skip >*/
{
G_TYPE_FLAG_CLASSED = (1 << 0),
G_TYPE_FLAG_INSTANTIATABLE = (1 << 1),
G_TYPE_FLAG_DERIVABLE = (1 << 2),
G_TYPE_FLAG_DEEP_DERIVABLE = (1 << 3)
} GTypeFlags;
struct _GTypeInfo
{
/* interface types, classed types, instantiated types */
guint16 class_size;
GBaseInitFunc base_init;
GBaseFinalizeFunc base_finalize;
/* classed types, instantiated types */
GClassInitFunc class_init;
GClassFinalizeFunc class_finalize;
gconstpointer class_data;
/* instantiated types */
guint16 instance_size;
guint16 n_preallocs;
GInstanceInitFunc instance_init;
};
struct _GTypeFundamentalInfo
{
GTypeFlags type_flags;
guint n_collect_bytes;
GTypeParamCollector param_collector;
};
struct _GInterfaceInfo
{
GInterfaceInitFunc interface_init;
GInterfaceFinalizeFunc interface_finalize;
gpointer interface_data;
};
GType g_type_register_static (GType parent_type,
const gchar *type_name,
const GTypeInfo *info);
GType g_type_register_dynamic (GType parent_type,
const gchar *type_name,
GTypePlugin *plugin);
GType g_type_register_fundamental (GType type_id,
const gchar *type_name,
const GTypeFundamentalInfo *finfo,
const GTypeInfo *info);
void g_type_add_interface_static (GType instance_type,
GType interface_type,
GInterfaceInfo *info);
void g_type_add_interface_dynamic (GType instance_type,
GType interface_type,
GTypePlugin *plugin);
/* --- implementation details --- */
gboolean g_type_class_is_a (GTypeClass *g_class,
GType is_a_type);
GTypeClass* g_type_check_class_cast (GTypeClass *g_class,
GType is_a_type);
GTypeInstance* g_type_check_instance_cast (GTypeInstance *instance,
GType iface_type);
gboolean g_type_instance_conforms_to (GTypeInstance *instance,
GType iface_type);
gboolean g_type_check_flags (GType type,
GTypeFlags flags);
gboolean g_type_is_dynamic (GType type,
GTypeFlags flags);
GTypeInstance* g_type_create_instance (GType type);
void g_type_free_instance (GTypeInstance *instance);
#ifndef G_DISABLE_CAST_CHECKS
# define _G_TYPE_CIC(ip, gt, ct) \
((ct*) g_type_check_instance_cast ((GTypeInstance*) ip, gt))
# define _G_TYPE_CCC(cp, gt, ct) \
((ct*) g_type_check_class_cast ((GTypeClass*) cp, gt))
#else /* G_DISABLE_CAST_CHECKS */
# define _G_TYPE_CIC(ip, gt, ct) ((ct*) ip)
# define _G_TYPE_CCC(cp, gt, ct) ((ct*) cp)
#endif /* G_DISABLE_CAST_CHECKS */
#define _G_TYPE_IGC(ip, ct) ((ct*) (((GTypeInstance*) ip)->g_class))
#define _G_TYPE_CIT(ip, gt) (g_type_instance_conforms_to ((GTypeInstance*) ip, gt))
#define _G_TYPE_CCT(cp, gt) (g_type_class_is_a ((GTypeClass*) cp, gt))
extern GType _g_type_fundamental_last;
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __G_TYPE_H__ */

374
gobject/gvalue.c Normal file
View File

@ -0,0 +1,374 @@
/* GObject - GLib Type, Object, Parameter and Signal Library
* Copyright (C) 1997, 1998, 1999, 2000 Tim Janik and Red Hat, Inc.
*
* 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 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, write to the
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "gvalue.h"
/* --- defines --- */
#define G_PARAM_SPEC_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), G_TYPE_PARAM, GParamSpecClass))
/* --- typedefs & structures --- */
typedef struct
{
GType value_type1;
GType value_type2;
GValueExchange func;
GType first_type;
} ExchangeEntry;
/* --- variables --- */
static GHashTable *param_exchange_ht = NULL;
/* --- functions --- */
void
g_value_init (GValue *value,
GType g_type)
{
GParamSpecClass *pclass;
g_return_if_fail (value != NULL);
g_return_if_fail (G_VALUE_TYPE (value) == 0);
g_type = g_type_next_base (g_type, G_TYPE_PARAM);
g_return_if_fail (G_TYPE_IS_VALUE (g_type));
memset (value, 0, sizeof (*value));
value->g_type = g_type;
pclass = g_type_class_ref (G_VALUE_TYPE (value));
pclass->param_init (value, NULL);
g_type_class_unref (pclass);
}
void
g_value_init_default (GValue *value,
GParamSpec *pspec)
{
g_return_if_fail (value != NULL);
g_return_if_fail (G_VALUE_TYPE (value) == 0);
g_return_if_fail (G_IS_PARAM_SPEC (pspec));
memset (value, 0, sizeof (*value));
value->g_type = g_type_next_base (G_PARAM_SPEC_TYPE (pspec), G_TYPE_PARAM);
G_PARAM_SPEC_GET_CLASS (pspec)->param_init (value, pspec);
}
gboolean
g_value_validate (GValue *value,
GParamSpec *pspec)
{
g_return_val_if_fail (G_IS_VALUE (value), FALSE);
g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), FALSE);
g_return_val_if_fail (g_type_is_a (G_PARAM_SPEC_TYPE (pspec), G_VALUE_TYPE (value)), FALSE);
if (G_PARAM_SPEC_GET_CLASS (pspec)->param_validate)
{
GValue oval = *value;
if (G_PARAM_SPEC_GET_CLASS (pspec)->param_validate (value, pspec) ||
memcmp (&oval.data, &value->data, sizeof (oval.data)))
return TRUE;
}
return FALSE;
}
gboolean
g_value_defaults (const GValue *value,
GParamSpec *pspec)
{
GValue dflt_value = { 0, };
gboolean defaults;
g_return_val_if_fail (G_IS_VALUE (value), FALSE);
g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), FALSE);
g_return_val_if_fail (g_type_is_a (G_PARAM_SPEC_TYPE (pspec), G_VALUE_TYPE (value)), FALSE);
dflt_value.g_type = g_type_next_base (G_PARAM_SPEC_TYPE (pspec), G_TYPE_PARAM);
G_PARAM_SPEC_GET_CLASS (pspec)->param_init (&dflt_value, pspec);
defaults = g_values_cmp (value, &dflt_value, pspec) == 0;
g_value_unset (&dflt_value);
return defaults;
}
void
g_value_set_default (GValue *value,
GParamSpec *pspec)
{
GValue tmp_value = { 0, };
g_return_if_fail (G_IS_VALUE (value));
g_return_if_fail (G_IS_PARAM_SPEC (pspec));
g_return_if_fail (g_type_is_a (G_PARAM_SPEC_TYPE (pspec), G_VALUE_TYPE (value)));
/* retrive default value */
tmp_value.g_type = g_type_next_base (G_PARAM_SPEC_TYPE (pspec), G_TYPE_PARAM);
G_PARAM_SPEC_GET_CLASS (pspec)->param_init (&tmp_value, pspec);
/* set default value */
g_values_exchange (&tmp_value, value);
g_value_unset (&tmp_value);
}
gint
g_values_cmp (const GValue *value1,
const GValue *value2,
GParamSpec *pspec)
{
GParamSpecClass *pclass;
gint cmp;
/* param_values_cmp() effectively does: value1 - value2
* so the return values are:
* -1) value1 < value2
* 0) value1 == value2
* 1) value1 > value2
*/
g_return_val_if_fail (G_IS_VALUE (value1), 0);
g_return_val_if_fail (G_IS_VALUE (value2), 0);
g_return_val_if_fail (G_VALUE_TYPE (value1) == G_VALUE_TYPE (value2), 0);
if (pspec)
{
g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), 0);
g_return_val_if_fail (g_type_is_a (G_PARAM_SPEC_TYPE (pspec), G_VALUE_TYPE (value1)), FALSE);
}
pclass = g_type_class_ref (G_VALUE_TYPE (value1));
cmp = pclass->param_values_cmp (value1, value2, pspec);
g_type_class_unref (pclass);
return CLAMP (cmp, -1, 1);
}
void
g_value_copy (const GValue *src_value,
GValue *dest_value)
{
g_return_if_fail (G_IS_VALUE (src_value));
g_return_if_fail (G_IS_VALUE (dest_value));
g_return_if_fail (G_VALUE_TYPE (src_value) == G_VALUE_TYPE (dest_value));
if (src_value != dest_value)
{
GParamSpecClass *pclass = g_type_class_ref (G_VALUE_TYPE (src_value));
/* make sure dest_value's value is free()d and zero initialized */
g_value_reset (dest_value);
if (pclass->param_copy_value)
pclass->param_copy_value (src_value, dest_value);
else
memcpy (&dest_value->data, &src_value->data, sizeof (src_value->data));
g_type_class_unref (pclass);
}
}
void
g_value_unset (GValue *value)
{
GParamSpecClass *pclass;
g_return_if_fail (G_IS_VALUE (value));
pclass = g_type_class_ref (G_VALUE_TYPE (value));
if (pclass->param_free_value)
pclass->param_free_value (value);
memset (value, 0, sizeof (*value));
g_type_class_unref (pclass);
}
void
g_value_reset (GValue *value)
{
GParamSpecClass *pclass;
GType g_type;
g_return_if_fail (G_IS_VALUE (value));
g_type = G_VALUE_TYPE (value);
pclass = g_type_class_ref (g_type);
if (pclass->param_free_value)
pclass->param_free_value (value);
memset (value, 0, sizeof (*value));
value->g_type = g_type;
pclass->param_init (value, NULL);
g_type_class_unref (pclass);
}
static gint
exchange_entries_equal (gconstpointer v1,
gconstpointer v2)
{
const ExchangeEntry *entry1 = v1;
const ExchangeEntry *entry2 = v2;
return (entry1->value_type1 == entry2->value_type1 &&
entry1->value_type2 == entry2->value_type2);
}
static guint
exchange_entry_hash (gconstpointer key)
{
const ExchangeEntry *entry = key;
return entry->value_type1 ^ entry->value_type2;
}
static void
value_exchange_memcpy (GValue *value1,
GValue *value2)
{
GValue tmp_value;
memcpy (&tmp_value.data, &value1->data, sizeof (value1->data));
memcpy (&value1->data, &value2->data, sizeof (value1->data));
memcpy (&value2->data, &tmp_value.data, sizeof (value2->data));
}
static inline GValueExchange
exchange_func_lookup (GType value_type1,
GType value_type2,
gboolean *need_swap)
{
if (value_type1 == value_type2)
return value_exchange_memcpy;
else
{
ExchangeEntry entry, *ret;
entry.value_type1 = MIN (value_type1, value_type2);
entry.value_type2 = MAX (value_type1, value_type2);
ret = g_hash_table_lookup (param_exchange_ht, &entry);
if (ret)
{
if (need_swap)
*need_swap = ret->first_type == value_type1;
return ret->func;
}
}
return NULL;
}
void
g_value_register_exchange_func (GType value_type1,
GType value_type2,
GValueExchange func)
{
GType type1, type2;
g_return_if_fail (G_TYPE_IS_VALUE (value_type1));
g_return_if_fail (G_TYPE_IS_VALUE (value_type2));
g_return_if_fail (func != NULL);
type1 = g_type_next_base (value_type1, G_TYPE_PARAM);
type2 = g_type_next_base (value_type2, G_TYPE_PARAM);
if (param_exchange_ht && exchange_func_lookup (type1, type2, NULL))
g_warning (G_STRLOC ": cannot re-register param value exchange function "
"for `%s' and `%s'",
g_type_name (type1),
g_type_name (type2));
else
{
ExchangeEntry *entry = g_new (ExchangeEntry, 1);
if (!param_exchange_ht)
param_exchange_ht = g_hash_table_new (exchange_entry_hash, exchange_entries_equal);
entry->value_type1 = MIN (type1, type2);
entry->value_type2 = MAX (type1, type2);
entry->func = func;
entry->first_type = type1;
g_hash_table_insert (param_exchange_ht, entry, entry);
}
}
gboolean
g_value_types_exchangable (GType value_type1,
GType value_type2)
{
GType type1, type2;
g_return_val_if_fail (G_TYPE_IS_VALUE (value_type1), FALSE);
g_return_val_if_fail (G_TYPE_IS_VALUE (value_type2), FALSE);
type1 = g_type_next_base (value_type1, G_TYPE_PARAM);
type2 = g_type_next_base (value_type2, G_TYPE_PARAM);
return exchange_func_lookup (type1, type2, NULL) != NULL;
}
gboolean
g_values_exchange (GValue *value1,
GValue *value2)
{
g_return_val_if_fail (G_IS_VALUE (value1), FALSE);
g_return_val_if_fail (G_IS_VALUE (value2), FALSE);
if (value1 != value2)
{
GType type1 = g_type_next_base (G_VALUE_TYPE (value1), G_TYPE_PARAM);
GType type2 = g_type_next_base (G_VALUE_TYPE (value2), G_TYPE_PARAM);
gboolean need_swap;
GValueExchange value_exchange = exchange_func_lookup (type1,
type2,
&need_swap);
if (value_exchange)
{
if (need_swap)
value_exchange (value2, value1);
else
value_exchange (value1, value2);
}
return value_exchange != NULL;
}
return TRUE;
}
gboolean
g_value_convert (const GValue *src_value,
GValue *dest_value)
{
gboolean success = TRUE;
g_return_val_if_fail (G_IS_VALUE (src_value), FALSE);
g_return_val_if_fail (G_IS_VALUE (dest_value), FALSE);
if (src_value != dest_value)
{
GValue tmp_value = { 0, };
g_value_init (&tmp_value, G_VALUE_TYPE (src_value));
g_value_copy (src_value, &tmp_value);
success = g_values_exchange (&tmp_value, dest_value);
g_value_unset (&tmp_value);
}
return success;
}

92
gobject/gvalue.h Normal file
View File

@ -0,0 +1,92 @@
/* GObject - GLib Type, Object, Parameter and Signal Library
* Copyright (C) 1997, 1998, 1999, 2000 Tim Janik and Red Hat, Inc.
*
* 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 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, write to the
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* gvalue.h: generic GValue functions
*/
#ifndef __G_VALUE_H__
#define __G_VALUE_H__
#include <gobject/gparam.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* --- type macros --- */
#define G_TYPE_IS_VALUE(type) (G_TYPE_FUNDAMENTAL (type) == G_TYPE_PARAM)
#define G_IS_VALUE(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM))
#define G_VALUE_TYPE(value) (G_TYPE_FROM_CLASS (value))
#define G_VALUE_TYPE_NAME(value) (g_type_name (G_VALUE_TYPE (value)))
/* --- typedefs & structures --- */
/* typedef struct _GValue GValue; */
struct _GValue
{
GType g_type; /* param value type */
union {
gint v_int;
guint v_uint;
glong v_long;
gulong v_ulong;
gfloat v_float;
gdouble v_double;
gpointer v_pointer;
} data[4];
};
/* --- prototypes --- */
void g_value_init (GValue *value,
GType g_type);
void g_value_init_default (GValue *value,
GParamSpec *pspec);
gboolean g_value_validate (GValue *value,
GParamSpec *pspec);
gboolean g_value_defaults (const GValue *value,
GParamSpec *pspec);
void g_value_set_default (GValue *value,
GParamSpec *pspec);
gint g_values_cmp (const GValue *value1,
const GValue *value2,
GParamSpec *pspec);
void g_value_copy (const GValue *src_value,
GValue *dest_value);
gboolean g_value_convert (const GValue *src_value,
GValue *dest_value);
gboolean g_values_exchange (GValue *value1,
GValue *value2);
void g_value_reset (GValue *value);
void g_value_unset (GValue *value);
/* --- implementation bits --- */
gboolean g_value_types_exchangable (GType value_type1,
GType value_type2);
void g_value_register_exchange_func (GType value_type1,
GType value_type2,
GValueExchange func);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __G_VALUE_H__ */

174
gobject/gvaluecollector.h Normal file
View File

@ -0,0 +1,174 @@
/* GObject - GLib Type, Object, Parameter and Signal Library
* Copyright (C) 1998, 1999, 2000 Tim Janik and Red Hat, Inc.
*
* 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 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, write to the
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* gvaluecollector.h: GValue varargs stubs
*/
#ifndef __G_VALUE_COLLECTOR_H__
#define __G_VALUE_COLLECTOR_H__
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* we may want to add aggregate types here some day, if requested
* by users. the basic C types are covered already, everything
* smaller than an int is promoted to an integer and floats are
* always promoted to doubles for varargs call constructions.
*/
enum /*< skip >*/
{
G_VALUE_COLLECT_NONE,
G_VALUE_COLLECT_INT,
G_VALUE_COLLECT_LONG,
G_VALUE_COLLECT_DOUBLE,
G_VALUE_COLLECT_POINTER
};
union _GParamCValue
{
gint v_int;
glong v_long;
gdouble v_double;
gpointer v_pointer;
};
/* G_PARAM_COLLECT_VALUE() collects a parameter's variable arguments
* from a va_list. we have to implement the varargs collection as a
* macro, because on some systems va_list variables cannot be passed
* by reference.
* param_value is supposed to be initialized according to the param
* type to be collected.
* the param_spec argument is optional, but probably needed by most
* param class' param_collect_value() implementations.
* var_args is the va_list variable and may be evaluated multiple times.
* __error is a gchar** variable that will be modified to hold a g_new()
* allocated error messages if something fails.
*/
#define G_PARAM_COLLECT_VALUE(param_value, param_spec, var_args, __error) \
G_STMT_START { \
GValue *_value = (param_value); \
GParamSpecClass *_pclass = g_type_class_ref (_value->g_type); \
GParamSpec *_pspec = (param_spec); \
gchar *_error_msg = NULL; \
guint _collect_type = _pclass->collect_type; \
guint _nth_value = 0; \
\
if (_pspec) \
g_param_spec_ref (_pspec); \
g_value_reset (_value); \
while (_collect_type && !_error_msg) \
{ \
GParamCValue _cvalue; \
\
memset (&_cvalue, 0, sizeof (_cvalue)); \
switch (_collect_type) \
{ \
case G_VALUE_COLLECT_INT: \
_cvalue.v_int = va_arg ((var_args), gint); \
break; \
case G_VALUE_COLLECT_LONG: \
_cvalue.v_long = va_arg ((var_args), glong); \
break; \
case G_VALUE_COLLECT_DOUBLE: \
_cvalue.v_double = va_arg ((var_args), gdouble); \
break; \
case G_VALUE_COLLECT_POINTER: \
_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_PARAM_COLLECT_VALUE()"); \
continue; \
} \
_error_msg = _pclass->param_collect_value (_value, \
_pspec, \
_nth_value++, \
&_collect_type, \
&_cvalue); \
} \
*(__error) = _error_msg; \
if (_pspec) \
g_param_spec_unref (_pspec); \
g_type_class_unref (_pclass); \
} G_STMT_END
/* G_PARAM_LCOPY_VALUE() collects a parameter's variable argument
* locations from a va_list. usage is analogous to G_PARAM_COLLECT_VALUE().
*/
#define G_PARAM_LCOPY_VALUE(param_value, param_spec, var_args, __error) \
G_STMT_START { \
GValue *_value = (param_value); \
GParamSpecClass *_pclass = g_type_class_ref (_value->g_type); \
GParamSpec *_pspec = (param_spec); \
gchar *_error_msg = NULL; \
guint _lcopy_type = _pclass->lcopy_type; \
guint _nth_value = 0; \
\
if (_pspec) \
g_param_spec_ref (_pspec); \
while (_lcopy_type && !_error_msg) \
{ \
GParamCValue _cvalue; \
\
memset (&_cvalue, 0, sizeof (_cvalue)); \
switch (_lcopy_type) \
{ \
case G_VALUE_COLLECT_INT: \
_cvalue.v_int = va_arg ((var_args), gint); \
break; \
case G_VALUE_COLLECT_LONG: \
_cvalue.v_long = va_arg ((var_args), glong); \
break; \
case G_VALUE_COLLECT_DOUBLE: \
_cvalue.v_double = va_arg ((var_args), gdouble); \
break; \
case G_VALUE_COLLECT_POINTER: \
_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_PARAM_LCOPY_VALUE()"); \
continue; \
} \
_error_msg = _pclass->param_lcopy_value (_value, \
_pspec, \
_nth_value++, \
&_lcopy_type, \
&_cvalue); \
} \
*(__error) = _error_msg; \
if (_pspec) \
g_param_spec_unref (_pspec); \
g_type_class_unref (_pclass); \
} G_STMT_END
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __G_VALUE_COLLECTOR_H__ */