Mercurial > audlegacy
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 } |
