run-time selection of xmms player using xmms_player
authorPhilip Kovacs <pkovacs@users.sourceforge.net>
Wed, 11 Jan 2006 17:03:45 +0000 (17:03 +0000)
committerPhilip Kovacs <pkovacs@users.sourceforge.net>
Wed, 11 Jan 2006 17:03:45 +0000 (17:03 +0000)
git-svn-id: https://conky.svn.sourceforge.net/svnroot/conky/trunk/conky@493 7f574dfc-610e-0410-a909-a81674777703

configure.in
doc/config_settings.xml
doc/conky.1
doc/docs.xml
src/conky.c
src/conky.h
src/xmms.c
src/xmms.h

index bc94cea..531722f 100644 (file)
@@ -3,6 +3,7 @@ AC_INIT([Conky],[1.3.6_CVS_20060108],[brenden1@users.sourceforge.net])
 AM_INIT_AUTOMAKE(conky, 1.3.6_CVS_20060108)
 AM_CONFIG_HEADER(src/config.h)
 AC_PROG_LIBTOOL
+PKG_PROG_PKG_CONFIG([0.17.2])
 
 
 AC_CONFIG_FILES(
@@ -43,8 +44,6 @@ AM_CONDITIONAL(BUILD_SOLARIS, test x$uname = xSunOS)
 AM_CONDITIONAL(BUILD_FREEBSD, test x$uname = xFreeBSD)
 AM_CONDITIONAL(BUILD_NETBSD, test x$uname = xNetBSD)
 
-PKG_PROG_PKG_CONFIG([0.17.2])
-
 dnl
 dnl XFT option
 dnl
@@ -81,46 +80,82 @@ if test $dah = "yes"; then
 fi
 
 dnl
-dnl XMMS_SUPPORT
+dnl XMMS (Version 1)
 dnl
 
-xmms_support=none
+want_xmms=no
 AC_ARG_ENABLE(xmms,
-   [  --enable-xmms[[=project]] none,xmms,bmp,audacious,infopipe [[default=none]]],
-   [xmms_support="$enableval"])
-
-case x$xmms_support in
-    xnone|xyes|xno)
-        ;;
-    xxmms)
-        AC_DEFINE(XMMS, 1, [Define for XMMS Version 1 support])
-       echo "Sorry, xmms isn't supported yet"
-       exit -1
-       ;;
-    xbmp)
-       PKG_CHECK_MODULES([XMMS], [bmp], [])
-       CFLAGS="$CFLAGS $XMMS_CFLAGS"
-       LIBS="$LIBS $XMMS_LIBS"
-       AC_DEFINE(BMP, 1, [Define for BMP support])
-       ;;
-    xaudacious)
-        PKG_CHECK_MODULES([XMMS], [audacious >= 0.1])
-        CFLAGS="$CFLAGS $XMMS_CFLAGS"
-       LIBS="$LIBS $XMMS_LIBS"
-        AC_DEFINE(AUDACIOUS, 1, [Define for Audacious support])
-        ;;
-    xinfopipe)
-        AC_DEFINE(INFOPIPE, 1, [Define for XMMS/BMP InfoPipe support])
-       ;;
-    *)
-        echo "Error: invalid xmms support specified: $xmms_support"
-       exit -1
-       ;;
-esac
-AM_CONDITIONAL(BUILD_XMMS, test x$xmms_support = xxmms)
-AM_CONDITIONAL(BUILD_BMP, test x$xmms_support = xbmp)
-AM_CONDITIONAL(BUILD_AUDACIOUS, test x$xmms_support = xaudacious)
-AM_CONDITIONAL(BUILD_INFOPIPE, test x$xmms_support = xinfopipe)
+   [  --enable-xmms           enable xmms (ver. 1) media player support [[default=no]]],
+   [want_xmms="$enableval"])
+
+if test x$want_xmms = "xyes"; then
+    AC_DEFINE(XMMS, 1, [Define for XMMS Version 1 support])
+    echo "Sorry, xmms isn't supported yet"
+    exit -1
+fi
+AM_CONDITIONAL(BUILD_XMMS, test x$want_xmms = xyes)
+
+dnl
+dnl BMP (through 0.9.7.1)
+dnl
+
+want_bmp=no
+AC_ARG_ENABLE(bmp,
+   [  --enable-bmp            enable beep media media player support [[default=no]]],
+   [want_bmp="$enableval"])
+
+if test x$want_bmp = "xyes"; then
+    AC_DEFINE(BMP, 1, [Define for Beep Media Player support])
+    PKG_CHECK_MODULES([BMP], [glib-2.0], [])
+    CFLAGS="$CFLAGS $BMP_CFLAGS"
+    LIBS="$LIBS $BMP_LIBS"
+    AC_CHECK_HEADERS([dlfcn.h], [], [DLFCN_MISSING=yes])
+    if test "x$DLFCN_MISSING" = xyes; then
+        AC_MSG_ERROR(["dlfcn.h missing: dynamic library loading not supported"])
+    fi
+    AC_CHECK_LIB(dl, dlopen,
+        LIBS="$LIBS -ldl",
+        AC_MSG_ERROR([Could not find dlopen in libdl]))
+fi
+AM_CONDITIONAL(BUILD_BMP, test x$want_bmp = xyes)
+
+dnl
+dnl Audacious Media Player
+dnl
+
+want_audacious=no
+AC_ARG_ENABLE(audacious,
+   [  --enable-audacious      enable beep audacious player support [[default=no]]],
+   [want_audacious="$enableval"])
+
+if test x$want_audacious = "xyes"; then
+    AC_DEFINE(AUDACIOUS, 1, [Define for Audacious support])
+    PKG_CHECK_MODULES([AUDACIOUS], [glib-2.0], [])
+    CFLAGS="$CFLAGS $AUDACIOUS_CFLAGS"
+    LIBS="$LIBS $AUDACIOUS_LIBS"
+    AC_CHECK_HEADERS([dlfcn.h], [], [DLFCN_MISSING=yes])
+    if test "x$DLFCN_MISSING" = xyes; then
+        AC_MSG_ERROR(["dlfcn.h missing: dynamic library loading not supported"])
+    fi
+    AC_CHECK_LIB(dl, dlopen,
+        LIBS="$LIBS -ldl",
+        AC_MSG_ERROR([Could not find dlopen in libdl]))
+fi
+AM_CONDITIONAL(BUILD_AUDACIOUS, test x$want_audacious = xyes)
+
+dnl
+dnl InfoPipe (Version 1.3)
+dnl
+
+want_infopipe=no
+AC_ARG_ENABLE(infopipe,
+   [  --enable-infopipe       enable xmms/bmp infopipe support [[default=no]]],
+   [want_infopipe="$enableval"])
+
+if test x$want_infopipe = "xyes"; then
+    AC_DEFINE(INFOPIPE, 1, [Define for InfoPipe support])
+fi
+AM_CONDITIONAL(BUILD_INFOPIPE, test x$want_infopipe = xyes)
 
 dnl
 dnl BMPx
