define gstring in terms of gchar*. this typedef reflects the type name of
authorTim Janik <timj@gtk.org>
Sat, 24 Jun 2000 22:30:10 +0000 (22:30 +0000)
committerTim Janik <timj@src.gnome.org>
Sat, 24 Jun 2000 22:30:10 +0000 (22:30 +0000)
Fri Jun 23 17:20:26 2000  Tim Janik  <timj@gtk.org>

        * glib.h: define gstring in terms of gchar*. this typedef reflects
        the type name of the primitive G_TYPE_STRING in the gobject module.

Sat Jun 24 23:03:04 2000  Tim Janik  <timj@gtk.org>

        * gtype.[hc]: provide G_TYPE_CHAR, G_TYPE_UCHAR, G_TYPE_BOOLEAN,
        G_TYPE_INT, G_TYPE_UINT, G_TYPE_LONG, G_TYPE_ULONG, G_TYPE_FLOAT,
        G_TYPE_DOUBLE and G_TYPE_STRING fundamental types.
        added a GTypeValueTable* pointer to GTypeInfo structure for types
        to implement GValue handling functions.
        GTypeValueTable contains the following members:
          value_init(): initialize a GValue structure.
          value_free(): free GValue structure contents (optional).
          value_copy(): copy one GValue contents to another GValue structure of
          collect_type: varargs collection type for the first variable argument
          to be collected by collect_value().
          collect_value(): variable arguments collection function (optional).
          lcopy_type: varargs collection type for the first variable argument
          to be location copyied by lcopy_value().
          lcopy_value(): variable arguments location copy function (optional).
        g_type_value_table_peek(): new function to retrive the GTypeValueTable*
        for a type node. ValueTables get inherited from parent types, unless
        overridden through the GTypeInfo structure. internally, GTypeValueTable
        support means an added overhead of one pointer per static or used
        dynamic type node.
        g_type_add_class_cache_func(): provide a cache_func/data pair to be
        called  prior to a type nodes last_unref() function, this can be used
        to prevent premature class destruction. multiple installed cache_func()
        will be chained upon last_unref() untill one of them returns TRUE.
        the cache_func()s have to check the type id passed in to figure whether
        they actually wants to cache the class of this type (since any types are
        routed through the cache_func() chain).
        g_type_remove_class_cache_func(): remove a previously installed
        cache_func/data pair. the cache maintained by this function has to be
        clear when calling g_type_remove_class_cache_func() to avoid leaks.
        g_type_class_unref_uncached(): class unref function for cache_func()
        implementations, unreferences a class omitting the cache chain (and
        therefore unref->cache->unref->... loops).

        * gvaluetypes.[hc]: provide the value setters/getters for the primitive
        fundamental types boolean, char, uchar, int, uint, long, ulong, float,
        double and string.

        * gvalue.[hc]: provide G_TYPE_IS_VALUE() in terms of whether a
        GTypeValueTable is provided for this type.
        removed g_value_init_default(), g_value_validate(), g_value_defaults(),
        g_value_set_default() and g_values_cmp() as these are supplied by the
        GParamSpec API now.
        moved g_values_exchange() into the "implementation details" section,
        since it just provides the underlying functionality for
        g_value_convert().

        * gvaluecollector.h: renamed the varargs value container from
        GParamCValue to GTypeCValue as the value collection methods are
        supplied by the type system now.
        G_PARAM_COLLECT_VALUE() and G_PARAM_LCOPY_VALUE() got renamed to
        G_VALUE_COLLECT() and G_VALUE_LCOPY() and operate without a
        GParamSpec structure now.

        * genums.h: macros cleanups/fixes.

        * genum.c: provide G_TYPE_ENUM and G_TYPE_FLAGS type
        and assorted g_value_{s|g}et_{enum|flags}() implementations.

        * gobject.[hc]:
        provide G_IS_VALUE_OBJECT(), G_TYPE_OBJECT ValueTable methods
        and g_value_{s|g}et_object().

        * gparam.[hc]: reduced class to value_set_default(),
        value_validate() and values_cmp(). also parameters now need to fill
        in a GType value_type; field to indicate the GValue type they
        are handling. provide g_param_value_set_default(),
        g_param_value_defaults(), g_param_value_validate() and
        g_param_values_cmp().

        * gparamspecs.[hc]: got rid of the g_value_* functions and
        the G_IS_VALUE_* macros. adapted param spec implementations
        according to the GParamSpecClass changes.

29 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-12
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
glib-object.h
glib.h
glib/glib-object.h
glib/glib.h
gobject/ChangeLog
gobject/Makefile.am
gobject/genums.c
gobject/genums.h
gobject/gobject.c
gobject/gobject.h
gobject/gparam.c
gobject/gparam.h
gobject/gparamspecs.c
gobject/gparamspecs.h
gobject/gtype.c
gobject/gtype.h
gobject/gvalue.c
gobject/gvalue.h
gobject/gvaluecollector.h
gobject/gvaluetypes.c [new file with mode: 0644]
gobject/gvaluetypes.h [new file with mode: 0644]

index 762650395db7fe0fd76ebfd181e3fedaa3760fad..92a9f8027a9a8cf7af76b0a4f106ec96b6f50acb 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Fri Jun 23 17:20:26 2000  Tim Janik  <timj@gtk.org>
+
+       * glib.h: define gstring in terms of gchar*. this typedef reflects
+       the type name of the primitive G_TYPE_STRING in the gobject module.
+
 Wed Jun 21 12:09:03 2000  Owen Taylor  <otaylor@redhat.com>
 
        * gunicode.h gutf8.c guniprop.c gunidecomp.[ch] gunichartables.h
index 762650395db7fe0fd76ebfd181e3fedaa3760fad..92a9f8027a9a8cf7af76b0a4f106ec96b6f50acb 100644 (file)
@@ -1,3 +1,8 @@
+Fri Jun 23 17:20:26 2000  Tim Janik  <timj@gtk.org>
+
+       * glib.h: define gstring in terms of gchar*. this typedef reflects
+       the type name of the primitive G_TYPE_STRING in the gobject module.
+
 Wed Jun 21 12:09:03 2000  Owen Taylor  <otaylor@redhat.com>
 
        * gunicode.h gutf8.c guniprop.c gunidecomp.[ch] gunichartables.h
index 762650395db7fe0fd76ebfd181e3fedaa3760fad..92a9f8027a9a8cf7af76b0a4f106ec96b6f50acb 100644 (file)
@@ -1,3 +1,8 @@
+Fri Jun 23 17:20:26 2000  Tim Janik  <timj@gtk.org>
+
+       * glib.h: define gstring in terms of gchar*. this typedef reflects
+       the type name of the primitive G_TYPE_STRING in the gobject module.
+
 Wed Jun 21 12:09:03 2000  Owen Taylor  <otaylor@redhat.com>
 
        * gunicode.h gutf8.c guniprop.c gunidecomp.[ch] gunichartables.h
index 762650395db7fe0fd76ebfd181e3fedaa3760fad..92a9f8027a9a8cf7af76b0a4f106ec96b6f50acb 100644 (file)
@@ -1,3 +1,8 @@
+Fri Jun 23 17:20:26 2000  Tim Janik  <timj@gtk.org>
+
+       * glib.h: define gstring in terms of gchar*. this typedef reflects
+       the type name of the primitive G_TYPE_STRING in the gobject module.
+
 Wed Jun 21 12:09:03 2000  Owen Taylor  <otaylor@redhat.com>
 
        * gunicode.h gutf8.c guniprop.c gunidecomp.[ch] gunichartables.h
index 762650395db7fe0fd76ebfd181e3fedaa3760fad..92a9f8027a9a8cf7af76b0a4f106ec96b6f50acb 100644 (file)
@@ -1,3 +1,8 @@
+Fri Jun 23 17:20:26 2000  Tim Janik  <timj@gtk.org>
+
+       * glib.h: define gstring in terms of gchar*. this typedef reflects
+       the type name of the primitive G_TYPE_STRING in the gobject module.
+
 Wed Jun 21 12:09:03 2000  Owen Taylor  <otaylor@redhat.com>
 
        * gunicode.h gutf8.c guniprop.c gunidecomp.[ch] gunichartables.h
index 762650395db7fe0fd76ebfd181e3fedaa3760fad..92a9f8027a9a8cf7af76b0a4f106ec96b6f50acb 100644 (file)
@@ -1,3 +1,8 @@
+Fri Jun 23 17:20:26 2000  Tim Janik  <timj@gtk.org>
+
+       * glib.h: define gstring in terms of gchar*. this typedef reflects
+       the type name of the primitive G_TYPE_STRING in the gobject module.
+
 Wed Jun 21 12:09:03 2000  Owen Taylor  <otaylor@redhat.com>
 
        * gunicode.h gutf8.c guniprop.c gunidecomp.[ch] gunichartables.h
index 762650395db7fe0fd76ebfd181e3fedaa3760fad..92a9f8027a9a8cf7af76b0a4f106ec96b6f50acb 100644 (file)
@@ -1,3 +1,8 @@
+Fri Jun 23 17:20:26 2000  Tim Janik  <timj@gtk.org>
+
+       * glib.h: define gstring in terms of gchar*. this typedef reflects
+       the type name of the primitive G_TYPE_STRING in the gobject module.
+
 Wed Jun 21 12:09:03 2000  Owen Taylor  <otaylor@redhat.com>
 
        * gunicode.h gutf8.c guniprop.c gunidecomp.[ch] gunichartables.h
index 762650395db7fe0fd76ebfd181e3fedaa3760fad..92a9f8027a9a8cf7af76b0a4f106ec96b6f50acb 100644 (file)
@@ -1,3 +1,8 @@
+Fri Jun 23 17:20:26 2000  Tim Janik  <timj@gtk.org>
+
+       * glib.h: define gstring in terms of gchar*. this typedef reflects
+       the type name of the primitive G_TYPE_STRING in the gobject module.
+
 Wed Jun 21 12:09:03 2000  Owen Taylor  <otaylor@redhat.com>
 
        * gunicode.h gutf8.c guniprop.c gunidecomp.[ch] gunichartables.h
index 14f54aba6f3874283145b508be7d77704a93de47..9336241d027ad7f45ac445069b40f9269eafb1e6 100644 (file)
@@ -23,6 +23,7 @@
 #include       <gobject/gtype.h>
 #include       <gobject/genums.h>
 #include       <gobject/gvalue.h>
+#include       <gobject/gvaluetypes.h>
 #include       <gobject/gparam.h>
 #include       <gobject/gparamspecs.h>
 #include       <gobject/gobject.h>
diff --git a/glib.h b/glib.h
index 952014e40de6e98696b94ca61b24c92f35ef57c6..7baeb485f4753864a4d22aea7284d72bd396f363 100644 (file)
--- a/glib.h
+++ b/glib.h
@@ -500,6 +500,7 @@ typedef short  gshort;
 typedef long   glong;
 typedef int    gint;
 typedef gint   gboolean;
+typedef gchar* gstring;
 
 typedef unsigned char  guchar;
 typedef unsigned short gushort;
index 14f54aba6f3874283145b508be7d77704a93de47..9336241d027ad7f45ac445069b40f9269eafb1e6 100644 (file)
@@ -23,6 +23,7 @@
 #include       <gobject/gtype.h>
 #include       <gobject/genums.h>
 #include       <gobject/gvalue.h>
+#include       <gobject/gvaluetypes.h>
 #include       <gobject/gparam.h>
 #include       <gobject/gparamspecs.h>
 #include       <gobject/gobject.h>
index 952014e40de6e98696b94ca61b24c92f35ef57c6..7baeb485f4753864a4d22aea7284d72bd396f363 100644 (file)
@@ -500,6 +500,7 @@ typedef short  gshort;
 typedef long   glong;
 typedef int    gint;
 typedef gint   gboolean;
+typedef gchar* gstring;
 
 typedef unsigned char  guchar;
 typedef unsigned short gushort;
index 2c6c318404f28c94182a8e05d1b209c29e5e42c6..0d0ea87a926bca4d1cfc6040254502041d4fb823 100644 (file)
@@ -1,3 +1,79 @@
+Sat Jun 24 23:03:04 2000  Tim Janik  <timj@gtk.org>
+
+       * gtype.[hc]: provide G_TYPE_CHAR, G_TYPE_UCHAR, G_TYPE_BOOLEAN,
+       G_TYPE_INT, G_TYPE_UINT, G_TYPE_LONG, G_TYPE_ULONG, G_TYPE_FLOAT,
+       G_TYPE_DOUBLE and G_TYPE_STRING fundamental types.
+       added a GTypeValueTable* pointer to GTypeInfo structure for types
+       to implement GValue handling functions.
+       GTypeValueTable contains the following members:
+         value_init(): initialize a GValue structure.
+         value_free(): free GValue structure contents (optional).
+         value_copy(): copy one GValue contents to another GValue structure of
+         collect_type: varargs collection type for the first variable argument
+         to be collected by collect_value().
+         collect_value(): variable arguments collection function (optional).
+         lcopy_type: varargs collection type for the first variable argument
+         to be location copyied by lcopy_value().
+         lcopy_value(): variable arguments location copy function (optional).
+       g_type_value_table_peek(): new function to retrive the GTypeValueTable*
+       for a type node. ValueTables get inherited from parent types, unless
+       overridden through the GTypeInfo structure. internally, GTypeValueTable
+       support means an added overhead of one pointer per static or used
+       dynamic type node.
+       g_type_add_class_cache_func(): provide a cache_func/data pair to be
+       called  prior to a type nodes last_unref() function, this can be used
+       to prevent premature class destruction. multiple installed cache_func()
+       will be chained upon last_unref() untill one of them returns TRUE.
+       the cache_func()s have to check the type id passed in to figure whether
+       they actually wants to cache the class of this type (since any types are
+       routed through the cache_func() chain).
+       g_type_remove_class_cache_func(): remove a previously installed
+       cache_func/data pair. the cache maintained by this function has to be
+       clear when calling g_type_remove_class_cache_func() to avoid leaks.
+       g_type_class_unref_uncached(): class unref function for cache_func()
+       implementations, unreferences a class omitting the cache chain (and
+       therefore unref->cache->unref->... loops).
+
+       * gvaluetypes.[hc]: provide the value setters/getters for the primitive
+       fundamental types boolean, char, uchar, int, uint, long, ulong, float,
+       double and string.
+
+       * gvalue.[hc]: provide G_TYPE_IS_VALUE() in terms of whether a
+       GTypeValueTable is provided for this type.
+       removed g_value_init_default(), g_value_validate(), g_value_defaults(),
+       g_value_set_default() and g_values_cmp() as these are supplied by the
+       GParamSpec API now.
+       moved g_values_exchange() into the "implementation details" section,
+       since it just provides the underlying functionality for
+       g_value_convert().
+
+       * gvaluecollector.h: renamed the varargs value container from
+       GParamCValue to GTypeCValue as the value collection methods are
+       supplied by the type system now.
+       G_PARAM_COLLECT_VALUE() and G_PARAM_LCOPY_VALUE() got renamed to
+       G_VALUE_COLLECT() and G_VALUE_LCOPY() and operate without a
+       GParamSpec structure now.
+
+       * genums.h: macros cleanups/fixes.
+
+       * genum.c: provide G_TYPE_ENUM and G_TYPE_FLAGS type
+       and assorted g_value_{s|g}et_{enum|flags}() implementations.
+
+       * gobject.[hc]:
+       provide G_IS_VALUE_OBJECT(), G_TYPE_OBJECT ValueTable methods
+       and g_value_{s|g}et_object().
+
+       * gparam.[hc]: reduced class to value_set_default(),
+       value_validate() and values_cmp(). also parameters now need to fill
+       in a GType value_type; field to indicate the GValue type they
+       are handling. provide g_param_value_set_default(),
+       g_param_value_defaults(), g_param_value_validate() and
+       g_param_values_cmp().
+
+       * gparamspecs.[hc]: got rid of the g_value_* functions and
+       the G_IS_VALUE_* macros. adapted param spec implementations
+       according to the GParamSpecClass changes.
+
 Sat Jun 10 08:38:27 2000  Tim Janik  <timj@gtk.org>
 
        * gtype.c (type_class_init): fetch the nth iface entry of the
index d7859bc5d33e9ab6272f145b79d71e518dfb584b..dac3c430e6e0ba4800b2bd52a89fadb95bf753cb 100644 (file)
@@ -28,6 +28,7 @@ libgobject_la_LIBADD = # $(libglib)
 # GObject header files for public installation (non-generated)
 gobject_public_h_sources = @STRIP_BEGIN@ \
        gvalue.h \
+       gvaluetypes.h \
        gparam.h \
        gparamspecs.h \
        genums.h \
@@ -42,6 +43,7 @@ gobject_private_h_sources = @STRIP_BEGIN@ \
 # GObject C sources to build the library from
 gobject_c_sources = @STRIP_BEGIN@ \
        gvalue.c \
+       gvaluetypes.c \
        gparam.c \
        gparamspecs.c \
        genums.c \
index 3fcadb53f19de66db66fce44e32371d9851c928a..ef5e41a042b23e9c7aef4bd456dd443c1b4e51bc 100644 (file)
  */
 #include       "genums.h"
 
+#include       "gvalue.h"
+#include       "gvaluecollector.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);
+static void    g_value_enum_init               (GValue         *value);
+static void    g_value_enum_copy_value         (const GValue   *src_value,
+                                                GValue         *dest_value);
+static gchar*  g_value_enum_collect_value      (GValue         *value,
+                                                guint           nth_value,
+                                                GType          *collect_type,
+                                                GTypeCValue    *collect_value);
+static gchar*  g_value_enum_lcopy_value        (const GValue   *value,
+                                                guint           nth_value,
+                                                GType          *collect_type,
+                                                GTypeCValue    *collect_value);
 
 
 /* --- functions --- */
 void
-g_enum_types_init (void)       /* sync with glib-gtype.c */
+g_enum_types_init (void)       /* sync with 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 */,
@@ -45,21 +56,32 @@ g_enum_types_init (void)    /* sync with glib-gtype.c */
     NULL       /* class_finalize */,
     NULL       /* class_data */,
   };
+  static const GTypeValueTable value_table = {
+    g_value_enum_init,           /* value_init */
+    NULL,                        /* value_free */
+    g_value_enum_copy_value,     /* value_copy */
+    G_VALUE_COLLECT_INT,         /* collect_type */
+    g_value_enum_collect_value,          /* collect_value */
+    G_VALUE_COLLECT_POINTER,     /* lcopy_type */
+    g_value_enum_lcopy_value,    /* lcopy_value */
+  };
   GType type;
   
   g_return_if_fail (initialized == FALSE);
   initialized = TRUE;
-  
+
+  info.value_table = &value_table;
+
   /* G_TYPE_ENUM
    */
   info.class_size = sizeof (GEnumClass);
-  type = g_type_register_fundamental (G_TYPE_ENUM, "GEnum", &finfo, &info);
+  type = g_type_register_fundamental (G_TYPE_ENUM, "GEnum", &info, &finfo);
   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);
+  type = g_type_register_fundamental (G_TYPE_FLAGS, "GFlags", &info, &finfo);
   g_assert (type == G_TYPE_FLAGS);
 }
 
@@ -304,3 +326,79 @@ g_flags_get_first_value (GFlagsClass *flags_class,
   
   return NULL;
 }
+
+void
+g_value_set_enum (GValue *value,
+                 gint    v_enum)
+{
+  g_return_if_fail (G_IS_VALUE_ENUM (value));
+
+  value->data[0].v_long = v_enum;
+}
+
+gint
+g_value_get_enum (GValue *value)
+{
+  g_return_val_if_fail (G_IS_VALUE_ENUM (value), 0);
+
+  return value->data[0].v_long;
+}
+
+void
+g_value_set_flags (GValue *value,
+                  guint   v_flags)
+{
+  g_return_if_fail (G_IS_VALUE_FLAGS (value));
+
+  value->data[0].v_ulong = v_flags;
+}
+
+guint
+g_value_get_flags (GValue *value)
+{
+  g_return_val_if_fail (G_IS_VALUE_FLAGS (value), 0);
+
+  return value->data[0].v_ulong;
+}
+
+static void
+g_value_enum_init (GValue *value)
+{
+  value->data[0].v_long = 0;
+}
+
+static void
+g_value_enum_copy_value (const GValue *src_value,
+                        GValue       *dest_value)
+{
+  dest_value->data[0].v_long = src_value->data[0].v_long;
+}
+
+static gchar*
+g_value_enum_collect_value (GValue     *value,
+                           guint        nth_value,
+                           GType       *collect_type,
+                           GTypeCValue *collect_value)
+{
+  value->data[0].v_long = collect_value->v_int;
+  
+  *collect_type = 0;
+  return NULL;
+}
+
+static gchar*
+g_value_enum_lcopy_value (const GValue *value,
+                         guint         nth_value,
+                         GType        *collect_type,
+                         GTypeCValue  *collect_value)
+{
+  gint *int_p = collect_value->v_pointer;
+  
+  if (!int_p)
+    return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
+  
+  *int_p = value->data[0].v_long;
+  
+  *collect_type = 0;
+  return NULL;
+}
index 4e90c671783f70c729b96e8abe37f025c86b4576..79dbb03537011006bee82d3c5d7c2c2fe5734062 100644 (file)
@@ -28,16 +28,18 @@ extern "C" {
 
 
 /* --- 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))
+#define G_TYPE_IS_ENUM(type)          (G_TYPE_FUNDAMENTAL (type) == G_TYPE_ENUM)
+#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_ENUM_CLASS_TYPE(class)       (G_TYPE_FROM_CLASS (class))
+#define G_ENUM_CLASS_TYPE_NAME(class)  (g_type_name (G_ENUM_TYPE (class)))
+#define G_TYPE_IS_FLAGS(type)         (G_TYPE_FUNDAMENTAL (type) == G_TYPE_FLAGS)
+#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))
+#define G_FLAGS_CLASS_TYPE(class)      (G_TYPE_FROM_CLASS (class))
+#define G_FLAGS_CLASS_TYPE_NAME(class) (g_type_name (G_FLAGS_TYPE (class)))
+#define G_IS_VALUE_ENUM(value)         (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_ENUM))
+#define G_IS_VALUE_FLAGS(value)        (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_FLAGS))
 
 
 /* --- enum/flag values & classes --- */
@@ -89,6 +91,13 @@ 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);
+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);
+
 
 
 /* --- registration functions --- */
