# $Id$
+2006-01-07
+ * Added Audacious media player support.
+
2006-01-06
* Fixed infopipe bug (select() affects timer as a side effect on
Linux!)
-AC_INIT([Conky],[1.3.6_CVS_20060106],[brenden1@users.sourceforge.net])
+AC_INIT([Conky],[1.3.6_CVS_20060107],[brenden1@users.sourceforge.net])
-AM_INIT_AUTOMAKE(conky, 1.3.6_CVS_20060106)
+AM_INIT_AUTOMAKE(conky, 1.3.6_CVS_20060107)
AM_CONFIG_HEADER(src/config.h)
AC_PROG_LIBTOOL
fi
dnl
+dnl Audacious
+dnl
+
+want_audacious=no
+AC_ARG_ENABLE(audacious,
+ [ --enable-audacious enable if you want Audacious support [[default=no]]],
+ [want_audacious="$enableval"])
+
+AM_CONDITIONAL(BUILD_AUDACIOUS, test x$want_audacious = xyes)
+if test x$want_audacious = xyes; then
+ PKG_CHECK_MODULES([AUDACIOUS], [audacious >= 0.1],
+ [], [AC_MSG_ERROR([Audacious 0.1 or higher is not installed])])
+ CFLAGS="$CFLAGS $AUDACIOUS_CFLAGS"
+ LIBS="$LIBS $AUDACIOUS_LIBS"
+ AC_DEFINE(AUDACIOUS, 1, [Define if you want BMPx support])
+fi
+
+dnl
dnl BMPx
dnl
bin_PROGRAMS = conky
+if BUILD_AUDACIOUS
+audacious = audacious.c
+endif
+
if BUILD_BMPX
bmpx = bmpx.c
endif
x11 = x11.c
endif
-conky_SOURCES = common.c fs.c $(linux) mail.c mixer.c $(seti) $(mpd) $(solaris) $(freebsd) $(netbsd) $(port_monitors) conky.c conky.h $(x11) $(mldonkey) remoted.c remoted.h remotec.c remotec.h $(bmpx) $(infopipe)
+conky_SOURCES = common.c fs.c $(linux) mail.c mixer.c $(seti) $(mpd) $(solaris) $(freebsd) $(netbsd) $(port_monitors) conky.c conky.h $(x11) $(mldonkey) remoted.c remoted.h remotec.c remotec.h $(audacious) $(bmpx) $(infopipe)
AM_LDFLAGS = $(X11_LIBS) $(XFT_LIBS) $(CAIRO_LIBS) $(PTHREAD_LIBS) -lm
--- /dev/null
+/* -------------------------------------------------------------------------
+ * audacious.c: conky support for Audacious media player
+ *
+ * http://audacious-media-player.org
+ *
+ * Copyright (C) 2005 Philip Kovacs kovacsp3@comcast.net
+ *
+ * $Id$
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * --------------------------------------------------------------------------- */
+
+#include <pthread.h>
+/*#include <glib.h>*/
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <audacious/beepctrl.h>
+#include "audacious.h"
+#include "conky.h"
+
+/* access to this item array is synchronized with mutexes */
+static audacious_t g_items;
+
+/* ----------------------------------------
+ * Conky update function for Audacious data.
+ * ---------------------------------------- */
+void update_audacious(void)
+{
+ /*
+ The worker thread is updating ihe g_items array asynchronously to the main
+ conky thread. We merely copy the g_items array into the main thread's info
+ structure when the main thread's update cycle fires. Note that using the
+ mutexes here makes it easier since we won't have to do any sync in conky.c.
+ */
+ pthread_mutex_lock(&info.audacious.item_mutex);
+ memcpy(&info.audacious.items,g_items,sizeof(g_items));
+ pthread_mutex_unlock(&info.audacious.item_mutex);
+}
+
+
+/* --------------------------------------------------
+ * Worker thread function for Audacious data sampling.
+ * -------------------------------------------------- */
+void *audacious_thread_func(void *pvoid)
+{
+ int runnable;
+ static audacious_t items;
+ int session,playpos,frames,length;
+ int rate,freq,chans;
+ char *psong;
+
+ pvoid=(void*)pvoid; /* useless cast to avoid unused var warning */
+ session=0;
+
+ /* Grab the runnable signal. Should be non-zero here or we do nothing. */
+ pthread_mutex_lock(&info.audacious.runnable_mutex);
+ runnable=info.audacious.runnable;
+ pthread_mutex_unlock(&info.audacious.runnable_mutex );
+
+ /* 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)) {
+ memset(&items,0,sizeof(items));
+ strcpy(items[AUDACIOUS_STATUS],"Not running");
+ break;
+ }
+
+ /* Player status */
+ if (xmms_remote_is_paused(session))
+ strcpy(items[AUDACIOUS_STATUS],"Paused");
+ else if (xmms_remote_is_playing(session))
+ strcpy(items[AUDACIOUS_STATUS],"Playing");
+ else
+ strcpy(items[AUDACIOUS_STATUS],"Stopped");
+
+ /* Current song title */
+ playpos = (int) xmms_remote_get_playlist_pos(session);
+ psong = (char *) xmms_remote_get_playlist_title(session, playpos);
+ if (psong)
+ strncpy(items[AUDACIOUS_SONG],psong,sizeof(items[AUDACIOUS_SONG]));
+
+ /* Current song length as MM:SS */
+ frames = xmms_remote_get_playlist_time(session,playpos);
+ length = frames / 1000;
+ snprintf(items[AUDACIOUS_SONG_LENGTH],sizeof(items[AUDACIOUS_SONG_LENGTH]),
+ "%d:%.2d", length / 60, length % 60);
+
+ /* Current song length in seconds */
+ snprintf(items[AUDACIOUS_SONG_LENGTH_SECONDS],sizeof(items[AUDACIOUS_SONG_LENGTH_SECONDS]),
+ "%d", length);
+
+ /* Current song length in frames */
+ snprintf(items[AUDACIOUS_SONG_LENGTH_FRAMES],sizeof(items[AUDACIOUS_SONG_LENGTH_FRAMES]),
+ "%d", frames);
+
+ /* Current song output length as MM:SS */
+ frames = xmms_remote_get_output_time(session);
+ length = frames / 1000;
+ snprintf(items[AUDACIOUS_SONG_OUTPUT_LENGTH],sizeof(items[AUDACIOUS_SONG_OUTPUT_LENGTH]),
+ "%d:%.2d", length / 60, length % 60);
+
+ /* Current song output length in seconds */
+ snprintf(items[AUDACIOUS_SONG_OUTPUT_LENGTH_SECONDS],sizeof(items[AUDACIOUS_SONG_OUTPUT_LENGTH_SECONDS]),
+ "%d", length);
+
+ /* Current song output length in frames */
+ snprintf(items[AUDACIOUS_SONG_OUTPUT_LENGTH_FRAMES],sizeof(items[AUDACIOUS_SONG_OUTPUT_LENGTH_FRAMES]),
+ "%d", frames);
+
+ /* Current song bitrate */
+ xmms_remote_get_info(session, &rate, &freq, &chans);
+ snprintf(items[AUDACIOUS_SONG_BITRATE],sizeof(items[AUDACIOUS_SONG_BITRATE]), "%d", rate);
+
+ /* Current song frequency */
+ snprintf(items[AUDACIOUS_SONG_FREQUENCY],sizeof(items[AUDACIOUS_SONG_FREQUENCY]), "%d", freq);
+
+ /* Current song channels */
+ snprintf(items[AUDACIOUS_SONG_CHANNELS],sizeof(items[AUDACIOUS_SONG_CHANNELS]), "%d", chans);
+
+
+ break;
+ }
+
+ /* Deliver the refreshed items array to g_items. */
+ pthread_mutex_lock(&info.audacious.item_mutex);
+ memcpy(&g_items,items,sizeof(items));
+ pthread_mutex_unlock(&info.audacious.item_mutex);
+
+ /* Grab the runnable signal for next loop. */
+ pthread_mutex_lock(&info.audacious.runnable_mutex);
+ runnable=info.audacious.runnable;
+ pthread_mutex_unlock(&info.audacious.runnable_mutex);
+
+ sleep(1);
+ }
+
+ pthread_exit(NULL);
+}
--- /dev/null
+/* -------------------------------------------------------------------------
+ * audacious.h: conky support for Audacious audio player
+ *
+ * http://audacious-media-player.org
+ *
+ * Copyright (C) 2005 Philip Kovacs kovacsp3@comcast.net
+ *
+ * $Id$
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * --------------------------------------------------------------------------- */
+
+#ifndef AUDACIOUS_H
+#define AUDACIOUS_H
+
+/* 11 keys comprise the audacious information. */
+enum _audacious_keys {
+ AUDACIOUS_STATUS,
+ AUDACIOUS_SONG,
+ AUDACIOUS_SONG_LENGTH,
+ AUDACIOUS_SONG_LENGTH_SECONDS,
+ AUDACIOUS_SONG_LENGTH_FRAMES,
+ AUDACIOUS_SONG_OUTPUT_LENGTH,
+ AUDACIOUS_SONG_OUTPUT_LENGTH_SECONDS,
+ AUDACIOUS_SONG_OUTPUT_LENGTH_FRAMES,
+ AUDACIOUS_SONG_BITRATE,
+ AUDACIOUS_SONG_FREQUENCY,
+ AUDACIOUS_SONG_CHANNELS
+};
+
+/* 11 slots for the audacious values */
+typedef char audacious_t[11][128];
+
+/* Service routine for the conky main thread */
+void update_audacious(void);
+
+/* Thread function */
+void *audacious_thread_func(void *);
+
+#endif
if (NEED(INFO_MPD))
update_mpd();
#endif
+#ifdef AUDACIOUS
+ if (NEED(INFO_AUDACIOUS))
+ update_audacious();
+#endif
#ifdef BMPX
if (NEED(INFO_BMPX))
update_bmpx();
OBJ_mpd_track,
OBJ_mpd_percent,
#endif
+#ifdef AUDACIOUS
+ OBJ_audacious_status,
+ OBJ_audacious_song,
+ OBJ_audacious_song_length,
+ OBJ_audacious_song_length_seconds,
+ OBJ_audacious_song_length_frames,
+ OBJ_audacious_song_output_length,
+ OBJ_audacious_song_output_length_seconds,
+ OBJ_audacious_song_output_length_frames,
+ OBJ_audacious_song_bitrate,
+ OBJ_audacious_song_frequency,
+ OBJ_audacious_song_channels,
+ OBJ_audacious_bar,
+#endif
#ifdef BMPX
OBJ_bmpx_title,
OBJ_bmpx_artist,
(void) scan_bar(arg, &obj->data.pair.a, &obj->data.pair.b);
END
#endif
+#ifdef AUDACIOUS
+ OBJ(audacious_status, INFO_AUDACIOUS) END
+ OBJ(audacious_song, INFO_AUDACIOUS) END
+ OBJ(audacious_song_length, INFO_AUDACIOUS) END
+ OBJ(audacious_song_length_seconds, INFO_AUDACIOUS) END
+ OBJ(audacious_song_length_frames, INFO_AUDACIOUS) END
+ OBJ(audacious_song_output_length, INFO_AUDACIOUS) END
+ OBJ(audacious_song_output_length_seconds, INFO_AUDACIOUS) END
+ OBJ(audacious_song_output_length_frames, INFO_AUDACIOUS) END
+ OBJ(audacious_song_bitrate, INFO_AUDACIOUS) END
+ OBJ(audacious_song_frequency, INFO_AUDACIOUS) END
+ OBJ(audacious_song_channels, INFO_AUDACIOUS) END
+ OBJ(audacious_bar, INFO_AUDACIOUS)
+ (void) scan_bar(arg, &obj->a, &obj->b);
+ END
+#endif
#ifdef BMPX
OBJ(bmpx_title, INFO_BMPX)
memset(&(info.bmpx), 0, sizeof(struct bmpx_s));
255.0f));
}
#endif
+#ifdef AUDACIOUS
+ OBJ(audacious_status) {
+ snprintf(p, p_max_size, "%s", cur->audacious.items[AUDACIOUS_STATUS]);
+ }
+ OBJ(audacious_song) {
+ snprintf(p, p_max_size, "%s", cur->audacious.items[AUDACIOUS_SONG]);
+ }
+ OBJ(audacious_song_length) {
+ snprintf(p, p_max_size, "%s", cur->audacious.items[AUDACIOUS_SONG_LENGTH]);
+ }
+ OBJ(audacious_song_length_seconds) {
+ snprintf(p, p_max_size, "%s", cur->audacious.items[AUDACIOUS_SONG_LENGTH_SECONDS]);
+ }
+ OBJ(audacious_song_length_frames) {
+ snprintf(p, p_max_size, "%s", cur->audacious.items[AUDACIOUS_SONG_LENGTH_FRAMES]);
+ }
+ OBJ(audacious_song_output_length) {
+ snprintf(p, p_max_size, "%s", cur->audacious.items[AUDACIOUS_SONG_OUTPUT_LENGTH]);
+ }
+ OBJ(audacious_song_output_length_seconds) {
+ snprintf(p, p_max_size, "%s", cur->audacious.items[AUDACIOUS_SONG_OUTPUT_LENGTH_SECONDS]);
+ }
+ OBJ(audacious_song_output_length_frames) {
+ snprintf(p, p_max_size, "%s", cur->audacious.items[AUDACIOUS_SONG_OUTPUT_LENGTH_FRAMES]);
+ }
+ OBJ(audacious_song_bitrate) {
+ snprintf(p, p_max_size, "%s", cur->audacious.items[AUDACIOUS_SONG_BITRATE]);
+ }
+ OBJ(audacious_song_frequency) {
+ snprintf(p, p_max_size, "%s", cur->audacious.items[AUDACIOUS_SONG_FREQUENCY]);
+ }
+ OBJ(audacious_song_channels) {
+ snprintf(p, p_max_size, "%s", cur->audacious.items[AUDACIOUS_STATUS]);
+ }
+ OBJ(audacious_bar) {
+ double progress;
+ progress= atof(cur->audacious.items[AUDACIOUS_SONG_OUTPUT_LENGTH_SECONDS]) /
+ atof(cur->audacious.items[AUDACIOUS_SONG_LENGTH_SECONDS]);
+ new_bar(p,obj->a,obj->b,(int)(progress*255.0f));
+
+ }
+#endif
#ifdef BMPX
OBJ(bmpx_title) {
snprintf(p, p_max_size, "%s", cur->bmpx.title);
ERR("error setting signal handler: %s", strerror(errno) );
}
+#ifdef AUDACIOUS
+ /* joinable thread for audacious activity */
+ pthread_attr_init(&info.audacious.thread_attr);
+ pthread_attr_setdetachstate(&info.audacious.thread_attr, PTHREAD_CREATE_JOINABLE);
+ /* init mutexex */
+ pthread_mutex_init(&info.audacious.item_mutex, NULL);
+ pthread_mutex_init(&info.audacious.runnable_mutex, NULL);
+ /* init runnable condition for worker thread */
+ pthread_mutex_lock(&info.audacious.runnable_mutex);
+ info.audacious.runnable=1;
+ pthread_mutex_unlock(&info.audacious.runnable_mutex);
+ if (pthread_create(&info.audacious.thread, &info.audacious.thread_attr, audacious_thread_func, NULL))
+ {
+ CRIT_ERR("unable to create audacious thread!");
+ }
+#endif
#ifdef INFOPIPE
/* joinable thread for infopipe activity */
pthread_attr_init(&info.infopipe.thread_attr);
#endif
main_loop();
-
+
+#ifdef AUDACIOUS
+ /* signal audacious worker thread to terminate */
+ pthread_mutex_lock(&info.audacious.runnable_mutex);
+ info.audacious.runnable=0;
+ pthread_mutex_unlock(&info.audacious.runnable_mutex);
+ /* destroy thread attribute and wait for thread */
+ pthread_attr_destroy(&info.audacious.thread_attr);
+ if (pthread_join(info.audacious.thread, NULL))
+ {
+ ERR("error joining audacious thread");
+ }
+ /* destroy mutexes */
+ pthread_mutex_destroy(&info.audacious.item_mutex);
+ pthread_mutex_destroy(&info.audacious.runnable_mutex);
+#endif
#ifdef INFOPIPE
/* signal infopipe worker thread to terminate */
pthread_mutex_lock(&info.infopipe.runnable_mutex);
#ifndef _conky_h_
#define _conky_h_
-#ifdef INFOPIPE
+#if defined(AUDACIOUS) || defined(INFOPIPE)
#include <pthread.h>
#endif
#if defined(HAS_MCHECK_H)
};
#endif
+#ifdef AUDACIOUS
+#include "audacious.h"
+struct audacious_s {
+ audacious_t items; /* e.g. items[AUDACIOUS_STATUS] yields char[] */
+ int runnable; /* used to signal infopipe thread to stop */
+ pthread_t thread; /* worker thread for infopipe updating */
+ pthread_attr_t thread_attr; /* thread attributes */
+ pthread_mutex_t item_mutex; /* mutex for item array */
+ pthread_mutex_t runnable_mutex; /* mutex for runnable flag */
+};
+#endif
+
#ifdef BMPX
void update_bmpx();
struct bmpx_s {
#ifdef INFOPIPE
INFO_INFOPIPE = 24,
#endif
+#ifdef AUDACIOUS
+ INFO_AUDACIOUS = 25,
+#endif
};
struct mpd_s mpd;
mpd_Connection *conn;
#endif
+#ifdef AUDACIOUS
+ struct audacious_s audacious;
+#endif
#ifdef BMPX
struct bmpx_s bmpx;
#endif