Sat, 16 Dec 2006 04:59:55 +0000
This is a hand-crafted commit to migrate across subversion revisions
16854:16861, due to some vagaries of the way the original renames were
done. Witness that monotone can do in one revision what svn had to
spread across several.
| 11660 | 1 | #include "mono-glue.h" |
| 2 | #include "mono-helper.h" | |
| 3 | #include "debug.h" | |
| 4 | #include "blist.h" | |
| 5 | #include "signals.h" | |
| 6 | #include "value.h" | |
| 7 | ||
| 8 | typedef struct { | |
| 9 | MonoObject *func; | |
| 10 | char *signal; | |
| 11 | GaimValue **values; | |
| 12 | GaimValue *ret_value; | |
| 13 | int num_vals; | |
| 14 | } SignalData; | |
| 15 | ||
| 16 | static GaimCallback get_callback(SignalData *sig_data); | |
| 17 | ||
| 18 | static gpointer dispatch_callback(SignalData *sig_data, int num_vals, ...) | |
| 19 | { | |
| 20 | MonoArray *array; | |
| 21 | MonoObject *obj; | |
| 22 | int i; | |
| 23 | gpointer meth_args[1]; | |
| 24 | gpointer gaim_obj; | |
| 25 | ||
| 26 | va_list args; | |
| 27 | ||
| 28 | va_start(args, num_vals); | |
| 29 | ||
|
11980
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
30 | array = mono_array_new(ml_get_domain(), mono_get_object_class(), num_vals); |
| 11660 | 31 | |
| 32 | for (i = 0; i < num_vals; i++) { | |
| 33 | if (gaim_value_get_type(sig_data->values[i]) == GAIM_TYPE_SUBTYPE) { | |
| 34 | gaim_obj = va_arg(args, gpointer); | |
|
11980
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
35 | obj = ml_object_from_gaim_subtype(gaim_value_get_subtype(sig_data->values[i]), gaim_obj); |
| 11660 | 36 | mono_array_set(array, MonoObject*, i, obj); |
| 37 | } else { | |
| 38 | gaim_obj = va_arg(args, gpointer); | |
|
11980
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
39 | obj = ml_object_from_gaim_type(gaim_value_get_type(sig_data->values[i]), gaim_obj); |
| 11660 | 40 | mono_array_set(array, MonoObject*, i, obj); |
| 41 | } | |
| 42 | } | |
| 43 | ||
| 44 | va_end(args); | |
| 45 | ||
| 46 | meth_args[0] = array; | |
| 47 | ||
|
11980
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
48 | return ml_delegate_invoke(sig_data->func, meth_args); |
| 11660 | 49 | } |
| 50 | ||
| 51 | static void cb_void__pointer(void *arg1, void *data) | |
| 52 | { | |
|
11980
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
53 | dispatch_callback((SignalData*)data, ((SignalData*)data)->num_vals, arg1); |
| 11660 | 54 | } |
| 55 | ||
|
11980
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
56 | static void cb_void__pointer_pointer_pointer(void *arg1, void *arg2, void *arg3, void *data) |
|
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
57 | { |
|
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
58 | dispatch_callback((SignalData*)data, ((SignalData*)data)->num_vals, arg1, arg2, arg3); |
|
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
59 | } |
|
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
60 | |
|
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
61 | |
| 11660 | 62 | int gaim_signal_connect_glue(MonoObject* h, MonoObject *plugin, MonoString *signal, MonoObject *func) |
| 63 | { | |
| 64 | char *sig; | |
| 65 | void **instance = NULL; | |
| 66 | SignalData *sig_data; | |
|
11980
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
67 | GaimMonoPlugin *mplug; |
|
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
68 | MonoClass *klass; |
| 11660 | 69 | |
| 70 | sig = mono_string_to_utf8(signal); | |
| 71 | gaim_debug(GAIM_DEBUG_INFO, "mono", "connecting signal: %s\n", sig); | |
| 72 | ||
| 73 | instance = (void*)mono_object_unbox(h); | |
|
11980
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
74 | |
| 11660 | 75 | sig_data = g_new0(SignalData, 1); |
| 76 | ||
| 77 | sig_data->func = func; | |
| 78 | sig_data->signal = sig; | |
| 79 | ||
| 80 | gaim_signal_get_values(*instance, sig, &sig_data->ret_value, &sig_data->num_vals, &sig_data->values); | |
|
11980
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
81 | |
|
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
82 | klass = mono_object_get_class(plugin); |
|
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
83 | |
|
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
84 | mplug = ml_find_plugin_by_class(klass); |
|
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
85 | |
|
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
86 | mplug->signal_data = g_list_append(mplug->signal_data, (gpointer)sig_data); |
| 11660 | 87 | |
|
11980
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
88 | return gaim_signal_connect(*instance, sig, (gpointer)klass, get_callback(sig_data), (gpointer)sig_data); |
| 11660 | 89 | } |
| 90 | ||
| 91 | static int determine_index(GaimType type) | |
| 92 | { | |
| 93 | switch (type) { | |
| 94 | case GAIM_TYPE_SUBTYPE: | |
| 95 | case GAIM_TYPE_STRING: | |
| 96 | case GAIM_TYPE_OBJECT: | |
| 97 | case GAIM_TYPE_POINTER: | |
| 98 | case GAIM_TYPE_BOXED: | |
| 99 | return 1; | |
| 100 | break; | |
| 101 | default: | |
| 102 | return type; | |
| 103 | break; | |
| 104 | } | |
| 105 | } | |
| 106 | ||
| 107 | static gpointer callbacks[]= { | |
| 108 | NULL, | |
| 109 | cb_void__pointer, | |
|
11980
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
110 | NULL, |
|
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
111 | cb_void__pointer_pointer_pointer |
| 11660 | 112 | }; |
| 113 | ||
| 114 | static int callbacks_array_size = sizeof(callbacks) / sizeof(GaimCallback); | |
| 115 | ||
| 116 | ||
| 117 | static GaimCallback get_callback(SignalData *sig_data) | |
| 118 | { | |
| 119 | int i, index = 0; | |
| 120 | ||
| 121 | if (sig_data->ret_value == NULL) | |
| 122 | index = 0; | |
| 123 | else | |
|
11980
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
124 | index = determine_index(gaim_value_get_type(sig_data->ret_value)); |
| 11660 | 125 | |
| 126 | for (i = 0; i < sig_data->num_vals; i++) { | |
| 127 | index += determine_index(gaim_value_get_type(sig_data->values[i])); | |
| 128 | } | |
| 129 | ||
|
11980
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
130 | gaim_debug(GAIM_DEBUG_INFO, "mono", "get_callback index = %d\n", index); |
|
fe5c2c58508c
[gaim-migrate @ 14273]
Eoin Coffey <ecoffey@soc.pidgin.im>
parents:
11952
diff
changeset
|
131 | |
| 11660 | 132 | if (index >= callbacks_array_size || callbacks[index] == NULL) { |
| 133 | gaim_debug(GAIM_DEBUG_ERROR, "mono", "couldn't find a callback function for signal: %s\n", sig_data->signal); | |
| 134 | return NULL; | |
| 135 | } | |
| 136 | ||
| 137 | gaim_debug(GAIM_DEBUG_MISC, "mono", "using callback at index: %d\n", index); | |
| 138 | return GAIM_CALLBACK(callbacks[index]); | |
| 139 | } |