#include <gobject/gparamspecs.h>
#include <gobject/gsignal.h>
#include <gobject/gtype.h>
+#include <gobject/gtypeplugin.h>
#include <gobject/gvalue.h>
#include <gobject/gvaluetypes.h>
#include <gobject/gparamspecs.h>
#include <gobject/gsignal.h>
#include <gobject/gtype.h>
+#include <gobject/gtypeplugin.h>
#include <gobject/gvalue.h>
#include <gobject/gvaluetypes.h>
+Sun Nov 5 05:22:55 2000 Tim Janik <timj@gtk.org>
+
+ * gsignal.c:
+ fixed a bag full of subtle bugs of immensive screw-up potential in
+ handlers_find(), luckily no one found out about them yet ;)
+ fixed signal_handlers_foreach_matched_R() so it operates on an
+ initial handler list snapshot provided by handlers_find() to work
+ around general reentrancy problems and to avoid multiple callback()
+ invocations on the same handlers.
+ this code is now officially 80% bug free (10% remaining for interface
+ types, and 10% remaining for destroyed signals ;)
+
+Sat Nov 4 02:01:33 2000 Tim Janik <timj@gtk.org>
+
+ * gsignal.c (_g_signals_destroy): valid signal nodes start out at 1.
+
+ * gtypeplugin.[hc]: new files holding a GTypePlugin interface
+ implementation that provides the API required by GType to deal with
+ dynamically loadable types.
+
+ * gtype.[hc]: displace any GTypePlugin business to gtypeplugin.h.
+
Fri Nov 3 07:35:00 2000 Tim Janik <timj@gtk.org>
* gsignal.[hc]: prefix internal functions with '_'. renamed
gparamspecs.h \
gsignal.h \
gtype.h \
+ gtypeplugin.h \
gvalue.h \
gvaluecollector.h \
gvaluetypes.h \
gparamspecs.c \
gsignal.c \
gtype.c \
+ gtypeplugin.c \
gvalue.c \
gvaluetypes.c \
@STRIP_END@
static void
g_object_do_finalize (GObject *object)
{
- _g_signal_handlers_destroy (object);
+ g_signal_handlers_destroy (object);
g_datalist_clear (&object->qdata);
#ifdef DEBUG_OBJECTS
/* --- typedefs --- */
-typedef struct _SignalNode SignalNode;
-typedef struct _SignalKey SignalKey;
-typedef struct _Emission Emission;
-typedef struct _Handler Handler;
-typedef struct _HandlerList HandlerList;
+typedef struct _SignalNode SignalNode;
+typedef struct _SignalKey SignalKey;
+typedef struct _Emission Emission;
+typedef struct _Handler Handler;
+typedef struct _HandlerList HandlerList;
+typedef struct _HandlerMatch HandlerMatch;
typedef enum
{
EMISSION_STOP,
/* --- prototypes --- */
-static inline guint signal_id_lookup (GQuark quark,
- GType itype);
-static void signal_destroy_R (SignalNode *signal_node);
-static inline HandlerList* handler_list_ensure (guint signal_id,
- gpointer instance);
-static inline HandlerList* handler_list_lookup (guint signal_id,
- gpointer instance);
-static inline Handler* handler_new (gboolean after);
-static void handler_insert (guint signal_id,
- gpointer instance,
- Handler *handler);
-static Handler* handler_lookup (gpointer instance,
- guint handler_id,
- guint *signal_id_p);
-static Handler* handler_find (gpointer instance,
- GSignalMatchType mask,
- guint signal_id,
- GQuark detail,
- GClosure *closure,
- gpointer func,
- gpointer data);
-static inline void handler_ref (Handler *handler);
-static inline void handler_unref_R (guint signal_id,
- gpointer instance,
- Handler *handler);
-static inline void emission_push (Emission **emission_list_p,
- guint signal_id,
- GQuark detail,
- gpointer instance,
- EmissionState *state_p);
-static inline void emission_pop (Emission **emission_list_p,
- EmissionState *state_p);
-static inline Emission* emission_find (Emission *emission_list,
- guint signal_id,
- GQuark detail,
- gpointer instance);
-static void signal_emit_R (SignalNode *node,
- GQuark detail,
- gpointer instance,
- GValue *return_value,
- const GValue *instance_and_params);
+static inline guint signal_id_lookup (GQuark quark,
+ GType itype);
+static void signal_destroy_R (SignalNode *signal_node);
+static inline HandlerList* handler_list_ensure (guint signal_id,
+ gpointer instance);
+static inline HandlerList* handler_list_lookup (guint signal_id,
+ gpointer instance);
+static inline Handler* handler_new (gboolean after);
+static void handler_insert (guint signal_id,
+ gpointer instance,
+ Handler *handler);
+static Handler* handler_lookup (gpointer instance,
+ guint handler_id,
+ guint *signal_id_p);
+static inline HandlerMatch* handler_match_prepend (HandlerMatch *list,
+ Handler *handler,
+ guint signal_id);
+static inline HandlerMatch* handler_match_free1_R (HandlerMatch *node,
+ gpointer instance);
+static HandlerMatch* handlers_find (gpointer instance,
+ GSignalMatchType mask,
+ guint signal_id,
+ GQuark detail,
+ GClosure *closure,
+ gpointer func,
+ gpointer data,
+ gboolean one_and_only);
+static inline void handler_ref (Handler *handler);
+static inline void handler_unref_R (guint signal_id,
+ gpointer instance,
+ Handler *handler);
+static inline void emission_push (Emission **emission_list_p,
+ guint signal_id,
+ GQuark detail,
+ gpointer instance,
+ EmissionState *state_p);
+static inline void emission_pop (Emission **emission_list_p,
+ EmissionState *state_p);
+static inline Emission* emission_find (Emission *emission_list,
+ guint signal_id,
+ GQuark detail,
+ gpointer instance);
+static void signal_emit_R (SignalNode *node,
+ GQuark detail,
+ gpointer instance,
+ GValue *return_value,
+ const GValue *instance_and_params);
/* --- structures --- */
guint signal_id;
Handler *handlers;
};
-
struct _Handler
{
guint id;
guint after : 1;
GClosure *closure;
};
+struct _HandlerMatch
+{
+ Handler *handler;
+ HandlerMatch *next;
+ union {
+ guint signal_id;
+ gpointer dummy;
+ } d;
+};
/* --- variables --- */
return NULL;
}
-static Handler*
-handler_find (gpointer instance,
- GSignalMatchType mask,
- guint signal_id,
- GQuark detail,
- GClosure *closure,
- gpointer func,
- gpointer data)
+static inline HandlerMatch*
+handler_match_prepend (HandlerMatch *list,
+ Handler *handler,
+ guint signal_id)
+{
+ HandlerMatch *node;
+
+ /* yeah, we could use our own memchunk here, introducing yet more
+ * rarely used cached nodes and extra allocation overhead.
+ * instead, we use GList* nodes, since they are exactly the size
+ * we need and are already cached. g_signal_init() asserts this.
+ */
+ node = (HandlerMatch*) g_list_alloc ();
+ node->handler = handler;
+ node->next = list;
+ node->d.signal_id = signal_id;
+ handler_ref (handler);
+
+ return node;
+}
+static inline HandlerMatch*
+handler_match_free1_R (HandlerMatch *node,
+ gpointer instance)
+{
+ HandlerMatch *next = node->next;
+
+ handler_unref_R (node->d.signal_id, instance, node->handler);
+ g_list_free_1 ((GList*) node);
+
+ return next;
+}
+
+static HandlerMatch*
+handlers_find (gpointer instance,
+ GSignalMatchType mask,
+ guint signal_id,
+ GQuark detail,
+ GClosure *closure,
+ gpointer func,
+ gpointer data,
+ gboolean one_and_only)
{
+ HandlerMatch *mlist = NULL;
+
if (mask & G_SIGNAL_MATCH_ID)
{
HandlerList *hlist = handler_list_lookup (signal_id, instance);
if (!node || !node->c_marshaller)
return NULL;
}
-
+
mask = ~mask;
for (handler = hlist ? hlist->handlers : NULL; handler; handler = handler->next)
- if (((mask & G_SIGNAL_MATCH_DETAIL) || handler->detail == detail) &&
+ if (handler->id &&
+ ((mask & G_SIGNAL_MATCH_DETAIL) || handler->detail == detail) &&
((mask & G_SIGNAL_MATCH_CLOSURE) || handler->closure == closure) &&
((mask & G_SIGNAL_MATCH_DATA) || handler->closure->data == data) &&
((mask & G_SIGNAL_MATCH_UNBLOCKED) || handler->block_count == 0) &&
((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller &&
handler->closure->meta_marshal == 0 &&
((GCClosure*) handler->closure)->callback == func)))
- return handler;
+ {
+ mlist = handler_match_prepend (mlist, handler, signal_id);
+ if (one_and_only)
+ return mlist;
+ }
}
else
{
if (!node->c_marshaller)
continue;
}
-
+
for (handler = hlist->handlers; handler; handler = handler->next)
- if (((mask & G_SIGNAL_MATCH_DETAIL) || handler->detail == detail) &&
+ if (handler->id &&
+ ((mask & G_SIGNAL_MATCH_DETAIL) || handler->detail == detail) &&
((mask & G_SIGNAL_MATCH_CLOSURE) || handler->closure == closure) &&
((mask & G_SIGNAL_MATCH_DATA) || handler->closure->data == data) &&
((mask & G_SIGNAL_MATCH_UNBLOCKED) || handler->block_count == 0) &&
((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller &&
handler->closure->meta_marshal == 0 &&
((GCClosure*) handler->closure)->callback == func)))
- return handler;
+ {
+ mlist = handler_match_prepend (mlist, handler, signal_id);
+ if (one_and_only)
+ return mlist;
+ }
}
}
}
- return NULL;
+ return mlist;
}
static inline Handler*
{
if (handler->next)
handler->next->prev = handler->prev;
- if (handler->prev) /* watch out for _g_signal_handlers_destroy()! */
+ if (handler->prev) /* watch out for g_signal_handlers_destroy()! */
handler->prev->next = handler->next;
else
{
EmissionState *state_p)
{
Emission **loc = emission_list_p, *emission = *loc;
-
+
while (emission->state_p != state_p)
{
loc = &emission->next;
G_LOCK (g_signal_mutex);
if (!g_n_signal_nodes)
{
+ /* handler_id_node_prepend() requires this */
+ g_assert (sizeof (GList) == sizeof (HandlerMatch));
+
/* setup signal key array */
g_signal_key_bsa.cmp_func = signal_key_cmp;
g_signal_key_bsa.sizeof_node = sizeof (SignalKey);
guint i;
G_LOCK (g_signal_mutex);
- for (i = 0; i < g_n_signal_nodes; i++)
+ for (i = 1; i < g_n_signal_nodes; i++)
{
SignalNode *node = g_signal_nodes[i];
{
GQuark detail = 0;
guint signal_id;
-
+
g_return_val_if_fail (detailed_signal != NULL, FALSE);
g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), FALSE);
-
+
G_LOCK (g_signal_mutex);
signal_id = signal_parse_name (detailed_signal, itype, &detail, force_detail_quark);
G_UNLOCK (g_signal_mutex);
-
+
if (signal_id)
{
if (signal_id_p)
*signal_id_p = signal_id;
if (detail_p)
*detail_p = detail;
-
+
return TRUE;
}
else
{
SignalNode *node;
gchar *name;
-
+
G_LOCK (g_signal_mutex);
node = LOOKUP_SIGNAL_NODE (signal_id);
name = node ? node->name : NULL;
GSignalQuery *query)
{
SignalNode *node;
-
+
g_return_if_fail (query != NULL);
-
+
G_LOCK (g_signal_mutex);
node = LOOKUP_SIGNAL_NODE (signal_id);
if (!node || node->destroyed)
GArray *result;
guint n_nodes;
guint i;
-
+
g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), NULL);
g_return_val_if_fail (n_ids != NULL, NULL);
-
+
G_LOCK (g_signal_mutex);
-
+
keys = g_signal_key_bsa.nodes;
n_nodes = g_signal_key_bsa.n_nodes;
result = g_array_new (FALSE, FALSE, sizeof (guint));
if (keys[i].itype == itype)
{
gchar *name = g_quark_to_string (keys[i].quark);
-
+
/* Signal names with "_" in them are aliases to the same
* name with "-" instead of "_".
*/
if (!strchr (name, '_'))
g_array_append_val (result, keys[i].signal_id);
}
-
+
*n_ids = result->len;
-
+
G_UNLOCK (g_signal_mutex);
return (guint *) g_array_free (result, FALSE);
}
void
-_g_signal_handlers_destroy (gpointer instance)
+g_signal_handlers_destroy (gpointer instance)
{
GBSearchArray *hlbsa;
/* reentrancy caution, delete instance trace first */
g_hash_table_remove (g_handler_list_bsa_ht, instance);
-
+
for (i = 0; i < hlbsa->n_nodes; i++)
{
HandlerList *hlist = g_bsearch_array_get_nth (hlbsa, i);
gpointer func,
gpointer data)
{
- Handler *handler;
guint handler_id = 0;
g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, 0);
-
+
if (mask & G_SIGNAL_MATCH_MASK)
{
+ HandlerMatch *mlist;
+
G_LOCK (g_signal_mutex);
- handler = handler_find (instance, mask, signal_id, detail, closure, func, data);
- handler_id = handler ? handler->id : 0;
+ mlist = handlers_find (instance, mask, signal_id, detail, closure, func, data, TRUE);
+ if (mlist)
+ {
+ handler_id = mlist->handler->id;
+ handler_match_free1_R (mlist, instance);
+ }
G_UNLOCK (g_signal_mutex);
}
-
+
return handler_id;
}
static guint
-signal_handlers_foreach_matched (gpointer instance,
- GSignalMatchType mask,
- guint signal_id,
- GQuark detail,
- GClosure *closure,
- gpointer func,
- gpointer data,
- void (*callback) (gpointer instance,
- guint handler_id))
+signal_handlers_foreach_matched_R (gpointer instance,
+ GSignalMatchType mask,
+ guint signal_id,
+ GQuark detail,
+ GClosure *closure,
+ gpointer func,
+ gpointer data,
+ void (*callback) (gpointer instance,
+ guint handler_id))
{
- Handler *handler;
+ HandlerMatch *mlist;
guint n_handlers = 0;
-
- handler = handler_find (instance, mask, signal_id, detail, closure, func, data);
- while (handler && handler->id)
+
+ mlist = handlers_find (instance, mask, signal_id, detail, closure, func, data, FALSE);
+ while (mlist)
{
n_handlers++;
G_UNLOCK (g_signal_mutex);
- callback (instance, handler->id);
+ callback (instance, mlist->handler->id);
G_LOCK (g_signal_mutex);
- /* need constant relookups due to callback */
- handler = handler_find (instance, mask, signal_id, detail, closure, func, data);
+ mlist = handler_match_free1_R (mlist, instance);
}
-
+
return n_handlers;
}
gpointer data)
{
guint n_handlers = 0;
-
+
g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE);
g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, FALSE);
-
+
if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA))
{
G_LOCK (g_signal_mutex);
- n_handlers = signal_handlers_foreach_matched (instance, mask, signal_id, detail,
- closure, func, data,
- g_signal_handler_block);
+ n_handlers = signal_handlers_foreach_matched_R (instance, mask, signal_id, detail,
+ closure, func, data,
+ g_signal_handler_block);
G_UNLOCK (g_signal_mutex);
}
-
+
return n_handlers;
}
if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA))
{
G_LOCK (g_signal_mutex);
- n_handlers = signal_handlers_foreach_matched (instance, mask, signal_id, detail,
- closure, func, data,
- g_signal_handler_unblock);
+ n_handlers = signal_handlers_foreach_matched_R (instance, mask, signal_id, detail,
+ closure, func, data,
+ g_signal_handler_unblock);
G_UNLOCK (g_signal_mutex);
}
-
+
return n_handlers;
}
gpointer data)
{
guint n_handlers = 0;
-
+
g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE);
g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, FALSE);
-
+
if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA))
{
G_LOCK (g_signal_mutex);
- n_handlers = signal_handlers_foreach_matched (instance, mask, signal_id, detail,
- closure, func, data,
- g_signal_handler_disconnect);
+ n_handlers = signal_handlers_foreach_matched_R (instance, mask, signal_id, detail,
+ closure, func, data,
+ g_signal_handler_disconnect);
G_UNLOCK (g_signal_mutex);
}
-
+
return n_handlers;
}
GQuark detail,
gboolean may_be_blocked)
{
- Handler *handler = NULL;
+ HandlerMatch *mlist;
+ gboolean has_pending;
g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE);
g_return_val_if_fail (signal_id > 0, FALSE);
return FALSE;
}
}
- handler = handler_find (instance,
- (G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DETAIL |
- (may_be_blocked ? 0 : G_SIGNAL_MATCH_UNBLOCKED)),
- signal_id, detail, NULL, NULL, NULL);
+ mlist = handlers_find (instance,
+ (G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DETAIL | (may_be_blocked ? 0 : G_SIGNAL_MATCH_UNBLOCKED)),
+ signal_id, detail, NULL, NULL, NULL, TRUE);
+ if (mlist)
+ {
+ has_pending = TRUE;
+ handler_match_free1_R (mlist, instance);
+ }
+ else
+ has_pending = FALSE;
G_UNLOCK (g_signal_mutex);
- return handler != NULL;
+ return has_pending;
}
void
instance = g_value_get_as_pointer (instance_and_params);
g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
g_return_if_fail (signal_id > 0);
-
+
param_values = instance_and_params + 1;
G_LOCK (g_signal_mutex);
guint *signal_id_p,
GQuark *detail_p,
gboolean force_detail_quark);
-void _g_signal_handlers_destroy (gpointer instance);
+void g_signal_handlers_destroy (gpointer instance);
void _g_signals_destroy (GType itype);
*/
#include "gtype.h"
+#include "gtypeplugin.h"
#include <string.h>
#define FIXME_DISABLE_PREALLOCATIONS
G_TYPE_FLAG_DEEP_DERIVABLE)
#define TYPE_FLAG_MASK (G_TYPE_FLAG_ABSTRACT)
-#define g_type_plugin_ref(p) ((p)->vtable->plugin_ref (p))
-#define g_type_plugin_unref(p) ((p)->vtable->plugin_unref (p))
-#define g_type_plugin_complete_type_info(p,t,i,v) ((p)->vtable->complete_type_info ((p), (t), (i), (v)))
-#define g_type_plugin_complete_interface_info(p,f,t,i) ((p)->vtable->complete_interface_info ((p), (f), (t), (i)))
/* --- typedefs --- */
type_name);
return FALSE;
}
- if (!plugin->vtable)
+ if (!G_IS_TYPE_PLUGIN (plugin))
{
- g_warning ("plugin for type `%s' has no function table",
- type_name);
- return FALSE;
- }
- if (!plugin->vtable->plugin_ref)
- {
- g_warning ("plugin for type `%s' has no plugin_ref() implementation",
- type_name);
+ g_warning ("plugin pointer (%p) for type `%s' is invalid",
+ plugin, type_name);
return FALSE;
}
- if (!plugin->vtable->plugin_unref)
- {
- g_warning ("plugin for type `%s' has no plugin_unref() implementation",
- type_name);
- return FALSE;
- }
- if (need_complete_type_info && !plugin->vtable->complete_type_info)
+ if (need_complete_type_info && !G_TYPE_PLUGIN_GET_CLASS (plugin)->complete_type_info)
{
g_warning ("plugin for type `%s' has no complete_type_info() implementation",
type_name);
return FALSE;
}
- if (need_complete_interface_info && !plugin->vtable->complete_interface_info)
+ if (need_complete_interface_info && !G_TYPE_PLUGIN_GET_CLASS (plugin)->complete_interface_info)
{
g_warning ("plugin for type `%s' has no complete_interface_info() implementation",
type_name);
memset (&tmp_info, 0, sizeof (tmp_info));
memset (&tmp_value_table, 0, sizeof (tmp_value_table));
- g_type_plugin_ref (node->plugin);
+ g_type_plugin_use (node->plugin);
g_type_plugin_complete_type_info (node->plugin, NODE_TYPE (node), &tmp_info, &tmp_value_table);
check_type_info (pnode, G_TYPE_FUNDAMENTAL (NODE_TYPE (node)), NODE_NAME (node), &tmp_info);
type_data_make (node, &tmp_info,
type_data_ref (iface);
memset (&tmp_info, 0, sizeof (tmp_info));
- g_type_plugin_ref (iholder->plugin);
+ g_type_plugin_use (iholder->plugin);
g_type_plugin_complete_interface_info (iholder->plugin, NODE_TYPE (iface), instance_type, &tmp_info);
check_interface_info (iface, instance_type, &tmp_info);
iholder->info = g_memdup (&tmp_info, sizeof (tmp_info));
{
g_free (iholder->info);
iholder->info = NULL;
- g_type_plugin_unref (iholder->plugin);
+ g_type_plugin_unuse (iholder->plugin);
type_data_unref (iface, FALSE);
}
if (ptype)
type_data_unref (LOOKUP_TYPE_NODE (ptype), FALSE);
- g_type_plugin_unref (node->plugin);
+ g_type_plugin_unuse (node->plugin);
}
}
type_data_make (node, &info, NULL); /* FIXME */
g_assert (type == G_TYPE_INTERFACE);
+ /* G_TYPE_TYPE_PLUGIN
+ */
+ g_type_plugin_get_type ();
+
/* G_TYPE_* value types
*/
g_value_types_init ();
typedef struct _GValue GValue;
typedef union _GTypeCValue GTypeCValue;
typedef struct _GTypePlugin GTypePlugin;
-typedef struct _GTypePluginVTable GTypePluginVTable;
typedef struct _GTypeClass GTypeClass;
typedef struct _GTypeInterface GTypeInterface;
typedef struct _GTypeInstance GTypeInstance;
#define G_TYPE_CHECK_INSTANCE(instance) (_G_TYPE_CHI ((GTypeInstance*) (instance)))
#define G_TYPE_CHECK_INSTANCE_CAST(instance, g_type, c_type) (_G_TYPE_CIC ((instance), (g_type), c_type))
#define G_TYPE_CHECK_INSTANCE_TYPE(instance, g_type) (_G_TYPE_CIT ((instance), (g_type)))
-#define G_TYPE_INSTANCE_GET_CLASS(instance, g_type, c_type) (_G_TYPE_IGC ((instance), c_type))
+#define G_TYPE_INSTANCE_GET_CLASS(instance, g_type, c_type) (_G_TYPE_IGC ((instance), (g_type), c_type))
#define G_TYPE_INSTANCE_GET_INTERFACE(instance, g_type, c_type) (_G_TYPE_IGI ((instance), (g_type), c_type))
#define G_TYPE_CHECK_CLASS_CAST(g_class, g_type, c_type) (_G_TYPE_CCC ((g_class), (g_type), c_type))
#define G_TYPE_CHECK_CLASS_TYPE(g_class, g_type) (_G_TYPE_CCT ((g_class), (g_type)))
gpointer iface_data);
typedef void (*GInterfaceFinalizeFunc) (gpointer g_iface,
gpointer iface_data);
-typedef void (*GTypePluginRef) (GTypePlugin *plugin);
-typedef void (*GTypePluginUnRef) (GTypePlugin *plugin);
-typedef void (*GTypePluginFillTypeInfo) (GTypePlugin *plugin,
- GType g_type,
- GTypeInfo *info,
- GTypeValueTable *value_table);
-typedef void (*GTypePluginFillInterfaceInfo) (GTypePlugin *plugin,
- GType interface_type,
- GType instance_type,
- GInterfaceInfo *info);
typedef gboolean (*GTypeClassCacheFunc) (gpointer cache_data,
GTypeClass *g_class);
-struct _GTypePlugin
-{
- GTypePluginVTable *vtable;
-};
-struct _GTypePluginVTable
-{
- GTypePluginRef plugin_ref;
- GTypePluginUnRef plugin_unref;
- GTypePluginFillTypeInfo complete_type_info;
- GTypePluginFillInterfaceInfo complete_interface_info;
-};
typedef enum /*< skip >*/
{
G_TYPE_FLAG_CLASSED = (1 << 0),
#define _G_TYPE_CCT(cp, gt) (g_type_class_is_a ((GTypeClass*) cp, gt))
#define _G_TYPE_CVT(vl, gt) (g_type_value_conforms_to ((GValue*) vl, gt))
#define _G_TYPE_CHV(vl) (g_type_check_value ((GValue*) vl))
-#define _G_TYPE_IGC(ip, ct) ((ct*) (((GTypeInstance*) ip)->g_class))
+#define _G_TYPE_IGC(ip, gt, ct) ((ct*) (((GTypeInstance*) ip)->g_class))
#define _G_TYPE_IGI(ip, gt, ct) ((ct*) g_type_interface_peek (((GTypeInstance*) ip)->g_class, gt))
--- /dev/null
+/* GObject - GLib Type, Object, Parameter and Signal Library
+ * Copyright (C) 2000 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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.
+ */
+#include "gtypeplugin.h"
+
+
+
+/* --- functions --- */
+GType
+g_type_plugin_get_type (void)
+{
+ static GType type_plugin_type = 0;
+
+ if (!type_plugin_type)
+ {
+ static const GTypeInfo type_plugin_info = {
+ sizeof (GTypePluginClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ };
+
+ type_plugin_type = g_type_register_static (G_TYPE_INTERFACE, "GTypePlugin", &type_plugin_info, 0);
+ }
+
+ return type_plugin_type;
+}
+
+void
+g_type_plugin_use (GTypePlugin *plugin)
+{
+ GTypePluginClass *iface;
+
+ g_return_if_fail (G_IS_TYPE_PLUGIN (plugin));
+
+ iface = G_TYPE_PLUGIN_GET_CLASS (plugin);
+ iface->use_plugin (plugin);
+}
+
+void
+g_type_plugin_unuse (GTypePlugin *plugin)
+{
+ GTypePluginClass *iface;
+
+ g_return_if_fail (G_IS_TYPE_PLUGIN (plugin));
+
+ iface = G_TYPE_PLUGIN_GET_CLASS (plugin);
+ iface->unuse_plugin (plugin);
+}
+
+void
+g_type_plugin_complete_type_info (GTypePlugin *plugin,
+ GType g_type,
+ GTypeInfo *info,
+ GTypeValueTable *value_table)
+{
+ GTypePluginClass *iface;
+
+ g_return_if_fail (G_IS_TYPE_PLUGIN (plugin));
+ g_return_if_fail (info != NULL);
+ g_return_if_fail (value_table != NULL);
+
+ iface = G_TYPE_PLUGIN_GET_CLASS (plugin);
+ iface->complete_type_info (plugin,
+ g_type,
+ info,
+ value_table);
+}
+
+void
+g_type_plugin_complete_interface_info (GTypePlugin *plugin,
+ GType interface_type,
+ GType instance_type,
+ GInterfaceInfo *info)
+{
+ GTypePluginClass *iface;
+
+ g_return_if_fail (G_IS_TYPE_PLUGIN (plugin));
+ g_return_if_fail (info != NULL);
+
+ iface = G_TYPE_PLUGIN_GET_CLASS (plugin);
+ iface->complete_interface_info (plugin,
+ interface_type,
+ instance_type,
+ info);
+}
--- /dev/null
+/* GObject - GLib Type, Object, Parameter and Signal Library
+ * Copyright (C) 2000 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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.
+ */
+#ifndef __G_TYPE_PLUGIN_H__
+#define __G_TYPE_PLUGIN_H__
+
+
+#include <gobject/gtype.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+
+/* --- type macros --- */
+#define G_TYPE_TYPE_PLUGIN (g_type_plugin_get_type ())
+#define G_TYPE_PLUGIN(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), G_TYPE_TYPE_PLUGIN, GTypePlugin))
+#define G_TYPE_PLUGIN_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), G_TYPE_TYPE_PLUGIN, GTypePluginClass))
+#define G_IS_TYPE_PLUGIN(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), G_TYPE_TYPE_PLUGIN))
+#define G_IS_TYPE_PLUGIN_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), G_TYPE_TYPE_PLUGIN))
+#define G_TYPE_PLUGIN_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), G_TYPE_TYPE_PLUGIN, GTypePluginClass))
+
+
+/* --- typedefs & structures --- */
+typedef struct _GTypePluginClass GTypePluginClass;
+typedef void (*GTypePluginUse) (GTypePlugin *plugin);
+typedef void (*GTypePluginUnuse) (GTypePlugin *plugin);
+typedef void (*GTypePluginCompleteTypeInfo) (GTypePlugin *plugin,
+ GType g_type,
+ GTypeInfo *info,
+ GTypeValueTable *value_table);
+typedef void (*GTypePluginCompleteInterfaceInfo) (GTypePlugin *plugin,
+ GType interface_type,
+ GType instance_type,
+ GInterfaceInfo *info);
+struct _GTypePluginClass
+{
+ GTypeInterface base_iface;
+
+ GTypePluginUse use_plugin;
+ GTypePluginUnuse unuse_plugin;
+ GTypePluginCompleteTypeInfo complete_type_info;
+ GTypePluginCompleteInterfaceInfo complete_interface_info;
+};
+
+
+/* --- prototypes --- */
+GType g_type_plugin_get_type (void) G_GNUC_CONST;
+void g_type_plugin_use (GTypePlugin *plugin);
+void g_type_plugin_unuse (GTypePlugin *plugin);
+void g_type_plugin_complete_type_info (GTypePlugin *plugin,
+ GType g_type,
+ GTypeInfo *info,
+ GTypeValueTable *value_table);
+void g_type_plugin_complete_interface_info (GTypePlugin *plugin,
+ GType interface_type,
+ GType instance_type,
+ GInterfaceInfo *info);
+
+
+
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __G_TYPE_PLUGIN_H__ */