index 3b4f721..544e552 100644 (file)
 </varlistentry>
 
 <varlistentry>
+       <term><command><option>min_port_monitors</option></command></term>
+       <listitem>
+               Allow for the creation of at least this number of port monitors (if 0 or not set, default is 16) 
+       <para></para></listitem>
+</varlistentry>
+
+<varlistentry>
+       <term><command><option>min_port_monitor_connections</option></command></term>
+       <listitem>
+               Allow each port monitor to track at least this many connections (if 0 or not set, default is 256)
+       <para></para></listitem>
+</varlistentry>
+
+<varlistentry>
        <term><command><option>mldonkey_hostname</option></command></term>
        <listitem>
                Hostname for mldonkey stuff, defaults to localhost
 </varlistentry>
 
 <varlistentry>
-       <term><command><option>min_port_monitors</option></command></term>
+       <term><command><option>xmms_player</option></command></term>
        <listitem>
-               Allow for the creation of at least this number of port monitors (if 0 or not set, default is 16) 
-       <para></para></listitem>
-</varlistentry>
-
-<varlistentry>
-       <term><command><option>min_port_monitor_connections</option></command></term>
-       <listitem>
-               Allow each port monitor to track at least this many connections (if 0 or not set, default is 256)
+               Use specified player/plugin for the xmms status variables.  Valid items are: none, xmms, bmp, audacious and infopipe. (default is none).  Note that bmpx is currently handled separately.
        <para></para></listitem>
 </varlistentry>
 
