static gpointer dispatch_callback(SignalData *sig_data, int num_vals, ...) { MonoArray *array; MonoObject *obj; int i; gpointer meth_args[1]; gpointer purple_obj; va_list args; va_start(args, num_vals); array = mono_array_new(ml_get_domain(), mono_get_object_class(), num_vals); for (i = 0; i < num_vals; i++) { if (purple_value_get_type(sig_data->values[i]) == PURPLE_TYPE_SUBTYPE) { purple_obj = va_arg(args, gpointer); obj = ml_object_from_purple_subtype(purple_value_get_subtype(sig_data->values[i]), purple_obj); mono_array_set(array, MonoObject*, i, obj); } else { purple_obj = va_arg(args, gpointer); obj = ml_object_from_purple_type(purple_value_get_type(sig_data->values[i]), purple_obj); mono_array_set(array, MonoObject*, i, obj); } } va_end(args); meth_args[0] = array; return ml_delegate_invoke(sig_data->func, meth_args); }
static PurpleCallback get_callback(SignalData *sig_data) { int i, index = 0; if (sig_data->ret_value == NULL) index = 0; else index = determine_index(purple_value_get_type(sig_data->ret_value)); for (i = 0; i < sig_data->num_vals; i++) { index += determine_index(purple_value_get_type(sig_data->values[i])); } purple_debug(PURPLE_DEBUG_INFO, "mono", "get_callback index = %d\n", index); if (index >= callbacks_array_size || callbacks[index] == NULL) { purple_debug(PURPLE_DEBUG_ERROR, "mono", "couldn't find a callback function for signal: %s\n", sig_data->signal); return NULL; } purple_debug(PURPLE_DEBUG_MISC, "mono", "using callback at index: %d\n", index); return PURPLE_CALLBACK(callbacks[index]); }
static void * perl_signal_cb(va_list args, void *data) { PurplePerlSignalHandler *handler = data; void *ret_val = NULL; int i; int count; int value_count; PurpleValue *ret_value, **values; SV **sv_args; DATATYPE **copy_args; dSP; ENTER; SAVETMPS; PUSHMARK(sp); purple_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] = purple_perl_sv_from_vargs(values[i], #ifdef VA_COPY_AS_ARRAY args, #else (va_list*)&args, #endif ©_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 = purple_perl_data_from_sv(ret_value, POPs); } else { call_sv(handler->callback, G_EVAL | G_SCALAR); SPAGAIN; } if (SvTRUE(ERRSV)) { purple_debug_error("perl", "Perl function exited abnormally: %s\n", SvPVutf8_nolen(ERRSV)); } /* See if any parameters changed. */ for (i = 0; i < value_count; i++) { if (purple_value_is_outgoing(values[i])) { switch (purple_value_get_type(values[i])) { case PURPLE_TYPE_BOOLEAN: *((gboolean *)copy_args[i]) = SvIV(sv_args[i]); break; case PURPLE_TYPE_INT: *((int *)copy_args[i]) = SvIV(sv_args[i]); break; case PURPLE_TYPE_UINT: *((unsigned int *)copy_args[i]) = SvUV(sv_args[i]); break; case PURPLE_TYPE_LONG: *((long *)copy_args[i]) = SvIV(sv_args[i]); break; case PURPLE_TYPE_ULONG: *((unsigned long *)copy_args[i]) = SvUV(sv_args[i]); break; case PURPLE_TYPE_INT64: *((gint64 *)copy_args[i]) = SvIV(sv_args[i]); break; case PURPLE_TYPE_UINT64: *((guint64 *)copy_args[i]) = SvUV(sv_args[i]); break; case PURPLE_TYPE_STRING: if (strcmp(*((char **)copy_args[i]), SvPVX(sv_args[i]))) { g_free(*((char **)copy_args[i])); *((char **)copy_args[i]) = g_strdup(SvPVutf8_nolen(sv_args[i])); } /* Clean up sv_args[i] - we're done with it */ sv_2mortal(sv_args[i]); break; case PURPLE_TYPE_POINTER: case PURPLE_TYPE_BOXED: *((void **)copy_args[i]) = (void *)SvIV(sv_args[i]); break; case PURPLE_TYPE_SUBTYPE: *((void **)copy_args[i]) = purple_perl_ref_object(sv_args[i]); break; default: break; } #if 0 *((void **)copy_args[i]) = purple_perl_data_from_sv(values[i], sv_args[i]); #endif } } PUTBACK; FREETMPS; LEAVE; g_free(sv_args); g_free(copy_args); purple_debug_misc("perl", "ret_val = %p\n", ret_val); return ret_val; }
Data IMInvoker::purpleValueToData(PURPLE_VALUE* value) { Data data; #if LIBPURPLE_VERSION_MAJOR >= 3 if (false) { } else if (g_type_check_value_holds(value, G_TYPE_CHAR)) { data = Data(g_value_get_schar(value), Data::VERBATIM); } else if (g_type_check_value_holds(value, G_TYPE_UCHAR)) { data = Data(g_value_get_uchar(value), Data::VERBATIM); } else if (g_type_check_value_holds(value, G_TYPE_BOOLEAN)) { data = Data(g_value_get_boolean(value)); } else if (g_type_check_value_holds(value, G_TYPE_INT)) { data = Data(g_value_get_int(value)); } else if (g_type_check_value_holds(value, G_TYPE_UINT)) { data = Data(g_value_get_uint(value)); } else if (g_type_check_value_holds(value, G_TYPE_LONG)) { data = Data(g_value_get_long(value)); } else if (g_type_check_value_holds(value, G_TYPE_ULONG)) { data = Data(g_value_get_ulong(value)); } else if (g_type_check_value_holds(value, G_TYPE_INT64)) { data = Data(g_value_get_int64(value)); } else if (g_type_check_value_holds(value, G_TYPE_FLOAT)) { data = Data(g_value_get_float(value)); } else if (g_type_check_value_holds(value, G_TYPE_DOUBLE)) { data = Data(g_value_get_double(value)); } else if (g_type_check_value_holds(value, G_TYPE_STRING)) { const gchar* tmp = g_value_get_string(value); if (tmp == NULL) { data = Data("", Data::VERBATIM); } else { data = Data(g_value_get_string(value), Data::VERBATIM); } } else if (g_type_check_value_holds(value, G_TYPE_OBJECT) || g_type_check_value_holds(value, G_TYPE_PARAM) || g_type_check_value_holds(value, G_TYPE_POINTER) || g_type_check_value_holds(value, G_TYPE_FLAGS) || g_type_check_value_holds(value, G_TYPE_ENUM)) { LOG(ERROR) << "purple thingy not supported"; } else { LOG(ERROR) << "purple thingy unknown"; } #else switch (purple_value_get_type(value)) { case PURPLE_TYPE_BOOLEAN: if (purple_value_get_boolean(value)) data = Data("true"); data = Data("false"); break; case PURPLE_TYPE_STRING: if (purple_value_get_string(value)) { data = Data(purple_value_get_string(value), Data::VERBATIM); } break; case PURPLE_TYPE_CHAR: Data(purple_value_get_char(value)); break; case PURPLE_TYPE_UCHAR: Data(purple_value_get_uchar(value)); break; case PURPLE_TYPE_SHORT: Data(purple_value_get_short(value)); break; case PURPLE_TYPE_USHORT: Data(purple_value_get_ushort(value)); break; case PURPLE_TYPE_INT: Data(purple_value_get_int(value)); break; case PURPLE_TYPE_UINT: Data(purple_value_get_uint(value)); break; case PURPLE_TYPE_LONG: Data(purple_value_get_long(value)); break; case PURPLE_TYPE_ULONG: Data(purple_value_get_ulong(value)); break; case PURPLE_TYPE_INT64: Data(purple_value_get_int64(value)); break; case PURPLE_TYPE_UINT64: Data(purple_value_get_uint64(value)); break; case PURPLE_TYPE_OBJECT: case PURPLE_TYPE_POINTER: case PURPLE_TYPE_ENUM: case PURPLE_TYPE_BOXED: case PURPLE_TYPE_UNKNOWN: case PURPLE_TYPE_SUBTYPE: LOG(ERROR) << "purple thingy not supported"; break; } #endif return data; }