Mercurial > pidgin.yaz
annotate plugins/mono/loader/signal-glue.c @ 12687:88ccc3603163
[gaim-migrate @ 15030]
I'm a stickler for getting rid of these crazy little things.
A stickler to the last.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Tue, 03 Jan 2006 01:19:32 +0000 |
parents | 67fbd2ff4c4e |
children |
rev | line source |
---|---|
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
67fbd2ff4c4e
[gaim-migrate @ 14273]
Gary Kramlich <grim@reaperworld.com>
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
67fbd2ff4c4e
[gaim-migrate @ 14273]
Gary Kramlich <grim@reaperworld.com>
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
67fbd2ff4c4e
[gaim-migrate @ 14273]
Gary Kramlich <grim@reaperworld.com>
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
67fbd2ff4c4e
[gaim-migrate @ 14273]
Gary Kramlich <grim@reaperworld.com>
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
67fbd2ff4c4e
[gaim-migrate @ 14273]
Gary Kramlich <grim@reaperworld.com>
parents:
11952
diff
changeset
|
53 dispatch_callback((SignalData*)data, ((SignalData*)data)->num_vals, arg1); |
11660 | 54 } |
55 | |
11980
67fbd2ff4c4e
[gaim-migrate @ 14273]
Gary Kramlich <grim@reaperworld.com>
parents:
11952
diff
changeset
|
56 static void cb_void__pointer_pointer_pointer(void *arg1, void *arg2, void *arg3, void *data) |
67fbd2ff4c4e
[gaim-migrate @ 14273]
Gary Kramlich <grim@reaperworld.com>
parents:
11952
diff
changeset
|
57 { |
67fbd2ff4c4e
[gaim-migrate @ 14273]
Gary Kramlich <grim@reaperworld.com>
parents:
11952
diff
changeset
|
58 dispatch_callback((SignalData*)data, ((SignalData*)data)->num_vals, arg1, arg2, arg3); |
67fbd2ff4c4e
[gaim-migrate @ 14273]
Gary Kramlich <grim@reaperworld.com>
parents:
11952
diff
changeset
|
59 } |
67fbd2ff4c4e
[gaim-migrate @ 14273]
Gary Kramlich <grim@reaperworld.com>
parents:
11952
diff
changeset
|
60 |
67fbd2ff4c4e
[gaim-migrate @ 14273]
Gary Kramlich <grim@reaperworld.com>
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
67fbd2ff4c4e
[gaim-migrate @ 14273]
Gary Kramlich <grim@reaperworld.com>
parents:
11952
diff
changeset
|
67 GaimMonoPlugin *mplug; |
67fbd2ff4c4e
[gaim-migrate @ 14273]
Gary Kramlich <grim@reaperworld.com>
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
67fbd2ff4c4e
[gaim-migrate @ 14273]
Gary Kramlich <grim@reaperworld.com>
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
67fbd2ff4c4e
[gaim-migrate @ 14273]
Gary Kramlich <grim@reaperworld.com>
parents:
11952
diff
changeset
|
81 |
67fbd2ff4c4e
[gaim-migrate @ 14273]
Gary Kramlich <grim@reaperworld.com>
parents:
11952
diff
changeset
|
82 klass = mono_object_get_class(plugin); |
67fbd2ff4c4e
[gaim-migrate @ 14273]
Gary Kramlich <grim@reaperworld.com>
parents:
11952
diff
changeset
|
83 |
67fbd2ff4c4e
[gaim-migrate @ 14273]
Gary Kramlich <grim@reaperworld.com>
parents:
11952
diff
changeset
|
84 mplug = ml_find_plugin_by_class(klass); |
67fbd2ff4c4e
[gaim-migrate @ 14273]
Gary Kramlich <grim@reaperworld.com>
parents:
11952
diff
changeset
|
85 |
67fbd2ff4c4e
[gaim-migrate @ 14273]
Gary Kramlich <grim@reaperworld.com>
parents:
11952
diff
changeset
|
86 mplug->signal_data = g_list_append(mplug->signal_data, (gpointer)sig_data); |
11660 | 87 |
11980
67fbd2ff4c4e
[gaim-migrate @ 14273]
Gary Kramlich <grim@reaperworld.com>
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
67fbd2ff4c4e
[gaim-migrate @ 14273]
Gary Kramlich <grim@reaperworld.com>
parents:
11952
diff
changeset
|
110 NULL, |
67fbd2ff4c4e
[gaim-migrate @ 14273]
Gary Kramlich <grim@reaperworld.com>
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
67fbd2ff4c4e
[gaim-migrate @ 14273]
Gary Kramlich <grim@reaperworld.com>
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
67fbd2ff4c4e
[gaim-migrate @ 14273]
Gary Kramlich <grim@reaperworld.com>
parents:
11952
diff
changeset
|
130 gaim_debug(GAIM_DEBUG_INFO, "mono", "get_callback index = %d\n", index); |
67fbd2ff4c4e
[gaim-migrate @ 14273]
Gary Kramlich <grim@reaperworld.com>
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 } |