? gtype.patch
Index: gparamspecs.c
===================================================================
RCS file: /cvs/gnome/glib/gobject/gparamspecs.c,v
retrieving revision 1.30
diff -u -p -r1.30 gparamspecs.c
--- gparamspecs.c	31 Aug 2005 17:56:49 -0000	1.30
+++ gparamspecs.c	11 Nov 2005 07:43:30 -0000
@@ -1016,13 +1016,55 @@ param_override_values_cmp (GParamSpec   
   return g_param_values_cmp (ospec->overridden, value1, value2);
 }
 
+static void
+param_gtype_init (GParamSpec *pspec)
+{
+}
+
+static void
+param_gtype_set_default (GParamSpec *pspec,
+			 GValue     *value)
+{
+  value->data[0].v_long = G_TYPE_NONE;
+}
+
+static gboolean
+param_gtype_validate (GParamSpec *pspec,
+		      GValue     *value)
+{
+  GParamSpecGType *tspec = G_PARAM_SPEC_GTYPE (pspec);
+  GType gtype = value->data[0].v_long;
+  guint changed = 0;
+  
+  if (tspec->is_a_type != G_TYPE_NONE && !g_type_is_a (gtype, tspec->is_a_type))
+    {
+      value->data[0].v_long = G_TYPE_NONE;
+      changed++;
+    }
+  
+  return changed;
+}
+
+static gint
+param_gtype_values_cmp (GParamSpec   *pspec,
+			const GValue *value1,
+			const GValue *value2)
+{
+  GType p1 = value1->data[0].v_long;
+  GType p2 = value2->data[0].v_long;
+
+  /* not much to compare here, try to at least provide stable lesser/greater result */
+
+  return p1 < p2 ? -1 : p1 > p2;
+}
+
 /* --- type initialization --- */
 GType *g_param_spec_types = NULL;
 
 void
 g_param_spec_types_init (void)	
 {
-  const guint n_types = 21;
+  const guint n_types = 22;
   GType type, *spec_types, *spec_types_bound;
 
   g_param_spec_types = g_new0 (GType, n_types);
@@ -1408,6 +1450,24 @@ g_param_spec_types_init (void)	
     g_assert (type == G_TYPE_PARAM_OVERRIDE);
   }
 
+  /* G_TYPE_PARAM_GTYPE
+   */
+  {
+    static const GParamSpecTypeInfo pspec_info = {
+      sizeof (GParamSpecGType),	/* instance_size */
+      0,			/* n_preallocs */
+      param_gtype_init,		/* instance_init */
+      G_TYPE_GTYPE,		/* value_type */
+      NULL,			/* finalize */
+      param_gtype_set_default,	/* value_set_default */
+      param_gtype_validate,	/* value_validate */
+      param_gtype_values_cmp,	/* values_cmp */
+    };
+    type = g_param_type_register_static (g_intern_static_string ("GParamGType"), &pspec_info);
+    *spec_types++ = type;
+    g_assert (type == G_TYPE_PARAM_GTYPE);
+  }
+
   g_assert (spec_types == spec_types_bound);
 }
 
@@ -1850,6 +1910,26 @@ g_param_spec_pointer (const gchar *name,
 				 blurb,
 				 flags);
   return G_PARAM_SPEC (pspec);
+}
+
+GParamSpec*
+g_param_spec_gtype (const gchar *name,
+		    const gchar *nick,
+		    const gchar *blurb,
+		    GType        is_a_type,
+		    GParamFlags  flags)
+{
+  GParamSpecGType *tspec;
+  
+  tspec = g_param_spec_internal (G_TYPE_PARAM_GTYPE,
+				 name,
+				 nick,
+				 blurb,
+				 flags);
+
+  tspec->is_a_type = is_a_type;
+
+  return G_PARAM_SPEC (tspec);
 }
 
 GParamSpec*
