changeset 3227:2619f4c62abe trunk

added Discovery plugin type
author Cristi Magherusan <majeru@atheme-project.org>
date Fri, 03 Aug 2007 07:20:58 +0300
parents db3983f423f3
children e90e154a353e
files configure.ac src/audacious/Makefile src/audacious/discovery.c src/audacious/discovery.h src/audacious/main.h src/audacious/plugin.h src/audacious/pluginenum.c
diffstat 7 files changed, 314 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/configure.ac	Thu Aug 02 17:42:38 2007 +0200
+++ b/configure.ac	Fri Aug 03 07:20:58 2007 +0300
@@ -389,9 +389,10 @@
     GENERAL_PLUGIN_DIR=Plugins
     VISUALIZATION_PLUGIN_DIR=Plugins
     CONTAINER_PLUGIN_DIR=Plugins
-    TRANSPORTR_PLUGIN_DIR=Plugins
+    TRANSPORT_PLUGIN_DIR=Plugins
+    DISCOVERY_PLUGIN_DIR=Plugins
 else
-    pluginsubs="\\\"Output\\\",\\\"Input\\\",\\\"Effect\\\",\\\"General\\\",\\\"Visualization\\\",\\\"Container\\\",\\\"Transport\\\""
+    pluginsubs="\\\"Output\\\",\\\"Input\\\",\\\"Effect\\\",\\\"General\\\",\\\"Visualization\\\",\\\"Container\\\",\\\"Transport\\\",\\\"Discovery\\\""
     INPUT_PLUGIN_DIR=Input
     OUTPUT_PLUGIN_DIR=Output
     EFFECT_PLUGIN_DIR=Effect
@@ -399,6 +400,7 @@
     VISUALIZATION_PLUGIN_DIR=Visualization
     CONTAINER_PLUGIN_DIR=Container
     TRANSPORT_PLUGIN_DIR=Transport
+    DISCOVERY_PLUGIN_DIR=Discovery
 fi
 
 AC_SUBST(INPUT_PLUGIN_DIR)
--- a/src/audacious/Makefile	Thu Aug 02 17:42:38 2007 +0200
+++ b/src/audacious/Makefile	Fri Aug 03 07:20:58 2007 +0300
@@ -66,6 +66,7 @@
 	auddrct.c \
 	build_stamp.c \
 	configdb.c \
+	discovery.c \
 	dnd.c \
 	dock.c \
 	effect.c \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/discovery.c	Fri Aug 03 07:20:58 2007 +0300
