Mercurial > pidgin.yaz
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, ©_args[i])); | 241 (va_list*)&args, ©_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 |