mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-25 15:06:14 +01:00
fixed a bag full of subtle bugs of immensive screw-up potential in
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.
This commit is contained in:
parent
3cc60a9ab1
commit
83c45024e3
@ -28,6 +28,7 @@
|
|||||||
#include <gobject/gparamspecs.h>
|
#include <gobject/gparamspecs.h>
|
||||||
#include <gobject/gsignal.h>
|
#include <gobject/gsignal.h>
|
||||||
#include <gobject/gtype.h>
|
#include <gobject/gtype.h>
|
||||||
|
#include <gobject/gtypeplugin.h>
|
||||||
#include <gobject/gvalue.h>
|
#include <gobject/gvalue.h>
|
||||||
#include <gobject/gvaluetypes.h>
|
#include <gobject/gvaluetypes.h>
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include <gobject/gparamspecs.h>
|
#include <gobject/gparamspecs.h>
|
||||||
#include <gobject/gsignal.h>
|
#include <gobject/gsignal.h>
|
||||||
#include <gobject/gtype.h>
|
#include <gobject/gtype.h>
|
||||||
|
#include <gobject/gtypeplugin.h>
|
||||||
#include <gobject/gvalue.h>
|
#include <gobject/gvalue.h>
|
||||||
#include <gobject/gvaluetypes.h>
|
#include <gobject/gvaluetypes.h>
|
||||||
|
|
||||||
|
@ -1,3 +1,25 @@
|
|||||||
|
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>
|
Fri Nov 3 07:35:00 2000 Tim Janik <timj@gtk.org>
|
||||||
|
|
||||||
* gsignal.[hc]: prefix internal functions with '_'. renamed
|
* gsignal.[hc]: prefix internal functions with '_'. renamed
|
||||||
|
@ -32,6 +32,7 @@ gobject_public_h_sources = @STRIP_BEGIN@ \
|
|||||||
gparamspecs.h \
|
gparamspecs.h \
|
||||||
gsignal.h \
|
gsignal.h \
|
||||||
gtype.h \
|
gtype.h \
|
||||||
|
gtypeplugin.h \
|
||||||
gvalue.h \
|
gvalue.h \
|
||||||
gvaluecollector.h \
|
gvaluecollector.h \
|
||||||
gvaluetypes.h \
|
gvaluetypes.h \
|
||||||
@ -51,6 +52,7 @@ gobject_c_sources = @STRIP_BEGIN@ \
|
|||||||
gparamspecs.c \
|
gparamspecs.c \
|
||||||
gsignal.c \
|
gsignal.c \
|
||||||
gtype.c \
|
gtype.c \
|
||||||
|
gtypeplugin.c \
|
||||||
gvalue.c \
|
gvalue.c \
|
||||||
gvaluetypes.c \
|
gvaluetypes.c \
|
||||||
@STRIP_END@
|
@STRIP_END@
|
||||||
|
@ -295,7 +295,7 @@ g_object_do_shutdown (GObject *object)
|
|||||||
static void
|
static void
|
||||||
g_object_do_finalize (GObject *object)
|
g_object_do_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
_g_signal_handlers_destroy (object);
|
g_signal_handlers_destroy (object);
|
||||||
g_datalist_clear (&object->qdata);
|
g_datalist_clear (&object->qdata);
|
||||||
|
|
||||||
#ifdef DEBUG_OBJECTS
|
#ifdef DEBUG_OBJECTS
|
||||||
|
@ -78,6 +78,7 @@ typedef struct _SignalKey SignalKey;
|
|||||||
typedef struct _Emission Emission;
|
typedef struct _Emission Emission;
|
||||||
typedef struct _Handler Handler;
|
typedef struct _Handler Handler;
|
||||||
typedef struct _HandlerList HandlerList;
|
typedef struct _HandlerList HandlerList;
|
||||||
|
typedef struct _HandlerMatch HandlerMatch;
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
EMISSION_STOP,
|
EMISSION_STOP,
|
||||||
@ -102,13 +103,19 @@ static void handler_insert (guint signal_i
|
|||||||
static Handler* handler_lookup (gpointer instance,
|
static Handler* handler_lookup (gpointer instance,
|
||||||
guint handler_id,
|
guint handler_id,
|
||||||
guint *signal_id_p);
|
guint *signal_id_p);
|
||||||
static Handler* handler_find (gpointer instance,
|
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,
|
GSignalMatchType mask,
|
||||||
guint signal_id,
|
guint signal_id,
|
||||||
GQuark detail,
|
GQuark detail,
|
||||||
GClosure *closure,
|
GClosure *closure,
|
||||||
gpointer func,
|
gpointer func,
|
||||||
gpointer data);
|
gpointer data,
|
||||||
|
gboolean one_and_only);
|
||||||
static inline void handler_ref (Handler *handler);
|
static inline void handler_ref (Handler *handler);
|
||||||
static inline void handler_unref_R (guint signal_id,
|
static inline void handler_unref_R (guint signal_id,
|
||||||
gpointer instance,
|
gpointer instance,
|
||||||
@ -172,7 +179,6 @@ struct _HandlerList
|
|||||||
guint signal_id;
|
guint signal_id;
|
||||||
Handler *handlers;
|
Handler *handlers;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _Handler
|
struct _Handler
|
||||||
{
|
{
|
||||||
guint id;
|
guint id;
|
||||||
@ -186,6 +192,15 @@ struct _Handler
|
|||||||
guint after : 1;
|
guint after : 1;
|
||||||
GClosure *closure;
|
GClosure *closure;
|
||||||
};
|
};
|
||||||
|
struct _HandlerMatch
|
||||||
|
{
|
||||||
|
Handler *handler;
|
||||||
|
HandlerMatch *next;
|
||||||
|
union {
|
||||||
|
guint signal_id;
|
||||||
|
gpointer dummy;
|
||||||
|
} d;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* --- variables --- */
|
/* --- variables --- */
|
||||||
@ -313,15 +328,50 @@ handler_lookup (gpointer instance,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Handler*
|
static inline HandlerMatch*
|
||||||
handler_find (gpointer instance,
|
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,
|
GSignalMatchType mask,
|
||||||
guint signal_id,
|
guint signal_id,
|
||||||
GQuark detail,
|
GQuark detail,
|
||||||
GClosure *closure,
|
GClosure *closure,
|
||||||
gpointer func,
|
gpointer func,
|
||||||
gpointer data)
|
gpointer data,
|
||||||
|
gboolean one_and_only)
|
||||||
{
|
{
|
||||||
|
HandlerMatch *mlist = NULL;
|
||||||
|
|
||||||
if (mask & G_SIGNAL_MATCH_ID)
|
if (mask & G_SIGNAL_MATCH_ID)
|
||||||
{
|
{
|
||||||
HandlerList *hlist = handler_list_lookup (signal_id, instance);
|
HandlerList *hlist = handler_list_lookup (signal_id, instance);
|
||||||
@ -337,14 +387,19 @@ handler_find (gpointer instance,
|
|||||||
|
|
||||||
mask = ~mask;
|
mask = ~mask;
|
||||||
for (handler = hlist ? hlist->handlers : NULL; handler; handler = handler->next)
|
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_CLOSURE) || handler->closure == closure) &&
|
||||||
((mask & G_SIGNAL_MATCH_DATA) || handler->closure->data == data) &&
|
((mask & G_SIGNAL_MATCH_DATA) || handler->closure->data == data) &&
|
||||||
((mask & G_SIGNAL_MATCH_UNBLOCKED) || handler->block_count == 0) &&
|
((mask & G_SIGNAL_MATCH_UNBLOCKED) || handler->block_count == 0) &&
|
||||||
((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller &&
|
((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller &&
|
||||||
handler->closure->meta_marshal == 0 &&
|
handler->closure->meta_marshal == 0 &&
|
||||||
((GCClosure*) handler->closure)->callback == func)))
|
((GCClosure*) handler->closure)->callback == func)))
|
||||||
return handler;
|
{
|
||||||
|
mlist = handler_match_prepend (mlist, handler, signal_id);
|
||||||
|
if (one_and_only)
|
||||||
|
return mlist;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -369,19 +424,24 @@ handler_find (gpointer instance,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (handler = hlist->handlers; handler; handler = handler->next)
|
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_CLOSURE) || handler->closure == closure) &&
|
||||||
((mask & G_SIGNAL_MATCH_DATA) || handler->closure->data == data) &&
|
((mask & G_SIGNAL_MATCH_DATA) || handler->closure->data == data) &&
|
||||||
((mask & G_SIGNAL_MATCH_UNBLOCKED) || handler->block_count == 0) &&
|
((mask & G_SIGNAL_MATCH_UNBLOCKED) || handler->block_count == 0) &&
|
||||||
((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller &&
|
((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller &&
|
||||||
handler->closure->meta_marshal == 0 &&
|
handler->closure->meta_marshal == 0 &&
|
||||||
((GCClosure*) handler->closure)->callback == func)))
|
((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*
|
static inline Handler*
|
||||||
@ -433,7 +493,7 @@ handler_unref_R (guint signal_id,
|
|||||||
{
|
{
|
||||||
if (handler->next)
|
if (handler->next)
|
||||||
handler->next->prev = handler->prev;
|
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;
|
handler->prev->next = handler->next;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -551,6 +611,9 @@ g_signal_init (void) /* sync with gtype.c */
|
|||||||
G_LOCK (g_signal_mutex);
|
G_LOCK (g_signal_mutex);
|
||||||
if (!g_n_signal_nodes)
|
if (!g_n_signal_nodes)
|
||||||
{
|
{
|
||||||
|
/* handler_id_node_prepend() requires this */
|
||||||
|
g_assert (sizeof (GList) == sizeof (HandlerMatch));
|
||||||
|
|
||||||
/* setup signal key array */
|
/* setup signal key array */
|
||||||
g_signal_key_bsa.cmp_func = signal_key_cmp;
|
g_signal_key_bsa.cmp_func = signal_key_cmp;
|
||||||
g_signal_key_bsa.sizeof_node = sizeof (SignalKey);
|
g_signal_key_bsa.sizeof_node = sizeof (SignalKey);
|
||||||
@ -573,7 +636,7 @@ _g_signals_destroy (GType itype)
|
|||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
G_LOCK (g_signal_mutex);
|
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];
|
SignalNode *node = g_signal_nodes[i];
|
||||||
|
|
||||||
@ -1056,7 +1119,7 @@ g_signal_handler_disconnect (gpointer instance,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_g_signal_handlers_destroy (gpointer instance)
|
g_signal_handlers_destroy (gpointer instance)
|
||||||
{
|
{
|
||||||
GBSearchArray *hlbsa;
|
GBSearchArray *hlbsa;
|
||||||
|
|
||||||
@ -1107,7 +1170,6 @@ g_signal_handler_find (gpointer instance,
|
|||||||
gpointer func,
|
gpointer func,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
Handler *handler;
|
|
||||||
guint handler_id = 0;
|
guint handler_id = 0;
|
||||||
|
|
||||||
g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
|
g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
|
||||||
@ -1115,9 +1177,15 @@ g_signal_handler_find (gpointer instance,
|
|||||||
|
|
||||||
if (mask & G_SIGNAL_MATCH_MASK)
|
if (mask & G_SIGNAL_MATCH_MASK)
|
||||||
{
|
{
|
||||||
|
HandlerMatch *mlist;
|
||||||
|
|
||||||
G_LOCK (g_signal_mutex);
|
G_LOCK (g_signal_mutex);
|
||||||
handler = handler_find (instance, mask, signal_id, detail, closure, func, data);
|
mlist = handlers_find (instance, mask, signal_id, detail, closure, func, data, TRUE);
|
||||||
handler_id = handler ? handler->id : 0;
|
if (mlist)
|
||||||
|
{
|
||||||
|
handler_id = mlist->handler->id;
|
||||||
|
handler_match_free1_R (mlist, instance);
|
||||||
|
}
|
||||||
G_UNLOCK (g_signal_mutex);
|
G_UNLOCK (g_signal_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1125,7 +1193,7 @@ g_signal_handler_find (gpointer instance,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static guint
|
static guint
|
||||||
signal_handlers_foreach_matched (gpointer instance,
|
signal_handlers_foreach_matched_R (gpointer instance,
|
||||||
GSignalMatchType mask,
|
GSignalMatchType mask,
|
||||||
guint signal_id,
|
guint signal_id,
|
||||||
GQuark detail,
|
GQuark detail,
|
||||||
@ -1135,18 +1203,17 @@ signal_handlers_foreach_matched (gpointer instance,
|
|||||||
void (*callback) (gpointer instance,
|
void (*callback) (gpointer instance,
|
||||||
guint handler_id))
|
guint handler_id))
|
||||||
{
|
{
|
||||||
Handler *handler;
|
HandlerMatch *mlist;
|
||||||
guint n_handlers = 0;
|
guint n_handlers = 0;
|
||||||
|
|
||||||
handler = handler_find (instance, mask, signal_id, detail, closure, func, data);
|
mlist = handlers_find (instance, mask, signal_id, detail, closure, func, data, FALSE);
|
||||||
while (handler && handler->id)
|
while (mlist)
|
||||||
{
|
{
|
||||||
n_handlers++;
|
n_handlers++;
|
||||||
G_UNLOCK (g_signal_mutex);
|
G_UNLOCK (g_signal_mutex);
|
||||||
callback (instance, handler->id);
|
callback (instance, mlist->handler->id);
|
||||||
G_LOCK (g_signal_mutex);
|
G_LOCK (g_signal_mutex);
|
||||||
/* need constant relookups due to callback */
|
mlist = handler_match_free1_R (mlist, instance);
|
||||||
handler = handler_find (instance, mask, signal_id, detail, closure, func, data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return n_handlers;
|
return n_handlers;
|
||||||
@ -1169,7 +1236,7 @@ g_signal_handlers_block_matched (gpointer instance,
|
|||||||
if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA))
|
if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA))
|
||||||
{
|
{
|
||||||
G_LOCK (g_signal_mutex);
|
G_LOCK (g_signal_mutex);
|
||||||
n_handlers = signal_handlers_foreach_matched (instance, mask, signal_id, detail,
|
n_handlers = signal_handlers_foreach_matched_R (instance, mask, signal_id, detail,
|
||||||
closure, func, data,
|
closure, func, data,
|
||||||
g_signal_handler_block);
|
g_signal_handler_block);
|
||||||
G_UNLOCK (g_signal_mutex);
|
G_UNLOCK (g_signal_mutex);
|
||||||
@ -1195,7 +1262,7 @@ g_signal_handlers_unblock_matched (gpointer instance,
|
|||||||
if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA))
|
if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA))
|
||||||
{
|
{
|
||||||
G_LOCK (g_signal_mutex);
|
G_LOCK (g_signal_mutex);
|
||||||
n_handlers = signal_handlers_foreach_matched (instance, mask, signal_id, detail,
|
n_handlers = signal_handlers_foreach_matched_R (instance, mask, signal_id, detail,
|
||||||
closure, func, data,
|
closure, func, data,
|
||||||
g_signal_handler_unblock);
|
g_signal_handler_unblock);
|
||||||
G_UNLOCK (g_signal_mutex);
|
G_UNLOCK (g_signal_mutex);
|
||||||
@ -1221,7 +1288,7 @@ g_signal_handlers_disconnect_matched (gpointer instance,
|
|||||||
if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA))
|
if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA))
|
||||||
{
|
{
|
||||||
G_LOCK (g_signal_mutex);
|
G_LOCK (g_signal_mutex);
|
||||||
n_handlers = signal_handlers_foreach_matched (instance, mask, signal_id, detail,
|
n_handlers = signal_handlers_foreach_matched_R (instance, mask, signal_id, detail,
|
||||||
closure, func, data,
|
closure, func, data,
|
||||||
g_signal_handler_disconnect);
|
g_signal_handler_disconnect);
|
||||||
G_UNLOCK (g_signal_mutex);
|
G_UNLOCK (g_signal_mutex);
|
||||||
@ -1236,7 +1303,8 @@ g_signal_has_handler_pending (gpointer instance,
|
|||||||
GQuark detail,
|
GQuark detail,
|
||||||
gboolean may_be_blocked)
|
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 (G_TYPE_CHECK_INSTANCE (instance), FALSE);
|
||||||
g_return_val_if_fail (signal_id > 0, FALSE);
|
g_return_val_if_fail (signal_id > 0, FALSE);
|
||||||
@ -1253,13 +1321,19 @@ g_signal_has_handler_pending (gpointer instance,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
handler = handler_find (instance,
|
mlist = handlers_find (instance,
|
||||||
(G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DETAIL |
|
(G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DETAIL | (may_be_blocked ? 0 : G_SIGNAL_MATCH_UNBLOCKED)),
|
||||||
(may_be_blocked ? 0 : G_SIGNAL_MATCH_UNBLOCKED)),
|
signal_id, detail, NULL, NULL, NULL, TRUE);
|
||||||
signal_id, detail, NULL, NULL, NULL);
|
if (mlist)
|
||||||
|
{
|
||||||
|
has_pending = TRUE;
|
||||||
|
handler_match_free1_R (mlist, instance);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
has_pending = FALSE;
|
||||||
G_UNLOCK (g_signal_mutex);
|
G_UNLOCK (g_signal_mutex);
|
||||||
|
|
||||||
return handler != NULL;
|
return has_pending;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -169,7 +169,7 @@ gboolean g_signal_parse_name (const gchar *detailed_signal,
|
|||||||
guint *signal_id_p,
|
guint *signal_id_p,
|
||||||
GQuark *detail_p,
|
GQuark *detail_p,
|
||||||
gboolean force_detail_quark);
|
gboolean force_detail_quark);
|
||||||
void _g_signal_handlers_destroy (gpointer instance);
|
void g_signal_handlers_destroy (gpointer instance);
|
||||||
void _g_signals_destroy (GType itype);
|
void _g_signals_destroy (GType itype);
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
#include "gtype.h"
|
#include "gtype.h"
|
||||||
|
|
||||||
|
#include "gtypeplugin.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#define FIXME_DISABLE_PREALLOCATIONS
|
#define FIXME_DISABLE_PREALLOCATIONS
|
||||||
@ -45,10 +46,6 @@
|
|||||||
G_TYPE_FLAG_DEEP_DERIVABLE)
|
G_TYPE_FLAG_DEEP_DERIVABLE)
|
||||||
#define TYPE_FLAG_MASK (G_TYPE_FLAG_ABSTRACT)
|
#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 --- */
|
/* --- typedefs --- */
|
||||||
@ -398,31 +395,19 @@ check_plugin (GTypePlugin *plugin,
|
|||||||
type_name);
|
type_name);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (!plugin->vtable)
|
if (!G_IS_TYPE_PLUGIN (plugin))
|
||||||
{
|
{
|
||||||
g_warning ("plugin for type `%s' has no function table",
|
g_warning ("plugin pointer (%p) for type `%s' is invalid",
|
||||||
type_name);
|
plugin, type_name);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (!plugin->vtable->plugin_ref)
|
if (need_complete_type_info && !G_TYPE_PLUGIN_GET_CLASS (plugin)->complete_type_info)
|
||||||
{
|
|
||||||
g_warning ("plugin for type `%s' has no plugin_ref() implementation",
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
g_warning ("plugin for type `%s' has no complete_type_info() implementation",
|
g_warning ("plugin for type `%s' has no complete_type_info() implementation",
|
||||||
type_name);
|
type_name);
|
||||||
return FALSE;
|
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",
|
g_warning ("plugin for type `%s' has no complete_interface_info() implementation",
|
||||||
type_name);
|
type_name);
|
||||||
@ -830,7 +815,7 @@ type_data_ref (TypeNode *node)
|
|||||||
|
|
||||||
memset (&tmp_info, 0, sizeof (tmp_info));
|
memset (&tmp_info, 0, sizeof (tmp_info));
|
||||||
memset (&tmp_value_table, 0, sizeof (tmp_value_table));
|
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);
|
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);
|
check_type_info (pnode, G_TYPE_FUNDAMENTAL (NODE_TYPE (node)), NODE_NAME (node), &tmp_info);
|
||||||
type_data_make (node, &tmp_info,
|
type_data_make (node, &tmp_info,
|
||||||
@ -930,7 +915,7 @@ type_iface_retrive_holder_info (TypeNode *iface,
|
|||||||
type_data_ref (iface);
|
type_data_ref (iface);
|
||||||
|
|
||||||
memset (&tmp_info, 0, sizeof (tmp_info));
|
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);
|
g_type_plugin_complete_interface_info (iholder->plugin, NODE_TYPE (iface), instance_type, &tmp_info);
|
||||||
check_interface_info (iface, instance_type, &tmp_info);
|
check_interface_info (iface, instance_type, &tmp_info);
|
||||||
iholder->info = g_memdup (&tmp_info, sizeof (tmp_info));
|
iholder->info = g_memdup (&tmp_info, sizeof (tmp_info));
|
||||||
@ -954,7 +939,7 @@ type_iface_blow_holder_info (TypeNode *iface,
|
|||||||
{
|
{
|
||||||
g_free (iholder->info);
|
g_free (iholder->info);
|
||||||
iholder->info = NULL;
|
iholder->info = NULL;
|
||||||
g_type_plugin_unref (iholder->plugin);
|
g_type_plugin_unuse (iholder->plugin);
|
||||||
|
|
||||||
type_data_unref (iface, FALSE);
|
type_data_unref (iface, FALSE);
|
||||||
}
|
}
|
||||||
@ -1279,7 +1264,7 @@ type_data_last_unref (GType type,
|
|||||||
|
|
||||||
if (ptype)
|
if (ptype)
|
||||||
type_data_unref (LOOKUP_TYPE_NODE (ptype), FALSE);
|
type_data_unref (LOOKUP_TYPE_NODE (ptype), FALSE);
|
||||||
g_type_plugin_unref (node->plugin);
|
g_type_plugin_unuse (node->plugin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2117,6 +2102,10 @@ g_type_init (void)
|
|||||||
type_data_make (node, &info, NULL); /* FIXME */
|
type_data_make (node, &info, NULL); /* FIXME */
|
||||||
g_assert (type == G_TYPE_INTERFACE);
|
g_assert (type == G_TYPE_INTERFACE);
|
||||||
|
|
||||||
|
/* G_TYPE_TYPE_PLUGIN
|
||||||
|
*/
|
||||||
|
g_type_plugin_get_type ();
|
||||||
|
|
||||||
/* G_TYPE_* value types
|
/* G_TYPE_* value types
|
||||||
*/
|
*/
|
||||||
g_value_types_init ();
|
g_value_types_init ();
|
||||||
|
@ -116,7 +116,6 @@ typedef guint32 GType;
|
|||||||
typedef struct _GValue GValue;
|
typedef struct _GValue GValue;
|
||||||
typedef union _GTypeCValue GTypeCValue;
|
typedef union _GTypeCValue GTypeCValue;
|
||||||
typedef struct _GTypePlugin GTypePlugin;
|
typedef struct _GTypePlugin GTypePlugin;
|
||||||
typedef struct _GTypePluginVTable GTypePluginVTable;
|
|
||||||
typedef struct _GTypeClass GTypeClass;
|
typedef struct _GTypeClass GTypeClass;
|
||||||
typedef struct _GTypeInterface GTypeInterface;
|
typedef struct _GTypeInterface GTypeInterface;
|
||||||
typedef struct _GTypeInstance GTypeInstance;
|
typedef struct _GTypeInstance GTypeInstance;
|
||||||
@ -154,7 +153,7 @@ struct _GTypeInterface
|
|||||||
#define G_TYPE_CHECK_INSTANCE(instance) (_G_TYPE_CHI ((GTypeInstance*) (instance)))
|
#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_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_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_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_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)))
|
#define G_TYPE_CHECK_CLASS_TYPE(g_class, g_type) (_G_TYPE_CCT ((g_class), (g_type)))
|
||||||
@ -210,29 +209,8 @@ typedef void (*GInterfaceInitFunc) (gpointer g_iface,
|
|||||||
gpointer iface_data);
|
gpointer iface_data);
|
||||||
typedef void (*GInterfaceFinalizeFunc) (gpointer g_iface,
|
typedef void (*GInterfaceFinalizeFunc) (gpointer g_iface,
|
||||||
gpointer iface_data);
|
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,
|
typedef gboolean (*GTypeClassCacheFunc) (gpointer cache_data,
|
||||||
GTypeClass *g_class);
|
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 >*/
|
typedef enum /*< skip >*/
|
||||||
{
|
{
|
||||||
G_TYPE_FLAG_CLASSED = (1 << 0),
|
G_TYPE_FLAG_CLASSED = (1 << 0),
|
||||||
@ -359,7 +337,7 @@ GTypeValueTable* g_type_value_table_peek (GType type);
|
|||||||
#define _G_TYPE_CCT(cp, gt) (g_type_class_is_a ((GTypeClass*) cp, gt))
|
#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_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_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))
|
#define _G_TYPE_IGI(ip, gt, ct) ((ct*) g_type_interface_peek (((GTypeInstance*) ip)->g_class, gt))
|
||||||
|
|
||||||
|
|
||||||
|
100
gobject/gtypeplugin.c
Normal file
100
gobject/gtypeplugin.c
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
/* 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);
|
||||||
|
}
|
85
gobject/gtypeplugin.h
Normal file
85
gobject/gtypeplugin.h
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/* 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__ */
|
Loading…
Reference in New Issue
Block a user