@@ -0,0 +1,168 @@
+/*  BMP - Cross-platform multimedia player
+ *  Copyright (C) 2003-2004  BMP development team.
+ *
+ *  Based on XMMS:
+ *  Copyright (C) 1998-2003  XMMS development team.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU Discovery Public License as published by
+ *  the Free Software Foundation; under version 3 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Discovery Public License for more details.
+ *
+ *  You should have received a copy of the GNU Discovery Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses>.
+ *
+ *  The Audacious team does not consider modular code linking to
+ *  Audacious or using our public API to be a derived work.
+ */
+
+#include <glib.h>
+#include <string.h>
+#include "plugin.h"
+#include "discovery.h"
+
+DiscoveryPluginData dp_data = {
+    NULL,
+    NULL
+};
+
+GList *
+get_discovery_list(void)
+{
+    return dp_data.discovery_list;
+}
+
+GList *
+get_discovery_enabled_list(void)
+{
+    return dp_data.enabled_list;
+}
+
+static DiscoveryPlugin *
+get_discovery_plugin(gint i)
+{
+    GList *node = g_list_nth(get_discovery_list(), i);
+
+    if (!node)
+        return NULL;
+
+    return DISCOVERY_PLUGIN(node->data);
+}
+
+
+void
+discovery_about(gint i)
+{
+    DiscoveryPlugin *plugin = get_discovery_plugin(i);
+
+    if (!plugin || !plugin->about)
+        return;
+
+    plugin->about();
+}
+
+void
+discovery_configure(gint i)
+{
+    DiscoveryPlugin *plugin = get_discovery_plugin(i);
+
+    if (!plugin || !plugin->configure)
+        return;
+
+    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)
+{
+    DiscoveryPlugin *plugin = get_discovery_plugin(i);
+
+    if (!plugin)
+        return;
+
+    if (enable && !discovery_plugin_is_enabled(plugin)) {
+        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)) {
+        dp_data.enabled_list = g_list_remove(dp_data.enabled_list, plugin);
+        if (plugin->cleanup)
+            plugin->cleanup();
+    }
+}
+
+gboolean
+discovery_enabled(gint i)
+{
+    return (g_list_find(dp_data.enabled_list,
+                        get_discovery_plugin(i)) != NULL);
+}
+
+gchar *
+discovery_stringify_enabled_list(void)
+{
+    GString *enable_str;
+    gchar *name;
+    GList *node = get_discovery_enabled_list();
+
+    if (!node)
+        return NULL;
+
+    name = g_path_get_basename(DISCOVERY_PLUGIN(node->data)->filename);
+    enable_str = g_string_new(name);
+    g_free(name);
+
+    for (node = g_list_next(node); node; node = g_list_next(node)) {
+        name = g_path_get_basename(DISCOVERY_PLUGIN(node->data)->filename);
+        g_string_append_c(enable_str, ',');
+        g_string_append(enable_str, name);
+        g_free(name);
+    }
+
+    return g_string_free(enable_str, FALSE);
+}
+
+void
+discovery_enable_from_stringified_list(const gchar * list_str)
+{
+    gchar **list, **str;
+    DiscoveryPlugin *plugin;
+
+    if (!list_str || !strcmp(list_str, ""))
+        return;
+
+    list = g_strsplit(list_str, ",", 0);
+
+    for (str = list; *str; str++) {
+        GList *node;
+
+        for (node = get_discovery_list(); node; node = g_list_next(node)) {
+            gchar *base;
+
+            base = g_path_get_basename(DISCOVERY_PLUGIN(node->data)->filename);
+
+            if (!strcmp(*str, base)) {
+                plugin = DISCOVERY_PLUGIN(node->data);
+                dp_data.enabled_list = g_list_append(dp_data.enabled_list,
+                                                      plugin);
+                if (plugin->init)
+                    plugin->init();
+            }
+
+            g_free(base);
+        }
+    }
+
+    g_strfreev(list);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/discovery.h	Fri Aug 03 07:20:58 2007 +0300
@@ -0,0 +1,46 @@
+/*  BMP - Cross-platform multimedia player
+ *  Copyright (C) 2003-2004  BMP development team.
+ *
+ *  Based on XMMS:
+ *  Copyright (C) 1998-2003  XMMS development team.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; under version 3 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses>.
+ *
+ *  The Audacious team does not consider modular code linking to
+ *  Audacious or using our public API to be a derived work.
+ */
+
+#ifndef DISCOVERY_H
+#define DISCOVERY_H
+
+#include <glib.h>
+
+typedef struct _DiscoveryPluginData DiscoveryPluginData;
+
+struct _DiscoveryPluginData {
+    GList *discovery_list;
+    GList *enabled_list;
+};
+
+GList *get_discovery_list(void);
+GList *get_discovery_enabled_list(void);
+void enable_discovery_plugin(gint i, gboolean enable);
+void discovery_about(gint i);
+void discovery_configure(gint i);
+gboolean discovery_enabled(gint i);
+gchar *discovery_stringify_enabled_list(void);
+void discovery_enable_from_stringified_list(const gchar * list);
+
+extern DiscoveryPluginData dp_data;
+
+#endif
--- a/src/audacious/main.h	Thu Aug 02 17:42:38 2007 +0200
+++ b/src/audacious/main.h	Fri Aug 03 07:20:58 2007 +0300
@@ -84,7 +84,7 @@
     gchar *playlist_path;
     gchar *playlist_font, *mainwin_font;
     gchar *disabled_iplugins;
-    gchar *enabled_gplugins, *enabled_vplugins, *enabled_eplugins;
+    gchar *enabled_gplugins, *enabled_vplugins, *enabled_eplugins, *enabled_dplugins ;
     gchar *eqpreset_default_file, *eqpreset_extension;
     GList *url_history;
     gint timer_mode;
--- a/src/audacious/plugin.h	Thu Aug 02 17:42:38 2007 +0200
+++ b/src/audacious/plugin.h	Fri Aug 03 07:20:58 2007 +0300
@@ -46,6 +46,7 @@
 #define EFFECT_PLUGIN(x)  ((EffectPlugin *)(x))
 #define GENERAL_PLUGIN(x) ((GeneralPlugin *)(x))
 #define VIS_PLUGIN(x)     ((VisPlugin *)(x))
+#define DISCOVERY_PLUGIN(x)     ((DiscoveryPlugin *)(x))
 
 #define LOWLEVEL_PLUGIN(x) ((LowlevelPlugin *)(x))
 
@@ -78,7 +79,7 @@
 typedef struct _EffectPlugin  EffectPlugin;
 typedef struct _GeneralPlugin GeneralPlugin;
 typedef struct _VisPlugin     VisPlugin;
-
+typedef struct _DiscoveryPlugin DiscoveryPlugin;
 typedef struct _LowlevelPlugin LowlevelPlugin;
 
 typedef struct _InputPlayback InputPlayback;
@@ -102,15 +103,16 @@
     EffectPlugin **ep_list;
     GeneralPlugin **gp_list;
     VisPlugin **vp_list;
+    DiscoveryPlugin **dp_list;
 } PluginHeader;
 
 #define PLUGIN_MAGIC 0x8EAC8DE2
 
