2010-01-07 03:45:19 +00:00
|
|
|
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
|
|
|
|
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
|
2009-07-28 21:44:22 +00:00
|
|
|
*
|
|
|
|
* audacious.c: conky support for audacious music player
|
2006-11-03 20:54:52 +00:00
|
|
|
*
|
2007-08-10 20:09:43 +00:00
|
|
|
* Copyright (C) 2005-2007 Philip Kovacs pkovacs@users.sourceforge.net
|
2008-02-20 20:30:45 +00:00
|
|
|
*
|
2006-11-03 20:54:52 +00:00
|
|
|
* 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
|
2006-12-13 16:54:59 +00:00
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
2009-07-27 20:47:19 +00:00
|
|
|
* USA.
|
|
|
|
*
|
|
|
|
*/
|
2006-11-03 20:54:52 +00:00
|
|
|
|
2010-01-04 17:06:14 +00:00
|
|
|
#include <config.h>
|
2011-03-25 14:06:26 +00:00
|
|
|
|
|
|
|
#include <cmath>
|
|
|
|
|
2008-12-15 21:40:24 +00:00
|
|
|
#include "conky.h"
|
|
|
|
#include "logging.h"
|
|
|
|
#include "audacious.h"
|
2010-01-04 17:06:14 +00:00
|
|
|
#include <mutex>
|
2011-03-25 14:06:26 +00:00
|
|
|
#include "update-cb.hh"
|
2007-11-17 04:13:20 +00:00
|
|
|
|
2006-11-03 20:54:52 +00:00
|
|
|
#include <glib.h>
|
2010-11-12 15:49:34 +00:00
|
|
|
#ifdef NEW_AUDACIOUS_FOUND
|
2007-11-17 03:43:21 +00:00
|
|
|
#include <glib-object.h>
|
|
|
|
#include <audacious/audctrl.h>
|
|
|
|
#include <audacious/dbus.h>
|
2010-11-12 15:49:34 +00:00
|
|
|
#else /* NEW_AUDACIOUS_FOUND */
|
2006-11-03 20:54:52 +00:00
|
|
|
#include <audacious/beepctrl.h>
|
2008-02-20 20:30:45 +00:00
|
|
|
#define audacious_remote_is_running(x) \
|
|
|
|
xmms_remote_is_running(x)
|
|
|
|
#define audacious_remote_is_paused(x) \
|
|
|
|
xmms_remote_is_paused(x)
|
|
|
|
#define audacious_remote_is_playing(x) \
|
|
|
|
xmms_remote_is_playing(x)
|
|
|
|
#define audacious_remote_get_playlist_pos(x) \
|
|
|
|
xmms_remote_get_playlist_pos(x)
|
|
|
|
#define audacious_remote_get_playlist_title(x, y) \
|
|
|
|
xmms_remote_get_playlist_title(x, y)
|
|
|
|
#define audacious_remote_get_playlist_time(x, y) \
|
|
|
|
xmms_remote_get_playlist_time(x, y)
|
|
|
|
#define audacious_remote_get_output_time(x) \
|
|
|
|
xmms_remote_get_output_time(x)
|
|
|
|
#define audacious_remote_get_info(w, x, y, z) \
|
|
|
|
xmms_remote_get_info(w, x, y, z)
|
|
|
|
#define audacious_remote_get_playlist_file(x, y) \
|
|
|
|
xmms_remote_get_playlist_file(x, y)
|
|
|
|
#define audacious_remote_get_playlist_length(x) \
|
|
|
|
xmms_remote_get_playlist_length(x)
|
2010-11-12 15:49:34 +00:00
|
|
|
#endif /* NEW_AUDACIOUS_FOUND */
|
2006-11-03 20:54:52 +00:00
|
|
|
|
2011-03-25 14:06:26 +00:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
enum aud_status { AS_NOT_RUNNING, AS_PAUSED, AS_PLAYING, AS_STOPPED };
|
|
|
|
const char * const as_message[] = { "Not running", "Paused", "Playing", "Stopped" };
|
|
|
|
|
|
|
|
struct aud_result {
|
|
|
|
std::string title;
|
|
|
|
std::string filename;
|
|
|
|
int length; // in ms
|
|
|
|
int position; // in ms
|
|
|
|
int bitrate;
|
|
|
|
int frequency;
|
|
|
|
int channels;
|
|
|
|
int playlist_length;
|
|
|
|
int playlist_position;
|
|
|
|
int main_volume;
|
|
|
|
aud_status status;
|
|
|
|
|
|
|
|
aud_result()
|
|
|
|
: length(0), position(0), bitrate(0), frequency(0), channels(0), playlist_length(0),
|
|
|
|
playlist_position(0), main_volume(0), status(AS_NOT_RUNNING)
|
|
|
|
{}
|
|
|
|
};
|
|
|
|
|
|
|
|
class audacious_cb: public conky::callback<aud_result> {
|
|
|
|
typedef conky::callback<aud_result> Base;
|
2006-12-23 06:01:16 +00:00
|
|
|
|
2010-11-12 15:49:34 +00:00
|
|
|
#ifdef NEW_AUDACIOUS_FOUND
|
2011-03-25 14:06:26 +00:00
|
|
|
DBusGProxy *session;
|
2007-11-17 03:43:21 +00:00
|
|
|
#else
|
2011-03-25 14:06:26 +00:00
|
|
|
gint session;
|
2007-11-17 03:43:21 +00:00
|
|
|
#endif
|
|
|
|
|
2011-03-25 14:06:26 +00:00
|
|
|
protected:
|
|
|
|
virtual void work();
|
2006-12-23 06:01:16 +00:00
|
|
|
|
2011-03-25 14:06:26 +00:00
|
|
|
public:
|
|
|
|
audacious_cb(uint32_t period)
|
|
|
|
: Base(period, false, Tuple())
|
|
|
|
{
|
2010-11-12 15:49:34 +00:00
|
|
|
#ifdef NEW_AUDACIOUS_FOUND
|
2011-03-25 14:06:26 +00:00
|
|
|
g_type_init();
|
|
|
|
DBusGConnection *connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
|
|
|
|
if (!connection)
|
|
|
|
throw std::runtime_error("unable to establish dbus connection");
|
|
|
|
|
|
|
|
session = dbus_g_proxy_new_for_name(connection, AUDACIOUS_DBUS_SERVICE,
|
|
|
|
AUDACIOUS_DBUS_PATH, AUDACIOUS_DBUS_INTERFACE);
|
|
|
|
if (!session)
|
|
|
|
throw std::runtime_error("unable to create dbus proxy");
|
|
|
|
#else
|
|
|
|
session = 0;
|
2010-11-12 15:49:34 +00:00
|
|
|
#endif /* NEW_AUDACIOUS_FOUND */
|
2011-03-25 14:06:26 +00:00
|
|
|
}
|
2007-11-17 03:43:21 +00:00
|
|
|
|
2011-03-25 14:06:26 +00:00
|
|
|
#ifdef NEW_AUDACIOUS_FOUND
|
|
|
|
~audacious_cb()
|
|
|
|
{
|
|
|
|
/* release reference to dbus proxy */
|
|
|
|
g_object_unref(session);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
};
|
|
|
|
|
|
|
|
/* ---------------------------------------------------
|
|
|
|
* Worker thread function for audacious data sampling.
|
|
|
|
* --------------------------------------------------- */
|
|
|
|
void audacious_cb::work()
|
|
|
|
{
|
|
|
|
aud_result tmp;
|
|
|
|
gchar *psong, *pfilename;
|
|
|
|
psong = NULL;
|
|
|
|
pfilename = NULL;
|
2008-02-20 20:30:45 +00:00
|
|
|
|
2008-04-10 22:45:45 +00:00
|
|
|
do {
|
|
|
|
if (!audacious_remote_is_running(session)) {
|
2011-03-25 14:06:26 +00:00
|
|
|
tmp.status = AS_NOT_RUNNING;
|
2008-04-10 22:45:45 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Player status */
|
|
|
|
if (audacious_remote_is_paused(session)) {
|
2011-03-25 14:06:26 +00:00
|
|
|
tmp.status = AS_PAUSED;
|
2008-04-10 22:45:45 +00:00
|
|
|
} else if (audacious_remote_is_playing(session)) {
|
2011-03-25 14:06:26 +00:00
|
|
|
tmp.status = AS_PLAYING;
|
2008-04-10 22:45:45 +00:00
|
|
|
} else {
|
2011-03-25 14:06:26 +00:00
|
|
|
tmp.status = AS_STOPPED;
|
2008-04-10 22:45:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Current song title */
|
2011-03-25 14:06:26 +00:00
|
|
|
tmp.playlist_position = audacious_remote_get_playlist_pos(session);
|
|
|
|
psong = audacious_remote_get_playlist_title(session, tmp.playlist_position);
|
2008-04-10 22:45:45 +00:00
|
|
|
if (psong) {
|
2011-03-25 14:06:26 +00:00
|
|
|
tmp.title = psong;
|
2008-04-10 22:45:45 +00:00
|
|
|
g_free(psong);
|
|
|
|
}
|
|
|
|
|
2011-03-25 14:06:26 +00:00
|
|
|
/* Current song length */
|
|
|
|
tmp.length = audacious_remote_get_playlist_time(session, tmp.playlist_position);
|
2008-04-10 22:45:45 +00:00
|
|
|
|
2011-03-25 14:06:26 +00:00
|
|
|
/* Current song position */
|
|
|
|
tmp.position = audacious_remote_get_output_time(session);
|
2008-04-10 22:45:45 +00:00
|
|
|
|
2011-03-25 14:06:26 +00:00
|
|
|
/* Current song bitrate, frequency, channels */
|
|
|
|
audacious_remote_get_info(session, &tmp.bitrate, &tmp.frequency, &tmp.channels);
|
2008-04-10 22:45:45 +00:00
|
|
|
|
|
|
|
/* Current song filename */
|
2011-03-25 14:06:26 +00:00
|
|
|
pfilename = audacious_remote_get_playlist_file(session, tmp.playlist_position);
|
2008-04-10 22:45:45 +00:00
|
|
|
if (pfilename) {
|
2011-03-25 14:06:26 +00:00
|
|
|
tmp.filename = pfilename;
|
2008-04-10 22:45:45 +00:00
|
|
|
g_free(pfilename);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Length of the Playlist (number of songs) */
|
2011-03-25 14:06:26 +00:00
|
|
|
tmp.playlist_length = audacious_remote_get_playlist_length(session);
|
2008-04-10 22:45:45 +00:00
|
|
|
|
2008-12-07 07:38:06 +00:00
|
|
|
/* Main volume */
|
2011-03-25 14:06:26 +00:00
|
|
|
tmp.main_volume = audacious_remote_get_main_volume(session);
|
2008-04-10 22:45:45 +00:00
|
|
|
} while (0);
|
2010-01-04 17:06:14 +00:00
|
|
|
{
|
|
|
|
/* Deliver the refreshed items array to audacious_items. */
|
2011-03-25 14:06:26 +00:00
|
|
|
std::lock_guard<std::mutex> lock(result_mutex);
|
|
|
|
result = tmp;
|
2010-01-04 17:06:14 +00:00
|
|
|
}
|
2011-03-25 14:06:26 +00:00
|
|
|
}
|
2006-12-23 06:01:16 +00:00
|
|
|
|
2011-03-25 14:06:26 +00:00
|
|
|
aud_result get_res()
|
|
|
|
{
|
|
|
|
uint32_t period = std::max(
|
2012-07-13 18:17:54 +00:00
|
|
|
lround(music_player_interval.get(*state)/active_update_interval()), 1l
|
2011-03-25 14:06:26 +00:00
|
|
|
);
|
|
|
|
return conky::register_cb<audacious_cb>(period)->get_result_copy();
|
2008-02-20 20:30:45 +00:00
|
|
|
}
|
2006-11-03 20:54:52 +00:00
|
|
|
}
|
2009-11-08 18:19:42 +00:00
|
|
|
|
2011-03-25 14:06:26 +00:00
|
|
|
void print_audacious_status(struct text_object *, char *p, int p_max_size)
|
|
|
|
{
|
|
|
|
const aud_result &res = get_res();
|
|
|
|
snprintf(p, p_max_size, "%s", as_message[res.status]);
|
|
|
|
}
|
|
|
|
|
|
|
|
void print_audacious_title(struct text_object *obj, char *p, int p_max_size)
|
|
|
|
{
|
|
|
|
snprintf(p, std::min(obj->data.i, p_max_size), "%s", get_res().title.c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
void print_audacious_filename(struct text_object *obj, char *p, int p_max_size)
|
2009-11-08 18:19:42 +00:00
|
|
|
{
|
2011-03-25 14:06:26 +00:00
|
|
|
snprintf(p, std::min(obj->data.i, p_max_size), "%s", get_res().filename.c_str());
|
2009-11-08 18:19:42 +00:00
|
|
|
}
|
|
|
|
|
2010-01-04 17:06:14 +00:00
|
|
|
double audacious_barval(struct text_object *)
|
2009-11-08 18:19:42 +00:00
|
|
|
{
|
2011-03-25 14:06:26 +00:00
|
|
|
const aud_result &res = get_res();
|
|
|
|
return (double)res.position / res.length;
|
|
|
|
}
|
2009-11-08 18:19:42 +00:00
|
|
|
|
2011-03-25 14:06:26 +00:00
|
|
|
#define AUDACIOUS_TIME_GENERATOR(name) \
|
|
|
|
void print_audacious_##name(struct text_object *, char *p, int p_max_size) \
|
|
|
|
{ \
|
|
|
|
const aud_result &res = get_res(); \
|
|
|
|
int sec = res.name / 1000; \
|
|
|
|
snprintf(p, p_max_size, "%d:%.2d", sec/60, sec%60); \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
void print_audacious_##name##_seconds(struct text_object *, char *p, int p_max_size) \
|
|
|
|
{ \
|
|
|
|
snprintf(p, p_max_size, "%d", get_res().name); \
|
2009-11-08 18:19:42 +00:00
|
|
|
}
|
|
|
|
|
2011-03-25 14:06:26 +00:00
|
|
|
AUDACIOUS_TIME_GENERATOR(length)
|
|
|
|
AUDACIOUS_TIME_GENERATOR(position)
|
|
|
|
|
|
|
|
#define AUDACIOUS_INT_GENERATOR(name, offset) \
|
2010-01-04 17:06:14 +00:00
|
|
|
void print_audacious_##name(struct text_object *, char *p, int p_max_size) \
|
2009-11-08 18:19:42 +00:00
|
|
|
{ \
|
2011-03-25 14:06:26 +00:00
|
|
|
snprintf(p, p_max_size, "%d", get_res().name + offset); \
|
2009-11-08 18:19:42 +00:00
|
|
|
}
|
|
|
|
|
2011-03-25 14:06:26 +00:00
|
|
|
AUDACIOUS_INT_GENERATOR(bitrate, 0)
|
|
|
|
AUDACIOUS_INT_GENERATOR(frequency, 0)
|
|
|
|
AUDACIOUS_INT_GENERATOR(channels, 0)
|
|
|
|
AUDACIOUS_INT_GENERATOR(playlist_length, 0)
|
|
|
|
AUDACIOUS_INT_GENERATOR(playlist_position, 1)
|
|
|
|
AUDACIOUS_INT_GENERATOR(main_volume, 0)
|
2009-11-08 18:19:42 +00:00
|
|
|
|
|
|
|
#undef AUDACIOUS_PRINT_GENERATOR
|