changeset 6549:ed796f756237

[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 <tailor@pidgin.im>
author Christian Hammond <chipx86@chipx86.com>
date Thu, 21 Aug 2003 08:38:32 +0000
parents d01ba50e3f3e
children f1736493aebb
files plugins/perl/perl-handlers.c plugins/perl/perl-handlers.h plugins/perl/perl.c
diffstat 3 files changed, 151 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- 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);
+}
+
--- 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_ */
--- 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;