index 8d54b349a7a961061681ad7c794fabcd6df5eae1..3448a34b52330354953dab9c995873cc890036c7 100644 (file)
@@ -19,7 +19,6 @@
 #include       "gobject.h"
 
 
-#include       "gvalue.h"
 #include       "gvaluecollector.h"
 
 
 
 
 /* --- 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_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);
+static void    g_value_object_init                     (GValue         *value);
+static void    g_value_object_free_value               (GValue         *value);
+static void    g_value_object_copy_value               (const GValue   *src_value,
+                                                        GValue         *dest_value);
+static gchar*  g_value_object_collect_value            (GValue         *value,
+                                                        guint           nth_value,
+                                                        GType          *collect_type,
+                                                        GTypeCValue    *collect_value);
+static gchar*  g_value_object_lcopy_value              (const GValue   *value,
+                                                        guint           nth_value,
+                                                        GType          *collect_type,
+                                                        GTypeCValue    *collect_value);
 
 
 /* --- variables --- */
@@ -61,7 +71,7 @@ debug_objects_foreach (gpointer key,
                       gpointer user_data)
 {
   GObject *object = value;
-
+  
   g_message ("[%p] stale %s\tref_count=%u",
             object,
             G_OBJECT_TYPE_NAME (object),
@@ -79,13 +89,11 @@ debug_objects_atexit (void)
 #endif DEBUG_OBJECTS
 
 void
-g_object_type_init (void)      /* sync with glib-gtype.c */
+g_object_type_init (void)      /* sync with 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),
@@ -97,6 +105,16 @@ g_object_type_init (void)   /* sync with glib-gtype.c */
     sizeof (GObject),
     0          /* n_preallocs */,
     (GInstanceInitFunc) g_object_do_init,
+    NULL,      /* value_table */
+  };
+  static const GTypeValueTable value_table = {
+    g_value_object_init,         /* value_init */
+    g_value_object_free_value,   /* value_free */
+    g_value_object_copy_value,   /* value_copy */
+    G_VALUE_COLLECT_POINTER,     /* collect_type */
+    g_value_object_collect_value, /* collect_value */
+    G_VALUE_COLLECT_POINTER,     /* lcopy_type */
+    g_value_object_lcopy_value,          /* lcopy_value */
   };
   GType type;
   
@@ -105,12 +123,13 @@ g_object_type_init (void) /* sync with glib-gtype.c */
   
   /* G_TYPE_OBJECT
    */
-  type = g_type_register_fundamental (G_TYPE_OBJECT, "GObject", &finfo, &info);
+  info.value_table = &value_table;
+  type = g_type_register_fundamental (G_TYPE_OBJECT, "GObject", &info, &finfo);
   g_assert (type == G_TYPE_OBJECT);
-
-#ifdef  DEBUG_OBJECTS
+  
+#ifdef DEBUG_OBJECTS
   g_atexit (debug_objects_atexit);
-#endif  DEBUG_OBJECTS
+#endif DEBUG_OBJECTS
 }
 
 static void
@@ -127,7 +146,7 @@ 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++)
@@ -158,11 +177,11 @@ g_object_do_class_init (GObjectClass *class)
 
 void
 g_object_class_install_param (GObjectClass *class,
-                             guint         param_id,
+                             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)
@@ -171,7 +190,7 @@ g_object_class_install_param (GObjectClass *class,
     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)
@@ -191,7 +210,7 @@ g_object_class_install_param (GObjectClass *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++;
@@ -205,7 +224,7 @@ g_object_class_find_param_spec (GObjectClass *class,
 {
   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),
@@ -217,7 +236,7 @@ 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);
@@ -230,12 +249,12 @@ 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);
 }
@@ -265,31 +284,31 @@ g_object_do_finalize (GObject *object)
 }
 
 gpointer
-g_object_new (GType        object_type,
+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,
+g_object_new_valist (GType       object_type,
                     const gchar *first_param_name,
-                    va_list      var_args)
+                    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);
@@ -312,15 +331,15 @@ 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)
       {
@@ -376,11 +395,11 @@ object_get_param (GObject     *object,
                  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);
 }
 
@@ -391,36 +410,36 @@ object_set_param (GObject     *object,
                  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,
+g_object_set_valist (GObject    *object,
                     const gchar *first_param_name,
-                    va_list      var_args)
+                    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),
@@ -442,10 +461,10 @@ g_object_set_valist (GObject     *object,
                     G_OBJECT_TYPE_NAME (object));
          break;
        }
-
-      g_value_init (&value, G_PARAM_SPEC_TYPE (pspec));
-
-      G_PARAM_COLLECT_VALUE (&value, pspec, var_args, &error);
+      
+      g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
+      
+      G_VALUE_COLLECT (&value, var_args, &error);
       if (error)
        {
          g_warning ("%s: %s", G_STRLOC, error);
@@ -456,37 +475,37 @@ g_object_set_valist (GObject     *object,
           */
          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,
+g_object_get_valist (GObject    *object,
                     const gchar *first_param_name,
-                    va_list      var_args)
+                    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),
@@ -508,12 +527,12 @@ g_object_get_valist (GObject     *object,
                     G_OBJECT_TYPE_NAME (object));
          break;
        }
-
-      g_value_init (&value, G_PARAM_SPEC_TYPE (pspec));
-
+      
+      g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
+      
       object_get_param (object, &value, pspec, trailer);
-
-      G_PARAM_LCOPY_VALUE (&value, pspec, var_args, &error);
+      
+      G_VALUE_LCOPY (&value, var_args, &error);
       if (error)
        {
          g_warning ("%s: %s", G_STRLOC, error);
@@ -526,55 +545,55 @@ g_object_get_valist (GObject     *object,
        }
       
       g_value_unset (&value);
-
+      
       name = va_arg (var_args, gchar*);
     }
-
+  
   g_object_unref (object);
 }
 
 void
-g_object_set (GObject     *object,
+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,
+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,
+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),
@@ -588,17 +607,17 @@ g_object_set_param (GObject      *object,
   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));
-
+      g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_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_param_value_validate (pspec, &tmp_value))
+       g_warning ("%s: cannot convert `%s' value to parameter `%s' value of type `%s'",
                   G_STRLOC,
                   G_VALUE_TYPE_NAME (value),
                   pspec->name,
-                  G_PARAM_SPEC_TYPE_NAME (pspec));
+                  g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)));
       else
        object_set_param (object, &tmp_value, pspec, trailer);
       
@@ -609,9 +628,9 @@ g_object_set_param (GObject      *object,
 }
 
 void