index 1bf4cae..01c6578 100644 (file)
@@ -35,7 +35,7 @@ Example to compile and run Conky with all optional components (note that some co
 .TP 
 \fBsh autogen.sh\fR \fB# Only required if building from CVS\fR 
 .TP 
-\fB\&./configure \fR\fB\-\-prefix=/usr \-\-mandir=/usr/share/man \-\-infodir=/usr/share/info \-\-datadir=/usr/share \-\-sysconfdir=/etc \-\-localstatedir=/var/lib \-\-enable\-xft \-\-enable\-seti \-\-enable\-double\-buffer \-\-enable\-own\-window \-\-enable\-proc\-uptime \-\-enable\-mpd \-\-enable\-mldonkey \-\-enable\-x11 \-\-enable\-portmon \-\-enable\-bmpx \-\-enable\-xmms=[project]\fR 
+\fB\&./configure \fR\fB\-\-prefix=/usr \-\-mandir=/usr/share/man \-\-infodir=/usr/share/info \-\-datadir=/usr/share \-\-sysconfdir=/etc \-\-localstatedir=/var/lib \-\-enable\-xft \-\-enable\-seti \-\-enable\-double\-buffer \-\-enable\-own\-window \-\-enable\-proc\-uptime \-\-enable\-mpd \-\-enable\-mldonkey \-\-enable\-x11 \-\-enable\-portmon \-\-enable\-xmms \-\-enable\-bmp \-\-enable\-audacious \-\-enable\-infopipe \-\-enable\-bmpx \fR
 .TP 
 \fBmake\fR 
 .TP 
@@ -211,6 +211,14 @@ Maximum width of window
 Minimum size of window
 
 .TP 
+\fBmin_port_monitors\fR
+Allow for the creation of at least this number of port monitors (if 0 or not set, default is 16) 
+
+.TP 
+\fBmin_port_monitor_connections\fR
+Allow each port monitor to track at least this many connections (if 0 or not set, default is 256)
+
+.TP 
 \fBmldonkey_hostname\fR
 Hostname for mldonkey stuff, defaults to localhost
 
@@ -291,12 +299,8 @@ Adds spaces after certain objects to stop them from moving other things around.
 Use Xft (anti-aliased font and stuff)
 
 .TP 
-\fBmin_port_monitors\fR
-Allow for the creation of at least this number of port monitors (if 0 or not set, default is 16) 
-
-.TP 
-\fBmin_port_monitor_connections\fR
-Allow each port monitor to track at least this many connections (if 0 or not set, default is 256)
+\fBxmms_player\fR
+Use specified player/plugin for the xmms status variables. Valid items are: none, xmms, bmp, audacious and infopipe. (default is none). Note that bmpx is currently handled separately.
 
 .TP 
 \fBTEXT\fR
index 5a09133..8f14c34 100644 (file)
@@ -79,7 +79,7 @@
                        </varlistentry>
                        <varlistentry>
                                <term>
-                                       <command><option>./configure </option></command><option>--prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --datadir=/usr/share --sysconfdir=/etc --localstatedir=/var/lib --enable-xft --enable-seti --enable-double-buffer --enable-own-window --enable-proc-uptime --enable-mpd --enable-mldonkey --enable-x11 --enable-portmon --enable-bmpx --enable-xmms=[project]</option>
+                                       <command><option>./configure </option></command><option>--prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --datadir=/usr/share --sysconfdir=/etc --localstatedir=/var/lib --enable-xft --enable-seti --enable-double-buffer --enable-own-window --enable-proc-uptime --enable-mpd --enable-mldonkey --enable-x11 --enable-portmon --enable-xmms --enable-bmp --enable-audacious --enable-infopipe --enable-bmpx </option>
                                </term>
                        </varlistentry>
                        <varlistentry>
index 6bed45e..cf9358d 100644 (file)
@@ -4565,6 +4565,19 @@ void reload_config(void)
                destroy_tcp_port_monitor_collection( info.p_tcp_port_monitor_collection );
                info.p_tcp_port_monitor_collection = NULL; 
 #endif
+#if defined(XMMS) || defined(BMP) || defined(AUDACIOUS) || defined(INFOPIPE)
+                if (info.xmms.thread) {
+                    if (destroy_xmms_thread()!=0)
+                    {
+                        ERR("error destroying xmms thread");
+                    }
+               }
+                if ( (!info.xmms.thread) && (info.xmms.current_project > PROJECT_NONE) && 
+                    (create_xmms_thread() !=0) )
+                    {
+                        CRIT_ERR("unable to create xmms thread!");
+                    }
+#endif
                extract_variable_text(text);
                free(text);
                text = NULL;
@@ -4618,6 +4631,12 @@ void clean_up(void)
        destroy_tcp_port_monitor_collection( info.p_tcp_port_monitor_collection );
        info.p_tcp_port_monitor_collection = NULL;
 #endif
+#if defined(XMMS) || defined(BMP) || defined(AUDACIOUS) || defined(INFOPIPE)
+        if ( info.xmms.thread && (destroy_xmms_thread()!=0) )
+        {
+            ERR("error destroying xmms thread");
+        }
+#endif
 }
 
 static int string_to_bool(const char *s)
@@ -4725,6 +4744,10 @@ static void set_default_configurations(void)
        tcp_port_monitor_collection_args.min_port_monitors = MIN_PORT_MONITORS_DEFAULT;
        tcp_port_monitor_args.min_port_monitor_connections = MIN_PORT_MONITOR_CONNECTIONS_DEFAULT;
 #endif
