aboutsummaryrefslogtreecommitdiffstats
path: root/plugin_mpd.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugin_mpd.c')
-rw-r--r--plugin_mpd.c848
1 files changed, 585 insertions, 263 deletions
diff --git a/plugin_mpd.c b/plugin_mpd.c
index 5d109fd..f54c477 100644
--- a/plugin_mpd.c
+++ b/plugin_mpd.c
@@ -1,9 +1,11 @@
-/* $Id: plugin_mpd.c 789 2007-04-30 04:48:10Z michael $
- * $URL: https://ssl.bulix.org/svn/lcd4linux/branches/0.10.1/plugin_mpd.c $
+/* $Id: plugin_mpd.c 1044 2009-09-23 04:34:38Z michael $
+ * $URL: https://ssl.bulix.org/svn/lcd4linux/trunk/plugin_mpd.c $
*
- * mpd informations
+ * mpd informations v0.82
*
* Copyright (C) 2006 Stefan Kuhne <sk-privat@gmx.net>
+ * Copyright (C) 2007 Robert Buchholz <rbu@gentoo.org>
+ * Copyright (C) 2008 Michael Vogt <michu@neophob.com>
* Copyright (C) 2006 The LCD4Linux Team <lcd4linux-devel@users.sourceforge.net>
*
* This file is part of LCD4Linux.
@@ -25,408 +27,728 @@
*/
/*
- * exported functions:
+ * changelog v0.5 (20.11.2007):
+ * changed: mpd::artist(), mpd::title(), mpd::album()
+ * init code, call only if a function is used.
+ * removed: "old style" functions, duplicate code
+ * fixed: strdup() mem leaks
+ * added: getstate, function which return player status: play/pause/stop
+ * getVolume, funtcion which returns the mpd volume
+ * getFilename, return current filename
*
- * int plugin_init_sample (void)
- * adds various functions
+ *
+ * changelog v0.6 (05.12.2007):
+ * changed: -connection handling
+ * -verbose "NO TAG" messages
+ * -init code
+ * added: -added password support (MPD_PASSWORD env variable)
+ * -mpd::getSongsInDb - how many songs are in the mpd db?
+ * -mpd::getMpdUptime - uptime of mpd
+ * -mpd::getMpdPlayTime - playtime of mpd
+ * -mpd::getMpdDbPlayTime - playtime of all songs in mpd db
+ * -basic error handler..
+ * -mpd configuration in lcd4linux.conf
+ * -formatTime* - use those functions to format time values
+ * removed: -reprand method
+ *
+ *
+ * changelog v0.7 (14.12.2007):
+ * changed: -connection handling improved, do not disconnect/reconnect for each query
+ * -> uses less ressources
+ *
+ * changelog v0.8 (30.01.2008):
+ * changed: -libmpd is not needed anymore, use libmpdclient.c instead
+ * fixed: -getMpdUptime()
+ * -getMpdPlaytime()
+ * -type definition
+ * added: -mpd::getSamplerateHz
+ * -getAudioChannels
+ *
+ * changelog v0.83 (26.07.2008):
+ * added: -mpd::cmd* commands
*
*/
+/*
+
+TODO:
+ -what happens if the db is updating?
+
+*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
+#include <signal.h>
#include "debug.h"
#include "plugin.h"
+#include "cfg.h"
+/* struct timeval */
+#include <sys/time.h>
-#include <libmpd/libmpd.h>
+/* source: http://www.musicpd.org/libmpdclient.shtml */
+#include "libmpd/libmpdclient.h"
#ifdef WITH_DMALLOC
#include <dmalloc.h>
#endif
-/* Struct Pointer */
-
-struct Pointer {
- mpd_Connection *conn;
- mpd_Status *status;
- mpd_InfoEntity *entity;
-};
-
-
-
-static struct Pointer connect()
+#define TIMEOUT_IN_S 10
+#define ERROR_DISPLAY 5
+
+/* current song */
+
+static int l_totalTimeSec;
+static int l_elapsedTimeSec;
+static int l_bitRate;
+static int l_repeatEnabled;
+static int l_randomEnabled;
+static int l_state;
+static int l_volume;
+static int l_numberOfSongs;
+static unsigned long l_uptime;
+static unsigned long l_playTime;
+static unsigned long l_dbPlayTime;
+static int l_playlistLength;
+/* pos in playlist */
+static int l_currentSongPos;
+static unsigned int l_sampleRate;
+static int l_channels;
+
+static mpd_Song *currentSong;
+
+/* connection information */
+static char host[255];
+static char pw[255];
+static int iport;
+static int plugin_enabled;
+static int waittime;
+struct timeval timestamp;
+
+static mpd_Connection *conn;
+static char Section[] = "Plugin:MPD";
+static int errorcnt = 0;
+
+
+static int configure_mpd(void)
{
- char *host = "localhost";
- char *port = "6600";
- int iport;
- char *test;
- struct Pointer mpd;
+ static int configured = 0;
- if ((test = getenv("MPD_HOST"))) {
- host = test;
- }
+ char *s;
- if ((test = getenv("MPD_PORT"))) {
- port = test;
- }
+ if (configured != 0)
+ return configured;
- iport = strtol(port, &test, 10);
+ /* read enabled */
+ if (cfg_number(Section, "enabled", 0, 0, 1, &plugin_enabled) < 1) {
+ plugin_enabled = 0;
+ }
- if (iport < 0 || *test != '\0') {
- fprintf(stderr, "MPD_PORT \"%s\" is not a positive integer\n", port);
- exit(EXIT_FAILURE);
+ if (plugin_enabled != 1) {
+ info("[MPD] WARNING: Plugin is not enabled! (set 'enabled 1' to enable this plugin)");
+ configured = 1;
+ return configured;
}
- mpd.conn = mpd_newConnection(host, iport, 10);
+ /* read server */
+ s = cfg_get(Section, "server", "localhost");
+ if (*s == '\0') {
+ info("[MPD] empty '%s.server' entry from %s, assuming 'localhost'", Section, cfg_source());
+ strcpy(host, "localhost");
+ } else
+ strcpy(host, s);
- mpd_sendCommandListOkBegin(mpd.conn);
- mpd_sendStatusCommand(mpd.conn);
- mpd_sendCurrentSongCommand(mpd.conn);
- mpd_sendCommandListEnd(mpd.conn);
+ free(s);
- if ((mpd.status = mpd_getStatus(mpd.conn)) == NULL) {
- fprintf(stderr, "%s\n", mpd.conn->errorStr);
- mpd_closeConnection(mpd.conn);
+ /* read port */
+ if (cfg_number(Section, "port", 6600, 1, 65536, &iport) < 1) {
+ info("[MPD] no '%s.port' entry from %s using MPD's default", Section, cfg_source());
}
- if (mpd.status->error) {
- printf("error: %s\n", mpd.status->error);
+ /* read minUpdateTime in ms */
+ if (cfg_number(Section, "minUpdateTime", 500, 1, 10000, &waittime) < 1) {
+ info("[MPD] no '%s.minUpdateTime' entry from %s using MPD's default", Section, cfg_source());
}
- if (mpd.conn->error) {
- fprintf(stderr, "%s\n", mpd.conn->errorStr);
- mpd_closeConnection(mpd.conn);
+
+ /* read password */
+ s = cfg_get(Section, "password", "");
+ if (*s == '\0') {
+ info("[MPD] empty '%s.password' entry in %s, assuming none", Section, cfg_source());
+ memset(pw, 0, sizeof(pw));
+ } else {
+ strcpy(pw, s);
+ free(s);
}
- return mpd;
+ debug("[MPD] connection detail: [%s:%d]", host, iport);
+ configured = 1;
+ return configured;
}
-static void disconnect(struct Pointer mpd)
+static int mpd_update()
{
- if (mpd.conn->error) {
- fprintf(stderr, "%s\n", mpd.conn->errorStr);
- mpd_closeConnection(mpd.conn);
+ int ret = -1;
+ struct timeval now;
+
+ /* reread every 1000 msec only */
+ gettimeofday(&now, NULL);
+ int timedelta = (now.tv_sec - timestamp.tv_sec) * 1000 + (now.tv_usec - timestamp.tv_usec) / 1000;
+
+ if (timedelta < waittime) {
+ /* debug("[MPD] waittime not reached...\n"); */
+ return 1;
}
- mpd_finishCommand(mpd.conn);
- if (mpd.conn->error) {
- fprintf(stderr, "%s\n", mpd.conn->errorStr);
- mpd_closeConnection(mpd.conn);
+ /* check if configured */
+ if (configure_mpd() < 0) {
+ return -1;
+ }
+ /* check if connected */
+ if (conn == NULL || conn->error) {
+ if (conn) {
+ if (errorcnt < ERROR_DISPLAY)
+ debug("[MPD] Error: [%s], try to reconnect to [%s]:[%i]\n", conn->errorStr, host, iport);
+ mpd_closeConnection(conn);
+ } else
+ debug("[MPD] initialize connect to [%s]:[%i]\n", host, iport);
+
+ conn = mpd_newConnection(host, iport, TIMEOUT_IN_S);
+ if (conn->error) {
+ if (errorcnt < ERROR_DISPLAY)
+ error("[MPD] connection failed, give up...");
+ if (errorcnt == ERROR_DISPLAY)
+ error("[MPD] stop logging, until connection is fixed!");
+ errorcnt++;
+ gettimeofday(&timestamp, NULL);
+ return -1;
+ }
+ errorcnt = 0;
+ debug("[MPD] connection fixed...");
}
- mpd_freeStatus(mpd.status);
- mpd_closeConnection(mpd.conn);
-}
+ mpd_Status *status = NULL;
+ mpd_Stats *stats = NULL;
+ mpd_InfoEntity *entity;
+
+ mpd_sendCommandListOkBegin(conn);
+ mpd_sendStatsCommand(conn);
+ if (conn->error) {
+ error("[MPD] error: %s", conn->errorStr);
+ return -1;
+ }
+ mpd_sendStatusCommand(conn);
+ mpd_sendCurrentSongCommand(conn);
+ mpd_sendCommandListEnd(conn);
-static void artist(RESULT * result, RESULT * query)
-{
- char *value = " ";
- struct Pointer mpd = connect();
+ stats = mpd_getStats(conn);
+ if (stats == NULL) {
+ error("[MPD] error mpd_getStats: %s", conn->errorStr);
+ goto cleanup;
+ }
- mpd_nextListOkCommand(mpd.conn);
+ mpd_nextListOkCommand(conn);
+ if ((status = mpd_getStatus(conn)) == NULL) {
+ error("[MPD] error mpd_nextListOkCommand: %s", conn->errorStr);
+ goto cleanup;
+ }
- while ((mpd.entity = mpd_getNextInfoEntity(mpd.conn))) {
- mpd_Song *song = mpd.entity->info.song;
+ mpd_nextListOkCommand(conn);
+ while ((entity = mpd_getNextInfoEntity(conn))) {
+ mpd_Song *song = entity->info.song;
- if (mpd.entity->type != MPD_INFO_ENTITY_TYPE_SONG) {
- mpd_freeInfoEntity(mpd.entity);
+ if (entity->type != MPD_INFO_ENTITY_TYPE_SONG) {
+ mpd_freeInfoEntity(entity);
continue;
}
+ if (currentSong != NULL)
+ mpd_freeSong(currentSong);
- if (song->artist) {
- value = strdup(song->artist);
- //add comment
- if (query) {
- char *myarg;
- myarg = strdup(R2S(query));
- value = strcat(value, myarg);
- free(myarg);
- }
- }
- mpd_freeInfoEntity(mpd.entity);
+ currentSong = mpd_songDup(song);
+ mpd_freeInfoEntity(entity);
}
- disconnect(mpd);
+ l_elapsedTimeSec = status->elapsedTime;
+ l_totalTimeSec = status->totalTime;
+ l_repeatEnabled = status->repeat;
+ l_randomEnabled = status->random;
+ l_bitRate = status->bitRate;
+ l_state = status->state;
+ l_volume = status->volume;
+ l_playlistLength = status->playlistLength;
+ l_currentSongPos = status->song + 1;
+ l_sampleRate = status->sampleRate;
+ l_channels = status->channels;
- /* store result */
- SetResult(&result, R_STRING, value);
+ l_numberOfSongs = stats->numberOfSongs;
+ l_uptime = stats->uptime;
+ l_playTime = stats->playTime;
+ l_dbPlayTime = stats->dbPlayTime;
- free(value);
-}
+ /* sanity checks */
+ if (l_volume < 0 || l_volume > 100)
+ l_volume = 0;
-static void title(RESULT * result)
-{
- char *value = " ";
- struct Pointer mpd = connect();
+ if (l_bitRate < 0)
+ l_bitRate = 0;
- mpd_nextListOkCommand(mpd.conn);
+ if (l_elapsedTimeSec > l_totalTimeSec || l_elapsedTimeSec < 0)
+ l_elapsedTimeSec = 0;
+ ret = 0;
- while ((mpd.entity = mpd_getNextInfoEntity(mpd.conn))) {
- mpd_Song *song = mpd.entity->info.song;
+ cleanup:
+ if (stats != NULL)
+ mpd_freeStats(stats);
- if (mpd.entity->type != MPD_INFO_ENTITY_TYPE_SONG) {
- mpd_freeInfoEntity(mpd.entity);
- continue;
- }
+ if (status != NULL)
+ mpd_freeStatus(status);
- if (song->title) {
- value = strdup(song->title);
- }
- mpd_freeInfoEntity(mpd.entity);
+ if (conn->error) {
+ error("[MPD] error: %s", conn->errorStr);
+ return -1;
}
- disconnect(mpd);
-
- /* store result */
- SetResult(&result, R_STRING, value);
+ mpd_finishCommand(conn);
+ if (conn->error) {
+ error("[MPD] error mpd_finishCommand: %s", conn->errorStr);
+ return -1;
+ }
- free(value);
+ gettimeofday(&timestamp, NULL);
+ return ret;
}
-static void album(RESULT * result)
+static void elapsedTimeSec(RESULT * result)
{
- char *value = " ";
- struct Pointer mpd = connect();
-
- mpd_nextListOkCommand(mpd.conn);
-
- while ((mpd.entity = mpd_getNextInfoEntity(mpd.conn))) {
- mpd_Song *song = mpd.entity->info.song;
+ double d;
+ mpd_update();
+ d = (double) l_elapsedTimeSec;
+ SetResult(&result, R_NUMBER, &d);
+}
- if (mpd.entity->type != MPD_INFO_ENTITY_TYPE_SONG) {
- mpd_freeInfoEntity(mpd.entity);
- continue;
- }
- if (song->album) {
- value = strdup(song->album);
- }
- mpd_freeInfoEntity(mpd.entity);
- }
+static void totalTimeSec(RESULT * result)
+{
+ double d;
+ mpd_update();
+ d = (double) l_totalTimeSec;
+ SetResult(&result, R_NUMBER, &d);
+}
- disconnect(mpd);
+static void bitRate(RESULT * result)
+{
+ double d;
+ mpd_update();
+ d = (double) l_bitRate;
+ SetResult(&result, R_NUMBER, &d);
+}
- /* store result */
- SetResult(&result, R_STRING, value);
- free(value);
+static void getRepeatInt(RESULT * result)
+{
+ double d;
+ mpd_update();
+ d = (double) l_repeatEnabled;
+ SetResult(&result, R_NUMBER, &d);
}
-#define _mpd_dummy 000
-#define _mpd_status_get_elapsed_song_time 001
-#define _mpd_status_get_bitrate 002
-#define _mpd_status_get_total_song_time 003
-#define _mpd_player_get_repeat 004
-#define _mpd_player_get_random 005
-void error_callback(MpdObj * mi, int errorid, char *msg, void *userdata)
+static void getRandomInt(RESULT * result)
{
- printf("Error %i: '%s'\n", errorid, msg);
+ double d;
+ mpd_update();
+ d = (double) l_randomEnabled;
+ SetResult(&result, R_NUMBER, &d);
}
-static int mpd_get(int function)
+/* if no tag is availabe, use filename */
+static void getArtist(RESULT * result)
{
- int ret = -1;
- MpdObj *mi = NULL;
-
- mi = mpd_new("localhost", 6600, NULL);
- mpd_signal_connect_error(mi, (ErrorCallback) error_callback, NULL);
- mpd_set_connection_timeout(mi, 5);
-
- if (!mpd_connect(mi)) {
- switch (function) {
- case _mpd_dummy:
- ret = 1;
- break;
- case _mpd_status_get_elapsed_song_time:
- ret = mpd_status_get_elapsed_song_time(mi);
- break;
- case _mpd_status_get_bitrate:
- ret = mpd_status_get_bitrate(mi);
- break;
- case _mpd_status_get_total_song_time:
- ret = mpd_status_get_total_song_time(mi);
- break;
- case _mpd_player_get_repeat:
- ret = mpd_player_get_repeat(mi);
- break;
- case _mpd_player_get_random:
- ret = mpd_player_get_random(mi);
- break;
+ mpd_update();
+ if (currentSong != NULL) {
+ if (currentSong->artist != NULL) {
+ SetResult(&result, R_STRING, currentSong->artist);
+ } else {
+ if (currentSong->file != NULL)
+ SetResult(&result, R_STRING, currentSong->file);
+ else
+ SetResult(&result, R_STRING, "");
}
+ } else
+ SetResult(&result, R_STRING, "");
- mpd_disconnect(mi);
- mpd_free(mi);
- }
- return ret;
}
-static void elapsedTime(RESULT * result)
+static void getTitle(RESULT * result)
{
- char *value = " ";
+ mpd_update();
+ if (currentSong != NULL) {
+ if (currentSong->title != NULL) {
+ SetResult(&result, R_STRING, currentSong->title);
+ } else
+ SetResult(&result, R_STRING, "");
+ } else
+ SetResult(&result, R_STRING, "");
+
+}
- int playTime = mpd_get(_mpd_status_get_elapsed_song_time);
+static void getAlbum(RESULT * result)
+{
+ mpd_update();
+ if (currentSong != NULL) {
+ if (currentSong->album != NULL)
+ SetResult(&result, R_STRING, currentSong->album);
+ else
+ SetResult(&result, R_STRING, "");
+ } else
+ SetResult(&result, R_STRING, "");
+}
- if (playTime != -1) {
- char myTime[6];
- memset(myTime, 0, 6);
- int minutes = (int) (playTime / 60);
- int seconds = (int) (playTime % 60);
- sprintf(myTime, "%02d:%02d", minutes, seconds);
+static void getFilename(RESULT * result)
+{
+ mpd_update();
+ if (currentSong != NULL) {
+ if (currentSong->file != NULL)
+ SetResult(&result, R_STRING, currentSong->file);
+ else
+ SetResult(&result, R_STRING, "");
+ } else
+ SetResult(&result, R_STRING, "");
- value = strdup(myTime);
- }
- // store result
- SetResult(&result, R_STRING, value);
}
-static void elapsedTimeSec(RESULT * result)
+/*
+ return player state:
+ 0=unknown
+ 1=play
+ 2=pause
+ 3=stop
+*/
+static void getStateInt(RESULT * result)
{
- int playTime = mpd_get(_mpd_status_get_elapsed_song_time);
- double d = 0.0;
+ double ret;
+
+ mpd_update();
+
+ switch (l_state) {
+ case MPD_STATUS_STATE_PLAY:
+ ret = 1;
+ break;
+ case MPD_STATUS_STATE_PAUSE:
+ ret = 2;
+ break;
+ case MPD_STATUS_STATE_STOP:
+ ret = 3;
+ break;
+ default:
+ ret = 0;
+ break;
+ }
- if (playTime != -1)
- d = playTime;
+ SetResult(&result, R_NUMBER, &ret);
+}
- // store result
+
+static void getVolume(RESULT * result)
+{
+ double d;
+ mpd_update();
+ d = (double) l_volume;
+ /* return 0..100 or < 0 when failed */
SetResult(&result, R_NUMBER, &d);
}
-static void totalTime(RESULT * result)
+/* return the # of songs in the mpd db .. */
+static void getSongsInDb(RESULT * result)
{
- char *value = " ";
+ double d;
+ mpd_update();
+ d = (double) l_numberOfSongs;
+ SetResult(&result, R_NUMBER, &d);
+}
- int totTime = mpd_get(_mpd_status_get_total_song_time);
- if (totTime != -1) {
- char myTime[6];
- memset(myTime, 0, 6);
- int minutes = (int) (totTime / 60);
- int seconds = (int) (totTime % 60);
- sprintf(myTime, "%02d:%02d", minutes, seconds);
+static void getMpdUptime(RESULT * result)
+{
+ double d;
+ mpd_update();
+ d = (double) l_uptime;
+ SetResult(&result, R_NUMBER, &d);
+}
- value = strdup(myTime);
- } else
- value = strdup("ERROR");
- // store result
- SetResult(&result, R_STRING, value);
+static void getMpdPlayTime(RESULT * result)
+{
+ double d;
+ mpd_update();
+ d = (double) l_playTime;
+ SetResult(&result, R_NUMBER, &d);
}
-static void totalTimeSec(RESULT * result)
+static void getMpdDbPlayTime(RESULT * result)
{
- int totTime = mpd_get(_mpd_status_get_total_song_time);
- double d = 0.0;
+ double d;
+ mpd_update();
+ d = (double) l_dbPlayTime;
+ SetResult(&result, R_NUMBER, &d);
+}
+
+static void getMpdPlaylistLength(RESULT * result)
+{
+ double d;
+ mpd_update();
+ d = (double) l_playlistLength;
+ SetResult(&result, R_NUMBER, &d);
+}
- if (totTime != -1)
- d = totTime;
+static void getCurrentSongPos(RESULT * result)
+{
+ double d;
+ mpd_update();
+ d = (double) l_currentSongPos;
+ SetResult(&result, R_NUMBER, &d);
+}
- // store result
+static void getAudioChannels(RESULT * result)
+{
+ double d;
+ mpd_update();
+ d = (double) l_channels;
SetResult(&result, R_NUMBER, &d);
}
-static void bitRate(RESULT * result)
+static void getSamplerateHz(RESULT * result)
{
- char *value = "";
+ double d;
+ mpd_update();
+ d = (double) l_sampleRate;
+ SetResult(&result, R_NUMBER, &d);
+}
- int rate = mpd_get(_mpd_status_get_bitrate);
- if (rate != -1) {
- char rateStr[4];
- memset(rateStr, 0, 4);
- sprintf(rateStr, "%03d", rate);
+static void nextSong()
+{
+ mpd_update();
+ if (currentSong != NULL) {
+ mpd_sendNextCommand(conn);
+ mpd_finishCommand(conn);
+ if (conn->error) {
+ error("[MPD] error mpd_finishCommand: %s", conn->errorStr);
+ }
+ }
+}
+
+static void prevSong()
+{
+ mpd_update();
+ if (currentSong != NULL) {
+ mpd_sendPrevCommand(conn);
+ mpd_finishCommand(conn);
+ if (conn->error) {
+ error("[MPD] error mpd_finishCommand: %s", conn->errorStr);
+ }
+ }
+}
- value = strdup(rateStr);
+static void stopSong()
+{
+ mpd_update();
+ if (currentSong != NULL) {
+ mpd_sendStopCommand(conn);
+ mpd_finishCommand(conn);
+ if (conn->error) {
+ error("[MPD] error mpd_finishCommand: %s", conn->errorStr);
+ }
}
- // store result
- SetResult(&result, R_STRING, value);
}
-static void getRepeat(RESULT * result)
+static void pauseSong()
{
- char *value = " ";
+ mpd_update();
+ if (currentSong != NULL) {
+ if (l_state == MPD_STATUS_STATE_PAUSE) {
+ mpd_sendPauseCommand(conn, 0);
+ } else {
+ mpd_sendPauseCommand(conn, 1);
+ }
- int rep = mpd_get(_mpd_player_get_repeat);
+ mpd_finishCommand(conn);
+ if (conn->error) {
+ error("[MPD] error mpd_finishCommand: %s", conn->errorStr);
+ }
+ }
+}
- if (rep != -1) {
- if (rep)
- value = strdup("REP");
- // else value = strdup(" ");
+static void volUp()
+{
+ mpd_update();
+ if (currentSong != NULL) {
+ l_volume += 5;
+ if (l_volume > 100)
+ l_volume = 100;
+ mpd_sendSetvolCommand(conn, l_volume);
+ mpd_finishCommand(conn);
+ if (conn->error) {
+ error("[MPD] error mpd_finishCommand: %s", conn->errorStr);
+ }
}
- // store result
- SetResult(&result, R_STRING, value);
}
+static void volDown()
+{
+ mpd_update();
+ if (currentSong != NULL) {
+ if (l_volume > 5)
+ l_volume -= 5;
+ else
+ l_volume = 0;
+ mpd_sendSetvolCommand(conn, l_volume);
+ mpd_finishCommand(conn);
+ if (conn->error) {
+ error("[MPD] error mpd_finishCommand: %s", conn->errorStr);
+ }
+ }
+}
-static void getRandom(RESULT * result)
+static void toggleRepeat()
{
- char *value = " ";
+ mpd_update();
+ if (currentSong != NULL) {
- int ran = mpd_get(_mpd_player_get_random);
+ l_repeatEnabled = !l_repeatEnabled;
+ mpd_sendRepeatCommand(conn, l_repeatEnabled);
- if (ran != -1) {
- if (ran)
- value = strdup("RND");
- // else value = strdup(" ");
+ mpd_finishCommand(conn);
+ if (conn->error) {
+ error("[MPD] error mpd_finishCommand: %s", conn->errorStr);
+ }
}
- // store result
- SetResult(&result, R_STRING, value);
}
-static void getRepRand(RESULT * result)
+
+static void toggleRandom()
{
- char *value = " ";
+ mpd_update();
+ if (currentSong != NULL) {
- int ran = mpd_get(_mpd_player_get_random);
- int rep = mpd_get(_mpd_player_get_repeat);
+ l_randomEnabled = !l_randomEnabled;
+ mpd_sendRandomCommand(conn, l_randomEnabled);
- if (ran != -1 && rep != -1) {
- char str[9];
- if (rep)
- sprintf(str, "REP/");
- else
- sprintf(str, "---/");
- if (ran)
- sprintf(str, "%sRND", str);
- else
- sprintf(str, "%s---", str);
- value = strdup(str);
+ mpd_finishCommand(conn);
+ if (conn->error) {
+ error("[MPD] error mpd_finishCommand: %s", conn->errorStr);
+ }
}
- // store result
- SetResult(&result, R_STRING, value);
}
-int plugin_init_mpd(void)
+
+static void formatTimeMMSS(RESULT * result, RESULT * param)
{
- /* Check for File */
- if (mpd_get(_mpd_dummy) != 1) {
- error("Error: Cannot connect to MPD! Is MPD started?");
- return -1;
- }
+ long sec;
+ char myTime[6] = " ";
+
+ sec = R2N(param);
- AddFunction("mpd::artist", 1, artist);
- AddFunction("mpd::title", 0, title);
- AddFunction("mpd::album", 0, album);
- AddFunction("mpd::totalTime", 0, totalTime);
+ if ((sec >= 0) && (sec < 6000)) {
+ const int minutes = (int) (sec / 60);
+ const int seconds = (int) (sec % 60);
+ sprintf(myTime, "%02d:%02d", minutes, seconds);
+ } else if (sec >= 6000) {
+ strcpy(myTime, "LONG");
+ } else
+ strcpy(myTime, "ERROR");
+
+ /* store result */
+ SetResult(&result, R_STRING, myTime);
+}
+
+static void formatTimeDDHHMM(RESULT * result, RESULT * param)
+{
+ long sec;
+ char myTime[16] = " ";
+
+ sec = R2N(param);
+
+ if (sec >= 0) {
+ int days = sec / 86400;
+ int hours = (sec % 86400) / 3600;
+ int minutes = (sec % 3600) / 60;
+ sprintf(myTime, "%dd%02dh%02dm", days, hours, minutes); /* 3d 12:33h */
+ } else
+ strcpy(myTime, "ERROR");
+
+ /* store result */
+ SetResult(&result, R_STRING, myTime);
+}
+
+
+
+int plugin_init_mpd(void)
+{
+ int check;
+ debug("[MPD] v0.83, check lcd4linux configuration file...");
+
+ check = configure_mpd();
+ if (plugin_enabled != 1)
+ return 0;
+
+ if (check)
+ debug("[MPD] configured!");
+ else
+ debug("[MPD] error, NOT configured!");
+
+ /* when mpd dies, do NOT exit application, ignore it! */
+ signal(SIGPIPE, SIG_IGN);
+ gettimeofday(&timestamp, NULL);
+
+ AddFunction("mpd::artist", 0, getArtist);
+ AddFunction("mpd::title", 0, getTitle);
+ AddFunction("mpd::album", 0, getAlbum);
+ AddFunction("mpd::file", 0, getFilename);
AddFunction("mpd::totalTimeSec", 0, totalTimeSec);
- AddFunction("mpd::elapsedTime", 0, elapsedTime);
AddFunction("mpd::elapsedTimeSec", 0, elapsedTimeSec);
AddFunction("mpd::bitRate", 0, bitRate);
- AddFunction("mpd::getRepeat", 0, getRepeat);
- AddFunction("mpd::getRandom", 0, getRandom);
- AddFunction("mpd::getRepRand", 0, getRepRand);
+ AddFunction("mpd::getSamplerateHz", 0, getSamplerateHz);
+ AddFunction("mpd::getAudioChannels", 0, getAudioChannels);
+ AddFunction("mpd::getRepeatInt", 0, getRepeatInt);
+ AddFunction("mpd::getRandomInt", 0, getRandomInt);
+ AddFunction("mpd::getStateInt", 0, getStateInt);
+ AddFunction("mpd::getVolume", 0, getVolume);
+ AddFunction("mpd::getSongsInDb", 0, getSongsInDb);
+ AddFunction("mpd::getMpdUptime", 0, getMpdUptime);
+ AddFunction("mpd::getMpdPlayTime", 0, getMpdPlayTime);
+ AddFunction("mpd::getMpdDbPlayTime", 0, getMpdDbPlayTime);
+ AddFunction("mpd::getMpdPlaylistLength", 0, getMpdPlaylistLength);
+ AddFunction("mpd::getMpdPlaylistGetCurrentId", 0, getCurrentSongPos);
+
+ AddFunction("mpd::cmdNextSong", 0, nextSong);
+ AddFunction("mpd::cmdPrevSong", 0, prevSong);
+ AddFunction("mpd::cmdStopSong", 0, stopSong);
+ AddFunction("mpd::cmdTogglePauseSong", 0, pauseSong);
+ AddFunction("mpd::cmdVolUp", 0, volUp);
+ AddFunction("mpd::cmdVolDown", 0, volDown);
+ AddFunction("mpd::cmdToggleRandom", 0, toggleRandom);
+ AddFunction("mpd::cmdToggleRepeat", 0, toggleRepeat);
+
+ AddFunction("mpd::formatTimeMMSS", 1, formatTimeMMSS);
+ AddFunction("mpd::formatTimeDDHHMM", 1, formatTimeDDHHMM);
+
return 0;
}
void plugin_exit_mpd(void)
{
- /* empty */
+ if (plugin_enabled == 1) {
+ debug("[MPD] disconnect from mpd");
+ if (currentSong != NULL)
+ mpd_freeSong(currentSong);
+ mpd_closeConnection(conn);
+ }
}