changeset 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 7410b81a3362
children a3d30a174720
files src/audacious/discovery.c src/audacious/effect.c src/audacious/general.c src/audacious/input.c src/audacious/output.c src/audacious/playback.c src/audacious/playlist.c src/audacious/plugin.h src/audacious/pluginenum.c src/audacious/pluginenum.h src/audacious/ui_fileinfo.c src/audacious/ui_preferences.c src/audacious/visualization.c
diffstat 13 files changed, 266 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/src/audacious/discovery.c	Sun Feb 10 10:40:51 2008 +0100
+++ b/src/audacious/discovery.c	Sun Feb 10 12:31:44 2008 +0100
@@ -23,6 +23,7 @@
 #include <glib.h>
 #include <string.h>
 #include "plugin.h"
+#include "pluginenum.h"
 #include "discovery.h"
 
 DiscoveryPluginData dp_data = {
@@ -64,12 +65,18 @@
     if (enable && !plugin->enabled) {
         dp_data.enabled_list = g_list_append(dp_data.enabled_list, plugin);
         if (plugin->init)
+	{
+	    plugin_set_current((Plugin *)plugin);
             plugin->init();
+	}
     }
     else if (!enable && plugin->enabled) {
         dp_data.enabled_list = g_list_remove(dp_data.enabled_list, plugin);
         if (plugin->cleanup)
+	{
+	    plugin_set_current((Plugin *)plugin);
             plugin->cleanup();
+	}
     }
 
     plugin->enabled = enable;
@@ -123,7 +130,10 @@
                 dp_data.enabled_list = g_list_append(dp_data.enabled_list,
                                                       plugin);
                 if (plugin->init)
+		{
+		    plugin_set_current((Plugin *)plugin);
                     plugin->init();
+		}
 
                 plugin->enabled = TRUE;
             }
--- a/src/audacious/effect.c	Sun Feb 10 10:40:51 2008 +0100
+++ b/src/audacious/effect.c	Sun Feb 10 12:31:44 2008 +0100
@@ -29,6 +29,7 @@
 #include <glib.h>
 #include <string.h>
 #include "plugin.h"
+#include "pluginenum.h"
 
 EffectPluginData ep_data = {
     NULL,
@@ -45,7 +46,10 @@
         if (l->data) {
             EffectPlugin *ep = l->data;
             if (ep->mod_samples)
+	    {
+	        plugin_set_current((Plugin *)ep);
                 length = ep->mod_samples(data, length, fmt, srate, nch);
+	    }
         }
         l = g_list_next(l);
     }
@@ -62,7 +66,10 @@
         if (l->data) {
             EffectPlugin *ep = l->data;
             if (ep->query_format)
+	    {
+	        plugin_set_current((Plugin *)ep);
                 ep->query_format(fmt, rate, nch);
+	    }
         }
         l = g_list_next(l);
     }
@@ -87,12 +94,18 @@
     if (enable && !ep->enabled) {
         ep_data.enabled_list = g_list_append(ep_data.enabled_list, ep);
         if (ep->init)
+	{
+	    plugin_set_current((Plugin *)ep);
             ep->init();
+	}
     }
     else if (!enable && ep->enabled) {
         ep_data.enabled_list = g_list_remove(ep_data.enabled_list, ep);
         if (ep->cleanup)
+	{
+	    plugin_set_current((Plugin *)ep);
             ep->cleanup();
+	}
     }
 
     ep->enabled = enable;
@@ -150,7 +163,10 @@
                 ep_data.enabled_list =
                     g_list_append(ep_data.enabled_list, ep);
                 if (ep->init)
+		{
+		    plugin_set_current((Plugin *)ep);
                     ep->init();
+		}
             }
             g_free(base);
             node = node->next;
--- a/src/audacious/general.c	Sun Feb 10 10:40:51 2008 +0100
+++ b/src/audacious/general.c	Sun Feb 10 12:31:44 2008 +0100
@@ -23,6 +23,7 @@
 #include <glib.h>
 #include <string.h>
 #include "plugin.h"
+#include "pluginenum.h"
 #include "general.h"
 
 GeneralPluginData gp_data = {
@@ -64,12 +65,18 @@
     if (enable && !plugin->enabled) {
         gp_data.enabled_list = g_list_append(gp_data.enabled_list, plugin);
         if (plugin->init)
+	{
+	    plugin_set_current((Plugin *)plugin);
             plugin->init();
+	}
     }
     else if (!enable && plugin->enabled) {
         gp_data.enabled_list = g_list_remove(gp_data.enabled_list, plugin);
         if (plugin->cleanup)
+	{
+	    plugin_set_current((Plugin *)plugin);
             plugin->cleanup();
+	}
     }
 
     plugin->enabled = enable;
@@ -125,7 +132,10 @@
                 gp_data.enabled_list = g_list_append(gp_data.enabled_list,
                                                       plugin);
                 if (plugin->init)
+		{
+	            plugin_set_current((Plugin *)plugin);
                     plugin->init();
+		}
             }
 
             g_free(base);
