⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gtktypeutils.c

📁 gtk是linux一款强大的夸平台的图形化开发工具
💻 C
📖 第 1 页 / 共 2 页
字号:
/* GTK - The GIMP Toolkit * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library 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. *//* * Modified by the GTK+ Team and others 1997-1999.  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"#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 guint gtk_type_name_hash			(const char  *key);static gint  gtk_type_name_compare		(const char  *a,						 const char  *b);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){  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;}voidgtk_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 ((GHashFunc) gtk_type_name_hash,					      (GCompareFunc) gtk_type_name_compare);            gtk_type_init_builtin_types ();    }}voidgtk_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);}static GtkTypegtk_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;}GtkTypegtk_type_unique (GtkType      parent_type,		 const GtkTypeInfo *type_info){  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.   */  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;}GtkTypegtk_type_from_name (const gchar *name){  if (type_name_2_type_ht)    {      GtkType type;            type = GPOINTER_TO_UINT (g_hash_table_lookup (type_name_2_type_ht, (gpointer) name));            return type;    }    return 0;}GtkTypegtk_type_parent (GtkType type){  GtkTypeNode *node;    LOOKUP_TYPE_NODE (node, type);  if (node)    return node->parent_type;    return 0;}gpointergtk_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;	}    }    return NULL;}gpointergtk_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;}gpointergtk_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;  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;      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;}voidgtk_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);}GList*gtk_type_children_types (GtkType type){  GtkTypeNode *node;    LOOKUP_TYPE_NODE (node, type);  if (node)    return node->children_types;    return NULL;}voidgtk_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);    }}voidgtk_type_describe_tree (GtkType	 type,			gboolean show_size){  GtkTypeNode *node;    LOOKUP_TYPE_NODE (node, type);    if (node)    {      static gint indent = 0;      GList *list;      guint old_indent;      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);      g_message ("%s", gstring->str);      g_string_free (gstring, TRUE);            old_indent = indent;      indent += 4;            for (list = node->children_types; list; list = list->next)	gtk_type_describe_tree (GPOINTER_TO_UINT (list->data), show_size);            indent = old_indent;    }}gbooleangtk_type_is_a (GtkType type,	       GtkType is_a_type){  if (type == is_a_type)    return TRUE;  else    {      GtkTypeNode *node;            LOOKUP_TYPE_NODE (node, type);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -