1
0
mirror of https://github.com/Llewellynvdm/conky.git synced 2025-01-27 09:08:25 +00:00

internal rewrite of mpd support

Handle mpd internal information inside mpd.c. Use a refcounter to check
if the mpd-information can be freed (maybe useless). Remove the now
useless "full" flag of free_text_objects.
This commit is contained in:
Phil Sutter 2008-12-18 13:37:53 +01:00
parent 35a2d09c5f
commit 757983ab56
5 changed files with 303 additions and 479 deletions

View File

@ -332,18 +332,7 @@ void update_stuff(void)
#ifdef MPD #ifdef MPD
if (NEED(INFO_MPD)) { if (NEED(INFO_MPD)) {
if (!info.mpd.timed_thread) { update_mpd();
init_mpd_stats(&info.mpd);
info.mpd.timed_thread = timed_thread_create(&update_mpd,
(void *) &info.mpd, info.music_player_interval * 1000000);
if (!info.mpd.timed_thread) {
ERR("Failed to create MPD timed thread");
}
timed_thread_register(info.mpd.timed_thread, &info.mpd.timed_thread);
if (timed_thread_run(info.mpd.timed_thread)) {
ERR("Failed to run MPD timed thread");
}
}
} }
#endif #endif

View File

@ -1200,10 +1200,8 @@ static struct text_object *new_text_object_internal(void)
return obj; return obj;
} }
/* /* free the list of text objects root points to */
* call with full == 0 when freeing after 'internal' evaluation of objects static void free_text_objects(struct text_object *root)
*/
static void free_text_objects(struct text_object *root, char full)
{ {
struct text_object *obj; struct text_object *obj;
@ -1506,9 +1504,7 @@ static void free_text_objects(struct text_object *root, char full)
case OBJ_mpd_percent: case OBJ_mpd_percent:
case OBJ_mpd_smart: case OBJ_mpd_smart:
case OBJ_if_mpd_playing: case OBJ_if_mpd_playing:
if (full) { free_mpd();
free_mpd_vars(&info.mpd);
}
break; break;
#endif #endif
#ifdef MOC #ifdef MOC
@ -1533,8 +1529,6 @@ static void free_text_objects(struct text_object *root, char full)
free(obj); free(obj);
} }
#undef data #undef data
/* FIXME: below is surely useless */
if (full) {} // disable warning when MPD !defined
} }
void scan_mixer_bar(const char *arg, int *a, int *w, int *h) void scan_mixer_bar(const char *arg, int *a, int *w, int *h)
@ -2872,102 +2866,51 @@ static struct text_object *construct_text_object(const char *s,
ERR("smapi_bat_bar needs an argument"); ERR("smapi_bat_bar needs an argument");
#endif /* SMAPI */ #endif /* SMAPI */
#ifdef MPD #ifdef MPD
#define mpd_set_maxlen(name) \
if (arg) { \
int i; \
sscanf(arg, "%d", &i); \
if (i > 0) \
obj->data.i = i + 1; \
else \
ERR(#name ": invalid length argument"); \
}
END OBJ_THREAD(mpd_artist, INFO_MPD) END OBJ_THREAD(mpd_artist, INFO_MPD)
if (arg) { mpd_set_maxlen(mpd_artist);
sscanf(arg, "%d", &obj->data.i); init_mpd();
if (obj->data.i > 0) {
obj->data.i++;
} else {
ERR("mpd_artist: invalid length argument");
obj->data.i = 0;
}
} else {
obj->data.i = 0;
}
END OBJ_THREAD(mpd_title, INFO_MPD) END OBJ_THREAD(mpd_title, INFO_MPD)
if (arg) { mpd_set_maxlen(mpd_title);
sscanf(arg, "%d", &obj->data.i); init_mpd();
if (obj->data.i > 0) { END OBJ_THREAD(mpd_random, INFO_MPD) init_mpd();
obj->data.i++; END OBJ_THREAD(mpd_repeat, INFO_MPD) init_mpd();
} else { END OBJ_THREAD(mpd_elapsed, INFO_MPD) init_mpd();
ERR("mpd_title: invalid length argument"); END OBJ_THREAD(mpd_length, INFO_MPD) init_mpd();
obj->data.i = 0;
}
} else {
obj->data.i = 0;
}
END OBJ_THREAD(mpd_random, INFO_MPD)
END OBJ_THREAD(mpd_repeat, INFO_MPD)
END OBJ_THREAD(mpd_elapsed, INFO_MPD)
END OBJ_THREAD(mpd_length, INFO_MPD)
END OBJ_THREAD(mpd_track, INFO_MPD) END OBJ_THREAD(mpd_track, INFO_MPD)
if (arg) { mpd_set_maxlen(mpd_track);
sscanf(arg, "%d", &obj->data.i); init_mpd();
if (obj->data.i > 0) {
obj->data.i++;
} else {
ERR("mpd_track: invalid length argument");
obj->data.i = 0;
}
} else {
obj->data.i = 0;
}
END OBJ_THREAD(mpd_name, INFO_MPD) END OBJ_THREAD(mpd_name, INFO_MPD)
if (arg) { mpd_set_maxlen(mpd_name);
sscanf(arg, "%d", &obj->data.i); init_mpd();
if (obj->data.i > 0) {
obj->data.i++;
} else {
ERR("mpd_name: invalid length argument");
obj->data.i = 0;
}
} else {
obj->data.i = 0;
}
END OBJ_THREAD(mpd_file, INFO_MPD) END OBJ_THREAD(mpd_file, INFO_MPD)
if (arg) { mpd_set_maxlen(mpd_file);
sscanf(arg, "%d", &obj->data.i); init_mpd();
if (obj->data.i > 0) { END OBJ_THREAD(mpd_percent, INFO_MPD) init_mpd();
obj->data.i++;
} else {
ERR("mpd_file: invalid length argument");
obj->data.i = 0;
}
} else {
obj->data.i = 0;
}
END OBJ_THREAD(mpd_percent, INFO_MPD)
END OBJ_THREAD(mpd_album, INFO_MPD) END OBJ_THREAD(mpd_album, INFO_MPD)
if (arg) { mpd_set_maxlen(mpd_album);
sscanf(arg, "%d", &obj->data.i); init_mpd();
if (obj->data.i > 0) { END OBJ_THREAD(mpd_vol, INFO_MPD) init_mpd();
obj->data.i++; END OBJ_THREAD(mpd_bitrate, INFO_MPD) init_mpd();
} else { END OBJ_THREAD(mpd_status, INFO_MPD) init_mpd();
ERR("mpd_album: invalid length argument");
obj->data.i = 0;
}
} else {
obj->data.i = 0;
}
END OBJ_THREAD(mpd_vol, INFO_MPD)
END OBJ_THREAD(mpd_bitrate, INFO_MPD)
END OBJ_THREAD(mpd_status, INFO_MPD)
END OBJ_THREAD(mpd_bar, INFO_MPD) END OBJ_THREAD(mpd_bar, INFO_MPD)
scan_bar(arg, &obj->data.pair.a, &obj->data.pair.b); scan_bar(arg, &obj->data.pair.a, &obj->data.pair.b);
init_mpd();
END OBJ_THREAD(mpd_smart, INFO_MPD) END OBJ_THREAD(mpd_smart, INFO_MPD)
if (arg) { mpd_set_maxlen(mpd_smart);
sscanf(arg, "%d", &obj->data.i); init_mpd();
if (obj->data.i > 0) {
obj->data.i++;
} else {
ERR("mpd_smart: invalid length argument");
obj->data.i = 0;
}
} else {
obj->data.i = 0;
}
END OBJ_THREAD(if_mpd_playing, INFO_MPD) END OBJ_THREAD(if_mpd_playing, INFO_MPD)
obj_be_ifblock_if(obj); obj_be_ifblock_if(obj);
init_mpd();
#undef mpd_set_maxlen
#endif /* MPD */ #endif /* MPD */
#ifdef MOC #ifdef MOC
END OBJ_THREAD(moc_state, INFO_MOC) END OBJ_THREAD(moc_state, INFO_MOC)
@ -3466,7 +3409,7 @@ static int extract_variable_text_internal(struct text_object *retval, const char
static void extract_variable_text(const char *p) static void extract_variable_text(const char *p)
{ {
free_text_objects(&global_root_object, 1); free_text_objects(&global_root_object);
if (tmpstring1) { if (tmpstring1) {
free(tmpstring1); free(tmpstring1);
tmpstring1 = 0; tmpstring1 = 0;
@ -4203,7 +4146,7 @@ static void generate_text_internal(char *p, int p_max_size,
memcpy(tmp_info, cur, sizeof(struct information)); memcpy(tmp_info, cur, sizeof(struct information));
parse_conky_vars(&subroot, p, p, tmp_info); parse_conky_vars(&subroot, p, p, tmp_info);
free_text_objects(&subroot, 0); free_text_objects(&subroot);
free(tmp_info); free(tmp_info);
} }
OBJ(execbar) { OBJ(execbar) {
@ -4301,7 +4244,7 @@ static void generate_text_internal(char *p, int p_max_size,
parse_conky_vars(&subroot, obj->data.execi.buffer, p, tmp_info); parse_conky_vars(&subroot, obj->data.execi.buffer, p, tmp_info);
obj->data.execi.last_update = current_update_time; obj->data.execi.last_update = current_update_time;
} }
free_text_objects(&subroot, 0); free_text_objects(&subroot);
free(tmp_info); free(tmp_info);
} }
OBJ(texeci) { OBJ(texeci) {
@ -4625,7 +4568,7 @@ static void generate_text_internal(char *p, int p_max_size,
DO_JUMP; DO_JUMP;
} }
p[0] = '\0'; p[0] = '\0';
free_text_objects(&subroot, 0); free_text_objects(&subroot);
free(tmp_info); free(tmp_info);
} }
OBJ(if_existing) { OBJ(if_existing) {
@ -4879,96 +4822,78 @@ static void generate_text_internal(char *p, int p_max_size,
#endif /* __FreeBSD__ __OpenBSD__ */ #endif /* __FreeBSD__ __OpenBSD__ */
#ifdef MPD #ifdef MPD
OBJ(mpd_title) { #define mpd_printf(fmt, val) \
int len = obj->data.i; snprintf(p, p_max_size, fmt, mpd_get_info()->val)
if (len == 0 || len > p_max_size) #define mpd_sprintf(val) { \
len = p_max_size; if (!obj->data.i || obj->data.i > p_max_size) \
snprintf(p, len, "%s", cur->mpd.title); mpd_printf("%s", val); \
} else \
OBJ(mpd_artist) { snprintf(p, obj->data.i, "%s", mpd_get_info()->val); \
int len = obj->data.i; }
if (len == 0 || len > p_max_size) OBJ(mpd_title)
len = p_max_size; mpd_sprintf(title);
snprintf(p, len, "%s", cur->mpd.artist); OBJ(mpd_artist)
} mpd_sprintf(artist);
OBJ(mpd_album) { OBJ(mpd_album)
int len = obj->data.i; mpd_sprintf(album);
if (len == 0 || len > p_max_size) OBJ(mpd_random)
len = p_max_size; mpd_printf("%s", random);
snprintf(p, len, "%s", cur->mpd.album); OBJ(mpd_repeat)
} mpd_printf("%s", repeat);
OBJ(mpd_random) { OBJ(mpd_track)
snprintf(p, p_max_size, "%s", cur->mpd.random); mpd_sprintf(track);
} OBJ(mpd_name)
OBJ(mpd_repeat) { mpd_sprintf(name);
snprintf(p, p_max_size, "%s", cur->mpd.repeat); OBJ(mpd_file)
} mpd_sprintf(file);
OBJ(mpd_track) { OBJ(mpd_vol)
int len = obj->data.i; mpd_printf("%d", volume);
if (len == 0 || len > p_max_size) OBJ(mpd_bitrate)
len = p_max_size; mpd_printf("%d", bitrate);
snprintf(p, len, "%s", cur->mpd.track); OBJ(mpd_status)
} mpd_printf("%s", status);
OBJ(mpd_name) {
int len = obj->data.i;
if (len == 0 || len > p_max_size)
len = p_max_size;
snprintf(p, len, "%s", cur->mpd.name);
}
OBJ(mpd_file) {
int len = obj->data.i;
if (len == 0 || len > p_max_size)
len = p_max_size;
snprintf(p, len, "%s", cur->mpd.file);
}
OBJ(mpd_vol) {
snprintf(p, p_max_size, "%i", cur->mpd.volume);
}
OBJ(mpd_bitrate) {
snprintf(p, p_max_size, "%i", cur->mpd.bitrate);
}
OBJ(mpd_status) {
snprintf(p, p_max_size, "%s", cur->mpd.status);
}
OBJ(mpd_elapsed) { OBJ(mpd_elapsed) {
format_media_player_time(p, p_max_size, cur->mpd.elapsed); format_media_player_time(p, p_max_size, mpd_get_info()->elapsed);
} }
OBJ(mpd_length) { OBJ(mpd_length) {
format_media_player_time(p, p_max_size, cur->mpd.length); format_media_player_time(p, p_max_size, mpd_get_info()->length);
} }
OBJ(mpd_percent) { OBJ(mpd_percent) {
spaced_print(p, p_max_size, "%*d", 4, spaced_print(p, p_max_size, "%*d", 4,
pad_percents, (int) (cur->mpd.progress * 100)); pad_percents, (int) (mpd_get_info()->progress * 100));
} }
OBJ(mpd_bar) { OBJ(mpd_bar) {
new_bar(p, obj->data.pair.a, obj->data.pair.b, new_bar(p, obj->data.pair.a, obj->data.pair.b,
(int) (cur->mpd.progress * 255.0f)); (int) (mpd_get_info()->progress * 255.0f));
} }
OBJ(mpd_smart) { OBJ(mpd_smart) {
struct mpd_s *mpd = mpd_get_info();
int len = obj->data.i; int len = obj->data.i;
if (len == 0 || len > p_max_size) if (len == 0 || len > p_max_size)
len = p_max_size; len = p_max_size;
memset(p, 0, p_max_size); memset(p, 0, p_max_size);
if (cur->mpd.artist && *cur->mpd.artist && cur->mpd.title if (mpd->artist && *mpd->artist &&
&& *cur->mpd.title) { mpd->title && *mpd->title) {
snprintf(p, len, "%s - %s", cur->mpd.artist, snprintf(p, len, "%s - %s", mpd->artist,
cur->mpd.title); mpd->title);
} else if (cur->mpd.title && *cur->mpd.title) { } else if (mpd->title && *mpd->title) {
snprintf(p, len, "%s", cur->mpd.title); snprintf(p, len, "%s", mpd->title);
} else if (cur->mpd.artist && *cur->mpd.artist) { } else if (mpd->artist && *mpd->artist) {
snprintf(p, len, "%s", cur->mpd.artist); snprintf(p, len, "%s", mpd->artist);
} else if (cur->mpd.file && *cur->mpd.file) { } else if (mpd->file && *mpd->file) {
snprintf(p, len, "%s", cur->mpd.file); snprintf(p, len, "%s", mpd->file);
} else { } else {
*p = 0; *p = 0;
} }
} }
OBJ(if_mpd_playing) { OBJ(if_mpd_playing) {
if (!cur->mpd.is_playing) { if (!mpd_get_info()->is_playing) {
DO_JUMP; DO_JUMP;
} }
} }
#undef mpd_sprintf
#undef mpd_printf
#endif #endif
#ifdef MOC #ifdef MOC
@ -6940,49 +6865,10 @@ static void reload_config(void)
free(info.mail); free(info.mail);
} }
#ifdef MPD
if (info.mpd.title) {
free(info.mpd.title);
info.mpd.title = NULL;
}
if (info.mpd.artist) {
free(info.mpd.artist);
info.mpd.artist = NULL;
}
if (info.mpd.album) {
free(info.mpd.album);
info.mpd.album = NULL;
}
if (info.mpd.random) {
free(info.mpd.random);
info.mpd.random = NULL;
}
if (info.mpd.repeat) {
free(info.mpd.repeat);
info.mpd.repeat = NULL;
}
if (info.mpd.track) {
free(info.mpd.track);
info.mpd.track = NULL;
}
if (info.mpd.name) {
free(info.mpd.name);
info.mpd.name = NULL;
}
if (info.mpd.file) {
free(info.mpd.file);
info.mpd.file = NULL;
}
if (info.mpd.status) {
free(info.mpd.status);
info.mpd.status = NULL;
}
#endif
#ifdef MOC #ifdef MOC
free_moc(&info.moc); free_moc(&info.moc);
#endif #endif
#ifdef X11 #ifdef X11
free_fonts(); free_fonts();
#endif /* X11 */ #endif /* X11 */
@ -7061,7 +6947,7 @@ static void clean_up(void)
free_fonts(); free_fonts();
#endif /* X11 */ #endif /* X11 */
free_text_objects(&global_root_object, 1); free_text_objects(&global_root_object);
if (tmpstring1) { if (tmpstring1) {
free(tmpstring1); free(tmpstring1);
tmpstring1 = 0; tmpstring1 = 0;
@ -7173,16 +7059,8 @@ static void set_default_configurations(void)
short_units = 0; short_units = 0;
top_mem = 0; top_mem = 0;
#ifdef MPD #ifdef MPD
strcpy(info.mpd.host, "localhost"); mpd_set_host("localhost");
info.mpd.port = 6600; mpd_set_port("6600");
info.mpd.status = NULL;
info.mpd.artist = NULL;
info.mpd.album = NULL;
info.mpd.title = NULL;
info.mpd.random = NULL;
info.mpd.track = NULL;
info.mpd.name = NULL;
info.mpd.file = NULL;
#endif #endif
#ifdef MOC #ifdef MOC
init_moc(&info.moc); init_moc(&info.moc);
@ -7529,22 +7407,19 @@ static void load_config_file(const char *f)
#ifdef MPD #ifdef MPD
CONF("mpd_host") { CONF("mpd_host") {
if (value) { if (value) {
strncpy(info.mpd.host, value, 127); mpd_set_host(value);
} else { } else {
CONF_ERR; CONF_ERR;
} }
} }
CONF("mpd_port") { CONF("mpd_port") {
if (value) { if (value && mpd_set_port(value)) {
info.mpd.port = strtol(value, 0, 0); CONF_ERR;
if (info.mpd.port < 1 || info.mpd.port > 0xffff) {
CONF_ERR;
}
} }
} }
CONF("mpd_password") { CONF("mpd_password") {
if (value) { if (value) {
strncpy(info.mpd.password, value, 127); mpd_set_password(value);
} else { } else {
CONF_ERR; CONF_ERR;
} }

View File

@ -232,9 +232,6 @@ struct information {
struct mail_s *mail; struct mail_s *mail;
int mail_running; int mail_running;
#ifdef MPD
struct mpd_s mpd;
#endif
#ifdef MOC #ifdef MOC
struct moc_s moc; struct moc_s moc;
#endif #endif

418
src/mpd.c
View File

@ -26,309 +26,273 @@
#include "conky.h" #include "conky.h"
#include "logging.h" #include "logging.h"
#include "timed_thread.h"
#include "libmpdclient.h"
#include "mpd.h"
void init_mpd_stats(struct mpd_s *mpd) /* server connection data */
static char mpd_host[128];
static char mpd_password[128];
static int mpd_port;
/* global mpd information */
static struct mpd_s mpd_info;
/* number of users of the above struct */
static int refcount = 0;
void mpd_set_host(const char *host)
{ {
if (mpd->artist == NULL) { snprintf(mpd_host, 128, "%s", host);
mpd->artist = malloc(text_buffer_size); }
} void mpd_set_password(const char *password)
if (mpd->album == NULL) { {
mpd->album = malloc(text_buffer_size); snprintf(mpd_password, 128, "%s", password);
} }
if (mpd->title == NULL) { void mpd_clear_password(void)
mpd->title = malloc(text_buffer_size); {
} *mpd_password = '\0';
if (mpd->random == NULL) { }
mpd->random = malloc(text_buffer_size); int mpd_set_port(const char *port)
} {
if (mpd->repeat == NULL) { int val;
mpd->repeat = malloc(text_buffer_size);
} val = strtol(port, 0, 0);
if (mpd->track == NULL) { if (val < 1 || val > 0xffff)
mpd->track = malloc(text_buffer_size); return 1;
} mpd_port = val;
if (mpd->status == NULL) { return 0;
mpd->status = malloc(text_buffer_size);
}
if (mpd->name == NULL) {
mpd->name = malloc(text_buffer_size);
}
if (mpd->file == NULL) {
mpd->file = malloc(text_buffer_size);
}
clear_mpd_stats(mpd);
} }
void free_mpd_vars(struct mpd_s *mpd) void init_mpd(void)
{ {
if (mpd->title) { if (!(refcount++)) /* first client */
free(mpd->title); memset(&mpd_info, 0, sizeof(struct mpd_s));
mpd->title = NULL;
} refcount++;
if (mpd->artist) {
free(mpd->artist);
mpd->artist = NULL;
}
if (mpd->album) {
free(mpd->album);
mpd->album = NULL;
}
if (mpd->random) {
free(mpd->random);
mpd->random = NULL;
}
if (mpd->repeat) {
free(mpd->repeat);
mpd->repeat = NULL;
}
if (mpd->track) {
free(mpd->track);
mpd->track = NULL;
}
if (mpd->name) {
free(mpd->name);
mpd->name = NULL;
}
if (mpd->file) {
free(mpd->file);
mpd->file = NULL;
}
if (mpd->status) {
free(mpd->status);
mpd->status = NULL;
}
if (mpd->conn) {
mpd_closeConnection(mpd->conn);
mpd->conn = 0;
}
} }
void clear_mpd_stats(struct mpd_s *mpd) struct mpd_s *mpd_get_info(void)
{ {
*mpd->name = 0; return &mpd_info;
*mpd->file = 0;
*mpd->artist = 0;
*mpd->album = 0;
*mpd->title = 0;
*mpd->random = 0;
*mpd->repeat = 0;
*mpd->track = 0;
*mpd->status = 0;
mpd->is_playing = 0;
mpd->bitrate = 0;
mpd->progress = 0;
mpd->elapsed = 0;
mpd->length = 0;
} }
void *update_mpd(void *arg) static void clear_mpd(void)
{ {
struct mpd_s *mpd; #define xfree(x) if (x) free(x)
xfree(mpd_info.title);
xfree(mpd_info.artist);
xfree(mpd_info.album);
/* do not free() the const char *status! */
/* do not free() the const char *random! */
/* do not free() the const char *repeat! */
xfree(mpd_info.track);
xfree(mpd_info.name);
xfree(mpd_info.file);
#undef xfree
memset(&mpd_info, 0, sizeof(struct mpd_s));
}
if (arg == NULL) { void free_mpd(void)
CRIT_ERR("update_mpd called with a null argument!"); {
if (!(--refcount)) /* last client */
clear_mpd();
}
static void *update_mpd_thread(void *) __attribute__((noreturn));
void update_mpd(void)
{
int interval;
static timed_thread *thread = NULL;
if (thread)
return;
interval = info.music_player_interval * 1000000;
thread = timed_thread_create(&update_mpd_thread, &thread, interval);
if (!thread) {
ERR("Failed to create MPD timed thread");
return;
} }
timed_thread_register(thread, &thread);
if (timed_thread_run(thread))
ERR("Failed to run MPD timed thread");
}
mpd = (struct mpd_s *) arg; /* stringMAXdup dups at most text_buffer_size bytes */
#define strmdup(x) strndup(x, text_buffer_size - 1)
static void *update_mpd_thread(void *arg)
{
static mpd_Connection *conn = NULL;
mpd_Status *status;
mpd_InfoEntity *entity;
timed_thread *me = *(timed_thread **)arg;
while (1) { while (1) {
mpd_Status *status; clear_mpd();
mpd_InfoEntity *entity;
if (!mpd->conn) { if (!conn)
mpd->conn = mpd_newConnection(mpd->host, conn = mpd_newConnection(mpd_host, mpd_port, 10);
mpd->port, 10);
} if (*mpd_password) {
if (strlen(mpd->password) > 1) { mpd_sendPasswordCommand(conn, mpd_password);
mpd_sendPasswordCommand(mpd->conn, mpd_finishCommand(conn);
mpd->password);
mpd_finishCommand(mpd->conn);
} }
timed_thread_lock(mpd->timed_thread); timed_thread_lock(me);
if (mpd->conn->error || mpd->conn == NULL) { if (conn->error || conn == NULL) {
ERR("MPD error: %s\n", mpd->conn->errorStr); ERR("MPD error: %s\n", conn->errorStr);
mpd_closeConnection(mpd->conn); mpd_closeConnection(conn);
mpd->conn = 0; conn = 0;
clear_mpd_stats(mpd); clear_mpd();
strncpy(mpd->status, "MPD not responding", mpd_info.status = "MPD not responding";
text_buffer_size - 1); timed_thread_unlock(me);
timed_thread_unlock(mpd->timed_thread); if (timed_thread_test(me, 0)) {
if (timed_thread_test(mpd->timed_thread, 0)) { timed_thread_exit(me);
timed_thread_exit(mpd->timed_thread);
} }
continue; continue;
} }
mpd_sendStatusCommand(mpd->conn); mpd_sendStatusCommand(conn);
if ((status = mpd_getStatus(mpd->conn)) == NULL) { if ((status = mpd_getStatus(conn)) == NULL) {
ERR("MPD error: %s\n", mpd->conn->errorStr); ERR("MPD error: %s\n", conn->errorStr);
mpd_closeConnection(mpd->conn); mpd_closeConnection(conn);
mpd->conn = 0; conn = 0;
clear_mpd_stats(mpd); clear_mpd();
strncpy(mpd->status, "MPD not responding", mpd_info.status = "MPD not responding";
text_buffer_size - 1); timed_thread_unlock(me);
timed_thread_unlock(mpd->timed_thread); if (timed_thread_test(me, 0)) {
if (timed_thread_test(mpd->timed_thread, 0)) { timed_thread_exit(me);
timed_thread_exit(mpd->timed_thread);
} }
continue; continue;
} }
mpd_finishCommand(mpd->conn); mpd_finishCommand(conn);
if (mpd->conn->error) { if (conn->error) {
// fprintf(stderr, "%s\n", mpd->conn->errorStr); // fprintf(stderr, "%s\n", conn->errorStr);
mpd_closeConnection(mpd->conn); mpd_closeConnection(conn);
mpd->conn = 0; conn = 0;
timed_thread_unlock(mpd->timed_thread); timed_thread_unlock(me);
if (timed_thread_test(mpd->timed_thread, 0)) { if (timed_thread_test(me, 0)) {
timed_thread_exit(mpd->timed_thread); timed_thread_exit(me);
} }
continue; continue;
} }
mpd->volume = status->volume; mpd_info.volume = status->volume;
/* if (status->error) { /* if (status->error) {
printf("error: %s\n", status->error); printf("error: %s\n", status->error);
} */ } */
if (status->state == MPD_STATUS_STATE_PLAY) { switch(status->state) {
strncpy(mpd->status, "Playing", text_buffer_size - 1); case MPD_STATUS_STATE_PLAY:
mpd_info.status = "Playing";
break;
case MPD_STATUS_STATE_STOP:
mpd_info.status = "Stopped";
break;
case MPD_STATUS_STATE_PAUSE:
mpd_info.status = "Paused";
break;
default:
mpd_info.status = "";
clear_mpd();
break;
} }
if (status->state == MPD_STATUS_STATE_STOP) {
clear_mpd_stats(mpd); if (status->state == MPD_STATUS_STATE_PLAY ||
strncpy(mpd->status, "Stopped", text_buffer_size - 1); status->state == MPD_STATUS_STATE_PAUSE) {
} mpd_info.is_playing = 1;
if (status->state == MPD_STATUS_STATE_PAUSE) { mpd_info.bitrate = status->bitRate;
strncpy(mpd->status, "Paused", text_buffer_size - 1); mpd_info.progress = (float) status->elapsedTime /
}
if (status->state == MPD_STATUS_STATE_UNKNOWN) {
clear_mpd_stats(mpd);
*mpd->status = 0;
}
if (status->state == MPD_STATUS_STATE_PLAY
|| status->state == MPD_STATUS_STATE_PAUSE) {
mpd->is_playing = 1;
mpd->bitrate = status->bitRate;
mpd->progress = (float) status->elapsedTime /
status->totalTime; status->totalTime;
mpd->elapsed = status->elapsedTime; mpd_info.elapsed = status->elapsedTime;
mpd->length = status->totalTime; mpd_info.length = status->totalTime;
if (status->random == 0) { if (status->random == 0) {
strcpy(mpd->random, "Off"); mpd_info.random = "Off";
} else if (status->random == 1) { } else if (status->random == 1) {
strcpy(mpd->random, "On"); mpd_info.random = "On";
} else { } else {
*mpd->random = 0; mpd_info.random = "";
} }
if (status->repeat == 0) { if (status->repeat == 0) {
strcpy(mpd->repeat, "Off"); mpd_info.repeat = "Off";
} else if (status->repeat == 1) { } else if (status->repeat == 1) {
strcpy(mpd->repeat, "On"); mpd_info.repeat = "On";
} else { } else {
*mpd->repeat = 0; mpd_info.repeat = "";
} }
} }
if (mpd->conn->error) { if (conn->error) {
// fprintf(stderr, "%s\n", mpd->conn->errorStr); // fprintf(stderr, "%s\n", conn->errorStr);
mpd_closeConnection(mpd->conn); mpd_closeConnection(conn);
mpd->conn = 0; conn = 0;
timed_thread_unlock(mpd->timed_thread); timed_thread_unlock(me);
if (timed_thread_test(mpd->timed_thread, 0)) { if (timed_thread_test(me, 0)) {
timed_thread_exit(mpd->timed_thread); timed_thread_exit(me);
} }
continue; continue;
} }
mpd_sendCurrentSongCommand(mpd->conn); mpd_sendCurrentSongCommand(conn);
while ((entity = mpd_getNextInfoEntity(mpd->conn))) { while ((entity = mpd_getNextInfoEntity(conn))) {
mpd_Song *song = entity->info.song; mpd_Song *song = entity->info.song;
if (entity->type != MPD_INFO_ENTITY_TYPE_SONG) { if (entity->type != MPD_INFO_ENTITY_TYPE_SONG) {
mpd_freeInfoEntity(entity); mpd_freeInfoEntity(entity);
continue; continue;
} }
#define SONGSET(x) if(song->x) mpd_info.x = strmdup(song->x)
if (song->artist) { SONGSET(artist);
strncpy(mpd->artist, song->artist, SONGSET(album);
text_buffer_size - 1); SONGSET(title);
} else { SONGSET(track);
*mpd->artist = 0; SONGSET(name);
} SONGSET(file);
if (song->album) { #undef SONGSET
strncpy(mpd->album, song->album,
text_buffer_size - 1);
} else {
*mpd->album = 0;
}
if (song->title) {
strncpy(mpd->title, song->title,
text_buffer_size - 1);
} else {
*mpd->title = 0;
}
if (song->track) {
strncpy(mpd->track, song->track,
text_buffer_size - 1);
} else {
*mpd->track = 0;
}
if (song->name) {
strncpy(mpd->name, song->name,
text_buffer_size - 1);
} else {
*mpd->name = 0;
}
if (song->file) {
strncpy(mpd->file, song->file,
text_buffer_size - 1);
} else {
*mpd->file = 0;
}
if (entity != NULL) { if (entity != NULL) {
mpd_freeInfoEntity(entity); mpd_freeInfoEntity(entity);
entity = NULL; entity = NULL;
} }
} }
if (entity != NULL) { mpd_finishCommand(conn);
mpd_freeInfoEntity(entity); if (conn->error) {
entity = NULL; // fprintf(stderr, "%s\n", conn->errorStr);
} mpd_closeConnection(conn);
mpd_finishCommand(mpd->conn); conn = 0;
if (mpd->conn->error) { timed_thread_unlock(me);
// fprintf(stderr, "%s\n", mpd->conn->errorStr); if (timed_thread_test(me, 0)) {
mpd_closeConnection(mpd->conn); timed_thread_exit(me);
mpd->conn = 0;
timed_thread_unlock(mpd->timed_thread);
if (timed_thread_test(mpd->timed_thread, 0)) {
timed_thread_exit(mpd->timed_thread);
} }
continue; continue;
} }
timed_thread_unlock(mpd->timed_thread); timed_thread_unlock(me);
if (mpd->conn->error) { if (conn->error) {
// fprintf(stderr, "%s\n", mpd->conn->errorStr); // fprintf(stderr, "%s\n", conn->errorStr);
mpd_closeConnection(mpd->conn); mpd_closeConnection(conn);
mpd->conn = 0; conn = 0;
if (timed_thread_test(mpd->timed_thread, 0)) { if (timed_thread_test(me, 0)) {
timed_thread_exit(mpd->timed_thread); timed_thread_exit(me);
} }
continue; continue;
} }
mpd_freeStatus(status); mpd_freeStatus(status);
/* if (mpd->conn) { /* if (conn) {
mpd_closeConnection(mpd->conn); mpd_closeConnection(conn);
mpd->conn = 0; conn = 0;
} */ } */
if (timed_thread_test(mpd->timed_thread, 0)) { if (timed_thread_test(me, 0)) {
timed_thread_exit(mpd->timed_thread); timed_thread_exit(me);
} }
continue; continue;
} }
/* never reached */ /* never reached */
} }

View File

@ -1,37 +1,36 @@
#ifndef MPD_H_ #ifndef MPD_H_
#define MPD_H_ #define MPD_H_
#include "libmpdclient.h" //#include "conky.h"
#include "timed_thread.h"
struct mpd_s { struct mpd_s {
char *title; char *title;
char *artist; char *artist;
char *album; char *album;
char *status; const char *status;
char *random; const char *random;
char *repeat; const char *repeat;
char *track; char *track;
char *name; char *name;
char *file; char *file;
int is_playing; int is_playing;
int volume; int volume;
unsigned int port;
char host[128];
char password[128];
float progress; float progress;
int bitrate; int bitrate;
int length; int length;
int elapsed; int elapsed;
mpd_Connection *conn;
timed_thread *timed_thread;
}; };
#include "conky.h" /* functions for setting the configuration values */
void mpd_set_host(const char *);
void mpd_set_password(const char *);
void mpd_clear_password(void);
int mpd_set_port(const char *);
extern void init_mpd_stats(struct mpd_s *mpd); /* text object functions */
void clear_mpd_stats(struct mpd_s *mpd); void init_mpd(void);
void *update_mpd(void *) __attribute__((noreturn)); struct mpd_s *mpd_get_info(void);
void free_mpd_vars(struct mpd_s *mpd); void free_mpd(void);
void update_mpd(void);
#endif /*MPD_H_*/ #endif /*MPD_H_*/