-#define DECLARE_PLUGIN(name, init, fini, ip_list, op_list, ep_list, gp_list, vp_list) \
+#define DECLARE_PLUGIN(name, init, fini, ip_list, op_list, ep_list, gp_list, vp_list, dp_list) \
 	G_BEGIN_DECLS \
 	static PluginHeader _pluginInfo = { PLUGIN_MAGIC, __AUDACIOUS_PLUGIN_API__, \
 		(gchar *)#name, init, fini, NULL, ip_list, op_list, ep_list, gp_list, \
-		vp_list }; \
+		vp_list,dp_list }; \
 	G_MODULE_EXPORT PluginHeader *get_plugin_info(void) { \
 		return &_pluginInfo; \
 	} \
@@ -278,6 +280,17 @@
     void (*render_freq) (gint16 freq_data[2][256]);
 };
 
+struct _DiscoveryPlugin {
+    gpointer handle;
+    gchar *filename;
+    gchar *description;
+ 
+    void (*init) (void);
+    void (*cleanup) (void);
+    void (*about) (void);
+    void (*configure) (void);
+    gchar *(*get_devices);  
+};
 
 G_BEGIN_DECLS
 
--- a/src/audacious/pluginenum.c	Thu Aug 02 17:42:38 2007 +0200
+++ b/src/audacious/pluginenum.c	Fri Aug 03 07:20:58 2007 +0300
@@ -50,7 +50,7 @@
 #include "input.h"
 #include "output.h"
 #include "visualization.h"
-
+#include "discovery.h"
 const gchar *plugin_dir_list[] = {
     PLUGINSUBS,
     NULL
@@ -58,7 +58,6 @@
 
 GHashTable *plugin_matrix = NULL;
 GList *lowlevel_list = NULL;
-
 extern GList *vfs_transports;
 
 static gint
@@ -111,6 +110,16 @@
         return 0;
 }
 
+static gint
+discoverylist_compare_func(gconstpointer a, gconstpointer b)
+{
+    const DiscoveryPlugin *ap = a, *bp = b;
+    if(ap->description && bp->description)
+        return strcasecmp(ap->description, bp->description);
+    else
+        return 0;
+}
+
 static gboolean
 plugin_is_duplicate(const gchar * filename)
 {
@@ -140,7 +149,11 @@
             return TRUE;
 
     for (l = lowlevel_list; l; l = g_list_next(l))
-        if (!strcmp(basename, g_basename(VIS_PLUGIN(l->data)->filename)))
+        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;
 
     return FALSE;
@@ -200,6 +213,13 @@
     vp_data.vis_list = g_list_append(vp_data.vis_list, p);
 }
 
+static void
+discovery_plugin_init(Plugin * plugin)
+{
+    DiscoveryPlugin *p = DISCOVERY_PLUGIN(plugin);
+    dp_data.discovery_list = g_list_append(dp_data.discovery_list, p);
+}
+
 /*******************************************************************/
 
 static void
@@ -224,6 +244,8 @@
     EffectPlugin **ep_iter;
     GeneralPlugin **gp_iter;
     VisPlugin **vp_iter;
