changeset 3501:95d6cbf21614 trunk

Branch merge.
author Matti Hamalainen <ccr@tnsp.org>
date Fri, 07 Sep 2007 12:45:50 +0300
parents 0cfd5aeacc74 (current diff) 7043b5c94a94 (diff)
children b413aa0c939c
files src/audacious/input.c src/audacious/plugin.h
diffstat 16 files changed, 213 insertions(+), 459 deletions(-) [+]
line wrap: on
line diff
--- a/configure.ac	Fri Sep 07 07:16:04 2007 +0300
+++ b/configure.ac	Fri Sep 07 12:45:50 2007 +0300
@@ -141,6 +141,16 @@
 AM_CONDITIONAL(USE_IPV6,test "x$enable_ipv6" = xyes)
 AC_SUBST(USE_IPV6)
 
+dnl PCH support
+dnl ========================
+AC_ARG_ENABLE(pch,
+	[  --enable-pch                   use GCC precompiled headers (experimental) (default=no)],
+			enable_pch=$enableval, enable_pch=no)
+if test "x$enable_pch" = xyes; then
+   PCH="pch"
+fi
+AC_SUBST(PCH)
+
 dnl rpath stuff
 dnl ========================
 AC_ARG_ENABLE(rpath,
--- a/mk/objective.mk	Fri Sep 07 07:16:04 2007 +0300
+++ b/mk/objective.mk	Fri Sep 07 12:45:50 2007 +0300
@@ -85,7 +85,7 @@
 		done; \
 	fi
 	$(MAKE) clean-posthook
-	rm -f *.o *.lo *.so *.a *.sl .depend-done .depend
+	rm -f *.o *.lo *.so *.a *.sl *.h.gch .depend-done .depend
 	touch .depend
 	@if [ "x$(OBJECTIVE_BINS)" != "x" ]; then \
 		for i in $(OBJECTIVE_BINS); do \
@@ -209,6 +209,16 @@
 	fi;
 	$(CXX) $(CXXFLAGS) -c $< -o $@
 
+pch:
+	@for i in *.h; do \
+		if [ $(SHOW_CFLAGS) -eq 1 ]; then	\
+			printf "%10s     %-20s (%s)\n" "CC [HDR]" $$i "${CFLAGS}";	\
+		else \
+			printf "%10s     %-20s\n" "CC [HDR]" $$i;	\
+		fi; \
+		$(CC) $(CFLAGS) -c $$i -o $$i.gch; \
+	done
+
 $(OBJECTIVE_LIBS): $(OBJECTS)
 	if [ "x$(OBJECTS)" != "x" ]; then \
 		$(MAKE) $(OBJECTS) || exit;		\
--- a/mk/rules.mk.in	Fri Sep 07 07:16:04 2007 +0300
+++ b/mk/rules.mk.in	Fri Sep 07 12:45:50 2007 +0300
@@ -339,3 +339,4 @@
 LIBAUDCLIENT_OBJECTIVE ?= @LIBAUDCLIENT_OBJECTIVE@
 TRANSPORT_PLUGIN_DIR ?= @TRANSPORT_PLUGIN_DIR@
 TRANSPORT_PLUGINS ?= @TRANSPORT_PLUGINS@
+PCH ?= @PCH@
--- a/src/audacious/Makefile	Fri Sep 07 07:16:04 2007 +0300
+++ b/src/audacious/Makefile	Fri Sep 07 12:45:50 2007 +0300
@@ -1,11 +1,12 @@
 include ../../mk/rules.mk
 include ../../mk/init.mk
-include ../../mk/objective.mk
 
 SUBDIRS = $(INTL_OBJECTIVE) glade images ui
 
 OBJECTIVE_BINS = audacious
 
+include ../../mk/objective.mk
+
 LDFLAGS += $(AUDLDFLAGS)
 
 LDADD = \
@@ -158,6 +159,8 @@
 LDADD += -L../libaudclient -laudclient
 endif
 
+LIBADD += $(LDADD)
+
 depend-prehook: $(DBUS_BINDINGS)
 
 build_stamp.c: 
@@ -183,9 +186,7 @@
 desktop_DATA = audacious.desktop
 desktopdir = $(datadir)/applications
 
-audacious: $(OBJECTS) $(LIBDEP)
-	$(CXX) $(LDFLAGS) $(OBJECTS) $(LDADD) -o $@ 
-	@printf "%10s     %-20s\n" LINK $@
+build-prehook: $(PCH)
 
 dbus-server-bindings.h: $(DBUS_BINDINGS_SOURCES)
 	$(DBUS_BINDING_TOOL) --mode=glib-server --prefix=audacious_rc objects.xml > $@
@@ -199,3 +200,4 @@
 	@printf "%10s     %-20s\n" DBUS-BIND $@
 
 OBJECTIVE_DATA = audacious.desktop:$(datadir)/applications
+
--- a/src/audacious/discovery.c	Fri Sep 07 07:16:04 2007 +0300
+++ b/src/audacious/discovery.c	Fri Sep 07 12:45:50 2007 +0300
@@ -76,12 +76,6 @@
     plugin->configure();
 }
 
