diff options
Diffstat (limited to 'plugin_mpd.c')
-rw-r--r-- | plugin_mpd.c | 848 |
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(×tamp, 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(×tamp, 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(×tamp, 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); + } } |