Index: gparamspecs.h
===================================================================
RCS file: /cvs/gnome/glib/gobject/gparamspecs.h,v
retrieving revision 1.22
diff -u -p -r1.22 gparamspecs.h
--- gparamspecs.h	21 Oct 2003 19:12:27 -0000	1.22
+++ gparamspecs.h	11 Nov 2005 07:43:30 -0000
@@ -96,6 +96,9 @@ G_BEGIN_DECLS
 #define	G_TYPE_PARAM_OVERRIDE		   (g_param_spec_types[20])
 #define G_IS_PARAM_SPEC_OVERRIDE(pspec)    (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_OVERRIDE))
 #define G_PARAM_SPEC_OVERRIDE(pspec)       (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_OVERRIDE, GParamSpecOverride))
+#define	G_TYPE_PARAM_GTYPE		   (g_param_spec_types[21])
+#define G_IS_PARAM_SPEC_GTYPE(pspec)       (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_GTYPE))
+#define G_PARAM_SPEC_GTYPE(pspec)          (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_GTYPE, GParamSpecGType))
 
 
 /* --- typedefs & structures --- */
@@ -120,6 +123,7 @@ typedef struct _GParamSpecPointer    GPa
 typedef struct _GParamSpecValueArray GParamSpecValueArray;
 typedef struct _GParamSpecObject     GParamSpecObject;
 typedef struct _GParamSpecOverride   GParamSpecOverride;
+typedef struct _GParamSpecGType      GParamSpecGType;
 
 struct _GParamSpecChar
 {
@@ -268,6 +272,11 @@ struct _GParamSpecOverride
   GParamSpec    parent_instance;
   GParamSpec   *overridden;
 };