-static gboolean
-discovery_plugin_is_enabled(DiscoveryPlugin * plugin)
-{
-    return (g_list_find(get_discovery_enabled_list(), plugin) != NULL);
-}
-
 void
 enable_discovery_plugin(gint i, gboolean enable)
 {
@@ -90,16 +84,18 @@
     if (!plugin)
         return;
 
-    if (enable && !discovery_plugin_is_enabled(plugin)) {
+    if (enable && !plugin->enabled) {
         dp_data.enabled_list = g_list_append(dp_data.enabled_list, plugin);
         if (plugin->init)
             plugin->init();
     }
-    else if (!enable && discovery_plugin_is_enabled(plugin)) {
+    else if (!enable && plugin->enabled) {
         dp_data.enabled_list = g_list_remove(dp_data.enabled_list, plugin);
         if (plugin->cleanup)
             plugin->cleanup();
     }
+
+    plugin->enabled = enable;
 }
 
 gboolean
@@ -158,6 +154,8 @@
                                                       plugin);
                 if (plugin->init)
                     plugin->init();
+
+                plugin->enabled = TRUE;
             }
 
             g_free(base);
--- a/src/audacious/effect.c	Fri Sep 07 07:16:04 2007 +0300
+++ b/src/audacious/effect.c	Fri Sep 07 12:45:50 2007 +0300
@@ -76,6 +76,7 @@
     NULL,
     NULL,
     NULL,
+    TRUE,
     effect_do_mod_samples,
     effect_do_query_format
 };
@@ -137,13 +138,14 @@
     if (!node || !(node->data))
         return;
     ep = node->data;
+    ep->enabled = enable;
 
