changeset 6919:1aa771990188

[gaim-migrate @ 7466] Added support for return values in perl plugin signal callbacks, and for modifying parameters, in theory (but apparently not in practice. Darn you perl! Darn you to Dell!) committer: Tailor Script <tailor@pidgin.im>
author Christian Hammond <chipx86@chipx86.com>
date Tue, 23 Sep 2003 22:35:00 +0000
parents d4b53b3d20eb
children 13f78c350cd3
files plugins/perl/perl-handlers.c
diffstat 1 files changed, 115 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/plugins/perl/perl-handlers.c	Tue Sep 23 22:14:57 2003 +0000
+++ b/plugins/perl/perl-handlers.c	Tue Sep 23 22:35:00 2003 +0000
@@ -70,6 +70,8 @@
 	int count;
 	int value_count;
 	GaimValue *ret_value, **values;
+	SV **sv_args;
+	STRLEN na;
 
 	dSP;
 	ENTER;
@@ -79,16 +81,17 @@
 	gaim_signal_get_values(handler->instance, handler->signal,
 						   &ret_value, &value_count, &values);
 
+	sv_args = g_new(SV *, value_count);
+
 	for (i = 0; i < value_count; i++)
 	{
 		SV *sv = gaim_perl_sv_from_vargs(values[i], args);
 
-		gaim_debug(GAIM_DEBUG_INFO, "perl", "Pushing arg %p\n", sv);
+		sv_args[i] = sv;
 
 		XPUSHs(sv);
 	}
 
-	gaim_debug(GAIM_DEBUG_INFO, "perl", "Pushing data %p\n", handler->data);
 	XPUSHs((SV *)handler->data);
 
 	PUTBACK;
@@ -102,14 +105,123 @@
 		if (count != 1)
 			croak("Uh oh! call_sv returned %i != 1", i);
 		else
-			ret_val = POPs;
+		{
+			SV *temp_ret_val = POPs;
+
+			switch (gaim_value_get_type(ret_value))
+			{
+				case GAIM_TYPE_BOOLEAN:
+					ret_val = (void *)SvIV(temp_ret_val);
+					break;
+
+				case GAIM_TYPE_INT:
+					ret_val = (void *)SvIV(temp_ret_val);
+					break;
+
+				case GAIM_TYPE_UINT:
+					ret_val = (void *)SvUV(temp_ret_val);
+					break;
+
+				case GAIM_TYPE_LONG:
+					ret_val = (void *)SvIV(temp_ret_val);
+					break;
+
+				case GAIM_TYPE_ULONG:
+					ret_val = (void *)SvUV(temp_ret_val);
+					break;
+
+				case GAIM_TYPE_INT64:
+					ret_val = (void *)SvIV(temp_ret_val);
+					break;
+
+				case GAIM_TYPE_UINT64:
+					ret_val = (void *)SvUV(temp_ret_val);
+					break;
+
+				case GAIM_TYPE_STRING:
+					ret_val = (void *)SvPV(temp_ret_val, na);
+					break;
+
+				case GAIM_TYPE_POINTER:
+					ret_val = (void *)SvIV(temp_ret_val);
+					break;
+
+				case GAIM_TYPE_BOXED:
+					ret_val = (void *)SvIV(temp_ret_val);
+					break;
+
+				default:
+					ret_val = NULL;
+			}
+		}
 	}
 	else
 		call_sv(handler->callback, G_SCALAR);
 
+	/* 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:
+					*va_arg(args, gboolean *) = SvIV(sv_args[i]);
+					break;
+
+				case GAIM_TYPE_INT:
+					*va_arg(args, int *) = SvIV(sv_args[i]);
+					break;
+
+				case GAIM_TYPE_UINT:
+					*va_arg(args, unsigned int *) = SvUV(sv_args[i]);
+					break;
+
+				case GAIM_TYPE_LONG:
+					*va_arg(args, long *) = SvIV(sv_args[i]);
+					break;
+
+				case GAIM_TYPE_ULONG:
+					*va_arg(args, unsigned long *) = SvUV(sv_args[i]);
+					break;
+
+				case GAIM_TYPE_INT64:
+					*va_arg(args, gint64 *) = SvIV(sv_args[i]);
+					break;
+
+				case GAIM_TYPE_UINT64:
+					*va_arg(args, guint64 *) = SvUV(sv_args[i]);
+					break;
+
+				case GAIM_TYPE_STRING:
+					/* XXX Memory leak! */
+					*va_arg(args, char **) = SvPV(sv_args[i], na);
+					break;
+
+				case GAIM_TYPE_POINTER:
+					/* XXX Possible memory leak! */
+					*va_arg(args, void **) = (void *)SvIV(sv_args[i]);
+					break;
+
+				case GAIM_TYPE_BOXED:
+					/* Uh.. I dunno. Try this? Likely won't work. Heh. */
+					/* XXX Possible memory leak! */
+					*va_arg(args, void **) = (void *)SvIV(sv_args[i]);
+					break;
+
+				default:
+					return FALSE;
+			}
+		}
+	}
+
 	FREETMPS;
 	LEAVE;
 
+	g_free(sv_args);
+
+	gaim_debug_misc("perl", "ret_val = %p\n", ret_val);
+
 	return ret_val;
 }