+struct _GParamSpecGType
+{
+  GParamSpec    parent_instance;
+  GType         is_a_type;
+};
 
 /* --- GParamSpec prototypes --- */
 GParamSpec*	g_param_spec_char	 (const gchar	 *name,
@@ -391,9 +400,13 @@ GParamSpec*	g_param_spec_object	 (const 
 					  const gchar	 *blurb,
 					  GType		  object_type,
 					  GParamFlags	  flags);
-
 GParamSpec*     g_param_spec_override    (const gchar    *name,
 					  GParamSpec     *overridden);
+GParamSpec*	g_param_spec_gtype	 (const gchar	 *name,
+					  const gchar	 *nick,
+					  const gchar	 *blurb,
+					  GType           is_a_type,
+					  GParamFlags	  flags);
 
 /* --- internal --- */
 /* We prefix variable declarations so they can
Index: gtype.c
===================================================================
RCS file: /cvs/gnome/glib/gobject/gtype.c,v
retrieving revision 1.84
diff -u -p -r1.84 gtype.c
--- gtype.c	1 Nov 2005 18:10:31 -0000	1.84
+++ gtype.c	11 Nov 2005 07:43:31 -0000
@@ -3343,6 +3343,31 @@ g_type_name_from_class (GTypeClass *g_cl
 
 
 /* --- initialization --- */
+GType
+g_gtype_type_register_static (const gchar *name)
+{
+  static const GTypeInfo type_info = {
+    0,			/* class_size */
+    NULL,		/* base_init */
+    NULL,		/* base_finalize */
+    NULL,		/* class_init */
+    NULL,		/* class_finalize */
+    NULL,		/* class_data */
+    0,			/* instance_size */
+    0,			/* n_preallocs */
+    NULL,		/* instance_init */
+    NULL		/* value_table */
+  };
+  GType type;
+
+  g_return_val_if_fail (name != NULL, 0);
+  g_return_val_if_fail (g_type_from_name (name) == 0, 0);
+
+  type = g_type_register_static (G_TYPE_POINTER, name, &type_info, 0);
+
+  return type;
+}
+
 void
 g_type_init_with_debug_flags (GTypeDebugFlags debug_flags)
 {
Index: gtype.h
===================================================================
RCS file: /cvs/gnome/glib/gobject/gtype.h,v
retrieving revision 1.63
diff -u -p -r1.63 gtype.h
--- gtype.h	27 Sep 2005 23:19:16 -0000	1.63
+++ gtype.h	11 Nov 2005 07:43:31 -0000
@@ -56,6 +56,7 @@ G_BEGIN_DECLS
 #define G_TYPE_BOXED			G_TYPE_MAKE_FUNDAMENTAL (18)
 #define G_TYPE_PARAM			G_TYPE_MAKE_FUNDAMENTAL (19)
 #define G_TYPE_OBJECT			G_TYPE_MAKE_FUNDAMENTAL (20)
+#define G_TYPE_GTYPE                    G_TYPE_MAKE_FUNDAMENTAL (21)
 
 
 /* Reserved fundamental type numbers to create new fundamental
@@ -64,7 +65,7 @@ G_BEGIN_DECLS
  */
 #define	G_TYPE_FUNDAMENTAL_SHIFT	(2)
 #define	G_TYPE_MAKE_FUNDAMENTAL(x)	((GType) ((x) << G_TYPE_FUNDAMENTAL_SHIFT))
-#define G_TYPE_RESERVED_GLIB_FIRST	(21)
+#define G_TYPE_RESERVED_GLIB_FIRST	(22)
 #define G_TYPE_RESERVED_GLIB_LAST	(31)
 #define G_TYPE_RESERVED_BSE_FIRST	(32)
 #define G_TYPE_RESERVED_BSE_LAST	(48)
Index: gvaluetypes.c
===================================================================
RCS file: /cvs/gnome/glib/gobject/gvaluetypes.c,v
retrieving revision 1.20
diff -u -p -r1.20 gvaluetypes.c
--- gvaluetypes.c	31 Aug 2005 14:38:18 -0000	1.20
+++ gvaluetypes.c	11 Nov 2005 07:43:31 -0000
@@ -433,7 +433,7 @@ g_value_types_init (void)
     g_assert (type == G_TYPE_UINT);
   }
 
-  /* G_TYPE_LONG / G_TYPE_ULONG
+  /* G_TYPE_LONG / G_TYPE_ULONG / G_TYPE_GTYPE
    */
   {
     static const GTypeValueTable value_table = {
@@ -451,6 +451,8 @@ g_value_types_init (void)
     g_assert (type == G_TYPE_LONG);
     type = g_type_register_fundamental (G_TYPE_ULONG, g_intern_static_string ("gulong"), &info, &finfo, 0);
     g_assert (type == G_TYPE_ULONG);
+    type = g_type_register_fundamental (G_TYPE_GTYPE, g_intern_static_string ("GType"), &info, &finfo, 0);
+    g_assert (type == G_TYPE_GTYPE);
   }
   
   /* G_TYPE_INT64 / G_TYPE_UINT64
@@ -817,6 +819,25 @@ g_value_get_pointer (const GValue *value
 
   return value->data[0].v_pointer;
 }
+
+void 
+g_value_set_gtype (GValue *value,
+		   GType   v_gtype)
+{
+  g_return_val_if_fail (G_VALUE_HOLDS_GTYPE (value), NULL);
+
+  value->data[0].v_long = v_gtype;
+  
+}
+
+GType	              
+g_value_get_gtype (const GValue *value)
+{
+  g_return_val_if_fail (G_VALUE_HOLDS_GTYPE (value), NULL);
+
+  return value->data[0].v_long;
+}
+
 
 /* need extra includes for g_strdup_value_contents() ;( */
 #include "gobject.h"
Index: gvaluetypes.h
===================================================================
RCS file: /cvs/gnome/glib/gobject/gvaluetypes.h,v
retrieving revision 1.16
diff -u -p -r1.16 gvaluetypes.h
--- gvaluetypes.h	12 Sep 2003 20:11:36 -0000	1.16
+++ gvaluetypes.h	11 Nov 2005 07:43:31 -0000
@@ -43,6 +43,7 @@ G_BEGIN_DECLS
 #define G_VALUE_HOLDS_DOUBLE(value)	 (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_DOUBLE))
 #define G_VALUE_HOLDS_STRING(value)	 (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_STRING))
 #define G_VALUE_HOLDS_POINTER(value)	 (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_POINTER))
+#define G_VALUE_HOLDS_GTYPE(value)	 (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_GTYPE))
 
 
 /* --- prototypes --- */
@@ -88,6 +89,9 @@ gchar*		      g_value_dup_string	(const 
 void		      g_value_set_pointer	(GValue	      *value,
 						 gpointer      v_pointer);
 gpointer	      g_value_get_pointer	(const GValue *value);
+void		      g_value_set_gtype	        (GValue	      *value,
+						 GType         v_gtype);
+GType	              g_value_get_gtype	        (const GValue *value);
 
 
 /* Convenience for registering new pointer types */