-    if (enable && !g_list_find(ep_data.enabled_list, ep)) {
+    if (enable && !ep->enabled) {
         ep_data.enabled_list = g_list_append(ep_data.enabled_list, ep);
         if (ep->init)
             ep->init();
     }
-    else if (!enable && g_list_find(ep_data.enabled_list, ep)) {
+    else if (!enable && ep->enabled) {
         ep_data.enabled_list = g_list_remove(ep_data.enabled_list, ep);
         if (ep->cleanup)
             ep->cleanup();
@@ -207,6 +209,7 @@
                                               data)->filename);
             if (!strcmp(plugins[i], base)) {
                 ep = node->data;
+                ep->enabled = TRUE;
                 ep_data.enabled_list =
                     g_list_append(ep_data.enabled_list, ep);
                 if (ep->init)
--- a/src/audacious/general.c	Fri Sep 07 07:16:04 2007 +0300
+++ b/src/audacious/general.c	Fri Sep 07 12:45:50 2007 +0300
@@ -76,12 +76,6 @@
     plugin->configure();
 }
 
-static gboolean
-general_plugin_is_enabled(GeneralPlugin * plugin)
-{
-    return (g_list_find(get_general_enabled_list(), plugin) != NULL);
-}
-
 void
 enable_general_plugin(gint i, gboolean enable)
 {
@@ -90,16 +84,18 @@
     if (!plugin)
         return;
 
-    if (enable && !general_plugin_is_enabled(plugin)) {
+    if (enable && !plugin->enabled) {
         gp_data.enabled_list = g_list_append(gp_data.enabled_list, plugin);
         if (plugin->init)
             plugin->init();
     }
-    else if (!enable && general_plugin_is_enabled(plugin)) {
+    else if (!enable && plugin->enabled) {
         gp_data.enabled_list = g_list_remove(gp_data.enabled_list, plugin);
         if (plugin->cleanup)
             plugin->cleanup();
     }
+
+    plugin->enabled = enable;
 }
 
 gboolean
@@ -154,6 +150,8 @@
 
             if (!strcmp(*str, base)) {
                 plugin = GENERAL_PLUGIN(node->data);
+                plugin->enabled = TRUE;
+
                 gp_data.enabled_list = g_list_append(gp_data.enabled_list,
                                                       plugin);
                 if (plugin->init)
--- a/src/audacious/input.c	Fri Sep 07 07:16:04 2007 +0300
+++ b/src/audacious/input.c	Fri Sep 07 12:45:50 2007 +0300
@@ -32,6 +32,8 @@
 #include <gtk/gtk.h>
 #include <string.h>
 
+#include <mowgli.h>
+
 #include "fft.h"
 #include "input.h"
 #include "main.h"
@@ -93,46 +95,34 @@
     return ip_data.input_list;
 }
 
-
-gboolean
-input_is_enabled(const gchar * filename)
-{
-    gchar *basename = g_path_get_basename(filename);
-    gint enabled;
-
-    enabled = GPOINTER_TO_INT(g_hash_table_lookup(plugin_matrix, basename));
-    g_free(basename);
-
-    return enabled;
-}
-
-static void
-disabled_iplugins_foreach_func(const gchar * name,
-                               gboolean enabled,
-                               GString * list)
-{
-    g_return_if_fail(list != NULL);
-
-    if (enabled)
-        return;
-
-    if (list->len > 0)
-        g_string_append(list, ":");
-
-    g_string_append(list, name);
-}
-
+/*
+ * TODO: move this to utility as something like
+ *   plugin_generate_list(GList *plugin_list, gboolean enabled_state)
+ *
+ *   -nenolod
+ */
 gchar *
 input_stringify_disabled_list(void)
 {
-    GString *disabled_list;
+    GList *node;
+    GString *list = g_string_new("");
+
+    MOWGLI_ITER_FOREACH(node, ip_data.input_list)
+    {
+        Plugin *plugin = (Plugin *) node->data;
+        gchar *filename = g_path_get_basename(plugin->filename);
 
-    disabled_list = g_string_new("");
-    g_hash_table_foreach(plugin_matrix,
-                         (GHFunc) disabled_iplugins_foreach_func,
-                         disabled_list);
+        if (plugin->enabled)
+            continue;
+
+        if (list->len > 0)
+            g_string_append(list, ":");
 
-    return g_string_free(disabled_list, FALSE);
+        g_string_append(list, filename);
+        g_free(filename);
+    }
+
+    return g_string_free(list, FALSE);
 }
 
 void
@@ -371,8 +361,7 @@
 
     /* Check for plugins with custom URI:// strings */
     /* cue:// cdda:// tone:// tact:// */
-    if ((ip = uri_get_plugin(filename)) != NULL &&
-        input_is_enabled(ip->filename) == TRUE)
+    if ((ip = uri_get_plugin(filename)) != NULL && ip->enabled)
     {
         if (ip->is_our_file != NULL)
             ret = ip->is_our_file(filename_proxy);
@@ -396,7 +385,7 @@
         for (node = get_input_list(); node != NULL; node = g_list_next(node))
         {
             ip = INPUT_PLUGIN(node->data);
-            if (!ip || !input_is_enabled(ip->filename))
+            if (!ip || !ip->enabled)
                 continue;
             if (ip->is_our_file != NULL)
                 ret = ip->is_our_file(filename_proxy);
@@ -430,8 +419,7 @@
                         !g_strncasecmp(filename, "file://", 7))) ? TRUE : FALSE;
 
     mimetype = vfs_get_metadata(fd, "content-type");
-    if ((ip = mime_get_plugin(mimetype)) != NULL &&
-	input_is_enabled(ip->filename) == TRUE)
+    if ((ip = mime_get_plugin(mimetype)) != NULL && ip->enabled)
     {
         if (ip->probe_for_tuple != NULL)
         {
@@ -486,7 +474,7 @@
     {
         ip = INPUT_PLUGIN(node->data);
 
-        if (!ip || !input_is_enabled(ip->filename))
+        if (!ip || !ip->enabled)
             continue;
 
         vfs_rewind(fd);
@@ -765,7 +753,7 @@
         if (!ip->scan_dir)
             continue;
 
-        if (!input_is_enabled(ip->filename))
+        if (!ip->enabled)
             continue;
 
         if ((result = ip->scan_dir(path_proxy)))
--- a/src/audacious/input.h	Fri Sep 07 07:16:04 2007 +0300
+++ b/src/audacious/input.h	Fri Sep 07 12:45:50 2007 +0300
@@ -81,8 +81,6 @@
 void input_set_volume(gint l, gint r);
 void input_file_info_box(const gchar * filename);
 
-gboolean input_is_disabled(const gchar * filename);
-gboolean input_is_enabled(const gchar * filename);
 gchar *input_stringify_disabled_list(void);
 
 extern InputPluginData ip_data;
--- a/src/audacious/output.c	Fri Sep 07 07:16:04 2007 +0300
+++ b/src/audacious/output.c	Fri Sep 07 12:45:50 2007 +0300
@@ -63,6 +63,7 @@
     NULL,
     NULL,
     NULL,
+    TRUE,
     output_get_volume,
     output_set_volume,
     output_open_audio,
--- a/src/audacious/playback.c	Fri Sep 07 07:16:04 2007 +0300
+++ b/src/audacious/playback.c	Fri Sep 07 12:45:50 2007 +0300
@@ -334,7 +334,7 @@
         }
     }
 
-    if (!entry->decoder || !input_is_enabled(entry->decoder->filename))
+    if (!entry->decoder || !entry->decoder->enabled)
     {
         set_current_input_playback(NULL);
 
--- a/src/audacious/plugin.h	Fri Sep 07 07:16:04 2007 +0300
+++ b/src/audacious/plugin.h	Fri Sep 07 12:45:50 2007 +0300
@@ -86,6 +86,17 @@
 
 typedef struct _InputPlayback InputPlayback;
 
+#define PLUGIN_COMMON_FIELDS		\
+    gpointer handle;			\
+    gchar *filename;			\
+    gchar *description;			\
+    void (*init) (void);		\
+    void (*cleanup) (void);		\
+    void (*about) (void);		\
+    void (*configure) (void);		\
+    gboolean enabled;
+	
+
 /*
  * The v2 Module header.
  *
@@ -140,9 +151,7 @@
 /* Sadly, this is the most we can generalize out of the disparate
    plugin structs usable with typecasts - descender */
 struct _Plugin {
-    gpointer handle;
-    gchar *filename;
-    gchar *description;
+    PLUGIN_COMMON_FIELDS
 };
 
 /*
@@ -150,27 +159,16 @@
  * VFSContainers and the like.
  *
  * They are not GUI visible at this time.
+ *
+ * XXX: Is this still in use in 1.4? --nenolod
  */
 struct _LowlevelPlugin {
-    gpointer handle;
-    gchar *filename;
-
-    gchar *description;
-
-    void (*init) (void);
-    void (*cleanup) (void);
+    PLUGIN_COMMON_FIELDS
 };
 
 struct _OutputPlugin {
-    gpointer handle;
-    gchar *filename;
-
-    gchar *description;
+    PLUGIN_COMMON_FIELDS
 
-    void (*init) (void);
-    void (*cleanup) (void);
-    void (*about) (void);
-    void (*configure) (void);
     void (*get_volume) (gint * l, gint * r);
     void (*set_volume) (gint l, gint r);
 
@@ -189,15 +187,7 @@
 };
 
 struct _EffectPlugin {
-    gpointer handle;
-    gchar *filename;
-
-    gchar *description;
-
-    void (*init) (void);
-    void (*cleanup) (void);
-    void (*about) (void);
-    void (*configure) (void);
+    PLUGIN_COMMON_FIELDS
 
     gint (*mod_samples) (gpointer * data, gint length, AFormat fmt, gint srate, gint nch);
     void (*query_format) (AFormat * fmt, gint * rate, gint * nch);
@@ -222,14 +212,7 @@
 };
 
 struct _InputPlugin {
-    gpointer handle;
-    gchar *filename;
-
-    gchar *description;
-
-    void (*init) (void);
-    void (*about) (void);
-    void (*configure) (void);
+    PLUGIN_COMMON_FIELDS
 
     gint (*is_our_file) (gchar * filename);
     GList *(*scan_dir) (gchar * dirname);
@@ -246,8 +229,6 @@
     gint (*get_volume) (gint * l, gint * r);
     gint (*set_volume) (gint l, gint r);
 
-    void (*cleanup) (void);
-
     InputVisType (*get_vis_type) (void);
     void (*add_vis_pcm) (gint time, AFormat fmt, gint nch, gint length, gpointer ptr);
 
@@ -273,30 +254,15 @@
 };
 
 struct _GeneralPlugin {
-    gpointer handle;
-    gchar *filename;
-
-    gchar *description;
-
-    void (*init) (void);
-    void (*about) (void);
-    void (*configure) (void);
-    void (*cleanup) (void);
+    PLUGIN_COMMON_FIELDS
 };
 
 struct _VisPlugin {
-    gpointer handle;
-    gchar *filename;
-
-    gchar *description;
+    PLUGIN_COMMON_FIELDS
 
     gint num_pcm_chs_wanted;
     gint num_freq_chs_wanted;
 
-    void (*init) (void);
-    void (*cleanup) (void);
-    void (*about) (void);
-    void (*configure) (void);
     void (*disable_plugin) (struct _VisPlugin *);
     void (*playback_start) (void);
     void (*playback_stop) (void);
@@ -305,17 +271,14 @@
 };
 
 struct _DiscoveryPlugin {
-    gpointer handle;
-    gchar *filename;
-    gchar *description;
- 
-    void (*init) (void);
-    void (*cleanup) (void);
-    void (*about) (void);
-    void (*configure) (void);
+    PLUGIN_COMMON_FIELDS
+
     GList *(*get_devices);  
 };
 
+/* undefine the macro -- struct Plugin should be used instead. */
+#undef PLUGIN_COMMON_FIELDS
+
 G_BEGIN_DECLS
 
 /* So that input plugins can get the title formatting information */
--- a/src/audacious/pluginenum.c	Fri Sep 07 07:16:04 2007 +0300
+++ b/src/audacious/pluginenum.c	Fri Sep 07 12:45:50 2007 +0300
@@ -31,8 +31,6 @@
 # define SHARED_SUFFIX G_MODULE_SUFFIX
 #endif
 
-#include "pluginenum.h"
-
 #include <glib.h>
 #include <gmodule.h>
 #include <glib/gprintf.h>
@@ -51,15 +49,19 @@
 #include "output.h"
 #include "visualization.h"
 #include "discovery.h"
+
+#include "pluginenum.h"
+
 const gchar *plugin_dir_list[] = {
     PLUGINSUBS,
     NULL
 };
 
-GHashTable *plugin_matrix = NULL;
 GList *lowlevel_list = NULL;
 extern GList *vfs_transports;
 
+mowgli_dictionary_t *plugin_dict = NULL;
+
 static gint
 inputlist_compare_func(gconstpointer a, gconstpointer b)
 {
@@ -123,45 +125,46 @@
 static gboolean
 plugin_is_duplicate(const gchar * filename)
 {
-    GList *l;
-    const gchar *basename = g_basename(filename);
-
-    /* FIXME: messy stuff */
-
-    for (l = ip_data.input_list; l; l = g_list_next(l))
-        if (!strcmp(basename, g_basename(INPUT_PLUGIN(l->data)->filename)))
-            return TRUE;
-
-    for (l = op_data.output_list; l; l = g_list_next(l))
-        if (!strcmp(basename, g_basename(OUTPUT_PLUGIN(l->data)->filename)))
-            return TRUE;
+    gchar *base_filename = g_path_get_basename(filename);
 
-    for (l = ep_data.effect_list; l; l = g_list_next(l))
-        if (!strcmp(basename, g_basename(EFFECT_PLUGIN(l->data)->filename)))
-            return TRUE;
-
-    for (l = gp_data.general_list; l; l = g_list_next(l))
-        if (!strcmp(basename, g_basename(GENERAL_PLUGIN(l->data)->filename)))
-            return TRUE;
+    if (mowgli_dictionary_retrieve(plugin_dict, base_filename) != NULL)
+    {
+        g_free(base_filename);
+        return TRUE;
+    }
 
-    for (l = vp_data.vis_list; l; l = g_list_next(l))
-        if (!strcmp(basename, g_basename(VIS_PLUGIN(l->data)->filename)))
-            return TRUE;
-
-    for (l = lowlevel_list; l; l = g_list_next(l))
-        if (!strcmp(basename, g_basename(LOWLEVEL_PLUGIN(l->data)->filename)))
-            return TRUE;
-
-    for (l = dp_data.discovery_list; l; l = g_list_next(l))
-        if (!strcmp(basename, g_basename(DISCOVERY_PLUGIN(l->data)->filename)))
-            return TRUE;
+    g_free(base_filename);
 
     return FALSE;
 }
 
+gboolean
+plugin_is_enabled(const gchar *filename)
+{
+    Plugin *plugin = mowgli_dictionary_retrieve(plugin_dict, filename);
 
-#define PLUGIN_GET_INFO(x) ((PluginGetInfoFunc)(x))()
-typedef Plugin * (*PluginGetInfoFunc) (void);
+    if (!plugin)
+        return FALSE;
+
+    return plugin->enabled;
+}
+
+void
+plugin_set_enabled(const gchar *filename, gboolean enabled)
+{
+    Plugin *plugin = mowgli_dictionary_retrieve(plugin_dict, filename);
+
+    if (!plugin)
+        return;
+
+    plugin->enabled = enabled;
+}
+
+Plugin *
+plugin_get_plugin(const gchar *filename)
+{
+    return mowgli_dictionary_retrieve(plugin_dict, filename);
+}
 
 static void
 input_plugin_init(Plugin * plugin)
@@ -180,8 +183,11 @@
 
     ip_data.input_list = g_list_append(ip_data.input_list, p);
     
-    g_hash_table_replace(plugin_matrix, g_path_get_basename(p->filename),
-                         GINT_TO_POINTER(1));
+    p->enabled = TRUE;
+
+    /* XXX: we need something better than p->filename if plugins
+       will eventually provide multiple plugins --nenolod */
+    mowgli_dictionary_add(plugin_dict, g_basename(p->filename), p);
 }
 
 static void
@@ -189,6 +195,8 @@
 {
     OutputPlugin *p = OUTPUT_PLUGIN(plugin);
     op_data.output_list = g_list_append(op_data.output_list, p);    
+
+    mowgli_dictionary_add(plugin_dict, g_basename(p->filename), p);
 }
 
 static void
@@ -196,6 +204,8 @@
 {
     EffectPlugin *p = EFFECT_PLUGIN(plugin);
     ep_data.effect_list = g_list_append(ep_data.effect_list, p);
+
+    mowgli_dictionary_add(plugin_dict, g_basename(p->filename), p);
 }
 
 static void
@@ -203,6 +213,8 @@
 {
     GeneralPlugin *p = GENERAL_PLUGIN(plugin);
     gp_data.general_list = g_list_append(gp_data.general_list, p);
+
+    mowgli_dictionary_add(plugin_dict, g_basename(p->filename), p);
 }
 
 static void
@@ -211,6 +223,8 @@
     VisPlugin *p = VIS_PLUGIN(plugin);
     p->disable_plugin = vis_disable_plugin;
     vp_data.vis_list = g_list_append(vp_data.vis_list, p);
+
+    mowgli_dictionary_add(plugin_dict, g_basename(p->filename), p);
 }
 
 static void
@@ -218,6 +232,8 @@
 {
     DiscoveryPlugin *p = DISCOVERY_PLUGIN(plugin);
     dp_data.discovery_list = g_list_append(dp_data.discovery_list, p);
+
+    mowgli_dictionary_add(plugin_dict, g_basename(p->filename), p);
 }
 
 /*******************************************************************/
@@ -246,7 +262,6 @@
     VisPlugin **vp_iter;
     DiscoveryPlugin **dp_iter;
 
-
     if (header->magic != PLUGIN_MAGIC)
         return plugin2_dispose(module, "plugin <%s> discarded, invalid module magic", filename);
 
@@ -406,8 +421,7 @@
         return;
     }
 
-    plugin_matrix = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
-                                          NULL);
+    plugin_dict = mowgli_dictionary_create(g_ascii_strcasecmp);
 
 #ifndef DISABLE_USER_PLUGIN_DIR
     scan_plugins(bmp_paths[BMP_PATH_USER_PLUGIN_DIR]);
@@ -505,9 +519,9 @@
 
     if (cfg.disabled_iplugins) {
         disabled = g_strsplit(cfg.disabled_iplugins, ":", 0);
+
         while (disabled[i]) {
-            g_hash_table_replace(plugin_matrix, disabled[i],
-                                 GINT_TO_POINTER(FALSE));
+            INPUT_PLUGIN(plugin_get_plugin(disabled[i]))->enabled = FALSE;
             i++;
         }
 
@@ -684,5 +698,5 @@
         vfs_transports = NULL;
     }
 
-    g_hash_table_destroy( plugin_matrix );
+    mowgli_dictionary_destroy(plugin_dict, NULL, NULL);
 }
--- a/src/audacious/pluginenum.h	Fri Sep 07 07:16:04 2007 +0300
+++ b/src/audacious/pluginenum.h	Fri Sep 07 12:45:50 2007 +0300
@@ -36,4 +36,8 @@
 extern const gchar *plugin_dir_list[];
 extern GHashTable *plugin_matrix;
 
+gboolean plugin_is_enabled(const gchar *filename);
+void plugin_set_enabled(const gchar *filename, gboolean enabled);
+Plugin *plugin_get_plugin(const gchar *filename);
+
 #endif
--- a/src/audacious/ui_preferences.c	Fri Sep 07 07:16:04 2007 +0300
+++ b/src/audacious/ui_preferences.c	Fri Sep 07 12:45:50 2007 +0300
@@ -213,15 +213,14 @@
     GtkTreeModel *model = GTK_TREE_MODEL(data);
     GtkTreeIter iter;
     GtkTreePath *path = gtk_tree_path_new_from_string(path_str);
-    gboolean fixed;
     gint pluginnr;
     gchar *filename, *basename;
+    Plugin *plugin;
     /*GList *diplist, *tmplist; */
 
     /* get toggled iter */
     gtk_tree_model_get_iter(model, &iter, path);
     gtk_tree_model_get(model, &iter,
-                       PLUGIN_VIEW_COL_ACTIVE, &fixed,
                        PLUGIN_VIEW_COL_ID, &pluginnr,
                        PLUGIN_VIEW_COL_FILENAME, &filename,
                        -1);
@@ -229,18 +228,19 @@
     basename = g_path_get_basename(filename);
     g_free(filename);
 
+    /* get our plugin */
+    plugin = plugin_get_plugin(basename);
+
     /* do something with the value */
-    fixed ^= 1;
-
-    g_hash_table_replace(plugin_matrix, basename, GINT_TO_POINTER(fixed));
-    /*  g_hash_table_foreach(pluginmatrix, (GHFunc) disp_matrix, NULL); */
+    plugin->enabled ^= 1;
 
     /* set new value */
     gtk_list_store_set(GTK_LIST_STORE(model), &iter,
-                       PLUGIN_VIEW_COL_ACTIVE, fixed, -1);
+                       PLUGIN_VIEW_COL_ACTIVE, plugin->enabled, -1);
 
     /* clean up */
     gtk_tree_path_free(path);