+
+#if defined(XMMS) || defined(BMP) || defined(AUDACIOUS) || defined(INFOPIPE)
+       info.xmms.current_project=PROJECT_NONE;
+#endif
 }
 
 static void load_config_file(const char *f)
@@ -4847,6 +4870,26 @@ else if (strcasecmp(name, a) == 0 || strcasecmp(name, b) == 0)
                                CONF_ERR;
                }
 #endif /* X11 */
+#if defined(XMMS) || defined(BMP) || defined(AUDACIOUS) || defined(INFOPIPE)
+               CONF("xmms_player") {
+                       if (value) {
+                               if (strncmp(value,"none",4)==0)
+                                   info.xmms.current_project=PROJECT_NONE;
+                               else if (strncmp(value,"xmms",4)==0)
+                                   info.xmms.current_project=PROJECT_XMMS;
+                               else if (strncmp(value,"bmp",3)==0)
+                                   info.xmms.current_project=PROJECT_BMP;
+                               else if (strncmp(value,"audacious",9)==0)
+                                   info.xmms.current_project=PROJECT_AUDACIOUS;
+                               else if  (strncmp(value,"infopipe",8)==0)
+                                   info.xmms.current_project=PROJECT_INFOPIPE;
+                               else
+                                       CONF_ERR;
+                       }
+                       else
+                               CONF_ERR;
+               }
+#endif
 #ifdef MPD
                CONF("mpd_host") {
                        if (value)
@@ -5206,6 +5249,19 @@ int main(int argc, char **argv)
        tcp_port_monitor_collection_args.min_port_monitors = MIN_PORT_MONITORS_DEFAULT;
        tcp_port_monitor_args.min_port_monitor_connections = MIN_PORT_MONITOR_CONNECTIONS_DEFAULT;
 #endif
+
+#if defined(XMMS)
+       SET_XMMS_PROJECT_AVAILABLE(info.xmms.project_mask, PROJECT_XMMS);
+#endif
+#if defined(BMP)
+       SET_XMMS_PROJECT_AVAILABLE(info.xmms.project_mask, PROJECT_BMP);
+#endif
+#if defined(AUDACIOUS)
+       SET_XMMS_PROJECT_AVAILABLE(info.xmms.project_mask, PROJECT_AUDACIOUS);
+#endif
+#if defined(INFOPIPE)
+       SET_XMMS_PROJECT_AVAILABLE(info.xmms.project_mask, PROJECT_INFOPIPE);
+#endif
                
        /* handle command line parameters that don't change configs */
 #ifdef X11
@@ -5486,17 +5542,7 @@ int main(int argc, char **argv)
        }
 
 #if defined(XMMS) || defined(BMP) || defined(AUDACIOUS) || defined(INFOPIPE)
-       /* joinable thread for xmms activity */
-        pthread_attr_init(&info.xmms.thread_attr);
-       pthread_attr_setdetachstate(&info.xmms.thread_attr, PTHREAD_CREATE_JOINABLE);
-       /* init mutexex */
-       pthread_mutex_init(&info.xmms.item_mutex, NULL);
-       pthread_mutex_init(&info.xmms.runnable_mutex, NULL);
-       /* init runnable condition for worker thread */
-       pthread_mutex_lock(&info.xmms.runnable_mutex);
-       info.xmms.runnable=1;
-       pthread_mutex_unlock(&info.xmms.runnable_mutex);
-       if (pthread_create(&info.xmms.thread, &info.xmms.thread_attr, xmms_thread_func, NULL))
+       if ( (info.xmms.current_project > PROJECT_NONE) && (create_xmms_thread() !=0) )
        {
            CRIT_ERR("unable to create xmms thread!");
        }
@@ -5505,19 +5551,10 @@ int main(int argc, char **argv)
        main_loop();
 
 #if defined(XMMS) || defined(BMP) || defined(AUDACIOUS) || defined(INFOPIPE)
-        /* signal xmms worker thread to terminate */
-        pthread_mutex_lock(&info.xmms.runnable_mutex);
-        info.xmms.runnable=0;
-        pthread_mutex_unlock(&info.xmms.runnable_mutex);
-        /* destroy thread attribute and wait for thread */
-        pthread_attr_destroy(&info.xmms.thread_attr);
-        if (pthread_join(info.xmms.thread, NULL))
+       if ( info.xmms.thread && (destroy_xmms_thread()!=0) )
         {
-            ERR("error joining xmms thread");
+            ERR("error destroying xmms thread");
         }
-        /* destroy mutexes */
-        pthread_mutex_destroy(&info.xmms.item_mutex);
-        pthread_mutex_destroy(&info.xmms.runnable_mutex);
 #endif 
 
        return 0;
