From b39c1ef247a01c538bf61d8b2bbc0730b9198a9a Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 28 Sep 2009 13:10:27 +0200 Subject: [PATCH] use libmpdclient2 --- INSTALL | 1 + Makefile.am | 6 +- NEWS | 1 + configure.ac | 25 +- src/filelist.c | 33 +- src/filelist.h | 6 +- src/libmpdclient.c | 1703 ------------------------------------------ src/libmpdclient.h | 600 --------------- src/main.c | 25 +- src/mpdclient.c | 321 ++++---- src/mpdclient.h | 20 +- src/options.c | 20 +- src/options.h | 3 - src/playlist.c | 14 +- src/playlist.h | 36 +- src/screen.c | 180 +++-- src/screen.h | 6 +- src/screen_artist.c | 16 +- src/screen_browser.c | 84 ++- src/screen_file.c | 51 +- src/screen_lyrics.c | 14 +- src/screen_outputs.c | 36 +- src/screen_play.c | 27 +- src/screen_search.c | 70 +- src/screen_song.c | 113 +-- src/screen_utils.c | 12 +- src/song.c | 141 ---- src/song.h | 101 --- src/strfsong.c | 53 +- src/strfsong.h | 3 +- src/utils.c | 30 +- 31 files changed, 659 insertions(+), 3092 deletions(-) delete mode 100644 src/libmpdclient.c delete mode 100644 src/libmpdclient.h delete mode 100644 src/song.c delete mode 100644 src/song.h diff --git a/INSTALL b/INSTALL index 99af54f..d46f21b 100644 --- a/INSTALL +++ b/INSTALL @@ -5,6 +5,7 @@ Requirements ------------ * a C99 compliant compiler (e.g. gcc) + * libmpdclient 2.0 * ncurses (ncursesw for unicode / wide character support) * glib-2.2 (2.4 for NLS support) diff --git a/Makefile.am b/Makefile.am index 911b19e..b5dccf8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,15 +5,14 @@ ACLOCAL_AMFLAGS = -I m4 AUTOMAKE_OPTIONS = foreign 1.9 dist-bzip2 AM_CPPFLAGS = \ + $(LIBMPDCLIENT_CFLAGS) \ $(GLIB_CFLAGS) \ $(LIBLIRCCLIENT_CFLAGS) \ -DLOCALE_DIR=\""$(datadir)/locale"\"\ -DSYSCONFDIR=\""$(sysconfdir)"\" ncmpc_headers = \ - src/libmpdclient.h \ src/resolver.h \ - src/song.h \ src/mpdclient.h \ src/playlist.h \ src/filelist.h \ @@ -46,14 +45,13 @@ ncmpc_headers = \ bin_PROGRAMS = src/ncmpc src_ncmpc_LDADD = \ + $(LIBMPDCLIENT_LIBS) \ $(GLIB_LIBS) \ $(LIBLIRCCLIENT_LIBS) src_ncmpc_SOURCES = \ $(ncmpc_headers) \ - src/libmpdclient.c \ src/resolver.c \ - src/song.c \ src/main.c \ src/mpdclient.c \ src/playlist.c \ diff --git a/NEWS b/NEWS index 178c143..d6669c6 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,5 @@ ncmpc 0.16 - not yet released +* using libmpdclient 2.0 instead of built-in libmpdclient ncmpc 0.15 - 2009-09-24 diff --git a/configure.ac b/configure.ac index 8ee474a..5bc8531 100644 --- a/configure.ac +++ b/configure.ac @@ -146,6 +146,10 @@ dnl Check for glib-2.4 PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.4],, [AC_MSG_ERROR([glib 2.4 is required])]) +dnl Check for libmpdclient 2.0 +PKG_CHECK_MODULES([LIBMPDCLIENT], [libmpdclient >= 2.0],, + [AC_MSG_ERROR([libmpdclient2 is required])]) + dnl i18n @@ -363,27 +367,6 @@ fi AM_CONDITIONAL(ENABLE_OUTPUTS_SCREEN, test x$outputs_screen = xyes) -dnl Default host -AC_MSG_CHECKING([for default MPD host]) -AC_ARG_WITH([default-host], - AC_HELP_STRING([--with-default-host=ARG], - [Default MPD host @<:@localhost@:>@]), - [DEFAULT_HOST="$withval"], - [DEFAULT_HOST="localhost"]) -AC_MSG_RESULT([$DEFAULT_HOST]) -AC_DEFINE_UNQUOTED([DEFAULT_HOST], ["$DEFAULT_HOST"], [Default MPD host]) - -dnl Default port -AC_MSG_CHECKING([for default MPD port]) -AC_ARG_WITH([default-port], - AC_HELP_STRING([--with-default-port=ARG], - [Default port @<:@6600@:>@]), - [DEFAULT_PORT="$withval"], - [DEFAULT_PORT="6600"]) -AC_MSG_RESULT([$DEFAULT_PORT]) -AC_DEFINE_UNQUOTED([DEFAULT_PORT], [$DEFAULT_PORT], [Default MPD port]) -AC_DEFINE_UNQUOTED([DEFAULT_PORT_STR], ["$DEFAULT_PORT"], [Default MPD port]) - dnl Default timedisplay type AC_MSG_CHECKING([for default timedisplay type]) AC_ARG_WITH([default-timedisplay_type], diff --git a/src/filelist.c b/src/filelist.c index e3e1cb1..575d407 100644 --- a/src/filelist.c +++ b/src/filelist.c @@ -18,7 +18,8 @@ */ #include "filelist.h" -#include "libmpdclient.h" + +#include #include #include @@ -43,7 +44,7 @@ filelist_free(struct filelist *filelist) struct filelist_entry *entry = filelist_get(filelist, i); if (entry->entity) - mpd_freeInfoEntity(entry->entity); + mpd_entity_free(entry->entity); g_slice_free(struct filelist_entry, entry); } @@ -53,7 +54,7 @@ filelist_free(struct filelist *filelist) } struct filelist_entry * -filelist_append(struct filelist *filelist, struct mpd_InfoEntity *entity) +filelist_append(struct filelist *filelist, struct mpd_entity *entity) { struct filelist_entry *entry = g_slice_new(struct filelist_entry); @@ -66,7 +67,7 @@ filelist_append(struct filelist *filelist, struct mpd_InfoEntity *entity) } struct filelist_entry * -filelist_prepend(struct filelist *filelist, struct mpd_InfoEntity *entity) +filelist_prepend(struct filelist *filelist, struct mpd_entity *entity) { struct filelist_entry *entry = filelist_append(filelist, entity); @@ -125,7 +126,7 @@ void filelist_sort_dir_play(struct filelist *filelist, GCompareFunc compare_func) { unsigned first, last; - const mpd_InfoEntity *iter; + const struct mpd_entity *iter; assert(filelist && filelist->entries); @@ -143,7 +144,7 @@ filelist_sort_dir_play(struct filelist *filelist, GCompareFunc compare_func) /* find the last directory entry */ for (last = first+1; last < filelist->entries->len; last++) { iter = ((struct filelist_entry*) g_ptr_array_index(filelist->entries, last))->entity; - if (iter->type != MPD_INFO_ENTITY_TYPE_DIRECTORY) + if (mpd_entity_get_type(iter) != MPD_ENTITY_TYPE_DIRECTORY) break; } if (last == filelist->entries->len - 1) @@ -156,7 +157,7 @@ filelist_sort_dir_play(struct filelist *filelist, GCompareFunc compare_func) /* find the first playlist entry */ for (first = last; first < filelist->entries->len; first++) { iter = ((struct filelist_entry*) g_ptr_array_index(filelist->entries, first))->entity; - if (iter->type == MPD_INFO_ENTITY_TYPE_PLAYLISTFILE) + if (mpd_entity_get_type(iter) == MPD_ENTITY_TYPE_PLAYLIST) break; } /* sort the playlist entries */ @@ -169,7 +170,7 @@ filelist_sort_dir_play(struct filelist *filelist, GCompareFunc compare_func) static bool same_song(const struct mpd_song *a, const struct mpd_song *b) { - return strcmp(a->file, b->file) == 0; + return strcmp(mpd_song_get_uri(a), mpd_song_get_uri(b)) == 0; } int @@ -181,10 +182,12 @@ filelist_find_song(struct filelist *fl, const struct mpd_song *song) for (i = 0; i < filelist_length(fl); ++i) { struct filelist_entry *entry = filelist_get(fl, i); - mpd_InfoEntity *entity = entry->entity; + const struct mpd_entity *entity = entry->entity; - if (entity && entity->type == MPD_INFO_ENTITY_TYPE_SONG) { - struct mpd_song *song2 = entity->info.song; + if (entity != NULL && + mpd_entity_get_type(entity) == MPD_ENTITY_TYPE_SONG) { + const struct mpd_song *song2 = + mpd_entity_get_song(entity); if (same_song(song, song2)) return i; @@ -203,10 +206,12 @@ filelist_find_directory(struct filelist *filelist, const char *name) for (i = 0; i < filelist_length(filelist); ++i) { struct filelist_entry *entry = filelist_get(filelist, i); - mpd_InfoEntity *entity = entry->entity; + const struct mpd_entity *entity = entry->entity; - if (entity && entity->type == MPD_INFO_ENTITY_TYPE_DIRECTORY && - strcmp(entity->info.directory->path, name) == 0) + if (entity != NULL && + mpd_entity_get_type(entity) == MPD_ENTITY_TYPE_DIRECTORY && + strcmp(mpd_directory_get_path(mpd_entity_get_directory(entity)), + name) == 0) return i; } diff --git a/src/filelist.h b/src/filelist.h index 6e13b23..7904016 100644 --- a/src/filelist.h +++ b/src/filelist.h @@ -26,7 +26,7 @@ struct mpd_song; typedef struct filelist_entry { guint flags; - struct mpd_InfoEntity *entity; + struct mpd_entity *entity; } filelist_entry_t; typedef struct filelist { @@ -59,10 +59,10 @@ filelist_get(const struct filelist *filelist, guint i) } struct filelist_entry * -filelist_append(struct filelist *filelist, struct mpd_InfoEntity *entity); +filelist_append(struct filelist *filelist, struct mpd_entity *entity); struct filelist_entry * -filelist_prepend(struct filelist *filelist, struct mpd_InfoEntity *entity); +filelist_prepend(struct filelist *filelist, struct mpd_entity *entity); void filelist_move(struct filelist *filelist, struct filelist *from); diff --git a/src/libmpdclient.c b/src/libmpdclient.c deleted file mode 100644 index 4cf2d80..0000000 --- a/src/libmpdclient.c +++ /dev/null @@ -1,1703 +0,0 @@ -/* libmpdclient - (c)2003-2006 by Warren Dukes (warren.dukes@gmail.com) - This project's homepage is: http://www.musicpd.org - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Music Player Daemon nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "libmpdclient.h" -#include "resolver.h" -#include "str_pool.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef WIN32 -# include -# include -#else -# include -# include -# include -# include -#endif - -#ifndef WIN32 -#include -#endif - -#ifndef MSG_DONTWAIT -# define MSG_DONTWAIT 0 -#endif - -#define COMMAND_LIST 1 -#define COMMAND_LIST_OK 2 - -#ifdef WIN32 -# define SELECT_ERRNO_IGNORE (errno == WSAEINTR || errno == WSAEINPROGRESS) -# define SENDRECV_ERRNO_IGNORE SELECT_ERRNO_IGNORE -#else -# define SELECT_ERRNO_IGNORE (errno == EINTR) -# define SENDRECV_ERRNO_IGNORE (errno == EINTR || errno == EAGAIN) -# define winsock_dll_error(c) 0 -# define closesocket(s) close(s) -# define WSACleanup() do { /* nothing */ } while (0) -#endif - -#ifdef WIN32 -static int winsock_dll_error(mpd_Connection *connection) -{ - WSADATA wsaData; - if ((WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0 || - LOBYTE(wsaData.wVersion) != 2 || - HIBYTE(wsaData.wVersion) != 2 ) { - snprintf(connection->errorStr, sizeof(connection->errorStr), - "Could not find usable WinSock DLL."); - connection->error = MPD_ERROR_SYSTEM; - return 1; - } - return 0; -} - -static int do_connect_fail(mpd_Connection *connection, - const struct sockaddr *serv_addr, int addrlen) -{ - int iMode = 1; /* 0 = blocking, else non-blocking */ - ioctlsocket(connection->sock, FIONBIO, (u_long FAR*) &iMode); - return (connect(connection->sock,serv_addr,addrlen) == SOCKET_ERROR - && WSAGetLastError() != WSAEWOULDBLOCK); -} -#else /* !WIN32 (sane operating systems) */ -static int do_connect_fail(mpd_Connection *connection, - const struct sockaddr *serv_addr, int addrlen) -{ - int flags = fcntl(connection->sock, F_GETFL, 0); - fcntl(connection->sock, F_SETFL, flags | O_NONBLOCK); - return (connect(connection->sock,serv_addr,addrlen)<0 && - errno!=EINPROGRESS); -} -#endif /* !WIN32 */ - -const char *const mpdTagItemKeys[MPD_TAG_NUM_OF_ITEM_TYPES] = -{ - "Artist", - "Album", - "Title", - "Track", - "Name", - "Genre", - "Date", - "Composer", - "Performer", - "Comment", - "Disc", - "filename" -}; - -static char * mpd_sanitizeArg(const char * arg) { - size_t i; - char * ret; - register const char *c; - register char *rc; - - /* instead of counting in that loop above, just - * use a bit more memory and half running time - */ - ret = malloc(strlen(arg) * 2 + 1); - - c = arg; - rc = ret; - for(i = strlen(arg)+1; i != 0; --i) { - if(*c=='"' || *c=='\\') - *rc++ = '\\'; - *(rc++) = *(c++); - } - - return ret; -} - -static mpd_ReturnElement * mpd_newReturnElement(const char * name, const char * value) -{ - mpd_ReturnElement * ret = malloc(sizeof(mpd_ReturnElement)); - - ret->name = str_pool_get(name); - ret->value = str_pool_get(value); - - return ret; -} - -static void mpd_freeReturnElement(mpd_ReturnElement * re) { - str_pool_put(re->name); - str_pool_put(re->value); - free(re); -} - -void -mpd_setConnectionTimeout(mpd_Connection *connection, float timeout_) { - connection->timeout.tv_sec = (int)timeout_; - connection->timeout.tv_usec = (int)(timeout_ * 1e6 - - connection->timeout.tv_sec*1000000 + - 0.5); -} - -static int mpd_parseWelcome(mpd_Connection * connection, const char * host, int port, - char * output) { - char * tmp; - char * test; - int i; - - if(strncmp(output,MPD_WELCOME_MESSAGE,strlen(MPD_WELCOME_MESSAGE))) { - snprintf(connection->errorStr, sizeof(connection->errorStr), - "mpd not running on port %i on host \"%s\"", - port,host); - connection->error = MPD_ERROR_NOTMPD; - return 1; - } - - tmp = &output[strlen(MPD_WELCOME_MESSAGE)]; - - for(i=0;i<3;i++) { - if(tmp) connection->version[i] = strtol(tmp,&test,10); - - if (!tmp || (test[0] != '.' && test[0] != '\0')) { - snprintf(connection->errorStr, sizeof(connection->errorStr), - "error parsing version number at " - "\"%s\"", - &output[strlen(MPD_WELCOME_MESSAGE)]); - connection->error = MPD_ERROR_NOTMPD; - return 1; - } - tmp = ++test; - } - - return 0; -} - -/** - * Wait for the socket to become readable. - */ -static int mpd_wait(mpd_Connection *connection) -{ - struct timeval tv; - fd_set fds; - int ret; - - assert(connection->sock >= 0); - - while (1) { - tv = connection->timeout; - FD_ZERO(&fds); - FD_SET(connection->sock, &fds); - - ret = select(connection->sock + 1, &fds, NULL, NULL, &tv); - if (ret > 0) - return 0; - - if (ret == 0 || !SELECT_ERRNO_IGNORE) - return -1; - } -} - -/** - * Wait until the socket is connected and check its result. Returns 1 - * on success, 0 on timeout, -errno on error. - */ -static int mpd_wait_connected(mpd_Connection *connection) -{ - int ret; - int s_err = 0; - socklen_t s_err_size = sizeof(s_err); - - ret = mpd_wait(connection); - if (ret < 0) - return 0; - - ret = getsockopt(connection->sock, SOL_SOCKET, SO_ERROR, - (char*)&s_err, &s_err_size); - if (ret < 0) - return -errno; - - if (s_err != 0) - return -s_err; - - return 1; -} - -/** - * Attempt to read data from the socket into the input buffer. - * Returns 0 on success, -1 on error. - */ -static int mpd_recv(mpd_Connection *connection) -{ - int ret; - ssize_t nbytes; - - assert(connection != NULL); - assert(connection->buflen <= sizeof(connection->buffer)); - assert(connection->bufstart <= connection->buflen); - - if (connection->sock < 0) { - strcpy(connection->errorStr, "not connected"); - connection->error = MPD_ERROR_CONNCLOSED; - connection->doneProcessing = 1; - connection->doneListOk = 0; - return -1; - } - - if (connection->buflen >= sizeof(connection->buffer)) { - /* delete consumed data from beginning of buffer */ - connection->buflen -= connection->bufstart; - memmove(connection->buffer, - connection->buffer + connection->bufstart, - connection->buflen); - connection->bufstart = 0; - } - - if (connection->buflen >= sizeof(connection->buffer)) { - strcpy(connection->errorStr, "buffer overrun"); - connection->error = MPD_ERROR_BUFFEROVERRUN; - connection->doneProcessing = 1; - connection->doneListOk = 0; - return -1; - } - - while (1) { - ret = mpd_wait(connection); - if (ret < 0) { - strcpy(connection->errorStr, "connection timeout"); - connection->error = MPD_ERROR_TIMEOUT; - connection->doneProcessing = 1; - connection->doneListOk = 0; - return -1; - } - - nbytes = read(connection->sock, - connection->buffer + connection->buflen, - sizeof(connection->buffer) - connection->buflen); - if (nbytes > 0) { - connection->buflen += nbytes; - return 0; - } - - if (nbytes == 0 || !SENDRECV_ERRNO_IGNORE) { - strcpy(connection->errorStr, "connection closed"); - connection->error = MPD_ERROR_CONNCLOSED; - connection->doneProcessing = 1; - connection->doneListOk = 0; - return -1; - } - } -} - -static int -mpd_connect(mpd_Connection *connection, const char * host, int port) -{ - struct resolver *resolver; - const struct resolver_address *address; - int ret; - - resolver = resolver_new(host, port); - if (resolver == NULL) { - snprintf(connection->errorStr, sizeof(connection->errorStr), - "host \"%s\" not found", host); - connection->error = MPD_ERROR_UNKHOST; - return -1; - } - - while ((address = resolver_next(resolver)) != NULL) { - connection->sock = socket(address->family, SOCK_STREAM, - address->protocol); - if (connection->sock < 0) { - snprintf(connection->errorStr, - sizeof(connection->errorStr), - "problems creating socket: %s", - strerror(errno)); - connection->error = MPD_ERROR_SYSTEM; - continue; - } - - ret = do_connect_fail(connection, - address->addr, address->addrlen); - if (ret != 0) { - snprintf(connection->errorStr, - sizeof(connection->errorStr), - "problems connecting to \"%s\" on port" - " %i: %s", host, port, strerror(errno)); - connection->error = MPD_ERROR_CONNPORT; - - closesocket(connection->sock); - connection->sock = -1; - continue; - } - - ret = mpd_wait_connected(connection); - if (ret > 0) { - resolver_free(resolver); - mpd_clearError(connection); - return 0; - } - - if (ret == 0) { - snprintf(connection->errorStr, - sizeof(connection->errorStr), - "timeout in attempting to get a response from" - " \"%s\" on port %i", host, port); - connection->error = MPD_ERROR_NORESPONSE; - } else if (ret < 0) { - snprintf(connection->errorStr, - sizeof(connection->errorStr), - "problems connecting to \"%s\" on port %i: %s", - host, port, strerror(-ret)); - connection->error = MPD_ERROR_CONNPORT; - } - - closesocket(connection->sock); - connection->sock = -1; - } - - resolver_free(resolver); - return -1; -} - -mpd_Connection * -mpd_newConnection(const char *host, int port, float timeout_) { - int err; - char * rt; - mpd_Connection * connection = malloc(sizeof(mpd_Connection)); - - connection->buflen = 0; - connection->bufstart = 0; - mpd_clearError(connection); - connection->doneProcessing = 0; - connection->commandList = 0; - connection->listOks = 0; - connection->doneListOk = 0; - connection->returnElement = NULL; - connection->request = NULL; - - if (winsock_dll_error(connection)) - return connection; - - mpd_setConnectionTimeout(connection, timeout_); - - err = mpd_connect(connection, host, port); - if (err < 0) - return connection; - - while(!(rt = memchr(connection->buffer, '\n', connection->buflen))) { - err = mpd_recv(connection); - if (err < 0) - return connection; - } - - *rt = '\0'; - if (mpd_parseWelcome(connection, host, port, connection->buffer) == 0) - connection->doneProcessing = 1; - - connection->buflen -= rt + 1 - connection->buffer; - memmove(connection->buffer, rt + 1, connection->buflen); - - return connection; -} - -void mpd_clearError(mpd_Connection * connection) { - connection->error = 0; - connection->errorStr[0] = '\0'; -} - -void mpd_closeConnection(mpd_Connection * connection) { - closesocket(connection->sock); - if(connection->returnElement) free(connection->returnElement); - if(connection->request) free(connection->request); - free(connection); - WSACleanup(); -} - -static void mpd_executeCommand(mpd_Connection *connection, - const char *command) { - int ret; - struct timeval tv; - fd_set fds; - const char *commandPtr = command; - int commandLen = strlen(command); - - if (connection->sock < 0) { - strcpy(connection->errorStr, "not connected"); - connection->error = MPD_ERROR_CONNCLOSED; - return; - } - - if (!connection->doneProcessing && !connection->commandList) { - strcpy(connection->errorStr, - "not done processing current command"); - connection->error = 1; - return; - } - - mpd_clearError(connection); - - FD_ZERO(&fds); - FD_SET(connection->sock,&fds); - tv.tv_sec = connection->timeout.tv_sec; - tv.tv_usec = connection->timeout.tv_usec; - - while((ret = select(connection->sock+1,NULL,&fds,NULL,&tv)==1) || - (ret==-1 && SELECT_ERRNO_IGNORE)) { - ret = send(connection->sock,commandPtr,commandLen,MSG_DONTWAIT); - if(ret<=0) - { - if (SENDRECV_ERRNO_IGNORE) continue; - snprintf(connection->errorStr, sizeof(connection->errorStr), - "problems giving command \"%s\"",command); - connection->error = MPD_ERROR_SENDING; - return; - } - else { - commandPtr+=ret; - commandLen-=ret; - } - - if(commandLen<=0) break; - } - - if(commandLen>0) { - perror(""); - snprintf(connection->errorStr, sizeof(connection->errorStr), - "timeout sending command \"%s\"",command); - connection->error = MPD_ERROR_TIMEOUT; - return; - } - - if(!connection->commandList) connection->doneProcessing = 0; - else if(connection->commandList == COMMAND_LIST_OK) { - connection->listOks++; - } -} - -static void mpd_getNextReturnElement(mpd_Connection * connection) { - char * output = NULL; - char * rt = NULL; - char * name = NULL; - char * value = NULL; - char * tok = NULL; - int err; - int pos; - - if(connection->returnElement) mpd_freeReturnElement(connection->returnElement); - connection->returnElement = NULL; - - if (connection->doneProcessing || - (connection->listOks && connection->doneListOk)) { - strcpy(connection->errorStr,"already done processing current command"); - connection->error = 1; - return; - } - - while (!(rt = memchr(connection->buffer + connection->bufstart, '\n', - connection->buflen - connection->bufstart))) { - err = mpd_recv(connection); - if (err < 0) - return; - } - - *rt = '\0'; - output = connection->buffer+connection->bufstart; - connection->bufstart = rt - connection->buffer + 1; - - if(strcmp(output,"OK")==0) { - if(connection->listOks > 0) { - strcpy(connection->errorStr, "expected more list_OK's"); - connection->error = 1; - } - connection->listOks = 0; - connection->doneProcessing = 1; - connection->doneListOk = 0; - return; - } - - if(strcmp(output, "list_OK") == 0) { - if(!connection->listOks) { - strcpy(connection->errorStr, - "got an unexpected list_OK"); - connection->error = 1; - } - else { - connection->doneListOk = 1; - connection->listOks--; - } - return; - } - - if(strncmp(output,"ACK",strlen("ACK"))==0) { - size_t length = strlen(output); - char * test; - char * needle; - int val; - - if (length >= sizeof(connection->errorStr)) - length = sizeof(connection->errorStr) - 1; - - memcpy(connection->errorStr, output, length); - connection->errorStr[length] = 0; - connection->error = MPD_ERROR_ACK; - connection->errorCode = MPD_ACK_ERROR_UNK; - connection->errorAt = MPD_ERROR_AT_UNK; - connection->doneProcessing = 1; - connection->doneListOk = 0; - - needle = strchr(output, '['); - if(!needle) return; - val = strtol(needle+1, &test, 10); - if(*test != '@') return; - connection->errorCode = val; - val = strtol(test+1, &test, 10); - if(*test != ']') return; - connection->errorAt = val; - return; - } - - tok = strchr(output, ':'); - if (!tok) return; - pos = tok - output; - value = ++tok; - name = output; - name[pos] = '\0'; - - if(value[0]==' ') { - connection->returnElement = mpd_newReturnElement(name,&(value[1])); - } - else { - snprintf(connection->errorStr, sizeof(connection->errorStr), - "error parsing: %s:%s",name,value); - connection->error = 1; - } -} - -void mpd_finishCommand(mpd_Connection * connection) { - while(!connection->doneProcessing) { - if(connection->doneListOk) connection->doneListOk = 0; - mpd_getNextReturnElement(connection); - } -} - -static void mpd_finishListOkCommand(mpd_Connection * connection) { - while(!connection->doneProcessing && connection->listOks && - !connection->doneListOk) - { - mpd_getNextReturnElement(connection); - } -} - -int mpd_nextListOkCommand(mpd_Connection * connection) { - mpd_finishListOkCommand(connection); - if(!connection->doneProcessing) connection->doneListOk = 0; - if(connection->listOks == 0 || connection->doneProcessing) return -1; - return 0; -} - -void mpd_sendStatusCommand(mpd_Connection * connection) { - mpd_executeCommand(connection,"status\n"); -} - -mpd_Status * mpd_getStatus(mpd_Connection * connection) { - mpd_Status * status; - - /*mpd_executeCommand(connection,"status\n"); - - if(connection->error) return NULL;*/ - - if(connection->doneProcessing || (connection->listOks && - connection->doneListOk)) - { - return NULL; - } - - if(!connection->returnElement) mpd_getNextReturnElement(connection); - - status = malloc(sizeof(mpd_Status)); - status->volume = -1; - status->repeat = 0; - status->random = 0; - status->single = 0; - status->consume = 0; - status->playlist = -1; - status->playlistLength = -1; - status->state = -1; - status->song = 0; - status->songid = 0; - status->elapsedTime = 0; - status->totalTime = 0; - status->bitRate = 0; - status->sampleRate = 0; - status->bits = 0; - status->channels = 0; - status->crossfade = -1; - status->error = NULL; - status->updatingDb = 0; - - if(connection->error) { - free(status); - return NULL; - } - while(connection->returnElement) { - mpd_ReturnElement * re = connection->returnElement; - if(strcmp(re->name,"volume")==0) { - status->volume = atoi(re->value); - } - else if(strcmp(re->name,"repeat")==0) { - status->repeat = atoi(re->value); - } - else if(strcmp(re->name,"random")==0) { - status->random = atoi(re->value); - } - else if(strcmp(re->name,"single")==0) { - status->single = atoi(re->value); - } - else if(strcmp(re->name,"consume")==0) { - status->consume = atoi(re->value); - } - else if(strcmp(re->name,"playlist")==0) { - status->playlist = strtol(re->value,NULL,10); - } - else if(strcmp(re->name,"playlistlength")==0) { - status->playlistLength = atoi(re->value); - } - else if(strcmp(re->name,"bitrate")==0) { - status->bitRate = atoi(re->value); - } - else if(strcmp(re->name,"state")==0) { - if(strcmp(re->value,"play")==0) { - status->state = MPD_STATUS_STATE_PLAY; - } - else if(strcmp(re->value,"stop")==0) { - status->state = MPD_STATUS_STATE_STOP; - } - else if(strcmp(re->value,"pause")==0) { - status->state = MPD_STATUS_STATE_PAUSE; - } - else { - status->state = MPD_STATUS_STATE_UNKNOWN; - } - } - else if(strcmp(re->name,"song")==0) { - status->song = atoi(re->value); - } - else if(strcmp(re->name,"songid")==0) { - status->songid = atoi(re->value); - } - else if(strcmp(re->name,"time")==0) { - char * tok = strchr(re->value,':'); - /* the second strchr below is a safety check */ - if (tok && (strchr(tok,0) > (tok+1))) { - /* atoi stops at the first non-[0-9] char: */ - status->elapsedTime = atoi(re->value); - status->totalTime = atoi(tok+1); - } - } - else if(strcmp(re->name,"error")==0) { - status->error = strdup(re->value); - } - else if(strcmp(re->name,"xfade")==0) { - status->crossfade = atoi(re->value); - } - else if(strcmp(re->name,"updating_db")==0) { - status->updatingDb = atoi(re->value); - } - else if(strcmp(re->name,"audio")==0) { - char * tok = strchr(re->value,':'); - if (tok && (strchr(tok,0) > (tok+1))) { - status->sampleRate = atoi(re->value); - status->bits = atoi(++tok); - tok = strchr(tok,':'); - if (tok && (strchr(tok,0) > (tok+1))) - status->channels = atoi(tok+1); - } - } - - mpd_getNextReturnElement(connection); - if(connection->error) { - free(status); - return NULL; - } - } - - if(connection->error) { - free(status); - return NULL; - } - else if(status->state<0) { - strcpy(connection->errorStr,"state not found"); - connection->error = 1; - free(status); - return NULL; - } - - return status; -} - -void mpd_freeStatus(mpd_Status * status) { - if(status->error) free(status->error); - free(status); -} - -void mpd_sendStatsCommand(mpd_Connection * connection) { - mpd_executeCommand(connection,"stats\n"); -} - -mpd_Stats * mpd_getStats(mpd_Connection * connection) { - mpd_Stats * stats; - - /*mpd_executeCommand(connection,"stats\n"); - - if(connection->error) return NULL;*/ - - if(connection->doneProcessing || (connection->listOks && - connection->doneListOk)) - { - return NULL; - } - - if(!connection->returnElement) mpd_getNextReturnElement(connection); - - stats = malloc(sizeof(mpd_Stats)); - stats->numberOfArtists = 0; - stats->numberOfAlbums = 0; - stats->numberOfSongs = 0; - stats->uptime = 0; - stats->dbUpdateTime = 0; - stats->playTime = 0; - stats->dbPlayTime = 0; - - if(connection->error) { - free(stats); - return NULL; - } - while(connection->returnElement) { - mpd_ReturnElement * re = connection->returnElement; - if(strcmp(re->name,"artists")==0) { - stats->numberOfArtists = atoi(re->value); - } - else if(strcmp(re->name,"albums")==0) { - stats->numberOfAlbums = atoi(re->value); - } - else if(strcmp(re->name,"songs")==0) { - stats->numberOfSongs = atoi(re->value); - } - else if(strcmp(re->name,"uptime")==0) { - stats->uptime = strtol(re->value,NULL,10); - } - else if(strcmp(re->name,"db_update")==0) { - stats->dbUpdateTime = strtol(re->value,NULL,10); - } - else if(strcmp(re->name,"playtime")==0) { - stats->playTime = strtol(re->value,NULL,10); - } - else if(strcmp(re->name,"db_playtime")==0) { - stats->dbPlayTime = strtol(re->value,NULL,10); - } - - mpd_getNextReturnElement(connection); - if(connection->error) { - free(stats); - return NULL; - } - } - - if(connection->error) { - free(stats); - return NULL; - } - - return stats; -} - -void mpd_freeStats(mpd_Stats * stats) { - free(stats); -} - -static void mpd_initDirectory(mpd_Directory * directory) { - directory->path = NULL; -} - -static void mpd_finishDirectory(mpd_Directory * directory) { - if (directory->path) - str_pool_put(directory->path); -} - -mpd_Directory * mpd_newDirectory(void) { - mpd_Directory * directory = malloc(sizeof(mpd_Directory));; - - mpd_initDirectory(directory); - - return directory; -} - -void mpd_freeDirectory(mpd_Directory * directory) { - mpd_finishDirectory(directory); - - free(directory); -} - -mpd_Directory * mpd_directoryDup(mpd_Directory * directory) { - mpd_Directory * ret = mpd_newDirectory(); - - if (directory->path) - ret->path = str_pool_dup(directory->path); - - return ret; -} - -static void mpd_initPlaylistFile(mpd_PlaylistFile * playlist) { - playlist->path = NULL; -} - -static void mpd_finishPlaylistFile(mpd_PlaylistFile * playlist) { - if (playlist->path) - str_pool_put(playlist->path); -} - -mpd_PlaylistFile * mpd_newPlaylistFile(void) { - mpd_PlaylistFile * playlist = malloc(sizeof(mpd_PlaylistFile)); - - mpd_initPlaylistFile(playlist); - - return playlist; -} - -void mpd_freePlaylistFile(mpd_PlaylistFile * playlist) { - mpd_finishPlaylistFile(playlist); - free(playlist); -} - -mpd_PlaylistFile * mpd_playlistFileDup(mpd_PlaylistFile * playlist) { - mpd_PlaylistFile * ret = mpd_newPlaylistFile(); - - if (playlist->path) - ret->path = str_pool_dup(playlist->path); - - return ret; -} - -static void mpd_initInfoEntity(mpd_InfoEntity * entity) { - entity->info.directory = NULL; -} - -static void mpd_finishInfoEntity(mpd_InfoEntity * entity) { - if(entity->info.directory) { - if(entity->type == MPD_INFO_ENTITY_TYPE_DIRECTORY) { - mpd_freeDirectory(entity->info.directory); - } - else if(entity->type == MPD_INFO_ENTITY_TYPE_SONG) { - mpd_freeSong(entity->info.song); - } - else if(entity->type == MPD_INFO_ENTITY_TYPE_PLAYLISTFILE) { - mpd_freePlaylistFile(entity->info.playlistFile); - } - } -} - -mpd_InfoEntity * mpd_newInfoEntity(void) { - mpd_InfoEntity * entity = malloc(sizeof(mpd_InfoEntity)); - - mpd_initInfoEntity(entity); - - return entity; -} - -void mpd_freeInfoEntity(mpd_InfoEntity * entity) { - mpd_finishInfoEntity(entity); - free(entity); -} - -static void mpd_sendInfoCommand(mpd_Connection * connection, char * command) { - mpd_executeCommand(connection,command); -} - -mpd_InfoEntity * mpd_getNextInfoEntity(mpd_Connection * connection) { - mpd_InfoEntity * entity = NULL; - - if(connection->doneProcessing || (connection->listOks && - connection->doneListOk)) { - return NULL; - } - - if(!connection->returnElement) mpd_getNextReturnElement(connection); - - if(connection->returnElement) { - if(strcmp(connection->returnElement->name,"file")==0) { - entity = mpd_newInfoEntity(); - entity->type = MPD_INFO_ENTITY_TYPE_SONG; - entity->info.song = mpd_newSong(); - entity->info.song->file = - str_pool_dup(connection->returnElement->value); - } - else if(strcmp(connection->returnElement->name, - "directory")==0) { - entity = mpd_newInfoEntity(); - entity->type = MPD_INFO_ENTITY_TYPE_DIRECTORY; - entity->info.directory = mpd_newDirectory(); - entity->info.directory->path = - str_pool_dup(connection->returnElement->value); - } - else if(strcmp(connection->returnElement->name,"playlist")==0) { - entity = mpd_newInfoEntity(); - entity->type = MPD_INFO_ENTITY_TYPE_PLAYLISTFILE; - entity->info.playlistFile = mpd_newPlaylistFile(); - entity->info.playlistFile->path = - str_pool_dup(connection->returnElement->value); - } - else if(strcmp(connection->returnElement->name, "cpos") == 0){ - entity = mpd_newInfoEntity(); - entity->type = MPD_INFO_ENTITY_TYPE_SONG; - entity->info.song = mpd_newSong(); - entity->info.song->pos = atoi(connection->returnElement->value); - } - else { - connection->error = 1; - strcpy(connection->errorStr,"problem parsing song info"); - return NULL; - } - } - else return NULL; - - mpd_getNextReturnElement(connection); - while(connection->returnElement) { - mpd_ReturnElement * re = connection->returnElement; - - if(strcmp(re->name,"file")==0) return entity; - else if(strcmp(re->name,"directory")==0) return entity; - else if(strcmp(re->name,"playlist")==0) return entity; - else if(strcmp(re->name,"cpos")==0) return entity; - - if(entity->type == MPD_INFO_ENTITY_TYPE_SONG && - strlen(re->value)) { - if(!entity->info.song->artist && - strcmp(re->name,"Artist")==0) { - entity->info.song->artist = str_pool_dup(re->value); - } - else if(!entity->info.song->album && - strcmp(re->name,"Album")==0) { - entity->info.song->album = str_pool_dup(re->value); - } - else if(!entity->info.song->title && - strcmp(re->name,"Title")==0) { - entity->info.song->title = str_pool_dup(re->value); - } - else if(!entity->info.song->track && - strcmp(re->name,"Track")==0) { - entity->info.song->track = str_pool_dup(re->value); - } - else if(!entity->info.song->name && - strcmp(re->name,"Name")==0) { - entity->info.song->name = str_pool_dup(re->value); - } - else if(entity->info.song->time==MPD_SONG_NO_TIME && - strcmp(re->name,"Time")==0) { - entity->info.song->time = atoi(re->value); - } - else if(entity->info.song->pos==MPD_SONG_NO_NUM && - strcmp(re->name,"Pos")==0) { - entity->info.song->pos = atoi(re->value); - } - else if(entity->info.song->id==MPD_SONG_NO_ID && - strcmp(re->name,"Id")==0) { - entity->info.song->id = atoi(re->value); - } - else if(!entity->info.song->date && - strcmp(re->name, "Date") == 0) { - entity->info.song->date = str_pool_dup(re->value); - } - else if(!entity->info.song->genre && - strcmp(re->name, "Genre") == 0) { - entity->info.song->genre = str_pool_dup(re->value); - } - else if(!entity->info.song->composer && - strcmp(re->name, "Composer") == 0) { - entity->info.song->composer = str_pool_dup(re->value); - } - else if(!entity->info.song->disc && - strcmp(re->name, "Disc") == 0) { - entity->info.song->disc = str_pool_dup(re->value); - } - else if(!entity->info.song->comment && - strcmp(re->name, "Comment") == 0) { - entity->info.song->comment = str_pool_dup(re->value); - } - } - else if(entity->type == MPD_INFO_ENTITY_TYPE_DIRECTORY) { - } - else if(entity->type == MPD_INFO_ENTITY_TYPE_PLAYLISTFILE) { - } - - mpd_getNextReturnElement(connection); - } - - return entity; -} - -static char * mpd_getNextReturnElementNamed(mpd_Connection * connection, - const char * name) -{ - if(connection->doneProcessing || (connection->listOks && - connection->doneListOk)) - { - return NULL; - } - - mpd_getNextReturnElement(connection); - while(connection->returnElement) { - mpd_ReturnElement * re = connection->returnElement; - - if(strcmp(re->name,name)==0) return strdup(re->value); - mpd_getNextReturnElement(connection); - } - - return NULL; -} - -char * mpd_getNextTag(mpd_Connection * connection,int table) { - if(table >= 0 && table < MPD_TAG_NUM_OF_ITEM_TYPES) - { - return mpd_getNextReturnElementNamed(connection,mpdTagItemKeys[table]); - } - return NULL; -} - -char * mpd_getNextArtist(mpd_Connection * connection) { - return mpd_getNextReturnElementNamed(connection,"Artist"); -} - -char * mpd_getNextAlbum(mpd_Connection * connection) { - return mpd_getNextReturnElementNamed(connection,"Album"); -} - -void mpd_sendPlaylistInfoCommand(mpd_Connection * connection, int songPos) { - char * string = malloc(strlen("playlistinfo")+25); - sprintf(string,"playlistinfo \"%i\"\n",songPos); - mpd_sendInfoCommand(connection,string); - free(string); -} - -void mpd_sendPlaylistIdCommand(mpd_Connection * connection, int id) { - char * string = malloc(strlen("playlistid")+25); - sprintf(string, "playlistid \"%i\"\n", id); - mpd_sendInfoCommand(connection, string); - free(string); -} - -void mpd_sendPlChangesCommand(mpd_Connection * connection, long long playlist) { - char * string = malloc(strlen("plchanges")+25); - sprintf(string,"plchanges \"%lld\"\n",playlist); - mpd_sendInfoCommand(connection,string); - free(string); -} - -void mpd_sendPlChangesPosIdCommand(mpd_Connection * connection, long long playlist) { - char * string = malloc(strlen("plchangesposid")+25); - sprintf(string,"plchangesposid \"%lld\"\n",playlist); - mpd_sendInfoCommand(connection,string); - free(string); -} - -void mpd_sendListallCommand(mpd_Connection * connection, const char * dir) { - char * sDir = mpd_sanitizeArg(dir); - char * string = malloc(strlen("listall")+strlen(sDir)+5); - sprintf(string,"listall \"%s\"\n",sDir); - mpd_sendInfoCommand(connection,string); - free(string); - free(sDir); -} - -void mpd_sendListallInfoCommand(mpd_Connection * connection, const char * dir) { - char * sDir = mpd_sanitizeArg(dir); - char * string = malloc(strlen("listallinfo")+strlen(sDir)+5); - sprintf(string,"listallinfo \"%s\"\n",sDir); - mpd_sendInfoCommand(connection,string); - free(string); - free(sDir); -} - -void mpd_sendLsInfoCommand(mpd_Connection * connection, const char * dir) { - char * sDir = mpd_sanitizeArg(dir); - char * string = malloc(strlen("lsinfo")+strlen(sDir)+5); - sprintf(string,"lsinfo \"%s\"\n",sDir); - mpd_sendInfoCommand(connection,string); - free(string); - free(sDir); -} - -void mpd_sendCurrentSongCommand(mpd_Connection * connection) { - mpd_executeCommand(connection,"currentsong\n"); -} - -void mpd_sendSearchCommand(mpd_Connection * connection, int table, - const char * str) -{ - char st[10]; - char * string; - char * sanitStr = mpd_sanitizeArg(str); - if(table == MPD_TABLE_ARTIST) strcpy(st,"artist"); - else if(table == MPD_TABLE_ALBUM) strcpy(st,"album"); - else if(table == MPD_TABLE_TITLE) strcpy(st,"title"); - else if(table == MPD_TABLE_FILENAME) strcpy(st,"filename"); - else { - connection->error = 1; - strcpy(connection->errorStr,"unknown table for search"); - return; - } - string = malloc(strlen("search")+strlen(sanitStr)+strlen(st)+6); - sprintf(string,"search %s \"%s\"\n",st,sanitStr); - mpd_sendInfoCommand(connection,string); - free(string); - free(sanitStr); -} - -void mpd_sendFindCommand(mpd_Connection * connection, int table, - const char * str) -{ - char st[10]; - char * string; - char * sanitStr = mpd_sanitizeArg(str); - if(table == MPD_TABLE_ARTIST) strcpy(st,"artist"); - else if(table == MPD_TABLE_ALBUM) strcpy(st,"album"); - else if(table == MPD_TABLE_TITLE) strcpy(st,"title"); - else { - connection->error = 1; - strcpy(connection->errorStr,"unknown table for find"); - return; - } - string = malloc(strlen("find")+strlen(sanitStr)+strlen(st)+6); - sprintf(string,"find %s \"%s\"\n",st,sanitStr); - mpd_sendInfoCommand(connection,string); - free(string); - free(sanitStr); -} - -void mpd_sendListCommand(mpd_Connection * connection, int table, - const char * arg1) -{ - char st[10]; - char * string; - if(table == MPD_TABLE_ARTIST) strcpy(st,"artist"); - else if(table == MPD_TABLE_ALBUM) strcpy(st,"album"); - else { - connection->error = 1; - strcpy(connection->errorStr,"unknown table for list"); - return; - } - if(arg1) { - char * sanitArg1 = mpd_sanitizeArg(arg1); - string = malloc(strlen("list")+strlen(sanitArg1)+strlen(st)+6); - sprintf(string,"list %s \"%s\"\n",st,sanitArg1); - free(sanitArg1); - } - else { - string = malloc(strlen("list")+strlen(st)+3); - sprintf(string,"list %s\n",st); - } - mpd_sendInfoCommand(connection,string); - free(string); -} - -void mpd_sendAddCommand(mpd_Connection * connection, const char * file) { - char * sFile = mpd_sanitizeArg(file); - char * string = malloc(strlen("add")+strlen(sFile)+5); - sprintf(string,"add \"%s\"\n",sFile); - mpd_executeCommand(connection,string); - free(string); - free(sFile); -} - -void mpd_sendDeleteCommand(mpd_Connection * connection, int songPos) { - char * string = malloc(strlen("delete")+25); - sprintf(string,"delete \"%i\"\n",songPos); - mpd_sendInfoCommand(connection,string); - free(string); -} - -void mpd_sendDeleteIdCommand(mpd_Connection * connection, int id) { - char * string = malloc(strlen("deleteid")+25); - sprintf(string, "deleteid \"%i\"\n", id); - mpd_sendInfoCommand(connection,string); - free(string); -} - -void mpd_sendSaveCommand(mpd_Connection * connection, const char * name) { - char * sName = mpd_sanitizeArg(name); - char * string = malloc(strlen("save")+strlen(sName)+5); - sprintf(string,"save \"%s\"\n",sName); - mpd_executeCommand(connection,string); - free(string); - free(sName); -} - -void mpd_sendLoadCommand(mpd_Connection * connection, const char * name) { - char * sName = mpd_sanitizeArg(name); - char * string = malloc(strlen("load")+strlen(sName)+5); - sprintf(string,"load \"%s\"\n",sName); - mpd_executeCommand(connection,string); - free(string); - free(sName); -} - -void mpd_sendRmCommand(mpd_Connection * connection, const char * name) { - char * sName = mpd_sanitizeArg(name); - char * string = malloc(strlen("rm")+strlen(sName)+5); - sprintf(string,"rm \"%s\"\n",sName); - mpd_executeCommand(connection,string); - free(string); - free(sName); -} - -void mpd_sendShuffleCommand(mpd_Connection * connection) { - mpd_executeCommand(connection,"shuffle\n"); -} - -void mpd_sendShuffleRangeCommand(mpd_Connection * connection, unsigned start, unsigned end) { - char * string = malloc(strlen("shufflerange")+25); - sprintf(string,"shuffle \"%u:%u\"\n", start, end); - mpd_executeCommand(connection,string); - free(string); -} - -void mpd_sendClearCommand(mpd_Connection * connection) { - mpd_executeCommand(connection,"clear\n"); -} - -void mpd_sendPlayCommand(mpd_Connection * connection, int songPos) { - char * string = malloc(strlen("play")+25); - sprintf(string,"play \"%i\"\n",songPos); - mpd_sendInfoCommand(connection,string); - free(string); -} - -void mpd_sendPlayIdCommand(mpd_Connection * connection, int id) { - char * string = malloc(strlen("playid")+25); - sprintf(string,"playid \"%i\"\n",id); - mpd_sendInfoCommand(connection,string); - free(string); -} - -void mpd_sendStopCommand(mpd_Connection * connection) { - mpd_executeCommand(connection,"stop\n"); -} - -void mpd_sendPauseCommand(mpd_Connection * connection, int pauseMode) { - char * string = malloc(strlen("pause")+25); - sprintf(string,"pause \"%i\"\n",pauseMode); - mpd_executeCommand(connection,string); - free(string); -} - -void mpd_sendNextCommand(mpd_Connection * connection) { - mpd_executeCommand(connection,"next\n"); -} - -void mpd_sendMoveCommand(mpd_Connection * connection, int from, int to) { - char * string = malloc(strlen("move")+25); - sprintf(string,"move \"%i\" \"%i\"\n",from,to); - mpd_sendInfoCommand(connection,string); - free(string); -} - -void mpd_sendMoveIdCommand(mpd_Connection * connection, int id, int to) { - char * string = malloc(strlen("moveid")+25); - sprintf(string, "moveid \"%i\" \"%i\"\n", id, to); - mpd_sendInfoCommand(connection,string); - free(string); -} - -void mpd_sendSwapCommand(mpd_Connection * connection, int song1, int song2) { - char * string = malloc(strlen("swap")+25); - sprintf(string,"swap \"%i\" \"%i\"\n",song1,song2); - mpd_sendInfoCommand(connection,string); - free(string); -} - -void mpd_sendSwapIdCommand(mpd_Connection * connection, int id1, int id2) { - char * string = malloc(strlen("swapid")+25); - sprintf(string, "swapid \"%i\" \"%i\"\n", id1, id2); - mpd_sendInfoCommand(connection,string); - free(string); -} - -void mpd_sendSeekCommand(mpd_Connection * connection, int song, int to) { - char * string = malloc(strlen("seek")+25); - sprintf(string,"seek \"%i\" \"%i\"\n", song, to); - mpd_sendInfoCommand(connection,string); - free(string); -} - -void mpd_sendSeekIdCommand(mpd_Connection * connection, int id, int to) { - char * string = malloc(strlen("seekid")+25); - sprintf(string,"seekid \"%i\" \"%i\"\n", id, to); - mpd_sendInfoCommand(connection,string); - free(string); -} - -void mpd_sendUpdateCommand(mpd_Connection * connection, const char *path) { - char *sPath = mpd_sanitizeArg(path); - char * string = malloc(strlen("update")+strlen(sPath)+5); - sprintf(string,"update \"%s\"\n",sPath); - mpd_sendInfoCommand(connection,string); - free(string); - free(sPath); -} - -int mpd_getUpdateId(mpd_Connection * connection) { - char * jobid; - int ret = 0; - - jobid = mpd_getNextReturnElementNamed(connection,"updating_db"); - if(jobid) { - ret = atoi(jobid); - free(jobid); - } - - return ret; -} - -void mpd_sendPrevCommand(mpd_Connection * connection) { - mpd_executeCommand(connection,"previous\n"); -} - -void mpd_sendRepeatCommand(mpd_Connection * connection, int repeatMode) { - char * string = malloc(strlen("repeat")+25); - sprintf(string,"repeat \"%i\"\n",repeatMode); - mpd_executeCommand(connection,string); - free(string); -} - -void mpd_sendRandomCommand(mpd_Connection * connection, int randomMode) { - char * string = malloc(strlen("random")+25); - sprintf(string,"random \"%i\"\n",randomMode); - mpd_executeCommand(connection,string); - free(string); -} - -void mpd_sendSingleCommand(mpd_Connection * connection, int singleMode) { - char * string = malloc(strlen("single")+25); - sprintf(string,"single \"%i\"\n",singleMode); - mpd_executeCommand(connection,string); - free(string); -} - -void mpd_sendConsumeCommand(mpd_Connection * connection, int consumeMode) { - char * string = malloc(strlen("consume")+25); - sprintf(string,"consume \"%i\"\n",consumeMode); - mpd_executeCommand(connection,string); - free(string); -} - -void mpd_sendSetvolCommand(mpd_Connection * connection, int volumeChange) { - char * string = malloc(strlen("setvol")+25); - sprintf(string,"setvol \"%i\"\n",volumeChange); - mpd_executeCommand(connection,string); - free(string); -} - -void mpd_sendVolumeCommand(mpd_Connection * connection, int volumeChange) { - char * string = malloc(strlen("volume")+25); - sprintf(string,"volume \"%i\"\n",volumeChange); - mpd_executeCommand(connection,string); - free(string); -} - -void mpd_sendCrossfadeCommand(mpd_Connection * connection, int seconds) { - char * string = malloc(strlen("crossfade")+25); - sprintf(string,"crossfade \"%i\"\n",seconds); - mpd_executeCommand(connection,string); - free(string); -} - -void mpd_sendPasswordCommand(mpd_Connection * connection, const char * pass) { - char * sPass = mpd_sanitizeArg(pass); - char * string = malloc(strlen("password")+strlen(sPass)+5); - sprintf(string,"password \"%s\"\n",sPass); - mpd_executeCommand(connection,string); - free(string); - free(sPass); -} - -void mpd_sendCommandListBegin(mpd_Connection * connection) { - if(connection->commandList) { - strcpy(connection->errorStr,"already in command list mode"); - connection->error = 1; - return; - } - connection->commandList = COMMAND_LIST; - mpd_executeCommand(connection,"command_list_begin\n"); -} - -void mpd_sendCommandListOkBegin(mpd_Connection * connection) { - if(connection->commandList) { - strcpy(connection->errorStr,"already in command list mode"); - connection->error = 1; - return; - } - connection->commandList = COMMAND_LIST_OK; - mpd_executeCommand(connection,"command_list_ok_begin\n"); - connection->listOks = 0; -} - -void mpd_sendCommandListEnd(mpd_Connection * connection) { - if(!connection->commandList) { - strcpy(connection->errorStr,"not in command list mode"); - connection->error = 1; - return; - } - connection->commandList = 0; - mpd_executeCommand(connection,"command_list_end\n"); -} - -void mpd_sendOutputsCommand(mpd_Connection * connection) { - mpd_executeCommand(connection,"outputs\n"); -} - -mpd_OutputEntity * mpd_getNextOutput(mpd_Connection * connection) { - mpd_OutputEntity * output = NULL; - - if(connection->doneProcessing || (connection->listOks && - connection->doneListOk)) - { - return NULL; - } - - if(connection->error) return NULL; - - output = malloc(sizeof(mpd_OutputEntity)); - output->id = -10; - output->name = NULL; - output->enabled = 0; - - if(!connection->returnElement) mpd_getNextReturnElement(connection); - - while(connection->returnElement) { - mpd_ReturnElement * re = connection->returnElement; - if(strcmp(re->name,"outputid")==0) { - if(output!=NULL && output->id>=0) return output; - output->id = atoi(re->value); - } - else if(strcmp(re->name,"outputname")==0) { - output->name = strdup(re->value); - } - else if(strcmp(re->name,"outputenabled")==0) { - output->enabled = atoi(re->value); - } - - mpd_getNextReturnElement(connection); - if(connection->error) { - free(output); - return NULL; - } - - } - - return output; -} - -void mpd_sendEnableOutputCommand(mpd_Connection * connection, int outputId) { - char * string = malloc(strlen("enableoutput")+25); - sprintf(string,"enableoutput \"%i\"\n",outputId); - mpd_executeCommand(connection,string); - free(string); -} - -void mpd_sendDisableOutputCommand(mpd_Connection * connection, int outputId) { - char * string = malloc(strlen("disableoutput")+25); - sprintf(string,"disableoutput \"%i\"\n",outputId); - mpd_executeCommand(connection,string); - free(string); -} - -void mpd_freeOutputElement(mpd_OutputEntity * output) { - free(output->name); - free(output); -} - -/** - * mpd_sendNotCommandsCommand - * odd naming, but it gets the not allowed commands - */ - -void mpd_sendNotCommandsCommand(mpd_Connection * connection) { - mpd_executeCommand(connection,"notcommands\n"); -} - -/** - * mpd_sendCommandsCommand - * odd naming, but it gets the allowed commands - */ - -void mpd_sendCommandsCommand(mpd_Connection * connection) { - mpd_executeCommand(connection,"commands\n"); -} -/** - * Get the next returned command - */ -char * mpd_getNextCommand(mpd_Connection * connection) { - return mpd_getNextReturnElementNamed(connection,"command"); -} - -void mpd_startSearch(mpd_Connection * connection,int exact) { - if(connection->request) { - /* search/find already in progress */ - /* TODO: set error here? */ - return; - } - if(exact){ - connection->request = strdup("find"); - } - else{ - connection->request = strdup("search"); - } -} - - -void mpd_startFieldSearch(mpd_Connection * connection,int field) { - if(connection->request) { - /* search/find already in progress */ - /* TODO: set error here? */ - return; - } - if(field < 0 || field >= MPD_TAG_NUM_OF_ITEM_TYPES) { - /* set error here */ - return; - } - - connection->request = malloc(sizeof(char)*( - /* length of the field name */ - strlen(mpdTagItemKeys[field])+ - /* "list"+space+\0 */ - 6 - )); - sprintf(connection->request, "list %s", mpdTagItemKeys[field]); -} - - - -void mpd_addConstraintSearch(mpd_Connection *connection, - int field, - char *name) -{ - char *arg = NULL; - if(!connection->request){ - return; - } - if(name == NULL) { - return; - } - if(field < 0 || field >= MPD_TAG_NUM_OF_ITEM_TYPES) { - return; - } - /* clean up the query */ - arg = mpd_sanitizeArg(name); - /* create space for the query */ - connection->request = realloc(connection->request, ( - /* length of the old string */ - strlen(connection->request)+ - /* space between */ - 1+ - /* length of the field name */ - strlen(mpdTagItemKeys[field])+ - /* space plus starting " */ - 2+ - /* length of search term */ - strlen(arg)+ - /* closing " +\0 that is added sprintf */ - 2 - )*sizeof(char)); - /* and form the query */ - sprintf(connection->request, "%s %s \"%s\"", - connection->request, - mpdTagItemKeys[field], - arg); - free(arg); -} - - -void mpd_commitSearch(mpd_Connection *connection) -{ - if(connection->request) - { - int length = strlen(connection->request); - /* fixing up the string for mpd to like */ - connection->request = realloc(connection->request, - (length+ /* old length */ - 2 /* closing \n and \0 */ - )*sizeof(char)); - connection->request[length] = '\n'; - connection->request[length+1] = '\0'; - /* and off we go */ - mpd_sendInfoCommand(connection, connection->request); - /* clean up a bit */ - free(connection->request); - connection->request = NULL; - } -} - -/** - * @param connection a MpdConnection - * @param path the path to the playlist. - * - * List the content, with full metadata, of a stored playlist. - * - */ -void mpd_sendListPlaylistInfoCommand(mpd_Connection *connection, char *path) -{ - char *arg = mpd_sanitizeArg(path); - char *query = malloc(strlen("listplaylistinfo")+strlen(arg)+5); - sprintf(query, "listplaylistinfo \"%s\"\n",arg); - mpd_sendInfoCommand(connection, query); - free(arg); - free(query); -} - -/** - * @param connection a MpdConnection - * @param path the path to the playlist. - * - * List the content of a stored playlist. - * - */ -void mpd_sendListPlaylistCommand(mpd_Connection *connection, char *path) -{ - char *arg = mpd_sanitizeArg(path); - char *query = malloc(strlen("listplaylist")+strlen(arg)+5); - sprintf(query, "listplaylist \"%s\"\n",arg); - mpd_sendInfoCommand(connection, query); - free(arg); - free(query); -} diff --git a/src/libmpdclient.h b/src/libmpdclient.h deleted file mode 100644 index de0bb61..0000000 --- a/src/libmpdclient.h +++ /dev/null @@ -1,600 +0,0 @@ -/* libmpdclient - (c)2003-2006 by Warren Dukes (warren.dukes@gmail.com) - This project's homepage is: http://www.musicpd.org - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Music Player Daemon nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef LIBMPDCLIENT_H -#define LIBMPDCLIENT_H - -#include "song.h" - -#ifdef WIN32 -# define __W32API_USE_DLLIMPORT__ 1 -#endif - -#include -#include - -#define MPD_WELCOME_MESSAGE "OK MPD " - -enum mpd_error { - /** no error */ - MPD_ERROR_SUCCESS = 0, - - /** timeout trying to talk to mpd */ - MPD_ERROR_TIMEOUT = 10, - - /** system error */ - MPD_ERROR_SYSTEM, - - /** unknown host */ - MPD_ERROR_UNKHOST, - - /** problems connecting to port on host */ - MPD_ERROR_CONNPORT, - - /** mpd not running on port at host */ - MPD_ERROR_NOTMPD, - - /** no response on attempting to connect */ - MPD_ERROR_NORESPONSE, - - /** error sending command */ - MPD_ERROR_SENDING, - - /** connection closed by mpd */ - MPD_ERROR_CONNCLOSED, - - /** ACK returned! */ - MPD_ERROR_ACK, - - /** Buffer was overrun! */ - MPD_ERROR_BUFFEROVERRUN, -}; - -#define MPD_ERROR_AT_UNK -1 - -enum mpd_ack { - MPD_ACK_ERROR_UNK = -1, - - MPD_ACK_ERROR_NOT_LIST = 1, - MPD_ACK_ERROR_ARG = 2, - MPD_ACK_ERROR_PASSWORD = 3, - MPD_ACK_ERROR_PERMISSION = 4, - MPD_ACK_ERROR_UNKNOWN_CMD = 5, - - MPD_ACK_ERROR_NO_EXIST = 50, - MPD_ACK_ERROR_PLAYLIST_MAX = 51, - MPD_ACK_ERROR_SYSTEM = 52, - MPD_ACK_ERROR_PLAYLIST_LOAD = 53, - MPD_ACK_ERROR_UPDATE_ALREADY = 54, - MPD_ACK_ERROR_PLAYER_SYNC = 55, - MPD_ACK_ERROR_EXIST = 56, -}; - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum mpd_TagItems -{ - MPD_TAG_ITEM_ARTIST, - MPD_TAG_ITEM_ALBUM, - MPD_TAG_ITEM_TITLE, - MPD_TAG_ITEM_TRACK, - MPD_TAG_ITEM_NAME, - MPD_TAG_ITEM_GENRE, - MPD_TAG_ITEM_DATE, - MPD_TAG_ITEM_COMPOSER, - MPD_TAG_ITEM_PERFORMER, - MPD_TAG_ITEM_COMMENT, - MPD_TAG_ITEM_DISC, - MPD_TAG_ITEM_FILENAME, - MPD_TAG_NUM_OF_ITEM_TYPES -}mpd_TagItems; - -extern const char *const mpdTagItemKeys[MPD_TAG_NUM_OF_ITEM_TYPES]; - -/* internal stuff don't touch this struct */ -typedef struct _mpd_ReturnElement { - char * name; - char * value; -} mpd_ReturnElement; - -/* mpd_Connection - * holds info about connection to mpd - * use error, and errorStr to detect errors - */ -typedef struct _mpd_Connection { - /* use this to check the version of mpd */ - int version[3]; - /* IMPORTANT, you want to get the error messages from here */ - char errorStr[512]; - enum mpd_ack errorCode; - int errorAt; - /* this will be set to MPD_ERROR_* if there is an error, 0 if not */ - enum mpd_error error; - /* DON'T TOUCH any of the rest of this stuff */ - int sock; - char buffer[16384]; - size_t buflen; - size_t bufstart; - int doneProcessing; - int listOks; - int doneListOk; - int commandList; - mpd_ReturnElement * returnElement; - struct timeval timeout; - char *request; -} mpd_Connection; - -/* mpd_newConnection - * use this to open a new connection - * you should use mpd_closeConnection, when your done with the connection, - * even if an error has occurred - * _timeout_ is the connection timeout period in seconds - */ -mpd_Connection * -mpd_newConnection(const char *host, int port, float timeout_); - -void -mpd_setConnectionTimeout(mpd_Connection *connection, float timeout_); - -/* mpd_closeConnection - * use this to close a connection and free'ing subsequent memory - */ -void mpd_closeConnection(mpd_Connection * connection); - -/* mpd_clearError - * clears error - */ -void mpd_clearError(mpd_Connection * connection); - -/* STATUS STUFF */ - -/* use these with status.state to determine what state the player is in */ -#define MPD_STATUS_STATE_UNKNOWN 0 -#define MPD_STATUS_STATE_STOP 1 -#define MPD_STATUS_STATE_PLAY 2 -#define MPD_STATUS_STATE_PAUSE 3 - -/* us this with status.volume to determine if mpd has volume support */ -#define MPD_STATUS_NO_VOLUME -1 - -/* mpd_Status - * holds info return from status command - */ -typedef struct mpd_Status { - /* 0-100, or MPD_STATUS_NO_VOLUME when there is no volume support */ - int volume; - /* 1 if repeat is on, 0 otherwise */ - int repeat; - /* 1 if random is on, 0 otherwise */ - int random; - /* 1 if single is on, 0 otherwise */ - int single; - /* 1 if consume is on, 0 otherwise */ - int consume; - /* playlist length */ - int playlistLength; - /* playlist, use this to determine when the playlist has changed */ - long long playlist; - /* use with MPD_STATUS_STATE_* to determine state of player */ - int state; - /* crossfade setting in seconds */ - int crossfade; - /* if a song is currently selected (always the case when state is - * PLAY or PAUSE), this is the position of the currently - * playing song in the playlist, beginning with 0 - */ - int song; - /* Song ID of the currently selected song */ - int songid; - /* time in seconds that have elapsed in the currently playing/paused - * song - */ - int elapsedTime; - /* length in seconds of the currently playing/paused song */ - int totalTime; - /* current bit rate in kbs */ - int bitRate; - /* audio sample rate */ - unsigned int sampleRate; - /* audio bits */ - int bits; - /* audio channels */ - int channels; - /* 1 if mpd is updating, 0 otherwise */ - int updatingDb; - /* error */ - char * error; -} mpd_Status; - -void mpd_sendStatusCommand(mpd_Connection * connection); - -/* mpd_getStatus - * returns status info, be sure to free it with mpd_freeStatus() - * call this after mpd_sendStatusCommand() - */ -mpd_Status * mpd_getStatus(mpd_Connection * connection); - -/* mpd_freeStatus - * free's status info malloc'd and returned by mpd_getStatus - */ -void mpd_freeStatus(mpd_Status * status); - -typedef struct _mpd_Stats { - int numberOfArtists; - int numberOfAlbums; - int numberOfSongs; - unsigned long uptime; - unsigned long dbUpdateTime; - unsigned long playTime; - unsigned long dbPlayTime; -} mpd_Stats; - -void mpd_sendStatsCommand(mpd_Connection * connection); - -mpd_Stats * mpd_getStats(mpd_Connection * connection); - -void mpd_freeStats(mpd_Stats * stats); - -/* DIRECTORY STUFF */ - -/* mpd_Directory - * used to store info fro directory (right now that just the path) - */ -typedef struct _mpd_Directory { - char * path; -} mpd_Directory; - -/* mpd_newDirectory - * allocates memory for a new directory - * use mpd_freeDirectory to free this memory - */ -mpd_Directory * mpd_newDirectory(void); - -/* mpd_freeDirectory - * used to free memory allocated with mpd_newDirectory, and it frees - * path of mpd_Directory, so be careful - */ -void mpd_freeDirectory(mpd_Directory * directory); - -/* mpd_directoryDup - * works like strdup, but for mpd_Directory - */ -mpd_Directory * mpd_directoryDup(mpd_Directory * directory); - -/* PLAYLISTFILE STUFF */ - -/* mpd_PlaylistFile - * stores info about playlist file returned by lsinfo - */ -typedef struct _mpd_PlaylistFile { - char * path; -} mpd_PlaylistFile; - -/* mpd_newPlaylistFile - * allocates memory for new mpd_PlaylistFile, path is set to NULL - * free this memory with mpd_freePlaylistFile - */ -mpd_PlaylistFile * mpd_newPlaylistFile(void); - -/* mpd_freePlaylist - * free memory allocated for freePlaylistFile, will also free - * path, so be careful - */ -void mpd_freePlaylistFile(mpd_PlaylistFile * playlist); - -/* mpd_playlistFileDup - * works like strdup, but for mpd_PlaylistFile - */ -mpd_PlaylistFile * mpd_playlistFileDup(mpd_PlaylistFile * playlist); - -/* INFO ENTITY STUFF */ - -/* the type of entity returned from one of the commands that generates info - * use in conjunction with mpd_InfoEntity.type - */ -#define MPD_INFO_ENTITY_TYPE_DIRECTORY 0 -#define MPD_INFO_ENTITY_TYPE_SONG 1 -#define MPD_INFO_ENTITY_TYPE_PLAYLISTFILE 2 - -/* mpd_InfoEntity - * stores info on stuff returned info commands - */ -typedef struct mpd_InfoEntity { - /* the type of entity, use with MPD_INFO_ENTITY_TYPE_* to determine - * what this entity is (song, directory, etc...) - */ - int type; - /* the actual data you want, mpd_Song, mpd_Directory, etc */ - union { - mpd_Directory * directory; - mpd_Song * song; - mpd_PlaylistFile * playlistFile; - } info; -} mpd_InfoEntity; - -mpd_InfoEntity * mpd_newInfoEntity(void); - -void mpd_freeInfoEntity(mpd_InfoEntity * entity); - -/* INFO COMMANDS AND STUFF */ - -/* use this function to loop over after calling Info/Listall functions */ -mpd_InfoEntity * mpd_getNextInfoEntity(mpd_Connection * connection); - -/* fetches the currently seeletect song (the song referenced by status->song - * and status->songid*/ -void mpd_sendCurrentSongCommand(mpd_Connection * connection); - -/* songNum of -1, means to display the whole list */ -void mpd_sendPlaylistInfoCommand(mpd_Connection * connection, int songNum); - -/* songId of -1, means to display the whole list */ -void mpd_sendPlaylistIdCommand(mpd_Connection * connection, int songId); - -/* use this to get the changes in the playlist since version _playlist_ */ -void mpd_sendPlChangesCommand(mpd_Connection * connection, long long playlist); - -/** - * @param connection: A valid and connected mpd_Connection. - * @param playlist: The playlist version you want the diff with. - * A more bandwidth efficient version of the mpd_sendPlChangesCommand. - * It only returns the pos+id of the changes song. - */ -void mpd_sendPlChangesPosIdCommand(mpd_Connection * connection, long long playlist); - -/* recursivel fetches all songs/dir/playlists in "dir* (no metadata is - * returned) */ -void mpd_sendListallCommand(mpd_Connection * connection, const char * dir); - -/* same as sendListallCommand, but also metadata is returned */ -void mpd_sendListallInfoCommand(mpd_Connection * connection, const char * dir); - -/* non-recursive version of ListallInfo */ -void mpd_sendLsInfoCommand(mpd_Connection * connection, const char * dir); - -#define MPD_TABLE_ARTIST 0 -#define MPD_TABLE_ALBUM 1 -#define MPD_TABLE_TITLE 2 -#define MPD_TABLE_FILENAME 3 - -void mpd_sendSearchCommand(mpd_Connection * connection, int table, - const char * str); - -void mpd_sendFindCommand(mpd_Connection * connection, int table, - const char * str); - -/* LIST TAG COMMANDS */ - -/* use this function fetch next artist entry, be sure to free the returned - * string. NULL means there are no more. Best used with sendListArtists - */ -char * mpd_getNextArtist(mpd_Connection * connection); - -char * mpd_getNextAlbum(mpd_Connection * connection); - -char * mpd_getNextTag(mpd_Connection *connection, int table); - -/* list artist or albums by artist, arg1 should be set to the artist if - * listing albums by a artist, otherwise NULL for listing all artists or albums - */ -void mpd_sendListCommand(mpd_Connection * connection, int table, - const char * arg1); - -/* SIMPLE COMMANDS */ - -void mpd_sendAddCommand(mpd_Connection * connection, const char * file); - -void mpd_sendDeleteCommand(mpd_Connection * connection, int songNum); - -void mpd_sendDeleteIdCommand(mpd_Connection * connection, int songNum); - -void mpd_sendSaveCommand(mpd_Connection * connection, const char * name); - -void mpd_sendLoadCommand(mpd_Connection * connection, const char * name); - -void mpd_sendRmCommand(mpd_Connection * connection, const char * name); - -void mpd_sendShuffleCommand(mpd_Connection * connection); - -void mpd_sendShuffleRangeCommand(mpd_Connection * connection, unsigned start, unsigned end); - -void mpd_sendClearCommand(mpd_Connection * connection); - -/* use this to start playing at the beginning, useful when in random mode */ -#define MPD_PLAY_AT_BEGINNING -1 - -void mpd_sendPlayCommand(mpd_Connection * connection, int songNum); - -void mpd_sendPlayIdCommand(mpd_Connection * connection, int songNum); - -void mpd_sendStopCommand(mpd_Connection * connection); - -void mpd_sendPauseCommand(mpd_Connection * connection, int pauseMode); - -void mpd_sendNextCommand(mpd_Connection * connection); - -void mpd_sendPrevCommand(mpd_Connection * connection); - -void mpd_sendMoveCommand(mpd_Connection * connection, int from, int to); - -void mpd_sendMoveIdCommand(mpd_Connection * connection, int from, int to); - -void mpd_sendSwapCommand(mpd_Connection * connection, int song1, int song2); - -void mpd_sendSwapIdCommand(mpd_Connection * connection, int song1, int song2); - -void mpd_sendSeekCommand(mpd_Connection * connection, int song, int to); - -void mpd_sendSeekIdCommand(mpd_Connection * connection, int song, int to); - -void mpd_sendRepeatCommand(mpd_Connection * connection, int repeatMode); - -void mpd_sendRandomCommand(mpd_Connection * connection, int randomMode); - -void mpd_sendSingleCommand(mpd_Connection * connection, int singleMode); - -void mpd_sendConsumeCommand(mpd_Connection * connection, int consumeMode); - -void mpd_sendSetvolCommand(mpd_Connection * connection, int volumeChange); - -/* WARNING: don't use volume command, its deprecated */ -void mpd_sendVolumeCommand(mpd_Connection * connection, int volumeChange); - -void mpd_sendCrossfadeCommand(mpd_Connection * connection, int seconds); - -void mpd_sendUpdateCommand(mpd_Connection * connection, const char *path); - -/* returns the update job id, call this after a update command*/ -int mpd_getUpdateId(mpd_Connection * connection); - -void mpd_sendPasswordCommand(mpd_Connection * connection, const char * pass); - -/* after executing a command, when your done with it to get its status - * (you want to check connection->error for an error) - */ -void mpd_finishCommand(mpd_Connection * connection); - -/* command list stuff, use this to do things like add files very quickly */ -void mpd_sendCommandListBegin(mpd_Connection * connection); - -void mpd_sendCommandListOkBegin(mpd_Connection * connection); - -void mpd_sendCommandListEnd(mpd_Connection * connection); - -/* advance to the next listOk - * returns 0 if advanced to the next list_OK, - * returns -1 if it advanced to an OK or ACK */ -int mpd_nextListOkCommand(mpd_Connection * connection); - -typedef struct _mpd_OutputEntity { - int id; - char * name; - int enabled; -} mpd_OutputEntity; - -void mpd_sendOutputsCommand(mpd_Connection * connection); - -mpd_OutputEntity * mpd_getNextOutput(mpd_Connection * connection); - -void mpd_sendEnableOutputCommand(mpd_Connection * connection, int outputId); - -void mpd_sendDisableOutputCommand(mpd_Connection * connection, int outputId); - -void mpd_freeOutputElement(mpd_OutputEntity * output); - -/** - * @param connection a #mpd_Connection - * - * Queries mpd for the allowed commands - */ -void mpd_sendCommandsCommand(mpd_Connection * connection); -/** - * @param connection a #mpd_Connection - * - * Queries mpd for the not allowed commands - */ -void mpd_sendNotCommandsCommand(mpd_Connection * connection); - -/** - * @param connection a #mpd_Connection - * - * returns the next supported command. - * - * @returns a string, needs to be free'ed - */ -char *mpd_getNextCommand(mpd_Connection *connection); - -/** - * @param connection a MpdConnection - * @param path the path to the playlist. - * - * List the content, with full metadata, of a stored playlist. - * - */ -void mpd_sendListPlaylistInfoCommand(mpd_Connection *connection, char *path); -/** - * @param connection a MpdConnection - * @param path the path to the playlist. - * - * List the content of a stored playlist. - * - */ -void mpd_sendListPlaylistCommand(mpd_Connection *connection, char *path); - -/** - * @param connection a #mpd_Connection - * @param exact if to match exact - * - * starts a search, use mpd_addConstraintSearch to add - * a constraint to the search, and mpd_commitSearch to do the actual search - */ -void mpd_startSearch(mpd_Connection * connection,int exact); -/** - * @param connection a #mpd_Connection - * @param field - * @param name - * - */ -void mpd_addConstraintSearch(mpd_Connection *connection, int field, char *name); -/** - * @param connection a #mpd_Connection - * - */ -void mpd_commitSearch(mpd_Connection *connection); - -/** - * @param connection a #mpd_Connection - * @param field The field to search - * - * starts a search for fields... f.e. get a list of artists would be: - * mpd_startFieldSearch(connection, MPD_TAG_ITEM_ARTIST); - * mpd_commitSearch(connection); - * - * or get a list of artist in genre "jazz" would be: - * @code - * mpd_startFieldSearch(connection, MPD_TAG_ITEM_ARTIST); - * mpd_addConstraintSearch(connection, MPD_TAG_ITEM_GENRE, "jazz") - * mpd_commitSearch(connection); - * @endcode - * - * mpd_startSearch will return a list of songs (and you need mpd_getNextInfoEntity) - * this one will return a list of only one field (the field specified with field) and you need - * mpd_getNextTag to get the results - */ -void mpd_startFieldSearch(mpd_Connection * connection,int field); -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/main.c b/src/main.c index ed75977..9f68adb 100644 --- a/src/main.c +++ b/src/main.c @@ -41,6 +41,8 @@ #include "lirc.h" #endif +#include + #include #include #include @@ -88,10 +90,7 @@ error_callback(G_GNUC_UNUSED mpdclient_t *c, gint error, const gchar *_msg) error = error & 0xFF; switch (error) { - case MPD_ERROR_CONNPORT: - case MPD_ERROR_NORESPONSE: - break; - case MPD_ERROR_ACK: + case MPD_ERROR_SERVER: screen_status_printf("%s", error_msg(msg)); screen_bell(); break; @@ -111,8 +110,8 @@ update_xterm_title(void) { static char title[BUFSIZE]; char tmp[BUFSIZE]; - mpd_Status *status = NULL; - mpd_Song *song = NULL; + struct mpd_status *status = NULL; + struct mpd_song *song = NULL; if (mpd) { status = mpd->status; @@ -120,7 +119,7 @@ update_xterm_title(void) } if (options.xterm_title_format && status && song && - IS_PLAYING(status->state)) + IS_PLAYING(mpd_status_get_state(status))) strfsong(tmp, BUFSIZE, options.xterm_title_format, song); else g_strlcpy(tmp, PACKAGE " version " VERSION, BUFSIZE); @@ -225,11 +224,11 @@ timer_reconnect(G_GNUC_UNUSED gpointer data) #ifndef NCMPC_MINI /* quit if mpd is pre 0.11.0 - song id not supported by mpd */ - if (MPD_VERSION_LT(mpd, 0, 11, 0)) { + if (mpd_connection_cmp_server_version(mpd->connection, 0, 11, 0) < 0) { + const unsigned *version = + mpd_connection_get_server_version(mpd->connection); screen_status_printf(_("Error: MPD version %d.%d.%d is to old (%s needed)"), - mpd->connection->version[0], - mpd->connection->version[1], - mpd->connection->version[2], + version[0], version[1], version[2], "0.11.0"); mpdclient_disconnect(mpd); doupdate(); @@ -240,7 +239,9 @@ timer_reconnect(G_GNUC_UNUSED gpointer data) } #endif - screen_status_printf(_("Connected to %s"), options.host); + screen_status_printf(_("Connected to %s"), + options.host != NULL + ? options.host : "localhost"); doupdate(); connected = TRUE; diff --git a/src/mpdclient.c b/src/mpdclient.c index 0897e86..86f825f 100644 --- a/src/mpdclient.c +++ b/src/mpdclient.c @@ -24,6 +24,8 @@ #include "strfsong.h" #include "utils.h" +#include + #include #include #include @@ -40,7 +42,8 @@ static bool MPD_ERROR(const struct mpdclient *client) { - return client->connection == NULL; + return client->connection == NULL || + mpd_connection_get_error(client->connection) != MPD_ERROR_SUCCESS; } /* filelist sorting functions */ @@ -48,23 +51,26 @@ static gint compare_filelistentry(gconstpointer filelist_entry1, gconstpointer filelist_entry2) { - const mpd_InfoEntity *e1, *e2; + const struct mpd_entity *e1, *e2; int n = 0; e1 = ((const filelist_entry_t *)filelist_entry1)->entity; e2 = ((const filelist_entry_t *)filelist_entry2)->entity; - if (e1 && e2 && e1->type == e2->type) { - switch (e1->type) { - case MPD_INFO_ENTITY_TYPE_DIRECTORY: - n = g_utf8_collate(e1->info.directory->path, - e2->info.directory->path); + if (e1 != NULL && e2 != NULL && + mpd_entity_get_type(e1) == mpd_entity_get_type(e2)) { + switch (mpd_entity_get_type(e1)) { + case MPD_ENTITY_TYPE_UNKNOWN: + break; + case MPD_ENTITY_TYPE_DIRECTORY: + n = g_utf8_collate(mpd_directory_get_path(mpd_entity_get_directory(e1)), + mpd_directory_get_path(mpd_entity_get_directory(e2))); break; - case MPD_INFO_ENTITY_TYPE_SONG: + case MPD_ENTITY_TYPE_SONG: break; - case MPD_INFO_ENTITY_TYPE_PLAYLISTFILE: - n = g_utf8_collate(e1->info.playlistFile->path, - e2->info.playlistFile->path); + case MPD_ENTITY_TYPE_PLAYLIST: + n = g_utf8_collate(mpd_playlist_get_path(mpd_entity_get_playlist(e1)), + mpd_playlist_get_path(mpd_entity_get_playlist(e2))); } } return n; @@ -75,7 +81,7 @@ gint compare_filelistentry_format(gconstpointer filelist_entry1, gconstpointer filelist_entry2) { - const mpd_InfoEntity *e1, *e2; + const struct mpd_entity *e1, *e2; char key1[BUFSIZE], key2[BUFSIZE]; int n = 0; @@ -83,10 +89,10 @@ compare_filelistentry_format(gconstpointer filelist_entry1, e2 = ((const filelist_entry_t *)filelist_entry2)->entity; if (e1 && e2 && - e1->type == MPD_INFO_ENTITY_TYPE_SONG && - e2->type == MPD_INFO_ENTITY_TYPE_SONG) { - strfsong(key1, BUFSIZE, options.list_format, e1->info.song); - strfsong(key2, BUFSIZE, options.list_format, e2->info.song); + mpd_entity_get_type(e1) == MPD_ENTITY_TYPE_SONG && + mpd_entity_get_type(e2) == MPD_ENTITY_TYPE_SONG) { + strfsong(key1, BUFSIZE, options.list_format, mpd_entity_get_song(e1)); + strfsong(key2, BUFSIZE, options.list_format, mpd_entity_get_song(e2)); n = strcmp(key1,key2); } @@ -110,7 +116,7 @@ error_cb(mpdclient_t *c, gint error, const gchar *msg) list = list->next; } - mpd_clearError(c->connection); + mpd_connection_clear_error(c->connection); return error; } @@ -122,21 +128,20 @@ error_cb(mpdclient_t *c, gint error, const gchar *msg) static gint mpdclient_handle_error(mpdclient_t *c) { - enum mpd_error error = c->connection->error; - bool is_fatal = error != MPD_ERROR_ACK; + enum mpd_error error = mpd_connection_get_error(c->connection); + bool is_fatal = error != MPD_ERROR_SERVER; - if (error == MPD_ERROR_SUCCESS) - return 0; + assert(error != MPD_ERROR_SUCCESS); - if (error == MPD_ERROR_ACK && - c->connection->errorCode == MPD_ACK_ERROR_PERMISSION && + if (error == MPD_ERROR_SERVER && + mpd_connection_get_server_error(c->connection) == MPD_SERVER_ERROR_PERMISSION && screen_auth(c) == 0) return 0; - if (error == MPD_ERROR_ACK) - error = error | (c->connection->errorCode << 8); + if (error == MPD_ERROR_SERVER) + error = error | (mpd_connection_get_server_error(c->connection) << 8); - error_cb(c, error, c->connection->errorStr); + error_cb(c, error, mpd_connection_get_error_message(c->connection)); if (is_fatal) mpdclient_disconnect(c); @@ -147,8 +152,8 @@ mpdclient_handle_error(mpdclient_t *c) gint mpdclient_finish_command(mpdclient_t *c) { - mpd_finishCommand(c->connection); - return mpdclient_handle_error(c); + return mpd_response_finish(c->connection) + ? 0 : mpdclient_handle_error(c); } mpdclient_t * @@ -180,11 +185,11 @@ gint mpdclient_disconnect(mpdclient_t *c) { if (c->connection) - mpd_closeConnection(c->connection); + mpd_connection_free(c->connection); c->connection = NULL; if (c->status) - mpd_freeStatus(c->status); + mpd_status_free(c->status); c->status = NULL; playlist_clear(&c->playlist); @@ -209,12 +214,15 @@ mpdclient_connect(mpdclient_t *c, mpdclient_disconnect(c); /* connect to MPD */ - c->connection = mpd_newConnection(host, port, _timeout); - if (c->connection->error) { - retval = error_cb(c, c->connection->error, - c->connection->errorStr); + c->connection = mpd_connection_new(host, port, _timeout * 1000); + if (c->connection == NULL) + return error_cb(c, MPD_ERROR_OOM, "Out of memory"); + + if (mpd_connection_get_error(c->connection) != MPD_ERROR_SUCCESS) { + retval = error_cb(c, mpd_connection_get_error(c->connection), + mpd_connection_get_error_message(c->connection)); if (retval != 0) { - mpd_closeConnection(c->connection); + mpd_connection_free(c->connection); c->connection = NULL; } @@ -223,7 +231,7 @@ mpdclient_connect(mpdclient_t *c, /* send password */ if( password ) { - mpd_sendPasswordCommand(c->connection, password); + mpd_send_password(c->connection, password); retval = mpdclient_finish_command(c); } c->need_update = TRUE; @@ -243,22 +251,22 @@ mpdclient_update(mpdclient_t *c) /* free the old status */ if (c->status) - mpd_freeStatus(c->status); + mpd_status_free(c->status); /* retrieve new status */ - mpd_sendStatusCommand(c->connection); - c->status = mpd_getStatus(c->connection); - if ((retval=mpdclient_finish_command(c))) - return retval; + c->status = mpd_run_status(c->connection); + if (c->status == NULL) + return mpdclient_handle_error(c); - if (c->updatingdb && c->updatingdb != c->status->updatingDb) + if (c->updatingdb && + c->updatingdb != mpd_status_get_update_id(c->status)) mpdclient_browse_callback(c, BROWSE_DB_UPDATED, NULL); - c->updatingdb = c->status->updatingDb; - c->volume = c->status->volume; + c->updatingdb = mpd_status_get_update_id(c->status); + c->volume = mpd_status_get_volume(c->status); /* check if the playlist needs an update */ - if (c->playlist.id != c->status->playlist) { + if (c->playlist.id != mpd_status_get_queue_version(c->status)) { if (playlist_is_empty(&c->playlist)) retval = mpdclient_playlist_update_changes(c); else @@ -266,8 +274,8 @@ mpdclient_update(mpdclient_t *c) } /* update the current song */ - if (!c->song || c->status->songid != c->song->id) { - c->song = playlist_get_song(c, c->status->song); + if (!c->song || mpd_status_get_song_id(c->status)) { + c->song = playlist_get_song(c, mpd_status_get_song_pos(c->status)); } c->need_update = FALSE; @@ -290,9 +298,9 @@ mpdclient_cmd_play(mpdclient_t *c, gint idx) return -1; if (song) - mpd_sendPlayIdCommand(c->connection, song->id); + mpd_send_play_id(c->connection, mpd_song_get_id(song)); else - mpd_sendPlayIdCommand(c->connection, MPD_PLAY_AT_BEGINNING); + mpd_send_play(c->connection); #else if (MPD_ERROR(c)) return -1; @@ -309,44 +317,41 @@ mpdclient_cmd_pause(mpdclient_t *c, gint value) if (MPD_ERROR(c)) return -1; - mpd_sendPauseCommand(c->connection, value); + mpd_send_pause(c->connection, value); return mpdclient_finish_command(c); } gint mpdclient_cmd_crop(mpdclient_t *c) { - gint error; - mpd_Status *status; + struct mpd_status *status; bool playing; int length, current; if (MPD_ERROR(c)) return -1; - mpd_sendStatusCommand(c->connection); - status = mpd_getStatus(c->connection); - error = mpdclient_finish_command(c); - if (error) - return error; + status = mpd_run_status(c->connection); + if (status == NULL) + return mpdclient_handle_error(c); - playing = status->state == MPD_STATUS_STATE_PLAY || - status->state == MPD_STATUS_STATE_PAUSE; - length = status->playlistLength; - current = status->song; + playing = mpd_status_get_state(status) == MPD_STATE_PLAY || + mpd_status_get_state(status) == MPD_STATE_PAUSE; + length = mpd_status_get_queue_length(status); + current = mpd_status_get_song_pos(status); - mpd_freeStatus(status); + mpd_status_free(status); if (!playing || length < 2) return 0; - mpd_sendCommandListBegin( c->connection ); + mpd_command_list_begin(c->connection, false); while (--length >= 0) if (length != current) - mpd_sendDeleteCommand(c->connection, length); + mpd_send_delete(c->connection, length); - mpd_sendCommandListEnd(c->connection); + mpd_command_list_end(c->connection); return mpdclient_finish_command(c); } @@ -357,7 +362,7 @@ mpdclient_cmd_stop(mpdclient_t *c) if (MPD_ERROR(c)) return -1; - mpd_sendStopCommand(c->connection); + mpd_send_stop(c->connection); return mpdclient_finish_command(c); } @@ -367,7 +372,7 @@ mpdclient_cmd_next(mpdclient_t *c) if (MPD_ERROR(c)) return -1; - mpd_sendNextCommand(c->connection); + mpd_send_next(c->connection); c->need_update = TRUE; return mpdclient_finish_command(c); } @@ -378,7 +383,7 @@ mpdclient_cmd_prev(mpdclient_t *c) if (MPD_ERROR(c)) return -1; - mpd_sendPrevCommand(c->connection); + mpd_send_previous(c->connection); c->need_update = TRUE; return mpdclient_finish_command(c); } @@ -389,7 +394,7 @@ mpdclient_cmd_seek(mpdclient_t *c, gint id, gint pos) if (MPD_ERROR(c)) return -1; - mpd_sendSeekIdCommand(c->connection, id, pos); + mpd_send_seek_id(c->connection, id, pos); return mpdclient_finish_command(c); } @@ -399,7 +404,7 @@ mpdclient_cmd_shuffle(mpdclient_t *c) if (MPD_ERROR(c)) return -1; - mpd_sendShuffleCommand(c->connection); + mpd_send_shuffle(c->connection); c->need_update = TRUE; return mpdclient_finish_command(c); } @@ -407,7 +412,7 @@ mpdclient_cmd_shuffle(mpdclient_t *c) gint mpdclient_cmd_shuffle_range(mpdclient_t *c, guint start, guint end) { - mpd_sendShuffleRangeCommand(c->connection, start, end); + mpd_send_shuffle_range(c->connection, start, end); c->need_update = TRUE; return mpdclient_finish_command(c); } @@ -420,7 +425,7 @@ mpdclient_cmd_clear(mpdclient_t *c) if (MPD_ERROR(c)) return -1; - mpd_sendClearCommand(c->connection); + mpd_send_clear(c->connection); retval = mpdclient_finish_command(c); /* call playlist updated callback */ mpdclient_playlist_callback(c, PLAYLIST_EVENT_CLEAR, NULL); @@ -434,7 +439,7 @@ mpdclient_cmd_repeat(mpdclient_t *c, gint value) if (MPD_ERROR(c)) return -1; - mpd_sendRepeatCommand(c->connection, value); + mpd_send_repeat(c->connection, value); return mpdclient_finish_command(c); } @@ -444,7 +449,7 @@ mpdclient_cmd_random(mpdclient_t *c, gint value) if (MPD_ERROR(c)) return -1; - mpd_sendRandomCommand(c->connection, value); + mpd_send_random(c->connection, value); return mpdclient_finish_command(c); } @@ -454,7 +459,7 @@ mpdclient_cmd_single(mpdclient_t *c, gint value) if (MPD_ERROR(c)) return -1; - mpd_sendSingleCommand(c->connection, value); + mpd_send_single(c->connection, value); return mpdclient_finish_command(c); } @@ -464,7 +469,7 @@ mpdclient_cmd_consume(mpdclient_t *c, gint value) if (MPD_ERROR(c)) return -1; - mpd_sendConsumeCommand(c->connection, value); + mpd_send_consume(c->connection, value); return mpdclient_finish_command(c); } @@ -474,7 +479,7 @@ mpdclient_cmd_crossfade(mpdclient_t *c, gint value) if (MPD_ERROR(c)) return -1; - mpd_sendCrossfadeCommand(c->connection, value); + mpd_send_crossfade(c->connection, value); return mpdclient_finish_command(c); } @@ -486,7 +491,7 @@ mpdclient_cmd_db_update(mpdclient_t *c, const gchar *path) if (MPD_ERROR(c)) return -1; - mpd_sendUpdateCommand(c->connection, path ? path : ""); + mpd_send_update(c->connection, path ? path : ""); ret = mpdclient_finish_command(c); if (ret == 0) @@ -504,7 +509,7 @@ mpdclient_cmd_volume(mpdclient_t *c, gint value) if (MPD_ERROR(c)) return -1; - mpd_sendSetvolCommand(c->connection, value); + mpd_send_set_volume(c->connection, value); return mpdclient_finish_command(c); } @@ -513,11 +518,12 @@ gint mpdclient_cmd_volume_up(struct mpdclient *c) if (MPD_ERROR(c)) return -1; - if (c->status == NULL || c->status->volume == MPD_STATUS_NO_VOLUME) + if (c->status == NULL || + mpd_status_get_volume(c->status) == MPD_STATUS_NO_VOLUME) return 0; if (c->volume == MPD_STATUS_NO_VOLUME) - c->volume = c->status->volume; + c->volume = mpd_status_get_volume(c->status); if (c->volume >= 100) return 0; @@ -530,11 +536,12 @@ gint mpdclient_cmd_volume_down(struct mpdclient *c) if (MPD_ERROR(c)) return -1; - if (c->status == NULL || c->status->volume == MPD_STATUS_NO_VOLUME) + if (c->status == NULL || + mpd_status_get_volume(c->status) == MPD_STATUS_NO_VOLUME) return 0; if (c->volume == MPD_STATUS_NO_VOLUME) - c->volume = c->status->volume; + c->volume = mpd_status_get_volume(c->status); if (c->volume <= 0) return 0; @@ -548,7 +555,7 @@ mpdclient_cmd_add_path(mpdclient_t *c, const gchar *path_utf8) if (MPD_ERROR(c)) return -1; - mpd_sendAddCommand(c->connection, path_utf8); + mpd_send_add(c->connection, path_utf8); return mpdclient_finish_command(c); } @@ -560,11 +567,11 @@ mpdclient_cmd_add(mpdclient_t *c, const struct mpd_song *song) if (MPD_ERROR(c)) return -1; - if( !song || !song->file ) + if (song == NULL) return -1; /* send the add command to mpd */ - mpd_sendAddCommand(c->connection, song->file); + mpd_send_add(c->connection, mpd_song_get_uri(song)); if( (retval=mpdclient_finish_command(c)) ) return retval; @@ -600,9 +607,9 @@ mpdclient_cmd_delete(mpdclient_t *c, gint idx) /* send the delete command to mpd */ #ifdef ENABLE_SONG_ID - mpd_sendDeleteIdCommand(c->connection, song->id); + mpd_send_delete_id(c->connection, mpd_song_get_id(song)); #else - mpd_sendDeleteCommand(c->connection, idx); + mpd_send_delete(c->connection, idx); #endif if( (retval=mpdclient_finish_command(c)) ) return retval; @@ -623,7 +630,7 @@ mpdclient_cmd_delete(mpdclient_t *c, gint idx) c->need_update = TRUE; } - mpd_freeSong(song); + mpd_song_free(song); #else c->need_update = TRUE; @@ -650,9 +657,10 @@ mpdclient_cmd_move(mpdclient_t *c, gint old_index, gint new_index) /* send the move command to mpd */ #ifdef ENABLE_SONG_ID - mpd_sendSwapIdCommand(c->connection, song1->id, song2->id); + mpd_send_swap_id(c->connection, + mpd_song_get_id(song1), mpd_song_get_id(song2)); #else - mpd_sendMoveCommand(c->connection, old_index, new_index); + mpd_send_move(c->connection, old_index, new_index); #endif if( (n=mpdclient_finish_command(c)) ) return n; @@ -682,7 +690,7 @@ mpdclient_cmd_save_playlist(mpdclient_t *c, const gchar *filename_utf8) if (MPD_ERROR(c)) return -1; - mpd_sendSaveCommand(c->connection, filename_utf8); + mpd_send_save(c->connection, filename_utf8); if ((retval = mpdclient_finish_command(c)) == 0) mpdclient_browse_callback(c, BROWSE_PLAYLIST_SAVED, NULL); return retval; @@ -694,7 +702,7 @@ mpdclient_cmd_load_playlist(mpdclient_t *c, const gchar *filename_utf8) if (MPD_ERROR(c)) return -1; - mpd_sendLoadCommand(c->connection, filename_utf8); + mpd_send_load(c->connection, filename_utf8); c->need_update = TRUE; return mpdclient_finish_command(c); } @@ -707,7 +715,7 @@ mpdclient_cmd_delete_playlist(mpdclient_t *c, const gchar *filename_utf8) if (MPD_ERROR(c)) return -1; - mpd_sendRmCommand(c->connection, filename_utf8); + mpd_send_rm(c->connection, filename_utf8); if ((retval = mpdclient_finish_command(c)) == 0) mpdclient_browse_callback(c, BROWSE_PLAYLIST_DELETED, NULL); return retval; @@ -787,22 +795,22 @@ mpdclient_remove_error_callback(mpdclient_t *c, mpdc_error_cb_t cb) gint mpdclient_playlist_update(mpdclient_t *c) { - mpd_InfoEntity *entity; + struct mpd_entity *entity; if (MPD_ERROR(c)) return -1; playlist_clear(&c->playlist); - mpd_sendPlaylistInfoCommand(c->connection,-1); - while ((entity = mpd_getNextInfoEntity(c->connection))) { - if (entity->type == MPD_INFO_ENTITY_TYPE_SONG) - playlist_append(&c->playlist, entity->info.song); + mpd_send_list_queue_meta(c->connection); + while ((entity = mpd_recv_entity(c->connection))) { + if (mpd_entity_get_type(entity) == MPD_ENTITY_TYPE_SONG) + playlist_append(&c->playlist, mpd_entity_get_song(entity)); - mpd_freeInfoEntity(entity); + mpd_entity_free(entity); } - c->playlist.id = c->status->playlist; + c->playlist.id = mpd_status_get_queue_version(c->status); c->song = NULL; /* call playlist updated callbacks */ @@ -817,29 +825,32 @@ mpdclient_playlist_update(mpdclient_t *c) gint mpdclient_playlist_update_changes(mpdclient_t *c) { - mpd_InfoEntity *entity; + struct mpd_song *song; + guint length; if (MPD_ERROR(c)) return -1; - mpd_sendPlChangesCommand(c->connection, c->playlist.id); + mpd_send_queue_changes_meta(c->connection, c->playlist.id); - while ((entity = mpd_getNextInfoEntity(c->connection)) != NULL) { - struct mpd_song *song = entity->info.song; + while ((song = mpd_recv_song(c->connection)) != NULL) { + int pos = mpd_song_get_pos(song); - if (song->pos >= 0 && (guint)song->pos < c->playlist.list->len) { + if (pos >= 0 && (guint)pos < c->playlist.list->len) { /* update song */ - playlist_replace(&c->playlist, song->pos, song); + playlist_replace(&c->playlist, pos, song); } else { /* add a new song */ playlist_append(&c->playlist, song); } - mpd_freeInfoEntity(entity); + mpd_song_free(song); } /* remove trailing songs */ - while ((guint)c->status->playlistLength < c->playlist.list->len) { + + length = mpd_status_get_queue_length(c->status); + while (length < c->playlist.list->len) { guint pos = c->playlist.list->len - 1; /* Remove the last playlist entry */ @@ -847,7 +858,7 @@ mpdclient_playlist_update_changes(mpdclient_t *c) } c->song = NULL; - c->playlist.id = c->status->playlist; + c->playlist.id = mpd_status_get_queue_version(c->status); mpdclient_playlist_callback(c, PLAYLIST_EVENT_UPDATED, NULL); @@ -871,20 +882,19 @@ mpdclient_filelist_t * mpdclient_filelist_get(mpdclient_t *c, const gchar *path) { mpdclient_filelist_t *filelist; - mpd_InfoEntity *entity; + struct mpd_entity *entity; if (MPD_ERROR(c)) return NULL; - mpd_sendLsInfoCommand(c->connection, path); + mpd_send_list_meta(c->connection, path); filelist = filelist_new(); if (path && path[0] && strcmp(path, "/")) /* add a dummy entry for ./.. */ filelist_append(filelist, NULL); - while ((entity=mpd_getNextInfoEntity(c->connection))) { + while ((entity = mpd_recv_entity(c->connection)) != NULL) filelist_append(filelist, entity); - } /* If there's an error, ignore it. We'll return an empty filelist. */ mpdclient_finish_command(c); @@ -894,25 +904,15 @@ mpdclient_filelist_get(mpdclient_t *c, const gchar *path) return filelist; } -mpdclient_filelist_t * -mpdclient_filelist_search(mpdclient_t *c, - int exact_match, - int table, - gchar *filter_utf8) +static struct filelist * +mpdclient_recv_filelist_response(struct mpdclient *c) { - mpdclient_filelist_t *filelist; - mpd_InfoEntity *entity; - - if (MPD_ERROR(c)) - return NULL; + struct filelist *filelist; + struct mpd_entity *entity; - if (exact_match) - mpd_sendFindCommand(c->connection, table, filter_utf8); - else - mpd_sendSearchCommand(c->connection, table, filter_utf8); filelist = filelist_new(); - while ((entity=mpd_getNextInfoEntity(c->connection))) + while ((entity = mpd_recv_entity(c->connection)) != NULL) filelist_append(filelist, entity); if (mpdclient_finish_command(c)) { @@ -923,6 +923,23 @@ mpdclient_filelist_search(mpdclient_t *c, return filelist; } +mpdclient_filelist_t * +mpdclient_filelist_search(mpdclient_t *c, + int exact_match, + enum mpd_tag_type tag, + gchar *filter_utf8) +{ + if (MPD_ERROR(c)) + return NULL; + + mpd_search_db_songs(c->connection, exact_match); + mpd_search_add_tag_constraint(c->connection, MPD_OPERATOR_DEFAULT, + tag, filter_utf8); + mpd_search_commit(c->connection); + + return mpdclient_recv_filelist_response(c); +} + int mpdclient_filelist_add_all(mpdclient_t *c, mpdclient_filelist_t *fl) { @@ -934,35 +951,44 @@ mpdclient_filelist_add_all(mpdclient_t *c, mpdclient_filelist_t *fl) if (filelist_is_empty(fl)) return 0; - mpd_sendCommandListBegin(c->connection); + mpd_command_list_begin(c->connection, false); for (i = 0; i < filelist_length(fl); ++i) { filelist_entry_t *entry = filelist_get(fl, i); - mpd_InfoEntity *entity = entry->entity; + struct mpd_entity *entity = entry->entity; - if (entity && entity->type == MPD_INFO_ENTITY_TYPE_SONG) { - struct mpd_song *song = entity->info.song; + if (entity != NULL && + mpd_entity_get_type(entity) == MPD_ENTITY_TYPE_SONG) { + const struct mpd_song *song = + mpd_entity_get_song(entity); + const char *uri = mpd_song_get_uri(song); - mpd_sendAddCommand(c->connection, song->file); + if (uri != NULL) + mpd_send_add(c->connection, uri); } } - mpd_sendCommandListEnd(c->connection); + mpd_command_list_end(c->connection); return mpdclient_finish_command(c); } GList * mpdclient_get_artists(mpdclient_t *c) { - gchar *str = NULL; GList *list = NULL; + struct mpd_pair *pair; if (MPD_ERROR(c)) return NULL; - mpd_sendListCommand(c->connection, MPD_TABLE_ARTIST, NULL); - while ((str = mpd_getNextArtist(c->connection))) - list = g_list_append(list, (gpointer) str); + mpd_search_db_tags(c->connection, MPD_TAG_ARTIST); + mpd_search_commit(c->connection); + + while ((pair = mpd_recv_pair_tag(c->connection, + MPD_TAG_ARTIST)) != NULL) { + list = g_list_append(list, g_strdup(pair->value)); + mpd_return_pair(c->connection, pair); + } if (mpdclient_finish_command(c)) return string_list_free(list); @@ -973,15 +999,24 @@ mpdclient_get_artists(mpdclient_t *c) GList * mpdclient_get_albums(mpdclient_t *c, const gchar *artist_utf8) { - gchar *str = NULL; GList *list = NULL; + struct mpd_pair *pair; if (MPD_ERROR(c)) return NULL; - mpd_sendListCommand(c->connection, MPD_TABLE_ALBUM, artist_utf8); - while ((str = mpd_getNextAlbum(c->connection))) - list = g_list_append(list, (gpointer) str); + mpd_search_db_tags(c->connection, MPD_TAG_ALBUM); + if (artist_utf8 != NULL) + mpd_search_add_tag_constraint(c->connection, + MPD_OPERATOR_DEFAULT, + MPD_TAG_ARTIST, artist_utf8); + mpd_search_commit(c->connection); + + while ((pair = mpd_recv_pair_tag(c->connection, + MPD_TAG_ALBUM)) != NULL) { + list = g_list_append(list, g_strdup(pair->value)); + mpd_return_pair(c->connection, pair); + } if (mpdclient_finish_command(c)) return string_list_free(list); diff --git a/src/mpdclient.h b/src/mpdclient.h index a25c890..82940ab 100644 --- a/src/mpdclient.h +++ b/src/mpdclient.h @@ -1,18 +1,10 @@ #ifndef MPDCLIENT_H #define MPDCLIENT_H -#include "libmpdclient.h" #include "playlist.h" #include "filelist.h" -#define MPD_VERSION_EQ(c,x,y,z) (c->connection->version[0] == x && \ - c->connection->version[1] == y && \ - c->connection->version[2] == z ) - -#define MPD_VERSION_LT(c,x,y,z) ( c->connection->version[0]connection->version[0]==x && c->connection->version[1]connection->version[0]==x && c->connection->version[1]==y && \ - c->connection->version[2] typedef struct mpdclient { /* playlist */ @@ -23,14 +15,14 @@ typedef struct mpdclient { GList *playlist_callbacks; GList *browse_callbacks; - mpd_Connection *connection; - mpd_Status *status; - mpd_Song *song; + struct mpd_connection *connection; + struct mpd_status *status; + struct mpd_song *song; gboolean need_update; int volume; - int updatingdb; + unsigned updatingdb; } mpdclient_t; /** functions ***************************************************************/ @@ -128,7 +120,7 @@ void mpdclient_playlist_callback(mpdclient_t *c, int event, gpointer data); mpdclient_filelist_t *mpdclient_filelist_get(mpdclient_t *c, const gchar *path); mpdclient_filelist_t *mpdclient_filelist_search(mpdclient_t *c, int exact_match, - int table, + enum mpd_tag_type tag, gchar *filter_utf8); /* add all songs in filelist to the playlist */ diff --git a/src/options.c b/src/options.c index 05c91c9..9715daf 100644 --- a/src/options.c +++ b/src/options.c @@ -49,7 +49,6 @@ typedef void (*option_callback_fn_t)(int c, const char *arg); options_t options = { - .port = DEFAULT_PORT, .crossfade_time = DEFAULT_CROSSFADE_TIME, .seek_time = 1, #ifdef ENABLE_LYRICS_SCREEN @@ -80,8 +79,8 @@ static const arg_opt_t option_table[] = { { 'M', "no-mouse", NULL, "Disable mouse" }, #endif { 'e', "exit", NULL, "Exit on connection errors" }, - { 'p', "port", "PORT", "Connect to server on port [" DEFAULT_PORT_STR "]" }, - { 'h', "host", "HOST", "Connect to server on host [" DEFAULT_HOST "]" }, + { 'p', "port", "PORT", "Connect to server on port" }, + { 'h', "host", "HOST", "Connect to server on host" }, { 'P', "password","PASSWORD", "Connect with password" }, { 'f', "config", "FILE", "Read configuration from file" }, { 'k', "key-file","FILE", "Read configuration from file" }, @@ -369,15 +368,7 @@ options_parse(int argc, const char *argv[]) void options_init(void) { - const char *value; - char *tmp; - - /* get initial values for host and password from MPD_HOST (environment) */ - if ((value = g_getenv(MPD_HOST_ENV))) - options.host = g_strdup(value); - else - options.host = g_strdup(DEFAULT_HOST); - + /* XXX if ((tmp = g_strstr_len(options.host, strlen(options.host), "@"))) { char *oldhost = options.host; *tmp = '\0'; @@ -385,10 +376,7 @@ options_init(void) options.host = g_strdup(tmp+1); g_free(oldhost); } - - /* get initial values for port from MPD_PORT (environment) */ - if ((value = g_getenv(MPD_PORT_ENV))) - options.port = atoi(value); + */ /* default option values */ options.list_format = g_strdup(DEFAULT_LIST_FORMAT); diff --git a/src/options.h b/src/options.h index 1fc0424..b57ecba 100644 --- a/src/options.h +++ b/src/options.h @@ -25,9 +25,6 @@ #include #include -#define MPD_HOST_ENV "MPD_HOST" -#define MPD_PORT_ENV "MPD_PORT" - typedef struct { char *host; char *username; diff --git a/src/playlist.c b/src/playlist.c index 0a44833..564cee6 100644 --- a/src/playlist.c +++ b/src/playlist.c @@ -43,7 +43,7 @@ playlist_clear(struct mpdclient_playlist *playlist) for (i = 0; i < playlist->list->len; ++i) { struct mpd_song *song = playlist_get(playlist, i); - mpd_freeSong(song); + mpd_song_free(song); } g_ptr_array_set_size(playlist->list, 0); @@ -71,13 +71,13 @@ playlist_get_song(mpdclient_t *c, gint idx) } struct mpd_song * -playlist_lookup_song(mpdclient_t *c, gint id) +playlist_lookup_song(mpdclient_t *c, unsigned id) { guint i; for (i = 0; i < c->playlist.list->len; ++i) { struct mpd_song *song = playlist_get(&c->playlist, i); - if (song->id == id) + if (mpd_song_get_id(song) == id) return song; } @@ -98,13 +98,13 @@ playlist_get_index(const struct mpdclient *c, const struct mpd_song *song) } gint -playlist_get_index_from_id(const struct mpdclient *c, gint id) +playlist_get_index_from_id(const struct mpdclient *c, unsigned id) { guint i; for (i = 0; i < c->playlist.list->len; ++i) { const struct mpd_song *song = playlist_get(&c->playlist, i); - if (song->id == id) + if (mpd_song_get_id(song) == id) return (gint)i; } @@ -118,7 +118,9 @@ playlist_get_index_from_file(const struct mpdclient *c, const gchar *filename) for (i = 0; i < c->playlist.list->len; ++i) { struct mpd_song *song = playlist_get(&c->playlist, i); - if(strcmp(song->file, filename) == 0) + const char *uri = mpd_song_get_uri(song); + + if (uri != NULL && strcmp(uri, filename) == 0) return (gint)i; } diff --git a/src/playlist.h b/src/playlist.h index ca0950d..f56daa3 100644 --- a/src/playlist.h +++ b/src/playlist.h @@ -20,7 +20,7 @@ #ifndef MPDCLIENT_PLAYLIST_H #define MPDCLIENT_PLAYLIST_H -#include "libmpdclient.h" +#include #include #include @@ -29,7 +29,7 @@ struct mpdclient; typedef struct mpdclient_playlist { /* playlist id */ - long long id; + unsigned id; /* the list */ GPtrArray *list; @@ -69,25 +69,25 @@ playlist_get(const struct mpdclient_playlist *playlist, guint idx) } static inline void -playlist_append(struct mpdclient_playlist *playlist, const mpd_Song *song) +playlist_append(struct mpdclient_playlist *playlist, const struct mpd_song *song) { - g_ptr_array_add(playlist->list, mpd_songDup(song)); + g_ptr_array_add(playlist->list, mpd_song_dup(song)); } static inline void playlist_set(const struct mpdclient_playlist *playlist, guint idx, - const mpd_Song *song) + const struct mpd_song *song) { assert(idx < playlist_length(playlist)); - g_ptr_array_index(playlist->list, idx) = mpd_songDup(song); + g_ptr_array_index(playlist->list, idx) = mpd_song_dup(song); } static inline void playlist_replace(struct mpdclient_playlist *playlist, guint idx, - const mpd_Song *song) + const struct mpd_song *song) { - mpd_freeSong(playlist_get(playlist, idx)); + mpd_song_free(playlist_get(playlist, idx)); playlist_set(playlist, idx, song); } @@ -100,27 +100,27 @@ playlist_remove_reuse(struct mpdclient_playlist *playlist, guint idx) static inline void playlist_remove(struct mpdclient_playlist *playlist, guint idx) { - mpd_freeSong(playlist_remove_reuse(playlist, idx)); + mpd_song_free(playlist_remove_reuse(playlist, idx)); } static inline void playlist_swap(struct mpdclient_playlist *playlist, guint idx1, guint idx2) { - mpd_Song *song1 = playlist_get(playlist, idx1); - mpd_Song *song2 = playlist_get(playlist, idx2); - gint n; + struct mpd_song *song1 = playlist_get(playlist, idx1); + struct mpd_song *song2 = playlist_get(playlist, idx2); + int n; /* update the songs position field */ - n = song1->pos; - song1->pos = song2->pos; - song2->pos = n; + n = mpd_song_get_pos(song1); + mpd_song_set_pos(song1, mpd_song_get_pos(song2)); + mpd_song_set_pos(song2, n); /* update the array */ g_ptr_array_index(playlist->list, idx1) = song2; g_ptr_array_index(playlist->list, idx2) = song1; } -struct mpd_song *playlist_lookup_song(struct mpdclient *c, gint id); +struct mpd_song *playlist_lookup_song(struct mpdclient *c, unsigned id); struct mpd_song *playlist_get_song(struct mpdclient *c, gint index); @@ -128,7 +128,7 @@ gint playlist_get_index(const struct mpdclient *c, const struct mpd_song *song); gint -playlist_get_index_from_id(const struct mpdclient *c, gint id); +playlist_get_index_from_id(const struct mpdclient *c, unsigned id); gint playlist_get_index_from_file(const struct mpdclient *c, const gchar *filename); @@ -137,7 +137,7 @@ static inline gint playlist_get_index_from_same_song(const struct mpdclient *c, const struct mpd_song *song) { - return playlist_get_index_from_file(c, song->file); + return playlist_get_index_from_file(c, mpd_song_get_uri(song)); } #endif diff --git a/src/screen.c b/src/screen.c index 8e31d14..255cacd 100644 --- a/src/screen.c +++ b/src/screen.c @@ -33,6 +33,8 @@ #include "hscroll.h" #endif +#include + #include #include #include @@ -160,10 +162,10 @@ print_hotkey(WINDOW *w, command_t cmd, const char *label) #endif static inline int -get_volume(const struct mpd_Status *status) +get_volume(const struct mpd_status *status) { return status != NULL - ? status->volume + ? mpd_status_get_volume(status) : MPD_STATUS_NO_VOLUME; } @@ -211,17 +213,17 @@ paint_top_window2(const char *header, mpdclient_t *c) flags[0] = 0; if (c->status != NULL) { - if (c->status->repeat) + if (mpd_status_get_repeat(c->status)) g_strlcat(flags, "r", sizeof(flags)); - if (c->status->random) + if (mpd_status_get_random(c->status)) g_strlcat(flags, "z", sizeof(flags)); - if (c->status->single) + if (mpd_status_get_single(c->status)) g_strlcat(flags, "s", sizeof(flags)); - if (c->status->consume) + if (mpd_status_get_consume(c->status)) g_strlcat(flags, "c", sizeof(flags)); - if (c->status->crossfade) + if (mpd_status_get_crossfade(c->status)) g_strlcat(flags, "x", sizeof(flags)); - if (c->status->updatingDb) + if (mpd_status_get_update_id(c->status) != 0) g_strlcat(flags, "U", sizeof(flags)); } @@ -263,7 +265,8 @@ paint_top_window(const char *header, mpdclient_t *c, int full_repaint) } if (c->status && - volume_length(prev_volume) != volume_length(c->status->volume)) + volume_length(prev_volume) != + volume_length(mpd_status_get_volume(c->status))) full_repaint = 1; if (full_repaint) { @@ -271,7 +274,8 @@ paint_top_window(const char *header, mpdclient_t *c, int full_repaint) wclrtoeol(w); } - if ((c->status != NULL && prev_volume != c->status->volume) || + if ((c->status != NULL && + prev_volume != mpd_status_get_volume(c->status)) || full_repaint) paint_top_window2(header, c); } @@ -283,19 +287,19 @@ paint_progress_window(mpdclient_t *c) int width; int elapsedTime; - if (c->status==NULL || IS_STOPPED(c->status->state)) { + if (c->status==NULL || IS_STOPPED(mpd_status_get_state(c->status))) { mvwhline(screen.progress_window.w, 0, 0, ACS_HLINE, screen.progress_window.cols); wnoutrefresh(screen.progress_window.w); return; } - if (c->song && seek_id == c->song->id) + if (c->song != NULL && seek_id == (int)mpd_song_get_id(c->song)) elapsedTime = seek_target_time; else - elapsedTime = c->status->elapsedTime; + elapsedTime = mpd_status_get_elapsed_time(c->status); - p = ((double) elapsedTime) / ((double) c->status->totalTime); + p = ((double) elapsedTime) / ((double) mpd_status_get_total_time(c->status)); width = (int) (p * (double) screen.progress_window.cols); mvwhline(screen.progress_window.w, @@ -311,9 +315,9 @@ static void paint_status_window(mpdclient_t *c) { WINDOW *w = screen.status_window.w; - mpd_Status *status = c->status; - int state; - mpd_Song *song = c->song; + const struct mpd_status *status = c->status; + enum mpd_state state; + const struct mpd_song *song = c->song; int elapsedTime = 0; #ifdef NCMPC_MINI static char bitrate[1]; @@ -330,16 +334,17 @@ paint_status_window(mpdclient_t *c) wclrtoeol(w); colors_use(w, COLOR_STATUS_BOLD); - state = status == NULL ? MPD_STATUS_STATE_UNKNOWN : status->state; + state = status == NULL ? MPD_STATE_UNKNOWN + : mpd_status_get_state(status); switch (state) { - case MPD_STATUS_STATE_PLAY: + case MPD_STATE_PLAY: str = _("Playing:"); break; - case MPD_STATUS_STATE_PAUSE: + case MPD_STATE_PAUSE: str = _("[Paused]"); break; - case MPD_STATUS_STATE_STOP: + case MPD_STATE_STOP: default: break; } @@ -352,42 +357,49 @@ paint_status_window(mpdclient_t *c) /* create time string */ memset(screen.buf, 0, screen.buf_size); if (IS_PLAYING(state) || IS_PAUSED(state)) { - if (status->totalTime > 0) { + int total_time = mpd_status_get_total_time(status); + if (total_time > 0) { /*checks the conf to see whether to display elapsed or remaining time */ if(!strcmp(options.timedisplay_type,"elapsed")) - elapsedTime = c->status->elapsedTime; + elapsedTime = mpd_status_get_elapsed_time(c->status); else if(!strcmp(options.timedisplay_type,"remaining")) - elapsedTime = (c->status->totalTime - c->status->elapsedTime); + elapsedTime = total_time - + mpd_status_get_elapsed_time(c->status); - if( c->song && seek_id == c->song->id ) + if (c->song != NULL && + seek_id == (int)mpd_song_get_id(c->song)) elapsedTime = seek_target_time; /* display bitrate if visible-bitrate is true */ #ifndef NCMPC_MINI if (options.visible_bitrate) { g_snprintf(bitrate, 16, - " [%d kbps]", status->bitRate); + " [%d kbps]", + mpd_status_get_kbit_rate(status)); } else { bitrate[0] = '\0'; } #endif /*write out the time, using hours if time over 60 minutes*/ - if (c->status->totalTime > 3600) { + if (total_time > 3600) { g_snprintf(screen.buf, screen.buf_size, "%s [%i:%02i:%02i/%i:%02i:%02i]", bitrate, elapsedTime/3600, (elapsedTime%3600)/60, elapsedTime%60, - status->totalTime/3600, (status->totalTime%3600)/60, status->totalTime%60); + total_time / 3600, + (total_time % 3600)/60, + total_time % 60); } else { g_snprintf(screen.buf, screen.buf_size, "%s [%i:%02i/%i:%02i]", bitrate, elapsedTime/60, elapsedTime%60, - status->totalTime/60, status->totalTime%60 ); + total_time / 60, total_time % 60); } #ifndef NCMPC_MINI } else { g_snprintf(screen.buf, screen.buf_size, - " [%d kbps]", status->bitRate ); + " [%d kbps]", + mpd_status_get_kbit_rate(status)); #endif } #ifndef NCMPC_MINI @@ -402,8 +414,7 @@ paint_status_window(mpdclient_t *c) } /* display song */ - if (status != NULL && (IS_PLAYING(status->state) || - IS_PAUSED(status->state))) { + if (IS_PLAYING(state) || IS_PAUSED(state)) { char songname[MAX_SONGNAME_LENGTH]; #ifndef NCMPC_MINI int width = COLS - x - utf8_width(screen.buf); @@ -651,36 +662,38 @@ void screen_update(mpdclient_t *c) { #ifndef NCMPC_MINI - static int repeat = -1; - static int random_enabled = -1; - static int single = -1; - static int consume = -1; - static int crossfade = -1; - static int dbupdate = -1; + static bool initialized = false; + static bool repeat; + static bool random_enabled; + static bool single; + static bool consume; + static unsigned crossfade; + static unsigned dbupdate; /* print a message if mpd status has changed */ if (c->status != NULL) { - if (repeat < 0) { - repeat = c->status->repeat; - random_enabled = c->status->random; - single = c->status->single; - consume = c->status->consume; - crossfade = c->status->crossfade; - dbupdate = c->status->updatingDb; + if (!initialized) { + repeat = mpd_status_get_repeat(c->status); + random_enabled = mpd_status_get_random(c->status); + single = mpd_status_get_single(c->status); + consume = mpd_status_get_consume(c->status); + crossfade = mpd_status_get_crossfade(c->status); + dbupdate = mpd_status_get_update_id(c->status); + initialized = true; } - if (repeat != c->status->repeat) - screen_status_printf(c->status->repeat ? + if (repeat != mpd_status_get_repeat(c->status)) + screen_status_printf(mpd_status_get_repeat(c->status) ? _("Repeat mode is on") : _("Repeat mode is off")); - if (random_enabled != c->status->random) - screen_status_printf(c->status->random ? + if (random_enabled != mpd_status_get_random(c->status)) + screen_status_printf(mpd_status_get_random(c->status) ? _("Random mode is on") : _("Random mode is off")); - if (single != c->status->single) - screen_status_printf(c->status->single ? + if (single != mpd_status_get_single(c->status)) + screen_status_printf(mpd_status_get_single(c->status) ? /* "single" mode means that MPD will automatically stop @@ -689,8 +702,8 @@ screen_update(mpdclient_t *c) _("Single mode is on") : _("Single mode is off")); - if (consume != c->status->consume) - screen_status_printf(c->status->consume ? + if (consume != mpd_status_get_consume(c->status)) + screen_status_printf(mpd_status_get_consume(c->status) ? /* "consume" mode means that MPD removes each song which has @@ -698,19 +711,21 @@ screen_update(mpdclient_t *c) _("Consume mode is on") : _("Consume mode is off")); - if (crossfade != c->status->crossfade) - screen_status_printf(_("Crossfade %d seconds"), c->status->crossfade); + if (crossfade != mpd_status_get_crossfade(c->status)) + screen_status_printf(_("Crossfade %d seconds"), + mpd_status_get_crossfade(c->status)); - if (dbupdate && dbupdate != c->status->updatingDb) { + if (dbupdate != 0 && + dbupdate != mpd_status_get_update_id(c->status)) { screen_status_printf(_("Database updated")); } - repeat = c->status->repeat; - single = c->status->single; - consume = c->status->consume; - random_enabled = c->status->random; - crossfade = c->status->crossfade; - dbupdate = c->status->updatingDb; + repeat = mpd_status_get_repeat(c->status); + random_enabled = mpd_status_get_random(c->status); + single = mpd_status_get_single(c->status); + consume = mpd_status_get_consume(c->status); + crossfade = mpd_status_get_crossfade(c->status); + dbupdate = mpd_status_get_update_id(c->status); } /* update title/header window */ @@ -752,7 +767,7 @@ screen_update(mpdclient_t *c) void screen_idle(mpdclient_t *c) { - if (c->song && seek_id == c->song->id && + if (c->song != NULL && seek_id == (int)mpd_song_get_id(c->song) && (screen.last_cmd == CMD_SEEK_FORWARD || screen.last_cmd == CMD_SEEK_BACKWARD)) mpdclient_cmd_seek(c, seek_id, seek_target_time); @@ -796,7 +811,7 @@ screen_client_cmd(mpdclient_t *c, command_t cmd) break; */ case CMD_PAUSE: - mpdclient_cmd_pause(c, !IS_PAUSED(c->status->state)); + mpdclient_cmd_pause(c, !IS_PAUSED(mpd_status_get_state(c->status))); break; case CMD_STOP: mpdclient_cmd_stop(c); @@ -805,28 +820,29 @@ screen_client_cmd(mpdclient_t *c, command_t cmd) mpdclient_cmd_crop(c); break; case CMD_SEEK_FORWARD: - if (!IS_STOPPED(c->status->state)) { - if (c->song && seek_id != c->song->id) { - seek_id = c->song->id; - seek_target_time = c->status->elapsedTime; + if (!IS_STOPPED(mpd_status_get_state(c->status))) { + if (c->song != NULL && + seek_id != (int)mpd_song_get_id(c->song)) { + seek_id = mpd_song_get_id(c->song); + seek_target_time = mpd_status_get_elapsed_time(c->status); } seek_target_time+=options.seek_time; - if (seek_target_time < c->status->totalTime) + if (seek_target_time < (int)mpd_status_get_total_time(c->status)) break; - seek_target_time = c->status->totalTime; + seek_target_time = mpd_status_get_total_time(c->status); /* seek_target_time=0; */ } break; /* fall through... */ case CMD_TRACK_NEXT: - if (!IS_STOPPED(c->status->state)) + if (!IS_STOPPED(mpd_status_get_state(c->status))) mpdclient_cmd_next(c); break; case CMD_SEEK_BACKWARD: - if (!IS_STOPPED(c->status->state)) { - if (seek_id != c->song->id) { - seek_id = c->song->id; - seek_target_time = c->status->elapsedTime; + if (!IS_STOPPED(mpd_status_get_state(c->status))) { + if (seek_id != (int)mpd_song_get_id(c->song)) { + seek_id = mpd_song_get_id(c->song); + seek_target_time = mpd_status_get_elapsed_time(c->status); } seek_target_time-=options.seek_time; if (seek_target_time < 0) @@ -834,7 +850,7 @@ screen_client_cmd(mpdclient_t *c, command_t cmd) } break; case CMD_TRACK_PREVIOUS: - if (!IS_STOPPED(c->status->state)) + if (!IS_STOPPED(mpd_status_get_state(c->status))) mpdclient_cmd_prev(c); break; case CMD_SHUFFLE: @@ -846,25 +862,25 @@ screen_client_cmd(mpdclient_t *c, command_t cmd) screen_status_message(_("Cleared playlist")); break; case CMD_REPEAT: - mpdclient_cmd_repeat(c, !c->status->repeat); + mpdclient_cmd_repeat(c, !mpd_status_get_repeat(c->status)); break; case CMD_RANDOM: - mpdclient_cmd_random(c, !c->status->random); + mpdclient_cmd_random(c, !mpd_status_get_random(c->status)); break; case CMD_SINGLE: - mpdclient_cmd_single(c, !c->status->single); + mpdclient_cmd_single(c, !mpd_status_get_single(c->status)); break; case CMD_CONSUME: - mpdclient_cmd_consume(c, !c->status->consume); + mpdclient_cmd_consume(c, !mpd_status_get_consume(c->status)); break; case CMD_CROSSFADE: - if (c->status->crossfade) + if (mpd_status_get_crossfade(c->status)) mpdclient_cmd_crossfade(c, 0); else mpdclient_cmd_crossfade(c, options.crossfade_time); break; case CMD_DB_UPDATE: - if (!c->status->updatingDb) { + if (!mpd_status_get_update_id(c->status)) { if( mpdclient_cmd_db_update(c,NULL)==0 ) screen_status_printf(_("Database update started")); } else diff --git a/src/screen.h b/src/screen.h index 343f944..fb2bc30 100644 --- a/src/screen.h +++ b/src/screen.h @@ -24,6 +24,8 @@ #include "mpdclient.h" #include "command.h" +#include + #include #ifdef HAVE_NCURSESW_NCURSES_H @@ -32,8 +34,8 @@ #include #endif -#define IS_PLAYING(s) (s==MPD_STATUS_STATE_PLAY) -#define IS_PAUSED(s) (s==MPD_STATUS_STATE_PAUSE) +#define IS_PLAYING(s) (s==MPD_STATE_PLAY) +#define IS_PAUSED(s) (s==MPD_STATE_PAUSE) #define IS_STOPPED(s) (!(IS_PLAYING(s) | IS_PAUSED(s))) #define MAX_SONGNAME_LENGTH 512 diff --git a/src/screen_artist.c b/src/screen_artist.c index 1dc300a..f6de9dd 100644 --- a/src/screen_artist.c +++ b/src/screen_artist.c @@ -143,7 +143,7 @@ string_array_free(GPtrArray *array) for (i = 0; i < array->len; ++i) { char *value = g_ptr_array_index(array, i); - free(value); + g_free(value); } g_ptr_array_free(array, TRUE); @@ -220,12 +220,12 @@ load_song_list(struct mpdclient *c) if (album[0] == 0) browser.filelist = mpdclient_filelist_search(c, TRUE, - MPD_TABLE_ARTIST, + MPD_TAG_ARTIST, artist); else browser.filelist = mpdclient_filelist_search(c, TRUE, - MPD_TABLE_ALBUM, + MPD_TAG_ALBUM, album); if (browser.filelist == NULL) browser.filelist = filelist_new(); @@ -407,7 +407,7 @@ get_title(char *str, size_t size) } static void -add_query(mpdclient_t *c, int table, char *_filter) +add_query(mpdclient_t *c, enum mpd_tag_type table, char *_filter) { char *str; mpdclient_filelist_t *addlist; @@ -415,7 +415,7 @@ add_query(mpdclient_t *c, int table, char *_filter) assert(filter != NULL); str = utf8_to_locale(_filter); - if (table== MPD_TABLE_ALBUM) + if (table == MPD_TAG_ALBUM) screen_status_printf("Adding album %s...", str); else screen_status_printf("Adding %s...", str); @@ -617,7 +617,7 @@ artist_cmd(mpdclient_t *c, command_t cmd) for(i = browser.lw->selected_start; i <= browser.lw->selected_end; ++i) { selected = g_ptr_array_index(artist_list, i); - add_query(c, MPD_TABLE_ARTIST, selected); + add_query(c, MPD_TAG_ARTIST, selected); cmd = CMD_LIST_NEXT; /* continue and select next item... */ } break; @@ -628,12 +628,12 @@ artist_cmd(mpdclient_t *c, command_t cmd) for(i = browser.lw->selected_start; i <= browser.lw->selected_end; ++i) { if(i == album_list->len + 1) - add_query(c, MPD_TABLE_ARTIST, artist); + add_query(c, MPD_TAG_ARTIST, artist); else if (i > 0) { selected = g_ptr_array_index(album_list, browser.lw->selected - 1); - add_query(c, MPD_TABLE_ALBUM, selected); + add_query(c, MPD_TAG_ALBUM, selected); cmd = CMD_LIST_NEXT; /* continue and select next item... */ } } diff --git a/src/screen_browser.c b/src/screen_browser.c index 501c875..c8f705b 100644 --- a/src/screen_browser.c +++ b/src/screen_browser.c @@ -24,6 +24,8 @@ #include "strfsong.h" #include "screen_utils.h" +#include + #include #define BUFSIZE 1024 @@ -51,7 +53,7 @@ clear_highlights(mpdclient_filelist_t *fl) /* change the highlight flag for a song */ static void -set_highlight(mpdclient_filelist_t *fl, mpd_Song *song, int highlight) +set_highlight(mpdclient_filelist_t *fl, struct mpd_song *song, int highlight) { int i = filelist_find_song(fl, song); struct filelist_entry *entry; @@ -74,10 +76,11 @@ sync_highlights(mpdclient_t *c, mpdclient_filelist_t *fl) for (i = 0; i < filelist_length(fl); ++i) { struct filelist_entry *entry = filelist_get(fl, i); - mpd_InfoEntity *entity = entry->entity; + struct mpd_entity *entity = entry->entity; - if ( entity && entity->type==MPD_INFO_ENTITY_TYPE_SONG ) { - mpd_Song *song = entity->info.song; + if (entity != NULL && mpd_entity_get_type(entity) == MPD_ENTITY_TYPE_SONG) { + const struct mpd_song *song = + mpd_entity_get_song(entity); if (playlist_get_index_from_same_song(c, song) >= 0) entry->flags |= HIGHLIGHT; @@ -100,10 +103,10 @@ browser_playlist_changed(struct screen_browser *browser, mpdclient_t *c, clear_highlights(browser->filelist); break; case PLAYLIST_EVENT_ADD: - set_highlight(browser->filelist, (mpd_Song *) data, 1); + set_highlight(browser->filelist, (struct mpd_song *) data, 1); break; case PLAYLIST_EVENT_DELETE: - set_highlight(browser->filelist, (mpd_Song *) data, 0); + set_highlight(browser->filelist, (struct mpd_song *) data, 0); break; case PLAYLIST_EVENT_MOVE: break; @@ -122,7 +125,7 @@ browser_lw_callback(unsigned idx, bool *highlight, G_GNUC_UNUSED char **second_c static char buf[BUFSIZE]; mpdclient_filelist_t *fl = (mpdclient_filelist_t *) data; filelist_entry_t *entry; - mpd_InfoEntity *entity; + struct mpd_entity *entity; if (fl == NULL || idx >= filelist_length(fl)) return NULL; @@ -140,21 +143,23 @@ browser_lw_callback(unsigned idx, bool *highlight, G_GNUC_UNUSED char **second_c if( entity == NULL ) return "[..]"; - if( entity->type==MPD_INFO_ENTITY_TYPE_DIRECTORY ) { - mpd_Directory *dir = entity->info.directory; - char *directory = utf8_to_locale(g_basename(dir->path)); + if (mpd_entity_get_type(entity) == MPD_ENTITY_TYPE_DIRECTORY) { + const struct mpd_directory *dir = + mpd_entity_get_directory(entity); + char *directory = utf8_to_locale(g_basename(mpd_directory_get_path(dir))); g_snprintf(buf, BUFSIZE, "[%s]", directory); g_free(directory); return buf; - } else if( entity->type==MPD_INFO_ENTITY_TYPE_SONG ) { - const mpd_Song *song = entity->info.song; + } else if (mpd_entity_get_type(entity) == MPD_ENTITY_TYPE_SONG) { + const struct mpd_song *song = mpd_entity_get_song(entity); strfsong(buf, BUFSIZE, options.list_format, song); return buf; - } else if( entity->type==MPD_INFO_ENTITY_TYPE_PLAYLISTFILE ) { - mpd_PlaylistFile *plf = entity->info.playlistFile; - char *filename = utf8_to_locale(g_basename(plf->path)); + } else if (mpd_entity_get_type(entity) == MPD_ENTITY_TYPE_PLAYLIST) { + const struct mpd_playlist *playlist = + mpd_entity_get_playlist(entity); + char *filename = utf8_to_locale(g_basename(mpd_playlist_get_path(playlist))); g_snprintf(buf, BUFSIZE, playlist_format, filename); g_free(filename); @@ -165,11 +170,11 @@ browser_lw_callback(unsigned idx, bool *highlight, G_GNUC_UNUSED char **second_c } static bool -load_playlist(mpdclient_t *c, const mpd_PlaylistFile *plf) +load_playlist(mpdclient_t *c, const struct mpd_playlist *playlist) { - char *filename = utf8_to_locale(plf->path); + char *filename = utf8_to_locale(mpd_playlist_get_path(playlist)); - if (mpdclient_cmd_load_playlist(c, plf->path) == 0) + if (mpdclient_cmd_load_playlist(c, mpd_playlist_get_path(playlist)) == 0) screen_status_printf(_("Loading playlist %s..."), g_basename(filename)); g_free(filename); @@ -180,8 +185,7 @@ static bool enqueue_and_play(mpdclient_t *c, filelist_entry_t *entry) { int idx; - mpd_InfoEntity *entity = entry->entity; - mpd_Song *song = entity->info.song; + const struct mpd_song *song = mpd_entity_get_song(entry->entity); #ifndef NCMPC_MINI if (!(entry->flags & HIGHLIGHT)) { @@ -217,7 +221,7 @@ browser_get_selected_entry(const struct screen_browser *browser) return filelist_get(browser->filelist, browser->lw->selected); } -static const struct mpd_InfoEntity * +static const struct mpd_entity * browser_get_selected_entity(const struct screen_browser *browser) { const struct filelist_entry *entry = browser_get_selected_entry(browser); @@ -230,10 +234,11 @@ browser_get_selected_entity(const struct screen_browser *browser) static const struct mpd_song * browser_get_selected_song(const struct screen_browser *browser) { - const struct mpd_InfoEntity *entity = browser_get_selected_entity(browser); + const struct mpd_entity *entity = browser_get_selected_entity(browser); - return entity != NULL && entity->type == MPD_INFO_ENTITY_TYPE_SONG - ? entity->info.song + return entity != NULL && + mpd_entity_get_type(entity) == MPD_ENTITY_TYPE_SONG + ? mpd_entity_get_song(entity) : NULL; } @@ -251,7 +256,7 @@ static bool browser_handle_enter(struct screen_browser *browser, mpdclient_t *c) { struct filelist_entry *entry = browser_get_selected_entry(browser); - mpd_InfoEntity *entity; + struct mpd_entity *entity; if (entry == NULL) return false; @@ -260,9 +265,9 @@ browser_handle_enter(struct screen_browser *browser, mpdclient_t *c) if (entity == NULL) return false; - if (entity->type == MPD_INFO_ENTITY_TYPE_PLAYLISTFILE) - return load_playlist(c, entity->info.playlistFile); - else if (entity->type == MPD_INFO_ENTITY_TYPE_SONG) + if (mpd_entity_get_type(entity) == MPD_ENTITY_TYPE_PLAYLIST) + return load_playlist(c, mpd_entity_get_playlist(entity)); + else if (mpd_entity_get_type(entity) == MPD_ENTITY_TYPE_SONG) return enqueue_and_play(c, entry); return false; } @@ -274,14 +279,15 @@ browser_select_entry(mpdclient_t *c, filelist_entry_t *entry, assert(entry != NULL); assert(entry->entity != NULL); - if (entry->entity->type == MPD_INFO_ENTITY_TYPE_PLAYLISTFILE) - return load_playlist(c, entry->entity->info.playlistFile); + if (mpd_entity_get_type(entry->entity) == MPD_ENTITY_TYPE_PLAYLIST) + return load_playlist(c, mpd_entity_get_playlist(entry->entity)); - if (entry->entity->type == MPD_INFO_ENTITY_TYPE_DIRECTORY) { - mpd_Directory *dir = entry->entity->info.directory; + if (mpd_entity_get_type(entry->entity) == MPD_ENTITY_TYPE_DIRECTORY) { + const struct mpd_directory *dir = + mpd_entity_get_directory(entry->entity); - if (mpdclient_cmd_add_path(c, dir->path) == 0) { - char *tmp = utf8_to_locale(dir->path); + if (mpdclient_cmd_add_path(c, mpd_directory_get_path(dir)) == 0) { + char *tmp = utf8_to_locale(mpd_directory_get_path(dir)); screen_status_printf(_("Adding \'%s\' to playlist"), tmp); g_free(tmp); @@ -290,16 +296,15 @@ browser_select_entry(mpdclient_t *c, filelist_entry_t *entry, return true; } - if (entry->entity->type != MPD_INFO_ENTITY_TYPE_SONG) + if (mpd_entity_get_type(entry->entity) != MPD_ENTITY_TYPE_SONG) return false; - assert(entry->entity->info.song != NULL); - #ifndef NCMPC_MINI if (!toggle || (entry->flags & HIGHLIGHT) == 0) #endif { - mpd_Song *song = entry->entity->info.song; + const struct mpd_song *song = + mpd_entity_get_song(entry->entity); #ifndef NCMPC_MINI entry->flags |= HIGHLIGHT; @@ -314,7 +319,8 @@ browser_select_entry(mpdclient_t *c, filelist_entry_t *entry, #ifndef NCMPC_MINI } else { /* remove song from playlist */ - mpd_Song *song = entry->entity->info.song; + const struct mpd_song *song = + mpd_entity_get_song(entry->entity); int idx; entry->flags &= ~HIGHLIGHT; diff --git a/src/screen_file.c b/src/screen_file.c index 18abcec..c69b7d5 100644 --- a/src/screen_file.c +++ b/src/screen_file.c @@ -27,6 +27,8 @@ #include "screen_browser.h" #include "screen_play.h" +#include + #include #include #include @@ -153,8 +155,8 @@ file_change_to_entry(mpdclient_t *c, const filelist_entry_t *entry) if (entry->entity == NULL) return file_change_to_parent(c); - else if (entry->entity->type == MPD_INFO_ENTITY_TYPE_DIRECTORY) - return file_change_directory(c, entry->entity->info.directory->path); + else if (mpd_entity_get_type(entry->entity) == MPD_ENTITY_TYPE_DIRECTORY) + return file_change_directory(c, mpd_directory_get_path(mpd_entity_get_directory(entry->entity))); else return false; } @@ -174,7 +176,8 @@ static int handle_save(mpdclient_t *c) { filelist_entry_t *entry; - char *defaultname = NULL; + const char *defaultname = NULL; + char *defaultname_utf8 = NULL; int ret; unsigned selected; @@ -185,18 +188,19 @@ handle_save(mpdclient_t *c) { entry = filelist_get(browser.filelist, selected); if( entry && entry->entity ) { - mpd_InfoEntity *entity = entry->entity; - if( entity->type==MPD_INFO_ENTITY_TYPE_PLAYLISTFILE ) { - mpd_PlaylistFile *plf = entity->info.playlistFile; - defaultname = plf->path; + struct mpd_entity *entity = entry->entity; + if (mpd_entity_get_type(entity) == MPD_ENTITY_TYPE_PLAYLIST) { + const struct mpd_playlist *playlist = + mpd_entity_get_playlist(entity); + defaultname = mpd_playlist_get_path(playlist); } } } if(defaultname) - defaultname = utf8_to_locale(defaultname); - ret = playlist_save(c, NULL, defaultname); - g_free(defaultname); + defaultname_utf8 = utf8_to_locale(defaultname); + ret = playlist_save(c, NULL, defaultname_utf8); + g_free(defaultname_utf8); return ret; } @@ -205,8 +209,8 @@ static int handle_delete(mpdclient_t *c) { filelist_entry_t *entry; - mpd_InfoEntity *entity; - mpd_PlaylistFile *plf; + struct mpd_entity *entity; + const struct mpd_playlist *playlist; char *str, *buf; int key; unsigned selected; @@ -222,7 +226,7 @@ handle_delete(mpdclient_t *c) entity = entry->entity; - if( entity->type!=MPD_INFO_ENTITY_TYPE_PLAYLISTFILE ) { + if (mpd_entity_get_type(entity) != MPD_ENTITY_TYPE_PLAYLIST) { /* translators: the "delete" command is only possible for playlists; the user attempted to delete a song or a directory or something else */ @@ -231,8 +235,8 @@ handle_delete(mpdclient_t *c) continue; } - plf = entity->info.playlistFile; - str = utf8_to_locale(g_basename(plf->path)); + playlist = mpd_entity_get_playlist(entity); + str = utf8_to_locale(g_basename(mpd_playlist_get_path(playlist))); buf = g_strdup_printf(_("Delete playlist %s [%s/%s] ? "), str, YES, NO); g_free(str); key = tolower(screen_getch(screen.status_window.w, buf)); @@ -243,7 +247,7 @@ handle_delete(mpdclient_t *c) return 0; } - if( mpdclient_cmd_delete_playlist(c, plf->path) ) + if (mpdclient_cmd_delete_playlist(c, mpd_playlist_get_path(playlist))) continue; /* translators: MPD deleted the playlist, as requested by the @@ -368,9 +372,9 @@ browse_cmd(mpdclient_t *c, command_t cmd) if (c->status == NULL) return true; - if (!c->status->updatingDb) { + if (mpd_status_get_update_id(c->status) == 0) { if (mpdclient_cmd_db_update(c, current_path) == 0) { - if (strcmp(current_path, "") != 0) { + if (strcmp(current_path, "")) { char *path_locale = utf8_to_locale(current_path); screen_status_printf(_("Database update of %s started"), @@ -409,23 +413,24 @@ const struct screen_functions screen_browse = { bool screen_file_goto_song(struct mpdclient *c, const struct mpd_song *song) { - const char *slash, *parent; + const char *uri, *slash, *parent; char *allocated = NULL; bool ret; int i; assert(song != NULL); - assert(song->file != NULL); - if (strstr(song->file, "//") != NULL) + uri = mpd_song_get_uri(song); + + if (strstr(uri, "//") != NULL) /* an URL? */ return false; /* determine the song's parent directory and go there */ - slash = strrchr(song->file, '/'); + slash = strrchr(uri, '/'); if (slash != NULL) - parent = allocated = g_strndup(song->file, slash - song->file); + parent = allocated = g_strndup(uri, slash - uri); else parent = ""; diff --git a/src/screen_lyrics.c b/src/screen_lyrics.c index 8f7c23d..5714258 100644 --- a/src/screen_lyrics.c +++ b/src/screen_lyrics.c @@ -65,7 +65,7 @@ screen_lyrics_abort(void) } if (current.song != NULL) { - mpd_freeSong(current.song); + mpd_song_free(current.song); current.song = NULL; } } @@ -167,7 +167,7 @@ screen_lyrics_load(const struct mpd_song *song) screen_lyrics_abort(); screen_text_clear(&text); - current.song = mpd_songDup(song); + current.song = mpd_song_dup(song); strfsong(buffer, sizeof(buffer), "%artist%", song); current.artist = g_strdup(buffer); @@ -207,11 +207,12 @@ lyrics_open(mpdclient_t *c) if (next_song != NULL && (current.song == NULL || - strcmp(next_song->file, current.song->file) != 0)) + strcmp(mpd_song_get_uri(next_song), + mpd_song_get_uri(current.song)) != 0)) screen_lyrics_load(next_song); if (next_song != c->song) - mpd_freeSong(next_song); + mpd_song_free(next_song); next_song = NULL; } @@ -225,7 +226,8 @@ lyrics_update(mpdclient_t *c) if (next_song != NULL && (current.song == NULL || - strcmp(next_song->file, current.song->file) != 0)) + strcmp(mpd_song_get_uri(next_song), + mpd_song_get_uri(current.song)) != 0)) screen_lyrics_load(next_song); next_song = NULL; @@ -329,6 +331,6 @@ screen_lyrics_switch(struct mpdclient *c, const struct mpd_song *song, bool f) assert(song != NULL); follow = f; - next_song = mpd_songDup(song); + next_song = mpd_song_dup(song); screen_switch(&screen_lyrics, c); } diff --git a/src/screen_outputs.c b/src/screen_outputs.c index 4e55df9..43b95e3 100644 --- a/src/screen_outputs.c +++ b/src/screen_outputs.c @@ -21,6 +21,8 @@ #include "screen.h" #include "list_window.h" +#include + #include static list_window_t *lw = NULL; @@ -41,7 +43,7 @@ static int toggle_output(mpdclient_t *c, unsigned int output_index) { int return_value; - mpd_OutputEntity *output; + struct mpd_output *output; assert(mpd_outputs != NULL); @@ -50,18 +52,22 @@ toggle_output(mpdclient_t *c, unsigned int output_index) output = g_ptr_array_index(mpd_outputs, output_index); - if (output->enabled == 0) { - mpd_sendEnableOutputCommand(c->connection, output->id); + if (!mpd_output_get_enabled(output)) { + mpd_send_enable_output(c->connection, + mpd_output_get_id(output)); - output->enabled = 1; + /* XXX reload */ - screen_status_printf(_("Output '%s' enabled"), output->name); + screen_status_printf(_("Output '%s' enabled"), + mpd_output_get_name(output)); } else { - mpd_sendDisableOutputCommand(c->connection, output->id); + mpd_send_disable_output(c->connection, + mpd_output_get_id(output)); - output->enabled = 0; + /* XXX reload */ - screen_status_printf(_("Output '%s' disabled"), output->name); + screen_status_printf(_("Output '%s' disabled"), + mpd_output_get_name(output)); } return_value = mpdclient_finish_command(c); @@ -74,7 +80,7 @@ toggle_output(mpdclient_t *c, unsigned int output_index) static void clear_output_element(gpointer data, G_GNUC_UNUSED gpointer user_data) { - mpd_freeOutputElement(data); + mpd_output_free(data); } static void @@ -92,15 +98,15 @@ clear_outputs_list(void) static void fill_outputs_list(mpdclient_t *c) { - mpd_OutputEntity *output; + struct mpd_output *output; assert(mpd_outputs != NULL); if (c->connection == NULL) return; - mpd_sendOutputsCommand(c->connection); - while ((output = mpd_getNextOutput(c->connection)) != NULL) { + mpd_send_outputs(c->connection); + while ((output = mpd_recv_output(c->connection)) != NULL) { g_ptr_array_add(mpd_outputs, output); } } @@ -109,7 +115,7 @@ static const char * outputs_list_callback(unsigned int output_index, bool *highlight, G_GNUC_UNUSED char **sc, G_GNUC_UNUSED void *data) { - mpd_OutputEntity *output; + struct mpd_output *output; assert(mpd_outputs != NULL); @@ -118,10 +124,10 @@ outputs_list_callback(unsigned int output_index, bool *highlight, output = g_ptr_array_index(mpd_outputs, output_index); - if (output->enabled) + if (mpd_output_get_enabled(output)) *highlight = true; - return output->name; + return mpd_output_get_name(output); } static void diff --git a/src/screen_play.c b/src/screen_play.c index e1389b8..51835a1 100644 --- a/src/screen_play.c +++ b/src/screen_play.c @@ -35,6 +35,8 @@ #include "hscroll.h" #endif +#include + #include #include #include @@ -98,9 +100,9 @@ playlist_changed_callback(mpdclient_t *c, int event, gpointer data) #ifndef NCMPC_MINI static char * -format_duration(int duration) +format_duration(unsigned duration) { - if (duration == MPD_SONG_NO_TIME) + if (duration == 0) return NULL; return g_strdup_printf("%d:%02d", duration / 60, duration % 60); @@ -114,20 +116,20 @@ list_callback(unsigned idx, bool *highlight, char **second_column, G_GNUC_UNUSED #ifndef NCMPC_MINI static scroll_state_t st; #endif - mpd_Song *song; + struct mpd_song *song; if (playlist == NULL || idx >= playlist_length(playlist)) return NULL; song = playlist_get(playlist, idx); - if (song->id == current_song_id) + if ((int)mpd_song_get_id(song) == current_song_id) *highlight = true; strfsong(songname, MAX_SONG_LENGTH, options.list_format, song); #ifndef NCMPC_MINI if(second_column) - *second_column = format_duration(song->time); + *second_column = format_duration(mpd_song_get_duration(song)); if (idx == lw->selected) { @@ -166,7 +168,7 @@ center_playing_item(mpdclient_t *c, bool center_cursor) int idx; if (!c->song || c->status == NULL || - IS_STOPPED(c->status->state)) + IS_STOPPED(mpd_status_get_state(c->status))) return; /* try to center the song that are playing */ @@ -310,7 +312,7 @@ playlist_save(mpdclient_t *c, char *name, char *defaultname) if (error) { gint code = GET_ACK_ERROR_CODE(error); - if (code == MPD_ACK_ERROR_EXIST) { + if (code == MPD_SERVER_ERROR_EXIST) { char *buf; int key; @@ -468,7 +470,8 @@ timer_hide_cursor(gpointer data) /* hide the cursor when mpd is playing and the user is inactive */ - if (c->status != NULL && c->status->state == MPD_STATUS_STATE_PLAY) { + if (c->status != NULL && + mpd_status_get_state(c->status) == MPD_STATE_PLAY) { lw->hide_cursor = true; playlist_repaint(); } else @@ -524,7 +527,7 @@ play_exit(void) static const char * play_title(char *str, size_t size) { - if( strcmp(options.host, "localhost") == 0 ) + if (options.host == NULL) return _("Playlist"); g_snprintf(str, size, _("Playlist on %s"), options.host); @@ -543,7 +546,8 @@ play_update(mpdclient_t *c) static int prev_song_id = -1; current_song_id = c->song != NULL && c->status != NULL && - !IS_STOPPED(c->status->state) ? c->song->id : -1; + !IS_STOPPED(mpd_status_get_state(c->status)) + ? (int)mpd_song_get_id(c->song) : -1; if (current_song_id != prev_song_id) { prev_song_id = current_song_id; @@ -754,7 +758,8 @@ play_cmd(mpdclient_t *c, command_t cmd) bool follow = false; if (c->song && selected && - !strcmp(selected->file, c->song->file)) + !strcmp(mpd_song_get_uri(selected), + mpd_song_get_uri(c->song))) follow = true; screen_lyrics_switch(c, selected, follow); diff --git a/src/screen_search.c b/src/screen_search.c index cced93a..ff78082 100644 --- a/src/screen_search.c +++ b/src/screen_search.c @@ -32,21 +32,24 @@ #include #include +enum { + SEARCH_URI = MPD_TAG_COUNT + 100, +}; + static const struct { const char *name; const char *localname; -} search_tag[MPD_TAG_NUM_OF_ITEM_TYPES] = { - [MPD_TAG_ITEM_ARTIST] = { "artist", N_("artist") }, - [MPD_TAG_ITEM_ALBUM] = { "album", N_("album") }, - [MPD_TAG_ITEM_TITLE] = { "title", N_("title") }, - [MPD_TAG_ITEM_TRACK] = { "track", N_("track") }, - [MPD_TAG_ITEM_NAME] = { "name", N_("name") }, - [MPD_TAG_ITEM_GENRE] = { "genre", N_("genre") }, - [MPD_TAG_ITEM_DATE] = { "date", N_("date") }, - [MPD_TAG_ITEM_COMPOSER] = { "composer", N_("composer") }, - [MPD_TAG_ITEM_PERFORMER] = { "performer", N_("performer") }, - [MPD_TAG_ITEM_COMMENT] = { "comment", N_("comment") }, - [MPD_TAG_ITEM_FILENAME] = { "filename", N_("file") }, +} search_tag[MPD_TAG_COUNT] = { + [MPD_TAG_ARTIST] = { "artist", N_("artist") }, + [MPD_TAG_ALBUM] = { "album", N_("album") }, + [MPD_TAG_TITLE] = { "title", N_("title") }, + [MPD_TAG_TRACK] = { "track", N_("track") }, + [MPD_TAG_NAME] = { "name", N_("name") }, + [MPD_TAG_GENRE] = { "genre", N_("genre") }, + [MPD_TAG_DATE] = { "date", N_("date") }, + [MPD_TAG_COMPOSER] = { "composer", N_("composer") }, + [MPD_TAG_PERFORMER] = { "performer", N_("performer") }, + [MPD_TAG_COMMENT] = { "comment", N_("comment") }, }; static int @@ -54,7 +57,11 @@ search_get_tag_id(const char *name) { unsigned i; - for (i = 0; i < MPD_TAG_NUM_OF_ITEM_TYPES; ++i) + if (g_ascii_strcasecmp(name, "file") == 0 || + strcasecmp(name, _("file")) == 0) + return SEARCH_URI; + + for (i = 0; i < MPD_TAG_COUNT; ++i) if (search_tag[i].name != NULL && (strcasecmp(search_tag[i].name, name) == 0 || strcasecmp(search_tag[i].localname, name) == 0)) @@ -66,15 +73,15 @@ search_get_tag_id(const char *name) #define SEARCH_ARTIST_TITLE 999 typedef struct { - int table; + enum mpd_tag_type table; const char *label; } search_type_t; static search_type_t mode[] = { - { MPD_TABLE_TITLE, N_("Title") }, - { MPD_TABLE_ARTIST, N_("Artist") }, - { MPD_TABLE_ALBUM, N_("Album") }, - { MPD_TABLE_FILENAME, N_("Filename") }, + { MPD_TAG_TITLE, N_("Title") }, + { MPD_TAG_ARTIST, N_("Artist") }, + { MPD_TAG_ALBUM, N_("Album") }, + { SEARCH_URI, N_("file") }, { SEARCH_ARTIST_TITLE, N_("Artist + Title") }, { 0, NULL } }; @@ -176,12 +183,12 @@ filelist_search(mpdclient_t *c, G_GNUC_UNUSED int exact_match, int table, gchar *filter_utf8 = locale_to_utf8(local_pattern); if (table == SEARCH_ARTIST_TITLE) { - list = mpdclient_filelist_search(c, FALSE, MPD_TABLE_ARTIST, + list = mpdclient_filelist_search(c, FALSE, MPD_TAG_ARTIST, filter_utf8); if (list == NULL) list = filelist_new(); - list2 = mpdclient_filelist_search(c, FALSE, MPD_TABLE_TITLE, + list2 = mpdclient_filelist_search(c, FALSE, MPD_TAG_TITLE, filter_utf8); if (list2 != NULL) { filelist_move(list, list2); @@ -261,7 +268,7 @@ search_advanced_query(char *query, mpdclient_t *c) if (advanced_search_mode && j > 0) { int iter; - mpd_InfoEntity *entity; + struct mpd_entity *entity; /*----------------------------------------------------------------------- * NOTE (again): This code exists to test a new search ui, @@ -270,17 +277,24 @@ search_advanced_query(char *query, mpdclient_t *c) *----------------------------------------------------------------------- */ /** stupid - but this is just a test...... (fulhack) */ - mpd_startSearch(c->connection, FALSE); - - for(iter = 0; iter < 10; iter++) { - mpd_addConstraintSearch(c->connection, table[iter], arg[iter]); + mpd_search_db_songs(c->connection, false); + + for(iter = 0; iter < 10 && arg[iter] != NULL; iter++) { + if (table[iter] == SEARCH_URI) + mpd_search_add_uri_constraint(c->connection, + MPD_OPERATOR_DEFAULT, + arg[iter]); + else + mpd_search_add_tag_constraint(c->connection, + MPD_OPERATOR_DEFAULT, + table[iter], arg[iter]); } - mpd_commitSearch(c->connection); + mpd_search_commit(c->connection); fl = filelist_new(); - while ((entity=mpd_getNextInfoEntity(c->connection))) + while ((entity = mpd_recv_entity(c->connection)) != NULL) filelist_append(fl, entity); if (mpdclient_finish_command(c) && fl) @@ -319,7 +333,7 @@ search_new(mpdclient_t *c) browser.filelist = NULL; } - if (!MPD_VERSION_LT(c, 0, 12, 0)) + if (mpd_connection_cmp_server_version(c->connection, 0, 12, 0) >= 0) browser.filelist = search_advanced_query(pattern, c); if (!advanced_search_mode && browser.filelist == NULL) diff --git a/src/screen_song.c b/src/screen_song.c index a7d6f8e..8ded356 100644 --- a/src/screen_song.c +++ b/src/screen_song.c @@ -23,6 +23,8 @@ #include "charset.h" #include "utils.h" +#include + #include #include @@ -45,11 +47,11 @@ screen_song_clear(void) g_ptr_array_set_size(current.lines, 0); if (current.selected_song != NULL) { - mpd_freeSong(current.selected_song); + mpd_song_free(current.selected_song); current.selected_song = NULL; } if (current.played_song != NULL) { - mpd_freeSong(current.played_song); + mpd_song_free(current.played_song); current.played_song = NULL; } } @@ -179,13 +181,24 @@ screen_song_append(const char *label, const char *value, unsigned label_col) } } +static void +screen_song_append_tag(const char *label, const struct mpd_song *song, + enum mpd_tag_type tag, unsigned label_col) +{ + unsigned i = 0; + const char *value; + + while ((value = mpd_song_get_tag(song, tag, i++)) != NULL) + screen_song_append(label, value, label_col); +} + static void screen_song_add_song(const struct mpd_song *song, const mpdclient_t *c) { unsigned i, max_label_width; enum label { ARTIST, TITLE, ALBUM, LENGTH, COMPOSER, NAME, DISC, TRACK, - DATE, GENRE, COMMENT, PATH, BITRATE + DATE, GENRE, COMMENT, BITRATE }; const char *labels[] = { [ARTIST] = _("Artist"), [TITLE] = _("Title"), @@ -198,7 +211,6 @@ screen_song_add_song(const struct mpd_song *song, const mpdclient_t *c) [DATE] = _("Date"), [GENRE] = _("Genre"), [COMMENT] = _("Comment"), - [PATH] = _("Path"), [BITRATE] = _("Bitrate"), }; /* Determine the width of the longest label */ @@ -210,37 +222,50 @@ screen_song_add_song(const struct mpd_song *song, const mpdclient_t *c) assert(song != NULL); - screen_song_append(labels[ARTIST], song->artist, max_label_width); - screen_song_append(labels[TITLE], song->title, max_label_width); - screen_song_append(labels[ALBUM], song->album, max_label_width); + screen_song_append_tag(labels[ARTIST], song, MPD_TAG_ARTIST, + max_label_width); + screen_song_append_tag(labels[TITLE], song, MPD_TAG_TITLE, + max_label_width); + screen_song_append_tag(labels[ALBUM], song, MPD_TAG_ALBUM, + max_label_width); /* create time string and add it */ - if (song->time != MPD_SONG_NO_TIME) { + if (mpd_song_get_duration(song) > 0) { + unsigned t = mpd_song_get_duration(song); char length[16]; + /*write out the time, using hours if time over 60 minutes*/ - if (song->time > 3600) { + if (t > 3600) { g_snprintf(length, sizeof(length), "%i:%02i:%02i", - song->time/3600, (song->time%3600)/60, song->time%60); + t/3600, (t%3600)/60, t%60); } else { g_snprintf(length, sizeof(length), - "%i:%02i", song->time/60, song->time%60); + "%i:%02i", t/60, t%60); } screen_song_append(labels[LENGTH], length, max_label_width); } - screen_song_append(labels[COMPOSER], song->composer, max_label_width); - screen_song_append(labels[NAME], song->name, max_label_width); - screen_song_append(labels[DISC], song->disc, max_label_width); - screen_song_append(labels[TRACK], song->track, max_label_width); - screen_song_append(labels[DATE], song->date, max_label_width); - screen_song_append(labels[GENRE], song->genre, max_label_width); - screen_song_append(labels[COMMENT], song->comment, max_label_width); - screen_song_append(labels[PATH], song->file, max_label_width); + screen_song_append_tag(labels[COMPOSER], song, MPD_TAG_COMPOSER, + max_label_width); + screen_song_append_tag(labels[NAME], song, MPD_TAG_NAME, + max_label_width); + screen_song_append_tag(labels[DISC], song, MPD_TAG_DISC, + max_label_width); + screen_song_append_tag(labels[TRACK], song, MPD_TAG_TRACK, + max_label_width); + screen_song_append_tag(labels[DATE], song, MPD_TAG_DATE, + max_label_width); + screen_song_append_tag(labels[GENRE], song, MPD_TAG_GENRE, + max_label_width); + screen_song_append_tag(labels[COMMENT], song, MPD_TAG_COMMENT, + max_label_width); + screen_song_append(_("Path"), mpd_song_get_uri(song), max_label_width); if (c->status != NULL && c->song != NULL && - g_strcmp0(c->song->file, song->file) == 0 && - (c->status->state == MPD_STATUS_STATE_PLAY || - c->status->state == MPD_STATUS_STATE_PAUSE) ) { + strcmp(mpd_song_get_uri(c->song), mpd_song_get_uri(song)) == 0 && + (mpd_status_get_state(c->status) == MPD_STATE_PLAY || + mpd_status_get_state(c->status) == MPD_STATE_PAUSE)) { char buf[16]; - g_snprintf(buf, sizeof(buf), _("%d kbps"), c->status->bitRate); + g_snprintf(buf, sizeof(buf), _("%d kbps"), + mpd_status_get_kbit_rate(c->status)); screen_song_append(labels[BITRATE], buf, max_label_width); } } @@ -264,10 +289,10 @@ screen_song_add_stats(const mpdclient_t *c) [PLAYTIME] = _("Playtime"), [DBPLAYTIME] = _("DB playtime") }; - mpd_Stats *mpd_stats = NULL; + struct mpd_stats *mpd_stats = NULL; + if (c->connection != NULL) { - mpd_sendStatsCommand(c->connection); - mpd_stats = mpd_getStats(c->connection); + mpd_stats = mpd_run_stats(c->connection); } if (mpd_stats != NULL) { @@ -279,28 +304,31 @@ screen_song_add_stats(const mpdclient_t *c) } g_ptr_array_add(current.lines, g_strdup(_("MPD statistics")) ); - g_snprintf(buf, sizeof(buf), "%d", mpd_stats->numberOfArtists); + g_snprintf(buf, sizeof(buf), "%d", + mpd_stats_get_number_of_artists(mpd_stats)); screen_song_append(labels[ARTISTS], buf, max_label_width); - g_snprintf(buf, sizeof(buf), "%d", mpd_stats->numberOfAlbums); + g_snprintf(buf, sizeof(buf), "%d", + mpd_stats_get_number_of_albums(mpd_stats)); screen_song_append(labels[ALBUMS], buf, max_label_width); - g_snprintf(buf, sizeof(buf), "%d", mpd_stats->numberOfSongs); + g_snprintf(buf, sizeof(buf), "%d", + mpd_stats_get_number_of_songs(mpd_stats)); screen_song_append(labels[SONGS], buf, max_label_width); - duration = time_seconds_to_durationstr(mpd_stats->dbPlayTime); + duration = time_seconds_to_durationstr(mpd_stats_get_db_play_time(mpd_stats)); screen_song_append(labels[DBPLAYTIME], duration, max_label_width); g_free(duration); - duration = time_seconds_to_durationstr(mpd_stats->playTime); + duration = time_seconds_to_durationstr(mpd_stats_get_play_time(mpd_stats)); screen_song_append(labels[PLAYTIME], duration, max_label_width); g_free(duration); - duration = time_seconds_to_durationstr(mpd_stats->uptime); + duration = time_seconds_to_durationstr(mpd_stats_get_uptime(mpd_stats)); screen_song_append(labels[UPTIME], duration, max_label_width); g_free(duration); date = g_date_new(); - g_date_set_time_t(date, mpd_stats->dbUpdateTime); + g_date_set_time_t(date, mpd_stats_get_db_update_time(mpd_stats)); g_date_strftime(buf, sizeof(buf), "%x", date); screen_song_append(labels[DBUPTIME], buf, max_label_width); g_date_free(date); - mpd_freeStats(mpd_stats); + mpd_stats_free(mpd_stats); } } @@ -321,22 +349,23 @@ screen_song_update(mpdclient_t *c) if (current.selected_song != NULL && (c->song == NULL || - g_strcmp0(current.selected_song->file, c->song->file) != 0 || + strcmp(mpd_song_get_uri(current.selected_song), + mpd_song_get_uri(c->song)) != 0 || c->status == NULL || - (c->status->state != MPD_STATUS_STATE_PLAY && - c->status->state != MPD_STATUS_STATE_PAUSE)) ) { + (mpd_status_get_state(c->status) != MPD_STATE_PLAY && + mpd_status_get_state(c->status) != MPD_STATE_PAUSE))) { g_ptr_array_add(current.lines, g_strdup(_("Selected song")) ); screen_song_add_song(current.selected_song, c); g_ptr_array_add(current.lines, g_strdup("\0")); } if (c->song != NULL && c->status != NULL && - (c->status->state == MPD_STATUS_STATE_PLAY || - c->status->state == MPD_STATUS_STATE_PAUSE) ) { + (mpd_status_get_state(c->status) != MPD_STATE_PLAY && + mpd_status_get_state(c->status) != MPD_STATE_PAUSE)) { if (current.played_song != NULL) { - mpd_freeSong(current.played_song); + mpd_song_free(current.played_song); } - current.played_song = mpd_songDup(c->song); + current.played_song = mpd_song_dup(c->song); g_ptr_array_add(current.lines, g_strdup(_("Currently playing song"))); screen_song_add_song(current.played_song, c); g_ptr_array_add(current.lines, g_strdup("\0")); @@ -426,6 +455,6 @@ screen_song_switch(mpdclient_t *c, const struct mpd_song *song) assert(current.selected_song == NULL); assert(current.played_song == NULL); - next_song = mpd_songDup(song); + next_song = mpd_song_dup(song); screen_switch(&screen_song, c); } diff --git a/src/screen_utils.c b/src/screen_utils.c index 8eddfc5..d8e56df 100644 --- a/src/screen_utils.c +++ b/src/screen_utils.c @@ -29,6 +29,8 @@ #include "ncmpc.h" #endif /* NCMPC_H */ +#include + #include #include @@ -127,7 +129,7 @@ _screen_auth(struct mpdclient *c, gint recursion) { char *password; - mpd_clearError(c->connection); + mpd_connection_clear_error(c->connection); if (recursion > 2) return 1; @@ -135,12 +137,14 @@ _screen_auth(struct mpdclient *c, gint recursion) if (password == NULL) return 1; - mpd_sendPasswordCommand(c->connection, password); + mpd_send_password(c->connection, password); g_free(password); - mpd_finishCommand(c->connection); + mpd_response_finish(c->connection); mpdclient_update(c); - if (c->connection->errorCode == MPD_ACK_ERROR_PASSWORD) + + if (mpd_connection_get_error(c->connection) == MPD_ERROR_SERVER && + mpd_connection_get_server_error(c->connection) == MPD_SERVER_ERROR_PASSWORD) return _screen_auth(c, ++recursion); return 0; } diff --git a/src/song.c b/src/song.c deleted file mode 100644 index ab79653..0000000 --- a/src/song.c +++ /dev/null @@ -1,141 +0,0 @@ -/* libmpdclient - (c)2003-2006 by Warren Dukes (warren.dukes@gmail.com) - This project's homepage is: http://www.musicpd.org - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Music Player Daemon nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "song.h" -#include "str_pool.h" - -#define LIBMPDCLIENT_GLIB_SLICE - -#ifndef LIBMPDCLIENT_GLIB_SLICE -#include -#else -#include -#endif - -static void mpd_initSong(struct mpd_song *song) { - song->file = NULL; - song->artist = NULL; - song->album = NULL; - song->track = NULL; - song->title = NULL; - song->name = NULL; - song->date = NULL; - /* added by Qball */ - song->genre = NULL; - song->composer = NULL; - song->disc = NULL; - song->comment = NULL; - - song->time = MPD_SONG_NO_TIME; - song->pos = MPD_SONG_NO_NUM; - song->id = MPD_SONG_NO_ID; -} - -static void mpd_finishSong(struct mpd_song *song) { - if (song->file) - str_pool_put(song->file); - if (song->artist) - str_pool_put(song->artist); - if (song->album) - str_pool_put(song->album); - if (song->title) - str_pool_put(song->title); - if (song->track) - str_pool_put(song->track); - if (song->name) - str_pool_put(song->name); - if (song->date) - str_pool_put(song->date); - if (song->genre) - str_pool_put(song->genre); - if (song->composer) - str_pool_put(song->composer); - if (song->disc) - str_pool_put(song->disc); - if (song->comment) - str_pool_put(song->comment); -} - -struct mpd_song *mpd_newSong(void) { -#ifndef LIBMPDCLIENT_GLIB_SLICE - struct mpd_song *ret = malloc(sizeof(*ret)); -#else - struct mpd_song *ret = g_slice_new(struct mpd_song); -#endif - - mpd_initSong(ret); - - return ret; -} - -void mpd_freeSong(struct mpd_song *song) { - mpd_finishSong(song); - -#ifndef LIBMPDCLIENT_GLIB_SLICE - free(song); -#else - g_slice_free(struct mpd_song, song); -#endif -} - -struct mpd_song *mpd_songDup(const struct mpd_song *song) { - struct mpd_song *ret = mpd_newSong(); - - if (song->file) - ret->file = str_pool_dup(song->file); - if (song->artist) - ret->artist = str_pool_dup(song->artist); - if (song->album) - ret->album = str_pool_dup(song->album); - if (song->title) - ret->title = str_pool_dup(song->title); - if (song->track) - ret->track = str_pool_dup(song->track); - if (song->name) - ret->name = str_pool_dup(song->name); - if (song->date) - ret->date = str_pool_dup(song->date); - if (song->genre) - ret->genre= str_pool_dup(song->genre); - if (song->composer) - ret->composer= str_pool_dup(song->composer); - if (song->disc) - ret->disc = str_pool_dup(song->disc); - if (song->comment) - ret->comment = str_pool_dup(song->comment); - - ret->time = song->time; - ret->pos = song->pos; - ret->id = song->id; - - return ret; -} diff --git a/src/song.h b/src/song.h deleted file mode 100644 index e3ad7e9..0000000 --- a/src/song.h +++ /dev/null @@ -1,101 +0,0 @@ -/* libmpdclient - (c)2003-2006 by Warren Dukes (warren.dukes@gmail.com) - (c) 2008 Max Kellermann - This project's homepage is: http://www.musicpd.org - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Music Player Daemon nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef SONG_H -#define SONG_H - -#define MPD_SONG_NO_TIME -1 -#define MPD_SONG_NO_NUM -1 -#define MPD_SONG_NO_ID -1 - -/* mpd_Song - * for storing song info returned by mpd - */ -typedef struct mpd_song { - /* filename of song */ - char * file; - /* artist, maybe NULL if there is no tag */ - char * artist; - /* title, maybe NULL if there is no tag */ - char * title; - /* album, maybe NULL if there is no tag */ - char * album; - /* track, maybe NULL if there is no tag */ - char * track; - /* name, maybe NULL if there is no tag; it's the name of the current - * song, f.e. the icyName of the stream */ - char * name; - /* date */ - char *date; - - /* added by qball */ - /* Genre */ - char *genre; - /* Composer */ - char *composer; - /* Disc */ - char *disc; - /* Comment */ - char *comment; - - /* length of song in seconds, check that it is not MPD_SONG_NO_TIME */ - int time; - /* if plchanges/playlistinfo/playlistid used, is the position of the - * song in the playlist */ - int pos; - /* song id for a song in the playlist */ - int id; -} mpd_Song; - -/* mpd_newSong - * use to allocate memory for a new mpd_Song - * file, artist, etc all initialized to NULL - * if your going to assign values to file, artist, etc - * be sure to malloc or strdup the memory - * use mpd_freeSong to free the memory for the mpd_Song, it will also - * free memory for file, artist, etc, so don't do it yourself - */ -struct mpd_song *mpd_newSong(void); - -/* mpd_freeSong - * use to free memory allocated by mpd_newSong - * also it will free memory pointed to by file, artist, etc, so be careful - */ -void mpd_freeSong(struct mpd_song *song); - -/* mpd_songDup - * works like strDup, but for a mpd_Song - */ -struct mpd_song *mpd_songDup(const struct mpd_song *song); - -#endif diff --git a/src/strfsong.c b/src/strfsong.c index 714a0b0..ff1d6ad 100644 --- a/src/strfsong.c +++ b/src/strfsong.c @@ -20,6 +20,8 @@ #include "strfsong.h" #include "charset.h" +#include + #include static const gchar * @@ -46,6 +48,16 @@ skip(const gchar * p) return p; } +static char * +song_tag_locale(const struct mpd_song *song, enum mpd_tag_type tag) +{ + const char *value = mpd_song_get_tag(song, tag, 0); + if (value == NULL) + return NULL; + + return utf8_to_locale(value); +} + static gsize _strfsong(gchar *s, gsize max, @@ -134,15 +146,15 @@ _strfsong(gchar *s, if(*end != '%') n--; else if (strncmp("%file%", p, n) == 0) - temp = utf8_to_locale(song->file); + temp = utf8_to_locale(mpd_song_get_uri(song)); else if (strncmp("%artist%", p, n) == 0) - temp = song->artist ? utf8_to_locale(song->artist) : NULL; + temp = song_tag_locale(song, MPD_TAG_ARTIST); else if (strncmp("%title%", p, n) == 0) - temp = song->title ? utf8_to_locale(song->title) : NULL; + temp = song_tag_locale(song, MPD_TAG_TITLE); else if (strncmp("%album%", p, n) == 0) - temp = song->album ? utf8_to_locale(song->album) : NULL; + temp = song_tag_locale(song, MPD_TAG_ALBUM); else if (strncmp("%shortalbum%", p, n) == 0) { - temp = song->album ? utf8_to_locale(song->album) : NULL; + temp = song_tag_locale(song, MPD_TAG_ALBUM); if (temp) { gchar *temp2 = g_strndup(temp, 25); if (strlen(temp) > 25) { @@ -155,29 +167,32 @@ _strfsong(gchar *s, } } else if (strncmp("%track%", p, n) == 0) - temp = song->track ? utf8_to_locale(song->track) : NULL; + temp = song_tag_locale(song, MPD_TAG_TRACK); else if (strncmp("%name%", p, n) == 0) - temp = song->name ? utf8_to_locale(song->name) : NULL; + temp = song_tag_locale(song, MPD_TAG_NAME); else if (strncmp("%date%", p, n) == 0) - temp = song->date ? utf8_to_locale(song->date) : NULL; + temp = song_tag_locale(song, MPD_TAG_DATE); else if (strncmp("%genre%", p, n) == 0) - temp = song->genre ? utf8_to_locale(song->genre) : NULL; + temp = song_tag_locale(song, MPD_TAG_GENRE); else if (strncmp("%shortfile%", p, n) == 0) { - if( strstr(song->file, "://") ) - temp = utf8_to_locale(song->file); + const char *uri = mpd_song_get_uri(song); + if (strstr(uri, "://") != NULL) + temp = utf8_to_locale(uri); else - temp = utf8_to_locale(g_basename(song->file)); + temp = utf8_to_locale(g_basename(uri)); } else if (strncmp("%time%", p, n) == 0) { - if (song->time != MPD_SONG_NO_TIME) { - if (song->time > 3600) { + unsigned duration = mpd_song_get_duration(song); + + if (duration > 0) { + if (duration > 3600) { temp = g_strdup_printf("%d:%02d:%02d", - song->time / 3600, - (song->time % 3600) / 60, - song->time % 60); + duration / 3600, + (duration % 3600) / 60, + duration % 60); } else { temp = g_strdup_printf("%d:%02d", - song->time / 60, - song->time % 60); + duration / 60, + duration % 60); } } } diff --git a/src/strfsong.h b/src/strfsong.h index a596bf8..c1f5ae4 100644 --- a/src/strfsong.h +++ b/src/strfsong.h @@ -21,7 +21,8 @@ #define STRFSONG_H #include -#include "libmpdclient.h" + +struct mpd_song; gsize strfsong(gchar *s, gsize max, const gchar *format, const struct mpd_song *song); diff --git a/src/utils.c b/src/utils.c index da8fd60..23408f2 100644 --- a/src/utils.c +++ b/src/utils.c @@ -81,30 +81,34 @@ gcmp_list_from_path(mpdclient_t *c, const gchar *path, GList *list, gint types) return list; for (i = 0; i < filelist_length(filelist); ++i) { - struct filelist_entry *entry = filelist_get(filelist, i); - mpd_InfoEntity *entity = entry ? entry->entity : NULL; + const struct filelist_entry *entry = filelist_get(filelist, i); + const struct mpd_entity *entity = entry ? entry->entity : NULL; char *name = NULL; - if (entity && entity->type==MPD_INFO_ENTITY_TYPE_DIRECTORY && + if (entity != NULL && + mpd_entity_get_type(entity) == MPD_ENTITY_TYPE_DIRECTORY && types & GCMP_TYPE_DIR) { - mpd_Directory *dir = entity->info.directory; - gchar *tmp = utf8_to_locale(dir->path); + const struct mpd_directory *dir = + mpd_entity_get_directory(entity); + gchar *tmp = utf8_to_locale(mpd_directory_get_path(dir)); gsize size = strlen(tmp)+2; name = g_malloc(size); g_strlcpy(name, tmp, size); g_strlcat(name, "/", size); g_free(tmp); - } else if (entity && - entity->type == MPD_INFO_ENTITY_TYPE_SONG && + } else if (entity != NULL && + mpd_entity_get_type(entity) == MPD_ENTITY_TYPE_SONG && types & GCMP_TYPE_FILE) { - mpd_Song *song = entity->info.song; - name = utf8_to_locale(song->file); - } else if (entity && - entity->type == MPD_INFO_ENTITY_TYPE_PLAYLISTFILE && + const struct mpd_song *song = + mpd_entity_get_song(entity); + name = utf8_to_locale(mpd_song_get_uri(song)); + } else if (entity != NULL && + mpd_entity_get_type(entity) == MPD_ENTITY_TYPE_PLAYLIST && types & GCMP_TYPE_PLAYLIST) { - mpd_PlaylistFile *plf = entity->info.playlistFile; - name = utf8_to_locale(plf->path); + const struct mpd_playlist *playlist = + mpd_entity_get_playlist(entity); + name = utf8_to_locale(mpd_playlist_get_path(playlist)); } if (name) -- 2.30.2