# HG changeset patch # User Christian Hammond # Date 1061455112 0 # Node ID ed796f7562379d8228ece20b4e6ce744dd6a3615 # Parent d01ba50e3f3ea1879deae985d6aebe858d2979d5 [gaim-migrate @ 7071] Added the C framework for perl signal handlers. Untested, not implemented in perl, and may crash. Should be fun! committer: Tailor Script diff -r d01ba50e3f3e -r ed796f756237 plugins/perl/perl-handlers.c --- a/plugins/perl/perl-handlers.c Thu Aug 21 07:37:47 2003 +0000 +++ b/plugins/perl/perl-handlers.c Thu Aug 21 08:38:32 2003 +0000 @@ -2,8 +2,10 @@ #include "perl-handlers.h" #include "debug.h" +#include "signals.h" static GList *timeout_handlers = NULL; +static GList *signal_handlers = NULL; extern PerlInterpreter *my_perl; @@ -16,10 +18,19 @@ g_free(handler); } +static void +destroy_signal_handler(GaimPerlSignalHandler *handler) +{ + signal_handlers = g_list_remove(signal_handlers, handler); + + g_free(handler->signal); + g_free(handler->func); + g_free(handler); +} + static int perl_timeout_cb(gpointer data) { - void *atmp[2] = { NULL, NULL }; GaimPerlTimeoutHandler *handler = (GaimPerlTimeoutHandler *)data; dSP; @@ -31,8 +42,6 @@ call_pv(handler->name, G_EVAL | G_SCALAR); SPAGAIN; - atmp[0] = handler->args; - PUTBACK; FREETMPS; LEAVE; @@ -42,6 +51,61 @@ return 0; } +static void * +perl_signal_cb(va_list args, void *data) +{ + GaimPerlSignalHandler *handler = (GaimPerlSignalHandler *)data; + void *arg; + void *ret_val = NULL; + int count; + + dSP; + ENTER; + SAVETMPS; + PUSHMARK(sp); + + while ((arg = va_arg(args, void *)) != NULL) + XPUSHs((SV *)arg); + + XPUSHs((SV *)handler->data); + + PUTBACK; + count = call_pv(handler->func, G_EVAL | G_SCALAR); + SPAGAIN; + + if (count > 1) + ret_val = POPp; + + PUTBACK; + FREETMPS; + LEAVE; + + return ret_val; +} + +static GaimPerlSignalHandler * +find_signal_handler(GaimPlugin *plugin, void *instance, + const char *signal, const char *func) +{ + GaimPerlSignalHandler *handler; + GList *l; + + for (l = signal_handlers; l != NULL; l = l->next) + { + handler = (GaimPerlSignalHandler *)l->data; + + if (handler->plugin == plugin && + handler->instance == instance && + !strcmp(handler->signal, signal) && + !strcmp(handler->func, func)) + { + return handler; + } + } + + return NULL; +} + void gaim_perl_timeout_add(GaimPlugin *plugin, int seconds, const char *func, void *args) @@ -50,8 +114,7 @@ if (plugin == NULL) { - gaim_debug(GAIM_DEBUG_ERROR, "perl", - "Invalid handle in adding perl timeout handler.\n"); + croak("Invalid handle in adding perl timeout handler.\n"); return; } @@ -85,7 +148,68 @@ void gaim_perl_timeout_clear(void) { - while (timeout_handlers) + while (timeout_handlers != NULL) destroy_timeout_handler(timeout_handlers->data); } +void +gaim_perl_signal_connect(GaimPlugin *plugin, void *instance, + const char *signal, const char *func, void *data) +{ + GaimPerlSignalHandler *handler; + + handler = g_new0(GaimPerlSignalHandler, 1); + handler->plugin = plugin; + handler->instance = instance; + handler->signal = g_strdup(signal); + handler->func = g_strdup(func); + handler->data = data; + + signal_handlers = g_list_append(signal_handlers, handler); + + gaim_signal_connect(instance, signal, + plugin, GAIM_CALLBACK(perl_signal_cb), handler); +} + +void +gaim_perl_signal_disconnect(GaimPlugin *plugin, void *instance, + const char *signal, const char *func) +{ + GaimPerlSignalHandler *handler; + + handler = find_signal_handler(plugin, instance, signal, func); + + if (handler == NULL) + { + croak("Invalid signal handler information in " + "disconnecting a perl signal handler.\n"); + return; + } + + destroy_signal_handler(handler); +} + +void +gaim_perl_signal_clear_for_plugin(GaimPlugin *plugin) +{ + GaimPerlSignalHandler *handler; + GList *l, *l_next; + + for (l = signal_handlers; l != NULL; l = l_next) + { + l_next = l->next; + + handler = (GaimPerlSignalHandler *)l->data; + + if (handler->plugin == plugin) + destroy_signal_handler(handler); + } +} + +void +gaim_perl_signal_clear(void) +{ + while (signal_handlers != NULL) + destroy_signal_handler(signal_handlers->data); +} + diff -r d01ba50e3f3e -r ed796f756237 plugins/perl/perl-handlers.h --- a/plugins/perl/perl-handlers.h Thu Aug 21 07:37:47 2003 +0000 +++ b/plugins/perl/perl-handlers.h Thu Aug 21 08:38:32 2003 +0000 @@ -6,15 +6,34 @@ typedef struct { char *name; - char *args; + void *args; GaimPlugin *plugin; int iotag; } GaimPerlTimeoutHandler; +typedef struct +{ + char *signal; + char *func; + void *data; + void *instance; + GaimPlugin *plugin; + +} GaimPerlSignalHandler; + + void gaim_perl_timeout_add(GaimPlugin *plugin, int seconds, const char *func, void *args); void gaim_perl_timeout_clear_for_plugin(GaimPlugin *plugin); void gaim_perl_timeout_clear(void); +void gaim_perl_signal_connect(GaimPlugin *plugin, void *handle, + const char *signal, const char *func, + void *data); +void gaim_perl_signal_disconnect(GaimPlugin *plugin, void *handle, + const char *signal, const char *func); +void gaim_perl_signal_clear_for_plugin(GaimPlugin *plugin); +void gaim_perl_signal_clear(void); + #endif /* _GAIM_PERL_HANDLERS_H_ */ diff -r d01ba50e3f3e -r ed796f756237 plugins/perl/perl.c --- a/plugins/perl/perl.c Thu Aug 21 07:37:47 2003 +0000 +++ b/plugins/perl/perl.c Thu Aug 21 08:38:32 2003 +0000 @@ -374,7 +374,7 @@ LEAVE; } - gaim_signals_disconnect_by_handle(plugin); + gaim_perl_signal_clear_for_plugin(plugin); gaim_perl_timeout_clear_for_plugin(plugin); return TRUE;