comparison plugins/perl/perl-handlers.c @ 12882:e1603fd610fa

[gaim-migrate @ 15234] I give you perl /cmd support. I only tested this a little bit but it seemed to work for me, let me know if anything breaks. committer: Tailor Script <tailor@pidgin.im>
author Etan Reisner <pidgin@unreliablesource.net>
date Sun, 15 Jan 2006 07:56:58 +0000
parents e65a7a7eabaf
children b457aa723bab
comparison
equal deleted inserted replaced
12881:7e45ccd91e58 12882:e1603fd610fa
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 6
7 extern PerlInterpreter *my_perl;
8 static GList *cmd_handlers = NULL;
9 static GList *signal_handlers = NULL;
7 static GList *timeout_handlers = NULL; 10 static GList *timeout_handlers = NULL;
8 static GList *signal_handlers = NULL;
9 extern PerlInterpreter *my_perl;
10 11
11 /* perl < 5.8.0 doesn't define PERL_MAGIC_ext */ 12 /* perl < 5.8.0 doesn't define PERL_MAGIC_ext */
12 #ifndef PERL_MAGIC_ext 13 #ifndef PERL_MAGIC_ext
13 #define PERL_MAGIC_ext '~' 14 #define PERL_MAGIC_ext '~'
14 #endif 15 #endif
439 gaim_perl_signal_clear(void) 440 gaim_perl_signal_clear(void)
440 { 441 {
441 while (signal_handlers != NULL) 442 while (signal_handlers != NULL)
442 destroy_signal_handler(signal_handlers->data); 443 destroy_signal_handler(signal_handlers->data);
443 } 444 }
445
446 static GaimCmdRet
447 perl_cmd_cb(GaimConversation *conv, const gchar *command,
448 gchar **args, gchar **error, void *data)
449 {
450 int i = 0, count, ret_value = GAIM_CMD_RET_OK;
451 SV *cmdSV, *tmpSV, *convSV;
452 GaimPerlCmdHandler *handler = (GaimPerlCmdHandler *)data;
453
454 dSP;
455 ENTER;
456 SAVETMPS;
457 PUSHMARK(SP);
458
459 /* Push the conversation onto the perl stack */
460 convSV = sv_2mortal(gaim_perl_bless_object(conv, "Gaim::Conversation"));
461 XPUSHs(convSV);
462
463 /* Push the command string onto the perl stack */
464 cmdSV = newSVpv(command, 0);
465 cmdSV = sv_2mortal(cmdSV);
466 XPUSHs(cmdSV);
467
468 /* Push the data onto the perl stack */
469 XPUSHs((SV *)handler->data);
470
471 /* Push any arguments we may have */
472 for (i = 0; args[i] != NULL; i++) {
473 /* XXX The mortality of these created SV's should prevent
474 * memory issues, if I read/understood everything correctly...
475 */
476 tmpSV = newSVpv(args[i], 0);
477 tmpSV = sv_2mortal(tmpSV);
478 XPUSHs(tmpSV);
479 }
480
481 PUTBACK;
482 count = call_sv(handler->callback, G_EVAL|G_SCALAR);
483
484 if (count != 1)
485 croak("call_sv: Did not return the correct number of values.\n");
486
487 SPAGAIN;
488
489 ret_value = POPi;
490
491 PUTBACK;
492 FREETMPS;
493 LEAVE;
494
495 return ret_value;
496 }
497
498 GaimCmdId
499 gaim_perl_cmd_register(GaimPlugin *plugin, const gchar *command,
500 const gchar *args, GaimCmdPriority priority,
501 GaimCmdFlag flag, const gchar *prpl_id, SV *callback,
502 const gchar *helpstr, SV *data)
503 {
504 GaimPerlCmdHandler *handler;
505
506 handler = g_new0(GaimPerlCmdHandler, 1);
507 handler->plugin = plugin;
508 handler->cmd = g_strdup(command);
509 handler->prpl_id = g_strdup(prpl_id);
510
511 if (callback != NULL && callback != &PL_sv_undef)
512 handler->callback = newSVsv(callback);
513 else
514 handler->callback = NULL;
515
516 if (data != NULL && data != &PL_sv_undef)
517 handler->data = newSVsv(data);
518 else
519 handler->data = NULL;
520
521 cmd_handlers = g_list_append(cmd_handlers, handler);
522
523 handler->id = gaim_cmd_register(command, args, priority, flag, prpl_id,
524 GAIM_CMD_FUNC(perl_cmd_cb), helpstr,
525 handler);
526
527 return handler->id;
528 }
529
530 static void
531 destroy_cmd_handler(GaimPerlCmdHandler *handler)
532 {
533 cmd_handlers = g_list_remove(cmd_handlers, handler);
534
535 if (handler->callback != NULL)
536 SvREFCNT_dec(handler->callback);
537
538 if (handler->data != NULL)
539 SvREFCNT_dec(handler->data);
540
541 g_free(handler->cmd);
542 g_free(handler->prpl_id);
543 g_free(handler);
544 }
545
546 void
547 gaim_perl_cmd_clear_for_plugin(GaimPlugin *plugin)
548 {
549 GList *l, *l_next;
550
551 for (l = cmd_handlers; l != NULL; l = l_next) {
552 GaimPerlCmdHandler *handler = (GaimPerlCmdHandler *)l->data;
553
554 l_next = l->next;
555
556 if (handler->plugin == plugin)
557 destroy_cmd_handler(handler);
558 }
559 }
560
561 static GaimPerlCmdHandler *
562 find_cmd_handler(GaimCmdId id)
563 {
564 GList *l;
565
566 for (l = cmd_handlers; l != NULL; l = l->next) {
567 GaimPerlCmdHandler *handler = (GaimPerlCmdHandler *)l->data;
568
569 if (handler->id == id)
570 return handler;
571 }
572
573 return NULL;
574 }
575
576 void
577 gaim_perl_cmd_unregister(GaimCmdId id)
578 {
579 GaimPerlCmdHandler *handler;
580
581 handler = find_cmd_handler(id);
582
583 if (handler == NULL) {
584 croak("Invalid command id in removing a perl command handler.\n");
585 return;
586 }
587
588 gaim_cmd_unregister(id);
589 destroy_cmd_handler(handler);
590 }