--- a/src/audacious/input.c	Sun Feb 10 10:40:51 2008 +0100
+++ b/src/audacious/input.c	Sun Feb 10 12:31:44 2008 +0100
@@ -254,6 +254,7 @@
          (ip->probe_for_tuple && ip->have_subtune == TRUE) ||
          (ip->probe_for_tuple && (cfg.use_pl_metadata && (!loading || (loading && cfg.get_info_on_load)))) ) {
 
+        plugin_set_current((Plugin *)ip);
         Tuple *tuple = ip->probe_for_tuple(filename_proxy, fd);
 
         if (tuple != NULL) {
@@ -267,6 +268,7 @@
     }
 
     else if (ip->is_our_file_from_vfs != NULL) {
+	plugin_set_current((Plugin *)ip);
         result = ip->is_our_file_from_vfs(filename_proxy, fd);
 
         if (result > 0) {
@@ -278,6 +280,7 @@
     }
 
     else if (ip->is_our_file != NULL) {
+	plugin_set_current((Plugin *)ip);
         result = ip->is_our_file(filename_proxy);
 
         if (result > 0) {
@@ -363,7 +366,10 @@
     /* cue:// cdda:// tone:// tact:// */
     if ((ip = uri_get_plugin(filename_proxy)) != NULL && ip->enabled) {
         if (ip->is_our_file != NULL)
+	{
+	    plugin_set_current((Plugin *)ip);
             ret = ip->is_our_file(filename_proxy);
+	}
         else
             ret = 0;
         if (ret > 0) {
@@ -488,7 +494,10 @@
         return;
 
     if (playback->plugin->set_eq)
+    {
+        plugin_set_current((Plugin *)(playback->plugin));
         playback->plugin->set_eq(on, preamp, bands);
+    }
 }
 
 
@@ -518,7 +527,10 @@
     g_free(pr);
 
     if (ip && ip->get_song_tuple)
+    {
+        plugin_set_current((Plugin *)ip);
         input = ip->get_song_tuple(filename_proxy);
+    }
     else
     {
         gchar *scratch;
@@ -641,7 +653,10 @@
     g_free(pr);
 
     if (ip->file_info_box)
+    {
+        plugin_set_current((Plugin *)ip);
         ip->file_info_box(filename_proxy);
+    }
     else
         input_general_file_info_box(filename, ip);
 
@@ -676,6 +691,7 @@
         if (!ip->enabled)
             continue;
 
+        plugin_set_current((Plugin *)ip);
         if ((result = ip->scan_dir(path_proxy)))
             break;
     }
@@ -706,11 +722,14 @@
     h_vol[1] = r;
     hook_call("volume set", h_vol);
     
-    if (playback_get_playing() &&
-        (playback = get_current_input_playback()) != NULL &&
-        playback->plugin->set_volume &&
-        playback->plugin->set_volume(l, r))
-        return;
+    if (playback_get_playing())
+        if ((playback = get_current_input_playback()) != NULL)
+	    if (playback->plugin->set_volume != NULL)
+	    {
+	        plugin_set_current((Plugin *)(playback->plugin));
+	        if (playback->plugin->set_volume(l, r))
+		    return;
+	    }
 
     output_set_volume(l, r);
 
--- a/src/audacious/output.c	Sun Feb 10 10:40:51 2008 +0100
+++ b/src/audacious/output.c	Sun Feb 10 12:31:44 2008 +0100
@@ -40,6 +40,8 @@
 
 #include "flow.h"
 
+#include "pluginenum.h"
+
 #include "effect.h"
 #include "volumecontrol.h"
 #include "visualization.h"
@@ -112,6 +114,8 @@
     {
         guint time, pos;
         PlaylistEntry *entry;
+	
+	plugin_set_current((Plugin *)op);
 
         /* don't stop yet, get the seek time and playlist position first */
         pos = playlist_get_position(playlist_get_active());
@@ -156,7 +160,10 @@
 {
     OutputPlugin *out = g_list_nth(op_data.output_list, i)->data;
     if (out && out->about)
+    {
+	plugin_set_current((Plugin *)out);
         out->about();
+    }
 }
 
 void
@@ -164,7 +171,10 @@
 {
     OutputPlugin *out = g_list_nth(op_data.output_list, i)->data;
     if (out && out->configure)
+    {
+	plugin_set_current((Plugin *)out);
         out->configure();
+    }
 }
 
 void
@@ -181,7 +191,10 @@
     if (cfg.software_volume_control)
         volumecontrol_get_volume_state(l, r);
     else
+    {
+        plugin_set_current((Plugin *)op_data.current_output_plugin);
         op_data.current_output_plugin->get_volume(l, r);
+    }
 }
 
 void
@@ -196,7 +209,10 @@
     if (cfg.software_volume_control)
         volumecontrol_set_volume_state(l, r);
     else
+    {
+        plugin_set_current((Plugin *)op_data.current_output_plugin);
         op_data.current_output_plugin->set_volume(l, r);
+    }
 }
 
 void
@@ -219,6 +235,7 @@
 {
     OutputPlugin *op = get_current_output_plugin();
 
+    plugin_set_current((Plugin *)op);
     return op->written_time();
 }
 
@@ -228,6 +245,7 @@
 {
     OutputPlugin *op = get_current_output_plugin();
 
+    plugin_set_current((Plugin *)op);
     return op->output_time();
 }
 
@@ -438,13 +456,18 @@
         (op_state.rate == rate && op_state.nch == nch && op_state.fmt == fmt))
     {
         /* Yes, and it's the correct sampling rate. Reset the counter and go. */
-        AUDDBG("flushing output instead of reopening\n");
+	AUDDBG("flushing output instead of reopening\n");
+	plugin_set_current((Plugin *)op);
         op->flush(0);
         return TRUE;
     }
     else if (op_state.rate != 0 && op_state.nch != 0)
+    {
+        plugin_set_current((Plugin *)op);
         op->close_audio();
+    }
 
+    plugin_set_current((Plugin *)op);
     ret = op->open_audio(fmt, rate, nch);
 
     if (ret == 1)            /* Success? */
@@ -467,6 +490,7 @@
     if (op == NULL)
         return;
 
+    plugin_set_current((Plugin *)op);
     op->write_audio(ptr, length);
 }
 
@@ -500,6 +524,7 @@
     if (op == NULL)
         return;
 
+    plugin_set_current((Plugin *)op);
     op->close_audio();
 
     /* Reset the op_state. */
@@ -514,6 +539,7 @@
     if (op == NULL)
         return;
 
+    plugin_set_current((Plugin *)op);
     op->flush(time);
 }
 
@@ -525,6 +551,7 @@
     if (op == NULL)
         return;
 
+    plugin_set_current((Plugin *)op);
     op->pause(paused);
 }
 