+    g_free(basename);
 }
 
 
@@ -370,10 +370,10 @@
                      G_CALLBACK(on_output_plugin_cbox_changed), NULL);
 }
 
-
 static void
-on_input_plugin_view_realize(GtkTreeView * treeview,
-                             gpointer data)
+on_plugin_view_realize(GtkTreeView * treeview,
+                       GCallback callback,
+                       gpointer data)
 {
     GtkListStore *store;
     GtkTreeIter iter;
@@ -383,10 +383,9 @@
 
     GList *ilist;
     gchar *description[2];
-    InputPlugin *ip;
     gint id = 0;
 
-    gboolean enabled;
+    GList *list = (GList *) data;
 
     store = gtk_list_store_new(PLUGIN_VIEW_N_COLS,
                                G_TYPE_BOOLEAN, G_TYPE_STRING,
@@ -401,7 +400,7 @@
 
     renderer = gtk_cell_renderer_toggle_new();
     g_signal_connect(renderer, "toggled",
-                     G_CALLBACK(input_plugin_toggle), store);
+                     G_CALLBACK(callback), store);
     gtk_tree_view_column_pack_start(column, renderer, TRUE);
     gtk_tree_view_column_set_attributes(column, renderer, "active",
                                         PLUGIN_VIEW_COL_ACTIVE, NULL);
@@ -435,194 +434,16 @@
 
     gtk_tree_view_append_column(treeview, column);
 
-    for (ilist = get_input_list(); ilist; ilist = g_list_next(ilist)) {
-        ip = INPUT_PLUGIN(ilist->data);
-
-        description[0] = g_strdup(ip->description);
-        description[1] = g_strdup(ip->filename);
-
-        enabled = input_is_enabled(description[1]);
+    MOWGLI_ITER_FOREACH(ilist, list)
+    {
+        Plugin *plugin = PLUGIN(ilist->data);
+
+        description[0] = g_strdup(plugin->description);
+        description[1] = g_strdup(plugin->filename);
 
         gtk_list_store_append(store, &iter);
         gtk_list_store_set(store, &iter,
-                           PLUGIN_VIEW_COL_ACTIVE, enabled,
-                           PLUGIN_VIEW_COL_DESC, description[0],
-                           PLUGIN_VIEW_COL_FILENAME, description[1],
-                           PLUGIN_VIEW_COL_ID, id++, -1);
-
-        g_free(description[1]);
-        g_free(description[0]);
-    }
-
-    gtk_tree_view_set_model(treeview, GTK_TREE_MODEL(store));
-}
-
-
-static void
-on_general_plugin_view_realize(GtkTreeView * treeview,
-                               gpointer data)
-{
-    GtkListStore *store;
-    GtkTreeIter iter;
-
-    GtkCellRenderer *renderer;
-    GtkTreeViewColumn *column;
-
-    GList *ilist /*, *diplist */ ;
-    gchar *description[2];
-    GeneralPlugin *gp;
-    gint id = 0;
-
-    gboolean enabled;
-
-    store = gtk_list_store_new(PLUGIN_VIEW_N_COLS,
-                               G_TYPE_BOOLEAN, G_TYPE_STRING,
-                               G_TYPE_STRING, G_TYPE_INT);
-
-    column = gtk_tree_view_column_new();
-    gtk_tree_view_column_set_title(column, _("Enabled"));
-    gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
-    gtk_tree_view_column_set_spacing(column, 4);
-    gtk_tree_view_column_set_resizable(column, FALSE);
-    gtk_tree_view_column_set_fixed_width(column, 50);
-
-    renderer = gtk_cell_renderer_toggle_new();
-    g_signal_connect(renderer, "toggled",
-                     G_CALLBACK(general_plugin_toggle), store);
-    gtk_tree_view_column_pack_start(column, renderer, TRUE);
-    gtk_tree_view_column_set_attributes(column, renderer, "active",
-                                        PLUGIN_VIEW_COL_ACTIVE, NULL);
-
-    gtk_tree_view_append_column(treeview, column);
-
-    column = gtk_tree_view_column_new();
-    gtk_tree_view_column_set_title(column, _("Description"));
-    gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
-    gtk_tree_view_column_set_spacing(column, 4);
-    gtk_tree_view_column_set_resizable(column, TRUE);
-
-
-    renderer = gtk_cell_renderer_text_new();
-    gtk_tree_view_column_pack_start(column, renderer, FALSE);
-    gtk_tree_view_column_set_attributes(column, renderer,
-                                        "text", PLUGIN_VIEW_COL_DESC, NULL);
-
-    gtk_tree_view_append_column(treeview, column);
-
-
-    column = gtk_tree_view_column_new();
-    gtk_tree_view_column_set_title(column, _("Filename"));
-    gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
-    gtk_tree_view_column_set_spacing(column, 4);
-    gtk_tree_view_column_set_resizable(column, TRUE);
-
-    renderer = gtk_cell_renderer_text_new();
-    gtk_tree_view_column_pack_start(column, renderer, TRUE);
-    gtk_tree_view_column_set_attributes(column, renderer, "text",
-                                        PLUGIN_VIEW_COL_FILENAME, NULL);
-
-    gtk_tree_view_append_column(treeview, column);
-
-    for (ilist = get_general_list(); ilist; ilist = g_list_next(ilist)) {
-        gp = GENERAL_PLUGIN(ilist->data);
-
-        description[0] = g_strdup(gp->description);
-        description[1] = g_strdup(gp->filename);
-
-        enabled = general_enabled(id);
-
-        gtk_list_store_append(store, &iter);
-        gtk_list_store_set(store, &iter,
-                           PLUGIN_VIEW_COL_ACTIVE, enabled,
-                           PLUGIN_VIEW_COL_DESC, description[0],
-                           PLUGIN_VIEW_COL_FILENAME, description[1],
-                           PLUGIN_VIEW_COL_ID, id++, -1);
-
-        g_free(description[1]);
-        g_free(description[0]);
-    }
-
-    gtk_tree_view_set_model(treeview, GTK_TREE_MODEL(store));
-}
-
-
-static void
-on_vis_plugin_view_realize(GtkTreeView * treeview,
-                           gpointer data)
-{
-    GtkListStore *store;
-    GtkTreeIter iter;
-
-    GtkCellRenderer *renderer;
-    GtkTreeViewColumn *column;
-
-    GList *vlist;
-    gchar *description[2];
-    VisPlugin *vp;
-    gint id = 0;
-
-    gboolean enabled;
-
-
-    store = gtk_list_store_new(PLUGIN_VIEW_N_COLS,
-                               G_TYPE_BOOLEAN, G_TYPE_STRING,
-                               G_TYPE_STRING, G_TYPE_INT);
-
-    column = gtk_tree_view_column_new();
-    gtk_tree_view_column_set_title(column, _("Enabled"));
-    gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
-    gtk_tree_view_column_set_spacing(column, 4);
-    gtk_tree_view_column_set_resizable(column, FALSE);
-    gtk_tree_view_column_set_fixed_width(column, 50);
-
-    renderer = gtk_cell_renderer_toggle_new();
-    g_signal_connect(renderer, "toggled",
-                     G_CALLBACK(vis_plugin_toggle), store);
-    gtk_tree_view_column_pack_start(column, renderer, TRUE);
-    gtk_tree_view_column_set_attributes(column, renderer, "active",
-                                        PLUGIN_VIEW_COL_ACTIVE, NULL);
-
-    gtk_tree_view_append_column(treeview, column);
-
-    column = gtk_tree_view_column_new();
-    gtk_tree_view_column_set_title(column, _("Description"));
-    gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
-    gtk_tree_view_column_set_spacing(column, 4);
-    gtk_tree_view_column_set_resizable(column, TRUE);
-
-
-    renderer = gtk_cell_renderer_text_new();
-    gtk_tree_view_column_pack_start(column, renderer, FALSE);
-    gtk_tree_view_column_set_attributes(column, renderer,
-                                        "text", PLUGIN_VIEW_COL_DESC, NULL);
-
-    gtk_tree_view_append_column(treeview, column);
-
-
-    column = gtk_tree_view_column_new();
-    gtk_tree_view_column_set_title(column, _("Filename"));
-    gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
-    gtk_tree_view_column_set_spacing(column, 4);
-    gtk_tree_view_column_set_resizable(column, TRUE);
-
-    renderer = gtk_cell_renderer_text_new();
-    gtk_tree_view_column_pack_start(column, renderer, TRUE);
-    gtk_tree_view_column_set_attributes(column, renderer, "text",
-                                        PLUGIN_VIEW_COL_FILENAME, NULL);
-
-    gtk_tree_view_append_column(treeview, column);
-
-    for (vlist = get_vis_list(); vlist; vlist = g_list_next(vlist)) {
-        vp = VIS_PLUGIN(vlist->data);
-
-        description[0] = g_strdup(vp->description);
-        description[1] = g_strdup(vp->filename);
-
-        enabled = vis_enabled(id);
-
-        gtk_list_store_append(store, &iter);
-        gtk_list_store_set(store, &iter,
-                           PLUGIN_VIEW_COL_ACTIVE, enabled,
+                           PLUGIN_VIEW_COL_ACTIVE, plugin->enabled,
                            PLUGIN_VIEW_COL_DESC, description[0],
                            PLUGIN_VIEW_COL_FILENAME, description[1],
                            PLUGIN_VIEW_COL_ID, id++, -1);
@@ -635,99 +456,39 @@
 }
 
 static void
-editable_insert_text(GtkEditable * editable,
-                     const gchar * text,
-                     gint * pos)
+on_input_plugin_view_realize(GtkTreeView * treeview,
+                             gpointer data)
 {
-    gtk_editable_insert_text(editable, text, strlen(text), pos);
+    on_plugin_view_realize(treeview, G_CALLBACK(input_plugin_toggle), ip_data.input_list);
 }
 
-
 static void
 on_effect_plugin_view_realize(GtkTreeView * treeview,
                               gpointer data)
 {
-    GtkListStore *store;
-    GtkTreeIter iter;
-
-    GtkCellRenderer *renderer;
-    GtkTreeViewColumn *column;
-
-    GList *elist;
-    gchar *description[2];
-    gint id = 0;
-
-    gboolean enabled;
-
-
-    store = gtk_list_store_new(PLUGIN_VIEW_N_COLS,
-                               G_TYPE_BOOLEAN, G_TYPE_STRING,
-                               G_TYPE_STRING, G_TYPE_INT);
-
-    column = gtk_tree_view_column_new();
-    gtk_tree_view_column_set_title(column, _("Enabled"));
-    gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
-    gtk_tree_view_column_set_spacing(column, 4);
-    gtk_tree_view_column_set_resizable(column, FALSE);
-    gtk_tree_view_column_set_fixed_width(column, 50);
-
-    renderer = gtk_cell_renderer_toggle_new();
-    g_signal_connect(renderer, "toggled",
-                     G_CALLBACK(effect_plugin_toggle), store);
-    gtk_tree_view_column_pack_start(column, renderer, TRUE);
-    gtk_tree_view_column_set_attributes(column, renderer, "active",
-                                        PLUGIN_VIEW_COL_ACTIVE, NULL);
-
-    gtk_tree_view_append_column(treeview, column);
-
-    column = gtk_tree_view_column_new();
-    gtk_tree_view_column_set_title(column, _("Description"));
-    gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
-    gtk_tree_view_column_set_spacing(column, 4);
-    gtk_tree_view_column_set_resizable(column, TRUE);
-
-
-    renderer = gtk_cell_renderer_text_new();
-    gtk_tree_view_column_pack_start(column, renderer, FALSE);
-    gtk_tree_view_column_set_attributes(column, renderer,
-                                        "text", PLUGIN_VIEW_COL_DESC, NULL);
-
-    gtk_tree_view_append_column(treeview, column);
-
-
-    column = gtk_tree_view_column_new();
-    gtk_tree_view_column_set_title(column, _("Filename"));
-    gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
-    gtk_tree_view_column_set_spacing(column, 4);
-    gtk_tree_view_column_set_resizable(column, TRUE);
-
-    renderer = gtk_cell_renderer_text_new();
-    gtk_tree_view_column_pack_start(column, renderer, TRUE);
-    gtk_tree_view_column_set_attributes(column, renderer, "text",
-                                        PLUGIN_VIEW_COL_FILENAME, NULL);
-
-    gtk_tree_view_append_column(treeview, column);
-
-    for (elist = get_effect_list(); elist; elist = g_list_next(elist)) {
-        EffectPlugin *ep = EFFECT_PLUGIN(elist->data);
-
-        description[0] = g_strdup(ep->description);
-        description[1] = g_strdup(ep->filename);
-
-        enabled = effect_enabled(id);
-
-        gtk_list_store_append(store, &iter);
-        gtk_list_store_set(store, &iter,
-                           PLUGIN_VIEW_COL_ACTIVE, enabled,
-                           PLUGIN_VIEW_COL_DESC, description[0],
-                           PLUGIN_VIEW_COL_FILENAME, description[1],
-                           PLUGIN_VIEW_COL_ID, id++, -1);
-
-        g_free(description[1]);
-        g_free(description[0]);
-    }
-
-    gtk_tree_view_set_model(treeview, GTK_TREE_MODEL(store));
+    on_plugin_view_realize(treeview, G_CALLBACK(effect_plugin_toggle), ep_data.effect_list);
+}
+
+static void
+on_general_plugin_view_realize(GtkTreeView * treeview,
+                               gpointer data)
+{
+    on_plugin_view_realize(treeview, G_CALLBACK(general_plugin_toggle), gp_data.general_list);
+}
+
+static void
+on_vis_plugin_view_realize(GtkTreeView * treeview,
+                           gpointer data)
+{
+    on_plugin_view_realize(treeview, G_CALLBACK(vis_plugin_toggle), vp_data.vis_list);
+}
+
+static void
+editable_insert_text(GtkEditable * editable,
+                     const gchar * text,
+                     gint * pos)
+{
+    gtk_editable_insert_text(editable, text, strlen(text), pos);
 }
 
 static void
--- a/src/audacious/visualization.c	Fri Sep 07 07:16:04 2007 +0300
+++ b/src/audacious/visualization.c	Fri Sep 07 12:45:50 2007 +0300
@@ -124,20 +124,22 @@
         return;
     vp = node->data;
 
-    if (enable && !g_list_find(vp_data.enabled_list, vp)) {
+    if (enable && !vp->enabled) {
         vp_data.enabled_list = g_list_append(vp_data.enabled_list, vp);
         if (vp->init)
             vp->init();
         if (playback_get_playing() && vp->playback_start)
             vp->playback_start();
     }
-    else if (!enable && g_list_find(vp_data.enabled_list, vp)) {
+    else if (!enable && vp->enabled) {
         vp_data.enabled_list = g_list_remove(vp_data.enabled_list, vp);
         if (playback_get_playing() && vp->playback_stop)
             vp->playback_stop();
         if (vp->cleanup)
             vp->cleanup();
     }
+
+    vp->enabled = enable;
 }
 
 gboolean
@@ -189,6 +191,7 @@
                     vp->init();
                 if (playback_get_playing() && vp->playback_start)
                     vp->playback_start();
+                vp->enabled = TRUE;
             }
             g_free(base);
         }