index 5fa7c26..99f8ed1 100644 (file)
 #include <machine/apm_bios.h>
 #endif /* __FreeBSD__ */
 
+#if defined(XMMS) || defined(BMP) || defined(AUDACIOUS) || defined(INFOPIPE)
+#include "xmms.h"
+#endif
+
 #define TOP_CPU 1
 #define TOP_NAME 2
 #define TOP_PID 3
@@ -128,9 +132,10 @@ struct mpd_s {
 #endif
 
 #if defined(XMMS) || defined(BMP) || defined(AUDACIOUS) || defined(INFOPIPE)
-#include "xmms.h"
 struct xmms_s {
-       xmms_t items;                  /* e.g. items[XMMS_STATUS] yields char[] */
+       unsigned int project_mask;
+       unsigned int current_project;
+       xmms_t items;                   /* e.g. items[XMMS_STATUS] yields char[] */
        int runnable;                   /* used to signal worker thread to stop */
        pthread_t thread;               /* worker thread for xmms updating */
        pthread_attr_t thread_attr;     /* thread attributes */
index 1840a6d..49b5011 100644 (file)
 
 #if defined(XMMS) || defined(BMP) || defined(AUDACIOUS)
 #include <glib.h>
+#include <dlfcn.h>
 #endif
 
-#if defined(XMMS)
-#include <xmms/xmmsctrl.h>
-
-#elif defined(BMP)
-#include <bmp/beepctrl.h>
-
-#elif defined(AUDACIOUS)
-#include <audacious/beepctrl.h>
-
-#elif defined(INFOPIPE)
+#if defined(INFOPIPE)
 #include <sys/select.h>
 #include <sys/time.h>
 #include <sys/types.h>
@@ -90,23 +82,194 @@ void update_xmms(void)
 }
 
 
+/* ------------------------------------------------------------
+ * Create a worker thread for xmms-related media player status.
+ *
+ * Returns 0 on success, -1 on error. 
+ * ------------------------------------------------------------*/
+int create_xmms_thread(void)
+{
+    /* Was an an available project requested? */
+    if (!TEST_XMMS_PROJECT_AVAILABLE(info.xmms.project_mask, info.xmms.current_project))
+        return(-1);
+    
+    /* The project should not be PROJECT_NONE */
+    if (info.xmms.current_project==PROJECT_NONE)
+        return(-1);
+
+    /* Is a worker is thread already running? */
+    if (info.xmms.thread)
+       return(-1);
+
+    /* Joinable thread for xmms activity */
+    pthread_attr_init(&info.xmms.thread_attr);
+    pthread_attr_setdetachstate(&info.xmms.thread_attr, PTHREAD_CREATE_JOINABLE);
+    /* Init mutexes */
+    pthread_mutex_init(&info.xmms.item_mutex, NULL);
+    pthread_mutex_init(&info.xmms.runnable_mutex, NULL);
+    /* Init runnable condition for worker thread */
+    pthread_mutex_lock(&info.xmms.runnable_mutex);
+    info.xmms.runnable=1;
+    pthread_mutex_unlock(&info.xmms.runnable_mutex);
+#if defined(XMMS) || defined(BMP) || defined(AUDACIOUS)            
+    if (info.xmms.current_project==PROJECT_XMMS || 
+        info.xmms.current_project==PROJECT_BMP || 
+       info.xmms.current_project==PROJECT_AUDACIOUS) {
+        if (pthread_create(&info.xmms.thread, &info.xmms.thread_attr, xmms_thread_func_dynamic, NULL))
+            return(-1);
+    }
+#endif
+#if defined(INFOPIPE)
+    if (info.xmms.current_project==PROJECT_INFOPIPE) {
+       if (pthread_create(&info.xmms.thread, &info.xmms.thread_attr, xmms_thread_func_infopipe, NULL))
+            return(-1);
+    }
+#endif
+
+    return 0;
+}
+
+/* ------------------------------------------------
+ * Destroy xmms-related media player status thread.
+ *
+ * Returns 0 on success, -1 on error.
+ * ------------------------------------------------ */
+int destroy_xmms_thread(void)
+{
+    /* Is a worker is thread running? If not, no error. */
+    if (!info.xmms.thread)
+        return(0);
+
+    /* Signal xmms worker thread to terminate */
+    pthread_mutex_lock(&info.xmms.runnable_mutex);
+    info.xmms.runnable=0;
+    pthread_mutex_unlock(&info.xmms.runnable_mutex);
+    /* Destroy thread attribute and wait for thread */
+    pthread_attr_destroy(&info.xmms.thread_attr);
+    if (pthread_join(info.xmms.thread, NULL))
+        return(-1);
+    /* Destroy mutexes */
+    pthread_mutex_destroy(&info.xmms.item_mutex);
+    pthread_mutex_destroy(&info.xmms.runnable_mutex);
+
+    info.xmms.thread=(pthread_t)0;
+    return 0;
+}
+
 #if defined(XMMS) || defined(BMP) || defined(AUDACIOUS)
 /* ------------------------------------------------------------
  * Worker thread function for XMMS/BMP/Audacious data sampling.
  * ------------------------------------------------------------ */ 
-void *xmms_thread_func(void *pvoid)
+void *xmms_thread_func_dynamic(void *pvoid)
 {
+    void *handle;
+    const char *error;
     int runnable;
     static xmms_t items;
     gint session,playpos,frames,length;
     gint rate,freq,chans;
     gchar *psong,*pfilename;
 
-    pvoid=(void*)pvoid; /* useless cast to avoid unused var warning */
+    /* Function pointers for the functions we load dynamically */
+    gboolean (*xmms_remote_is_running)(gint session);
+    gboolean (*xmms_remote_is_paused)(gint session);
+    gboolean (*xmms_remote_is_playing)(gint session);
+    gint (*xmms_remote_get_playlist_pos)(gint session);
+    gchar *(*xmms_remote_get_playlist_title)(gint session, gint pos);
+    gint (*xmms_remote_get_playlist_time)(gint session, gint pos);
+    gint (*xmms_remote_get_output_time)(gint session);
+    void (*xmms_remote_get_info)(gint session, gint *rate, gint *freq, gint *chans);
+    gchar *(*xmms_remote_get_playlist_file)(gint session, gint pos);
+    gint (*xmms_remote_get_playlist_length)(gint session);
+
+    pvoid=(void *)pvoid;  /* avoid warning */
     session=0;
     psong=NULL;
     pfilename=NULL;
 
+    switch(info.xmms.current_project) {
+
+    case (PROJECT_XMMS) :
+           handle = dlopen("libxmms.so", RTLD_LAZY);
+           if (!handle) {
+               ERR("unable to open libxmms.so");
+               pthread_exit(NULL);
+           }
+           break;
+                   
+    case (PROJECT_BMP) :
+           handle = dlopen("libbeep.so", RTLD_LAZY);
+           if (!handle) {
+                ERR("unable to open libbeep.so");
+                pthread_exit(NULL);
+            }
+           break;
+
+    case (PROJECT_AUDACIOUS) :
+           handle = dlopen("libaudacious.so", RTLD_LAZY);
+           if (!handle) {
+                ERR("unable to open libaudacious.so");
+                pthread_exit(NULL);
+            }
+           break;
+
+    case (PROJECT_NONE) :
+    default :
+         pthread_exit(NULL);
+    }
+
+    /* Grab the function pointers from the library */
+    xmms_remote_is_running = dlsym(handle, "xmms_remote_is_running");
+    if ((error = dlerror()) != NULL) {
+        ERR("error grabbing function symbol");
+       pthread_exit(NULL);
+    }
+    xmms_remote_is_paused = dlsym(handle, "xmms_remote_is_paused");
+    if ((error = dlerror()) != NULL) {
+        ERR("error grabbing function symbol");
+       pthread_exit(NULL);
+    }
+    xmms_remote_is_playing = dlsym(handle, "xmms_remote_is_playing");
+    if ((error = dlerror()) != NULL) {
+        ERR("error grabbing function symbol");
+       pthread_exit(NULL);
+    }
+    xmms_remote_get_playlist_pos = dlsym(handle, "xmms_remote_get_playlist_pos");
+    if ((error = dlerror()) != NULL) {
+        ERR("error grabbing function symbol");
+       pthread_exit(NULL);
+    }
+    xmms_remote_get_playlist_title = dlsym(handle, "xmms_remote_get_playlist_title");
+    if ((error = dlerror()) != NULL) {
+        ERR("error grabbing function symbol");
+       pthread_exit(NULL);
+    }
+    xmms_remote_get_playlist_time = dlsym(handle, "xmms_remote_get_playlist_time");
+    if ((error = dlerror()) != NULL) {
+        ERR("error grabbing function symbol");
+       pthread_exit(NULL);
+    }
+    xmms_remote_get_output_time = dlsym(handle, "xmms_remote_get_output_time");
+    if ((error = dlerror()) != NULL) {
+        ERR("error grabbing function symbol");
+       pthread_exit(NULL);
+    }
+    xmms_remote_get_info = dlsym(handle, "xmms_remote_get_info");
+    if ((error = dlerror()) != NULL) {
+        ERR("error grabbing function symbol");
+       pthread_exit(NULL);
+    }
+    xmms_remote_get_playlist_file = dlsym(handle, "xmms_remote_get_playlist_file");
+    if ((error = dlerror()) != NULL) {
+        ERR("error grabbing function symbol");
+       pthread_exit(NULL);
+    }
+    xmms_remote_get_playlist_length = dlsym(handle, "xmms_remote_get_playlist_length");
+    if ((error = dlerror()) != NULL) {
+        ERR("error grabbing function symbol");
+       pthread_exit(NULL);
+    }
+
     /* Grab the runnable signal.  Should be non-zero here or we do nothing. */
     pthread_mutex_lock(&info.xmms.runnable_mutex);
     runnable=info.xmms.runnable;
@@ -115,53 +278,53 @@ void *xmms_thread_func(void *pvoid)
     /* Loop until the main thread sets the runnable signal to 0. */
     while(runnable) {
 
-       for (;;) {  /* convenience loop so we can break below */
-       
-            if (!xmms_remote_is_running(session)) {
+        for (;;) {  /* convenience loop so we can break below */
+
+            if (!(*xmms_remote_is_running)(session)) {
                 memset(&items,0,sizeof(items));
-               strcpy(items[XMMS_STATUS],"Not running");
-               break;
+                strcpy(items[XMMS_STATUS],"Not running");
+                break;
             }
 
-           /* Player status */
-           if (xmms_remote_is_paused(session))
-               strcpy(items[XMMS_STATUS],"Paused");
-           else if (xmms_remote_is_playing(session))
-                strcpy(items[XMMS_STATUS],"Playing");
-           else
-                strcpy(items[XMMS_STATUS],"Stopped");
-
-           /* Current song title */
-           playpos = xmms_remote_get_playlist_pos(session);
-           psong = xmms_remote_get_playlist_title(session, playpos);
-           if (psong) {
+            /* Player status */
+            if ((*xmms_remote_is_paused)(session))
+                strcpy(items[XMMS_STATUS],"Paused");
+            else if ((*xmms_remote_is_playing)(session))
+                 strcpy(items[XMMS_STATUS],"Playing");
+            else
+                 strcpy(items[XMMS_STATUS],"Stopped");
+
+            /* Current song title */
+            playpos = (*xmms_remote_get_playlist_pos)(session);
+            psong = (*xmms_remote_get_playlist_title)(session, playpos);
+            if (psong) {
                 strncpy(items[XMMS_TITLE],psong,sizeof(items[XMMS_TITLE])-1);
-               g_free(psong);
-               psong=NULL;
-           }
+                g_free(psong);
+                psong=NULL;
+            }
 
-           /* Current song length as MM:SS */ 
-            frames = xmms_remote_get_playlist_time(session,playpos);
-           length = frames / 1000;
+            /* Current song length as MM:SS */
+            frames = (*xmms_remote_get_playlist_time)(session,playpos);
+            length = frames / 1000;
             snprintf(items[XMMS_LENGTH],sizeof(items[XMMS_LENGTH])-1,
-                    "%d:%.2d", length / 60, length % 60);
-        
-           /* Current song length in seconds */
-           snprintf(items[XMMS_LENGTH_SECONDS],sizeof(items[XMMS_LENGTH_SECONDS])-1,
-                    "%d", length);
-
-           /* Current song position as MM:SS */ 
-            frames = xmms_remote_get_output_time(session);
-           length = frames / 1000;
+                     "%d:%.2d", length / 60, length % 60);
+
+            /* Current song length in seconds */
+            snprintf(items[XMMS_LENGTH_SECONDS],sizeof(items[XMMS_LENGTH_SECONDS])-1,
+                     "%d", length);
+
+            /* Current song position as MM:SS */
+            frames = (*xmms_remote_get_output_time)(session);
+            length = frames / 1000;
             snprintf(items[XMMS_POSITION],sizeof(items[XMMS_POSITION])-1,
-                    "%d:%.2d", length / 60, length % 60);
-        
-           /* Current song position in seconds */
-           snprintf(items[XMMS_POSITION_SECONDS],sizeof(items[XMMS_POSITION_SECONDS])-1,
-                    "%d", length);
+                     "%d:%.2d", length / 60, length % 60);
+
+            /* Current song position in seconds */
+            snprintf(items[XMMS_POSITION_SECONDS],sizeof(items[XMMS_POSITION_SECONDS])-1,
+                     "%d", length);
 
             /* Current song bitrate */
-            xmms_remote_get_info(session, &rate, &freq, &chans);
+            (*xmms_remote_get_info)(session, &rate, &freq, &chans);
             snprintf(items[XMMS_BITRATE],sizeof(items[XMMS_BITRATE])-1, "%d", rate);
 
             /* Current song frequency */
@@ -169,46 +332,48 @@ void *xmms_thread_func(void *pvoid)
 
             /* Current song channels */
             snprintf(items[XMMS_CHANNELS],sizeof(items[XMMS_CHANNELS])-1, "%d", chans);
-            
+
             /* Current song filename */
-           pfilename = xmms_remote_get_playlist_file(session,playpos);
-           if (pfilename) {
-               strncpy(items[XMMS_FILENAME],pfilename,sizeof(items[XMMS_FILENAME])-1);
-               g_free(pfilename);
-               pfilename=NULL;
-           }
+            pfilename = (*xmms_remote_get_playlist_file)(session,playpos);
+            if (pfilename) {
+                strncpy(items[XMMS_FILENAME],pfilename,sizeof(items[XMMS_FILENAME])-1);
+                g_free(pfilename);
+                pfilename=NULL;
+            }
 
-           /* Length of the Playlist (number of songs) */
-           length = xmms_remote_get_playlist_length(session);
-           snprintf(items[XMMS_PLAYLIST_LENGTH],sizeof(items[XMMS_PLAYLIST_LENGTH])-1, "%d", length);
+            /* Length of the Playlist (number of songs) */
+            length = (*xmms_remote_get_playlist_length)(session);
+            snprintf(items[XMMS_PLAYLIST_LENGTH],sizeof(items[XMMS_PLAYLIST_LENGTH])-1, "%d", length);
 
-           /* Playlist position (index of song) */
-           snprintf(items[XMMS_PLAYLIST_POSITION],sizeof(items[XMMS_PLAYLIST_POSITION])-1, "%d", playpos+1);
+            /* Playlist position (index of song) */
+            snprintf(items[XMMS_PLAYLIST_POSITION],sizeof(items[XMMS_PLAYLIST_POSITION])-1, "%d", playpos+1);
 
-           break;
-       }
+            break;
+        }
 
-       /* Deliver the refreshed items array to g_items. */
-       pthread_mutex_lock(&info.xmms.item_mutex);
+        /* Deliver the refreshed items array to g_items. */
+        pthread_mutex_lock(&info.xmms.item_mutex);
         memcpy(&g_items,items,sizeof(items));
-       pthread_mutex_unlock(&info.xmms.item_mutex);
+        pthread_mutex_unlock(&info.xmms.item_mutex);
 
-       /* Grab the runnable signal for next loop. */
+        /* Grab the runnable signal for next loop. */
         pthread_mutex_lock(&info.xmms.runnable_mutex);
         runnable=info.xmms.runnable;
         pthread_mutex_unlock(&info.xmms.runnable_mutex);
 
-       sleep(1);
+        sleep(1);
     }
 
+    dlclose(handle);
     pthread_exit(NULL);
 }
