diff options
author | Tim Janik <timj@gtk.org> | 1998-09-05 06:54:20 +0000 |
---|---|---|
committer | Tim Janik <timj@src.gnome.org> | 1998-09-05 06:54:20 +0000 |
commit | 78dbc1efdb39a1f70ea0782f1042187695a79bf7 (patch) | |
tree | c62984ec2a124d6911c1bb6d8af845add5316d59 /gtk | |
parent | 0f0d9509c061a1df2a6386e9ddc02ee4a921de26 (diff) | |
download | gdk-pixbuf-78dbc1efdb39a1f70ea0782f1042187695a79bf7.tar.gz |
don't include any gdk headers. added structure definitions for
Sat Sep 5 07:13:19 1998 Tim Janik <timj@gtk.org>
* gtk/gtktypeutils.h: don't include any gdk headers.
added structure definitions for GtkTypeObject and GtkTypeClass,
which cover the very basic fields of GtkObject and GtkObjectClass,
which are actually used by the type system.
* gtk/gtktypeutils.c: don't include gtkobject.h or gtkcontainer.h,
we only refer to our own structures. improved class inheritance
sanity checking a bit.
* gtk/gtkobject.h: placed appropriate comments at the beginnings
of the GtkObject and GtkObjectClass structures, which explain
their relationship to GtkTypeObject and GtkTypeClass.
* gtk/gtktypeutils.h:
* gtk/gtkobject.h:
moved GTK_STRUCT_OFFSET(), GTK_CHECK_CAST(), GTK_CHECK_CLASS_CAST(),
GTK_CHECK_TYPE() and GTK_CHECK_CLASS_TYPE() macro definitions from
gtkobject.h to gtktypeutils.h.
* gtk/gtkobject.h:
* gtk/gtkobject.c:
removed gtk_object_check_cast() and gtk_object_check_class_cast()
functions. to keep source compatibility, we can provide macro aliases
for the corresponding gtk_type_* functions. but then again, people
shouldn't have been using these functions anyways since they were part
of Gtk's internal API.
* gtk/gtktypeutils.h:
* gtk/gtktypeutils.c:
implemented gtk_type_check_object_cast() and gtk_type_check_class_cast()
functions to check GtkTypeObject and GtkTypeClass types.
Diffstat (limited to 'gtk')
-rw-r--r-- | gtk/gtkobject.c | 79 | ||||
-rw-r--r-- | gtk/gtkobject.h | 78 | ||||
-rw-r--r-- | gtk/gtktypeutils.c | 117 | ||||
-rw-r--r-- | gtk/gtktypeutils.h | 75 |
4 files changed, 193 insertions, 156 deletions
diff --git a/gtk/gtkobject.c b/gtk/gtkobject.c index d65aeea23..9a8014e4e 100644 --- a/gtk/gtkobject.c +++ b/gtk/gtkobject.c @@ -917,85 +917,6 @@ gtk_object_query_args (GtkType class_type, return gtk_args_query (class_type, object_arg_info_ht, arg_flags, n_args); } -/******************************************************** - * GtkObject and GtkObjectClass cast checking functions - * - ********************************************************/ - -static gchar* -gtk_object_descriptive_type_name (GtkType type) -{ - gchar *name; - - name = gtk_type_name (type); - if (!name) - name = "(unknown)"; - - return name; -} - -GtkObject* -gtk_object_check_cast (GtkObject *obj, - GtkType cast_type) -{ - if (!obj) - { - g_warning ("invalid cast from (NULL) pointer to `%s'", - gtk_object_descriptive_type_name (cast_type)); - return obj; - } - if (!obj->klass) - { - g_warning ("invalid unclassed pointer in cast to `%s'", - gtk_object_descriptive_type_name (cast_type)); - return obj; - } - if (obj->klass->type < GTK_TYPE_OBJECT) - { - g_warning ("invalid class type `%s' in cast to `%s'", - gtk_object_descriptive_type_name (obj->klass->type), - gtk_object_descriptive_type_name (cast_type)); - return obj; - } - if (!gtk_type_is_a (obj->klass->type, cast_type)) - { - g_warning ("invalid cast from `%s' to `%s'", - gtk_object_descriptive_type_name (obj->klass->type), - gtk_object_descriptive_type_name (cast_type)); - return obj; - } - - return obj; -} - -GtkObjectClass* -gtk_object_check_class_cast (GtkObjectClass *klass, - GtkType cast_type) -{ - if (!klass) - { - g_warning ("invalid class cast from (NULL) pointer to `%s'", - gtk_object_descriptive_type_name (cast_type)); - return klass; - } - if (klass->type < GTK_TYPE_OBJECT) - { - g_warning ("invalid class type `%s' in class cast to `%s'", - gtk_object_descriptive_type_name (klass->type), - gtk_object_descriptive_type_name (cast_type)); - return klass; - } - if (!gtk_type_is_a (klass->type, cast_type)) - { - g_warning ("invalid class cast from `%s' to `%s'", - gtk_object_descriptive_type_name (klass->type), - gtk_object_descriptive_type_name (cast_type)); - return klass; - } - - return klass; -} - /***************************************** * GtkObject object_data mechanism * diff --git a/gtk/gtkobject.h b/gtk/gtkobject.h index 3fe07f24d..e472b820d 100644 --- a/gtk/gtkobject.h +++ b/gtk/gtkobject.h @@ -33,42 +33,6 @@ extern "C" { -#ifdef offsetof -#define GTK_STRUCT_OFFSET(struct, field) ((gint) offsetof (struct, field)) -#else /* !offsetof */ -#define GTK_STRUCT_OFFSET(struct, field) ((gint) ((gchar*) &((struct*) 0)->field)) -#endif /* !offsetof */ - - -/* The debugging versions of the casting macros make sure the cast is "ok" - * before proceeding, but they are definately slower than their less - * careful counterparts as they involve no less than 3 function calls. - */ -#ifdef GTK_NO_CHECK_CASTS - -#define GTK_CHECK_CAST(obj,cast_type,cast) ((cast*) (obj)) -#define GTK_CHECK_CLASS_CAST(klass,cast_type,cast) ((cast*) (klass)) - -#else /* !GTK_NO_CHECK_CASTS */ - -#define GTK_CHECK_CAST(obj,cast_type,cast) \ - ((cast*) gtk_object_check_cast ((GtkObject*) (obj), (cast_type))) - -#define GTK_CHECK_CLASS_CAST(klass,cast_type,cast) \ - ((cast*) gtk_object_check_class_cast ((GtkObjectClass*) (klass), (cast_type))) - -#endif /* GTK_NO_CHECK_CASTS */ - - -/* Determines whether `obj' and `klass' are a type of `otype'. - */ -#define GTK_CHECK_TYPE(obj,otype) ( \ - gtk_type_is_a (((GtkObject*) (obj))->klass->type, (otype)) \ -) -#define GTK_CHECK_CLASS_TYPE(klass,otype) ( \ - gtk_type_is_a (((GtkObjectClass*) (klass))->type, (otype)) \ -) - /* Macro for casting a pointer to a GtkObject or GtkObjectClass pointer. * The second portion of the ?: statments are just in place to offer * descriptive warning message. @@ -76,12 +40,12 @@ extern "C" { #define GTK_OBJECT(object) ( \ GTK_IS_OBJECT (object) ? \ (GtkObject*) (object) : \ - (GtkObject*) gtk_object_check_cast ((GtkObject*) (object), GTK_TYPE_OBJECT) \ + (GtkObject*) gtk_type_check_object_cast ((GtkTypeObject*) (object), GTK_TYPE_OBJECT) \ ) #define GTK_OBJECT_CLASS(klass) ( \ GTK_IS_OBJECT_CLASS (klass) ? \ (GtkObjectClass*) (klass) : \ - (GtkObjectClass*) gtk_object_check_class_cast ((GtkObjectClass*) (klass), GTK_TYPE_OBJECT) \ + (GtkObjectClass*) gtk_type_check_class_cast ((GtkTypeClass*) (klass), GTK_TYPE_OBJECT) \ ) /* Macro for testing whether `object' and `klass' are of type GTK_TYPE_OBJECT. @@ -145,17 +109,17 @@ typedef enum typedef struct _GtkObjectClass GtkObjectClass; -/* GtkObject is the base of the object hierarchy. It defines - * the few basic items that all derived classes contain. +/* The GtkObject structure is the base of the Gtk+ objects hierarchy, + * it ``inherits'' from the GtkTypeObject by mirroring its fields, + * which must always be kept in sync completely. The GtkObject defines + * the few basic items that all derived classes contain. */ struct _GtkObject { - /* A pointer to the objects class. This will actually point to - * the derived objects class struct (which will be derived from - * GtkObjectClass). - */ + /* GtkTypeObject related fields: */ GtkObjectClass *klass; - + + /* 32 bits of flags. GtkObject only uses 4 of these bits and * GtkWidget uses the rest. This is done because structs are * aligned on 4 or 8 byte boundaries. If a new bitfield were @@ -174,17 +138,19 @@ struct _GtkObject gpointer object_data; }; -/* GtkObjectClass is the base of the class hierarchy. It defines - * the basic necessities for the class mechanism to work. Namely, - * the "type", "signals" and "nsignals" fields. +/* The GtkObjectClass is the base of the Gtk+ objects classes hierarchy, + * it ``inherits'' from the GtkTypeClass by mirroring its fields, which + * must always be kept in sync completely. The GtkObjectClass defines + * the basic necessities for the object inheritance mechanism to work. + * Namely, the `signals' and `nsignals' fields as well as the function + * pointers, required to end an object's lifetime. */ struct _GtkObjectClass { - /* The type identifier for the objects class. There is - * one unique identifier per class. - */ + /* GtkTypeClass fields: */ GtkType type; + /* The signals this object class handles. "signals" is an * array of signal ID's. */ @@ -337,16 +303,6 @@ void gtk_object_add_arg_type (const gchar *arg_name, guint arg_flags, guint arg_id); -/* The next two functions are provided to check an object/class pointer - * for its validity. Appropriate warning messages will be put out if - * the object or class pointers are invalid. - */ -GtkObject* gtk_object_check_cast (GtkObject *obj, - GtkType cast_type); - -GtkObjectClass* gtk_object_check_class_cast (GtkObjectClass *klass, - GtkType cast_type); - /* Object data method variants that operate on key ids. */ void gtk_object_set_data_by_id (GtkObject *object, GQuark data_id, diff --git a/gtk/gtktypeutils.c b/gtk/gtktypeutils.c index f27b25ab6..d261fbe8e 100644 --- a/gtk/gtktypeutils.c +++ b/gtk/gtktypeutils.c @@ -17,9 +17,7 @@ * Boston, MA 02111-1307, USA. */ #include <string.h> -#include "gtkobject.h" #include "gtktypeutils.h" -#include "gtkcontainer.h" #define TYPE_NODES_BLOCK_SIZE (200) @@ -331,7 +329,7 @@ gpointer gtk_type_new (GtkType type) { GtkTypeNode *node; - GtkObject *object; + GtkTypeObject *tobject; gpointer klass; guint i; @@ -340,13 +338,14 @@ gtk_type_new (GtkType type) klass = gtk_type_class (type); node->chunk_alloc_locked = TRUE; + if (node->mem_chunk) { - object = g_mem_chunk_alloc (node->mem_chunk); - memset (object, 0, node->type_info.object_size); + tobject = g_mem_chunk_alloc (node->mem_chunk); + memset (tobject, 0, node->type_info.object_size); } else - object = g_malloc0 (node->type_info.object_size); + 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 @@ -360,15 +359,15 @@ gtk_type_new (GtkType type) LOOKUP_TYPE_NODE (pnode, node->supers[i]); if (pnode->type_info.object_init_func) { - object->klass = pnode->klass; - pnode->type_info.object_init_func (object); + tobject->klass = pnode->klass; + pnode->type_info.object_init_func (tobject); } } - object->klass = klass; + tobject->klass = klass; if (node->type_info.object_init_func) - node->type_info.object_init_func (object); + node->type_info.object_init_func (tobject); - return object; + return tobject; } void @@ -501,11 +500,13 @@ gtk_type_class_init (GtkType 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); @@ -514,6 +515,12 @@ gtk_type_class_init (GtkType 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, + node->type_info.type_name); + if (!parent->klass) { gtk_type_class_init (parent->type); @@ -525,8 +532,8 @@ gtk_type_class_init (GtkType type) 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. @@ -559,6 +566,86 @@ gtk_type_class_init (GtkType type) } } +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) { diff --git a/gtk/gtktypeutils.h b/gtk/gtktypeutils.h index c2b3668b9..62957edee 100644 --- a/gtk/gtktypeutils.h +++ b/gtk/gtktypeutils.h @@ -20,7 +20,7 @@ #define __GTK_TYPE_UTILS_H__ -#include <gdk/gdk.h> +#include <glib.h> #ifdef __cplusplus @@ -74,8 +74,48 @@ typedef enum #define GTK_TYPE_FUNDAMENTAL_LAST GTK_TYPE_OBJECT +/* retrive a structure offset */ +#ifdef offsetof +#define GTK_STRUCT_OFFSET(struct, field) ((gint) offsetof (struct, field)) +#else /* !offsetof */ +#define GTK_STRUCT_OFFSET(struct, field) ((gint) ((gchar*) &((struct*) 0)->field)) +#endif /* !offsetof */ + + +/* The debugging versions of the casting macros make sure the cast is "ok" + * before proceeding, but they are definately slower than their less + * careful counterparts as they involve extra ``is a'' checks. + */ +#ifdef GTK_NO_CHECK_CASTS +# define GTK_CHECK_CAST(tobj, cast_type, cast) ((cast*) (tobj)) +# define GTK_CHECK_CLASS_CAST(tclass,cast_type,cast) ((cast*) (tclass)) +#else /* !GTK_NO_CHECK_CASTS */ +# define GTK_CHECK_CAST(tobj, cast_type, cast) \ + ((cast*) gtk_type_check_object_cast ((GtkTypeObject*) (tobj), (cast_type))) +# define GTK_CHECK_CLASS_CAST(tclass,cast_type,cast) \ + ((cast*) gtk_type_check_class_cast ((GtkTypeClass*) (tclass), (cast_type))) +#endif /* GTK_NO_CHECK_CASTS */ + +/* Determines whether `type_object' and `type_class' are a type of `otype'. + */ +#define GTK_CHECK_TYPE(type_object, otype) ( \ + gtk_type_is_a (((GtkTypeObject*) (type_object))->klass->type, (otype)) \ +) +#define GTK_CHECK_CLASS_TYPE(type_class, otype) ( \ + gtk_type_is_a (((GtkTypeClass*) (type_class))->type, (otype)) \ +) + + + + +/* A GtkType holds a unique type id + */ typedef guint GtkType; +typedef struct _GtkTypeObject GtkTypeObject; +typedef struct _GtkTypeClass GtkTypeClass; + + /* Builtin Types */ #include <gtk/gtktypebuiltins.h> @@ -118,6 +158,35 @@ typedef void (*GtkArgGetFunc) (GtkObject*, GtkArg*, guint); typedef void (*GtkArgSetFunc) (GtkObject*, GtkArg*, guint); +/* A GtkTypeObject defines the minimum structure requirements + * for type instances. Type instances returned from gtk_type_new () + * and initialized through a GtkObjectInitFunc need to directly inherit + * from this structure or at least copy its fields one by one. + */ +struct _GtkTypeObject +{ + /* A pointer to the objects class. This will actually point to + * the derived objects class struct (which will be derived from + * GtkTypeClass). + */ + GtkTypeClass *klass; +}; + + +/* A GtkTypeClass defines the minimum structure requirements for + * a types class. Classes returned from gtk_type_class () and + * initialized through a GtkClassInitFunc need to directly inherit + * from this structure or at least copy its fields one by one. + */ +struct _GtkTypeClass +{ + /* The type identifier for the objects class. There is + * one unique identifier per class. + */ + GtkType type; +}; + + struct _GtkArg { GtkType type; @@ -259,6 +328,10 @@ void gtk_type_describe_tree (GtkType type, gboolean show_size); gint gtk_type_is_a (GtkType type, GtkType is_a_type); +GtkTypeObject* gtk_type_check_object_cast (GtkTypeObject *type_object, + GtkType cast_type); +GtkTypeClass* gtk_type_check_class_cast (GtkTypeClass *klass, + GtkType cast_type); GtkType gtk_type_register_enum (const gchar *type_name, GtkEnumValue *values); GtkType gtk_type_register_flags (const gchar *type_name, |