comparison plugins/perl/perl-handlers.c @ 12803:050b29b7232a

[gaim-migrate @ 15150] More whitespace stuff. committer: Tailor Script <tailor@pidgin.im>
author Etan Reisner <pidgin@unreliablesource.net>
date Tue, 10 Jan 2006 05:09:17 +0000
parents f8e22fef03fc
children 86d67bd4ef24
comparison
equal deleted inserted replaced
12802:26b31b4c43a2 12803:050b29b7232a
1 #include "perl-common.h" 1 #include "perl-common.h"
2 #include "perl-handlers.h" 2 #include "perl-handlers.h"
3 3
4 #include "debug.h" 4 #include "debug.h"
5 #include "signals.h" 5 #include "signals.h"
6
7 6
8 static GList *timeout_handlers = NULL; 7 static GList *timeout_handlers = NULL;
9 static GList *signal_handlers = NULL; 8 static GList *signal_handlers = NULL;
10 static char *perl_plugin_pref_cb; 9 static char *perl_plugin_pref_cb;
11 static char *perl_gtk_plugin_pref_cb; 10 static char *perl_gtk_plugin_pref_cb;
15 #ifndef PERL_MAGIC_ext 14 #ifndef PERL_MAGIC_ext
16 #define PERL_MAGIC_ext '~' 15 #define PERL_MAGIC_ext '~'
17 #endif 16 #endif
18 17
19 /* For now a plugin can only have one action */ 18 /* For now a plugin can only have one action */
20 void gaim_perl_plugin_action_cb(GaimPluginAction * gpa) { 19 void
21 20 gaim_perl_plugin_action_cb(GaimPluginAction * gpa)
22 dSP; 21 {
23 ENTER; 22 dSP;
24 SAVETMPS; 23 ENTER;
25 PUSHMARK(sp); 24 SAVETMPS;
26 25 PUSHMARK(sp);
27 /* We put the plugin handle on the stack so it can pass it along */ 26
28 /* to anythng called from the callback. It is supposed to pass */ 27 /* We put the plugin handle on the stack so it can pass it along */
29 /* the Action, but there is no way to access the plugin handle from */ 28 /* to anything called from the callback. It is supposed to pass */
30 /* the GaimPluginAction in perl...yet. */ 29 /* the Action, but there is no way to access the plugin handle from */
30 /* the GaimPluginAction in perl...yet. */
31 31
32 XPUSHs(gaim_perl_bless_object(gpa->plugin, "Gaim::Plugin")); 32 XPUSHs(gaim_perl_bless_object(gpa->plugin, "Gaim::Plugin"));
33 PUTBACK; 33 PUTBACK;
34 34
35 /* gaim_perl_plugin_action_callback_sub defined in the header is set */ 35 /* gaim_perl_plugin_action_callback_sub defined in the header is set
36 /* in perl.c during plugin probe by a PLUGIN_INFO hash value limiting */ 36 * in perl.c during plugin probe by a PLUGIN_INFO hash value limiting
37 /* us to only one action for right now even though the action member of */ 37 * us to only one action for right now even though the action member
38 /* GaimPluginInfo can take (does take) a GList. */ 38 * of GaimPluginInfo can take (does take) a GList. */
39 call_pv(gaim_perl_plugin_action_callback_sub, G_EVAL | G_SCALAR); 39 call_pv(gaim_perl_plugin_action_callback_sub, G_EVAL | G_SCALAR);
40 SPAGAIN; 40 SPAGAIN;
41 41
42 PUTBACK; 42 PUTBACK;
43 FREETMPS; 43 FREETMPS;
44 LEAVE; 44 LEAVE;
45 } 45 }
46 46
47 GList *gaim_perl_plugin_action(GaimPlugin *plugin, gpointer context) { 47 GList *
48 GaimPluginAction *act = NULL; 48 gaim_perl_plugin_action(GaimPlugin *plugin, gpointer context)
49 GList *gl = NULL; 49 {
50 50 GaimPluginAction *act = NULL;
51 /* TODO: Fix the way we create action handlers so we can have mroe than */ 51 GList *gl = NULL;
52 /* one action in perl. Maybe there is a clever work around, but so far */ 52
53 /* I have not figured it out. There is no way to tie the perl sub's */ 53 /* TODO: Fix the way we create action handlers so we can have more
54 /* name to the callback function without these global variables and */ 54 * than one action in perl. Maybe there is a clever work around, but
55 /* there is no way to create a callback on the fly so each would have */ 55 * so far I have not figured it out. There is no way to tie the perl
56 /* to be hardcoded--more than one would just be arbitrary. */ 56 * sub's name to the callback function without these global variables
57 act = gaim_plugin_action_new(gaim_perl_plugin_action_label, gaim_perl_plugin_action_cb); 57 * and there is no way to create a callback on the fly so each would
58 gl = g_list_append(gl, act); 58 * have to be hardcoded--more than one would just be arbitrary. */
59 59 act = gaim_plugin_action_new(gaim_perl_plugin_action_label,
60 return gl; 60 gaim_perl_plugin_action_cb);
61 } 61 gl = g_list_append(gl, act);
62 62
63 63 return gl;
64 GaimGtkPluginUiInfo *gaim_perl_gtk_plugin_pref(const char * frame_cb) { 64 }
65 65
66
67 GaimGtkPluginUiInfo *
68 gaim_perl_gtk_plugin_pref(const char * frame_cb)
69 {
66 GaimGtkPluginUiInfo *ui_info; 70 GaimGtkPluginUiInfo *ui_info;
67 71
68 ui_info = g_new0(GaimGtkPluginUiInfo, 1); 72 ui_info = g_new0(GaimGtkPluginUiInfo, 1);
69 perl_gtk_plugin_pref_cb = g_strdup(frame_cb); 73 perl_gtk_plugin_pref_cb = g_strdup(frame_cb);
70 ui_info->get_config_frame = gaim_perl_gtk_get_plugin_frame; 74 ui_info->get_config_frame = gaim_perl_gtk_get_plugin_frame;
71 75
72 return ui_info; 76 return ui_info;
73 } 77 }
74 78
75 GtkWidget *gaim_perl_gtk_get_plugin_frame(GaimPlugin *plugin) { 79 GtkWidget *
76 80 gaim_perl_gtk_get_plugin_frame(GaimPlugin *plugin)
81 {
77 SV * sv; 82 SV * sv;
78 GtkWidget *ret; 83 GtkWidget *ret;
79 MAGIC *mg; 84 MAGIC *mg;
80 dSP; 85 dSP;
81 int count; 86 int count;
84 SAVETMPS; 89 SAVETMPS;
85 90
86 count = call_pv(perl_gtk_plugin_pref_cb, G_SCALAR | G_NOARGS); 91 count = call_pv(perl_gtk_plugin_pref_cb, G_SCALAR | G_NOARGS);
87 if (count != 1) 92 if (count != 1)
88 croak("call_pv: Did not return the correct number of values.\n"); 93 croak("call_pv: Did not return the correct number of values.\n");
89 94
90 /* the frame was created in a perl sub and is returned */ 95 /* the frame was created in a perl sub and is returned */
91 SPAGAIN; 96 SPAGAIN;
92 97
93 /* We have a Gtk2::Frame on top of the stack */ 98 /* We have a Gtk2::Frame on top of the stack */
94 sv = POPs; 99 sv = POPs;
95 100
96 /* The magic field hides the pointer to the actuale GtkWidget */ 101 /* The magic field hides the pointer to the actuale GtkWidget */
97 mg = mg_find(SvRV(sv), PERL_MAGIC_ext); 102 mg = mg_find(SvRV(sv), PERL_MAGIC_ext);
98 ret = (GtkWidget *)mg->mg_ptr; 103 ret = (GtkWidget *)mg->mg_ptr;
99 104
100 PUTBACK; 105 PUTBACK;
101 FREETMPS; 106 FREETMPS;
102 LEAVE; 107 LEAVE;
103 108
104 return ret; 109 return ret;
105 } 110 }
106 111
107 112 /* Called to create a pointer to GaimPluginUiInfo for the GaimPluginInfo */
108 113 /* It will then in turn create ui_info with the C function pointer */
109 114 /* that will eventually do a call_pv to call a perl functions so users */
110 /* Called to create a pointer to GaimPluginUiInfo for the GaimPluginInfo */ 115 /* can create their own frames in the prefs */
111 /* It will then inturn create ui_info with the C function pointer */ 116 GaimPluginUiInfo *
112 /* that will eventually do a call_pv to call a perl functions so users */ 117 gaim_perl_plugin_pref(const char * frame_cb)
113 /* can create their own frames in the prefs */ 118 {
114 GaimPluginUiInfo *gaim_perl_plugin_pref(const char * frame_cb) {
115 GaimPluginUiInfo *ui_info; 119 GaimPluginUiInfo *ui_info;
116 120
117 ui_info = g_new0(GaimPluginUiInfo, 1); 121 ui_info = g_new0(GaimPluginUiInfo, 1);
118 perl_plugin_pref_cb = g_strdup(frame_cb); 122 perl_plugin_pref_cb = g_strdup(frame_cb);
119 ui_info->get_plugin_pref_frame = gaim_perl_get_plugin_frame; 123 ui_info->get_plugin_pref_frame = gaim_perl_get_plugin_frame;
120 124
121 return ui_info; 125 return ui_info;
122 } 126 }
123 127
124 GaimPluginPrefFrame *gaim_perl_get_plugin_frame(GaimPlugin *plugin) { 128 GaimPluginPrefFrame *
125 /* Sets up the Perl Stack for our call back into the script to run the */ 129 gaim_perl_get_plugin_frame(GaimPlugin *plugin)
126 /* plugin_pref... sub */ 130 {
131 /* Sets up the Perl Stack for our call back into the script to run the
132 * plugin_pref... sub */
127 GaimPluginPrefFrame *ret_frame; 133 GaimPluginPrefFrame *ret_frame;
128 dSP; 134 dSP;
129 int count; 135 int count;
130 136
131 ENTER; 137 ENTER;
132 SAVETMPS; 138 SAVETMPS;
133 /* Some perl magic to run perl_plugin_pref_frame_SV perl sub and return */ 139 /* Some perl magic to run perl_plugin_pref_frame_SV perl sub and
134 /* the frame */ 140 * return the frame */
135 PUSHMARK(SP); 141 PUSHMARK(SP);
136 PUTBACK; 142 PUTBACK;
137 143
138 count = call_pv(perl_plugin_pref_cb, G_SCALAR | G_NOARGS); 144 count = call_pv(perl_plugin_pref_cb, G_SCALAR | G_NOARGS);
139 145
228 &ret_value, &value_count, &values); 234 &ret_value, &value_count, &values);
229 235
230 sv_args = g_new(SV *, value_count); 236 sv_args = g_new(SV *, value_count);
231 copy_args = g_new(void **, value_count); 237 copy_args = g_new(void **, value_count);
232 238
233 for (i = 0; i < value_count; i++) 239 for (i = 0; i < value_count; i++) {
234 {
235 sv_args[i] = sv_2mortal(gaim_perl_sv_from_vargs(values[i], 240 sv_args[i] = sv_2mortal(gaim_perl_sv_from_vargs(values[i],
236 (va_list*)&args, &copy_args[i])); 241 (va_list*)&args, &copy_args[i]));
237 242
238 XPUSHs(sv_args[i]); 243 XPUSHs(sv_args[i]);
239 } 244 }
240 245
241 XPUSHs((SV *)handler->data); 246 XPUSHs((SV *)handler->data);
242 247
243 PUTBACK; 248 PUTBACK;
244 249
245 if (ret_value != NULL) 250 if (ret_value != NULL) {
246 {
247 count = call_sv(handler->callback, G_EVAL | G_SCALAR); 251 count = call_sv(handler->callback, G_EVAL | G_SCALAR);
248 252
249 SPAGAIN; 253 SPAGAIN;
250 254
251 if (count != 1) 255 if (count != 1)
252 croak("Uh oh! call_sv returned %i != 1", i); 256 croak("Uh oh! call_sv returned %i != 1", i);
253 else 257 else
254 ret_val = gaim_perl_data_from_sv(ret_value, POPs); 258 ret_val = gaim_perl_data_from_sv(ret_value, POPs);
255 } 259 } else {
256 else
257 {
258 call_sv(handler->callback, G_SCALAR); 260 call_sv(handler->callback, G_SCALAR);
259 261
260 SPAGAIN; 262 SPAGAIN;
261 } 263 }
262 264
263 if (SvTRUE(ERRSV)) 265 if (SvTRUE(ERRSV)) {
264 { 266 gaim_debug_error("perl",
265 gaim_debug_error("perl", "Perl function exited abnormally: %s\n", 267 "Perl function exited abnormally: %s\n",
266 SvPV(ERRSV, na)); 268 SvPV(ERRSV, na));
267 } 269 }
268 270
269 /* See if any parameters changed. */ 271 /* See if any parameters changed. */
270 for (i = 0; i < value_count; i++) 272 for (i = 0; i < value_count; i++) {
271 { 273 if (gaim_value_is_outgoing(values[i])) {
272 if (gaim_value_is_outgoing(values[i])) 274 switch (gaim_value_get_type(values[i])) {
273 {
274 switch (gaim_value_get_type(values[i]))
275 {
276 case GAIM_TYPE_BOOLEAN: 275 case GAIM_TYPE_BOOLEAN:
277 *((gboolean *)copy_args[i]) = SvIV(sv_args[i]); 276 *((gboolean *)copy_args[i]) = SvIV(sv_args[i]);
278 break; 277 break;
279 278
280 case GAIM_TYPE_INT: 279 case GAIM_TYPE_INT:
300 case GAIM_TYPE_UINT64: 299 case GAIM_TYPE_UINT64:
301 *((guint64 *)copy_args[i]) = SvUV(sv_args[i]); 300 *((guint64 *)copy_args[i]) = SvUV(sv_args[i]);
302 break; 301 break;
303 302
304 case GAIM_TYPE_STRING: 303 case GAIM_TYPE_STRING:
305 if (strcmp(*((char **)copy_args[i]), SvPVX(sv_args[i]))) 304 if (strcmp(*((char **)copy_args[i]), SvPVX(sv_args[i]))) {
306 {
307 g_free(*((char **)copy_args[i])); 305 g_free(*((char **)copy_args[i]));
308 *((char **)copy_args[i]) = 306 *((char **)copy_args[i]) =
309 g_strdup(SvPV(sv_args[i], na)); 307 g_strdup(SvPV(sv_args[i], na));
310 } 308 }
311 break; 309 break;
345 find_signal_handler(GaimPlugin *plugin, void *instance, const char *signal) 343 find_signal_handler(GaimPlugin *plugin, void *instance, const char *signal)
346 { 344 {
347 GaimPerlSignalHandler *handler; 345 GaimPerlSignalHandler *handler;
348 GList *l; 346 GList *l;
349 347
350 for (l = signal_handlers; l != NULL; l = l->next) 348 for (l = signal_handlers; l != NULL; l = l->next) {
351 {
352 handler = (GaimPerlSignalHandler *)l->data; 349 handler = (GaimPerlSignalHandler *)l->data;
353 350
354 if (handler->plugin == plugin && 351 if (handler->plugin == plugin &&
355 handler->instance == instance && 352 handler->instance == instance &&
356 !strcmp(handler->signal, signal)) 353 !strcmp(handler->signal, signal)) {
357 {
358 return handler; 354 return handler;
359 } 355 }
360 } 356 }
361 357
362 return NULL; 358 return NULL;
365 void 361 void
366 gaim_perl_timeout_add(GaimPlugin *plugin, int seconds, SV *callback, SV *data) 362 gaim_perl_timeout_add(GaimPlugin *plugin, int seconds, SV *callback, SV *data)
367 { 363 {
368 GaimPerlTimeoutHandler *handler; 364 GaimPerlTimeoutHandler *handler;
369 365
370 if (plugin == NULL) 366 if (plugin == NULL) {
371 {
372 croak("Invalid handle in adding perl timeout handler.\n"); 367 croak("Invalid handle in adding perl timeout handler.\n");
373 return; 368 return;
374 } 369 }
375 370
376 handler = g_new0(GaimPerlTimeoutHandler, 1); 371 handler = g_new0(GaimPerlTimeoutHandler, 1);
390 gaim_perl_timeout_clear_for_plugin(GaimPlugin *plugin) 385 gaim_perl_timeout_clear_for_plugin(GaimPlugin *plugin)
391 { 386 {
392 GaimPerlTimeoutHandler *handler; 387 GaimPerlTimeoutHandler *handler;
393 GList *l, *l_next; 388 GList *l, *l_next;
394 389
395 for (l = timeout_handlers; l != NULL; l = l_next) 390 for (l = timeout_handlers; l != NULL; l = l_next) {
396 {
397 l_next = l->next; 391 l_next = l->next;
398 392
399 handler = (GaimPerlTimeoutHandler *)l->data; 393 handler = (GaimPerlTimeoutHandler *)l->data;
400 394
401 if (handler->plugin == plugin) 395 if (handler->plugin == plugin)
410 destroy_timeout_handler(timeout_handlers->data); 404 destroy_timeout_handler(timeout_handlers->data);
411 } 405 }
412 406
413 void 407 void
414 gaim_perl_signal_connect(GaimPlugin *plugin, void *instance, 408 gaim_perl_signal_connect(GaimPlugin *plugin, void *instance,
415 const char *signal, SV *callback, SV *data) 409 const char *signal, SV *callback, SV *data)
416 { 410 {
417 GaimPerlSignalHandler *handler; 411 GaimPerlSignalHandler *handler;
418 412
419 handler = g_new0(GaimPerlSignalHandler, 1); 413 handler = g_new0(GaimPerlSignalHandler, 1);
420 handler->plugin = plugin; 414 handler->plugin = plugin;
421 handler->instance = instance; 415 handler->instance = instance;
422 handler->signal = g_strdup(signal); 416 handler->signal = g_strdup(signal);
423 handler->callback = (callback != NULL && callback != &PL_sv_undef 417 handler->callback = (callback != NULL &&
424 ? newSVsv(callback) : NULL); 418 callback != &PL_sv_undef ? newSVsv(callback)
425 handler->data = (data != NULL && data != &PL_sv_undef 419 : NULL);
426 ? newSVsv(data) : NULL); 420 handler->data = (data != NULL &&
421 data != &PL_sv_undef ? newSVsv(data) : NULL);
427 422
428 signal_handlers = g_list_append(signal_handlers, handler); 423 signal_handlers = g_list_append(signal_handlers, handler);
429 424
430 gaim_signal_connect_vargs(instance, signal, 425 gaim_signal_connect_vargs(instance, signal, plugin,
431 plugin, GAIM_CALLBACK(perl_signal_cb), handler); 426 GAIM_CALLBACK(perl_signal_cb), handler);
432 } 427 }
433 428
434 void 429 void
435 gaim_perl_signal_disconnect(GaimPlugin *plugin, void *instance, 430 gaim_perl_signal_disconnect(GaimPlugin *plugin, void *instance,
436 const char *signal) 431 const char *signal)
437 { 432 {
438 GaimPerlSignalHandler *handler; 433 GaimPerlSignalHandler *handler;
439 434
440 handler = find_signal_handler(plugin, instance, signal); 435 handler = find_signal_handler(plugin, instance, signal);
441 436
442 if (handler == NULL) 437 if (handler == NULL) {
443 {
444 croak("Invalid signal handler information in " 438 croak("Invalid signal handler information in "
445 "disconnecting a perl signal handler.\n"); 439 "disconnecting a perl signal handler.\n");
446 return; 440 return;
447 } 441 }
448 442
449 destroy_signal_handler(handler); 443 destroy_signal_handler(handler);
450 } 444 }
453 gaim_perl_signal_clear_for_plugin(GaimPlugin *plugin) 447 gaim_perl_signal_clear_for_plugin(GaimPlugin *plugin)
454 { 448 {
455 GaimPerlSignalHandler *handler; 449 GaimPerlSignalHandler *handler;
456 GList *l, *l_next; 450 GList *l, *l_next;
457 451
458 for (l = signal_handlers; l != NULL; l = l_next) 452 for (l = signal_handlers; l != NULL; l = l_next) {
459 {
460 l_next = l->next; 453 l_next = l->next;
461 454
462 handler = (GaimPerlSignalHandler *)l->data; 455 handler = (GaimPerlSignalHandler *)l->data;
463 456
464 if (handler->plugin == plugin) 457 if (handler->plugin == plugin)
470 gaim_perl_signal_clear(void) 463 gaim_perl_signal_clear(void)
471 { 464 {
472 while (signal_handlers != NULL) 465 while (signal_handlers != NULL)
473 destroy_signal_handler(signal_handlers->data); 466 destroy_signal_handler(signal_handlers->data);
474 } 467 }
475