+#endif
 
-#elif defined(INFOPIPE)
+#if defined(INFOPIPE)
 /* --------------------------------------------------
  * Worker thread function for InfoPipe data sampling.
  * -------------------------------------------------- */ 
-void *xmms_thread_func(void *pvoid)
+void *xmms_thread_func_infopipe(void *pvoid)
 {
     int i,rc,fd,runnable;
     fd_set readset;
@@ -217,7 +382,7 @@ void *xmms_thread_func(void *pvoid)
     static xmms_t items;
     char *pbuf,c;
 
-    pvoid=(void*)pvoid; /* useless cast to avoid unused var warning */
+    pvoid=(void*)pvoid; /* avoid warning */
 
     /* Grab the runnable signal.  Should be non-zero here or we do nothing. */
     pthread_mutex_lock(&info.xmms.runnable_mutex);
index d3f8892..2c30558 100644 (file)
@@ -38,13 +38,31 @@ enum _xmms_items {
        XMMS_PLAYLIST_POSITION,
 };
 
+enum _xmms_projects {
+       PROJECT_NONE = 0,
+       PROJECT_XMMS = 1,
+       PROJECT_BMP = 2,
+       PROJECT_AUDACIOUS = 3,
+       PROJECT_INFOPIPE = 4
+};
+
+#define SET_XMMS_PROJECT_AVAILABLE(mask,project)       (mask |= (1<<project))
+#define TEST_XMMS_PROJECT_AVAILABLE(mask,project)      (mask & (1<<project))
+
 /* 12 slots for the xmms values */
 typedef char xmms_t[12][128];
 
+/* create a worker thread for xmms media player status */
+int create_xmms_thread(void);
+
+/* destroy xmms media player worker thread */
+int destroy_xmms_thread(void);
+
 /* Service routine for the conky main thread */
 void update_xmms(void);
 
-/* Thread function */
-void *xmms_thread_func(void *);
+/* Thread functions */
+void *xmms_thread_func_dynamic(void *);
+void *xmms_thread_func_infopipe(void *);
 
 #endif