+    DiscoveryPlugin **dp_iter;
+
 
     if (header->magic != PLUGIN_MAGIC)
         return plugin2_dispose(module, "plugin <%s> discarded, invalid module magic", filename);
@@ -290,6 +312,17 @@
             vis_plugin_init(PLUGIN(*vp_iter));
         }
     }
+
+    if (header->dp_list)
+    {
+        for (dp_iter = header->dp_list; *dp_iter != NULL; dp_iter++)
+        {
+            PLUGIN(*dp_iter)->filename = g_strdup(filename);
+            g_print("plugin2 '%s' provides DiscoveryPlugin <%p>\n", filename, *dp_iter);
+            discovery_plugin_init(PLUGIN(*dp_iter));
+        }
+    }
+
 }
 
 void
@@ -374,6 +407,7 @@
     OutputPlugin *op;
     InputPlugin *ip;
     LowlevelPlugin *lp;
+    DiscoveryPlugin *dp;
     gint dirsel = 0, i = 0;
 
     if (!g_module_supported()) {
@@ -387,7 +421,8 @@
 #ifndef DISABLE_USER_PLUGIN_DIR
     scan_plugins(bmp_paths[BMP_PATH_USER_PLUGIN_DIR]);
     /*
-     * This is in a separate loop so if the user puts them in the
+     * This is in a separate lo
+     * DiscoveryPlugin *dpop so if the user puts them in the
      * wrong dir we'll still get them in the right order (home dir
      * first)                                                - Zinx
      */
@@ -423,9 +458,14 @@
     vp_data.vis_list = g_list_sort(vp_data.vis_list, vislist_compare_func);
     vp_data.enabled_list = NULL;
 
+    dp_data.discovery_list = g_list_sort(dp_data.discovery_list, discoverylist_compare_func);
+    dp_data.enabled_list = NULL;
+
+
     general_enable_from_stringified_list(cfg.enabled_gplugins);
     vis_enable_from_stringified_list(cfg.enabled_vplugins);
     effect_enable_from_stringified_list(cfg.enabled_eplugins);
+    discovery_enable_from_stringified_list(cfg.enabled_dplugins);
 
     g_free(cfg.enabled_gplugins);
     cfg.enabled_gplugins = NULL;
@@ -436,6 +476,10 @@
     g_free(cfg.enabled_eplugins);
     cfg.enabled_eplugins = NULL;
 
+    g_free(cfg.enabled_dplugins);
+    cfg.enabled_dplugins = NULL;
+
+
     for (node = op_data.output_list; node; node = g_list_next(node)) {
         op = OUTPUT_PLUGIN(node->data);
         /*
@@ -455,6 +499,13 @@
             ip->init();
     }
 
+    for (node = dp_data.discovery_list; node; node = g_list_next(node)) {
+        dp = DISCOVERY_PLUGIN(node->data);
+        if (dp->init)
+            dp->init();
+    }
+
+
     for (node = lowlevel_list; node; node = g_list_next(node)) {
         lp = LOWLEVEL_PLUGIN(node->data);
         if (lp->init)
@@ -485,6 +536,7 @@
     GeneralPlugin *gp;
     VisPlugin *vp;
     LowlevelPlugin *lp;
+    DiscoveryPlugin *dp;
     GList *node;
 
     g_message("Shutting down plugin system");
@@ -593,6 +645,28 @@
         vp_data.vis_list = NULL;
     }
 
+
+    for (node = get_discovery_list(); node; node = g_list_next(node)) {
+        dp = DISCOVERY_PLUGIN(node->data);
+        if (dp && dp->cleanup) {
+            dp->cleanup();
+            GDK_THREADS_LEAVE();
+            while (g_main_context_iteration(NULL, FALSE));
+            GDK_THREADS_ENTER();
+        }
+
+        if (dp->handle)
+            g_module_close(dp->handle);
+    }
+
+    if (dp_data.discovery_list != NULL)
+    {
+        g_list_free(dp_data.discovery_list);
+        dp_data.discovery_list = NULL;
+    }
+
+
+
     for (node = lowlevel_list; node; node = g_list_next(node)) {
         lp = LOWLEVEL_PLUGIN(node->data);
         if (lp && lp->cleanup) {