| 69 int i; |
69 int i; |
| 70 int count; |
70 int count; |
| 71 int value_count; |
71 int value_count; |
| 72 GaimValue *ret_value, **values; |
72 GaimValue *ret_value, **values; |
| 73 SV **sv_args; |
73 SV **sv_args; |
| 74 STRLEN na; |
74 void **copy_args; |
| 75 |
75 |
| 76 dSP; |
76 dSP; |
| 77 ENTER; |
77 ENTER; |
| 78 SAVETMPS; |
78 SAVETMPS; |
| 79 PUSHMARK(sp); |
79 PUSHMARK(sp); |
| 80 |
80 |
| 81 gaim_signal_get_values(handler->instance, handler->signal, |
81 gaim_signal_get_values(handler->instance, handler->signal, |
| 82 &ret_value, &value_count, &values); |
82 &ret_value, &value_count, &values); |
| 83 |
83 |
| 84 sv_args = g_new(SV *, value_count); |
84 sv_args = g_new(SV *, value_count); |
| |
85 copy_args = g_new(void *, value_count); |
| 85 |
86 |
| 86 for (i = 0; i < value_count; i++) |
87 for (i = 0; i < value_count; i++) |
| 87 { |
88 { |
| 88 SV *sv = gaim_perl_sv_from_vargs(values[i], args); |
89 sv_args[i] = gaim_perl_sv_from_vargs(values[i], &args, ©_args[i]); |
| 89 |
90 |
| 90 sv_args[i] = sv; |
91 XPUSHs(sv_args[i]); |
| 91 |
|
| 92 XPUSHs(sv); |
|
| 93 } |
92 } |
| 94 |
93 |
| 95 XPUSHs((SV *)handler->data); |
94 XPUSHs((SV *)handler->data); |
| 96 |
95 |
| 97 PUTBACK; |
96 PUTBACK; |
| 103 SPAGAIN; |
102 SPAGAIN; |
| 104 |
103 |
| 105 if (count != 1) |
104 if (count != 1) |
| 106 croak("Uh oh! call_sv returned %i != 1", i); |
105 croak("Uh oh! call_sv returned %i != 1", i); |
| 107 else |
106 else |
| 108 { |
107 ret_val = gaim_perl_data_from_sv(ret_value, POPs); |
| 109 SV *temp_ret_val = POPs; |
|
| 110 |
|
| 111 switch (gaim_value_get_type(ret_value)) |
|
| 112 { |
|
| 113 case GAIM_TYPE_BOOLEAN: |
|
| 114 ret_val = (void *)SvIV(temp_ret_val); |
|
| 115 break; |
|
| 116 |
|
| 117 case GAIM_TYPE_INT: |
|
| 118 ret_val = (void *)SvIV(temp_ret_val); |
|
| 119 break; |
|
| 120 |
|
| 121 case GAIM_TYPE_UINT: |
|
| 122 ret_val = (void *)SvUV(temp_ret_val); |
|
| 123 break; |
|
| 124 |
|
| 125 case GAIM_TYPE_LONG: |
|
| 126 ret_val = (void *)SvIV(temp_ret_val); |
|
| 127 break; |
|
| 128 |
|
| 129 case GAIM_TYPE_ULONG: |
|
| 130 ret_val = (void *)SvUV(temp_ret_val); |
|
| 131 break; |
|
| 132 |
|
| 133 case GAIM_TYPE_INT64: |
|
| 134 ret_val = (void *)SvIV(temp_ret_val); |
|
| 135 break; |
|
| 136 |
|
| 137 case GAIM_TYPE_UINT64: |
|
| 138 ret_val = (void *)SvUV(temp_ret_val); |
|
| 139 break; |
|
| 140 |
|
| 141 case GAIM_TYPE_STRING: |
|
| 142 ret_val = (void *)SvPV(temp_ret_val, na); |
|
| 143 break; |
|
| 144 |
|
| 145 case GAIM_TYPE_POINTER: |
|
| 146 ret_val = (void *)SvIV(temp_ret_val); |
|
| 147 break; |
|
| 148 |
|
| 149 case GAIM_TYPE_BOXED: |
|
| 150 ret_val = (void *)SvIV(temp_ret_val); |
|
| 151 break; |
|
| 152 |
|
| 153 default: |
|
| 154 ret_val = NULL; |
|
| 155 } |
|
| 156 } |
|
| 157 } |
108 } |
| 158 else |
109 else |
| 159 call_sv(handler->callback, G_SCALAR); |
110 call_sv(handler->callback, G_SCALAR); |
| 160 |
111 |
| 161 /* See if any parameters changed. */ |
112 /* See if any parameters changed. */ |
| 162 for (i = 0; i < value_count; i++) |
113 for (i = 0; i < value_count; i++) |
| 163 { |
114 { |
| 164 if (gaim_value_is_outgoing(values[i])) |
115 if (gaim_value_is_outgoing(values[i])) |
| 165 { |
116 { |
| 166 switch (gaim_value_get_type(values[i])) |
117 *((void **)copy_args[i]) = gaim_perl_data_from_sv(values[i], |
| 167 { |
118 sv_args[i]); |
| 168 case GAIM_TYPE_BOOLEAN: |
|
| 169 *va_arg(args, gboolean *) = SvIV(sv_args[i]); |
|
| 170 break; |
|
| 171 |
|
| 172 case GAIM_TYPE_INT: |
|
| 173 *va_arg(args, int *) = SvIV(sv_args[i]); |
|
| 174 break; |
|
| 175 |
|
| 176 case GAIM_TYPE_UINT: |
|
| 177 *va_arg(args, unsigned int *) = SvUV(sv_args[i]); |
|
| 178 break; |
|
| 179 |
|
| 180 case GAIM_TYPE_LONG: |
|
| 181 *va_arg(args, long *) = SvIV(sv_args[i]); |
|
| 182 break; |
|
| 183 |
|
| 184 case GAIM_TYPE_ULONG: |
|
| 185 *va_arg(args, unsigned long *) = SvUV(sv_args[i]); |
|
| 186 break; |
|
| 187 |
|
| 188 case GAIM_TYPE_INT64: |
|
| 189 *va_arg(args, gint64 *) = SvIV(sv_args[i]); |
|
| 190 break; |
|
| 191 |
|
| 192 case GAIM_TYPE_UINT64: |
|
| 193 *va_arg(args, guint64 *) = SvUV(sv_args[i]); |
|
| 194 break; |
|
| 195 |
|
| 196 case GAIM_TYPE_STRING: |
|
| 197 /* XXX Memory leak! */ |
|
| 198 *va_arg(args, char **) = SvPV(sv_args[i], na); |
|
| 199 break; |
|
| 200 |
|
| 201 case GAIM_TYPE_POINTER: |
|
| 202 /* XXX Possible memory leak! */ |
|
| 203 *va_arg(args, void **) = (void *)SvIV(sv_args[i]); |
|
| 204 break; |
|
| 205 |
|
| 206 case GAIM_TYPE_BOXED: |
|
| 207 /* Uh.. I dunno. Try this? Likely won't work. Heh. */ |
|
| 208 /* XXX Possible memory leak! */ |
|
| 209 *va_arg(args, void **) = (void *)SvIV(sv_args[i]); |
|
| 210 break; |
|
| 211 |
|
| 212 default: |
|
| 213 return FALSE; |
|
| 214 } |
|
| 215 } |
119 } |
| 216 } |
120 } |
| 217 |
121 |
| 218 FREETMPS; |
122 FREETMPS; |
| 219 LEAVE; |
123 LEAVE; |
| 220 |
124 |
| 221 g_free(sv_args); |
125 g_free(sv_args); |
| |
126 g_free(copy_args); |
| 222 |
127 |
| 223 gaim_debug_misc("perl", "ret_val = %p\n", ret_val); |
128 gaim_debug_misc("perl", "ret_val = %p\n", ret_val); |
| 224 |
129 |
| 225 return ret_val; |
130 return ret_val; |
| 226 } |
131 } |