*
* 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
+ * 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
* Boston, MA 02111-1307, USA.
*/
#include <string.h>
-#include "gtkobject.h"
#include "gtktypeutils.h"
-#include "gtkcontainer.h"
-#define TYPE_NODES_BLOCK_SIZE (200)
+#define TYPE_NODES_BLOCK_SIZE (35) /* needs to be > GTK_TYPE_FUNDAMENTAL_MAX */
typedef struct _GtkTypeNode GtkTypeNode;
#define LOOKUP_TYPE_NODE(node_var, type) { \
- if (type > 0) \
- { \
- register GtkType sqn = GTK_TYPE_SEQNO (type); \
- if (sqn < n_type_nodes) \
- node_var = type_nodes + sqn; \
- else \
- node_var = NULL; \
- } \
- else \
- node_var = NULL; \
-}
-
-static void gtk_type_class_init (GtkTypeNode *node);
+ 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_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 (void)
+gtk_type_node_next_and_invalidate (GtkType parent_type)
{
- static guint n_free_type_nodes = 0;
- register GtkTypeNode *node;
- register GtkType new_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)
{
- register guint i;
- register guint size;
+ guint i;
+ guint size;
/* nearest pow
*/
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;
+ }
}
- new_type = n_type_nodes++;
- n_free_type_nodes--;
-
- LOOKUP_TYPE_NODE (node, new_type);
- if (node)
- node->type = new_type;
+ 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;
}
{
if (n_type_nodes == 0)
{
- GtkTypeNode *zero;
-
g_assert (sizeof (GtkType) >= 4);
-
- zero = gtk_type_node_next_and_invalidate ();
- g_assert (zero == NULL);
-
+ 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 ();
}
}
void
gtk_type_set_chunk_alloc (GtkType type,
- guint n_chunks)
+ 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,
static GtkType
gtk_type_create (GtkType parent_type,
gchar *type_name,
- GtkTypeInfo *type_info)
+ 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;
}
}
-
+
/* relookup pointers afterwards.
*/
- new_node = gtk_type_node_next_and_invalidate ();
-
+ new_node = gtk_type_node_next_and_invalidate (parent_type);
+
if (parent_type)
{
- new_node->type = GTK_TYPE_MAKE (parent_type, new_node->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 <= 0xff);
+ 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->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;
}
GtkType
gtk_type_unique (GtkType parent_type,
- GtkTypeInfo *type_info)
+ 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 (n_type_nodes == 0)
- gtk_type_init ();
+ 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;
}
gtk_type_name (GtkType type)
{
GtkTypeNode *node;
-
+
LOOKUP_TYPE_NODE (node, type);
-
+
if (node)
return node->type_info.type_name;
-
+
return NULL;
}
GtkType type;
type = GPOINTER_TO_UINT (g_hash_table_lookup (type_name_2_type_ht, (gpointer) name));
-
+
return type;
}
-
+
return 0;
}
gtk_type_parent (GtkType type)
{
GtkTypeNode *node;
-
+
LOOKUP_TYPE_NODE (node, type);
if (node)
return node->parent_type;
-
+
return 0;
}
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)
- gtk_type_class_init (node);
-
+ {
+ type = node->type;
+ gtk_type_class_init (type);
+ LOOKUP_TYPE_NODE (node, type);
+ }
+
return node->klass;
}
}
-
+
return NULL;
}
gtk_type_class (GtkType type)
{
GtkTypeNode *node;
-
+
LOOKUP_TYPE_NODE (node, type);
g_return_val_if_fail (node != NULL, NULL);
-
+
if (!node->klass)
- gtk_type_class_init (node);
-
+ {
+ type = node->type;
+ gtk_type_class_init (type);
+ LOOKUP_TYPE_NODE (node, type);
+ }
+
return node->klass;
}
gtk_type_new (GtkType type)
{
GtkTypeNode *node;
- GtkObject *object;
+ GtkTypeObject *tobject;
gpointer klass;
- guint i;
-
+
LOOKUP_TYPE_NODE (node, type);
g_return_val_if_fail (node != NULL, NULL);
-
- klass = gtk_type_class (type);
- node->chunk_alloc_locked = TRUE;
- if (node->mem_chunk)
+
+ klass = node->klass;
+ if (!klass)
{
- object = g_mem_chunk_alloc (node->mem_chunk);
- memset (object, 0, node->type_info.object_size);
+ klass = gtk_type_class (type);
+ LOOKUP_TYPE_NODE (node, type);
}
- else
- object = g_malloc0 (node->type_info.object_size);
- object->klass = klass;
+ node->chunk_alloc_locked = TRUE;
- for (i = node->n_supers; i > 0; i--)
+ 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;
- LOOKUP_TYPE_NODE (pnode, node->supers[i]);
- if (pnode->type_info.object_init_func)
- (* pnode->type_info.object_init_func) (object);
+ 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) (object);
-
- return object;
+ {
+ node->type_info.object_init_func (tobject, klass);
+ tobject->klass = klass;
+ }
+
+ return tobject;
}
void
-gtk_type_free (GtkType type,
- gpointer mem)
+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
gtk_type_children_types (GtkType type)
{
GtkTypeNode *node;
-
+
LOOKUP_TYPE_NODE (node, type);
if (node)
return node->children_types;
-
+
return NULL;
}
gtk_type_describe_heritage (GtkType type)
{
GtkTypeNode *node;
- gboolean first;
-
+ gchar *is_a = "";
+
LOOKUP_TYPE_NODE (node, type);
- first = TRUE;
-
+
while (node)
{
- if (first)
- {
- first = FALSE;
- g_print ("is a ");
- }
-
if (node->type_info.type_name)
- g_print ("%s\n", node->type_info.type_name);
+ g_message ("%s%s",
+ is_a,
+ node->type_info.type_name);
else
- g_print ("<unnamed type>\n");
-
+ g_message ("%s<unnamed type>",
+ is_a);
+ is_a = "is a ";
+
LOOKUP_TYPE_NODE (node, node->parent_type);
}
}
void
-gtk_type_describe_tree (GtkType type,
+gtk_type_describe_tree (GtkType type,
gboolean show_size)
{
GtkTypeNode *node;
GList *list;
guint old_indent;
guint i;
+ GString *gstring;
+
+ gstring = g_string_new ("");
for (i = 0; i < indent; i++)
- g_print (" ");
+ g_string_append_c (gstring, ' ');
if (node->type_info.type_name)
- g_print ("%s", node->type_info.type_name);
+ g_string_append (gstring, node->type_info.type_name);
else
- g_print ("(no-name)");
+ g_string_append (gstring, "<unnamed type>");
if (show_size)
- g_print (" ( %d bytes )\n", node->type_info.object_size);
- else
- g_print ("\n");
+ 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;
}
}
-gint
+gboolean
gtk_type_is_a (GtkType type,
GtkType is_a_type)
{
return TRUE;
else
{
- register GtkTypeNode *node;
-
+ GtkTypeNode *node;
+
LOOKUP_TYPE_NODE (node, type);
if (node)
{
- register GtkTypeNode *a_node;
+ GtkTypeNode *a_node;
LOOKUP_TYPE_NODE (a_node, is_a_type);
if (a_node)
}
static void
-gtk_type_class_init (GtkTypeNode *node)
+gtk_type_class_init (GtkType type)
{
+ GtkTypeNode *node;
+
+ /* we need to relookup nodes everytime we called an external function */
+ LOOKUP_TYPE_NODE (node, type);
+
if (!node->klass && node->type_info.class_size)
{
- GtkObjectClass *object_class;
+ GtkTypeClass *type_class;
GtkTypeNode *base_node;
GSList *slist;
-
- g_assert (node->type_info.class_size >= sizeof (GtkObjectClass));
-
+
+ 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);
+ {
+ 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);
}
-
- object_class = node->klass;
- object_class->type = node->type;
-
+
+ type_class = node->klass;
+ type_class->type = node->type;
+
/* stack all base class initialization functions, so we
* call them in ascending order.
*/
if (slist)
{
GSList *walk;
-
+
for (walk = slist; walk; walk = walk->next)
{
- register GtkClassInitFunc base_class_init;
-
+ GtkClassInitFunc base_class_init;
+
base_class_init = walk->data;
base_class_init (node->klass);
+ LOOKUP_TYPE_NODE (node, type);
}
g_slist_free (slist);
}
- /* FIXME: this initialization needs to be done through
- * a function pointer someday.
- */
- g_assert (node->type_info.class_size >= sizeof (GtkObjectClass));
-
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)
{
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 `enum' or `flags'",
+
+ 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_flags_get_values (GtkType flags_type)
{
return gtk_type_enum_get_values (flags_type);
}
+GtkEnumValue*
+gtk_type_enum_find_value (GtkType enum_type,
+ const gchar *value_name)
+{
+ g_return_val_if_fail (value_name != NULL, 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));
+
+ return NULL;
+}
+
+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
+{
+ GtkType foreign_type;
+ GtkType varargs_type;
+};
+
+static GtkTypeVarargType *vararg_types = NULL;
+static guint n_vararg_types = 0;
+
+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;
+ }
+
+ n_vararg_types++;
+ vararg_types = g_realloc (vararg_types, sizeof (GtkTypeVarargType) * n_vararg_types);
+
+ vararg_types[n_vararg_types - 1].foreign_type = foreign_type;
+ vararg_types[n_vararg_types - 1].varargs_type = varargs_type;
+}
+
+GtkType
+gtk_type_get_varargs_type (GtkType foreign_type)
+{
+ 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;
+
+ return 0;
+}
+
static inline GtkType
-gtk_type_register_intern (gchar *name,
- GtkType parent,
- GtkEnumValue *values)
+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 = values;
+ 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;
}
{
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;
}
GtkType
-gtk_type_register_flags (const gchar *type_name,
- GtkFlagValue *values)
+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;
}
+GtkTypeQuery*
+gtk_type_query (GtkType type)
+{
+ 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;
+}
+
static guint
gtk_type_name_hash (const char *key)
{
guint result;
-
+
result = 0;
while (*key)
result += (result << 3) + *key++;
-
+
return result;
}
/* 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.
*/
-
- struct {
+
+ 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_ENUM, "GtkEnum" },
{ GTK_TYPE_FLAGS, "GtkFlags" },
{ GTK_TYPE_BOXED, "GtkBoxed" },
- { GTK_TYPE_FOREIGN, "GtkForeign" },
- { GTK_TYPE_CALLBACK, "GtkCallback" },
- { GTK_TYPE_ARGS, "GtkArgs" },
-
{ GTK_TYPE_POINTER, "gpointer" },
+
{ GTK_TYPE_SIGNAL, "GtkSignal" },
- { GTK_TYPE_C_CALLBACK, "GtkCCallback" }
+ { GTK_TYPE_ARGS, "GtkArgs" },
+ { GTK_TYPE_CALLBACK, "GtkCallback" },
+ { GTK_TYPE_C_CALLBACK, "GtkCCallback" },
+ { GTK_TYPE_FOREIGN, "GtkForeign" },
};
- struct {
+ static struct {
gchar *type_name;
GtkType *type_id;
GtkType parent;
- GtkEnumValue *values;
+ const GtkEnumValue *values;
} builtin_info[GTK_TYPE_NUM_BUILTINS + 1] = {
#include "gtktypebuiltins_ids.c" /* type entries */
{ NULL }
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, GTK_TYPE_INVALID, NULL);
-
+ type_id = gtk_type_register_intern (fundamental_info[i].name, 0, NULL);
+
g_assert (type_id == fundamental_info[i].type_id);
}
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 (type_id != GTK_TYPE_INVALID);
-
+
+ g_assert (GTK_TYPE_SEQNO (type_id) > GTK_TYPE_FUNDAMENTAL_MAX);
+
(*builtin_info[i].type_id) = type_id;
}
}
+
+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;
+}