@@ -536,6 +563,7 @@
     if (op == NULL)
         return 0;
 
+    plugin_set_current((Plugin *)op);
     return op->buffer_free();
 }
 
@@ -547,6 +575,7 @@
     if (op == NULL)
         return 0;
 
+    plugin_set_current((Plugin *)op);
     return op->buffer_playing();
 }
 
@@ -566,6 +595,8 @@
     gint writeoffs;
 
     if (length <= 0) return;
+    
+    plugin_set_current((Plugin *)(playback->output));
     gint time = playback->output->written_time();
 
     if (legacy_flow == NULL)
@@ -680,6 +711,7 @@
             return;                            /* so finish */
 
         /* do output */
+	plugin_set_current((Plugin *)op);
         op->write_audio(((guint8 *) ptr) + writeoffs, writable);
 
         writeoffs += writable;
--- a/src/audacious/playback.c	Sun Feb 10 10:40:51 2008 +0100
+++ b/src/audacious/playback.c	Sun Feb 10 12:31:44 2008 +0100
@@ -55,6 +55,7 @@
 #include "util.h"
 #include "visualization.h"
 #include "skin.h"
+#include "pluginenum.h"
 
 #include "playback.h"
 #include "playback_evlisteners.h"
@@ -113,6 +114,7 @@
     playback->nch = nch;
 
     /* XXX: this can be removed/merged here someday */
+    plugin_set_current((Plugin *)(playback->plugin));
     playback->plugin->set_info(title, length, rate, freq, nch);
 }
 
@@ -121,6 +123,7 @@
 {
     playback->title = g_strdup(title);
 
+    plugin_set_current((Plugin *)(playback->plugin));
     playback->plugin->set_info_text(title);
 }
 
@@ -145,8 +148,12 @@
 
     if (!playback) /* playback can be NULL during init even if playing is TRUE */              
         return -1;
+    plugin_set_current((Plugin *)(playback->plugin));
     if (playback->plugin->get_time)