-g_object_get_param (GObject     *object,
+g_object_get_param (GObject    *object,
                    const gchar *param_name,
-                   GValue      *value)
+                   GValue      *value)
 {
   GParamSpec *pspec;
   const gchar *trailer;
@@ -642,13 +661,13 @@ g_object_get_param (GObject     *object,
        * (though, at this point, GValue should exclusively be modified
        * through the accessor functions anyways)
        */
-      g_value_init (&tmp_value, G_PARAM_SPEC_TYPE (pspec));
+      g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_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'",
+      if (!g_value_types_exchangable (G_VALUE_TYPE (value), G_PARAM_SPEC_VALUE_TYPE (pspec)))
+       g_warning ("%s: can't retrive parameter `%s' value of type `%s' as value of type `%s'",
                   G_STRLOC,
                   pspec->name,
-                  G_PARAM_SPEC_TYPE_NAME (pspec),
+                  g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
                   G_VALUE_TYPE_NAME (value));
       else
        {
@@ -664,14 +683,14 @@ g_object_get_param (GObject     *object,
 }
 
 void
-g_object_queue_param_changed (GObject     *object,
+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),
@@ -690,9 +709,9 @@ 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;
 }
 
@@ -701,7 +720,7 @@ 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
@@ -713,7 +732,7 @@ 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;
 }
 
@@ -730,8 +749,8 @@ g_object_set_qdata (GObject *object,
 
 void
 g_object_set_qdata_full (GObject       *object,
-                        GQuark         quark,
-                        gpointer       data,
+                        GQuark         quark,
+                        gpointer       data,
                         GDestroyNotify destroy)
 {
   g_return_if_fail (G_IS_OBJECT (object));
@@ -749,3 +768,105 @@ g_object_steal_qdata (GObject *object,
   
   return g_datalist_id_remove_no_notify (&object->qdata, quark);
 }
+
+static void
+g_value_object_init (GValue *value)
+{
+  value->data[0].v_pointer = NULL;
+}
+
+static void
+g_value_object_free_value (GValue *value)
+{
+  if (value->data[0].v_pointer)
+    g_object_unref (value->data[0].v_pointer);
+}
+
+static void
+g_value_object_copy_value (const GValue *src_value,
+                          GValue       *dest_value)
+{
+  if (src_value->data[0].v_pointer)
+    dest_value->data[0].v_pointer = g_object_ref (src_value->data[0].v_pointer);
+  else
+    dest_value->data[0].v_pointer = NULL;
+}
+
+static gchar*
+g_value_object_collect_value (GValue     *value,
+                             guint        nth_value,
+                             GType       *collect_type,
+                             GTypeCValue *collect_value)
+{
+  if (collect_value->v_pointer)
+    {
+      GObject *object = collect_value->v_pointer;
+      
+      if (object->g_type_instance.g_class == NULL)
+       return g_strconcat ("invalid unclassed object pointer for value type `",
+                           G_VALUE_TYPE_NAME (value),
+                           "'",
+                           NULL);
+      else if (!g_type_is_a (G_OBJECT_TYPE (object), G_VALUE_TYPE (value)))
+       return g_strconcat ("invalid object type `",
+                           G_OBJECT_TYPE_NAME (object),
+                           "' for value type `",
+                           G_VALUE_TYPE_NAME (value),
+                           "'",
+                           NULL);
+      value->data[0].v_pointer = g_object_ref (object);
+    }
+  else
+    value->data[0].v_pointer = NULL;
+  
+  *collect_type = 0;
+  return NULL;
+}
+
+static gchar*
+g_value_object_lcopy_value (const GValue *value,
+                           guint         nth_value,
+                           GType        *collect_type,
+                           GTypeCValue  *collect_value)
+{
+  GObject **object_p = collect_value->v_pointer;
+  
+  if (!object_p)
+    return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
+  
+  *object_p = value->data[0].v_pointer ? g_object_ref (value->data[0].v_pointer) : NULL;
+  
+  *collect_type = 0;
+  return NULL;
+}
+
+void
+g_value_set_object (GValue  *value,
+                   GObject *v_object)
+{
+  g_return_if_fail (G_IS_VALUE_OBJECT (value));
+  if (v_object)
+    g_return_if_fail (G_IS_OBJECT (v_object));
+  
+  if (value->data[0].v_pointer)
+    g_object_unref (value->data[0].v_pointer);
+  value->data[0].v_pointer = v_object;
+  if (value->data[0].v_pointer)
+    g_object_ref (value->data[0].v_pointer);
+}
+
+GObject*
+g_value_get_object (GValue *value)
+{
+  g_return_val_if_fail (G_IS_VALUE_OBJECT (value), NULL);
+  
+  return value->data[0].v_pointer;
+}
+
+GObject*
+g_value_dup_object (GValue *value)
+{
+  g_return_val_if_fail (G_IS_VALUE_OBJECT (value), NULL);
+  
+  return value->data[0].v_pointer ? g_object_ref (value->data[0].v_pointer) : NULL;
+}
index 69c718d980d8fe720e118cd48272831ed3d9212c..68657abb06617a0a39ad2f54041dcc70e34995ce 100644 (file)
@@ -20,6 +20,7 @@
 #define __G_GOBJECT_H__
 
 #include       <gobject/gtype.h>
+#include       <gobject/gvalue.h>
 #include       <gobject/gparam.h>
 
 
@@ -43,6 +44,7 @@ extern "C" {
 #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_IS_VALUE_OBJECT(value)   (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_OBJECT))
 
 #define        G_NOTIFY_PRIORITY          (G_PRIORITY_HIGH_IDLE + 20)
 
@@ -140,6 +142,10 @@ void           g_object_set_qdata_full        (GObject        *object,
                                            GDestroyNotify  destroy);
 gpointer    g_object_steal_qdata          (GObject        *object,
                                            GQuark          quark);
+void        g_value_set_object            (GValue         *value,
+                                           GObject        *v_object);
+GObject*    g_value_get_object            (GValue         *value);
+GObject*    g_value_dup_object            (GValue         *value);
 
 
 /* --- implementation macros --- */
index e29b1a7c54b4e3c8f07abaac22c9d87fd9eb393e..7d0199ef864a06713ff72fb86f22be2ec593da81 100644 (file)
@@ -28,8 +28,6 @@
 
 
 /* --- 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,
@@ -40,15 +38,13 @@ static void g_param_spec_finalize            (GParamSpec            *pspec);
 
 /* --- functions --- */
 void
-g_param_types_init (void)      /* sync with glib-gtype.c */
+g_param_type_init (void)       /* sync with 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),
@@ -57,20 +53,18 @@ g_param_types_init (void)   /* sync with glib-gtype.c */
     (GBaseFinalizeFunc) g_param_spec_class_base_finalize,
     (GClassInitFunc) g_param_spec_class_init,
     (GClassFinalizeFunc) NULL,
-    NULL /* class_data */,
+    NULL,      /* class_data */
 
     sizeof (GParamSpec),
-    0 /* n_preallocs */,
+    0,         /* n_preallocs */
     (GInstanceInitFunc) g_param_spec_init,
+
+    NULL,      /* value_table */
   };
   GType type;
 
-  type = g_type_register_fundamental (G_TYPE_PARAM, "GParam", &finfo, &param_spec_info);
+  type = g_type_register_fundamental (G_TYPE_PARAM, "GParam", &param_spec_info, &finfo);
   g_assert (type == G_TYPE_PARAM);
-
-  /* derived param specs
-   */
-  g_param_spec_types_init ();
 }
 
 static void
@@ -87,16 +81,11 @@ static void
 g_param_spec_class_init (GParamSpecClass *class,
                         gpointer         class_data)
 {
+  class->value_type = G_TYPE_NONE;
   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;
+  class->value_set_default = NULL;
+  class->value_validate = NULL;
+  class->values_cmp = NULL;
 }
 
 static void
@@ -209,6 +198,81 @@ g_param_spec_steal_qdata (GParamSpec *pspec,
   return g_datalist_id_remove_no_notify (&pspec->qdata, quark);
 }
 
+void
+g_param_value_set_default (GParamSpec *pspec,
+                          GValue     *value)
+{
+  g_return_if_fail (G_IS_PARAM_SPEC (pspec));
+  g_return_if_fail (G_IS_VALUE (value));
+  g_return_if_fail (G_IS_PARAM_VALUE (pspec, value));
+
+  g_value_reset (value);
+  G_PARAM_SPEC_GET_CLASS (pspec)->value_set_default (pspec, value);
+}
+
+gboolean
+g_param_value_defaults (GParamSpec *pspec,
+                       GValue     *value)
+{
+  GValue dflt_value = { 0, };
+  gboolean defaults;
+
+  g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), FALSE);
+  g_return_val_if_fail (G_IS_VALUE (value), FALSE);
+  g_return_val_if_fail (G_IS_PARAM_VALUE (pspec, value), FALSE);
+
+  g_value_init (&dflt_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
+  G_PARAM_SPEC_GET_CLASS (pspec)->value_set_default (pspec, value);
+  defaults = G_PARAM_SPEC_GET_CLASS (pspec)->values_cmp (pspec, value, &dflt_value) == 0;
+  g_value_unset (&dflt_value);
+
+  return defaults;
+}
+
+gboolean
+g_param_value_validate (GParamSpec *pspec,
+                       GValue     *value)
+{
+  g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), FALSE);
+  g_return_val_if_fail (G_IS_VALUE (value), FALSE);
+  g_return_val_if_fail (G_IS_PARAM_VALUE (pspec, value), FALSE);
+
+  if (G_PARAM_SPEC_GET_CLASS (pspec)->value_validate)
+    {
+      GValue oval = *value;
+
+      if (G_PARAM_SPEC_GET_CLASS (pspec)->value_validate (pspec, value) ||
+         memcmp (&oval.data, &value->data, sizeof (oval.data)))
+       return TRUE;
+    }
+
+  return FALSE;
+}
+
+gint
+g_param_values_cmp (GParamSpec   *pspec,
+                   const GValue *value1,
+                   const GValue *value2)
+{
+  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_PARAM_SPEC (pspec), 0);
+  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_IS_PARAM_VALUE (pspec, value1), 0);
+  g_return_val_if_fail (G_IS_PARAM_VALUE (pspec, value2), 0);
+
+  cmp = G_PARAM_SPEC_GET_CLASS (pspec)->values_cmp (pspec, value1, value2);
+
+  return CLAMP (cmp, -1, 1);
+}
+
 static guint
 param_spec_hash (gconstpointer key_spec)
 {
index fb6ef1ecfc6d30f086d04b158d0f8f00981c1a00..3551b15ff01bf5e3b50a6377cc015907c5e58b45 100644 (file)
@@ -22,7 +22,7 @@
 #define __G_PARAM_H__
 
 
-#include       <gobject/gtype.h>
+#include       <gobject/gvalue.h>
 
 
 #ifdef __cplusplus
@@ -37,7 +37,8 @@ extern "C" {
 #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))
+#define        G_IS_PARAM_VALUE(pspec, value)  (g_type_is_a (G_VALUE_TYPE (value), G_PARAM_SPEC_VALUE_TYPE (pspec))) // FIXME
+#define        G_PARAM_SPEC_VALUE_TYPE(pspec)  (G_PARAM_SPEC_GET_CLASS (pspec)->value_type)
 
 
 /* --- flags --- */
@@ -54,39 +55,22 @@ typedef enum
 /* --- 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;
 
+  GType                  value_type;
+
   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);
+  void          (*value_set_default)    (GParamSpec   *pspec,
+                                        GValue       *value);
+  gboolean      (*value_validate)       (GParamSpec   *pspec,
+                                        GValue       *value);
+  gint          (*values_cmp)           (GParamSpec   *pspec,
+                                        const GValue *value1,
+                                        const GValue *value2);
 };
 struct _GParamSpec
 {
@@ -118,6 +102,15 @@ void            g_param_spec_set_qdata_full        (GParamSpec    *pspec,
                                                 GDestroyNotify destroy);
 gpointer        g_param_spec_steal_qdata       (GParamSpec    *pspec,
                                                 GQuark         quark);
+void           g_param_value_set_default       (GParamSpec    *pspec,
+                                                GValue        *value);
+gboolean       g_param_value_defaults          (GParamSpec    *pspec,
+                                                GValue        *value);
+gboolean       g_param_value_validate          (GParamSpec    *pspec,
+                                                GValue        *value);
+gint           g_param_values_cmp              (GParamSpec    *pspec,
+                                                const GValue  *value1,
+                                                const GValue  *value2);
 
 
 /* --- private --- */
@@ -140,6 +133,8 @@ GParamSpec* g_param_spec_hash_table_lookup  (GHashTable    *hash_table,
 
 
 /* contracts:
+ *
+ * +++ OUTDATED +++
  *
  * class functions may not evaluate param->pspec directly,
  * instead, pspec will be passed as argument if required.
index 628d134b8387ff45035da6cc19c425fd7afd7e0e..c62bf2f8d276ca24e13944e003bea0c19631e30b 100644 (file)
 #define        G_DOUBLE_EPSILON        (1e-90)
 
 
-/* --- prototypes --- */
-extern void    g_param_spec_types_init (void);
-
-
 /* --- param spec functions --- */
 static void
 param_spec_char_init (GParamSpec *pspec)
@@ -42,16 +38,15 @@ param_spec_char_init (GParamSpec *pspec)
 }
 
 static void
-param_char_init (GValue            *value,
-                GParamSpec *pspec)
+param_char_set_default (GParamSpec *pspec,
+                       GValue     *value)
 {
-  if (pspec)
-    value->data[0].v_int = G_PARAM_SPEC_CHAR (pspec)->default_value;
+  value->data[0].v_int = G_PARAM_SPEC_CHAR (pspec)->default_value;
 }
 
 static gboolean
-param_char_validate (GValue    *value,
-                    GParamSpec *pspec)
+param_char_validate (GParamSpec *pspec,
+                    GValue     *value)
 {
   GParamSpecChar *cspec = G_PARAM_SPEC_CHAR (pspec);
   gint oval = value->data[0].v_int;
@@ -61,25 +56,6 @@ param_char_validate (GValue  *value,
   return value->data[0].v_int != oval;
 }
 
-static gchar*
-param_char_lcopy_value (const GValue *value,
-                       GParamSpec   *pspec,
-                       guint         nth_value,
-                       GType        *collect_type,
-                       GParamCValue *collect_value)
-{
-  gint8 *int8_p = collect_value->v_pointer;
-  
-  if (!int8_p)
-    return g_strdup_printf ("value location for `%s' passed as NULL",
-                           g_type_name (pspec ? G_PARAM_SPEC_TYPE (pspec) : G_VALUE_TYPE (value)));
-  
-  *int8_p = value->data[0].v_int;
-  
-  *collect_type = 0;
-  return NULL;
-}
-
 static void
 param_spec_uchar_init (GParamSpec *pspec)
 {
@@ -91,16 +67,15 @@ param_spec_uchar_init (GParamSpec *pspec)
 }
 
 static void
-param_uchar_init (GValue     *value,
-                 GParamSpec *pspec)
+param_uchar_set_default (GParamSpec *pspec,
+                        GValue     *value)
 {
-  if (pspec)
-    value->data[0].v_uint = G_PARAM_SPEC_UCHAR (pspec)->default_value;
+  value->data[0].v_uint = G_PARAM_SPEC_UCHAR (pspec)->default_value;
 }
 
 static gboolean
-param_uchar_validate (GValue    *value,
-                     GParamSpec *pspec)
+param_uchar_validate (GParamSpec *pspec,
+                     GValue     *value)
 {
   GParamSpecUChar *uspec = G_PARAM_SPEC_UCHAR (pspec);
   guint oval = value->data[0].v_uint;
@@ -111,16 +86,15 @@ param_uchar_validate (GValue        *value,
 }
 
 static void
-param_bool_init (GValue            *value,
-                GParamSpec *pspec)
+param_boolean_set_default (GParamSpec *pspec,
+                          GValue     *value)
 {
-  if (pspec)
-    value->data[0].v_int = G_PARAM_SPEC_BOOL (pspec)->default_value;
+  value->data[0].v_int = G_PARAM_SPEC_BOOLEAN (pspec)->default_value;
 }
 
 static gboolean
-param_bool_validate (GValue    *value,
-                    GParamSpec *pspec)
+param_boolean_validate (GParamSpec *pspec,
+                       GValue     *value)
 {
   gint oval = value->data[0].v_int;
   
@@ -129,25 +103,6 @@ param_bool_validate (GValue        *value,
   return value->data[0].v_int != oval;
 }
 
-static gchar*
-param_bool_lcopy_value (const GValue *value,
-                       GParamSpec   *pspec,
-                       guint         nth_value,
-                       GType        *collect_type,
-                       GParamCValue *collect_value)
-{
-  gboolean *bool_p = collect_value->v_pointer;
-  
-  if (!bool_p)
-    return g_strdup_printf ("value location for `%s' passed as NULL",
-                           g_type_name (pspec ? G_PARAM_SPEC_TYPE (pspec) : G_VALUE_TYPE (value)));
-  
-  *bool_p = value->data[0].v_int;
-  
-  *collect_type = 0;
-  return NULL;
-}
-
 static void
 param_spec_int_init (GParamSpec *pspec)
 {
@@ -159,16 +114,15 @@ param_spec_int_init (GParamSpec *pspec)
 }
 
 static void
-param_int_init (GValue    *value,
-               GParamSpec *pspec)
+param_int_set_default (GParamSpec *pspec,
+                      GValue     *value)
 {
-  if (pspec)
-    value->data[0].v_int = G_PARAM_SPEC_INT (pspec)->default_value;
+  value->data[0].v_int = G_PARAM_SPEC_INT (pspec)->default_value;
 }
 
 static gboolean
-param_int_validate (GValue     *value,
-                   GParamSpec *pspec)
+param_int_validate (GParamSpec *pspec,
+                   GValue     *value)
 {
   GParamSpecInt *ispec = G_PARAM_SPEC_INT (pspec);
   gint oval = value->data[0].v_int;
@@ -179,46 +133,14 @@ param_int_validate (GValue     *value,
 }
 
 static gint
-param_int_values_cmp (const GValue *value1,
-                     const GValue *value2,
-                     GParamSpec   *pspec)
+param_int_values_cmp (GParamSpec   *pspec,
+                     const GValue *value1,
+                     const GValue *value2)
 {
   if (value1->data[0].v_int < value2->data[0].v_int)
     return -1;
   else
-    return value1->data[0].v_int - value2->data[0].v_int;
-}
-
-static gchar*
-param_int_collect_value (GValue              *value,
-                        GParamSpec   *pspec,
-                        guint         nth_value,
-                        GType        *collect_type,
-                        GParamCValue *collect_value)
-{
-  value->data[0].v_int = collect_value->v_int;
-  
-  *collect_type = 0;
-  return NULL;
-}
-
-static gchar*
-param_int_lcopy_value (const GValue *value,
-                      GParamSpec   *pspec,
-                      guint         nth_value,
-                      GType        *collect_type,
-                      GParamCValue *collect_value)
-{
-  gint *int_p = collect_value->v_pointer;
-  
-  if (!int_p)
-    return g_strdup_printf ("value location for `%s' passed as NULL",
-                           g_type_name (pspec ? G_PARAM_SPEC_TYPE (pspec) : G_VALUE_TYPE (value)));
-  
-  *int_p = value->data[0].v_int;
-  
-  *collect_type = 0;
-  return NULL;
+    return value1->data[0].v_int > value2->data[0].v_int;
 }
 
 static void
@@ -232,16 +154,15 @@ param_spec_uint_init (GParamSpec *pspec)
 }
 
 static void
-param_uint_init (GValue            *value,
-                GParamSpec *pspec)
+param_uint_set_default (GParamSpec *pspec,
+                       GValue     *value)
 {
-  if (pspec)
-    value->data[0].v_uint = G_PARAM_SPEC_UINT (pspec)->default_value;
+  value->data[0].v_uint = G_PARAM_SPEC_UINT (pspec)->default_value;
 }
 
 static gboolean
-param_uint_validate (GValue    *value,
-                    GParamSpec *pspec)
+param_uint_validate (GParamSpec *pspec,
+                    GValue     *value)
 {
   GParamSpecUInt *uspec = G_PARAM_SPEC_UINT (pspec);
   guint oval = value->data[0].v_uint;
@@ -252,14 +173,14 @@ param_uint_validate (GValue       *value,
 }
 
 static gint
-param_uint_values_cmp (const GValue *value1,
-                      const GValue *value2,
-                      GParamSpec   *pspec)
+param_uint_values_cmp (GParamSpec   *pspec,
+                      const GValue *value1,
+                      const GValue *value2)
 {
   if (value1->data[0].v_uint < value2->data[0].v_uint)
     return -1;
   else
-    return value1->data[0].v_uint - value2->data[0].v_uint;
+    return value1->data[0].v_uint > value2->data[0].v_uint;
 }
 
 static void
@@ -278,16 +199,15 @@ param_spec_long_init (GParamSpec *pspec)
 }
 
 static void
-param_long_init (GValue            *value,
-                GParamSpec *pspec)
+param_long_set_default (GParamSpec *pspec,
+                       GValue     *value)
 {
-  if (pspec)
-    value->data[0].v_long = G_PARAM_SPEC_LONG (pspec)->default_value;
+  value->data[0].v_long = G_PARAM_SPEC_LONG (pspec)->default_value;
 }
 
 static gboolean
-param_long_validate (GValue    *value,
-                    GParamSpec *pspec)
+param_long_validate (GParamSpec *pspec,
+                    GValue     *value)
 {
   GParamSpecLong *lspec = G_PARAM_SPEC_LONG (pspec);
   glong oval = value->data[0].v_long;
@@ -298,46 +218,14 @@ param_long_validate (GValue       *value,
 }
 
 static gint
-param_long_values_cmp (const GValue *value1,
-                      const GValue *value2,
-                      GParamSpec   *pspec)
+param_long_values_cmp (GParamSpec   *pspec,
+                      const GValue *value1,
+                      const GValue *value2)
 {
   if (value1->data[0].v_long < value2->data[0].v_long)
     return -1;
   else
-    return value1->data[0].v_long - value2->data[0].v_long;
-}
-
-static gchar*
-param_long_collect_value (GValue       *value,
-                         GParamSpec   *pspec,
-                         guint         nth_value,
-                         GType        *collect_type,
-                         GParamCValue *collect_value)
-{
-  value->data[0].v_long = collect_value->v_long;
-  
-  *collect_type = 0;
-  return NULL;
-}
-
-static gchar*
-param_long_lcopy_value (const GValue *value,
-                       GParamSpec   *pspec,
-                       guint         nth_value,
-                       GType        *collect_type,
-                       GParamCValue *collect_value)
-{
-  glong *long_p = collect_value->v_pointer;
-  
-  if (!long_p)
-    return g_strdup_printf ("value location for `%s' passed as NULL",
-                           g_type_name (pspec ? G_PARAM_SPEC_TYPE (pspec) : G_VALUE_TYPE (value)));
-  
-  *long_p = value->data[0].v_long;
-  
-  *collect_type = 0;
-  return NULL;
+    return value1->data[0].v_long > value2->data[0].v_long;
 }
 
 static void
@@ -355,16 +243,15 @@ param_spec_ulong_init (GParamSpec *pspec)
 }
 
 static void
-param_ulong_init (GValue     *value,
-                 GParamSpec *pspec)
+param_ulong_set_default (GParamSpec *pspec,
+                        GValue     *value)
 {
-  if (pspec)
-    value->data[0].v_ulong = G_PARAM_SPEC_ULONG (pspec)->default_value;
+  value->data[0].v_ulong = G_PARAM_SPEC_ULONG (pspec)->default_value;
 }
 
 static gboolean
-param_ulong_validate (GValue    *value,
-                     GParamSpec *pspec)
+param_ulong_validate (GParamSpec *pspec,
+                     GValue     *value)
 {
   GParamSpecULong *uspec = G_PARAM_SPEC_ULONG (pspec);
   gulong oval = value->data[0].v_ulong;
@@ -375,14 +262,14 @@ param_ulong_validate (GValue       *value,
 }
 
 static gint
-param_ulong_values_cmp (const GValue *value1,
-                       const GValue *value2,
-                       GParamSpec   *pspec)
+param_ulong_values_cmp (GParamSpec   *pspec,
+                       const GValue *value1,
+                       const GValue *value2)
 {
   if (value1->data[0].v_ulong < value2->data[0].v_ulong)
     return -1;
   else
-    return value1->data[0].v_ulong - value2->data[0].v_ulong;
+    return value1->data[0].v_ulong > value2->data[0].v_ulong;
 }
 
 static void
@@ -410,16 +297,15 @@ param_spec_enum_finalize (GParamSpec *pspec)
 }
 
 static void
-param_enum_init (GValue            *value,
-                GParamSpec *pspec)
+param_enum_set_default (GParamSpec *pspec,
+                       GValue     *value)
 {
-  if (pspec)
-    value->data[0].v_long = G_PARAM_SPEC_ENUM (pspec)->default_value;
+  value->data[0].v_long = G_PARAM_SPEC_ENUM (pspec)->default_value;
 }
 
 static gboolean
-param_enum_validate (GValue    *value,
-                    GParamSpec *pspec)
+param_enum_validate (GParamSpec *pspec,
+                    GValue     *value)
 {
   GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec);
   glong oval = value->data[0].v_long;
@@ -431,38 +317,6 @@ param_enum_validate (GValue        *value,
   return value->data[0].v_long != oval;
 }
 
-static gchar*
-param_enum_collect_value (GValue       *value,
-                         GParamSpec   *pspec,
-                         guint         nth_value,
-                         GType        *collect_type,
-                         GParamCValue *collect_value)
-{
-  value->data[0].v_long = collect_value->v_int;
-  
-  *collect_type = 0;
-  return NULL;
-}
-
-static gchar*
-param_enum_lcopy_value (const GValue *value,
-                       GParamSpec   *pspec,
-                       guint         nth_value,
-                       GType        *collect_type,
-                       GParamCValue *collect_value)
-{
-  gint *int_p = collect_value->v_pointer;
-  
-  if (!int_p)
-    return g_strdup_printf ("value location for `%s' passed as NULL",
-                           g_type_name (pspec ? G_PARAM_SPEC_TYPE (pspec) : G_VALUE_TYPE (value)));
-  
-  *int_p = value->data[0].v_long;
-  
-  *collect_type = 0;
-  return NULL;
-}
-
 static void
 param_spec_flags_init (GParamSpec *pspec)
 {
@@ -488,16 +342,15 @@ param_spec_flags_finalize (GParamSpec *pspec)
 }
 
 static void
-param_flags_init (GValue     *value,
-                 GParamSpec *pspec)
+param_flags_set_default (GParamSpec *pspec,
+                        GValue     *value)
 {
-  if (pspec)
-    value->data[0].v_ulong = G_PARAM_SPEC_FLAGS (pspec)->default_value;
+  value->data[0].v_ulong = G_PARAM_SPEC_FLAGS (pspec)->default_value;
 }
 
 static gboolean
-param_flags_validate (GValue    *value,
-                     GParamSpec *pspec)
+param_flags_validate (GParamSpec *pspec,
+                     GValue     *value)
 {
   GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec);
   gulong oval = value->data[0].v_ulong;
@@ -522,16 +375,15 @@ param_spec_float_init (GParamSpec *pspec)
 }
 
 static void
-param_float_init (GValue     *value,
-                 GParamSpec *pspec)
+param_float_set_default (GParamSpec *pspec,
+                        GValue     *value)
 {
-  if (pspec)
-    value->data[0].v_float = G_PARAM_SPEC_FLOAT (pspec)->default_value;
+  value->data[0].v_float = G_PARAM_SPEC_FLOAT (pspec)->default_value;
 }
 
 static gboolean
-param_float_validate (GValue    *value,
-                     GParamSpec *pspec)
+param_float_validate (GParamSpec *pspec,
+                     GValue     *value)
 {
   GParamSpecFloat *fspec = G_PARAM_SPEC_FLOAT (pspec);
   gfloat oval = value->data[0].v_float;
@@ -542,11 +394,11 @@ param_float_validate (GValue       *value,
 }
 
 static gint
-param_float_values_cmp (const GValue *value1,
-                       const GValue *value2,
-                       GParamSpec   *pspec)
+param_float_values_cmp (GParamSpec   *pspec,
+                       const GValue *value1,
+                       const GValue *value2)
 {
-  gfloat epsilon = pspec ? G_PARAM_SPEC_FLOAT (pspec)->epsilon : G_FLOAT_EPSILON;
+  gfloat epsilon = G_PARAM_SPEC_FLOAT (pspec)->epsilon;
   
   if (value1->data[0].v_float < value2->data[0].v_float)
     return - (value2->data[0].v_float - value1->data[0].v_float > epsilon);
@@ -554,38 +406,6 @@ param_float_values_cmp (const GValue *value1,
     return value1->data[0].v_float - value2->data[0].v_float > epsilon;
 }
 
-static gchar*
-param_float_collect_value (GValue      *value,
-                          GParamSpec   *pspec,
-                          guint         nth_value,
-                          GType        *collect_type,
-                          GParamCValue *collect_value)
-{
-  value->data[0].v_float = collect_value->v_double;
-  
-  *collect_type = 0;
-  return NULL;
-}
-
-static gchar*
-param_float_lcopy_value (const GValue *value,
-                        GParamSpec   *pspec,
-                        guint         nth_value,
-                        GType        *collect_type,
-                        GParamCValue *collect_value)
-{
-  gfloat *float_p = collect_value->v_pointer;
-  
-  if (!float_p)
-    return g_strdup_printf ("value location for `%s' passed as NULL",
-                           g_type_name (pspec ? G_PARAM_SPEC_TYPE (pspec) : G_VALUE_TYPE (value)));
-  
-  *float_p = value->data[0].v_float;
-  
-  *collect_type = 0;
-  return NULL;
-}
-
 static void
 param_spec_double_init (GParamSpec *pspec)
 {
@@ -598,16 +418,15 @@ param_spec_double_init (GParamSpec *pspec)
 }
 
 static void
-param_double_init (GValue     *value,
-                  GParamSpec *pspec)
+param_double_set_default (GParamSpec *pspec,
+                         GValue     *value)
 {
-  if (pspec)
-    value->data[0].v_double = G_PARAM_SPEC_DOUBLE (pspec)->default_value;
+  value->data[0].v_double = G_PARAM_SPEC_DOUBLE (pspec)->default_value;
 }
 
 static gboolean
-param_double_validate (GValue    *value,
-                      GParamSpec *pspec)
+param_double_validate (GParamSpec *pspec,
+                      GValue     *value)
 {
   GParamSpecDouble *dspec = G_PARAM_SPEC_DOUBLE (pspec);
   gdouble oval = value->data[0].v_double;
@@ -618,11 +437,11 @@ param_double_validate (GValue       *value,
 }
 
 static gint
-param_double_values_cmp (const GValue *value1,
-                        const GValue *value2,
-                        GParamSpec   *pspec)
+param_double_values_cmp (GParamSpec   *pspec,
+                        const GValue *value1,
+                        const GValue *value2)
 {
-  gdouble epsilon = pspec ? G_PARAM_SPEC_DOUBLE (pspec)->epsilon : G_DOUBLE_EPSILON;
+  gdouble epsilon = G_PARAM_SPEC_DOUBLE (pspec)->epsilon;
   
   if (value1->data[0].v_double < value2->data[0].v_double)
     return - (value2->data[0].v_double - value1->data[0].v_double > epsilon);
@@ -630,38 +449,6 @@ param_double_values_cmp (const GValue *value1,
     return value1->data[0].v_double - value2->data[0].v_double > epsilon;
 }
 
-static gchar*
-param_double_collect_value (GValue      *value,
-                           GParamSpec   *pspec,
-                           guint         nth_value,
-                           GType        *collect_type,
-                           GParamCValue *collect_value)
-{
-  value->data[0].v_double = collect_value->v_double;
-  
-  *collect_type = 0;
-  return NULL;
-}
-
-static gchar*
-param_double_lcopy_value (const GValue *value,
-                         GParamSpec   *pspec,
-                         guint         nth_value,
-                         GType        *collect_type,
-                         GParamCValue *collect_value)
-{
-  gdouble *double_p = collect_value->v_pointer;
-  
-  if (!double_p)
-    return g_strdup_printf ("value location for `%s' passed as NULL",
-                           g_type_name (pspec ? G_PARAM_SPEC_TYPE (pspec) : G_VALUE_TYPE (value)));
-  
-  *double_p = value->data[0].v_double;
-  
-  *collect_type = 0;
-  return NULL;
-}
-
 static void
 param_spec_string_init (GParamSpec *pspec)
 {
@@ -692,22 +479,15 @@ param_spec_string_finalize (GParamSpec *pspec)
 }
 
 static void
-param_string_init (GValue     *value,
-                  GParamSpec *pspec)
-{
-  if (pspec)
-    value->data[0].v_pointer = g_strdup (G_PARAM_SPEC_STRING (pspec)->default_value);
-}
-
-static void
-param_string_free_value (GValue *value)
+param_string_set_default (GParamSpec *pspec,
+                         GValue     *value)
 {
-  g_free (value->data[0].v_pointer);
+  value->data[0].v_pointer = g_strdup (G_PARAM_SPEC_STRING (pspec)->default_value);
 }
 
 static gboolean
-param_string_validate (GValue    *value,
-                      GParamSpec *pspec)
+param_string_validate (GParamSpec *pspec,
+                      GValue     *value)
 {
   GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec);
   gchar *string = value->data[0].v_pointer;
@@ -748,9 +528,9 @@ param_string_validate (GValue         *value,
 }
 
 static gint
-param_string_values_cmp (const GValue *value1,
-                        const GValue *value2,
-                        GParamSpec   *pspec)
+param_string_values_cmp (GParamSpec   *pspec,
+                        const GValue *value1,
+                        const GValue *value2)
 {
   if (!value1->data[0].v_pointer)
     return value2->data[0].v_pointer != NULL ? -1 : 0;
@@ -760,45 +540,6 @@ param_string_values_cmp (const GValue *value1,
     return strcmp (value1->data[0].v_pointer, value2->data[0].v_pointer);
 }
 
-static void
-param_string_copy_value (const GValue *src_value,
-                        GValue       *dest_value)
-{
-  dest_value->data[0].v_pointer = g_strdup (src_value->data[0].v_pointer);
-}
-
-static gchar*
-param_string_collect_value (GValue      *value,
-                           GParamSpec   *pspec,
-                           guint         nth_value,
-                           GType        *collect_type,
-                           GParamCValue *collect_value)
-{
-  value->data[0].v_pointer = g_strdup (collect_value->v_pointer);
-  
-  *collect_type = 0;
-  return NULL;
-}
-
-static gchar*
-param_string_lcopy_value (const GValue *value,
-                         GParamSpec   *pspec,
-                         guint         nth_value,
-                         GType        *collect_type,
-                         GParamCValue *collect_value)
-{
-  gchar **string_p = collect_value->v_pointer;
-  
-  if (!string_p)
-    return g_strdup_printf ("value location for `%s' passed as NULL",
-                           g_type_name (pspec ? G_PARAM_SPEC_TYPE (pspec) : G_VALUE_TYPE (value)));
-  
-  *string_p = g_strdup (value->data[0].v_pointer);
-  
-  *collect_type = 0;
-  return NULL;
-}
-
 static void
 param_spec_object_init (GParamSpec *pspec)
 {
@@ -808,22 +549,15 @@ param_spec_object_init (GParamSpec *pspec)
 }
 
 static void
-param_object_init (GValue     *value,
-                  GParamSpec *pspec)
+param_object_set_default (GParamSpec *pspec,
+                         GValue     *value)
 {
   value->data[0].v_pointer = NULL;
 }
 
-static void
-param_object_free_value (GValue *value)
-{
-  if (value->data[0].v_pointer)
-    g_object_unref (value->data[0].v_pointer);
-}
-
 static gboolean
-param_object_validate (GValue    *value,
-                      GParamSpec *pspec)
+param_object_validate (GParamSpec *pspec,
+                      GValue     *value)
 {
   GParamSpecObject *ospec = G_PARAM_SPEC_OBJECT (pspec);
   GObject *object = value->data[0].v_pointer;
@@ -840,76 +574,13 @@ param_object_validate (GValue       *value,
 }
 
 static gint
-param_object_values_cmp (const GValue *value1,
-                        const GValue *value2,
-                        GParamSpec   *pspec)
+param_object_values_cmp (GParamSpec   *pspec,
+                        const GValue *value1,
+                        const GValue *value2)
 {
   return value1->data[0].v_pointer != value2->data[0].v_pointer;
 }
 
-static void
-param_object_copy_value (const GValue *src_value,
-                        GValue       *dest_value)
-{
-  if (src_value->data[0].v_pointer)
-    dest_value->data[0].v_pointer = g_object_ref (src_value->data[0].v_pointer);
-  else
-    dest_value->data[0].v_pointer = NULL;
-}
-
-static gchar*
-param_object_collect_value (GValue      *value,
-                           GParamSpec   *pspec,
-                           guint         nth_value,
-                           GType        *collect_type,
-                           GParamCValue *collect_value)
-{
-  if (collect_value->v_pointer)
-    {
-      GObject *object = collect_value->v_pointer;
-      
-      if (object->g_type_instance.g_class == NULL)
-       return g_strconcat ("invalid unclassed object pointer for param type `",
-                           g_type_name (pspec ? G_PARAM_SPEC_TYPE (pspec) : G_VALUE_TYPE (value)),
-                           "'",
-                           NULL);
-      else if (pspec && !g_type_is_a (G_OBJECT_TYPE (object), G_PARAM_SPEC_OBJECT (pspec)->object_type))
-       return g_strconcat ("invalid object `",
-                           G_OBJECT_TYPE_NAME (object),
-                           "' for param type `",
-                           g_type_name (G_PARAM_SPEC_TYPE (pspec)),
-                           "' which requires `",
-                           g_type_name (G_PARAM_SPEC_OBJECT (pspec)->object_type),
-                           "'",
-                           NULL);
-      value->data[0].v_pointer = g_object_ref (object);
-    }
-  else
-    value->data[0].v_pointer = NULL;
-  
-  *collect_type = 0;
-  return NULL;
-}
-
-static gchar*
-param_object_lcopy_value (const GValue *value,
-                         GParamSpec   *pspec,
-                         guint         nth_value,
-                         GType        *collect_type,
-                         GParamCValue *collect_value)
-{
-  GObject **object_p = collect_value->v_pointer;
-  
-  if (!object_p)
-    return g_strdup_printf ("value location for `%s' passed as NULL",
-                           g_type_name (pspec ? G_PARAM_SPEC_TYPE (pspec) : G_VALUE_TYPE (value)));
-  
-  *object_p = value->data[0].v_pointer ? g_object_ref (value->data[0].v_pointer) : NULL;
-  
-  *collect_type = 0;
-  return NULL;
-}
-
 static void
 value_exch_memcpy (GValue *value1,
                   GValue *value2)
@@ -1040,29 +711,15 @@ value_exch_double_float (GValue *value1,
 
 /* --- type initialization --- */
 typedef struct {
+  GType           value_type;
   void         (*finalize)             (GParamSpec   *pspec);
-  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);
-  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);
+  void          (*value_set_default)    (GParamSpec   *pspec,
+                                        GValue       *value);
+  gboolean      (*value_validate)       (GParamSpec   *pspec,
+                                        GValue       *value);
+  gint          (*values_cmp)           (GParamSpec   *pspec,
+                                        const GValue *value1,
+                                        const GValue *value2);
 } ParamSpecClassInfo;
 
 static void
@@ -1071,27 +728,22 @@ param_spec_class_init (gpointer g_class,
 {
   GParamSpecClass *class = g_class;
   ParamSpecClassInfo *info = class_data;
-  
+
+  g_assert (info->value_type && !G_TYPE_IS_PARAM (info->value_type));
+
+  class->value_type = info->value_type;
   if (info->finalize)
     class->finalize = info->finalize;
-  if (info->param_init)
-    class->param_init = info->param_init;
-  if (info->param_free_value)
-    class->param_free_value = info->param_free_value;
-  if (info->param_validate)
-    class->param_validate = info->param_validate;
-  if (info->param_values_cmp)
-    class->param_values_cmp = info->param_values_cmp;
-  if (info->param_copy_value)
-    class->param_copy_value = info->param_copy_value;
-  class->collect_type = info->collect_type;
-  class->param_collect_value = info->param_collect_value;
-  class->lcopy_type = info->lcopy_type;
-  class->param_lcopy_value = info->param_lcopy_value;
+  if (info->value_set_default)
+    class->value_set_default = info->value_set_default;
+  if (info->value_validate)
+    class->value_validate = info->value_validate;
+  if (info->values_cmp)
+    class->values_cmp = info->values_cmp;
 }
 
 void
-g_param_spec_types_init (void) /* sync with glib-gparam.c */
+g_param_spec_types_init (void) /* sync with gtype.c */
 {
   GTypeInfo info = {
     sizeof (GParamSpecClass),  /* class_size */
@@ -1110,16 +762,11 @@ g_param_spec_types_init (void)   /* sync with glib-gparam.c */
    */
   {
     static const ParamSpecClassInfo class_info = {
+      G_TYPE_CHAR,             /* value_type */
       NULL,                    /* finalize */
-      param_char_init,         /* param_init */
-      NULL,                    /* param_free_value */
-      param_char_validate,     /* param_validate */
-      param_int_values_cmp,    /* param_values_cmp */
-      NULL,                    /* param_copy_value */
-      G_VALUE_COLLECT_INT,     /* collect_type */
-      param_int_collect_value, /* param_collect_value */
-      G_VALUE_COLLECT_POINTER, /* lcopy_type */
-      param_char_lcopy_value,  /* param_lcopy_value */
+      param_char_set_default,  /* value_set_default */
+      param_char_validate,     /* value_validate */
+      param_int_values_cmp,    /* values_cmp */
     };
     info.class_data = &class_info;
     info.instance_size = sizeof (GParamSpecChar);
@@ -1132,16 +779,11 @@ g_param_spec_types_init (void)   /* sync with glib-gparam.c */
    */
   {
     static const ParamSpecClassInfo class_info = {
+      G_TYPE_UCHAR,            /* value_type */
       NULL,                    /* finalize */
-      param_uchar_init,                /* param_init */
-      NULL,                    /* param_free_value */
-      param_uchar_validate,    /* param_validate */
-      param_uint_values_cmp,   /* param_values_cmp */
-      NULL,                    /* param_copy_value */
-      G_VALUE_COLLECT_INT,     /* collect_type */
-      param_int_collect_value, /* param_collect_value */
-      G_VALUE_COLLECT_POINTER, /* lcopy_type */
-      param_char_lcopy_value,  /* param_lcopy_value */
+      param_uchar_set_default, /* value_set_default */
+      param_uchar_validate,    /* value_validate */
+      param_uint_values_cmp,   /* values_cmp */
     };
     info.class_data = &class_info;
     info.instance_size = sizeof (GParamSpecUChar);
@@ -1150,42 +792,32 @@ g_param_spec_types_init (void)   /* sync with glib-gparam.c */
     g_assert (type == G_TYPE_PARAM_UCHAR);
   }
   
-  /* G_TYPE_PARAM_BOOL
+  /* G_TYPE_PARAM_BOOLEAN
    */
   {
     static const ParamSpecClassInfo class_info = {
-      NULL,                    /* finalize */
-      param_bool_init,         /* param_init */
-      NULL,                    /* param_free_value */
-      param_bool_validate,     /* param_validate */
-      param_int_values_cmp,    /* param_values_cmp */
-      NULL,                    /* param_copy_value */
-      G_VALUE_COLLECT_INT,     /* collect_type */
-      param_int_collect_value, /* param_collect_value */
-      G_VALUE_COLLECT_POINTER, /* lcopy_type */
-      param_bool_lcopy_value,  /* param_lcopy_value */
+      G_TYPE_BOOLEAN,            /* value_type */
+      NULL,                      /* finalize */
+      param_boolean_set_default, /* value_set_default */
+      param_boolean_validate,    /* value_validate */
+      param_int_values_cmp,      /* values_cmp */
     };
     info.class_data = &class_info;
-    info.instance_size = sizeof (GParamSpecBool);
+    info.instance_size = sizeof (GParamSpecBoolean);
     info.instance_init = (GInstanceInitFunc) NULL;
-    type = g_type_register_static (G_TYPE_PARAM, "GParamBool", &info);
-    g_assert (type == G_TYPE_PARAM_BOOL);
+    type = g_type_register_static (G_TYPE_PARAM, "GParamBoolean", &info);
+    g_assert (type == G_TYPE_PARAM_BOOLEAN);
   }
   
   /* G_TYPE_PARAM_INT
    */
   {
     static const ParamSpecClassInfo class_info = {
+      G_TYPE_INT,              /* value_type */
       NULL,                    /* finalize */
-      param_int_init,          /* param_init */
-      NULL,                    /* param_free_value */
-      param_int_validate,      /* param_validate */
-      param_int_values_cmp,    /* param_values_cmp */
-      NULL,                    /* param_copy_value */
-      G_VALUE_COLLECT_INT,     /* collect_type */
-      param_int_collect_value, /* param_collect_value */
-      G_VALUE_COLLECT_POINTER, /* lcopy_type */
-      param_int_lcopy_value,   /* param_lcopy_value */
+      param_int_set_default,   /* value_set_default */
+      param_int_validate,      /* value_validate */
+      param_int_values_cmp,    /* values_cmp */
     };
     info.class_data = &class_info;
     info.instance_size = sizeof (GParamSpecInt);
@@ -1198,16 +830,11 @@ g_param_spec_types_init (void)   /* sync with glib-gparam.c */
    */
   {
     static const ParamSpecClassInfo class_info = {
+      G_TYPE_UINT,             /* value_type */
       NULL,                    /* finalize */
-      param_uint_init,         /* param_init */
-      NULL,                    /* param_free_value */
-      param_uint_validate,     /* param_validate */
-      param_uint_values_cmp,   /* param_values_cmp */
-      NULL,                    /* param_copy_value */
-      G_VALUE_COLLECT_INT,     /* collect_type */
-      param_int_collect_value, /* param_collect_value */
-      G_VALUE_COLLECT_POINTER, /* lcopy_type */
-      param_int_lcopy_value,   /* param_lcopy_value */
+      param_uint_set_default,  /* value_set_default */
+      param_uint_validate,     /* value_validate */
+      param_uint_values_cmp,   /* values_cmp */
     };
     info.class_data = &class_info;
     info.instance_size = sizeof (GParamSpecUInt);
@@ -1220,16 +847,11 @@ g_param_spec_types_init (void)   /* sync with glib-gparam.c */
    */
   {
     static const ParamSpecClassInfo class_info = {
+      G_TYPE_LONG,             /* value_type */
       NULL,                    /* finalize */
-      param_long_init,         /* param_init */
-      NULL,                    /* param_free_value */
-      param_long_validate,     /* param_validate */
-      param_long_values_cmp,   /* param_values_cmp */
-      NULL,                    /* param_copy_value */
-      G_VALUE_COLLECT_LONG,    /* collect_type */
-      param_long_collect_value,        /* param_collect_value */
-      G_VALUE_COLLECT_POINTER, /* lcopy_type */
-      param_long_lcopy_value,  /* param_lcopy_value */
+      param_long_set_default,  /* value_set_default */
+      param_long_validate,     /* value_validate */
+      param_long_values_cmp,   /* values_cmp */
     };
     info.class_data = &class_info;
     info.instance_size = sizeof (GParamSpecLong);
@@ -1242,16 +864,11 @@ g_param_spec_types_init (void)   /* sync with glib-gparam.c */
    */
   {
     static const ParamSpecClassInfo class_info = {
+      G_TYPE_ULONG,            /* value_type */
       NULL,                    /* finalize */
-      param_ulong_init,                /* param_init */
-      NULL,                    /* param_free_value */
-      param_ulong_validate,    /* param_validate */
-      param_ulong_values_cmp,  /* param_values_cmp */
-      NULL,                    /* param_copy_value */
-      G_VALUE_COLLECT_LONG,    /* collect_type */
-      param_long_collect_value,        /* param_collect_value */
-      G_VALUE_COLLECT_POINTER, /* lcopy_type */
-      param_long_lcopy_value,  /* param_lcopy_value */
+      param_ulong_set_default, /* value_set_default */
+      param_ulong_validate,    /* value_validate */
+      param_ulong_values_cmp,  /* values_cmp */
     };
     info.class_data = &class_info;
     info.instance_size = sizeof (GParamSpecULong);
@@ -1264,16 +881,11 @@ g_param_spec_types_init (void)   /* sync with glib-gparam.c */
    */
   {
     static const ParamSpecClassInfo class_info = {
+      G_TYPE_ENUM,             /* value_type */
       param_spec_enum_finalize,        /* finalize */
-      param_enum_init,         /* param_init */
-      NULL,                    /* param_free_value */
-      param_enum_validate,     /* param_validate */
-      param_long_values_cmp,   /* param_values_cmp */
-      NULL,                    /* param_copy_value */
-      G_VALUE_COLLECT_INT,     /* collect_type */
-      param_enum_collect_value,        /* param_collect_value */
-      G_VALUE_COLLECT_POINTER, /* lcopy_type */
-      param_enum_lcopy_value,  /* param_lcopy_value */
+      param_enum_set_default,  /* value_set_default */
+      param_enum_validate,     /* value_validate */
+      param_long_values_cmp,   /* values_cmp */
     };
     info.class_data = &class_info;
     info.instance_size = sizeof (GParamSpecEnum);
@@ -1286,16 +898,11 @@ g_param_spec_types_init (void)   /* sync with glib-gparam.c */
    */
   {
     static const ParamSpecClassInfo class_info = {
+      G_TYPE_FLAGS,            /* value_type */
       param_spec_flags_finalize,/* finalize */
-      param_flags_init,                /* param_init */
-      NULL,                    /* param_free_value */
-      param_flags_validate,    /* param_validate */
-      param_ulong_values_cmp,  /* param_values_cmp */
-      NULL,                    /* param_copy_value */
-      G_VALUE_COLLECT_INT,     /* collect_type */
-      param_enum_collect_value,        /* param_collect_value */
-      G_VALUE_COLLECT_POINTER, /* lcopy_type */
-      param_enum_lcopy_value,  /* param_lcopy_value */
+      param_flags_set_default, /* value_set_default */
+      param_flags_validate,    /* value_validate */
+      param_ulong_values_cmp,  /* values_cmp */
     };
     info.class_data = &class_info;
     info.instance_size = sizeof (GParamSpecFlags);
@@ -1308,16 +915,11 @@ g_param_spec_types_init (void)   /* sync with glib-gparam.c */
    */
   {
     static const ParamSpecClassInfo class_info = {
+      G_TYPE_FLOAT,            /* value_type */
       NULL,                    /* finalize */
-      param_float_init,                /* param_init */
-      NULL,                    /* param_free_value */
-      param_float_validate,    /* param_validate */
-      param_float_values_cmp,  /* param_values_cmp */
-      NULL,                    /* param_copy_value */
-      G_VALUE_COLLECT_DOUBLE,  /* collect_type */
-      param_float_collect_value,/* param_collect_value */
-      G_VALUE_COLLECT_POINTER, /* lcopy_type */
-      param_float_lcopy_value, /* param_lcopy_value */
+      param_float_set_default, /* value_set_default */
+      param_float_validate,    /* value_validate */
+      param_float_values_cmp,  /* values_cmp */
     };
     info.class_data = &class_info;
     info.instance_size = sizeof (GParamSpecFloat);
@@ -1330,16 +932,11 @@ g_param_spec_types_init (void)   /* sync with glib-gparam.c */
    */
   {
     static const ParamSpecClassInfo class_info = {
-      NULL,                      /* finalize */
-      param_double_init,         /* param_init */
-      NULL,                      /* param_free_value */
-      param_double_validate,     /* param_validate */
-      param_double_values_cmp,   /* param_values_cmp */
-      NULL,                      /* param_copy_value */
-      G_VALUE_COLLECT_DOUBLE,    /* collect_type */
-      param_double_collect_value, /* param_collect_value */
-      G_VALUE_COLLECT_POINTER,   /* lcopy_type */
-      param_double_lcopy_value,          /* param_lcopy_value */
+      G_TYPE_DOUBLE,           /* value_type */
+      NULL,                    /* finalize */
+      param_double_set_default,        /* value_set_default */
+      param_double_validate,   /* value_validate */
+      param_double_values_cmp, /* values_cmp */
     };
     info.class_data = &class_info;
     info.instance_size = sizeof (GParamSpecDouble);
@@ -1352,16 +949,11 @@ g_param_spec_types_init (void)   /* sync with glib-gparam.c */
    */
   {
     static const ParamSpecClassInfo class_info = {
+      G_TYPE_STRING,             /* value_type */
       param_spec_string_finalize, /* finalize */
-      param_string_init,         /* param_init */
-      param_string_free_value,   /* param_free_value */
-      param_string_validate,     /* param_validate */
-      param_string_values_cmp,   /* param_values_cmp */
-      param_string_copy_value,   /* param_copy_value */
-      G_VALUE_COLLECT_POINTER,   /* collect_type */
-      param_string_collect_value, /* param_collect_value */
-      G_VALUE_COLLECT_POINTER,   /* lcopy_type */
-      param_string_lcopy_value,          /* param_lcopy_value */
+      param_string_set_default,          /* value_set_default */
+      param_string_validate,     /* value_validate */
+      param_string_values_cmp,   /* values_cmp */
     };
     info.class_data = &class_info;
     info.instance_size = sizeof (GParamSpecString);
@@ -1374,16 +966,11 @@ g_param_spec_types_init (void)   /* sync with glib-gparam.c */
    */
   {
     static const ParamSpecClassInfo class_info = {
-      NULL,                      /* finalize */
-      param_object_init,         /* param_init */
-      param_object_free_value,   /* param_free_value */
-      param_object_validate,     /* param_validate */
-      param_object_values_cmp,   /* param_values_cmp */
-      param_object_copy_value,   /* param_copy_value */
-      G_VALUE_COLLECT_POINTER,   /* collect_type */
-      param_object_collect_value, /* param_collect_value */
-      G_VALUE_COLLECT_POINTER,   /* lcopy_type */
-      param_object_lcopy_value,          /* param_lcopy_value */
+      G_TYPE_OBJECT,           /* value_type */
+      NULL,                    /* finalize */
+      param_object_set_default,        /* value_set_default */
+      param_object_validate,   /* value_validate */
+      param_object_values_cmp, /* values_cmp */
     };
     info.class_data = &class_info;
     info.instance_size = sizeof (GParamSpecObject);
@@ -1392,307 +979,61 @@ g_param_spec_types_init (void)  /* sync with glib-gparam.c */
     g_assert (type == G_TYPE_PARAM_OBJECT);
   }
   
-  g_value_register_exchange_func (G_TYPE_PARAM_CHAR,   G_TYPE_PARAM_UCHAR,  value_exch_memcpy);
-  g_value_register_exchange_func (G_TYPE_PARAM_CHAR,   G_TYPE_PARAM_BOOL,   value_exch_memcpy);
-  g_value_register_exchange_func (G_TYPE_PARAM_CHAR,   G_TYPE_PARAM_INT,    value_exch_memcpy);
-  g_value_register_exchange_func (G_TYPE_PARAM_CHAR,   G_TYPE_PARAM_UINT,   value_exch_memcpy);
-  g_value_register_exchange_func (G_TYPE_PARAM_CHAR,   G_TYPE_PARAM_ENUM,   value_exch_memcpy);
-  g_value_register_exchange_func (G_TYPE_PARAM_CHAR,   G_TYPE_PARAM_FLAGS,  value_exch_memcpy); 
-  g_value_register_exchange_func (G_TYPE_PARAM_UCHAR,  G_TYPE_PARAM_BOOL,   value_exch_memcpy);
-  g_value_register_exchange_func (G_TYPE_PARAM_UCHAR,  G_TYPE_PARAM_INT,    value_exch_memcpy);
-  g_value_register_exchange_func (G_TYPE_PARAM_UCHAR,  G_TYPE_PARAM_UINT,   value_exch_memcpy);
-  g_value_register_exchange_func (G_TYPE_PARAM_UCHAR,  G_TYPE_PARAM_ENUM,   value_exch_memcpy);
-  g_value_register_exchange_func (G_TYPE_PARAM_UCHAR,  G_TYPE_PARAM_FLAGS,  value_exch_memcpy); 
-  g_value_register_exchange_func (G_TYPE_PARAM_BOOL,   G_TYPE_PARAM_INT,    value_exch_memcpy);
-  g_value_register_exchange_func (G_TYPE_PARAM_BOOL,   G_TYPE_PARAM_UINT,   value_exch_memcpy);
-  g_value_register_exchange_func (G_TYPE_PARAM_BOOL,   G_TYPE_PARAM_ENUM,   value_exch_memcpy);
-  g_value_register_exchange_func (G_TYPE_PARAM_BOOL,   G_TYPE_PARAM_FLAGS,  value_exch_memcpy); 
-  g_value_register_exchange_func (G_TYPE_PARAM_INT,    G_TYPE_PARAM_UINT,   value_exch_memcpy); 
-  g_value_register_exchange_func (G_TYPE_PARAM_INT,    G_TYPE_PARAM_ENUM,   value_exch_memcpy); 
-  g_value_register_exchange_func (G_TYPE_PARAM_INT,    G_TYPE_PARAM_FLAGS,  value_exch_memcpy); 
-  g_value_register_exchange_func (G_TYPE_PARAM_UINT,   G_TYPE_PARAM_ENUM,   value_exch_memcpy); 
-  g_value_register_exchange_func (G_TYPE_PARAM_UINT,   G_TYPE_PARAM_FLAGS,  value_exch_memcpy); 
-  g_value_register_exchange_func (G_TYPE_PARAM_LONG,   G_TYPE_PARAM_CHAR,   value_exch_long_int); 
-  g_value_register_exchange_func (G_TYPE_PARAM_LONG,   G_TYPE_PARAM_UCHAR,  value_exch_long_uint); 
-  g_value_register_exchange_func (G_TYPE_PARAM_LONG,   G_TYPE_PARAM_BOOL,   value_exch_long_int); 
-  g_value_register_exchange_func (G_TYPE_PARAM_LONG,   G_TYPE_PARAM_INT,    value_exch_long_int); 
-  g_value_register_exchange_func (G_TYPE_PARAM_LONG,   G_TYPE_PARAM_UINT,   value_exch_long_uint); 
-  g_value_register_exchange_func (G_TYPE_PARAM_LONG,   G_TYPE_PARAM_ULONG,  value_exch_memcpy); 
-  g_value_register_exchange_func (G_TYPE_PARAM_LONG,   G_TYPE_PARAM_ENUM,   value_exch_long_int); 
-  g_value_register_exchange_func (G_TYPE_PARAM_LONG,   G_TYPE_PARAM_FLAGS,  value_exch_long_uint); 
-  g_value_register_exchange_func (G_TYPE_PARAM_ULONG,  G_TYPE_PARAM_CHAR,   value_exch_ulong_int); 
-  g_value_register_exchange_func (G_TYPE_PARAM_ULONG,  G_TYPE_PARAM_UCHAR,  value_exch_ulong_uint); 
-  g_value_register_exchange_func (G_TYPE_PARAM_ULONG,  G_TYPE_PARAM_BOOL,   value_exch_ulong_int); 
-  g_value_register_exchange_func (G_TYPE_PARAM_ULONG,  G_TYPE_PARAM_INT,    value_exch_ulong_int); 
-  g_value_register_exchange_func (G_TYPE_PARAM_ULONG,  G_TYPE_PARAM_UINT,   value_exch_ulong_uint); 
-  g_value_register_exchange_func (G_TYPE_PARAM_ULONG,  G_TYPE_PARAM_ENUM,   value_exch_ulong_int); 
-  g_value_register_exchange_func (G_TYPE_PARAM_ULONG,  G_TYPE_PARAM_FLAGS,  value_exch_ulong_uint); 
-  g_value_register_exchange_func (G_TYPE_PARAM_ENUM,   G_TYPE_PARAM_FLAGS,  value_exch_memcpy); 
-  g_value_register_exchange_func (G_TYPE_PARAM_FLOAT,  G_TYPE_PARAM_CHAR,   value_exch_float_int); 
-  g_value_register_exchange_func (G_TYPE_PARAM_FLOAT,  G_TYPE_PARAM_UCHAR,  value_exch_float_uint); 
-  g_value_register_exchange_func (G_TYPE_PARAM_FLOAT,  G_TYPE_PARAM_BOOL,   value_exch_float_int); 
-  g_value_register_exchange_func (G_TYPE_PARAM_FLOAT,  G_TYPE_PARAM_INT,    value_exch_float_int); 
-  g_value_register_exchange_func (G_TYPE_PARAM_FLOAT,  G_TYPE_PARAM_UINT,   value_exch_float_uint); 
-  g_value_register_exchange_func (G_TYPE_PARAM_FLOAT,  G_TYPE_PARAM_LONG,   value_exch_float_long); 
-  g_value_register_exchange_func (G_TYPE_PARAM_FLOAT,  G_TYPE_PARAM_ULONG,  value_exch_float_ulong);
-  g_value_register_exchange_func (G_TYPE_PARAM_FLOAT,  G_TYPE_PARAM_ENUM,   value_exch_float_int); 
-  g_value_register_exchange_func (G_TYPE_PARAM_FLOAT,  G_TYPE_PARAM_FLAGS,  value_exch_float_uint); 
-  g_value_register_exchange_func (G_TYPE_PARAM_DOUBLE, G_TYPE_PARAM_CHAR,   value_exch_double_int); 
-  g_value_register_exchange_func (G_TYPE_PARAM_DOUBLE, G_TYPE_PARAM_UCHAR,  value_exch_double_uint); 
-  g_value_register_exchange_func (G_TYPE_PARAM_DOUBLE, G_TYPE_PARAM_BOOL,   value_exch_double_int); 
-  g_value_register_exchange_func (G_TYPE_PARAM_DOUBLE, G_TYPE_PARAM_INT,    value_exch_double_int); 
-  g_value_register_exchange_func (G_TYPE_PARAM_DOUBLE, G_TYPE_PARAM_UINT,   value_exch_double_uint); 
-  g_value_register_exchange_func (G_TYPE_PARAM_DOUBLE, G_TYPE_PARAM_LONG,   value_exch_double_long);
-  g_value_register_exchange_func (G_TYPE_PARAM_DOUBLE, G_TYPE_PARAM_ULONG,  value_exch_double_ulong);
-  g_value_register_exchange_func (G_TYPE_PARAM_DOUBLE, G_TYPE_PARAM_ENUM,   value_exch_double_int); 
-  g_value_register_exchange_func (G_TYPE_PARAM_DOUBLE, G_TYPE_PARAM_FLAGS,  value_exch_double_uint);
-  g_value_register_exchange_func (G_TYPE_PARAM_DOUBLE, G_TYPE_PARAM_FLOAT,  value_exch_double_float); 
-}
-
-
-/* --- GValue functions --- */
-void
-g_value_set_char (GValue *value,
-                 gint8   v_char)
-{
-  g_return_if_fail (G_IS_VALUE_CHAR (value));
-  
-  value->data[0].v_int = v_char;
-}
-
-gint8
-g_value_get_char (GValue *value)
-{
-  g_return_val_if_fail (G_IS_VALUE_CHAR (value), 0);
-  
-  return value->data[0].v_int;
-}
-
-void
-g_value_set_uchar (GValue *value,
-                  guint8  v_uchar)
-{
-  g_return_if_fail (G_IS_VALUE_UCHAR (value));
-  
-  value->data[0].v_uint = v_uchar;
-}
-
-guint8
-g_value_get_uchar (GValue *value)
-{
-  g_return_val_if_fail (G_IS_VALUE_UCHAR (value), 0);
-  
-  return value->data[0].v_uint;
-}
-
-void
-g_value_set_bool (GValue  *value,
-                 gboolean v_bool)
-{
-  g_return_if_fail (G_IS_VALUE_BOOL (value));
-  
-  value->data[0].v_int = v_bool;
-}
-
-gboolean
-g_value_get_bool (GValue *value)
-{
-  g_return_val_if_fail (G_IS_VALUE_BOOL (value), 0);
-  
-  return value->data[0].v_int;
-}
-
-void
-g_value_set_int (GValue *value,
-                gint    v_int)
-{
-  g_return_if_fail (G_IS_VALUE_INT (value));
-  
-  value->data[0].v_int = v_int;
-}
-
-gint
-g_value_get_int (GValue *value)
-{
-  g_return_val_if_fail (G_IS_VALUE_INT (value), 0);
-  
-  return value->data[0].v_int;
-}
-
-void
-g_value_set_uint (GValue *value,
-                 guint   v_uint)
-{
-  g_return_if_fail (G_IS_VALUE_UINT (value));
-  
-  value->data[0].v_uint = v_uint;
-}
-
-guint
-g_value_get_uint (GValue *value)
-{
-  g_return_val_if_fail (G_IS_VALUE_UINT (value), 0);
-  
-  return value->data[0].v_uint;
-}
-
-void
-g_value_set_long (GValue *value,
-                 glong   v_long)
-{
-  g_return_if_fail (G_IS_VALUE_LONG (value));
-  
-  value->data[0].v_long = v_long;
-}
-
-glong
-g_value_get_long (GValue *value)
-{
-  g_return_val_if_fail (G_IS_VALUE_LONG (value), 0);
-  
-  return value->data[0].v_long;
-}
-
-void
-g_value_set_ulong (GValue *value,
-                  gulong  v_ulong)
-{
-  g_return_if_fail (G_IS_VALUE_ULONG (value));
-  
-  value->data[0].v_ulong = v_ulong;
-}
-
-gulong
-g_value_get_ulong (GValue *value)
-{
-  g_return_val_if_fail (G_IS_VALUE_ULONG (value), 0);
-  
-  return value->data[0].v_ulong;
-}
-
-void
-g_value_set_enum (GValue *value,
-                 gint    v_enum)
-{
-  g_return_if_fail (G_IS_VALUE_ENUM (value));
-  
-  value->data[0].v_long = v_enum;
-}
-
-gint
-g_value_get_enum (GValue *value)
-{
-  g_return_val_if_fail (G_IS_VALUE_ENUM (value), 0);
-  
-  return value->data[0].v_long;
-}
-
-void
-g_value_set_flags (GValue *value,
-                  guint   v_flags)
-{
-  g_return_if_fail (G_IS_VALUE_FLAGS (value));
-  
-  value->data[0].v_ulong = v_flags;
-}
-
-guint
-g_value_get_flags (GValue *value)
-{
-  g_return_val_if_fail (G_IS_VALUE_FLAGS (value), 0);
-  
-  return value->data[0].v_ulong;
-}
-
-void
-g_value_set_float (GValue *value,
-                  gfloat  v_float)
-{
-  g_return_if_fail (G_IS_VALUE_FLOAT (value));
-  
-  value->data[0].v_float = v_float;
-}
-
-gfloat
-g_value_get_float (GValue *value)
-{
-  g_return_val_if_fail (G_IS_VALUE_FLOAT (value), 0);
-  
-  return value->data[0].v_float;
-}
-
-void
-g_value_set_double (GValue *value,
-                   gdouble v_double)
-{
-  g_return_if_fail (G_IS_VALUE_DOUBLE (value));
-  
-  value->data[0].v_double = v_double;
-}
-
-gdouble
-g_value_get_double (GValue *value)
-{
-  g_return_val_if_fail (G_IS_VALUE_DOUBLE (value), 0);
-  
-  return value->data[0].v_double;
-}
-
-void
-g_value_set_string (GValue     *value,
-                   const gchar *v_string)
-{
-  g_return_if_fail (G_IS_VALUE_STRING (value));
-  
-  g_free (value->data[0].v_pointer);
-  value->data[0].v_pointer = g_strdup (v_string);
-}
-
-gchar*
-g_value_get_string (GValue *value)
-{
-  g_return_val_if_fail (G_IS_VALUE_STRING (value), NULL);
-  
-  return value->data[0].v_pointer;
-}
-
-gchar*
-g_value_dup_string (GValue *value)
-{
-  g_return_val_if_fail (G_IS_VALUE_STRING (value), NULL);
-  
-  return g_strdup (value->data[0].v_pointer);
-}
-
-void
-g_value_set_object (GValue  *value,
-                   GObject *v_object)
-{
-  g_return_if_fail (G_IS_VALUE_OBJECT (value));
-  if (v_object)
-    g_return_if_fail (G_IS_OBJECT (v_object));
-  
-  if (value->data[0].v_pointer)
-    g_object_unref (value->data[0].v_pointer);
-  value->data[0].v_pointer = v_object;
-  if (value->data[0].v_pointer)
-    g_object_ref (value->data[0].v_pointer);
-}
-
-GObject*
-g_value_get_object (GValue *value)
-{
-  g_return_val_if_fail (G_IS_VALUE_OBJECT (value), NULL);
-  
-  return value->data[0].v_pointer;
-}
-
-GObject*
-g_value_dup_object (GValue *value)
-{
-  g_return_val_if_fail (G_IS_VALUE_OBJECT (value), NULL);
-  
-  return value->data[0].v_pointer ? g_object_ref (value->data[0].v_pointer) : NULL;
+  g_value_register_exchange_func (G_TYPE_CHAR,    G_TYPE_UCHAR,   value_exch_memcpy);
+  g_value_register_exchange_func (G_TYPE_CHAR,    G_TYPE_BOOLEAN, value_exch_memcpy);
+  g_value_register_exchange_func (G_TYPE_CHAR,    G_TYPE_INT,     value_exch_memcpy);
+  g_value_register_exchange_func (G_TYPE_CHAR,    G_TYPE_UINT,    value_exch_memcpy);
+  g_value_register_exchange_func (G_TYPE_CHAR,    G_TYPE_ENUM,    value_exch_memcpy);
+  g_value_register_exchange_func (G_TYPE_CHAR,    G_TYPE_FLAGS,   value_exch_memcpy); 
+  g_value_register_exchange_func (G_TYPE_UCHAR,   G_TYPE_BOOLEAN, value_exch_memcpy);
+  g_value_register_exchange_func (G_TYPE_UCHAR,   G_TYPE_INT,     value_exch_memcpy);
+  g_value_register_exchange_func (G_TYPE_UCHAR,   G_TYPE_UINT,    value_exch_memcpy);
+  g_value_register_exchange_func (G_TYPE_UCHAR,   G_TYPE_ENUM,    value_exch_memcpy);
+  g_value_register_exchange_func (G_TYPE_UCHAR,   G_TYPE_FLAGS,   value_exch_memcpy); 
+  g_value_register_exchange_func (G_TYPE_BOOLEAN, G_TYPE_INT,     value_exch_memcpy);
+  g_value_register_exchange_func (G_TYPE_BOOLEAN, G_TYPE_UINT,    value_exch_memcpy);
+  g_value_register_exchange_func (G_TYPE_BOOLEAN, G_TYPE_ENUM,    value_exch_memcpy);
+  g_value_register_exchange_func (G_TYPE_BOOLEAN, G_TYPE_FLAGS,   value_exch_memcpy); 
+  g_value_register_exchange_func (G_TYPE_INT,     G_TYPE_UINT,    value_exch_memcpy); 
+  g_value_register_exchange_func (G_TYPE_INT,     G_TYPE_ENUM,    value_exch_memcpy); 
+  g_value_register_exchange_func (G_TYPE_INT,     G_TYPE_FLAGS,   value_exch_memcpy); 
+  g_value_register_exchange_func (G_TYPE_UINT,    G_TYPE_ENUM,    value_exch_memcpy); 
+  g_value_register_exchange_func (G_TYPE_UINT,    G_TYPE_FLAGS,   value_exch_memcpy); 
+  g_value_register_exchange_func (G_TYPE_LONG,    G_TYPE_CHAR,    value_exch_long_int); 
+  g_value_register_exchange_func (G_TYPE_LONG,    G_TYPE_UCHAR,   value_exch_long_uint); 
+  g_value_register_exchange_func (G_TYPE_LONG,    G_TYPE_BOOLEAN, value_exch_long_int); 
+  g_value_register_exchange_func (G_TYPE_LONG,    G_TYPE_INT,     value_exch_long_int); 
+  g_value_register_exchange_func (G_TYPE_LONG,    G_TYPE_UINT,    value_exch_long_uint); 
+  g_value_register_exchange_func (G_TYPE_LONG,    G_TYPE_ULONG,   value_exch_memcpy); 
+  g_value_register_exchange_func (G_TYPE_LONG,    G_TYPE_ENUM,    value_exch_long_int); 
+  g_value_register_exchange_func (G_TYPE_LONG,    G_TYPE_FLAGS,   value_exch_long_uint); 
+  g_value_register_exchange_func (G_TYPE_ULONG,   G_TYPE_CHAR,    value_exch_ulong_int); 
+  g_value_register_exchange_func (G_TYPE_ULONG,   G_TYPE_UCHAR,   value_exch_ulong_uint); 
+  g_value_register_exchange_func (G_TYPE_ULONG,   G_TYPE_BOOLEAN, value_exch_ulong_int); 
+  g_value_register_exchange_func (G_TYPE_ULONG,   G_TYPE_INT,     value_exch_ulong_int); 
+  g_value_register_exchange_func (G_TYPE_ULONG,   G_TYPE_UINT,    value_exch_ulong_uint); 
+  g_value_register_exchange_func (G_TYPE_ULONG,   G_TYPE_ENUM,    value_exch_ulong_int); 
+  g_value_register_exchange_func (G_TYPE_ULONG,   G_TYPE_FLAGS,   value_exch_ulong_uint); 
+  g_value_register_exchange_func (G_TYPE_ENUM,    G_TYPE_FLAGS,   value_exch_memcpy); 
+  g_value_register_exchange_func (G_TYPE_FLOAT,   G_TYPE_CHAR,    value_exch_float_int); 
+  g_value_register_exchange_func (G_TYPE_FLOAT,   G_TYPE_UCHAR,   value_exch_float_uint); 
+  g_value_register_exchange_func (G_TYPE_FLOAT,   G_TYPE_BOOLEAN, value_exch_float_int); 
+  g_value_register_exchange_func (G_TYPE_FLOAT,   G_TYPE_INT,     value_exch_float_int); 
+  g_value_register_exchange_func (G_TYPE_FLOAT,   G_TYPE_UINT,    value_exch_float_uint); 
+  g_value_register_exchange_func (G_TYPE_FLOAT,   G_TYPE_LONG,    value_exch_float_long); 
+  g_value_register_exchange_func (G_TYPE_FLOAT,   G_TYPE_ULONG,   value_exch_float_ulong);
+  g_value_register_exchange_func (G_TYPE_FLOAT,   G_TYPE_ENUM,    value_exch_float_int); 
+  g_value_register_exchange_func (G_TYPE_FLOAT,   G_TYPE_FLAGS,   value_exch_float_uint); 
+  g_value_register_exchange_func (G_TYPE_DOUBLE,  G_TYPE_CHAR,    value_exch_double_int); 
+  g_value_register_exchange_func (G_TYPE_DOUBLE,  G_TYPE_UCHAR,   value_exch_double_uint); 
+  g_value_register_exchange_func (G_TYPE_DOUBLE,  G_TYPE_BOOLEAN, value_exch_double_int); 
+  g_value_register_exchange_func (G_TYPE_DOUBLE,  G_TYPE_INT,     value_exch_double_int); 
+  g_value_register_exchange_func (G_TYPE_DOUBLE,  G_TYPE_UINT,    value_exch_double_uint); 
+  g_value_register_exchange_func (G_TYPE_DOUBLE,  G_TYPE_LONG,    value_exch_double_long);
+  g_value_register_exchange_func (G_TYPE_DOUBLE,  G_TYPE_ULONG,   value_exch_double_ulong);
+  g_value_register_exchange_func (G_TYPE_DOUBLE,  G_TYPE_ENUM,    value_exch_double_int); 
+  g_value_register_exchange_func (G_TYPE_DOUBLE,  G_TYPE_FLAGS,   value_exch_double_uint);
+  g_value_register_exchange_func (G_TYPE_DOUBLE,  G_TYPE_FLOAT,   value_exch_double_float); 
 }
 
 
@@ -1742,17 +1083,17 @@ g_param_spec_uchar (const gchar *name,
 }
 
 GParamSpec*
-g_param_spec_bool (const gchar *name,
-                  const gchar *nick,
-                  const gchar *blurb,
-                  gboolean     default_value,
-                  GParamFlags  flags)
-{
-  GParamSpecBool *bspec = g_param_spec_internal (G_TYPE_PARAM_BOOL,
-                                                name,
-                                                nick,
-                                                blurb,
-                                                flags);
+g_param_spec_boolean (const gchar *name,
+                     const gchar *nick,
+                     const gchar *blurb,
+                     gboolean     default_value,
+                     GParamFlags  flags)
+{
+  GParamSpecBoolean *bspec = g_param_spec_internal (G_TYPE_PARAM_BOOLEAN,
+                                                   name,
+                                                   nick,
+                                                   blurb,
+                                                   flags);
   
   bspec->default_value = default_value;
   
index 1becdefe85e56aea902fe1eedd95dbd65c1cd5a2..01219d06c23bcc3412c26f848708f1891ef935ae 100644 (file)
@@ -33,61 +33,48 @@ extern "C" {
 
 
 /* --- 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_BOOLEAN(pspec)  (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_BOOLEAN))
+#define G_PARAM_SPEC_BOOLEAN(pspec)     (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_BOOLEAN, GParamSpecBoolean))
 #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;
+typedef struct _GParamSpecChar    GParamSpecChar;
+typedef struct _GParamSpecUChar   GParamSpecUChar;
+typedef struct _GParamSpecBoolean GParamSpecBoolean;
+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;
@@ -104,7 +91,7 @@ struct _GParamSpecUChar
   guint8        maximum;
   guint8        default_value;
 };
-struct _GParamSpecBool
+struct _GParamSpecBoolean
 {
   GParamSpec    parent_instance;
   
@@ -193,50 +180,6 @@ struct _GParamSpecObject
 };
 
 
-/* --- 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,
@@ -252,7 +195,7 @@ GParamSpec*     g_param_spec_uchar      (const gchar    *name,
                                          guint8          maximum,
                                          guint8          default_value,
                                          GParamFlags     flags);
-GParamSpec*     g_param_spec_bool       (const gchar    *name,
+GParamSpec*     g_param_spec_boolean    (const gchar    *name,
                                          const gchar    *nick,
                                          const gchar    *blurb,
                                          gboolean        default_value,
index b00e58b41dd1ae10887d0be1bb695f3ab18757b7..80394d50bd9ecf8f2b8f72ee902404361989d627 100644 (file)
@@ -18,8 +18,6 @@
  */
 #include       "gtype.h"
 
-#include       "genums.h"
-#include       "gobject.h"
 #include       <string.h>
 
 #define FIXME_DISABLE_PREALLOCATIONS
@@ -45,7 +43,7 @@
                                 G_TYPE_FLAG_DEEP_DERIVABLE)
 #define        g_type_plugin_ref(p)                            ((p)->vtable->plugin_ref (p))
 #define g_type_plugin_unref(p)                         ((p)->vtable->plugin_unref (p))
-#define        g_type_plugin_complete_type_info(p,t,i)         ((p)->vtable->complete_type_info ((p), (t), (i)))
+#define        g_type_plugin_complete_type_info(p,t,i,v)       ((p)->vtable->complete_type_info ((p), (t), (i), (v)))
 #define        g_type_plugin_complete_interface_info(p,f,t,i)  ((p)->vtable->complete_interface_info ((p), (f), (t), (i)))
 
 typedef struct _TypeNode        TypeNode;
@@ -61,10 +59,13 @@ typedef struct _IFaceHolder IFaceHolder;
 /* --- prototypes --- */
 static inline GTypeFundamentalInfo*    type_node_fundamental_info      (TypeNode               *node);
 static       void                      type_data_make                  (TypeNode               *node,
-                                                                        const GTypeInfo        *info);
+                                                                        const GTypeInfo        *info,
+                                                                        const GTypeValueTable  *value_table);
 static inline void                     type_data_ref                   (TypeNode               *node);
-static inline void                     type_data_unref                 (TypeNode               *node);
-static       void                      type_data_last_unref            (GType                   type);
+static inline void                     type_data_unref                 (TypeNode               *node,
+                                                                        gboolean                uncached);
+static       void                      type_data_last_unref            (GType                   type,
+                                                                        gboolean                uncached);
 
 
 /* --- structures --- */
@@ -83,7 +84,7 @@ struct _TypeNode
   GData       *static_gdata;
   union {
     IFaceEntry  *iface_entries;
-    IFaceHolder *iholders;
+    IFaceHolder *iface_conformants;
   } private;
   GType        supers[1]; /* flexible array */
 };
@@ -99,21 +100,27 @@ struct _IFaceHolder
   GTypePlugin    *plugin;
   IFaceHolder    *next;
 };
+struct _IFaceEntry
+{
+  GType           iface_type;
+  GTypeInterface *vtable;
+};
 struct _CommonData
 {
-  guint                    ref_count;
+  guint             ref_count;
+  GTypeValueTable  *value_table;
 };
 struct _IFaceData
 {
   CommonData         common;
-  guint              vtable_size;
+  guint16            vtable_size;
   GBaseInitFunc      vtable_init_base;
   GBaseFinalizeFunc  vtable_finalize_base;
 };
 struct _ClassData
 {
   CommonData         common;
-  guint              class_size;
+  guint16            class_size;
   GBaseInitFunc      class_init_base;
   GBaseFinalizeFunc  class_finalize_base;
   GClassInitFunc     class_init;
@@ -124,7 +131,7 @@ struct _ClassData
 struct _InstanceData
 {
   CommonData         common;
-  guint              class_size;
+  guint16            class_size;
   GBaseInitFunc      class_init_base;
   GBaseFinalizeFunc  class_finalize_base;
   GClassInitFunc     class_init;
@@ -143,11 +150,15 @@ union _TypeData
   ClassData          class;
   InstanceData       instance;
 };
-struct _IFaceEntry
-{
-  GType           iface_type;
-  GTypeInterface *vtable;
-};
+typedef struct {
+  gpointer            cache_data;
+  GTypeClassCacheFunc cache_func;
+} ClassCacheFunc;
+
+
+/* --- variables --- */
+static guint           n_class_cache_funcs = 0;
+static ClassCacheFunc *class_cache_funcs = NULL;
 
 
 /* --- externs --- */
@@ -193,7 +204,7 @@ type_node_any_new (TypeNode    *pnode,
     g_type_nodes[ftype] = g_renew (TypeNode*, g_type_nodes[ftype], 1 << g_bit_storage (g_branch_seqnos[ftype] - 1));
 
   if (!pnode)
-    node_size += sizeof (GTypeFundamentalInfo);         /* fundamental type */
+    node_size += sizeof (GTypeFundamentalInfo);         /* fundamental type info */
   node_size += SIZEOF_BASE_TYPE_NODE ();        /* TypeNode structure */
   node_size += sizeof (GType[1 + n_supers + 1]); /* self + anchestors + 0 for ->supers[] */
   node = g_malloc0 (node_size);
@@ -213,7 +224,7 @@ type_node_any_new (TypeNode    *pnode,
 
       node->n_ifaces = 0;
       if (node->is_iface)
-       node->private.iholders = NULL;
+       node->private.iface_conformants = NULL;
       else
        node->private.iface_entries = NULL;
     }
@@ -229,7 +240,7 @@ type_node_any_new (TypeNode    *pnode,
       if (node->is_iface)
        {
          node->n_ifaces = 0;
-         node->private.iholders = NULL;
+         node->private.iface_conformants = NULL;
        }
       else
        {
@@ -315,8 +326,8 @@ type_node_new (TypeNode    *pnode,
 }
 
 static inline IFaceEntry*
-type_lookup_iface_entry (TypeNode       *node,
-                        TypeNode       *iface)
+type_lookup_iface_entry (TypeNode *node,
+                        TypeNode *iface)
 {
   if (iface->is_iface && node->n_ifaces)
     {
@@ -476,10 +487,59 @@ check_derivation (GType        parent_type,
 }
 
 static gboolean
-check_type_info (TypeNode             *pnode,
-                GType                 ftype,
-                const gchar          *type_name,
-                const GTypeInfo      *info)
+check_value_table (const gchar           *type_name,
+                  const GTypeValueTable *value_table)
+{
+  if (!value_table)
+    return FALSE;
+  else if (value_table->value_init == NULL)
+    {
+      if (value_table->value_free || value_table->value_copy ||
+         value_table->collect_type || value_table->collect_value ||
+         value_table->lcopy_type || value_table->lcopy_value)
+       g_warning ("cannot handle uninitializable values of type `%s'",
+                  type_name);
+
+      return FALSE;
+    }
+  else /* value_table->value_init != NULL */
+    {
+      if (!value_table->value_free)
+       {
+         /* +++ optional +++
+          * g_warning ("missing `value_free()' for type `%s'", type_name);
+          * return FALSE;
+          */
+       }
+      if (!value_table->value_copy)
+       {
+         g_warning ("missing `value_copy()' for type `%s'", type_name);
+         return FALSE;
+       }
+      if ((value_table->collect_type || value_table->collect_value) &&
+         (!value_table->collect_type || !value_table->collect_value))
+       {
+         g_warning ("one of `collect_type' and `collect_value()' is unspecified for type `%s'",
+                    type_name);
+         return FALSE;
+       }
+      if ((value_table->lcopy_type || value_table->lcopy_value) &&
+         (!value_table->lcopy_type || !value_table->lcopy_value))
+       {
+         g_warning ("one of `lcopy_type' and `lcopy_value()' is unspecified for type `%s'",
+                    type_name);
+         return FALSE;
+       }
+    }
+
+  return TRUE;
+}
+
+static gboolean
+check_type_info (TypeNode        *pnode,
+                GType            ftype,
+                const gchar     *type_name,
+                const GTypeInfo *info)
 {
   GTypeFundamentalInfo *finfo = type_node_fundamental_info (LOOKUP_TYPE_NODE (ftype));
   gboolean is_interface = G_TYPE_IS_INTERFACE (ftype);
@@ -636,16 +696,37 @@ check_interface_info (TypeNode             *iface,
 
 /* --- type info (type node data) --- */
 static void
-type_data_make (TypeNode        *node,
-               const GTypeInfo *info)
+type_data_make (TypeNode              *node,
+               const GTypeInfo       *info,
+               const GTypeValueTable *value_table)
 {
-  TypeData *data = NULL;
-
+  TypeData *data;
+  GTypeValueTable *vtable = NULL;
+  guint vtable_size = 0;
+  
   g_assert (node->data == NULL && info != NULL);
   
+  if (!value_table)
+    {
+      TypeNode *pnode = LOOKUP_TYPE_NODE (NODE_PARENT_TYPE (node));
+      
+      if (pnode)
+       vtable = pnode->data->common.value_table;
+      else
+       {
+         static const GTypeValueTable zero_vtable = { NULL, };
+         
+         value_table = &zero_vtable;
+       }
+    }
+  if (value_table)
+    vtable_size = sizeof (GTypeValueTable);
+  
   if (node->is_instantiatable) /* carefull, is_instantiatable is also is_classed */
     {
-      data = g_malloc0 (sizeof (InstanceData));
+      data = g_malloc0 (sizeof (InstanceData) + vtable_size);
+      if (vtable_size)
+       vtable = G_STRUCT_MEMBER_P (data, sizeof (InstanceData));
       data->instance.class_size = info->class_size;
       data->instance.class_init_base = info->base_init;
       data->instance.class_finalize_base = info->base_finalize;
@@ -663,7 +744,9 @@ type_data_make (TypeNode        *node,
     }
   else if (node->is_classed) /* only classed */
     {
-      data = g_malloc0 (sizeof (ClassData));
+      data = g_malloc0 (sizeof (ClassData) + vtable_size);
+      if (vtable_size)
+       vtable = G_STRUCT_MEMBER_P (data, sizeof (ClassData));
       data->class.class_size = info->class_size;
       data->class.class_init_base = info->base_init;
       data->class.class_finalize_base = info->base_finalize;
@@ -674,16 +757,28 @@ type_data_make (TypeNode        *node,
     }
   else if (node->is_iface)
     {
-      data = g_malloc0 (sizeof (IFaceData));
+      data = g_malloc0 (sizeof (IFaceData) + vtable_size);
+      if (vtable_size)
+       vtable = G_STRUCT_MEMBER_P (data, sizeof (IFaceData));
       data->iface.vtable_size = info->class_size;
       data->iface.vtable_init_base = info->base_init;
       data->iface.vtable_finalize_base = info->base_finalize;
     }
   else
-    data = g_malloc0 (sizeof (CommonData));
-
+    {
+      data = g_malloc0 (sizeof (CommonData) + vtable_size);
+      if (vtable_size)
+       vtable = G_STRUCT_MEMBER_P (data, sizeof (CommonData));
+    }
+  
   node->data = data;
   node->data->common.ref_count = 1;
+  
+  if (vtable_size)
+    *vtable = *value_table;
+  node->data->common.value_table = vtable;
+
+  g_assert (node->data->common.value_table != NULL); // FIXME: paranoid
 }
 
 static inline void
@@ -692,18 +787,21 @@ type_data_ref (TypeNode *node)
   if (!node->data)
     {
       TypeNode *pnode = LOOKUP_TYPE_NODE (NODE_PARENT_TYPE (node));
-      GTypeInfo tmpinfo;
+      GTypeInfo tmp_info;
+      GTypeValueTable tmp_value_table;
       
       g_assert (node->plugin != NULL);
       
       if (pnode)
        type_data_ref (pnode);
       
-      memset (&tmpinfo, 0, sizeof (tmpinfo));
+      memset (&tmp_info, 0, sizeof (tmp_info));
+      memset (&tmp_value_table, 0, sizeof (tmp_value_table));
       g_type_plugin_ref (node->plugin);
-      g_type_plugin_complete_type_info (node->plugin, NODE_TYPE (node), &tmpinfo);
-      check_type_info (pnode, G_TYPE_FUNDAMENTAL (NODE_TYPE (node)), NODE_NAME (node), &tmpinfo);
-      type_data_make (node, &tmpinfo);
+      g_type_plugin_complete_type_info (node->plugin, NODE_TYPE (node), &tmp_info, &tmp_value_table);
+      check_type_info (pnode, G_TYPE_FUNDAMENTAL (NODE_TYPE (node)), NODE_NAME (node), &tmp_info);
+      type_data_make (node, &tmp_info,
+                     check_value_table (NODE_NAME (node), &tmp_value_table) ? &tmp_value_table : NULL);
     }
   else
     {
@@ -714,7 +812,8 @@ type_data_ref (TypeNode *node)
 }
 
 static inline void
-type_data_unref (TypeNode *node)
+type_data_unref (TypeNode *node,
+                gboolean  uncached)
 {
   g_assert (node->data && node->data->common.ref_count);
 
@@ -729,7 +828,7 @@ type_data_unref (TypeNode *node)
          return;
        }
 
-      type_data_last_unref (NODE_TYPE (node));
+      type_data_last_unref (NODE_TYPE (node), uncached);
     }
 }
 
@@ -769,8 +868,8 @@ type_add_interface (TypeNode       *node,
    */
   g_assert (node->is_instantiatable && iface->is_iface && ((info && !plugin) || (!info && plugin)));
   
-  iholder->next = iface->private.iholders;
-  iface->private.iholders = iholder;
+  iholder->next = iface->private.iface_conformants;
+  iface->private.iface_conformants = iholder;
   iholder->instance_type = NODE_TYPE (node);
   iholder->info = info ? g_memdup (info, sizeof (*info)) : NULL;
   iholder->plugin = plugin;
@@ -782,7 +881,7 @@ static IFaceHolder*
 type_iface_retrive_holder_info (TypeNode *iface,
                                GType     instance_type)
 {
-  IFaceHolder *iholder = iface->private.iholders;
+  IFaceHolder *iholder = iface->private.iface_conformants;
 
   g_assert (iface->is_iface);
 
@@ -791,17 +890,17 @@ type_iface_retrive_holder_info (TypeNode *iface,
 
   if (!iholder->info)
     {
-      GInterfaceInfo tmpinfo;
+      GInterfaceInfo tmp_info;
       
       g_assert (iholder->plugin != NULL);
       
       type_data_ref (iface);
 
-      memset (&tmpinfo, 0, sizeof (tmpinfo));
+      memset (&tmp_info, 0, sizeof (tmp_info));
       g_type_plugin_ref (iholder->plugin);
-      g_type_plugin_complete_interface_info (iholder->plugin, NODE_TYPE (iface), instance_type, &tmpinfo);
-      check_interface_info (iface, instance_type, &tmpinfo);
-      iholder->info = g_memdup (&tmpinfo, sizeof (tmpinfo));
+      g_type_plugin_complete_interface_info (iholder->plugin, NODE_TYPE (iface), instance_type, &tmp_info);
+      check_interface_info (iface, instance_type, &tmp_info);
+      iholder->info = g_memdup (&tmp_info, sizeof (tmp_info));
     }
   
   return iholder;
@@ -811,7 +910,7 @@ static void
 type_iface_blow_holder_info (TypeNode *iface,
                             GType     instance_type)
 {
-  IFaceHolder *iholder = iface->private.iholders;
+  IFaceHolder *iholder = iface->private.iface_conformants;
 
   g_assert (iface->is_iface);
 
@@ -824,7 +923,7 @@ type_iface_blow_holder_info (TypeNode *iface,
       iholder->info = NULL;
       g_type_plugin_unref (iholder->plugin);
 
-      type_data_unref (iface);
+      type_data_unref (iface, FALSE);
     }
 }
 
@@ -947,7 +1046,7 @@ type_iface_vtable_finalize (TypeNode       *iface,
                            GTypeInterface *vtable)
 {
   IFaceEntry *entry = type_lookup_iface_entry (node, iface);
-  IFaceHolder *iholder = iface->private.iholders;
+  IFaceHolder *iholder = iface->private.iface_conformants;
 
   g_assert (entry && entry->vtable == vtable);
 
@@ -1081,10 +1180,11 @@ type_data_finalize_class (TypeNode  *node,
 }
 
 static void
-type_data_last_unref (GType type)
+type_data_last_unref (GType    type,
+                     gboolean uncached)
 {
   TypeNode *node = LOOKUP_TYPE_NODE (type);
-  
+
   g_return_if_fail (node != NULL && node->plugin != NULL);
   
   if (!node->data || node->data->common.ref_count == 0)
@@ -1093,12 +1193,22 @@ type_data_last_unref (GType type)
                 type_descriptive_name (type));
       return;
     }
-  
+
+  if (node->is_classed && node->data && node->data->class.class)
+    {
+      guint i;
+
+      for (i = 0; i < n_class_cache_funcs; i++)
+       if (class_cache_funcs[i].cache_func (class_cache_funcs[i].cache_data, node->data->class.class))
+         break;
+    }
+
   if (node->data->common.ref_count > 1)        /* may have been re-referenced meanwhile */
     node->data->common.ref_count -= 1;
   else
     {
       GType ptype = NODE_PARENT_TYPE (node);
+      TypeData *tdata;
       
       node->data->common.ref_count = 0;
       
@@ -1108,43 +1218,79 @@ type_data_last_unref (GType type)
          node->data->instance.mem_chunk = NULL;
        }
       
-      if (node->is_classed && node->data->class.class)
+      tdata = node->data;
+      if (node->is_classed && tdata->class.class)
        {
-         ClassData *cdata = &node->data->class;
-
          if (node->n_ifaces)
            type_data_finalize_class_ifaces (node);
          node->data = NULL;
-         type_data_finalize_class (node, cdata);
-         g_free (cdata);
+         type_data_finalize_class (node, &tdata->class);
        }
       else
-       {
-         g_free (node->data);
-         node->data = NULL;
-       }
+       node->data = NULL;
+
+      g_free (tdata);
       
       if (ptype)
-       type_data_unref (LOOKUP_TYPE_NODE (ptype));
+       type_data_unref (LOOKUP_TYPE_NODE (ptype), FALSE);
       g_type_plugin_unref (node->plugin);
     }
 }
 
+void
+g_type_add_class_cache_func (gpointer            cache_data,
+                            GTypeClassCacheFunc cache_func)
+{
+  guint i;
+
+  g_return_if_fail (cache_func != NULL);
+
+  i = n_class_cache_funcs++;
+  class_cache_funcs = g_renew (ClassCacheFunc, class_cache_funcs, n_class_cache_funcs);
+  class_cache_funcs[i].cache_data = cache_data;
+  class_cache_funcs[i].cache_func = cache_func;
+}
+
+void
+g_type_remove_class_cache_func (gpointer            cache_data,
+                               GTypeClassCacheFunc cache_func)
+{
+  guint i;
+
+  g_return_if_fail (cache_func != NULL);
+
+  for (i = 0; i < n_class_cache_funcs; i++)
+    if (class_cache_funcs[i].cache_data == cache_data &&
+       class_cache_funcs[i].cache_func == cache_func)
+      {
+       n_class_cache_funcs--;
+       g_memmove (class_cache_funcs + i,
+                  class_cache_funcs + i + 1,
+                  sizeof (class_cache_funcs[0]) * (n_class_cache_funcs - i));
+       class_cache_funcs = g_renew (ClassCacheFunc, class_cache_funcs, n_class_cache_funcs);
+
+       return;
+      }
+
+  g_warning (G_STRLOC ": cannot remove unregistered class cache func %p with data %p",
+            cache_func, cache_data);
+}
+
 
 /* --- type registration --- */
 GType
 g_type_register_fundamental (GType                       type_id,
                             const gchar                *type_name,
-                            const GTypeFundamentalInfo *finfo,
-                            const GTypeInfo            *info)
+                            const GTypeInfo            *info,
+                            const GTypeFundamentalInfo *finfo)
 {
   GTypeFundamentalInfo *node_finfo;
   TypeNode *node;
 
   g_return_val_if_fail (type_id > 0, 0);
   g_return_val_if_fail (type_name != NULL, 0);
-  g_return_val_if_fail (finfo != NULL, 0);
   g_return_val_if_fail (info != NULL, 0);
+  g_return_val_if_fail (finfo != NULL, 0);
 
   if (!check_type_name (type_name))
     return 0;
@@ -1172,12 +1318,11 @@ g_type_register_fundamental (GType                       type_id,
 
   node = type_node_fundamental_new (type_id, type_name, finfo->type_flags);
   node_finfo = type_node_fundamental_info (node);
-  node_finfo->n_collect_bytes = finfo->n_collect_bytes; // FIXME: check max bytes
-  node_finfo->param_collector = finfo->param_collector;
 
   if (!check_type_info (NULL, G_TYPE_FUNDAMENTAL (NODE_TYPE (node)), type_name, info))
     return NODE_TYPE (node);
-  type_data_make (node, info);
+  type_data_make (node, info,
+                 check_value_table (type_name, info->value_table) ? info->value_table : NULL);
 
   return NODE_TYPE (node);
 }
@@ -1213,7 +1358,8 @@ g_type_register_static (GType            parent_type,
 
   node = type_node_new (pnode, type_name, NULL);
   type = NODE_TYPE (node);
-  type_data_make (node, info);
+  type_data_make (node, info,
+                 check_value_table (type_name, info->value_table) ? info->value_table : NULL);
 
   return type;
 }
@@ -1333,7 +1479,24 @@ g_type_class_unref (gpointer g_class)
   node = LOOKUP_TYPE_NODE (class->g_type);
   if (node && node->is_classed && node->data &&
       node->data->class.class == class && node->data->common.ref_count > 0)
-    type_data_unref (node);
+    type_data_unref (node, FALSE);
+  else
+    g_warning ("cannot unreference class of invalid (unclassed) type `%s'",
+              type_descriptive_name (class->g_type));
+}
+
+void
+g_type_class_unref_uncached (gpointer g_class)
+{
+  TypeNode *node;
+  GTypeClass *class = g_class;
+
+  g_return_if_fail (g_class != NULL);
+
+  node = LOOKUP_TYPE_NODE (class->g_type);
+  if (node && node->is_classed && node->data &&
+      node->data->class.class == class && node->data->common.ref_count > 0)
+    type_data_unref (node, TRUE);
   else
     g_warning ("cannot unreference class of invalid (unclassed) type `%s'",
               type_descriptive_name (class->g_type));
@@ -1391,6 +1554,17 @@ g_type_interface_peek (gpointer instance_class,
   return NULL;
 }
 
+GTypeValueTable*
+g_type_value_table_peek (GType type)
+{
+  TypeNode *node = LOOKUP_TYPE_NODE (type);
+
+  if (node && node->data && node->data->common.ref_count > 0)
+    return node->data->common.value_table->value_init ? node->data->common.value_table : NULL;
+  else
+    return NULL;
+}
+
 gchar*
 g_type_name (GType type)
 {
@@ -1769,9 +1943,11 @@ g_type_check_class_cast (GTypeClass *type_class,
 
 
 /* --- foreign prototypes --- */
-extern void     g_param_types_init              (void);        /* sync with glib-gparam.c */
-extern void    g_enum_types_init               (void); /* sync with glib-genums.c */
-extern void     g_object_type_init             (void); /* sync with glib-gobject.c */
+extern void    g_value_types_init      (void); /* sync with gvaluetypes.c */
+extern void    g_enum_types_init       (void); /* sync with genums.c */
+extern void     g_param_type_init       (void);        /* sync with gparam.c */
+extern void     g_object_type_init      (void);        /* sync with gobject.c */
+extern void    g_param_spec_types_init (void); /* sync with gparamspecs.c */
 
 
 /* --- initialization --- */
@@ -1808,18 +1984,26 @@ g_type_init (void)
   memset (&info, 0, sizeof (info));
   node = type_node_fundamental_new (G_TYPE_INTERFACE, "GInterface", G_TYPE_FLAG_DERIVABLE);
   type = NODE_TYPE (node);
-  type_data_make (node, &info);
+  type_data_make (node, &info, NULL); // FIXME
   g_assert (type == G_TYPE_INTERFACE);
 
+  /* G_TYPE_* value types
+   */
+  g_value_types_init ();
+  
   /* G_TYPE_ENUM & G_TYPE_FLAGS
    */
   g_enum_types_init ();
-
+  
   /* G_TYPE_PARAM
    */
-  g_param_types_init ();
+  g_param_type_init ();
 
   /* G_TYPE_OBJECT
    */
   g_object_type_init ();
+
+  /* G_TYPE_PARAM_* pspec types
+   */
+  g_param_spec_types_init ();
 }
index 66b8a90ae316fc232595b7ba07abc356a0a2795a..8c60374e4218f2938b7c27894da983f105719ad2 100644 (file)
@@ -47,36 +47,42 @@ typedef enum    /*< skip >*/
   G_TYPE_INTERFACE,
 
   /* GLib type ids */
+  G_TYPE_CHAR,
+  G_TYPE_UCHAR,
+  G_TYPE_BOOLEAN,
+  G_TYPE_INT,
+  G_TYPE_UINT,
+  G_TYPE_LONG,
+  G_TYPE_ULONG,
   G_TYPE_ENUM,
   G_TYPE_FLAGS,
+  G_TYPE_FLOAT,
+  G_TYPE_DOUBLE,
+  G_TYPE_STRING,
   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,
 
+  /* reserved fundamental type ids,
+   * mail gtk-devel-list@redhat.com for reservations
+   */
+  G_TYPE_BSE_PROCEDURE,
+  G_TYPE_BSE_TIME,
+  G_TYPE_BSE_NOTE,
+  G_TYPE_BSE_DOTS,
+  G_TYPE_GLE_GOBJECT,
+
   G_TYPE_LAST_RESERVED_FUNDAMENTAL,
 
   /* derived type ids */
+  /* FIXME: G_TYPE_PARAM_INTERFACE */
   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_BOOLEAN          = 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),
@@ -86,6 +92,7 @@ typedef enum    /*< skip >*/
   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),
+  /* FIXME: G_TYPE_PARAM_PARAM */
   G_TYPE_PARAM_OBJECT           = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 13)
 } GTypeFundamentals;
 
@@ -103,7 +110,8 @@ typedef enum    /*< skip >*/
 /* Typedefs
  */
 typedef guint32                         GType;
-typedef struct _GParam                  GParam;
+typedef struct _GValue                  GValue;
+typedef union  _GTypeCValue             GTypeCValue;
 typedef struct _GTypePlugin             GTypePlugin;
 typedef struct _GTypePluginVTable       GTypePluginVTable;
 typedef struct _GTypeClass              GTypeClass;
@@ -112,20 +120,24 @@ typedef struct _GTypeInstance           GTypeInstance;
 typedef struct _GTypeInfo               GTypeInfo;
 typedef struct _GTypeFundamentalInfo    GTypeFundamentalInfo;
 typedef struct _GInterfaceInfo          GInterfaceInfo;
+typedef struct _GTypeValueTable         GTypeValueTable;
 
 
 /* Basic Type Structures
  */
 struct _GTypeClass
 {
+  /*< private >*/
   GType g_type;
 };
 struct _GTypeInstance
 {
+  /*< private >*/
   GTypeClass *g_class;
 };
 struct _GTypeInterface
 {
+  /*< private >*/
   GType g_type;         /* iface type */
   GType g_instance_type;
 };
@@ -140,6 +152,7 @@ struct _GTypeInterface
 #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)
+#define G_TYPE_FROM_INTERFACE(g_iface)                          (((GTypeInterface*) (g_iface))->g_type)
 
 
 /* --- prototypes --- */
@@ -166,7 +179,7 @@ GType*   g_type_children                (GType                   type,
                                          guint                  *n_children);
 GType*   g_type_interfaces              (GType                   type,
                                          guint                  *n_interfaces);
-/* per-type *static* data */
+/* per-type _static_ data */
 void     g_type_set_qdata               (GType                   type,
                                          GQuark                  quark,
                                          gpointer                data);
@@ -175,30 +188,30 @@ gpointer g_type_get_qdata               (GType                   type,
                                           
 
 /* --- 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);
+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 void (*GTypePluginRef)               (GTypePlugin     *plugin);
+typedef void (*GTypePluginUnRef)             (GTypePlugin     *plugin);
+typedef void (*GTypePluginFillTypeInfo)      (GTypePlugin     *plugin,
+                                              GType            g_type,
+                                              GTypeInfo       *info,
+                                             GTypeValueTable *value_table);
+typedef void (*GTypePluginFillInterfaceInfo) (GTypePlugin     *plugin,
+                                              GType            interface_type,
+                                              GType            instance_type,
+                                              GInterfaceInfo  *info);
+typedef gboolean (*GTypeClassCacheFunc)             (gpointer         cache_data,
+                                             GTypeClass      *g_class);
 struct _GTypePlugin
 {
   GTypePluginVTable     *vtable;
@@ -234,12 +247,13 @@ struct _GTypeInfo
   guint16                instance_size;
   guint16                n_preallocs;
   GInstanceInitFunc      instance_init;
+
+  /* value handling */
+  const GTypeValueTable        *value_table;
 };
 struct _GTypeFundamentalInfo
 {
   GTypeFlags             type_flags;
-  guint                  n_collect_bytes;
-  GTypeParamCollector    param_collector;
 };
 struct _GInterfaceInfo
 {
@@ -247,6 +261,24 @@ struct _GInterfaceInfo
   GInterfaceFinalizeFunc interface_finalize;
   gpointer               interface_data;
 };
+struct _GTypeValueTable
+{
+  void   (*value_init)    (GValue       *value);
+  void   (*value_free)    (GValue       *value);
+  void   (*value_copy)    (const GValue *src_value,
+                          GValue       *dest_value);
+  /* varargs functionality (optional) */
+  guint    collect_type;
+  gchar* (*collect_value) (GValue       *value,
+                          guint         nth_value,
+                          GType        *collect_type,
+                          GTypeCValue  *collect_value);
+  guint    lcopy_type;
+  gchar* (*lcopy_value)   (const GValue *value,
+                          guint         nth_value,
+                          GType        *collect_type,
+                          GTypeCValue  *collect_value);
+};
 GType g_type_register_static       (GType                       parent_type,
                                     const gchar                *type_name,
                                     const GTypeInfo            *info);
@@ -255,8 +287,8 @@ GType g_type_register_dynamic      (GType                       parent_type,
                                     GTypePlugin                *plugin);
 GType g_type_register_fundamental  (GType                       type_id,
                                     const gchar                *type_name,
-                                    const GTypeFundamentalInfo *finfo,
-                                    const GTypeInfo            *info);
+                                    const GTypeInfo            *info,
+                                    const GTypeFundamentalInfo *finfo);
 void  g_type_add_interface_static  (GType                       instance_type,
                                     GType                       interface_type,
                                     GInterfaceInfo             *info);
@@ -266,20 +298,27 @@ void  g_type_add_interface_dynamic (GType                       instance_type,
 
 
 /* --- 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);
+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);
+GTypeValueTable* g_type_value_table_peek        (GType              type);
+void            g_type_add_class_cache_func    (gpointer            cache_data,
+                                                GTypeClassCacheFunc cache_func);
+void            g_type_remove_class_cache_func (gpointer            cache_data,
+                                                GTypeClassCacheFunc cache_func);
+void             g_type_class_unref_uncached    (gpointer            g_class);
+
 
 #ifndef G_DISABLE_CAST_CHECKS
 #  define _G_TYPE_CIC(ip, gt, ct) \
index d85a9f793489ba1af4e86ea2f5694d640f79a605..7c4cb31ebb2488388ffb1242a65439340555e0a9 100644 (file)
 #include       "gvalue.h"
 
 
-/* --- defines --- */
-#define G_PARAM_SPEC_CLASS(class)    (G_TYPE_CHECK_CLASS_CAST ((class), G_TYPE_PARAM, GParamSpecClass))
-
-
 /* --- typedefs & structures --- */
 typedef struct
 {
@@ -42,179 +38,73 @@ 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)
-{
+  GTypeValueTable *value_table = g_type_value_table_peek (g_type);
+  
   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)
+  if (value_table)
     {
-      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);
+      memset (value, 0, sizeof (*value));
+      value->g_type = g_type;
+      value_table->value_init (value);
     }
-
-  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);
+  else
+    g_warning (G_STRLOC ": cannot initialize value of type `%s' which has no GTypeValueTable",
+              g_type_name (g_type));
 }
 
 void
 g_value_copy (const GValue *src_value,
              GValue       *dest_value)
 {
+  GTypeValueTable *value_table = g_type_value_table_peek (G_VALUE_TYPE (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));
-
+  g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), G_VALUE_TYPE (dest_value)));
+  if (!value_table)
+    g_return_if_fail (g_type_value_table_peek (G_VALUE_TYPE (dest_value)) != NULL);
+  
   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);
+      value_table->value_copy (src_value, dest_value);
     }
 }
 
 void
 g_value_unset (GValue *value)
 {
-  GParamSpecClass *pclass;
-
+  GTypeValueTable *value_table = g_type_value_table_peek (G_VALUE_TYPE (value));
+  
   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);
+  if (!value_table)
+    g_return_if_fail (g_type_value_table_peek (G_VALUE_TYPE (value)) != NULL);
+  
+  if (value_table->value_free)
+    value_table->value_free (value);
   memset (value, 0, sizeof (*value));
-  g_type_class_unref (pclass);
 }
 
 void
 g_value_reset (GValue *value)
 {
-  GParamSpecClass *pclass;
+  GTypeValueTable *value_table = g_type_value_table_peek (G_VALUE_TYPE (value));
   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);
+  
+  if (value_table->value_free)
+    value_table->value_free (value);
   memset (value, 0, sizeof (*value));
-
-  value->g_type = g_type;
-  pclass->param_init (value, NULL);
   
-  g_type_class_unref (pclass);
+  value->g_type = g_type;
+  value_table->value_init (value);
 }
 
 static gint
@@ -223,7 +113,7 @@ exchange_entries_equal (gconstpointer v1,
 {
   const ExchangeEntry *entry1 = v1;
   const ExchangeEntry *entry2 = v2;
-
+  
   return (entry1->value_type1 == entry2->value_type1 &&
          entry1->value_type2 == entry2->value_type2);
 }
@@ -232,7 +122,7 @@ static guint
 exchange_entry_hash (gconstpointer key)
 {
   const ExchangeEntry *entry = key;
-
+  
   return entry->value_type1 ^ entry->value_type2;
 }
 
@@ -241,7 +131,7 @@ 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));
@@ -256,20 +146,36 @@ exchange_func_lookup (GType     value_type1,
     return value_exchange_memcpy;
   else
     {
-      ExchangeEntry entry, *ret;
-      
-      entry.value_type1 = MIN (value_type1, value_type2);
-      entry.value_type2 = MAX (value_type1, value_type2);
+      GType type1 = value_type1;
       
-      ret = g_hash_table_lookup (param_exchange_ht, &entry);
-      if (ret)
+      do
        {
-         if (need_swap)
-           *need_swap = ret->first_type == value_type1;
-
-         return ret->func;
+         GType type2 = value_type2;
+         
+         do
+           {
+             ExchangeEntry entry, *ret;
+             
+             entry.value_type1 = MIN (type1, type2);
+             entry.value_type2 = MAX (type1, type2);
+             ret = g_hash_table_lookup (param_exchange_ht, &entry);
+             if (ret)
+               {
+                 if (need_swap)
+                   *need_swap = ret->first_type == type2;
+                 
+                 return ret->func;
+               }
+             
+             type2 = g_type_parent (type2);
+           }
+         while (type2);
+         
+         type1 = g_type_parent (type1);
        }
+      while (type1);
     }
+  
   return NULL;
 }
 
@@ -278,30 +184,29 @@ g_value_register_exchange_func (GType          value_type1,
                                GType          value_type2,
                                GValueExchange func)
 {
-  GType type1, type2;
-
+  ExchangeEntry entry;
+  
   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))
+  
+  entry.value_type1 = MIN (value_type1, value_type2);
+  entry.value_type2 = MAX (value_type1, value_type2);
+  if (param_exchange_ht && g_hash_table_lookup (param_exchange_ht, &entry))
     g_warning (G_STRLOC ": cannot re-register param value exchange function "
               "for `%s' and `%s'",
-              g_type_name (type1),
-              g_type_name (type2));
+              g_type_name (value_type1),
+              g_type_name (value_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->value_type1 = MIN (value_type1, value_type2);
+      entry->value_type2 = MAX (value_type1, value_type2);
       entry->func = func;
-      entry->first_type = type1;
+      entry->first_type = value_type1;
       g_hash_table_insert (param_exchange_ht, entry, entry);
     }
 }
@@ -310,15 +215,10 @@ 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;
+  
+  return exchange_func_lookup (value_type1, value_type2, NULL) != NULL;
 }
 
 gboolean
@@ -327,14 +227,12 @@ g_values_exchange (GValue *value1,
 {
   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,
+      GValueExchange value_exchange = exchange_func_lookup (G_VALUE_TYPE (value1),
+                                                           G_VALUE_TYPE (value2),
                                                            &need_swap);
       if (value_exchange)
        {
@@ -343,10 +241,10 @@ g_values_exchange (GValue *value1,
          else
            value_exchange (value1, value2);
        }
-
+      
       return value_exchange != NULL;
     }
-
+  
   return TRUE;
 }
 
@@ -355,20 +253,20 @@ 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;
 }
index 697e1dfe64c91f0a50a7b9461e2d5b0a32c4ba52..bf58cd4075270ec9721527a69b11fd966b0049bf 100644 (file)
@@ -22,7 +22,7 @@
 #define __G_VALUE_H__
 
 
-#include       <gobject/gparam.h>
+#include       <gobject/gtype.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -30,18 +30,21 @@ extern "C" {
 
 
 /* --- 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_TYPE_IS_VALUE(type)           (g_type_value_table_peek (type) != NULL)
+#define        G_IS_VALUE(value)               (G_TYPE_IS_VALUE (G_VALUE_TYPE (value))) // FIXME
 #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; */
+typedef void (*GValueExchange) (GValue *value1,
+                               GValue  *value2);
 struct _GValue
 {
-  GType           g_type;      /* param value type */
+  /*< private >*/
+  GType                g_type;
 
+  /* public for GTypeValueTable methods */
   union {
     gint       v_int;
     guint      v_uint;
@@ -57,28 +60,17 @@ struct _GValue
 /* --- 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 --- */
+/* --- implementation details --- */
+gboolean g_values_exchange             (GValue       *value1,
+                                        GValue       *value2);
 gboolean g_value_types_exchangable     (GType         value_type1,
                                         GType         value_type2);
 void     g_value_register_exchange_func        (GType         value_type1,
index b62c262774af02769830802686375976baae50ea..7bbdfc0b466ae24bc5e7c1f383e6ba9f586e530d 100644 (file)
@@ -41,7 +41,7 @@ enum  /*< skip >*/
   G_VALUE_COLLECT_POINTER
 };
 
-union _GParamCValue
+union _GTypeCValue
 {
   gint     v_int;
   glong    v_long;
@@ -50,33 +50,28 @@ union _GParamCValue
 };
 
 
-/* G_PARAM_COLLECT_VALUE() collects a parameter's variable arguments
+/* G_VALUE_COLLECT() collects a variable argument value
  * 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
+ * value is supposed to be initialized according to the value
  * 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)              \
+#define G_VALUE_COLLECT(value, var_args, __error)                                      \
 G_STMT_START {                                                                         \
-  GValue *_value = (param_value);                                                      \
-  GParamSpecClass *_pclass = g_type_class_ref (_value->g_type);                                \
-  GParamSpec *_pspec = (param_spec);                                                   \
+  GValue *_value = (value);                                                            \
+  GTypeValueTable *_vtable = g_type_value_table_peek (G_VALUE_TYPE (_value));          \
   gchar *_error_msg = NULL;                                                            \
-  guint _collect_type = _pclass->collect_type;                                         \
+  guint _collect_type = _vtable->collect_type;                                         \
   guint _nth_value = 0;                                                                        \
                                                                                         \
-  if (_pspec)                                                                          \
-    g_param_spec_ref (_pspec);                                                         \
   g_value_reset (_value);                                                              \
   while (_collect_type && !_error_msg)                                                 \
     {                                                                                  \
-      GParamCValue _cvalue;                                                            \
+      GTypeCValue _cvalue;                                                             \
                                                                                         \
       memset (&_cvalue, 0, sizeof (_cvalue));                                          \
       switch (_collect_type)                                                           \
@@ -97,39 +92,32 @@ G_STMT_START {                                                                              \
          _error_msg  = g_strdup_printf ("%s: invalid collect type (%d) used for %s",   \
                                         G_STRLOC,                                      \
                                         _collect_type,                                 \
-                                        "G_PARAM_COLLECT_VALUE()");                    \
+                                        "G_VALUE_COLLECT()");                          \
          continue;                                                                     \
        }                                                                               \
-      _error_msg = _pclass->param_collect_value (_value,                               \
-                                                _pspec,                                \
-                                                _nth_value++,                          \
-                                                &_collect_type,                        \
-                                                &_cvalue);                             \
+      _error_msg = _vtable->collect_value (_value,                                     \
+                                          _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().
+/* G_VALUE_LCOPY() collects a value's variable argument
+ * locations from a va_list. usage is analogous to G_VALUE_COLLECT().
  */
-#define G_PARAM_LCOPY_VALUE(param_value, param_spec, var_args, __error)                        \
+#define G_VALUE_LCOPY(value, var_args, __error)                                                \
 G_STMT_START {                                                                         \
-  GValue *_value = (param_value);                                                      \
-  GParamSpecClass *_pclass = g_type_class_ref (_value->g_type);                                \
-  GParamSpec *_pspec = (param_spec);                                                   \
+  GValue *_value = (value);                                                            \
+  GTypeValueTable *_vtable = g_type_value_table_peek (G_VALUE_TYPE (_value));          \
   gchar *_error_msg = NULL;                                                            \
-  guint _lcopy_type = _pclass->lcopy_type;                                             \
+  guint _lcopy_type = _vtable->lcopy_type;                                             \
   guint _nth_value = 0;                                                                        \
                                                                                         \
-  if (_pspec)                                                                          \
-    g_param_spec_ref (_pspec);                                                         \
   while (_lcopy_type && !_error_msg)                                                   \
     {                                                                                  \
-      GParamCValue _cvalue;                                                            \
+      GTypeCValue _cvalue;                                                             \
                                                                                         \
       memset (&_cvalue, 0, sizeof (_cvalue));                                          \
       switch (_lcopy_type)                                                             \
@@ -150,19 +138,15 @@ G_STMT_START {                                                                            \
          _error_msg  = g_strdup_printf ("%s: invalid collect type (%d) used for %s",   \
                                         G_STRLOC,                                      \
                                         _lcopy_type,                                   \
-                                        "G_PARAM_LCOPY_VALUE()");                      \
+                                        "G_VALUE_LCOPY()");                            \
          continue;                                                                     \
        }                                                                               \
-      _error_msg = _pclass->param_lcopy_value (_value,                                 \
-                                              _pspec,                                  \
-                                              _nth_value++,                            \
-                                              &_lcopy_type,                            \
-                                              &_cvalue);                               \
+      _error_msg = _vtable->lcopy_value (_value,                                       \
+                                        _nth_value++,                                  \
+                                        &_lcopy_type,                                  \
+                                        &_cvalue);                                     \
     }                                                                                  \
   *(__error) = _error_msg;                                                             \
-  if (_pspec)                                                                          \
-    g_param_spec_unref (_pspec);                                                       \
-  g_type_class_unref (_pclass);                                                                \
 } G_STMT_END
 
 
diff --git a/gobject/gvaluetypes.c b/gobject/gvaluetypes.c
new file mode 100644 (file)
index 0000000..d27171c
--- /dev/null
@@ -0,0 +1,588 @@
+/* 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       "gvaluetypes.h"
+
+#include       "gvaluecollector.h"
+#include       <string.h>
+
+
+/* --- value functions --- */
+static void
+value_long0_init (GValue *value)
+{
+  value->data[0].v_long = 0;
+}
+
+static void
+value_long0_copy (const GValue *src_value,
+                 GValue       *dest_value)
+{
+  dest_value->data[0].v_long = src_value->data[0].v_long;
+}
+
+static gchar*
+value_char_lcopy_value (const GValue *value,
+                       guint         nth_value,
+                       GType        *collect_type,
+                       GTypeCValue  *collect_value)
+{
+  gint8 *int8_p = collect_value->v_pointer;
+  
+  if (!int8_p)
+    return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
+  
+  *int8_p = value->data[0].v_int;
+  
+  *collect_type = 0;
+  return NULL;
+}
+
+static gchar*
+value_boolean_lcopy_value (const GValue *value,
+                          guint         nth_value,
+                          GType        *collect_type,
+                          GTypeCValue  *collect_value)
+{
+  gboolean *bool_p = collect_value->v_pointer;
+  
+  if (!bool_p)
+    return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
+  
+  *bool_p = value->data[0].v_int;
+  
+  *collect_type = 0;
+  return NULL;
+}
+
+static gchar*
+value_int_collect_value (GValue             *value,
+                        guint        nth_value,
+                        GType       *collect_type,
+                        GTypeCValue *collect_value)
+{
+  value->data[0].v_int = collect_value->v_int;
+  
+  *collect_type = 0;
+  return NULL;
+}
+
+static gchar*
+value_int_lcopy_value (const GValue *value,
+                      guint         nth_value,
+                      GType        *collect_type,
+                      GTypeCValue  *collect_value)
+{
+  gint *int_p = collect_value->v_pointer;
+  
+  if (!int_p)
+    return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
+  
+  *int_p = value->data[0].v_int;
+  
+  *collect_type = 0;
+  return NULL;
+}
+
+static gchar*
+value_long_collect_value (GValue      *value,
+                         guint        nth_value,
+                         GType       *collect_type,
+                         GTypeCValue *collect_value)
+{
+  value->data[0].v_long = collect_value->v_long;
+  
+  *collect_type = 0;
+  return NULL;
+}
+
+static gchar*
+value_long_lcopy_value (const GValue *value,
+                       guint         nth_value,
+                       GType        *collect_type,
+                       GTypeCValue  *collect_value)
+{
+  glong *long_p = collect_value->v_pointer;
+  
+  if (!long_p)
+    return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
+  
+  *long_p = value->data[0].v_long;
+  
+  *collect_type = 0;
+  return NULL;
+}
+
+static void
+value_float_init (GValue *value)
+{
+  value->data[0].v_float = 0.0;
+}
+
+static void
+value_float_copy (const GValue *src_value,
+                 GValue       *dest_value)
+{
+  dest_value->data[0].v_float = src_value->data[0].v_float;
+}
+
+static gchar*
+value_float_collect_value (GValue      *value,
+                          guint        nth_value,
+                          GType       *collect_type,
+                          GTypeCValue *collect_value)
+{
+  value->data[0].v_float = collect_value->v_double;
+  
+  *collect_type = 0;
+  return NULL;
+}
+
+static gchar*
+value_float_lcopy_value (const GValue *value,
+                        guint         nth_value,
+                        GType        *collect_type,
+                        GTypeCValue  *collect_value)
+{
+  gfloat *float_p = collect_value->v_pointer;
+  
+  if (!float_p)
+    return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
+  
+  *float_p = value->data[0].v_float;
+  
+  *collect_type = 0;
+  return NULL;
+}
+
+static void
+value_double_init (GValue *value)
+{
+  value->data[0].v_double = 0.0;
+}
+
+static void
+value_double_copy (const GValue *src_value,
+                  GValue       *dest_value)
+{
+  dest_value->data[0].v_double = src_value->data[0].v_double;
+}
+
+static gchar*
+value_double_collect_value (GValue     *value,
+                           guint        nth_value,
+                           GType       *collect_type,
+                           GTypeCValue *collect_value)
+{
+  value->data[0].v_double = collect_value->v_double;
+  
+  *collect_type = 0;
+  return NULL;
+}
+
+static gchar*
+value_double_lcopy_value (const GValue *value,
+                         guint         nth_value,
+                         GType        *collect_type,
+                         GTypeCValue  *collect_value)
+{
+  gdouble *double_p = collect_value->v_pointer;
+  
+  if (!double_p)
+    return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
+  
+  *double_p = value->data[0].v_double;
+  
+  *collect_type = 0;
+  return NULL;
+}
+
+static void
+value_string_init (GValue *value)
+{
+  value->data[0].v_pointer = NULL;
+}
+
+static void
+value_string_free_value (GValue *value)
+{
+  g_free (value->data[0].v_pointer);
+}
+
+static void
+value_string_copy_value (const GValue *src_value,
+                        GValue       *dest_value)
+{
+  dest_value->data[0].v_pointer = g_strdup (src_value->data[0].v_pointer);
+}
+
+static gchar*
+value_string_collect_value (GValue     *value,
+                           guint        nth_value,
+                           GType       *collect_type,
+                           GTypeCValue *collect_value)
+{
+  value->data[0].v_pointer = g_strdup (collect_value->v_pointer);
+  
+  *collect_type = 0;
+  return NULL;
+}
+
+static gchar*
+value_string_lcopy_value (const GValue *value,
+                         guint         nth_value,
+                         GType        *collect_type,
+                         GTypeCValue  *collect_value)
+{
+  gchar **string_p = collect_value->v_pointer;
+  
+  if (!string_p)
+    return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
+  
+  *string_p = g_strdup (value->data[0].v_pointer);
+  
+  *collect_type = 0;
+  return NULL;
+}
+
+
+/* --- type initialization --- */
+void
+g_value_types_init (void)  /* sync with gtype.c */
+{
+  GTypeInfo info = {
+    0,                         /* class_size */
+    NULL,                      /* base_init */
+    NULL,                      /* base_destroy */
+    NULL,                      /* class_init */
+    NULL,                      /* class_destroy */
+    NULL,                      /* class_data */
+    0,                         /* instance_size */
+    0,                         /* n_preallocs */
+    NULL,                      /* instance_init */
+    NULL,                      /* value_table */
+  };
+  const GTypeFundamentalInfo finfo = { G_TYPE_FLAG_DERIVABLE, };
+  GType type;
+  
+  /* G_TYPE_CHAR / G_TYPE_UCHAR
+   */
+  {
+    static const GTypeValueTable value_table = {
+      value_long0_init,                /* value_init */
+      NULL,                    /* value_free */
+      value_long0_copy,                /* value_copy */
+      G_VALUE_COLLECT_INT,     /* collect_type */
+      value_int_collect_value, /* collect_value */
+      G_VALUE_COLLECT_POINTER, /* lcopy_type */
+      value_char_lcopy_value,  /* lcopy_value */
+    };
+    info.value_table = &value_table;
+    type = g_type_register_fundamental (G_TYPE_CHAR, "gchar", &info, &finfo);
+    g_assert (type == G_TYPE_CHAR);
+    type = g_type_register_fundamental (G_TYPE_UCHAR, "guchar", &info, &finfo);
+    g_assert (type == G_TYPE_UCHAR);
+  }
+
+  /* G_TYPE_BOOLEAN
+   */
+  {
+    static const GTypeValueTable value_table = {
+      value_long0_init,                 /* value_init */
+      NULL,                     /* value_free */
+      value_long0_copy,                 /* value_copy */
+      G_VALUE_COLLECT_INT,      /* collect_type */
+      value_int_collect_value,  /* collect_value */
+      G_VALUE_COLLECT_POINTER,  /* lcopy_type */
+      value_boolean_lcopy_value, /* lcopy_value */
+    };
+    info.value_table = &value_table;
+    type = g_type_register_fundamental (G_TYPE_BOOLEAN, "gboolean", &info, &finfo);
+    g_assert (type == G_TYPE_BOOLEAN);
+  }
+  
+  /* G_TYPE_INT / G_TYPE_UINT
+   */
+  {
+    static const GTypeValueTable value_table = {
+      value_long0_init,                /* value_init */
+      NULL,                    /* value_free */
+      value_long0_copy,                /* value_copy */
+      G_VALUE_COLLECT_INT,     /* collect_type */
+      value_int_collect_value, /* collect_value */
+      G_VALUE_COLLECT_POINTER, /* lcopy_type */
+      value_int_lcopy_value,   /* lcopy_value */
+    };
+    info.value_table = &value_table;
+    type = g_type_register_fundamental (G_TYPE_INT, "gint", &info, &finfo);
+    g_assert (type == G_TYPE_INT);
+    type = g_type_register_fundamental (G_TYPE_UINT, "guint", &info, &finfo);
+    g_assert (type == G_TYPE_UINT);
+  }
+
+  /* G_TYPE_LONG / G_TYPE_ULONG
+   */
+  {
+    static const GTypeValueTable value_table = {
+      value_long0_init,                /* value_init */
+      NULL,                    /* value_free */
+      value_long0_copy,                /* value_copy */
+      G_VALUE_COLLECT_LONG,    /* collect_type */
+      value_long_collect_value,        /* collect_value */
+      G_VALUE_COLLECT_POINTER, /* lcopy_type */
+      value_long_lcopy_value,  /* lcopy_value */
+    };
+    info.value_table = &value_table;
+    type = g_type_register_fundamental (G_TYPE_LONG, "glong", &info, &finfo);
+    g_assert (type == G_TYPE_LONG);
+    type = g_type_register_fundamental (G_TYPE_ULONG, "gulong", &info, &finfo);
+    g_assert (type == G_TYPE_ULONG);
+  }
+  
+  /* G_TYPE_FLOAT
+   */
+  {
+    static const GTypeValueTable value_table = {
+      value_float_init,                 /* value_init */
+      NULL,                     /* value_free */
+      value_float_copy,                 /* value_copy */
+      G_VALUE_COLLECT_DOUBLE,   /* collect_type */
+      value_float_collect_value, /* collect_value */
+      G_VALUE_COLLECT_POINTER,  /* lcopy_type */
+      value_float_lcopy_value,  /* lcopy_value */
+    };
+    info.value_table = &value_table;
+    type = g_type_register_fundamental (G_TYPE_FLOAT, "gfloat", &info, &finfo);
+    g_assert (type == G_TYPE_FLOAT);
+  }
+  
+  /* G_TYPE_DOUBLE
+   */
+  {
+    static const GTypeValueTable value_table = {
+      value_double_init,         /* value_init */
+      NULL,                      /* value_free */
+      value_double_copy,         /* value_copy */
+      G_VALUE_COLLECT_DOUBLE,    /* collect_type */
+      value_double_collect_value, /* collect_value */
+      G_VALUE_COLLECT_POINTER,   /* lcopy_type */
+      value_double_lcopy_value,          /* lcopy_value */
+    };
+    info.value_table = &value_table;
+    type = g_type_register_fundamental (G_TYPE_DOUBLE, "gdouble", &info, &finfo);
+    g_assert (type == G_TYPE_DOUBLE);
+  }
+
+  /* G_TYPE_STRING
+   */
+  {
+    static const GTypeValueTable value_table = {
+      value_string_init,         /* value_init */
+      value_string_free_value,   /* value_free */
+      value_string_copy_value,   /* value_copy */
+      G_VALUE_COLLECT_POINTER,   /* collect_type */
+      value_string_collect_value, /* collect_value */
+      G_VALUE_COLLECT_POINTER,   /* lcopy_type */
+      value_string_lcopy_value,          /* lcopy_value */
+    };
+    info.value_table = &value_table;
+    type = g_type_register_fundamental (G_TYPE_STRING, "gstring", &info, &finfo);
+    g_assert (type == G_TYPE_STRING);
+  }
+}
+
+
+/* --- GValue functions --- */
+void
+g_value_set_char (GValue *value,
+                 gint8   v_char)
+{
+  g_return_if_fail (G_IS_VALUE_CHAR (value));
+  
+  value->data[0].v_int = v_char;
+}
+
+gint8
+g_value_get_char (GValue *value)
+{
+  g_return_val_if_fail (G_IS_VALUE_CHAR (value), 0);
+  
+  return value->data[0].v_int;
+}
+
+void
+g_value_set_uchar (GValue *value,
+                  guint8  v_uchar)
+{
+  g_return_if_fail (G_IS_VALUE_UCHAR (value));
+  
+  value->data[0].v_uint = v_uchar;
+}
+
+guint8
+g_value_get_uchar (GValue *value)
+{
+  g_return_val_if_fail (G_IS_VALUE_UCHAR (value), 0);
+  
+  return value->data[0].v_uint;
+}
+
+void
+g_value_set_boolean (GValue  *value,
+                    gboolean v_boolean)
+{
+  g_return_if_fail (G_IS_VALUE_BOOLEAN (value));
+  
+  value->data[0].v_int = v_boolean;
+}
+
+gboolean
+g_value_get_boolean (GValue *value)
+{
+  g_return_val_if_fail (G_IS_VALUE_BOOLEAN (value), 0);
+  
+  return value->data[0].v_int;
+}
+
+void
+g_value_set_int (GValue *value,
+                gint    v_int)
+{
+  g_return_if_fail (G_IS_VALUE_INT (value));
+  
+  value->data[0].v_int = v_int;
+}
+
+gint
+g_value_get_int (GValue *value)
+{
+  g_return_val_if_fail (G_IS_VALUE_INT (value), 0);
+  
+  return value->data[0].v_int;
+}
+
+void
+g_value_set_uint (GValue *value,
+                 guint   v_uint)
+{
+  g_return_if_fail (G_IS_VALUE_UINT (value));
+  
+  value->data[0].v_uint = v_uint;
+}
+
+guint
+g_value_get_uint (GValue *value)
+{
+  g_return_val_if_fail (G_IS_VALUE_UINT (value), 0);
+  
+  return value->data[0].v_uint;
+}
+
+void
+g_value_set_long (GValue *value,
+                 glong   v_long)
+{
+  g_return_if_fail (G_IS_VALUE_LONG (value));
+  
+  value->data[0].v_long = v_long;
+}
+
+glong
+g_value_get_long (GValue *value)
+{
+  g_return_val_if_fail (G_IS_VALUE_LONG (value), 0);
+  
+  return value->data[0].v_long;
+}
+
+void
+g_value_set_ulong (GValue *value,
+                  gulong  v_ulong)
+{
+  g_return_if_fail (G_IS_VALUE_ULONG (value));
+  
+  value->data[0].v_ulong = v_ulong;
+}
+
+gulong
+g_value_get_ulong (GValue *value)
+{
+  g_return_val_if_fail (G_IS_VALUE_ULONG (value), 0);
+  
+  return value->data[0].v_ulong;
+}
+
+void
+g_value_set_float (GValue *value,
+                  gfloat  v_float)
+{
+  g_return_if_fail (G_IS_VALUE_FLOAT (value));
+  
+  value->data[0].v_float = v_float;
+}
+
+gfloat
+g_value_get_float (GValue *value)
+{
+  g_return_val_if_fail (G_IS_VALUE_FLOAT (value), 0);
+  
+  return value->data[0].v_float;
+}
+
+void
+g_value_set_double (GValue *value,
+                   gdouble v_double)
+{
+  g_return_if_fail (G_IS_VALUE_DOUBLE (value));
+  
+  value->data[0].v_double = v_double;
+}
+
+gdouble
+g_value_get_double (GValue *value)
+{
+  g_return_val_if_fail (G_IS_VALUE_DOUBLE (value), 0);
+  
+  return value->data[0].v_double;
+}
+
+void
+g_value_set_string (GValue     *value,
+                   const gchar *v_string)
+{
+  g_return_if_fail (G_IS_VALUE_STRING (value));
+  
+  g_free (value->data[0].v_pointer);
+  value->data[0].v_pointer = g_strdup (v_string);
+}
+
+gchar*
+g_value_get_string (GValue *value)
+{
+  g_return_val_if_fail (G_IS_VALUE_STRING (value), NULL);
+  
+  return value->data[0].v_pointer;
+}
+
+gchar*
+g_value_dup_string (GValue *value)
+{
+  g_return_val_if_fail (G_IS_VALUE_STRING (value), NULL);
+  
+  return g_strdup (value->data[0].v_pointer);
+}
diff --git a/gobject/gvaluetypes.h b/gobject/gvaluetypes.h
new file mode 100644 (file)
index 0000000..f142967
--- /dev/null
@@ -0,0 +1,86 @@
+/* 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.
+ *
+ * gvaluetypes.h: GLib default values
+ */
+#ifndef __G_VALUETYPES_H__
+#define __G_VALUETYPES_H__
+
+
+#include        <gobject/gvalue.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* --- type macros --- */
+#define G_IS_VALUE_CHAR(value)          (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_CHAR))
+#define G_IS_VALUE_UCHAR(value)         (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_UCHAR))
+#define G_IS_VALUE_BOOLEAN(value)       (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_BOOLEAN))
+#define G_IS_VALUE_INT(value)           (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_INT))
+#define G_IS_VALUE_UINT(value)          (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_UINT))
+#define G_IS_VALUE_LONG(value)          (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_LONG))
+#define G_IS_VALUE_ULONG(value)         (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_ULONG))
+#define G_IS_VALUE_FLOAT(value)         (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_FLOAT))
+#define G_IS_VALUE_DOUBLE(value)        (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_DOUBLE))
+#define G_IS_VALUE_STRING(value)        (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_STRING))
+
+
+/* --- 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_boolean     (GValue         *value,
+                                         gboolean        v_boolean);
+gboolean        g_value_get_boolean     (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_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);
+
+
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __G_VALUETYPES_H__ */