]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtktypeutils.c
Add check for db2html
[~andy/gtk] / gtk / gtktypeutils.c
index a2c15e6aa3a8dac63be25fe32f1c46e51213c239..f607c5a217b4612d83e6718cb1a85e991e026cf1 100644 (file)
  */
 
 /*
- * Modified by the GTK+ Team and others 1997-1999.  See the AUTHORS
+ * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
  * file for a list of people on the GTK+ Team.  See the ChangeLog
  * files for a list of changes.  These files are distributed with
  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
  */
 
-#include <string.h>
 #include "gtktypeutils.h"
+#include "gtkobject.h"
 
 
-#define        TYPE_NODES_BLOCK_SIZE   (35)  /* needs to be > GTK_TYPE_FUNDAMENTAL_MAX */
-
-typedef struct _GtkTypeNode GtkTypeNode;
-
-struct _GtkTypeNode
-{
-  GtkType type;
-  GtkTypeInfo type_info;
-  guint n_supers : 24;
-  guint chunk_alloc_locked : 1;
-  GtkType *supers;
-  GtkType parent_type;
-  gpointer klass;
-  GList *children_types;
-  GMemChunk *mem_chunk;
-};
-
-#define        LOOKUP_TYPE_NODE(node_var, type)        { \
-    GtkTypeNode *__node = NULL; \
-    GtkType sqn = GTK_TYPE_SEQNO (type); \
-    if (sqn > 0) \
-      { \
-       sqn--; \
-       if (sqn < GTK_TYPE_FUNDAMENTAL_MAX) \
-         { \
-           if (sqn < n_ftype_nodes) \
-             __node = type_nodes + sqn; \
-         } \
-       else if (sqn < n_type_nodes) \
-         __node = type_nodes + sqn; \
-      } \
-    node_var = __node; \
-}
-
-static void  gtk_type_class_init               (GtkType      node_type);
-static void  gtk_type_init_builtin_types       (void);
-
-static GtkTypeNode *type_nodes = NULL;
-static guint       n_type_nodes = 0;
-static guint       n_ftype_nodes = 0;
-static GHashTable  *type_name_2_type_ht = NULL;
-
-
-static GtkTypeNode*
-gtk_type_node_next_and_invalidate (GtkType parent_type)
+/* --- functions --- */
+GtkType
+gtk_type_unique (GtkType            parent_type,
+                const GtkTypeInfo *gtkinfo)
 {
-  static guint n_free_type_nodes = 0;
-  GtkTypeNode *node;
-  
-  /* don't keep *any* GtkTypeNode pointers across invokation of this function!!!
-   */
-  
-  if (n_free_type_nodes == 0)
-    {
-      guint i;
-      guint size;
-      
-      /* nearest pow
-       */
-      size = n_type_nodes + TYPE_NODES_BLOCK_SIZE;
-      size *= sizeof (GtkTypeNode);
-      i = 1;
-      while (i < size)
-       i <<= 1;
-      size = i;
-      
-      type_nodes = g_realloc (type_nodes, size);
-      
-      n_free_type_nodes = size / sizeof (GtkTypeNode) - n_type_nodes;
-      
-      memset (type_nodes + n_type_nodes, 0, n_free_type_nodes * sizeof (GtkTypeNode));
-      if (!n_type_nodes)
-       {
-         n_type_nodes = GTK_TYPE_FUNDAMENTAL_MAX;
-         n_free_type_nodes -= GTK_TYPE_FUNDAMENTAL_MAX;
-       }
-    }
-
-  if (!parent_type)
-    {
-      g_assert (n_ftype_nodes < GTK_TYPE_FUNDAMENTAL_MAX); /* paranoid */
-
-      node = type_nodes + n_ftype_nodes;
-      n_ftype_nodes++;
-      node->type = n_ftype_nodes;
-    }
-  else
-    {
-      node = type_nodes + n_type_nodes;
-      n_type_nodes++;
-      n_free_type_nodes--;
-      node->type = GTK_TYPE_MAKE (parent_type, n_type_nodes);
-    }
-  
-  return node;
-}
+  GTypeInfo tinfo = { 0, };
 
-void
-gtk_type_init (void)
-{
-  if (n_type_nodes == 0)
-    {
-      g_assert (sizeof (GtkType) >= 4);
-      g_assert (TYPE_NODES_BLOCK_SIZE > GTK_TYPE_FUNDAMENTAL_MAX);
-      
-      type_name_2_type_ht = g_hash_table_new (g_str_hash, g_str_equal);
-      
-      gtk_type_init_builtin_types ();
-    }
-}
+  g_return_val_if_fail (GTK_TYPE_IS_OBJECT (parent_type), 0);
+  g_return_val_if_fail (gtkinfo != NULL, 0);
+  g_return_val_if_fail (gtkinfo->type_name != NULL, 0);
+  g_return_val_if_fail (g_type_from_name (gtkinfo->type_name) == 0, 0);
 