+    {
+        plugin_set_current((Plugin *)(playback->plugin));
         return playback->plugin->get_time(playback);
+    }
     if (playback->error)
         return -2;
     if (!playback->playing || 
@@ -166,6 +173,7 @@
         return playback->length;
 
     if (playback && playback->plugin->get_song_tuple) {
+        plugin_set_current((Plugin *)(playback->plugin));
         Tuple *tuple = playback->plugin->get_song_tuple(playback->filename);
         if (tuple_get_value_type(tuple, FIELD_LENGTH, NULL) == TUPLE_INT)
             return tuple_get_int(tuple, FIELD_LENGTH, NULL);
@@ -249,7 +257,10 @@
     ip_data.paused = !ip_data.paused;
 
     if (playback->plugin->pause)
+    {
+        plugin_set_current((Plugin *)(playback->plugin));
         playback->plugin->pause(playback, ip_data.paused);
+    }
 
     if (ip_data.paused)
         hook_call("playback pause", NULL);
@@ -300,7 +311,10 @@
         playback->set_pb_change(playback);
 
         if (playback->plugin->stop)
+	{
+	    plugin_set_current((Plugin *)(playback->plugin));
             playback->plugin->stop(playback);
+	}
 
         if (playback->thread != NULL)
         {
@@ -352,6 +366,7 @@
 {
     InputPlayback *playback = (InputPlayback *) data;
 
+    plugin_set_current((Plugin *)(playback->plugin));
     playback->plugin->play_file(playback);
 
     /* if play_file has not reached the 'safe state' before returning (an error
@@ -509,6 +524,7 @@
         playback_pause();
     }
     
+    plugin_set_current((Plugin *)(playback->plugin));
     playback->plugin->seek(playback, time);
     playback->set_pb_change(playback);
     free_vis_data();
--- a/src/audacious/playlist.c	Sun Feb 10 10:40:51 2008 +0100
+++ b/src/audacious/playlist.c	Sun Feb 10 12:31:44 2008 +0100
@@ -73,6 +73,8 @@
 
 #include "hook.h"
 
+#include "pluginenum.h"
+
 #include "playlist_evmessages.h"
 #include "playlist_evlisteners.h"
 #include "ui_skinned_playlist.h"
@@ -250,7 +252,10 @@
     if (pr != NULL && pr->tuple != NULL)
         tuple = pr->tuple;
     else if (entry->decoder != NULL && entry->decoder->get_song_tuple != NULL)
+    {
+        plugin_set_current((Plugin *)(entry->decoder));
         tuple = entry->decoder->get_song_tuple(entry->filename);
+    }
 
     if (tuple == NULL) {
         if (pr != NULL) g_free(pr);
@@ -709,6 +714,7 @@
              * to plugin, by passing the ?subtune suffix; this way we get
              * specific subtune information in the tuple, if available.
              */
+            plugin_set_current((Plugin *)dec);
             tuple = dec->get_song_tuple(filename_entry);
         } else
             filename_entry = g_strdup(filename);
@@ -2481,7 +2487,10 @@
             if (entry->decoder != NULL && entry->decoder->file_info_box == NULL)
                 fileinfo_show_for_tuple(tuple, FALSE);
             else if (entry->decoder != NULL && entry->decoder->file_info_box != NULL)
+	    {
+                plugin_set_current((Plugin *)(entry->decoder));
                 entry->decoder->file_info_box(path);
+	    }
             else
                 fileinfo_show_for_path(path);
             g_free(path);
@@ -2489,7 +2498,10 @@
         else if (path != NULL)
         {
             if (entry != NULL && entry->decoder != NULL && entry->decoder->file_info_box != NULL)
+	    {
+                plugin_set_current((Plugin *)(entry->decoder));
                 entry->decoder->file_info_box(path);
+	    }
             else
                 fileinfo_show_for_path(path);
             g_free(path);
@@ -2528,7 +2540,10 @@
             if (playlist->position->decoder != NULL && playlist->position->decoder->file_info_box == NULL)
                 fileinfo_show_for_tuple(tuple, FALSE);
             else if (playlist->position->decoder != NULL && playlist->position->decoder->file_info_box != NULL)
+	    {
+                plugin_set_current((Plugin *)(playlist->position->decoder));
                 playlist->position->decoder->file_info_box(path);
+	    }
             else
                 fileinfo_show_for_path(path);
             g_free(path);
@@ -2536,7 +2551,10 @@
         else if (path != NULL)
         {
             if (playlist->position != NULL && playlist->position->decoder != NULL && playlist->position->decoder->file_info_box != NULL)
+	    {
+                plugin_set_current((Plugin *)(playlist->position->decoder));
                 playlist->position->decoder->file_info_box(path);
+	    }
             else
                 fileinfo_show_for_path(path);
             g_free(path);
--- a/src/audacious/plugin.h	Sun Feb 10 10:40:51 2008 +0100
+++ b/src/audacious/plugin.h	Sun Feb 10 12:31:44 2008 +0100
@@ -652,6 +652,9 @@
     gchar *(*uri_to_display_basename)(const gchar * uri);
     gchar *(*uri_to_display_dirname)(const gchar * uri);
 
+    void (*set_pvt_data)(Plugin * plugin, gpointer data);
+    gpointer (*get_pvt_data)(void);
+
 };
 
 /* Convenience macros for accessing the public API. */
@@ -997,6 +1000,9 @@
 #define aud_uri_to_display_basename _audvt->uri_to_display_basename
 #define aud_uri_to_display_dirname _audvt->uri_to_display_dirname
 
+#define aud_set_pvt_data			_audvt->set_pvt_data
+#define aud_get_pvt_data			_audvt->get_pvt_data
+
 #include "audacious/auddrct.h"
 
 /* for multi-file plugins :( */
--- a/src/audacious/pluginenum.c	Sun Feb 10 10:40:51 2008 +0100
+++ b/src/audacious/pluginenum.c	Sun Feb 10 12:31:44 2008 +0100
@@ -70,6 +70,9 @@
 
 GHashTable *ext_hash = NULL;
 
+static void set_pvt_data(Plugin * plugin, gpointer data);
+static gpointer get_pvt_data(void);
+
 /*****************************************************************/
 
 static struct _AudaciousFuncTableV1 _aud_papi_v1 = {
@@ -392,6 +395,9 @@
     .uri_to_display_basename = uri_to_display_basename,
     .uri_to_display_dirname = uri_to_display_dirname,
 
+    .get_pvt_data = get_pvt_data,
+    .set_pvt_data = set_pvt_data,
+
 };
 
 /*****************************************************************/
@@ -401,6 +407,39 @@
 
 mowgli_dictionary_t *plugin_dict = NULL;
 
+static GStaticPrivate cur_plugin_key = G_STATIC_PRIVATE_INIT;
+static mowgli_dictionary_t *pvt_data_dict = NULL;
+
+static mowgli_list_t *headers_list = NULL;
+
+void plugin_set_current(Plugin *plugin)
+{
+    g_static_private_set(&cur_plugin_key, plugin, NULL);
+}
+
+static Plugin *plugin_get_current(void)
+{
+    return g_static_private_get(&cur_plugin_key);
+}
+
+static void set_pvt_data(Plugin * plugin, gpointer data)
+{
+    mowgli_dictionary_elem_t *elem;
+
+    elem = mowgli_dictionary_find(pvt_data_dict, g_basename(plugin->filename));
+    if (elem == NULL)
+        mowgli_dictionary_add(pvt_data_dict, g_basename(plugin->filename), data);
+    else
+        elem->data = data;
+}
+
+static gpointer get_pvt_data(void)
+{
+    Plugin *cur_p = plugin_get_current();
+
+    return mowgli_dictionary_retrieve(pvt_data_dict, g_basename(cur_p->filename));
+}
+
 static gint
 inputlist_compare_func(gconstpointer a, gconstpointer b)
 {
@@ -611,12 +650,8 @@
 void
 plugin2_process(PluginHeader *header, GModule *module, const gchar *filename)
 {
-    InputPlugin **ip_iter;
-    OutputPlugin **op_iter;
-    EffectPlugin **ep_iter;
-    GeneralPlugin **gp_iter;
-    VisPlugin **vp_iter;
-    DiscoveryPlugin **dp_iter;
+    int i;
+    mowgli_node_t *hlist_node;
 
     if (header->magic != PLUGIN_MAGIC)
         return plugin2_dispose(module, "plugin <%s> discarded, invalid module magic", filename);
@@ -625,6 +660,9 @@
         return plugin2_dispose(module, "plugin <%s> discarded, wanting API version %d, we implement API version %d",
                                filename, header->api_version, __AUDACIOUS_PLUGIN_API__);
 
+    hlist_node = mowgli_node_create();
+    mowgli_node_add(header, hlist_node, headers_list);
+
     if (header->init)
         header->init();
 
@@ -632,63 +670,65 @@
     header->priv_assoc->handle = module;
     header->priv_assoc->filename = g_strdup(filename);
 
+    i = 0;
+
     if (header->ip_list)
     {
-        for (ip_iter = header->ip_list; *ip_iter != NULL; ip_iter++)
+        for (; (header->ip_list)[i] != NULL; i++)
         {
-            PLUGIN(*ip_iter)->filename = g_strdup(filename);
-            input_plugin_init(PLUGIN(*ip_iter));
+            PLUGIN((header->ip_list)[i])->filename = g_strdup_printf("%s (#%d)", filename, i);
+            input_plugin_init(PLUGIN((header->ip_list)[i]));
         }
     }
 
     if (header->op_list)
     {
-        for (op_iter = header->op_list; *op_iter != NULL; op_iter++)
+        for (; (header->op_list)[i] != NULL; i++)
         {
-            PLUGIN(*op_iter)->filename = g_strdup(filename);
-            output_plugin_init(PLUGIN(*op_iter));
+            PLUGIN((header->op_list)[i])->filename = g_strdup_printf("%s (#%d)", filename, i);
+            output_plugin_init(PLUGIN((header->op_list)[i]));
         }
     }
 
     if (header->ep_list)
     {
-        for (ep_iter = header->ep_list; *ep_iter != NULL; ep_iter++)
+        for (; (header->ep_list)[i] != NULL; i++)
         {
-            PLUGIN(*ep_iter)->filename = g_strdup(filename);
-            effect_plugin_init(PLUGIN(*ep_iter));
+            PLUGIN((header->ep_list)[i])->filename = g_strdup_printf("%s (#%d)", filename, i);
+            effect_plugin_init(PLUGIN((header->ep_list)[i]));
         }
     }
 
     if (header->gp_list)
     {
-        for (gp_iter = header->gp_list; *gp_iter != NULL; gp_iter++)
+        for (; (header->gp_list)[i] != NULL; i++)
         {
-            PLUGIN(*gp_iter)->filename = g_strdup(filename);
-            general_plugin_init(PLUGIN(*gp_iter));
+            PLUGIN((header->gp_list)[i])->filename = g_strdup_printf("%s (#%d)", filename, i);
+            general_plugin_init(PLUGIN((header->gp_list)[i]));
         }
     }
 
     if (header->vp_list)
     {
-        for (vp_iter = header->vp_list; *vp_iter != NULL; vp_iter++)
+        for (; (header->vp_list)[i] != NULL; i++)
         {
-            PLUGIN(*vp_iter)->filename = g_strdup(filename);
-            vis_plugin_init(PLUGIN(*vp_iter));
+            PLUGIN((header->vp_list)[i])->filename = g_strdup_printf("%s (#%d)", filename, i);
+            vis_plugin_init(PLUGIN((header->vp_list)[i]));
         }
     }
 
     if (header->dp_list)
     {
-        for (dp_iter = header->dp_list; *dp_iter != NULL; dp_iter++)
+        for (; (header->dp_list)[i] != NULL; i++)
         {
-            PLUGIN(*dp_iter)->filename = g_strdup(filename);
-            discovery_plugin_init(PLUGIN(*dp_iter));
+            PLUGIN((header->dp_list)[i])->filename = g_strdup_printf("%s (#%d)", filename, i);
+            discovery_plugin_init(PLUGIN((header->dp_list)[i]));
         }
     }
 }
 
 void
-plugin2_unload(PluginHeader *header)
+plugin2_unload(PluginHeader *header, mowgli_node_t *hlist_node)
 {
     GModule *module;
 
@@ -702,6 +742,9 @@
     if (header->fini)
         header->fini();
 
+    mowgli_node_delete(hlist_node, headers_list);
+    mowgli_node_free(hlist_node);
+
     g_module_close(module);
 }
 
@@ -778,6 +821,9 @@
     }
 
     plugin_dict = mowgli_dictionary_create(g_ascii_strcasecmp);
+    pvt_data_dict = mowgli_dictionary_create(g_ascii_strcasecmp);
+
+    headers_list = mowgli_list_create();
 
     /* make extension hash */
     ext_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
@@ -854,26 +900,38 @@
         if (cfg.outputplugin && !strcmp(g_basename(cfg.outputplugin), g_basename(op->filename)))
             op_data.current_output_plugin = op;
         if (op->init)
+	{
+	    plugin_set_current((Plugin *)op);
             op->init();
+	}
     }
 
     for (node = ip_data.input_list; node; node = g_list_next(node)) {
         ip = INPUT_PLUGIN(node->data);
         if (ip->init)
+	{
+	    plugin_set_current((Plugin *)ip);
             ip->init();
+	}
     }
 
     for (node = dp_data.discovery_list; node; node = g_list_next(node)) {
         dp = DISCOVERY_PLUGIN(node->data);
         if (dp->init)
+	{
+	    plugin_set_current((Plugin *)dp);
             dp->init();
+	}
     }
 
 
     for (node = lowlevel_list; node; node = g_list_next(node)) {
         lp = LOWLEVEL_PLUGIN(node->data);
         if (lp->init)
+	{
+	    plugin_set_current((Plugin *)lp);
             lp->init();
+	}
     }
 
     if (cfg.disabled_iplugins) {
@@ -911,6 +969,7 @@
     LowlevelPlugin *lp;
     DiscoveryPlugin *dp;
     GList *node;
+    mowgli_node_t *hlist_node;
 
     g_message("Shutting down plugin system");
 
@@ -926,6 +985,7 @@
     for (node = get_input_list(); node; node = g_list_next(node)) {
         ip = INPUT_PLUGIN(node->data);
         if (ip && ip->cleanup) {
+	    plugin_set_current((Plugin *)ip);
             ip->cleanup();
             GDK_THREADS_LEAVE();
             while (g_main_context_iteration(NULL, FALSE));
@@ -945,6 +1005,7 @@
     for (node = get_output_list(); node; node = g_list_next(node)) {
         op = OUTPUT_PLUGIN(node->data);
         if (op && op->cleanup) {
+	    plugin_set_current((Plugin *)op);
             op->cleanup();
             GDK_THREADS_LEAVE();
             while (g_main_context_iteration(NULL, FALSE));
@@ -964,6 +1025,7 @@
     for (node = get_effect_list(); node; node = g_list_next(node)) {
         ep = EFFECT_PLUGIN(node->data);
         if (ep && ep->cleanup) {
+	    plugin_set_current((Plugin *)ep);
             ep->cleanup();
             GDK_THREADS_LEAVE();
             while (g_main_context_iteration(NULL, FALSE));
@@ -983,6 +1045,7 @@
     for (node = get_general_list(); node; node = g_list_next(node)) {
         gp = GENERAL_PLUGIN(node->data);
         if (gp && gp->cleanup) {
+	    plugin_set_current((Plugin *)gp);
             gp->cleanup();
             GDK_THREADS_LEAVE();
             while (g_main_context_iteration(NULL, FALSE));
@@ -1002,6 +1065,7 @@
     for (node = get_vis_list(); node; node = g_list_next(node)) {
         vp = VIS_PLUGIN(node->data);
         if (vp && vp->cleanup) {
+	    plugin_set_current((Plugin *)vp);
             vp->cleanup();
             GDK_THREADS_LEAVE();
             while (g_main_context_iteration(NULL, FALSE));
@@ -1022,6 +1086,7 @@
     for (node = get_discovery_list(); node; node = g_list_next(node)) {
         dp = DISCOVERY_PLUGIN(node->data);
         if (dp && dp->cleanup) {
+	    plugin_set_current((Plugin *)dp);
             dp->cleanup();
             GDK_THREADS_LEAVE();
             while (g_main_context_iteration(NULL, FALSE));
@@ -1043,6 +1108,7 @@
     for (node = lowlevel_list; node; node = g_list_next(node)) {
         lp = LOWLEVEL_PLUGIN(node->data);
         if (lp && lp->cleanup) {
+	    plugin_set_current((Plugin *)lp);
             lp->cleanup();
             GDK_THREADS_LEAVE();
             while (g_main_context_iteration(NULL, FALSE));
@@ -1066,7 +1132,14 @@
         vfs_transports = NULL;
     }
 
+    MOWGLI_LIST_FOREACH(hlist_node, headers_list->head)
+    	plugin2_unload(hlist_node->data, hlist_node);
+
     mowgli_dictionary_destroy(plugin_dict, NULL, NULL);
+    mowgli_dictionary_destroy(pvt_data_dict, NULL, NULL);
+
+    mowgli_list_free(headers_list);
+
     g_hash_table_foreach(ext_hash, remove_list, NULL);
     g_hash_table_remove_all(ext_hash);
 }
--- a/src/audacious/pluginenum.h	Sun Feb 10 10:40:51 2008 +0100
+++ b/src/audacious/pluginenum.h	Sun Feb 10 12:31:44 2008 +0100
@@ -40,4 +40,6 @@
 void plugin_set_enabled(const gchar *filename, gboolean enabled);
 Plugin *plugin_get_plugin(const gchar *filename);
 
+void plugin_set_current(Plugin *plugin);
+
 #endif
--- a/src/audacious/ui_fileinfo.c	Sun Feb 10 10:40:51 2008 +0100
+++ b/src/audacious/ui_fileinfo.c	Sun Feb 10 12:31:44 2008 +0100
@@ -357,7 +357,8 @@
 
             set_field_int_from_entry(tuple, FIELD_YEAR, entry_year);
             set_field_int_from_entry(tuple, FIELD_TRACK_NUMBER, entry_track);
-                
+
+            plugin_set_current((Plugin *)current_ip);
             if (current_ip->update_song_tuple(tuple, fd)) {
                 message_update_successfull();
                 something_changed = FALSE;
--- a/src/audacious/ui_preferences.c	Sun Feb 10 10:40:51 2008 +0100
+++ b/src/audacious/ui_preferences.c	Sun Feb 10 12:31:44 2008 +0100
@@ -751,6 +751,7 @@
     g_return_if_fail(plugin != NULL);
     g_return_if_fail(plugin->configure != NULL);
 
+    plugin_set_current(plugin);
     plugin->configure();
 }
 
@@ -769,6 +770,7 @@
 
     g_return_if_fail(plugin != NULL);
 
+    plugin_set_current(plugin);
     plugin->about();
 }
 
--- a/src/audacious/visualization.c	Sun Feb 10 10:40:51 2008 +0100
+++ b/src/audacious/visualization.c	Sun Feb 10 12:31:44 2008 +0100
@@ -34,6 +34,7 @@
 #include "input.h"
 #include "main.h"
 #include "playback.h"
+#include "pluginenum.h"
 #include "plugin.h"
 #include "ui_preferences.h"
 
@@ -74,7 +75,10 @@
     for (node = vp_data.enabled_list; node; node = g_list_next(node)) {
         vp = node->data;
         if (vp->playback_start)
+	{
+            plugin_set_current((Plugin *)vp);
             vp->playback_start();
+	}
     }
     vp_data.playback_started = TRUE;
 }
@@ -91,7 +95,10 @@
     for (node = vp_data.enabled_list; node; node = g_list_next(node)) {
         vp = node->data;
         if (vp->playback_stop)
+	{
+            plugin_set_current((Plugin *)vp);
             vp->playback_stop();
+	}
     }
     vp_data.playback_started = FALSE;
 }
@@ -109,16 +116,28 @@
     if (enable && !vp->enabled) {
         vp_data.enabled_list = g_list_append(vp_data.enabled_list, vp);
         if (vp->init)
+	{
+            plugin_set_current((Plugin *)vp);
             vp->init();
+	}
         if (playback_get_playing() && vp->playback_start)
+	{
+            plugin_set_current((Plugin *)vp);
             vp->playback_start();
+	}
     }
     else if (!enable && vp->enabled) {
         vp_data.enabled_list = g_list_remove(vp_data.enabled_list, vp);
         if (playback_get_playing() && vp->playback_stop)
+	{
+            plugin_set_current((Plugin *)vp);
             vp->playback_stop();
+	}
         if (vp->cleanup)
+	{
+            plugin_set_current((Plugin *)vp);
             vp->cleanup();
+	}
     }
 
     vp->enabled = enable;
@@ -162,9 +181,15 @@
                 vp_data.enabled_list =
                     g_list_append(vp_data.enabled_list, vp);
                 if (vp->init)
+		{
+                    plugin_set_current((Plugin *)vp);
                     vp->init();
+		}
                 if (playback_get_playing() && vp->playback_start)
+		{
+                    plugin_set_current((Plugin *)vp);
                     vp->playback_start();
+		}
                 vp->enabled = TRUE;
             }
             g_free(base);
@@ -277,6 +302,7 @@
                     calc_mono_pcm(mono_pcm, pcm_data, nch);
                     mono_pcm_calced = TRUE;
                 }
+		plugin_set_current((Plugin *)vp);
                 vp->render_pcm(mono_pcm);
             }
             else {
@@ -284,6 +310,7 @@
                     calc_stereo_pcm(stereo_pcm, pcm_data, nch);
                     stereo_pcm_calced = TRUE;
                 }
+		plugin_set_current((Plugin *)vp);
                 vp->render_pcm(stereo_pcm);
             }
         }
@@ -293,6 +320,7 @@
                     calc_mono_freq(mono_freq, pcm_data, nch);
                     mono_freq_calced = TRUE;
                 }
+		plugin_set_current((Plugin *)vp);
                 vp->render_freq(mono_freq);
             }
             else {
@@ -300,6 +328,7 @@
                     calc_stereo_freq(stereo_freq, pcm_data, nch);
                     stereo_freq_calced = TRUE;
                 }
+		plugin_set_current((Plugin *)vp);
                 vp->render_freq(stereo_freq);
             }
         }