comparison src/audacious/pluginenum.c @ 4266:2b7a74fce100

Implemented support for multiple subplugins inside a plugin (see bug #148) and PluginHeader finalization
author stefano@zanga
date Sun, 10 Feb 2008 12:31:44 +0100
parents b3830c28397e
children cfd60a10a6e2
comparison
equal deleted inserted replaced
4265:7410b81a3362 4266:2b7a74fce100
68 NULL 68 NULL
69 }; 69 };
70 70
71 GHashTable *ext_hash = NULL; 71 GHashTable *ext_hash = NULL;
72 72
73 static void set_pvt_data(Plugin * plugin, gpointer data);
74 static gpointer get_pvt_data(void);
75
73 /*****************************************************************/ 76 /*****************************************************************/
74 77
75 static struct _AudaciousFuncTableV1 _aud_papi_v1 = { 78 static struct _AudaciousFuncTableV1 _aud_papi_v1 = {
76 .vfs_fopen = vfs_fopen, 79 .vfs_fopen = vfs_fopen,
77 .vfs_fclose = vfs_fclose, 80 .vfs_fclose = vfs_fclose,
390 .input_get_volume = input_get_volume, 393 .input_get_volume = input_get_volume,
391 .construct_uri = construct_uri, 394 .construct_uri = construct_uri,
392 .uri_to_display_basename = uri_to_display_basename, 395 .uri_to_display_basename = uri_to_display_basename,
393 .uri_to_display_dirname = uri_to_display_dirname, 396 .uri_to_display_dirname = uri_to_display_dirname,
394 397
398 .get_pvt_data = get_pvt_data,
399 .set_pvt_data = set_pvt_data,
400
395 }; 401 };
396 402
397 /*****************************************************************/ 403 /*****************************************************************/
398 404
399 GList *lowlevel_list = NULL; 405 GList *lowlevel_list = NULL;
400 extern GList *vfs_transports; 406 extern GList *vfs_transports;
401 407
402 mowgli_dictionary_t *plugin_dict = NULL; 408 mowgli_dictionary_t *plugin_dict = NULL;
409
410 static GStaticPrivate cur_plugin_key = G_STATIC_PRIVATE_INIT;
411 static mowgli_dictionary_t *pvt_data_dict = NULL;
412
413 static mowgli_list_t *headers_list = NULL;
414
415 void plugin_set_current(Plugin *plugin)
416 {
417 g_static_private_set(&cur_plugin_key, plugin, NULL);
418 }
419
420 static Plugin *plugin_get_current(void)
421 {
422 return g_static_private_get(&cur_plugin_key);
423 }
424
425 static void set_pvt_data(Plugin * plugin, gpointer data)
426 {
427 mowgli_dictionary_elem_t *elem;
428
429 elem = mowgli_dictionary_find(pvt_data_dict, g_basename(plugin->filename));
430 if (elem == NULL)
431 mowgli_dictionary_add(pvt_data_dict, g_basename(plugin->filename), data);
432 else
433 elem->data = data;
434 }
435
436 static gpointer get_pvt_data(void)
437 {
438 Plugin *cur_p = plugin_get_current();
439
440 return mowgli_dictionary_retrieve(pvt_data_dict, g_basename(cur_p->filename));
441 }
403 442
404 static gint 443 static gint
405 inputlist_compare_func(gconstpointer a, gconstpointer b) 444 inputlist_compare_func(gconstpointer a, gconstpointer b)
406 { 445 {
407 const InputPlugin *ap = a, *bp = b; 446 const InputPlugin *ap = a, *bp = b;
609 } 648 }
610 649
611 void 650 void
612 plugin2_process(PluginHeader *header, GModule *module, const gchar *filename) 651 plugin2_process(PluginHeader *header, GModule *module, const gchar *filename)
613 { 652 {
614 InputPlugin **ip_iter; 653 int i;
615 OutputPlugin **op_iter; 654 mowgli_node_t *hlist_node;
616 EffectPlugin **ep_iter;
617 GeneralPlugin **gp_iter;
618 VisPlugin **vp_iter;
619 DiscoveryPlugin **dp_iter;
620 655
621 if (header->magic != PLUGIN_MAGIC) 656 if (header->magic != PLUGIN_MAGIC)
622 return plugin2_dispose(module, "plugin <%s> discarded, invalid module magic", filename); 657 return plugin2_dispose(module, "plugin <%s> discarded, invalid module magic", filename);
623 658
624 if (header->api_version != __AUDACIOUS_PLUGIN_API__) 659 if (header->api_version != __AUDACIOUS_PLUGIN_API__)
625 return plugin2_dispose(module, "plugin <%s> discarded, wanting API version %d, we implement API version %d", 660 return plugin2_dispose(module, "plugin <%s> discarded, wanting API version %d, we implement API version %d",
626 filename, header->api_version, __AUDACIOUS_PLUGIN_API__); 661 filename, header->api_version, __AUDACIOUS_PLUGIN_API__);
627 662
663 hlist_node = mowgli_node_create();
664 mowgli_node_add(header, hlist_node, headers_list);
665
628 if (header->init) 666 if (header->init)
629 header->init(); 667 header->init();
630 668
631 header->priv_assoc = g_new0(Plugin, 1); 669 header->priv_assoc = g_new0(Plugin, 1);
632 header->priv_assoc->handle = module; 670 header->priv_assoc->handle = module;
633 header->priv_assoc->filename = g_strdup(filename); 671 header->priv_assoc->filename = g_strdup(filename);
634 672
673 i = 0;
674
635 if (header->ip_list) 675 if (header->ip_list)
636 { 676 {
637 for (ip_iter = header->ip_list; *ip_iter != NULL; ip_iter++) 677 for (; (header->ip_list)[i] != NULL; i++)
638 { 678 {
639 PLUGIN(*ip_iter)->filename = g_strdup(filename); 679 PLUGIN((header->ip_list)[i])->filename = g_strdup_printf("%s (#%d)", filename, i);
640 input_plugin_init(PLUGIN(*ip_iter)); 680 input_plugin_init(PLUGIN((header->ip_list)[i]));
641 } 681 }
642 } 682 }
643 683
644 if (header->op_list) 684 if (header->op_list)
645 { 685 {
646 for (op_iter = header->op_list; *op_iter != NULL; op_iter++) 686 for (; (header->op_list)[i] != NULL; i++)
647 { 687 {
648 PLUGIN(*op_iter)->filename = g_strdup(filename); 688 PLUGIN((header->op_list)[i])->filename = g_strdup_printf("%s (#%d)", filename, i);
649 output_plugin_init(PLUGIN(*op_iter)); 689 output_plugin_init(PLUGIN((header->op_list)[i]));
650 } 690 }
651 } 691 }
652 692
653 if (header->ep_list) 693 if (header->ep_list)
654 { 694 {
655 for (ep_iter = header->ep_list; *ep_iter != NULL; ep_iter++) 695 for (; (header->ep_list)[i] != NULL; i++)
656 { 696 {
657 PLUGIN(*ep_iter)->filename = g_strdup(filename); 697 PLUGIN((header->ep_list)[i])->filename = g_strdup_printf("%s (#%d)", filename, i);
658 effect_plugin_init(PLUGIN(*ep_iter)); 698 effect_plugin_init(PLUGIN((header->ep_list)[i]));
659 } 699 }
660 } 700 }
661 701
662 if (header->gp_list) 702 if (header->gp_list)
663 { 703 {
664 for (gp_iter = header->gp_list; *gp_iter != NULL; gp_iter++) 704 for (; (header->gp_list)[i] != NULL; i++)
665 { 705 {
666 PLUGIN(*gp_iter)->filename = g_strdup(filename); 706 PLUGIN((header->gp_list)[i])->filename = g_strdup_printf("%s (#%d)", filename, i);
667 general_plugin_init(PLUGIN(*gp_iter)); 707 general_plugin_init(PLUGIN((header->gp_list)[i]));
668 } 708 }
669 } 709 }
670 710
671 if (header->vp_list) 711 if (header->vp_list)
672 { 712 {
673 for (vp_iter = header->vp_list; *vp_iter != NULL; vp_iter++) 713 for (; (header->vp_list)[i] != NULL; i++)
674 { 714 {
675 PLUGIN(*vp_iter)->filename = g_strdup(filename); 715 PLUGIN((header->vp_list)[i])->filename = g_strdup_printf("%s (#%d)", filename, i);
676 vis_plugin_init(PLUGIN(*vp_iter)); 716 vis_plugin_init(PLUGIN((header->vp_list)[i]));
677 } 717 }
678 } 718 }
679 719
680 if (header->dp_list) 720 if (header->dp_list)
681 { 721 {
682 for (dp_iter = header->dp_list; *dp_iter != NULL; dp_iter++) 722 for (; (header->dp_list)[i] != NULL; i++)
683 { 723 {
684 PLUGIN(*dp_iter)->filename = g_strdup(filename); 724 PLUGIN((header->dp_list)[i])->filename = g_strdup_printf("%s (#%d)", filename, i);
685 discovery_plugin_init(PLUGIN(*dp_iter)); 725 discovery_plugin_init(PLUGIN((header->dp_list)[i]));
686 } 726 }
687 } 727 }
688 } 728 }
689 729
690 void 730 void
691 plugin2_unload(PluginHeader *header) 731 plugin2_unload(PluginHeader *header, mowgli_node_t *hlist_node)
692 { 732 {
693 GModule *module; 733 GModule *module;
694 734
695 g_return_if_fail(header->priv_assoc != NULL); 735 g_return_if_fail(header->priv_assoc != NULL);
696 736
699 g_free(header->priv_assoc->filename); 739 g_free(header->priv_assoc->filename);
700 g_free(header->priv_assoc); 740 g_free(header->priv_assoc);
701 741
702 if (header->fini) 742 if (header->fini)
703 header->fini(); 743 header->fini();
744
745 mowgli_node_delete(hlist_node, headers_list);
746 mowgli_node_free(hlist_node);
704 747
705 g_module_close(module); 748 g_module_close(module);
706 } 749 }
707 750
708 /******************************************************************/ 751 /******************************************************************/
776 report_error("Module loading not supported! Plugins will not be loaded.\n"); 819 report_error("Module loading not supported! Plugins will not be loaded.\n");
777 return; 820 return;
778 } 821 }
779 822
780 plugin_dict = mowgli_dictionary_create(g_ascii_strcasecmp); 823 plugin_dict = mowgli_dictionary_create(g_ascii_strcasecmp);
824 pvt_data_dict = mowgli_dictionary_create(g_ascii_strcasecmp);
825
826 headers_list = mowgli_list_create();
781 827
782 /* make extension hash */ 828 /* make extension hash */
783 ext_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); 829 ext_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
784 830
785 #ifndef DISABLE_USER_PLUGIN_DIR 831 #ifndef DISABLE_USER_PLUGIN_DIR
852 * basename, so this is usually what the user want. 898 * basename, so this is usually what the user want.
853 */ 899 */
854 if (cfg.outputplugin && !strcmp(g_basename(cfg.outputplugin), g_basename(op->filename))) 900 if (cfg.outputplugin && !strcmp(g_basename(cfg.outputplugin), g_basename(op->filename)))
855 op_data.current_output_plugin = op; 901 op_data.current_output_plugin = op;
856 if (op->init) 902 if (op->init)
903 {
904 plugin_set_current((Plugin *)op);
857 op->init(); 905 op->init();
906 }
858 } 907 }
859 908
860 for (node = ip_data.input_list; node; node = g_list_next(node)) { 909 for (node = ip_data.input_list; node; node = g_list_next(node)) {
861 ip = INPUT_PLUGIN(node->data); 910 ip = INPUT_PLUGIN(node->data);
862 if (ip->init) 911 if (ip->init)
912 {
913 plugin_set_current((Plugin *)ip);
863 ip->init(); 914 ip->init();
915 }
864 } 916 }
865 917
866 for (node = dp_data.discovery_list; node; node = g_list_next(node)) { 918 for (node = dp_data.discovery_list; node; node = g_list_next(node)) {
867 dp = DISCOVERY_PLUGIN(node->data); 919 dp = DISCOVERY_PLUGIN(node->data);
868 if (dp->init) 920 if (dp->init)
921 {
922 plugin_set_current((Plugin *)dp);
869 dp->init(); 923 dp->init();
924 }
870 } 925 }
871 926
872 927
873 for (node = lowlevel_list; node; node = g_list_next(node)) { 928 for (node = lowlevel_list; node; node = g_list_next(node)) {
874 lp = LOWLEVEL_PLUGIN(node->data); 929 lp = LOWLEVEL_PLUGIN(node->data);
875 if (lp->init) 930 if (lp->init)
931 {
932 plugin_set_current((Plugin *)lp);
876 lp->init(); 933 lp->init();
934 }
877 } 935 }
878 936
879 if (cfg.disabled_iplugins) { 937 if (cfg.disabled_iplugins) {
880 disabled = g_strsplit(cfg.disabled_iplugins, ":", 0); 938 disabled = g_strsplit(cfg.disabled_iplugins, ":", 0);
881 939
909 GeneralPlugin *gp; 967 GeneralPlugin *gp;
910 VisPlugin *vp; 968 VisPlugin *vp;
911 LowlevelPlugin *lp; 969 LowlevelPlugin *lp;
912 DiscoveryPlugin *dp; 970 DiscoveryPlugin *dp;
913 GList *node; 971 GList *node;
972 mowgli_node_t *hlist_node;
914 973
915 g_message("Shutting down plugin system"); 974 g_message("Shutting down plugin system");
916 975
917 if (playback_get_playing()) { 976 if (playback_get_playing()) {
918 ip_data.stop = TRUE; 977 ip_data.stop = TRUE;
924 op_data.current_output_plugin = NULL; 983 op_data.current_output_plugin = NULL;
925 984
926 for (node = get_input_list(); node; node = g_list_next(node)) { 985 for (node = get_input_list(); node; node = g_list_next(node)) {
927 ip = INPUT_PLUGIN(node->data); 986 ip = INPUT_PLUGIN(node->data);
928 if (ip && ip->cleanup) { 987 if (ip && ip->cleanup) {
988 plugin_set_current((Plugin *)ip);
929 ip->cleanup(); 989 ip->cleanup();
930 GDK_THREADS_LEAVE(); 990 GDK_THREADS_LEAVE();
931 while (g_main_context_iteration(NULL, FALSE)); 991 while (g_main_context_iteration(NULL, FALSE));
932 GDK_THREADS_ENTER(); 992 GDK_THREADS_ENTER();
933 } 993 }
943 } 1003 }
944 1004
945 for (node = get_output_list(); node; node = g_list_next(node)) { 1005 for (node = get_output_list(); node; node = g_list_next(node)) {
946 op = OUTPUT_PLUGIN(node->data); 1006 op = OUTPUT_PLUGIN(node->data);
947 if (op && op->cleanup) { 1007 if (op && op->cleanup) {
1008 plugin_set_current((Plugin *)op);
948 op->cleanup(); 1009 op->cleanup();
949 GDK_THREADS_LEAVE(); 1010 GDK_THREADS_LEAVE();
950 while (g_main_context_iteration(NULL, FALSE)); 1011 while (g_main_context_iteration(NULL, FALSE));
951 GDK_THREADS_ENTER(); 1012 GDK_THREADS_ENTER();
952 } 1013 }
962 } 1023 }
963 1024
964 for (node = get_effect_list(); node; node = g_list_next(node)) { 1025 for (node = get_effect_list(); node; node = g_list_next(node)) {
965 ep = EFFECT_PLUGIN(node->data); 1026 ep = EFFECT_PLUGIN(node->data);
966 if (ep && ep->cleanup) { 1027 if (ep && ep->cleanup) {
1028 plugin_set_current((Plugin *)ep);
967 ep->cleanup(); 1029 ep->cleanup();
968 GDK_THREADS_LEAVE(); 1030 GDK_THREADS_LEAVE();
969 while (g_main_context_iteration(NULL, FALSE)); 1031 while (g_main_context_iteration(NULL, FALSE));
970 GDK_THREADS_ENTER(); 1032 GDK_THREADS_ENTER();
971 } 1033 }
981 } 1043 }
982 1044
983 for (node = get_general_list(); node; node = g_list_next(node)) { 1045 for (node = get_general_list(); node; node = g_list_next(node)) {
984 gp = GENERAL_PLUGIN(node->data); 1046 gp = GENERAL_PLUGIN(node->data);
985 if (gp && gp->cleanup) { 1047 if (gp && gp->cleanup) {
1048 plugin_set_current((Plugin *)gp);
986 gp->cleanup(); 1049 gp->cleanup();
987 GDK_THREADS_LEAVE(); 1050 GDK_THREADS_LEAVE();
988 while (g_main_context_iteration(NULL, FALSE)); 1051 while (g_main_context_iteration(NULL, FALSE));
989 GDK_THREADS_ENTER(); 1052 GDK_THREADS_ENTER();
990 } 1053 }
1000 } 1063 }
1001 1064
1002 for (node = get_vis_list(); node; node = g_list_next(node)) { 1065 for (node = get_vis_list(); node; node = g_list_next(node)) {
1003 vp = VIS_PLUGIN(node->data); 1066 vp = VIS_PLUGIN(node->data);
1004 if (vp && vp->cleanup) { 1067 if (vp && vp->cleanup) {
1068 plugin_set_current((Plugin *)vp);
1005 vp->cleanup(); 1069 vp->cleanup();
1006 GDK_THREADS_LEAVE(); 1070 GDK_THREADS_LEAVE();
1007 while (g_main_context_iteration(NULL, FALSE)); 1071 while (g_main_context_iteration(NULL, FALSE));
1008 GDK_THREADS_ENTER(); 1072 GDK_THREADS_ENTER();
1009 } 1073 }
1020 1084
1021 1085
1022 for (node = get_discovery_list(); node; node = g_list_next(node)) { 1086 for (node = get_discovery_list(); node; node = g_list_next(node)) {
1023 dp = DISCOVERY_PLUGIN(node->data); 1087 dp = DISCOVERY_PLUGIN(node->data);
1024 if (dp && dp->cleanup) { 1088 if (dp && dp->cleanup) {
1089 plugin_set_current((Plugin *)dp);
1025 dp->cleanup(); 1090 dp->cleanup();
1026 GDK_THREADS_LEAVE(); 1091 GDK_THREADS_LEAVE();
1027 while (g_main_context_iteration(NULL, FALSE)); 1092 while (g_main_context_iteration(NULL, FALSE));
1028 GDK_THREADS_ENTER(); 1093 GDK_THREADS_ENTER();
1029 } 1094 }
1041 1106
1042 1107
1043 for (node = lowlevel_list; node; node = g_list_next(node)) { 1108 for (node = lowlevel_list; node; node = g_list_next(node)) {
1044 lp = LOWLEVEL_PLUGIN(node->data); 1109 lp = LOWLEVEL_PLUGIN(node->data);
1045 if (lp && lp->cleanup) { 1110 if (lp && lp->cleanup) {
1111 plugin_set_current((Plugin *)lp);
1046 lp->cleanup(); 1112 lp->cleanup();
1047 GDK_THREADS_LEAVE(); 1113 GDK_THREADS_LEAVE();
1048 while (g_main_context_iteration(NULL, FALSE)); 1114 while (g_main_context_iteration(NULL, FALSE));
1049 GDK_THREADS_ENTER(); 1115 GDK_THREADS_ENTER();
1050 } 1116 }
1064 { 1130 {
1065 g_list_free(vfs_transports); 1131 g_list_free(vfs_transports);
1066 vfs_transports = NULL; 1132 vfs_transports = NULL;
1067 } 1133 }
1068 1134
1135 MOWGLI_LIST_FOREACH(hlist_node, headers_list->head)
1136 plugin2_unload(hlist_node->data, hlist_node);
1137
1069 mowgli_dictionary_destroy(plugin_dict, NULL, NULL); 1138 mowgli_dictionary_destroy(plugin_dict, NULL, NULL);
1139 mowgli_dictionary_destroy(pvt_data_dict, NULL, NULL);
1140
1141 mowgli_list_free(headers_list);
1142
1070 g_hash_table_foreach(ext_hash, remove_list, NULL); 1143 g_hash_table_foreach(ext_hash, remove_list, NULL);
1071 g_hash_table_remove_all(ext_hash); 1144 g_hash_table_remove_all(ext_hash);
1072 } 1145 }