-void
-gtk_type_set_chunk_alloc (GtkType      type,
-                         guint        n_chunks)
-{
-  GtkTypeNode *node;
-  
-  LOOKUP_TYPE_NODE (node, type);
-  g_return_if_fail (node != NULL);
-  g_return_if_fail (node->chunk_alloc_locked == FALSE);
-  
-  if (node->mem_chunk)
-    {
-      g_mem_chunk_destroy (node->mem_chunk);
-      node->mem_chunk = NULL;
-    }
-  
-  if (n_chunks)
-    node->mem_chunk = g_mem_chunk_new (node->type_info.type_name,
-                                      node->type_info.object_size,
-                                      node->type_info.object_size * n_chunks,
-                                      G_ALLOC_AND_FREE);
-}
+  tinfo.class_size = gtkinfo->class_size;
+  tinfo.base_init = gtkinfo->base_class_init_func;
+  tinfo.base_finalize = NULL;
+  tinfo.class_init = (GClassInitFunc) gtkinfo->class_init_func;
+  tinfo.class_finalize = NULL;
+  tinfo.class_data = NULL;
+  tinfo.instance_size = gtkinfo->object_size;
+  tinfo.n_preallocs = 0;
+  tinfo.instance_init = gtkinfo->object_init_func;
 
-static GtkType
-gtk_type_create (GtkType      parent_type,
-                gchar        *type_name,
-                const GtkTypeInfo *type_info)
-{
-  GtkTypeNode *new_node;
-  GtkTypeNode *parent;
-  guint i;
-  
-  if (g_hash_table_lookup (type_name_2_type_ht, type_name))
-    {
-      g_warning ("gtk_type_create(): type `%s' already exists.", type_name);
-      return 0;
-    }
-  
-  if (parent_type)
-    {
-      GtkTypeNode *tmp_node;
-      
-      LOOKUP_TYPE_NODE (tmp_node, parent_type);
-      if (!tmp_node)
-       {
-         g_warning ("gtk_type_create(): unknown parent type `%u'.", parent_type);
-         return 0;
-       }
-    }
-  
-  /* relookup pointers afterwards.
-   */
-  new_node = gtk_type_node_next_and_invalidate (parent_type);
-  
-  if (parent_type)
-    {
-      g_assert (GTK_TYPE_SEQNO (new_node->type) > GTK_TYPE_FUNDAMENTAL_MAX);
-      LOOKUP_TYPE_NODE (parent, parent_type);
-    }
-  else
-    {
-      g_assert (new_node->type <= GTK_TYPE_FUNDAMENTAL_MAX);
-      parent = NULL;
-    }
-  
-  new_node->type_info = *type_info;
-  new_node->type_info.type_name = type_name;
-  /* new_node->type_info.reserved_1 = NULL; */
-  new_node->type_info.reserved_2 = NULL;
-  new_node->n_supers = parent ? parent->n_supers + 1 : 0;
-  new_node->chunk_alloc_locked = FALSE;
-  new_node->supers = g_new0 (GtkType, new_node->n_supers + 1);
-  new_node->parent_type = parent_type;
-  new_node->klass = NULL;
-  new_node->children_types = NULL;
-  new_node->mem_chunk = NULL;
-  
-  if (parent)
-    parent->children_types = g_list_append (parent->children_types, GUINT_TO_POINTER (new_node->type));
-  
-  parent = new_node;
-  for (i = 0; i < new_node->n_supers + 1; i++)
-    {
-      new_node->supers[i] = parent->type;
-      LOOKUP_TYPE_NODE (parent, parent->parent_type);
-    }
-  
-  g_hash_table_insert (type_name_2_type_ht, new_node->type_info.type_name, GUINT_TO_POINTER (new_node->type));
-  
-  return new_node->type;
+  return g_type_register_static (parent_type, gtkinfo->type_name, &tinfo);
 }
 
