# HG changeset patch # User Christian Hammond # Date 1064356500 0 # Node ID 1aa7719901887a8e121e10ca6a927e530608ad65 # Parent d4b53b3d20eba8fc8ff40aadb290f07ad1e032d2 [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 diff -r d4b53b3d20eb -r 1aa771990188 plugins/perl/perl-handlers.c --- 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; }