comparison src/plugin.c @ 6822:7dba3e17cb21

[gaim-migrate @ 7366] Added plugin IPC. Its use is shown in plugins/ipc-test-server.c and plugins/ipc-test-client.c. committer: Tailor Script <tailor@pidgin.im>
author Christian Hammond <chipx86@chipx86.com>
date Sat, 13 Sep 2003 09:31:03 +0000
parents 1b91cb6be4c3
children abd3c684da31
comparison
equal deleted inserted replaced
6821:636b5215552e 6822:7dba3e17cb21
15 * 15 *
16 * You should have received a copy of the GNU General Public License 16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 19 */
20
21 /*
22 * ----------------
23 * The Plug-in plugin
24 *
25 * Plugin support is currently being maintained by Mike Saraf
26 * msaraf@dwc.edu
27 *
28 * Well, I didn't see any work done on it for a while, so I'm going to try
29 * my hand at it. - Eric warmenhoven@yahoo.com
30 *
31 * Mike is my roomate. I can assure you that he's lazy :-P
32 * -- Rob rob@marko.net
33 *
34 * Yeah, well now I'm re-writing a good portion of it! The perl stuff was
35 * a hack. Tsk tsk! -- Christian <chipx86@gnupdate.org>
36 */
37 #include "internal.h" 20 #include "internal.h"
38 21
39 #include "accountopt.h" 22 #include "accountopt.h"
40 #include "debug.h" 23 #include "debug.h"
41 #include "notify.h" 24 #include "notify.h"
52 #else 35 #else
53 # define PLUGIN_EXT ".so" 36 # define PLUGIN_EXT ".so"
54 #endif 37 #endif
55 #endif 38 #endif
56 39
40 typedef struct
41 {
42 GHashTable *commands;
43 size_t command_count;
44
45 } GaimPluginIpcInfo;
46
47 typedef struct
48 {
49 GaimCallback func;
50 GaimSignalMarshalFunc marshal;
51
52 int num_params;
53 GaimValue **params;
54 GaimValue *ret_value;
55
56 } GaimPluginIpcCommand;
57
57 static GList *loaded_plugins = NULL; 58 static GList *loaded_plugins = NULL;
58 static GList *plugins = NULL; 59 static GList *plugins = NULL;
59 static GList *plugin_loaders = NULL; 60 static GList *plugin_loaders = NULL;
60 static GList *protocol_plugins = NULL; 61 static GList *protocol_plugins = NULL;
61 62
393 if (loader_info->load != NULL) 394 if (loader_info->load != NULL)
394 loader_info->unload(plugin); 395 loader_info->unload(plugin);
395 } 396 }
396 397
397 gaim_signals_disconnect_by_handle(plugin); 398 gaim_signals_disconnect_by_handle(plugin);
399 gaim_plugin_ipc_unregister_all(plugin);
398 400
399 /* TODO */ 401 /* TODO */
400 if (unload_cb != NULL) 402 if (unload_cb != NULL)
401 unload_cb(plugin, unload_cb_data); 403 unload_cb(plugin, unload_cb_data);
402 404
497 g_return_val_if_fail(plugin != NULL, FALSE); 499 g_return_val_if_fail(plugin != NULL, FALSE);
498 500
499 return plugin->loaded; 501 return plugin->loaded;
500 } 502 }
501 503
504 /**************************************************************************
505 * Plugin IPC
506 **************************************************************************/
507 static void
508 destroy_ipc_info(void *data)
509 {
510 GaimPluginIpcCommand *ipc_command = (GaimPluginIpcCommand *)data;
511 int i;
512
513 for (i = 0; i < ipc_command->num_params; i++)
514 gaim_value_destroy(ipc_command->params[i]);
515
516 if (ipc_command->ret_value != NULL)
517 gaim_value_destroy(ipc_command->ret_value);
518
519 g_free(ipc_command);
520 }
521
522 gboolean
523 gaim_plugin_ipc_register(GaimPlugin *plugin, const char *command,
524 GaimCallback func, GaimSignalMarshalFunc marshal,
525 GaimValue *ret_value, int num_params, ...)
526 {
527 GaimPluginIpcInfo *ipc_info;
528 GaimPluginIpcCommand *ipc_command;
529
530 g_return_val_if_fail(plugin != NULL, FALSE);
531 g_return_val_if_fail(command != NULL, FALSE);
532 g_return_val_if_fail(func != NULL, FALSE);
533 g_return_val_if_fail(marshal != NULL, FALSE);
534
535 if (plugin->ipc_data == NULL)
536 {
537 ipc_info = plugin->ipc_data = g_new0(GaimPluginIpcInfo, 1);
538 ipc_info->commands = g_hash_table_new_full(g_str_hash, g_str_equal,
539 g_free, destroy_ipc_info);
540 }
541 else
542 ipc_info = (GaimPluginIpcInfo *)plugin->ipc_data;
543
544 ipc_command = g_new0(GaimPluginIpcCommand, 1);
545 ipc_command->func = func;
546 ipc_command->marshal = marshal;
547 ipc_command->num_params = num_params;
548 ipc_command->ret_value = ret_value;
549
550 if (num_params > 0)
551 {
552 va_list args;
553 int i;
554
555 ipc_command->params = g_new0(GaimValue *, num_params);
556
557 va_start(args, num_params);
558
559 for (i = 0; i < num_params; i++)
560 ipc_command->params[i] = va_arg(args, GaimValue *);
561
562 va_end(args);
563 }
564
565 g_hash_table_replace(ipc_info->commands, g_strdup(command), ipc_command);
566
567 ipc_info->command_count++;
568
569 return TRUE;
570 }
571
572 void
573 gaim_plugin_ipc_unregister(GaimPlugin *plugin, const char *command)
574 {
575 GaimPluginIpcInfo *ipc_info;
576
577 g_return_if_fail(plugin != NULL);
578 g_return_if_fail(command != NULL);
579
580 ipc_info = (GaimPluginIpcInfo *)plugin->ipc_data;
581
582 if (ipc_info == NULL ||
583 g_hash_table_lookup(ipc_info->commands, command) == NULL)
584 {
585 gaim_debug_error("plugins",
586 "IPC command '%s' was not registered for plugin %s\n",
587 command, plugin->info->name);
588 return;
589 }
590
591 g_hash_table_remove(ipc_info->commands, command);
592
593 ipc_info->command_count--;
594
595 if (ipc_info->command_count == 0)
596 {
597 g_hash_table_destroy(ipc_info->commands);
598 g_free(ipc_info);
599
600 plugin->ipc_data = NULL;
601 }
602 }
603
604 void
605 gaim_plugin_ipc_unregister_all(GaimPlugin *plugin)
606 {
607 GaimPluginIpcInfo *ipc_info;
608
609 g_return_if_fail(plugin != NULL);
610
611 if (plugin->ipc_data == NULL)
612 return; /* Silently ignore it. */
613
614 ipc_info = (GaimPluginIpcInfo *)plugin->ipc_data;
615
616 g_hash_table_destroy(ipc_info->commands);
617 g_free(ipc_info);
618
619 plugin->ipc_data = NULL;
620 }
621
622 gboolean
623 gaim_plugin_ipc_get_params(GaimPlugin *plugin, const char *command,
624 GaimValue **ret_value, int *num_params,
625 GaimValue ***params)
626 {
627 GaimPluginIpcInfo *ipc_info;
628 GaimPluginIpcCommand *ipc_command;
629
630 g_return_val_if_fail(plugin != NULL, FALSE);
631 g_return_val_if_fail(command != NULL, FALSE);
632
633 ipc_info = (GaimPluginIpcInfo *)plugin->ipc_data;
634
635 if (ipc_info == NULL ||
636 (ipc_command = g_hash_table_lookup(ipc_info->commands,
637 command)) == NULL)
638 {
639 gaim_debug_error("plugins",
640 "IPC command '%s' was not registered for plugin %s\n",
641 command, plugin->info->name);
642
643 return FALSE;
644 }
645
646 if (num_params != NULL)
647 *num_params = ipc_command->num_params;
648
649 if (params != NULL)
650 *params = ipc_command->params;
651
652 if (ret_value != NULL)
653 *ret_value = ipc_command->ret_value;
654
655 return TRUE;
656 }
657
658 void *
659 gaim_plugin_ipc_call(GaimPlugin *plugin, const char *command,
660 gboolean *ok, ...)
661 {
662 GaimPluginIpcInfo *ipc_info;
663 GaimPluginIpcCommand *ipc_command;
664 va_list args;
665 void *ret_value;
666
667 if (ok != NULL)
668 *ok = FALSE;
669
670 g_return_val_if_fail(plugin != NULL, NULL);
671 g_return_val_if_fail(command != NULL, NULL);
672
673 ipc_info = (GaimPluginIpcInfo *)plugin->ipc_data;
674
675 if (ipc_info == NULL ||
676 (ipc_command = g_hash_table_lookup(ipc_info->commands,
677 command)) == NULL)
678 {
679 gaim_debug_error("plugins",
680 "IPC command '%s' was not registered for plugin %s\n",
681 command, plugin->info->name);
682
683 return NULL;
684 }
685
686 va_start(args, ok);
687 ipc_command->marshal(ipc_command->func, args, NULL, &ret_value);
688 va_end(args);
689
690 if (ok != NULL)
691 *ok = TRUE;
692
693 return ret_value;
694 }
695
696 /**************************************************************************
697 * Plugins subsystem
698 **************************************************************************/
502 void 699 void
503 gaim_plugins_set_search_paths(size_t count, char **paths) 700 gaim_plugins_set_search_paths(size_t count, char **paths)
504 { 701 {
505 size_t s; 702 size_t s;
506 703