-GtkType
-gtk_type_unique (GtkType      parent_type,
-                const GtkTypeInfo *type_info)
+gpointer
+gtk_type_class (GtkType type)
 {
-  GtkType new_type;
-  gchar *type_name;
-  
-  g_return_val_if_fail (type_info != NULL, 0);
-  g_return_val_if_fail (type_info->type_name != NULL, 0);
-  
-  if (!parent_type && n_ftype_nodes >= GTK_TYPE_FUNDAMENTAL_MAX)
-    {
-      g_warning ("gtk_type_unique(): maximum amount of fundamental types reached, "
-                "try increasing GTK_TYPE_FUNDAMENTAL_MAX");
-      return 0;
-    }
-
-  type_name = g_strdup (type_info->type_name);
-  
-  /* relookup pointers afterwards.
+  static GQuark quark_static_class = 0;
+  gpointer class;
+
+  if (!G_TYPE_IS_ENUM (type) && !G_TYPE_IS_FLAGS (type))
+    g_return_val_if_fail (GTK_TYPE_IS_OBJECT (type), NULL);
+
+  /* ok, this is a bit ugly, GLib reference counts classes,
+   * and gtk_type_class() used to always return static classes.
+   * while we coud be faster with just peeking the glib class
+   * for the normal code path, we can't be sure that that
+   * class stays around (someone else might be holding the
+   * reference count and is going to drop it later). so to
+   * ensure that Gtk actually holds a static reference count
+   * on the class, we use GType qdata to store referenced
+   * classes, and only return those.
    */
-  new_type = gtk_type_create (parent_type, type_name, type_info);
-  
-  if (!new_type)
-    g_free (type_name);
 
-  return new_type;
-}
-
-gchar*
-gtk_type_name (GtkType type)
-{
-  GtkTypeNode *node;
-  
-  LOOKUP_TYPE_NODE (node, type);
-  
-  if (node)
-    return node->type_info.type_name;
-  
-  return NULL;
-}
-
-GtkType
-gtk_type_from_name (const gchar *name)
-{
-  if (type_name_2_type_ht)
+  class = g_type_get_qdata (type, quark_static_class);
+  if (!class)
     {
-      GtkType type;
-      
-      type = GPOINTER_TO_UINT (g_hash_table_lookup (type_name_2_type_ht, (gpointer) name));
-      
-      return type;
-    }
-  
-  return 0;
-}
-
-GtkType
-gtk_type_parent (GtkType type)
-{
-  GtkTypeNode *node;
-  
-  LOOKUP_TYPE_NODE (node, type);
-  if (node)
-    return node->parent_type;
-  
-  return 0;
-}
+      if (!quark_static_class)
+       quark_static_class = g_quark_from_static_string ("GtkStaticTypeClass");
 
-gpointer
-gtk_type_parent_class (GtkType type)
-{
-  GtkTypeNode *node;
-  
-  LOOKUP_TYPE_NODE (node, type);
-  g_return_val_if_fail (node != NULL, NULL);
-  
-  if (node)
-    {
-      LOOKUP_TYPE_NODE (node, node->parent_type);
-      
-      if (node)
-       {
-         if (!node->klass)
-           {
-             type = node->type;
-             gtk_type_class_init (type);
-             LOOKUP_TYPE_NODE (node, type);
-           }
-         
-         return node->klass;
-       }
+      class = g_type_class_ref (type);
+      g_assert (class != NULL);
+      g_type_set_qdata (type, quark_static_class, class);
     }
-  
-  return NULL;
-}
 
-gpointer
-gtk_type_class (GtkType type)
-{
-  GtkTypeNode *node;
-  
-  LOOKUP_TYPE_NODE (node, type);
-  g_return_val_if_fail (node != NULL, NULL);
-  
-  if (!node->klass)
-    {
-      type = node->type;
-      gtk_type_class_init (type);
-      LOOKUP_TYPE_NODE (node, type);
-    }
-  
-  return node->klass;
+  return class;
 }
 
 gpointer
 gtk_type_new (GtkType type)
 {
-  GtkTypeNode *node;
-  GtkTypeObject *tobject;
-  gpointer klass;
-  
-  LOOKUP_TYPE_NODE (node, type);
-  g_return_val_if_fail (node != NULL, NULL);
-  
-  klass = node->klass;
-  if (!klass)
-    {
-      klass = gtk_type_class (type);
-      LOOKUP_TYPE_NODE (node, type);
-    }
-  node->chunk_alloc_locked = TRUE;
+  gpointer object;
 
-  if (node->mem_chunk)
-    tobject = g_mem_chunk_alloc0 (node->mem_chunk);
-  else
-    tobject = g_malloc0 (node->type_info.object_size);
-  
-  /* we need to call the base classes' object_init_func for derived
-   * objects with the object's ->klass field still pointing to the
-   * corresponding base class, otherwise overridden class functions
-   * could get called with partly-initialized objects. the real object
-   * class is passed as second argment to the initializers.
-   */
-  if (node->n_supers)
-    {
-      guint i;
-      GtkType *supers;
-      GtkTypeNode *pnode;
+  g_return_val_if_fail (GTK_TYPE_IS_OBJECT (type), NULL);
 
-      supers = node->supers;
-      for (i = node->n_supers; i > 0; i--)
-       {
-         LOOKUP_TYPE_NODE (pnode, supers[i]);
-         if (pnode->type_info.object_init_func)
-           {
-             tobject->klass = pnode->klass;
-             pnode->type_info.object_init_func (tobject, klass);
-           }
-       }
-      LOOKUP_TYPE_NODE (node, type);
-    }
-  tobject->klass = klass;
-  if (node->type_info.object_init_func)
-    {
-      node->type_info.object_init_func (tobject, klass);
-      tobject->klass = klass;
-    }
-  
-  return tobject;
-}
+  object = g_type_create_instance (type);
 
