plugins/perl/perl-handlers.c

branch
gaim
changeset 20470
77693555855f
parent 13071
b98e72d4089a
parent 20469
b2836a24d81e
child 20471
1966704b3e42
--- a/plugins/perl/perl-handlers.c	Mon Apr 16 00:43:53 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,631 +0,0 @@
-#include "perl-common.h"
-#include "perl-handlers.h"
-
-#include "debug.h"
-#include "signals.h"
-
-extern PerlInterpreter *my_perl;
-static GList *cmd_handlers = NULL;
-static GList *signal_handlers = NULL;
-static GList *timeout_handlers = NULL;
-
-/* perl < 5.8.0 doesn't define PERL_MAGIC_ext */
-#ifndef PERL_MAGIC_ext
-#define PERL_MAGIC_ext '~'
-#endif
-
-void
-gaim_perl_plugin_action_cb(GaimPluginAction *action)
-{
-	SV **callback;
-	HV *hv = NULL;
-	gchar *hvname;
-	GaimPlugin *plugin;
-	GaimPerlScript *gps;
-	dSP;
-
-	plugin = action->plugin;
-	gps = (GaimPerlScript *)plugin->info->extra_info;
-	hvname = g_strdup_printf("%s::plugin_actions", gps->package);
-	hv = get_hv(hvname, FALSE);
-	g_free(hvname);
-
-	if (hv == NULL)
-		croak("No plugin_actions hash found in \"%s\" plugin.", gaim_plugin_get_name(plugin));
-
-	ENTER;
-	SAVETMPS;
-
-	callback = hv_fetch(hv, action->label, strlen(action->label), 0);
-
-	if (callback == NULL || *callback == NULL)
-		croak("No plugin_action function named \"%s\" in \"%s\" plugin.", action->label, gaim_plugin_get_name(plugin));
-
-	PUSHMARK(sp);
-	XPUSHs(gaim_perl_bless_object(gps->plugin, "Gaim::Plugin"));
-	PUTBACK;
-
-	call_sv(*callback, G_VOID | G_DISCARD);
-	SPAGAIN;
-
-	PUTBACK;
-	FREETMPS;
-	LEAVE;
-}
-
-GList *
-gaim_perl_plugin_actions(GaimPlugin *plugin, gpointer context)
-{
-	GList *l = NULL;
-	GaimPerlScript *gps;
-	int i = 0, count = 0;
-	dSP;
-
-	gps = (GaimPerlScript *)plugin->info->extra_info;
-
-	ENTER;
-	SAVETMPS;
-
-	PUSHMARK(SP);
-	XPUSHs(sv_2mortal(gaim_perl_bless_object(plugin, "Gaim::Plugin")));
-	/* XXX This *will* cease working correctly if context gets changed to
-	 * ever be able to hold anything other than a GaimConnection */
-	if (context != NULL)
-		XPUSHs(sv_2mortal(gaim_perl_bless_object(context, "Gaim::Connection")));
-	else
-		XPUSHs(&PL_sv_undef);
-	PUTBACK;
-
-	count = call_pv(gps->plugin_action_sub, G_ARRAY);
-
-	SPAGAIN;
-
-	if (count == 0)
-		croak("The plugin_actions sub didn't return anything.\n");
-
-	for (i = 0; i < count; i++) {
-		SV *sv;
-		gchar *label;
-		GaimPluginAction *act = NULL;
-
-		sv = POPs;
-		label = SvPV_nolen(sv);
-		/* XXX I think this leaks, but doing it without the strdup
-		 * just showed garbage */
-		act = gaim_plugin_action_new(g_strdup(label), gaim_perl_plugin_action_cb);
-		l = g_list_append(l, act);
-	}
-
-	PUTBACK;
-	FREETMPS;
-	LEAVE;
-
-	return l;
-}
-
-GtkWidget *
-gaim_perl_gtk_get_plugin_frame(GaimPlugin *plugin)
-{
-	SV * sv;
-	int count;
-	MAGIC *mg;
-	GtkWidget *ret;
-	GaimPerlScript *gps;
-	dSP;
-
-	gps = (GaimPerlScript *)plugin->info->extra_info;
-
-	ENTER;
-	SAVETMPS;
-
-	count = call_pv(gps->gtk_prefs_sub, G_SCALAR | G_NOARGS);
-	if (count != 1)
-		croak("call_pv: Did not return the correct number of values.\n");
-
-	/* the frame was created in a perl sub and is returned */
-	SPAGAIN;
-
-	/* We have a Gtk2::Frame on top of the stack */
-	sv = POPs;
-
-	/* The magic field hides the pointer to the actual GtkWidget */
-	mg = mg_find(SvRV(sv), PERL_MAGIC_ext);
-	ret = (GtkWidget *)mg->mg_ptr;
-
-	PUTBACK;
-	FREETMPS;
-	LEAVE;
-
-	return ret;
-}
-
-GaimPluginPrefFrame *
-gaim_perl_get_plugin_frame(GaimPlugin *plugin)
-{
-	/* Sets up the Perl Stack for our call back into the script to run the
-	 * plugin_pref... sub */
-	int count;
-	GaimPerlScript *gps;
-	GaimPluginPrefFrame *ret_frame;
-	dSP;
-
-	gps = (GaimPerlScript *)plugin->info->extra_info;
-
-	ENTER;
-	SAVETMPS;
-	/* Some perl magic to run perl_plugin_pref_frame_SV perl sub and
-	 * return the frame */
-	PUSHMARK(SP);
-	PUTBACK;
-
-	count = call_pv(gps->prefs_sub, G_SCALAR | G_NOARGS);
-
-	SPAGAIN;
-
-	if (count != 1)
-		croak("call_pv: Did not return the correct number of values.\n");
-	/* the frame was created in a perl sub and is returned */
-	ret_frame = (GaimPluginPrefFrame *)gaim_perl_ref_object(POPs);
-
-	/* Tidy up the Perl stack */
-	PUTBACK;
-	FREETMPS;
-	LEAVE;
-
-	return ret_frame;
-}
-
-static void
-destroy_timeout_handler(GaimPerlTimeoutHandler *handler)
-{
-	timeout_handlers = g_list_remove(timeout_handlers, handler);
-
-	if (handler->callback != NULL)
-		SvREFCNT_dec(handler->callback);
-
-	if (handler->data != NULL)
-		SvREFCNT_dec(handler->data);
-
-	g_free(handler);
-}
-
-static void
-destroy_signal_handler(GaimPerlSignalHandler *handler)
-{
-	signal_handlers = g_list_remove(signal_handlers, handler);
-
-	if (handler->callback != NULL)
-		SvREFCNT_dec(handler->callback);
-
-	if (handler->data != NULL)
-		SvREFCNT_dec(handler->data);
-
-	g_free(handler->signal);
-	g_free(handler);
-}
-
-static int
-perl_timeout_cb(gpointer data)
-{
-	GaimPerlTimeoutHandler *handler = (GaimPerlTimeoutHandler *)data;
-
-	dSP;
-	ENTER;
-	SAVETMPS;
-	PUSHMARK(sp);
-	XPUSHs((SV *)handler->data);
-	PUTBACK;
-	call_sv(handler->callback, G_EVAL | G_SCALAR);
-	SPAGAIN;
-
-	PUTBACK;
-	FREETMPS;
-	LEAVE;
-
-	destroy_timeout_handler(handler);
-
-	return 0;
-}
-
-typedef void *DATATYPE;
-
-static void *
-perl_signal_cb(va_list args, void *data)
-{
-	GaimPerlSignalHandler *handler = (GaimPerlSignalHandler *)data;
-	void *ret_val = NULL;
-	int i;
-	int count;
-	int value_count;
-	GaimValue *ret_value, **values;
-	SV **sv_args;
-	DATATYPE **copy_args;
-	STRLEN na;
-
-	dSP;
-	ENTER;
-	SAVETMPS;
-	PUSHMARK(sp);
-
-	gaim_signal_get_values(handler->instance, handler->signal,
-	                       &ret_value, &value_count, &values);
-
-	sv_args   = g_new(SV *,    value_count);
-	copy_args = g_new(void **, value_count);
-
-	for (i = 0; i < value_count; i++) {
-		sv_args[i] = gaim_perl_sv_from_vargs(values[i],
-		                                     (va_list*)&args,
-		                                     &copy_args[i]);
-
-		XPUSHs(sv_args[i]);
-	}
-
-	XPUSHs((SV *)handler->data);
-
-	PUTBACK;
-
-	if (ret_value != NULL) {
-		count = call_sv(handler->callback, G_EVAL | G_SCALAR);
-
-		SPAGAIN;
-
-		if (count != 1)
-			croak("Uh oh! call_sv returned %i != 1", i);
-		else
-			ret_val = gaim_perl_data_from_sv(ret_value, POPs);
-	} else {
-		call_sv(handler->callback, G_SCALAR);
-
-		SPAGAIN;
-	}
-
-	if (SvTRUE(ERRSV)) {
-		gaim_debug_error("perl",
-		                 "Perl function exited abnormally: %s\n",
-		                 SvPV(ERRSV, na));
-	}
-
-	/* See if any parameters changed. */
-	for (i = 0; i < value_count; i++) {
-		if (gaim_value_is_outgoing(values[i])) {
-			switch (gaim_value_get_type(values[i])) {
-				case GAIM_TYPE_BOOLEAN:
-					*((gboolean *)copy_args[i]) = SvIV(sv_args[i]);
-					break;
-
-				case GAIM_TYPE_INT:
-					*((int *)copy_args[i]) = SvIV(sv_args[i]);
-					break;
-
-				case GAIM_TYPE_UINT:
-					*((unsigned int *)copy_args[i]) = SvUV(sv_args[i]);
-					break;
-
-				case GAIM_TYPE_LONG:
-					*((long *)copy_args[i]) = SvIV(sv_args[i]);
-					break;
-
-				case GAIM_TYPE_ULONG:
-					*((unsigned long *)copy_args[i]) = SvUV(sv_args[i]);
-					break;
-
-				case GAIM_TYPE_INT64:
-					*((gint64 *)copy_args[i]) = SvIV(sv_args[i]);
-					break;
-
-				case GAIM_TYPE_UINT64:
-					*((guint64 *)copy_args[i]) = SvUV(sv_args[i]);
-					break;
-
-				case GAIM_TYPE_STRING:
-					if (strcmp(*((char **)copy_args[i]), SvPVX(sv_args[i]))) {
-						g_free(*((char **)copy_args[i]));
-						*((char **)copy_args[i]) =
-							g_strdup(SvPV(sv_args[i], na));
-					}
-					break;
-
-				case GAIM_TYPE_POINTER:
-					*((void **)copy_args[i]) = (void *)SvIV(sv_args[i]);
-					break;
-
-				case GAIM_TYPE_BOXED:
-					*((void **)copy_args[i]) = (void *)SvIV(sv_args[i]);
-					break;
-
-				default:
-					break;
-			}
-
-#if 0
-			*((void **)copy_args[i]) = gaim_perl_data_from_sv(values[i],
-															  sv_args[i]);
-#endif
-		}
-	}
-
-	PUTBACK;
-	FREETMPS;
-	LEAVE;
-
-	g_free(sv_args);
-	g_free(copy_args);
-
-	gaim_debug_misc("perl", "ret_val = %p\n", ret_val);
-
-	return ret_val;
-}
-
-static GaimPerlSignalHandler *
-find_signal_handler(GaimPlugin *plugin, void *instance, const char *signal)
-{
-	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)) {
-			return handler;
-		}
-	}
-
-	return NULL;
-}
-
-void
-gaim_perl_timeout_add(GaimPlugin *plugin, int seconds, SV *callback, SV *data)
-{
-	GaimPerlTimeoutHandler *handler;
-
-	if (plugin == NULL) {
-		croak("Invalid handle in adding perl timeout handler.\n");
-		return;
-	}
-
-	handler = g_new0(GaimPerlTimeoutHandler, 1);
-
-	handler->plugin   = plugin;
-	handler->callback = (callback != NULL && callback != &PL_sv_undef
-	                     ? newSVsv(callback) : NULL);
-	handler->data     = (data != NULL && data != &PL_sv_undef
-	                     ? newSVsv(data) : NULL);
-
-	timeout_handlers = g_list_append(timeout_handlers, handler);
-
-	handler->iotag = g_timeout_add(seconds * 1000, perl_timeout_cb, handler);
-}
-
-void
-gaim_perl_timeout_clear_for_plugin(GaimPlugin *plugin)
-{
-	GaimPerlTimeoutHandler *handler;
-	GList *l, *l_next;
-
-	for (l = timeout_handlers; l != NULL; l = l_next) {
-		l_next = l->next;
-
-		handler = (GaimPerlTimeoutHandler *)l->data;
-
-		if (handler->plugin == plugin)
-			destroy_timeout_handler(handler);
-	}
-}
-
-void
-gaim_perl_timeout_clear(void)
-{
-	while (timeout_handlers != NULL)
-		destroy_timeout_handler(timeout_handlers->data);
-}
-
-void
-gaim_perl_signal_connect(GaimPlugin *plugin, void *instance,
-                         const char *signal, SV *callback, SV *data)
-{
-	GaimPerlSignalHandler *handler;
-
-	handler = g_new0(GaimPerlSignalHandler, 1);
-	handler->plugin   = plugin;
-	handler->instance = instance;
-	handler->signal   = g_strdup(signal);
-	handler->callback = (callback != NULL &&
-	                     callback != &PL_sv_undef ? newSVsv(callback)
-	                                              : NULL);
-	handler->data     = (data != NULL &&
-	                     data != &PL_sv_undef ? newSVsv(data) : NULL);
-
-	signal_handlers = g_list_append(signal_handlers, handler);
-
-	gaim_signal_connect_vargs(instance, signal, plugin,
-	                          GAIM_CALLBACK(perl_signal_cb), handler);
-}
-
-void
-gaim_perl_signal_disconnect(GaimPlugin *plugin, void *instance,
-                            const char *signal)
-{
-	GaimPerlSignalHandler *handler;
-
-	handler = find_signal_handler(plugin, instance, signal);
-
-	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);
-}
-
-static GaimCmdRet
-perl_cmd_cb(GaimConversation *conv, const gchar *command,
-            gchar **args, gchar **error, void *data)
-{
-	int i = 0, count, ret_value = GAIM_CMD_RET_OK;
-	SV *cmdSV, *tmpSV, *convSV;
-	GaimPerlCmdHandler *handler = (GaimPerlCmdHandler *)data;
-
-	dSP;
-	ENTER;
-	SAVETMPS;
-	PUSHMARK(SP);
-
-	/* Push the conversation onto the perl stack */
-	convSV = sv_2mortal(gaim_perl_bless_object(conv, "Gaim::Conversation"));
-	XPUSHs(convSV);
-
-	/* Push the command string onto the perl stack */
-	cmdSV = newSVpv(command, 0);
-	cmdSV = sv_2mortal(cmdSV);
-	XPUSHs(cmdSV);
-
-	/* Push the data onto the perl stack */
-	XPUSHs((SV *)handler->data);
-
-	/* Push any arguments we may have */
-	for (i = 0; args[i] != NULL; i++) {
-		/* XXX The mortality of these created SV's should prevent
-		 * memory issues, if I read/understood everything correctly...
-		 */
-		tmpSV = newSVpv(args[i], 0);
-		tmpSV = sv_2mortal(tmpSV);
-		XPUSHs(tmpSV);
-	}
-
-	PUTBACK;
-	count = call_sv(handler->callback, G_EVAL|G_SCALAR);
-
-	if (count != 1)
-		croak("call_sv: Did not return the correct number of values.\n");
-
-	SPAGAIN;
-
-	ret_value = POPi;
-
-	PUTBACK;
-	FREETMPS;
-	LEAVE;
-
-	return ret_value;
-}
-
-GaimCmdId
-gaim_perl_cmd_register(GaimPlugin *plugin, const gchar *command,
-                       const gchar *args, GaimCmdPriority priority,
-                       GaimCmdFlag flag, const gchar *prpl_id, SV *callback,
-                       const gchar *helpstr, SV *data)
-{
-	GaimPerlCmdHandler *handler;
-
-	handler          = g_new0(GaimPerlCmdHandler, 1);
-	handler->plugin  = plugin;
-	handler->cmd     = g_strdup(command);
-	handler->prpl_id = g_strdup(prpl_id);
-
-	if (callback != NULL && callback != &PL_sv_undef)
-		handler->callback = newSVsv(callback);
-	else
-		handler->callback = NULL;
-
-	if (data != NULL && data != &PL_sv_undef)
-		handler->data = newSVsv(data);
-	else
-		handler->data = NULL;
-
-	cmd_handlers = g_list_append(cmd_handlers, handler);
-
-	handler->id = gaim_cmd_register(command, args, priority, flag, prpl_id,
-	                                GAIM_CMD_FUNC(perl_cmd_cb), helpstr,
-	                                handler);
-
-	return handler->id;
-}
-
-static void
-destroy_cmd_handler(GaimPerlCmdHandler *handler)
-{
-	cmd_handlers = g_list_remove(cmd_handlers, handler);
-
-	if (handler->callback != NULL)
-		SvREFCNT_dec(handler->callback);
-
-	if (handler->data != NULL)
-		SvREFCNT_dec(handler->data);
-
-	g_free(handler->cmd);
-	g_free(handler->prpl_id);
-	g_free(handler);
-}
-
-void
-gaim_perl_cmd_clear_for_plugin(GaimPlugin *plugin)
-{
-	GList *l, *l_next;
-
-	for (l = cmd_handlers; l != NULL; l = l_next) {
-		GaimPerlCmdHandler *handler = (GaimPerlCmdHandler *)l->data;
-
-		l_next = l->next;
-
-		if (handler->plugin == plugin)
-			destroy_cmd_handler(handler);
-	}
-}
-
-static GaimPerlCmdHandler *
-find_cmd_handler(GaimCmdId id)
-{
-	GList *l;
-
-	for (l = cmd_handlers; l != NULL; l = l->next) {
-		GaimPerlCmdHandler *handler = (GaimPerlCmdHandler *)l->data;
-
-		if (handler->id == id)
-			return handler;
-	}
-
-	return NULL;
-}
-
-void
-gaim_perl_cmd_unregister(GaimCmdId id)
-{
-	GaimPerlCmdHandler *handler;
-
-	handler = find_cmd_handler(id);
-
-	if (handler == NULL) {
-		croak("Invalid command id in removing a perl command handler.\n");
-		return;
-	}
-
-	gaim_cmd_unregister(id);
-	destroy_cmd_handler(handler);
-}

mercurial