-void
-gtk_type_free (GtkType     type,
-              gpointer     mem)
-{
-  GtkTypeNode *node;
-  
-  g_return_if_fail (mem != NULL);
-  LOOKUP_TYPE_NODE (node, type);
-  g_return_if_fail (node != NULL);
-  
-  if (node->mem_chunk)
-    g_mem_chunk_free (node->mem_chunk, mem);
-  else
-    g_free (mem);
+  return object;
 }
 
-GList*
-gtk_type_children_types (GtkType type)
-{
-  GtkTypeNode *node;
-  
-  LOOKUP_TYPE_NODE (node, type);
-  if (node)
-    return node->children_types;
-  
-  return NULL;
-}
+/* includes for various places
+ * with enum definitions
+ */
+#include "makeenums.h"
+/* type variable declarations
+ */
+#include "gtktypebuiltins_vars.c"
+GType GTK_TYPE_IDENTIFIER = 0;
+#include "gtktypebuiltins_evals.c"       /* enum value definition arrays */
 
-void
-gtk_type_describe_heritage (GtkType type)
-{
-  GtkTypeNode *node;
-  gchar *is_a = "";
-  
-  LOOKUP_TYPE_NODE (node, type);
-  
-  while (node)
-    {
-      if (node->type_info.type_name)
-       g_message ("%s%s",
-                  is_a,
-                  node->type_info.type_name);
-      else
-       g_message ("%s<unnamed type>",
-                  is_a);
-      is_a = "is a ";
-      
-      LOOKUP_TYPE_NODE (node, node->parent_type);
-    }
-}
+/* Hack to communicate with GLib object debugging for now
+ */
+extern gboolean glib_debug_objects;
 
 void
-gtk_type_describe_tree (GtkType         type,
-                       gboolean show_size)
+gtk_type_init (void)
 {
-  GtkTypeNode *node;
-  
-  LOOKUP_TYPE_NODE (node, type);
-  
-  if (node)
-    {
-      static gint indent = 0;
-      GList *list;
-      guint old_indent;
+  static gboolean initialized = FALSE;
+  
+  if (!initialized)
+    {
+      static const struct {
+       GtkType type_id;
+       gchar *name;
+      } fundamental_info[] = {
+       { GTK_TYPE_POINTER,     "gpointer" },
+       { GTK_TYPE_SIGNAL,      "GtkSignal" },
+      };
+      static struct {
+       gchar              *type_name;
+       GtkType            *type_id;
+       GtkType             parent;
+       const GtkEnumValue *values;
+      } builtin_info[GTK_TYPE_N_BUILTINS + 1] = {
+#include "gtktypebuiltins_ids.c"       /* type entries */
+       { NULL }
+      };
+      GTypeFundamentalInfo finfo = { 0, };
+      GTypeInfo tinfo = { 0, };
+      GtkType type_id;
       guint i;
-      GString *gstring;
 
-      gstring = g_string_new ("");
-      
-      for (i = 0; i < indent; i++)
-       g_string_append_c (gstring, ' ');
-      
-      if (node->type_info.type_name)
-       g_string_append (gstring, node->type_info.type_name);
-      else
-       g_string_append (gstring, "<unnamed type>");
-      
-      if (show_size)
-       g_string_sprintfa (gstring, " (%d bytes)", node->type_info.object_size);
+      initialized = TRUE;
 
-      g_message ("%s", gstring->str);
-      g_string_free (gstring, TRUE);
-      
-      old_indent = indent;
-      indent += 4;
+      glib_debug_objects = gtk_debug_flags & GTK_DEBUG_OBJECTS != 0;
       
-      for (list = node->children_types; list; list = list->next)
-       gtk_type_describe_tree (GPOINTER_TO_UINT (list->data), show_size);
+      /* initialize GLib type system
+       */
+      g_type_init ();
       
-      indent = old_indent;
-    }
-}
+      /* GTK_TYPE_OBJECT
+       */
+      gtk_object_get_type ();
 
-gboolean
-gtk_type_is_a (GtkType type,
-              GtkType is_a_type)
-{
-  if (type == is_a_type)
-    return TRUE;
-  else
-    {
-      GtkTypeNode *node;
-      
-      LOOKUP_TYPE_NODE (node, type);
-      if (node)
+      /* compatibility fundamentals
+       */
+      for (i = 0; i < sizeof (fundamental_info) / sizeof (fundamental_info[0]); i++)
        {
-         GtkTypeNode *a_node;
-         
-         LOOKUP_TYPE_NODE (a_node, is_a_type);
-         if (a_node)
-           {
-             if (a_node->n_supers <= node->n_supers)
-               return node->supers[node->n_supers - a_node->n_supers] == is_a_type;
-           }
+         type_id = g_type_register_fundamental (fundamental_info[i].type_id,
+                                                fundamental_info[i].name,
+                                                &tinfo,
+                                                &finfo);
+         g_assert (type_id == fundamental_info[i].type_id);
        }
-    }
-  
-  return FALSE;
-}
 
-static void
-gtk_type_class_init (GtkType type)
-{
-  GtkTypeNode *node;
+      /* GTK_TYPE_IDENTIFIER
+       */
+      GTK_TYPE_IDENTIFIER = g_type_register_static (G_TYPE_STRING, "GtkIdentifier", &tinfo);
 
-  /* we need to relookup nodes everytime we called an external function */
-  LOOKUP_TYPE_NODE (node, type);
-  
-  if (!node->klass && node->type_info.class_size)
-    {
-      GtkTypeClass *type_class;
-      GtkTypeNode *base_node;
-      GSList *slist;
-      
-      if (node->type_info.class_size < sizeof (GtkTypeClass))
-       g_warning ("The `%s' class is too small to inherit from GtkTypeClass",
-                  node->type_info.type_name);
-      
-      node->klass = g_malloc0 (node->type_info.class_size);
-      
-      if (node->parent_type)
-       {
-         GtkTypeNode *parent;
-         
-         LOOKUP_TYPE_NODE (parent, node->parent_type);
-         
-         if (node->type_info.class_size < parent->type_info.class_size)
-           g_warning ("The `%s' class is smaller than its parent class `%s'",
-                      node->type_info.type_name,
-                      parent->type_info.type_name);
-         
-         if (!parent->klass)
-           {
-             gtk_type_class_init (parent->type);
-             LOOKUP_TYPE_NODE (node, type);
-             LOOKUP_TYPE_NODE (parent, node->parent_type);
-           }
-         
-         if (parent->klass)
-           memcpy (node->klass, parent->klass, parent->type_info.class_size);
-       }
-      
-      type_class = node->klass;
-      type_class->type = node->type;
-      
-      /* stack all base class initialization functions, so we
-       * call them in ascending order.
+      /* GTK_TYPE_BOXED
        */
-      base_node = node;
-      slist = NULL;
-      while (base_node)
-       {
-         if (base_node->type_info.base_class_init_func)
-           slist = g_slist_prepend (slist, base_node->type_info.base_class_init_func);
-         LOOKUP_TYPE_NODE (base_node, base_node->parent_type);
-       }
-      if (slist)
+      finfo.type_flags = G_TYPE_FLAG_DERIVABLE;
+      type_id = g_type_register_fundamental (GTK_TYPE_BOXED, "GtkBoxed", &tinfo, &finfo);
+      g_assert (type_id == GTK_TYPE_BOXED);
+
+      /* enums and flags
+       */
+      for (i = 0; i < GTK_TYPE_N_BUILTINS; i++)
        {
-         GSList *walk;
-         
-         for (walk = slist; walk; walk = walk->next)
-           {
-             GtkClassInitFunc base_class_init;
-             
-             base_class_init = walk->data;
-             base_class_init (node->klass);
-             LOOKUP_TYPE_NODE (node, type);
-           }
-         g_slist_free (slist);
+         GtkType type_id = 0;
+
+         if (builtin_info[i].parent == G_TYPE_ENUM)
+           type_id = g_enum_register_static (builtin_info[i].type_name, builtin_info[i].values);
+         else if (builtin_info[i].parent == G_TYPE_FLAGS)
+           type_id = g_flags_register_static (builtin_info[i].type_name, builtin_info[i].values);
+         else if (builtin_info[i].parent == GTK_TYPE_BOXED)
+           type_id = g_type_register_static (GTK_TYPE_BOXED, builtin_info[i].type_name, &tinfo);
+         else
+           g_assert_not_reached ();
+
+         *builtin_info[i].type_id = type_id;
        }
-      
-      if (node->type_info.class_init_func)
-       node->type_info.class_init_func (node->klass);
-    }
-}
-
-static inline gchar*
-gtk_type_descriptive_name (GtkType type)
-{
-  gchar *name;
-
-  name = gtk_type_name (type);
-  if (!name)
-    name = "(unknown)";
-
-  return name;
-}
-
-GtkTypeObject*
-gtk_type_check_object_cast (GtkTypeObject  *type_object,
-                           GtkType         cast_type)
-{
-  if (!type_object)
-    {
-      g_warning ("invalid cast from (NULL) pointer to `%s'",
-                gtk_type_descriptive_name (cast_type));
-      return type_object;
     }
-  if (!type_object->klass)
-    {
-      g_warning ("invalid unclassed pointer in cast to `%s'",
-                gtk_type_descriptive_name (cast_type));
-      return type_object;
-    }
-  /* currently, GTK_TYPE_OBJECT is the lowest fundamental type
-   * dominator for types that introduce classes.
-   */
-  if (type_object->klass->type < GTK_TYPE_OBJECT)
-    {
-      g_warning ("invalid class type `%s' in cast to `%s'",
-                gtk_type_descriptive_name (type_object->klass->type),
-                gtk_type_descriptive_name (cast_type));
-      return type_object;
-    }
-  if (!gtk_type_is_a (type_object->klass->type, cast_type))
-    {
-      g_warning ("invalid cast from `%s' to `%s'",
-                gtk_type_descriptive_name (type_object->klass->type),
-                gtk_type_descriptive_name (cast_type));
-      return type_object;
-    }
-
-  return type_object;
-}
-
-GtkTypeClass*
-gtk_type_check_class_cast (GtkTypeClass   *klass,
-                          GtkType         cast_type)
-{
-  if (!klass)
-    {
-      g_warning ("invalid class cast from (NULL) pointer to `%s'",
-                gtk_type_descriptive_name (cast_type));
-      return klass;
-    }
-  /* currently, GTK_TYPE_OBJECT is the lowest fundamental type
-   * dominator for types that introduce classes.
-   */
-  if (klass->type < GTK_TYPE_OBJECT)
-    {
-      g_warning ("invalid class type `%s' in class cast to `%s'",
-                gtk_type_descriptive_name (klass->type),
-                gtk_type_descriptive_name (cast_type));
-      return klass;
-    }
-  if (!gtk_type_is_a (klass->type, cast_type))
-    {
-      g_warning ("invalid class cast from `%s' to `%s'",
-                gtk_type_descriptive_name (klass->type),
-                gtk_type_descriptive_name (cast_type));
-      return klass;
-    }
-
-  return klass;
 }
 
 GtkEnumValue*
-gtk_type_enum_get_values (GtkType      enum_type)
-{
-  if (GTK_FUNDAMENTAL_TYPE (enum_type) == GTK_TYPE_ENUM ||
-      GTK_FUNDAMENTAL_TYPE (enum_type) == GTK_TYPE_FLAGS)
-    {
-      GtkTypeNode *node;
-      
-      LOOKUP_TYPE_NODE (node, enum_type);
-      if (node)
-       return (GtkEnumValue*) node->type_info.reserved_1;
-    }
-  
-  g_warning ("gtk_type_enum_get_values(): type `%s' is not derived from `GtkEnum' or `GtkFlags'",
-            gtk_type_name (enum_type));
-  
-  return NULL;
-}
-
-GtkFlagValue*
-gtk_type_flags_get_values (GtkType       flags_type)
+gtk_type_enum_get_values (GtkType enum_type)
 {
-  return gtk_type_enum_get_values (flags_type);
-}
+  GEnumClass *class;
 
-GtkEnumValue*
-gtk_type_enum_find_value (GtkType        enum_type,
-                         const gchar    *value_name)
-{
-  g_return_val_if_fail (value_name != NULL, NULL);
+  g_return_val_if_fail (G_TYPE_IS_ENUM (enum_type), NULL);
   
-  if (GTK_FUNDAMENTAL_TYPE (enum_type) == GTK_TYPE_ENUM ||
-      GTK_FUNDAMENTAL_TYPE (enum_type) == GTK_TYPE_FLAGS)
-    {
-      GtkEnumValue *vals;
-
-      vals = gtk_type_enum_get_values (enum_type);
-      if (vals)
-       while (vals->value_name)
-         {
-           if (strcmp (vals->value_name, value_name) == 0 ||
-               strcmp (vals->value_nick, value_name) == 0)
-             return vals;
-           vals++;
-         }
-    }
-  else
-    g_warning ("gtk_type_enum_find_value(): type `%s' is not derived from `GtkEnum' or `GtkFlags'",
-              gtk_type_name (enum_type));
+  class = gtk_type_class (enum_type);
   
-  return NULL;
+  return class->values;
 }
 
 GtkFlagValue*
-gtk_type_flags_find_value (GtkType         flag_type,
-                          const gchar    *value_name)
-{
-  g_return_val_if_fail (value_name != NULL, NULL);
-
-  return gtk_type_enum_find_value (flag_type, value_name);
-}
-
-typedef struct _GtkTypeVarargType GtkTypeVarargType;
-struct _GtkTypeVarargType
+gtk_type_flags_get_values (GtkType flags_type)
 {
-  GtkType foreign_type;
-  GtkType varargs_type;
-};
-
-static GtkTypeVarargType *vararg_types = NULL;
-static guint              n_vararg_types = 0;
+  GFlagsClass *class;
 
-void
-gtk_type_set_varargs_type (GtkType        foreign_type,
-                          GtkType        varargs_type)
-{
-  g_return_if_fail (foreign_type == GTK_FUNDAMENTAL_TYPE (foreign_type));
-  g_return_if_fail (foreign_type > GTK_TYPE_FUNDAMENTAL_LAST);
-
-  if (!((varargs_type >= GTK_TYPE_STRUCTURED_FIRST &&
-        varargs_type <= GTK_TYPE_STRUCTURED_LAST) ||
-       (varargs_type >= GTK_TYPE_FLAT_FIRST &&
-        varargs_type <= GTK_TYPE_FLAT_LAST) ||
-       varargs_type == GTK_TYPE_NONE))
-    {
-      g_warning ("invalid varargs type `%s' for fundamental type `%s'",
-                gtk_type_name (varargs_type),
-                gtk_type_name (foreign_type));
-      return;
-    }
-  if (gtk_type_get_varargs_type (foreign_type))
-    {
-      g_warning ("varargs type is already registered for fundamental type `%s'",
-                gtk_type_name (foreign_type));
-      return;
-    }
+  g_return_val_if_fail (G_TYPE_IS_FLAGS (flags_type), NULL);
 
-  n_vararg_types++;
-  vararg_types = g_realloc (vararg_types, sizeof (GtkTypeVarargType) * n_vararg_types);
+  class = gtk_type_class (flags_type);
 
-  vararg_types[n_vararg_types - 1].foreign_type = foreign_type;
-  vararg_types[n_vararg_types - 1].varargs_type = varargs_type;
+  return class->values;
 }
 
-GtkType
-gtk_type_get_varargs_type (GtkType foreign_type)
+GtkEnumValue*
+gtk_type_enum_find_value (GtkType      enum_type,
+                         const gchar *value_name)
 {
-  GtkType type;
-  guint i;
-
-  type = GTK_FUNDAMENTAL_TYPE (foreign_type);
-  if (type <= GTK_TYPE_FUNDAMENTAL_LAST)
-    return type;
-
-  for (i = 0; i < n_vararg_types; i++)
-    if (vararg_types[i].foreign_type == type)
-      return vararg_types[i].varargs_type;
+  GtkEnumValue *value;
+  GEnumClass *class;
 
-  return 0;
-}
-
-static inline GtkType
-gtk_type_register_intern (gchar                     *name,
-                         GtkType             parent,
-                         const GtkEnumValue *values)
-{
-  GtkType type_id;
-  GtkTypeInfo info;
-  
-  info.type_name = name;
-  info.object_size = 0;
-  info.class_size = 0;
-  info.class_init_func = NULL;
-  info.object_init_func = NULL;
-  info.reserved_1 = (gpointer) values;
-  info.reserved_2 = NULL;
-  
-  /* relookup pointers afterwards.
-   */
-  type_id = gtk_type_create (parent, name, &info);
-  
-  if (type_id && values)
-    {
-      guint i;
-      
-      /* check for proper type consistency and NULL termination
-       * of value array
-       */
-      g_assert (GTK_FUNDAMENTAL_TYPE (type_id) == GTK_TYPE_ENUM ||
-               GTK_FUNDAMENTAL_TYPE (type_id) == GTK_TYPE_FLAGS);
-      
-      i = 0;
-      while (values[i].value_name)
-       i++;
-      
-      g_assert (values[i].value_name == NULL && values[i].value_nick == NULL);
-    }
-  
-  return type_id;
-}
+  g_return_val_if_fail (G_TYPE_IS_ENUM (enum_type), NULL);
+  g_return_val_if_fail (value_name != NULL, NULL);
 
-GtkType
-gtk_type_register_enum (const gchar    *type_name,
-                       GtkEnumValue   *values)
-{
-  GtkType type_id;
-  gchar *name;
-  
-  g_return_val_if_fail (type_name != NULL, 0);
-  
-  name = g_strdup (type_name);
-  
-  /* relookup pointers afterwards.
-   */
-  type_id = gtk_type_register_intern (name, GTK_TYPE_ENUM, values);
-  
-  if (!type_id)
-    g_free (name);
-  
-  return type_id;
-}
+  class = gtk_type_class (enum_type);
+  value = g_enum_get_value_by_name (class, value_name);
+  if (!value)
+    value = g_enum_get_value_by_nick (class, value_name);
 
-GtkType
-gtk_type_register_flags (const gchar   *type_name,
-                        GtkFlagValue   *values)
-{
-  GtkType type_id;
-  gchar *name;
-  
-  g_return_val_if_fail (type_name != NULL, 0);
-  
-  name = g_strdup (type_name);
-  
-  /* relookup pointers afterwards.
-   */
-  type_id = gtk_type_register_intern (name, GTK_TYPE_FLAGS, values);
-  
-  if (!type_id)
-    g_free (name);
-  
-  return type_id;
+  return value;
 }
 
-GtkTypeQuery*
-gtk_type_query (GtkType type)
+GtkFlagValue*
+gtk_type_flags_find_value (GtkType      flags_type,
+                          const gchar *value_name)
 {
-  GtkTypeNode *node;
-  
-  LOOKUP_TYPE_NODE (node, type);
-  if (node)
-    {
-      GtkTypeQuery *query;
-
-      query = g_new0 (GtkTypeQuery, 1);
-      query->type = type;
-      query->type_name = node->type_info.type_name;
-      query->object_size = node->type_info.object_size;
-      query->class_size = node->type_info.class_size;
-
-      return query;
-    }
-  
-  return NULL;
-}
-
-extern void gtk_object_init_type (void);
+  GtkFlagValue *value;
+  GFlagsClass *class;
 
-#include "makeenums.h"                 /* include for various places
-                                        * with enum definitions
-                                        */
-#include "gtktypebuiltins_vars.c"      /* type variable declarations
-                                        */
-#include "gtktypebuiltins_evals.c"     /* enum value definition arrays
-                                        */
+  g_return_val_if_fail (G_TYPE_IS_FLAGS (flags_type), NULL);
+  g_return_val_if_fail (value_name != NULL, NULL);
 
-static void
-gtk_type_init_builtin_types (void)
-{
-  /* GTK_TYPE_INVALID has typeid 0.  The first type id returned by
-   * gtk_type_unique is 1, which is GTK_TYPE_NONE.  And so on.
-   */
-  
-  static const struct {
-    GtkType type_id;
-    gchar *name;
-  } fundamental_info[] = {
-    { GTK_TYPE_NONE,           "void" },
-    { GTK_TYPE_CHAR,           "gchar" },
-    { GTK_TYPE_UCHAR,          "guchar" },
-    { GTK_TYPE_BOOL,           "gboolean" },
-    { GTK_TYPE_INT,            "gint" },
-    { GTK_TYPE_UINT,           "guint" },
-    { GTK_TYPE_LONG,           "glong" },
-    { GTK_TYPE_ULONG,          "gulong" },
-    { GTK_TYPE_FLOAT,          "gfloat" },
-    { GTK_TYPE_DOUBLE,         "gdouble" },
-    { GTK_TYPE_STRING,         "GtkString" },
-    { GTK_TYPE_ENUM,           "GtkEnum" },
-    { GTK_TYPE_FLAGS,          "GtkFlags" },
-    { GTK_TYPE_BOXED,          "GtkBoxed" },
-    { GTK_TYPE_POINTER,                "gpointer" },
-    
-    { GTK_TYPE_SIGNAL,         "GtkSignal" },
-    { GTK_TYPE_ARGS,           "GtkArgs" },
-    { GTK_TYPE_CALLBACK,       "GtkCallback" },
-    { GTK_TYPE_C_CALLBACK,     "GtkCCallback" },
-    { GTK_TYPE_FOREIGN,                "GtkForeign" },
-  };
-  static struct {
-    gchar *type_name;
-    GtkType *type_id;
-    GtkType parent;
-    const GtkEnumValue *values;
-  } builtin_info[GTK_TYPE_NUM_BUILTINS + 1] = {
-#include "gtktypebuiltins_ids.c"       /* type entries */
-    { NULL }
-  };
-  guint i;
-  
-  for (i = 0; i < sizeof (fundamental_info) / sizeof (fundamental_info[0]); i++)
-    {
-      GtkType type_id;
-      
-      /* relookup pointers afterwards.
-       */
-      type_id = gtk_type_register_intern (fundamental_info[i].name, 0, NULL);
-      
-      g_assert (type_id == fundamental_info[i].type_id);
-    }
-  
-  gtk_object_init_type ();
-  
-  for (i = 0; i < GTK_TYPE_NUM_BUILTINS; i++)
-    {
-      GtkType type_id;
-      
-      g_assert (builtin_info[i].type_name != NULL);
-      
-      /* relookup pointers afterwards.
-       */
-      type_id = gtk_type_register_intern (builtin_info[i].type_name,
-                                         builtin_info[i].parent,
-                                         builtin_info[i].values);
-      
-      g_assert (GTK_TYPE_SEQNO (type_id) > GTK_TYPE_FUNDAMENTAL_MAX);
-      
-      (*builtin_info[i].type_id) = type_id;
-    }
-}
+  class = gtk_type_class (flags_type);
+  value = g_flags_get_value_by_name (class, value_name);
+  if (!value)
+    value = g_flags_get_value_by_nick (class, value_name);
 
-GtkType
-gtk_identifier_get_type (void)
-{
-  static GtkType identifier_type = 0;
-  
-  if (!identifier_type)
-    identifier_type = gtk_type_register_intern ("GtkIdentifier", GTK_TYPE_STRING, NULL);
-  
-  return identifier_type;
+  return value;
 }