diff --git a/configure.in b/configure.in index 6fe9dccc..2d7a4fef 100644 --- a/configure.in +++ b/configure.in @@ -55,6 +55,24 @@ dnl ================================ AC_CHECK_HEADERS([dirent.h regex.h], , AC_MSG_ERROR(vital headers missing)) AC_CHECK_HEADERS([langinfo.h], , AC_MSG_WARN(locale detection disabled)) +dnl ============================== +dnl = checking for libmpdclient2 = +dnl ============================== +PKG_CHECK_MODULES([libmpdclient], [libmpdclient >= 2.0], [ + AC_SUBST(libmpdclient_LIBS) + AC_SUBST(libmpdclient_CFLAGS) + CPPFLAGS="$CPPFLAGS $libmpdclient_CFLAGS" + AC_CHECK_HEADERS([mpd/client.h], + LDFLAGS="$LDFLAGS $libmpdclient_LIBS" + , + AC_MSG_ERROR([missing mpd/client.h header]) + ) +], + if test "$fftw" = "yes" ; then + AC_MSG_ERROR([libmpdclient2 is required!]) + fi +) + dnl ====================== dnl = checking for iconv = dnl ====================== diff --git a/src/Makefile.am b/src/Makefile.am index f102309b..7b54ed03 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,9 +1,9 @@ bin_PROGRAMS = ncmpcpp ncmpcpp_SOURCES = browser.cpp charset.cpp clock.cpp conv.cpp display.cpp \ - error.cpp help.cpp helpers.cpp info.cpp libmpdclient.c lyrics.cpp \ - media_library.cpp menu.cpp misc.cpp mpdpp.cpp ncmpcpp.cpp outputs.cpp playlist.cpp \ - playlist_editor.cpp scrollpad.cpp search_engine.cpp settings.cpp song.cpp status.cpp \ - str_pool.c tag_editor.cpp tiny_tag_editor.cpp visualizer.cpp window.cpp + error.cpp help.cpp helpers.cpp info.cpp lyrics.cpp media_library.cpp menu.cpp \ + misc.cpp mpdpp.cpp ncmpcpp.cpp outputs.cpp playlist.cpp playlist_editor.cpp \ + scrollpad.cpp search_engine.cpp settings.cpp song.cpp status.cpp str_pool.c \ + tag_editor.cpp tiny_tag_editor.cpp visualizer.cpp window.cpp # set the include path found by configure INCLUDES= $(all_includes) diff --git a/src/browser.cpp b/src/browser.cpp index 3e7680d3..49d7efc1 100644 --- a/src/browser.cpp +++ b/src/browser.cpp @@ -329,8 +329,8 @@ void Browser::GetLocalDirectory(ItemList &v, const std::string &directory, bool else if (hasSupportedExtension(file->d_name)) { new_item.type = itSong; - mpd_Song *s = mpd_newSong(); - s->file = str_pool_get(full_path.c_str()); + mpd_pair file_pair = { "file", strdup(full_path.c_str()) }; + mpd_song *s = mpd_song_begin(&file_pair); # ifdef HAVE_TAGLIB_H if (!recursively) TagEditor::ReadTags(s); diff --git a/src/conv.cpp b/src/conv.cpp index a5996386..6852aebf 100644 --- a/src/conv.cpp +++ b/src/conv.cpp @@ -45,31 +45,31 @@ std::string IntoStr(int l) return ss.str(); } -std::string IntoStr(mpd_TagItems tag) // this is only for left column's title in media library +std::string IntoStr(mpd_tag_type tag) // this is only for left column's title in media library { switch (tag) { - case MPD_TAG_ITEM_ARTIST: + case MPD_TAG_ARTIST: return "Artist"; - case MPD_TAG_ITEM_ALBUM: + case MPD_TAG_ALBUM: return "Album"; - case MPD_TAG_ITEM_TITLE: + case MPD_TAG_TITLE: return "Title"; - case MPD_TAG_ITEM_TRACK: + case MPD_TAG_TRACK: return "Track"; - case MPD_TAG_ITEM_GENRE: + case MPD_TAG_GENRE: return "Genre"; - case MPD_TAG_ITEM_DATE: + case MPD_TAG_DATE: return "Year"; - case MPD_TAG_ITEM_COMPOSER: + case MPD_TAG_COMPOSER: return "Composer"; - case MPD_TAG_ITEM_PERFORMER: + case MPD_TAG_PERFORMER: return "Performer"; - case MPD_TAG_ITEM_COMMENT: + case MPD_TAG_COMMENT: return "Comment"; - case MPD_TAG_ITEM_DISC: + case MPD_TAG_DISC: return "Disc"; - case MPD_TAG_ITEM_FILENAME: + case MPD_TAG_FILE: return "Filename"; default: return ""; @@ -126,51 +126,51 @@ NCurses::Color IntoColor(const std::string &color) return result; } -mpd_TagItems IntoTagItem(char c) +mpd_tag_type IntoTagItem(char c) { switch (c) { case 'a': - return MPD_TAG_ITEM_ARTIST; + return MPD_TAG_ARTIST; case 'y': - return MPD_TAG_ITEM_DATE; + return MPD_TAG_DATE; case 'g': - return MPD_TAG_ITEM_GENRE; + return MPD_TAG_GENRE; case 'c': - return MPD_TAG_ITEM_COMPOSER; + return MPD_TAG_COMPOSER; case 'p': - return MPD_TAG_ITEM_PERFORMER; + return MPD_TAG_PERFORMER; default: - return MPD_TAG_ITEM_ARTIST; + return MPD_TAG_ARTIST; } } #ifdef HAVE_TAGLIB_H -MPD::Song::SetFunction IntoSetFunction(mpd_TagItems tag) +MPD::Song::SetFunction IntoSetFunction(mpd_tag_type tag) { switch (tag) { - case MPD_TAG_ITEM_ARTIST: + case MPD_TAG_ARTIST: return &MPD::Song::SetArtist; - case MPD_TAG_ITEM_ALBUM: + case MPD_TAG_ALBUM: return &MPD::Song::SetAlbum; - case MPD_TAG_ITEM_TITLE: + case MPD_TAG_TITLE: return &MPD::Song::SetTitle; - case MPD_TAG_ITEM_TRACK: + case MPD_TAG_TRACK: return &MPD::Song::SetTrack; - case MPD_TAG_ITEM_GENRE: + case MPD_TAG_GENRE: return &MPD::Song::SetGenre; - case MPD_TAG_ITEM_DATE: + case MPD_TAG_DATE: return &MPD::Song::SetDate; - case MPD_TAG_ITEM_COMPOSER: + case MPD_TAG_COMPOSER: return &MPD::Song::SetComposer; - case MPD_TAG_ITEM_PERFORMER: + case MPD_TAG_PERFORMER: return &MPD::Song::SetPerformer; - case MPD_TAG_ITEM_COMMENT: + case MPD_TAG_COMMENT: return &MPD::Song::SetComment; - case MPD_TAG_ITEM_DISC: + case MPD_TAG_DISC: return &MPD::Song::SetDisc; - case MPD_TAG_ITEM_FILENAME: + case MPD_TAG_FILE: return &MPD::Song::SetNewName; default: return 0; diff --git a/src/conv.h b/src/conv.h index 1c1af989..717f1250 100644 --- a/src/conv.h +++ b/src/conv.h @@ -38,16 +38,16 @@ long StrToLong(const std::string &); std::string IntoStr(int); -std::string IntoStr(mpd_TagItems); +std::string IntoStr(mpd_tag_type); std::string IntoStr(NCurses::Color); NCurses::Color IntoColor(const std::string &); -mpd_TagItems IntoTagItem(char); +mpd_tag_type IntoTagItem(char); #ifdef HAVE_TAGLIB_H -MPD::Song::SetFunction IntoSetFunction(mpd_TagItems); +MPD::Song::SetFunction IntoSetFunction(mpd_tag_type); #endif // HAVE_TAGLIB_H void EscapeUnallowedChars(std::string &); diff --git a/src/libmpdclient.c b/src/libmpdclient.c deleted file mode 100644 index b8b6998f..00000000 --- a/src/libmpdclient.c +++ /dev/null @@ -1,2102 +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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef WIN32 -# include -# include -#else -# include -# include -# include -# include -#endif - -/* (bits+1)/3 (plus the sign character) */ -#define INTLEN ((sizeof(int) * CHAR_BIT + 1) / 3 + 1) -#define LONGLONGLEN ((sizeof(long long) * CHAR_BIT + 1) / 3 + 1) - -#define COMMAND_LIST 1 -#define COMMAND_LIST_OK 2 - -#ifndef MPD_NO_GAI -# ifdef AI_ADDRCONFIG -# define MPD_HAVE_GAI -# endif -#endif - -#ifndef WIN32 -#include -#endif - -#ifndef MSG_DONTWAIT -# define MSG_DONTWAIT 0 -#endif - -#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 ) { - strcpy(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 */ - if (connect(connection->sock, serv_addr, addrlen) == SOCKET_ERROR) - return 1; - ioctlsocket(connection->sock, FIONBIO, (u_long FAR*) &iMode); - return 0; -} -#else /* !WIN32 (sane operating systems) */ -static int do_connect_fail(mpd_Connection *connection, - const struct sockaddr *serv_addr, int addrlen) -{ - int flags; - if (connect(connection->sock, serv_addr, addrlen) < 0) - return 1; - flags = fcntl(connection->sock, F_GETFL, 0); - fcntl(connection->sock, F_SETFL, flags | O_NONBLOCK); - return 0; -} -#endif /* !WIN32 */ - -#ifdef MPD_HAVE_GAI -static int mpd_connect(mpd_Connection * connection, const char * host, int port, - float timeout) -{ - int error; - char service[INTLEN+1]; - struct addrinfo hints; - struct addrinfo *res = NULL; - struct addrinfo *addrinfo = NULL; - - /** - * Setup hints - */ - hints.ai_flags = AI_ADDRCONFIG; - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - hints.ai_addrlen = 0; - hints.ai_addr = NULL; - hints.ai_canonname = NULL; - hints.ai_next = NULL; - - snprintf(service, sizeof(service), "%i", port); - - error = getaddrinfo(host, service, &hints, &addrinfo); - - if (error) { - snprintf(connection->errorStr, MPD_ERRORSTR_MAX_LENGTH, - "host \"%s\" not found: %s", - host, gai_strerror(error)); - connection->error = MPD_ERROR_UNKHOST; - return -1; - } - - for (res = addrinfo; res; res = res->ai_next) { - /* create socket */ - if (connection->sock >= 0) - closesocket(connection->sock); - connection->sock = socket(res->ai_family, SOCK_STREAM, - res->ai_protocol); - if (connection->sock < 0) { - snprintf(connection->errorStr, MPD_ERRORSTR_MAX_LENGTH, - "problems creating socket: %s", - strerror(errno)); - connection->error = MPD_ERROR_SYSTEM; - freeaddrinfo(addrinfo); - return -1; - } - - mpd_setConnectionTimeout(connection, timeout); - - /* connect stuff */ - if (do_connect_fail(connection, - res->ai_addr, res->ai_addrlen)) { - /* try the next address */ - closesocket(connection->sock); - connection->sock = -1; - continue; - } - - break; - } - - freeaddrinfo(addrinfo); - - if (connection->sock < 0) { - snprintf(connection->errorStr, MPD_ERRORSTR_MAX_LENGTH, - "problems connecting to \"%s\" on port %i: %s", - host, port, strerror(errno)); - connection->error = MPD_ERROR_CONNPORT; - - return -1; - } - - return 0; -} -#else /* !MPD_HAVE_GAI */ -static int mpd_connect(mpd_Connection * connection, const char * host, int port, - float timeout) -{ - struct hostent * he; - struct sockaddr * dest; - int destlen; - struct sockaddr_in sin; - - if(!(he=gethostbyname(host))) { - snprintf(connection->errorStr,MPD_ERRORSTR_MAX_LENGTH, - "host \"%s\" not found",host); - connection->error = MPD_ERROR_UNKHOST; - return -1; - } - - memset(&sin,0,sizeof(struct sockaddr_in)); - /*dest.sin_family = he->h_addrtype;*/ - sin.sin_family = AF_INET; - sin.sin_port = htons(port); - - switch(he->h_addrtype) { - case AF_INET: - memcpy((char *)&sin.sin_addr.s_addr,(char *)he->h_addr, - he->h_length); - dest = (struct sockaddr *)&sin; - destlen = sizeof(struct sockaddr_in); - break; - default: - strcpy(connection->errorStr,"address type is not IPv4"); - connection->error = MPD_ERROR_SYSTEM; - return -1; - break; - } - - if (connection->sock >= 0) - closesocket(connection->sock); - if((connection->sock = socket(dest->sa_family,SOCK_STREAM,0))<0) { - strcpy(connection->errorStr,"problems creating socket"); - connection->error = MPD_ERROR_SYSTEM; - return -1; - } - - mpd_setConnectionTimeout(connection,timeout); - - /* connect stuff */ - if (do_connect_fail(connection, dest, destlen)) { - snprintf(connection->errorStr,MPD_ERRORSTR_MAX_LENGTH, - "problems connecting to \"%s\" on port" - " %i",host,port); - connection->error = MPD_ERROR_CONNPORT; - return -1; - } - - return 0; -} -#endif /* !MPD_HAVE_GAI */ - -char * mpdTagItemKeys[MPD_TAG_NUM_OF_ITEM_TYPES] = -{ - "Artist", - "Album", - "Title", - "Track", - "Name", - "Genre", - "Date", - "Composer", - "Performer", - "Comment", - "Disc", - "Filename", - "Any" -}; - -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,MPD_ERRORSTR_MAX_LENGTH, - "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, - MPD_ERRORSTR_MAX_LENGTH, - "error parsing version number at " - "\"%s\"", - &output[strlen(MPD_WELCOME_MESSAGE)]); - connection->error = MPD_ERROR_NOTMPD; - return 1; - } - tmp = ++test; - } - - return 0; -} - -#ifndef WIN32 -static int mpd_connect_un(mpd_Connection * connection, - const char * host, float timeout) -{ - int error, flags; - size_t path_length; - struct sockaddr_un sun; - - path_length = strlen(host); - if (path_length >= sizeof(sun.sun_path)) { - strcpy(connection->errorStr, "unix socket path is too long"); - connection->error = MPD_ERROR_UNKHOST; - return -1; - } - - sun.sun_family = AF_UNIX; - memcpy(sun.sun_path, host, path_length + 1); - - connection->sock = socket(AF_UNIX, SOCK_STREAM, 0); - if (connection->sock < 0) { - strcpy(connection->errorStr, "problems creating socket"); - connection->error = MPD_ERROR_SYSTEM; - return -1; - } - - mpd_setConnectionTimeout(connection, timeout); - - flags = fcntl(connection->sock, F_GETFL, 0); - fcntl(connection->sock, F_SETFL, flags | O_NONBLOCK); - - error = connect(connection->sock, (struct sockaddr*)&sun, sizeof(sun)); - if (error < 0) { - /* try the next address family */ - close(connection->sock); - connection->sock = 0; - - snprintf(connection->errorStr,MPD_BUFFER_MAX_LENGTH, - "problems connecting to \"%s\": %s", - host, strerror(errno)); - connection->error = MPD_ERROR_CONNPORT; - return -1; - } - - return 0; -} -#endif /* WIN32 */ - -mpd_Connection * mpd_newConnection(const char * host, int port, float timeout) { - int err; - char * rt; - char * output = NULL; - mpd_Connection * connection = malloc(sizeof(mpd_Connection)); - struct timeval tv; - fd_set fds; - strcpy(connection->buffer,""); - connection->sock = -1; - connection->buflen = 0; - connection->bufstart = 0; - strcpy(connection->errorStr,""); - connection->error = 0; - 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; - -#ifndef WIN32 - if (host[0] == '/') - err = mpd_connect_un(connection, host, timeout); - else -#endif - err = mpd_connect(connection, host, port, timeout); - if (err < 0) - return connection; - - while(!(rt = strstr(connection->buffer,"\n"))) { - tv.tv_sec = connection->timeout.tv_sec; - tv.tv_usec = connection->timeout.tv_usec; - FD_ZERO(&fds); - FD_SET(connection->sock,&fds); - if((err = select(connection->sock+1,&fds,NULL,NULL,&tv)) == 1) { - int readed; - readed = recv(connection->sock, - &(connection->buffer[connection->buflen]), - MPD_BUFFER_MAX_LENGTH-connection->buflen,0); - if(readed<=0) { - snprintf(connection->errorStr,MPD_ERRORSTR_MAX_LENGTH, - "problems getting a response from" - " \"%s\" on port %i : %s",host, - port, strerror(errno)); - connection->error = MPD_ERROR_NORESPONSE; - return connection; - } - connection->buflen+=readed; - connection->buffer[connection->buflen] = '\0'; - } - else if(err<0) { - if (SELECT_ERRNO_IGNORE) - continue; - snprintf(connection->errorStr, - MPD_ERRORSTR_MAX_LENGTH, - "problems connecting to \"%s\" on port" - " %i",host,port); - connection->error = MPD_ERROR_CONNPORT; - return connection; - } - else { - snprintf(connection->errorStr,MPD_ERRORSTR_MAX_LENGTH, - "timeout in attempting to get a response from" - " \"%s\" on port %i",host,port); - connection->error = MPD_ERROR_NORESPONSE; - return connection; - } - } - - *rt = '\0'; - output = strdup(connection->buffer); - strcpy(connection->buffer,rt+1); - connection->buflen = strlen(connection->buffer); - - if(mpd_parseWelcome(connection,host,port,output) == 0) connection->doneProcessing = 1; - - free(output); - - 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(); -} - -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->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,MPD_ERRORSTR_MAX_LENGTH, - "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,MPD_ERRORSTR_MAX_LENGTH, - "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; - fd_set fds; - struct timeval tv; - char * tok = NULL; - int readed; - char * bufferCheck = 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; - } - - bufferCheck = connection->buffer+connection->bufstart; - while(connection->bufstart>=connection->buflen || - !(rt = strchr(bufferCheck,'\n'))) { - if(connection->buflen>=MPD_BUFFER_MAX_LENGTH) { - memmove(connection->buffer, - connection->buffer+ - connection->bufstart, - connection->buflen- - connection->bufstart+1); - connection->buflen-=connection->bufstart; - connection->bufstart = 0; - } - if(connection->buflen>=MPD_BUFFER_MAX_LENGTH) { - strcpy(connection->errorStr,"buffer overrun"); - connection->error = MPD_ERROR_BUFFEROVERRUN; - connection->doneProcessing = 1; - connection->doneListOk = 0; - return; - } - bufferCheck = connection->buffer+connection->buflen; - tv.tv_sec = connection->timeout.tv_sec; - tv.tv_usec = connection->timeout.tv_usec; - FD_ZERO(&fds); - FD_SET(connection->sock,&fds); - if((err = select(connection->sock+1,&fds,NULL,NULL,&tv) == 1)) { - readed = recv(connection->sock, - connection->buffer+connection->buflen, - MPD_BUFFER_MAX_LENGTH-connection->buflen, - MSG_DONTWAIT); - if(readed<0 && SENDRECV_ERRNO_IGNORE) { - continue; - } - if(readed<=0) { - strcpy(connection->errorStr,"connection" - " closed"); - connection->error = MPD_ERROR_CONNCLOSED; - connection->doneProcessing = 1; - connection->doneListOk = 0; - return; - } - connection->buflen+=readed; - connection->buffer[connection->buflen] = '\0'; - } - else if(err<0 && SELECT_ERRNO_IGNORE) continue; - else { - strcpy(connection->errorStr,"connection timeout"); - connection->error = MPD_ERROR_TIMEOUT; - connection->doneProcessing = 1; - connection->doneListOk = 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) { - char * test; - char * needle; - int val; - - strcpy(connection->errorStr, output); - 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,MPD_ERRORSTR_MAX_LENGTH, - "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 = -1; - 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); -} - -mpd_SearchStats * mpd_getSearchStats(mpd_Connection * connection) -{ - mpd_SearchStats * stats; - mpd_ReturnElement * re; - - if (connection->doneProcessing || - (connection->listOks && connection->doneListOk)) { - return NULL; - } - - if (!connection->returnElement) mpd_getNextReturnElement(connection); - - if (connection->error) - return NULL; - - stats = malloc(sizeof(mpd_SearchStats)); - stats->numberOfSongs = 0; - stats->playTime = 0; - - while (connection->returnElement) { - re = connection->returnElement; - - if (strcmp(re->name, "songs") == 0) { - stats->numberOfSongs = atoi(re->value); - } else if (strcmp(re->name, "playtime") == 0) { - stats->playTime = 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_freeSearchStats(mpd_SearchStats * stats) -{ - free(stats); -} - -static void mpd_initSong(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->performer = 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(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->performer) str_pool_put(song->performer); - if(song->disc) str_pool_put(song->disc); - if(song->comment) str_pool_put(song->comment); -} - -mpd_Song * mpd_newSong(void) { - mpd_Song * ret = malloc(sizeof(mpd_Song)); - - mpd_initSong(ret); - - return ret; -} - -void mpd_freeSong(mpd_Song * song) { - mpd_finishSong(song); - free(song); -} - -mpd_Song * mpd_songDup(mpd_Song * song) { - 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->performer) ret->performer = str_pool_dup(song->performer); - 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; -} - -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(strcmp(re->name, "Composer") == 0) { - char *tmp = 0; - if (entity->info.song->composer) { - tmp = malloc(strlen(entity->info.song->composer) + strlen(re->value) + 3); - sprintf(tmp, "%s, %s", entity->info.song->composer, re->value); - str_pool_put(entity->info.song->composer); - } - entity->info.song->composer = tmp ? str_pool_get(tmp) : str_pool_dup(re->value); - free(tmp); - } - else if(strcmp(re->name, "Performer") == 0) { - char *tmp = 0; - if (entity->info.song->performer) { - tmp = malloc(strlen(entity->info.song->performer) + strlen(re->value) + 3); - sprintf(tmp, "%s, %s", entity->info.song->performer, re->value); - str_pool_put(entity->info.song->performer); - } - entity->info.song->performer = tmp ? str_pool_get(tmp) : str_pool_dup(re->value); - free(tmp); - } - else if(strcmp(re->name, "Disc") == 0) { - char *tmp = 0; - if (entity->info.song->disc) { - tmp = malloc(strlen(entity->info.song->disc) + strlen(re->value) + 3); - sprintf(tmp, "%s, %s", entity->info.song->disc, re->value); - str_pool_put(entity->info.song->disc); - } - entity->info.song->disc = tmp ? str_pool_get(tmp) : str_pool_dup(re->value); - free(tmp); - } - 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 type) -{ - if (type < 0 || type >= MPD_TAG_NUM_OF_ITEM_TYPES || - type == MPD_TAG_ITEM_ANY) - return NULL; - if (type == MPD_TAG_ITEM_FILENAME) - return mpd_getNextReturnElementNamed(connection, "file"); - return mpd_getNextReturnElementNamed(connection, mpdTagItemKeys[type]); -} - -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) { - int len = strlen("playlistinfo")+2+INTLEN+3; - char *string = malloc(len); - snprintf(string, len, "playlistinfo \"%i\"\n", songPos); - mpd_sendInfoCommand(connection,string); - free(string); -} - -void mpd_sendPlaylistIdCommand(mpd_Connection * connection, int id) { - int len = strlen("playlistid")+2+INTLEN+3; - char *string = malloc(len); - snprintf(string, len, "playlistid \"%i\"\n", id); - mpd_sendInfoCommand(connection, string); - free(string); -} - -void mpd_sendPlChangesCommand(mpd_Connection * connection, long long playlist) { - int len = strlen("plchanges")+2+LONGLONGLEN+3; - char *string = malloc(len); - snprintf(string, len, "plchanges \"%lld\"\n", playlist); - mpd_sendInfoCommand(connection,string); - free(string); -} - -void mpd_sendPlChangesPosIdCommand(mpd_Connection * connection, long long playlist) { - int len = strlen("plchangesposid")+2+LONGLONGLEN+3; - char *string = malloc(len); - snprintf(string, len, "plchangesposid \"%lld\"\n", playlist); - mpd_sendInfoCommand(connection,string); - free(string); -} - -void mpd_sendListallCommand(mpd_Connection * connection, const char * dir) { - char * sDir = mpd_sanitizeArg(dir); - int len = strlen("listall")+2+strlen(sDir)+3; - char *string = malloc(len); - snprintf(string, len, "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); - int len = strlen("listallinfo")+2+strlen(sDir)+3; - char *string = malloc(len); - snprintf(string, len, "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); - int len = strlen("lsinfo")+2+strlen(sDir)+3; - char *string = malloc(len); - snprintf(string, len, "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) -{ - mpd_startSearch(connection, 0); - mpd_addConstraintSearch(connection, table, str); - mpd_commitSearch(connection); -} - -void mpd_sendFindCommand(mpd_Connection * connection, int table, - const char * str) -{ - mpd_startSearch(connection, 1); - mpd_addConstraintSearch(connection, table, str); - mpd_commitSearch(connection); -} - -void mpd_sendListCommand(mpd_Connection * connection, int table, - const char * arg1) -{ - char st[10]; - int len; - char *string; - switch(table) { - case MPD_TABLE_ARTIST: - strcpy(st,"artist"); - break; - case MPD_TABLE_ALBUM: - strcpy(st,"album"); - break; - case MPD_TABLE_TITLE: - strcpy(st,"title"); - break; - case MPD_TABLE_TRACK: - strcpy(st,"track"); - break; - case MPD_TABLE_GENRE: - strcpy(st,"genre"); - break; - case MPD_TABLE_DATE: - strcpy(st,"date"); - break; - case MPD_TABLE_COMPOSER: - strcpy(st,"composer"); - break; - case MPD_TABLE_PERFORMER: - strcpy(st,"performer"); - break; - case MPD_TABLE_COMMENT: - strcpy(st,"comment"); - break; - case MPD_TABLE_DISC: - strcpy(st,"disc"); - break; - case MPD_TABLE_FILENAME: - strcpy(st,"filename"); - break; - default: - connection->error = 1; - strcpy(connection->errorStr,"unknown table for list"); - return; - } - if(arg1) { - char * sanitArg1 = mpd_sanitizeArg(arg1); - len = strlen("list")+1+strlen(sanitArg1)+2+strlen(st)+3; - string = malloc(len); - snprintf(string, len, "list %s \"%s\"\n", st, sanitArg1); - free(sanitArg1); - } - else { - len = strlen("list")+1+strlen(st)+2; - string = malloc(len); - snprintf(string, len, "list %s\n", st); - } - mpd_sendInfoCommand(connection,string); - free(string); -} - -void mpd_sendAddCommand(mpd_Connection * connection, const char * file) { - char * sFile = mpd_sanitizeArg(file); - int len = strlen("add")+2+strlen(sFile)+3; - char *string = malloc(len); - snprintf(string, len, "add \"%s\"\n", sFile); - mpd_executeCommand(connection,string); - free(string); - free(sFile); -} - -int mpd_sendAddIdCommand(mpd_Connection *connection, const char *file) -{ - int retval = -1; - char *sFile = mpd_sanitizeArg(file); - int len = strlen("addid")+2+strlen(sFile)+3; - char *string = malloc(len); - - snprintf(string, len, "addid \"%s\"\n", sFile); - mpd_sendInfoCommand(connection, string); - free(string); - free(sFile); - - string = mpd_getNextReturnElementNamed(connection, "Id"); - if (string) { - retval = atoi(string); - free(string); - } - - return retval; -} - -void mpd_sendDeleteCommand(mpd_Connection * connection, int songPos) { - int len = strlen("delete")+2+INTLEN+3; - char *string = malloc(len); - snprintf(string, len, "delete \"%i\"\n", songPos); - mpd_sendInfoCommand(connection,string); - free(string); -} - -void mpd_sendDeleteIdCommand(mpd_Connection * connection, int id) { - int len = strlen("deleteid")+2+INTLEN+3; - char *string = malloc(len); - snprintf(string, len, "deleteid \"%i\"\n", id); - mpd_sendInfoCommand(connection,string); - free(string); -} - -void mpd_sendSaveCommand(mpd_Connection * connection, const char * name) { - char * sName = mpd_sanitizeArg(name); - int len = strlen("save")+2+strlen(sName)+3; - char *string = malloc(len); - snprintf(string, len, "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); - int len = strlen("load")+2+strlen(sName)+3; - char *string = malloc(len); - snprintf(string, len, "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); - int len = strlen("rm")+2+strlen(sName)+3; - char *string = malloc(len); - snprintf(string, len, "rm \"%s\"\n", sName); - mpd_executeCommand(connection,string); - free(string); - free(sName); -} - -void mpd_sendRenameCommand(mpd_Connection *connection, const char *from, - const char *to) -{ - char *sFrom = mpd_sanitizeArg(from); - char *sTo = mpd_sanitizeArg(to); - int len = strlen("rename")+2+strlen(sFrom)+3+strlen(sTo)+3; - char *string = malloc(len); - snprintf(string, len, "rename \"%s\" \"%s\"\n", sFrom, sTo); - mpd_executeCommand(connection, string); - free(string); - free(sFrom); - free(sTo); -} - -void mpd_sendShuffleCommand(mpd_Connection * connection) { - mpd_executeCommand(connection,"shuffle\n"); -} - -void mpd_sendClearCommand(mpd_Connection * connection) { - mpd_executeCommand(connection,"clear\n"); -} - -void mpd_sendPlayCommand(mpd_Connection * connection, int songPos) { - int len = strlen("play")+2+INTLEN+3; - char *string = malloc(len); - snprintf(string, len, "play \"%i\"\n", songPos); - mpd_sendInfoCommand(connection,string); - free(string); -} - -void mpd_sendPlayIdCommand(mpd_Connection * connection, int id) { - int len = strlen("playid")+2+INTLEN+3; - char *string = malloc(len); - snprintf(string, len, "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) { - int len = strlen("pause")+2+INTLEN+3; - char *string = malloc(len); - snprintf(string, len, "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) { - int len = strlen("move")+2+INTLEN+3+INTLEN+3; - char *string = malloc(len); - snprintf(string, len, "move \"%i\" \"%i\"\n", from, to); - mpd_sendInfoCommand(connection,string); - free(string); -} - -void mpd_sendMoveIdCommand(mpd_Connection * connection, int id, int to) { - int len = strlen("moveid")+2+INTLEN+3+INTLEN+3; - char *string = malloc(len); - snprintf(string, len, "moveid \"%i\" \"%i\"\n", id, to); - mpd_sendInfoCommand(connection,string); - free(string); -} - -void mpd_sendSwapCommand(mpd_Connection * connection, int song1, int song2) { - int len = strlen("swap")+2+INTLEN+3+INTLEN+3; - char *string = malloc(len); - snprintf(string, len, "swap \"%i\" \"%i\"\n", song1, song2); - mpd_sendInfoCommand(connection,string); - free(string); -} - -void mpd_sendSwapIdCommand(mpd_Connection * connection, int id1, int id2) { - int len = strlen("swapid")+2+INTLEN+3+INTLEN+3; - char *string = malloc(len); - snprintf(string, len, "swapid \"%i\" \"%i\"\n", id1, id2); - mpd_sendInfoCommand(connection,string); - free(string); -} - -void mpd_sendSeekCommand(mpd_Connection * connection, int song, int time) { - int len = strlen("seek")+2+INTLEN+3+INTLEN+3; - char *string = malloc(len); - snprintf(string, len, "seek \"%i\" \"%i\"\n", song, time); - mpd_sendInfoCommand(connection,string); - free(string); -} - -void mpd_sendSeekIdCommand(mpd_Connection * connection, int id, int time) { - int len = strlen("seekid")+2+INTLEN+3+INTLEN+3; - char *string = malloc(len); - snprintf(string, len, "seekid \"%i\" \"%i\"\n", id, time); - mpd_sendInfoCommand(connection,string); - free(string); -} - -void mpd_sendUpdateCommand(mpd_Connection * connection, const char * path) { - char * sPath = mpd_sanitizeArg(path); - int len = strlen("update")+2+strlen(sPath)+3; - char *string = malloc(len); - snprintf(string, len, "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) { - int len = strlen("repeat")+2+INTLEN+3; - char *string = malloc(len); - snprintf(string, len, "repeat \"%i\"\n", repeatMode); - mpd_executeCommand(connection,string); - free(string); -} - -void mpd_sendRandomCommand(mpd_Connection * connection, int randomMode) { - int len = strlen("random")+2+INTLEN+3; - char *string = malloc(len); - snprintf(string, len, "random \"%i\"\n", randomMode); - mpd_executeCommand(connection,string); - free(string); -} - -void mpd_sendSingleCommand(mpd_Connection * connection, int singleMode) { - int len = strlen("single")+2+INTLEN+3; - char *string = malloc(len); - snprintf(string, len, "single \"%i\"\n", singleMode); - mpd_executeCommand(connection,string); - free(string); -} - -void mpd_sendConsumeCommand(mpd_Connection * connection, int consumeMode) { - int len = strlen("consume")+2+INTLEN+3; - char *string = malloc(len); - snprintf(string, len, "consume \"%i\"\n", consumeMode); - mpd_executeCommand(connection,string); - free(string); -} - -void mpd_sendSetvolCommand(mpd_Connection * connection, int volumeChange) { - int len = strlen("setvol")+2+INTLEN+3; - char *string = malloc(len); - snprintf(string, len, "setvol \"%i\"\n", volumeChange); - mpd_executeCommand(connection,string); - free(string); -} - -void mpd_sendVolumeCommand(mpd_Connection * connection, int volumeChange) { - int len = strlen("volume")+2+INTLEN+3; - char *string = malloc(len); - snprintf(string, len, "volume \"%i\"\n", volumeChange); - mpd_executeCommand(connection,string); - free(string); -} - -void mpd_sendCrossfadeCommand(mpd_Connection * connection, int seconds) { - int len = strlen("crossfade")+2+INTLEN+3; - char *string = malloc(len); - snprintf(string, len, "crossfade \"%i\"\n", seconds); - mpd_executeCommand(connection,string); - free(string); -} - -void mpd_sendPasswordCommand(mpd_Connection * connection, const char * pass) { - char * sPass = mpd_sanitizeArg(pass); - int len = strlen("password")+2+strlen(sPass)+3; - char *string = malloc(len); - snprintf(string, len, "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) { - int len = strlen("enableoutput")+2+INTLEN+3; - char *string = malloc(len); - snprintf(string, len, "enableoutput \"%i\"\n", outputId); - mpd_executeCommand(connection,string); - free(string); -} - -void mpd_sendDisableOutputCommand(mpd_Connection * connection, int outputId) { - int len = strlen("disableoutput")+2+INTLEN+3; - char *string = malloc(len); - snprintf(string, len, "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_sendUrlHandlersCommand(mpd_Connection * connection) -{ - mpd_executeCommand(connection, "urlhandlers\n"); -} - -char * mpd_getNextHandler(mpd_Connection * connection) -{ - return mpd_getNextReturnElementNamed(connection, "handler"); -} - -void mpd_sendTagTypesCommand(mpd_Connection * connection) -{ - mpd_executeCommand(connection, "tagtypes\n"); -} - -char * mpd_getNextTagType(mpd_Connection * connection) -{ - return mpd_getNextReturnElementNamed(connection, "tagtype"); -} - -void mpd_startSearch(mpd_Connection *connection, int exact) -{ - if (connection->request) { - strcpy(connection->errorStr, "search already in progress"); - connection->error = 1; - return; - } - - if (exact) connection->request = strdup("find"); - else connection->request = strdup("search"); -} - -void mpd_startStatsSearch(mpd_Connection *connection) -{ - if (connection->request) { - strcpy(connection->errorStr, "search already in progress"); - connection->error = 1; - return; - } - - connection->request = strdup("count"); -} - -void mpd_startPlaylistSearch(mpd_Connection *connection, int exact) -{ - if (connection->request) { - strcpy(connection->errorStr, "search already in progress"); - connection->error = 1; - return; - } - - if (exact) connection->request = strdup("playlistfind"); - else connection->request = strdup("playlistsearch"); -} - -void mpd_startFieldSearch(mpd_Connection *connection, int type) -{ - char *strtype; - int len; - - if (connection->request) { - strcpy(connection->errorStr, "search already in progress"); - connection->error = 1; - return; - } - - if (type < 0 || type >= MPD_TAG_NUM_OF_ITEM_TYPES) { - strcpy(connection->errorStr, "invalid type specified"); - connection->error = 1; - return; - } - - strtype = mpdTagItemKeys[type]; - - len = 5+strlen(strtype)+1; - connection->request = malloc(len); - - snprintf(connection->request, len, "list %c%s", - tolower(strtype[0]), strtype+1); -} - -void mpd_addConstraintSearch(mpd_Connection *connection, int type, const char *name) -{ - char *strtype; - char *arg; - int len; - char *string; - - if (!connection->request) { - strcpy(connection->errorStr, "no search in progress"); - connection->error = 1; - return; - } - - if (type < 0 || type >= MPD_TAG_NUM_OF_ITEM_TYPES) { - strcpy(connection->errorStr, "invalid type specified"); - connection->error = 1; - return; - } - - if (name == NULL) { - strcpy(connection->errorStr, "no name specified"); - connection->error = 1; - return; - } - - string = strdup(connection->request); - strtype = mpdTagItemKeys[type]; - arg = mpd_sanitizeArg(name); - - len = strlen(string)+1+strlen(strtype)+2+strlen(arg)+2; - connection->request = realloc(connection->request, len); - snprintf(connection->request, len, "%s %c%s \"%s\"", - string, tolower(strtype[0]), strtype+1, arg); - - free(string); - free(arg); -} - -void mpd_commitSearch(mpd_Connection *connection) -{ - int len; - - if (!connection->request) { - strcpy(connection->errorStr, "no search in progress"); - connection->error = 1; - return; - } - - len = strlen(connection->request)+2; - connection->request = realloc(connection->request, len); - connection->request[len-2] = '\n'; - connection->request[len-1] = '\0'; - mpd_sendInfoCommand(connection, connection->request); - - 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, const char *path) -{ - char *arg = mpd_sanitizeArg(path); - int len = strlen("listplaylistinfo")+2+strlen(arg)+3; - char *query = malloc(len); - snprintf(query, len, "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); - int len = strlen("listplaylist")+2+strlen(arg)+3; - char *query = malloc(len); - snprintf(query, len, "listplaylist \"%s\"\n", arg); - mpd_sendInfoCommand(connection, query); - free(arg); - free(query); -} - -void mpd_sendPlaylistClearCommand(mpd_Connection *connection, const char *path) -{ - char *sPath = mpd_sanitizeArg(path); - int len = strlen("playlistclear")+2+strlen(sPath)+3; - char *string = malloc(len); - snprintf(string, len, "playlistclear \"%s\"\n", sPath); - mpd_executeCommand(connection, string); - free(sPath); - free(string); -} - -void mpd_sendPlaylistAddCommand(mpd_Connection *connection, - const char *playlist, const char *path) -{ - char *sPlaylist = mpd_sanitizeArg(playlist); - char *sPath = mpd_sanitizeArg(path); - int len = strlen("playlistadd")+2+strlen(sPlaylist)+3+strlen(sPath)+3; - char *string = malloc(len); - snprintf(string, len, "playlistadd \"%s\" \"%s\"\n", sPlaylist, sPath); - mpd_executeCommand(connection, string); - free(sPlaylist); - free(sPath); - free(string); -} - -void mpd_sendPlaylistMoveCommand(mpd_Connection *connection, - const char *playlist, int from, int to) -{ - char *sPlaylist = mpd_sanitizeArg(playlist); - int len = strlen("playlistmove")+ - 2+strlen(sPlaylist)+3+INTLEN+3+INTLEN+3; - char *string = malloc(len); - snprintf(string, len, "playlistmove \"%s\" \"%i\" \"%i\"\n", - sPlaylist, from, to); - mpd_executeCommand(connection, string); - free(sPlaylist); - free(string); -} - -void mpd_sendPlaylistDeleteCommand(mpd_Connection *connection, - const char *playlist, int pos) -{ - char *sPlaylist = mpd_sanitizeArg(playlist); - int len = strlen("playlistdelete")+2+strlen(sPlaylist)+3+INTLEN+3; - char *string = malloc(len); - snprintf(string, len, "playlistdelete \"%s\" \"%i\"\n", sPlaylist, pos); - mpd_executeCommand(connection, string); - free(sPlaylist); - free(string); -} diff --git a/src/libmpdclient.h b/src/libmpdclient.h deleted file mode 100644 index b2a26048..00000000 --- a/src/libmpdclient.h +++ /dev/null @@ -1,689 +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 - -#ifdef WIN32 -# define __W32API_USE_DLLIMPORT__ 1 -#endif - -#include "str_pool.h" -#include -#include -#define MPD_BUFFER_MAX_LENGTH 50000 -#define MPD_ERRORSTR_MAX_LENGTH 1000 -#define MPD_WELCOME_MESSAGE "OK MPD " - -#define MPD_ERROR_TIMEOUT 10 /* timeout trying to talk to mpd */ -#define MPD_ERROR_SYSTEM 11 /* system error */ -#define MPD_ERROR_UNKHOST 12 /* unknown host */ -#define MPD_ERROR_CONNPORT 13 /* problems connecting to port on host */ -#define MPD_ERROR_NOTMPD 14 /* mpd not running on port at host */ -#define MPD_ERROR_NORESPONSE 15 /* no response on attempting to connect */ -#define MPD_ERROR_SENDING 16 /* error sending command */ -#define MPD_ERROR_CONNCLOSED 17 /* connection closed by mpd */ -#define MPD_ERROR_ACK 18 /* ACK returned! */ -#define MPD_ERROR_BUFFEROVERRUN 19 /* Buffer was overrun! */ - -#define MPD_ACK_ERROR_UNK -1 -#define MPD_ERROR_AT_UNK -1 - -#define MPD_ACK_ERROR_NOT_LIST 1 -#define MPD_ACK_ERROR_ARG 2 -#define MPD_ACK_ERROR_PASSWORD 3 -#define MPD_ACK_ERROR_PERMISSION 4 -#define MPD_ACK_ERROR_UNKNOWN_CMD 5 - -#define MPD_ACK_ERROR_NO_EXIST 50 -#define MPD_ACK_ERROR_PLAYLIST_MAX 51 -#define MPD_ACK_ERROR_SYSTEM 52 -#define MPD_ACK_ERROR_PLAYLIST_LOAD 53 -#define MPD_ACK_ERROR_UPDATE_ALREADY 54 -#define MPD_ACK_ERROR_PLAYER_SYNC 55 -#define 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_ITEM_ANY, - MPD_TAG_NUM_OF_ITEM_TYPES -} mpd_TagItems; - -extern char * mpdTagItemKeys[MPD_TAG_NUM_OF_ITEM_TYPES]; - -/* internal stuff don't touch this struct */ -typedef struct _mpd_ReturnElement { - const char * name; - const 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[MPD_ERRORSTR_MAX_LENGTH+1]; - int errorCode; - int errorAt; - /* this will be set to MPD_ERROR_* if there is an error, 0 if not */ - int error; - /* DON'T TOUCH any of the rest of this stuff */ - int sock; - char buffer[MPD_BUFFER_MAX_LENGTH+1]; - int buflen; - int 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); - -/* added by unK, make this extern as I want to use it */ -void mpd_executeCommand(mpd_Connection * connection, const char * command); - -/* 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 mode is on, 0 otherwise */ - int single; - /* 1 if consume mode 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; - -typedef struct _mpd_SearchStats { - int numberOfSongs; - unsigned long playTime; -} mpd_SearchStats; - -void mpd_sendStatsCommand(mpd_Connection * connection); - -mpd_Stats * mpd_getStats(mpd_Connection * connection); - -void mpd_freeStats(mpd_Stats * stats); - -mpd_SearchStats * mpd_getSearchStats(mpd_Connection * connection); - -void mpd_freeSearchStats(mpd_SearchStats * stats); - -/* SONG STUFF */ - -#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 */ - const char * file; - /* artist, maybe NULL if there is no tag */ - const char * artist; - /* title, maybe NULL if there is no tag */ - const char * title; - /* album, maybe NULL if there is no tag */ - const char * album; - /* track, maybe NULL if there is no tag */ - const 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 */ - const char * name; - /* date */ - const char *date; - - /* added by qball */ - /* Genre */ - const char *genre; - /* Composer */ - const char *composer; - /* Performer */ - const char *performer; - /* Disc */ - const char *disc; - /* Comment */ - const 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 - */ -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(mpd_Song * song); - -/* mpd_songDup - * works like strDup, but for a mpd_Song - */ -mpd_Song * mpd_songDup(mpd_Song * song); - -/* DIRECTORY STUFF */ - -/* mpd_Directory - * used to store info fro directory (right now that just the path) - */ -typedef struct _mpd_Directory { - const 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 { - const 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 MPD_TAG_ITEM_ARTIST -#define MPD_TABLE_ALBUM MPD_TAG_ITEM_ALBUM -#define MPD_TABLE_TITLE MPD_TAG_ITEM_TITLE -#define MPD_TABLE_TRACK MPD_TAG_ITEM_TRACK -#define MPD_TABLE_GENRE MPD_TAG_ITEM_GENRE -#define MPD_TABLE_DATE MPD_TAG_ITEM_DATE -#define MPD_TABLE_COMPOSER MPD_TAG_ITEM_COMPOSER -#define MPD_TABLE_PERFORMER MPD_TAG_ITEM_PERFORMER -#define MPD_TABLE_COMMENT MPD_TAG_ITEM_COMMENT -#define MPD_TABLE_DISC MPD_TAG_ITEM_DISC -#define MPD_TABLE_FILENAME MPD_TAG_ITEM_FILENAME - -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 type); - -/* 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); - -int mpd_sendAddIdCommand(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_sendRenameCommand(mpd_Connection *connection, const char *from, - const char *to); - -void mpd_sendShuffleCommand(mpd_Connection * connection); - -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 time); - -void mpd_sendSeekIdCommand(mpd_Connection * connection, int song, int time); - -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 depreacted */ -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); - -void mpd_sendUrlHandlersCommand(mpd_Connection * connection); - -char *mpd_getNextHandler(mpd_Connection * connection); - -void mpd_sendTagTypesCommand(mpd_Connection * connection); - -char *mpd_getNextTagType(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, const 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 type - * @param name - */ -void mpd_addConstraintSearch(mpd_Connection *connection, int type, const char *name); - -/** - * @param connection a #mpd_Connection - */ -void mpd_commitSearch(mpd_Connection *connection); - -/** - * @param connection a #mpd_Connection - * @param type The type to search for - * - * starts a search for fields... f.e. get a list of artists would be: - * @code - * mpd_startFieldSearch(connection, MPD_TAG_ITEM_ARTIST); - * mpd_commitSearch(connection); - * @endcode - * - * 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 one specified with type) and you need - * mpd_getNextTag to get the results - */ -void mpd_startFieldSearch(mpd_Connection *connection, int type); - -void mpd_startPlaylistSearch(mpd_Connection *connection, int exact); - -void mpd_startStatsSearch(mpd_Connection *connection); - -void mpd_sendPlaylistClearCommand(mpd_Connection *connection, const char *path); - -void mpd_sendPlaylistAddCommand(mpd_Connection *connection, - const char *playlist, const char *path); - -void mpd_sendPlaylistMoveCommand(mpd_Connection *connection, - const char *playlist, int from, int to); - -void mpd_sendPlaylistDeleteCommand(mpd_Connection *connection, - const char *playlist, int pos); -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/media_library.cpp b/src/media_library.cpp index 6ccd9f10..0ea535b4 100644 --- a/src/media_library.cpp +++ b/src/media_library.cpp @@ -185,11 +185,11 @@ void MediaLibrary::Update() Albums->Reset(); TagList list; locale_to_utf(Artists->Current()); - if (Config.media_lib_primary_tag == MPD_TAG_ITEM_ARTIST) + if (Config.media_lib_primary_tag == MPD_TAG_ARTIST) Mpd.GetAlbums(Artists->Current(), list); else { - Mpd.StartFieldSearch(MPD_TAG_ITEM_ALBUM); + Mpd.StartFieldSearch(MPD_TAG_ALBUM); Mpd.AddSearch(Config.media_lib_primary_tag, Artists->Current()); Mpd.CommitSearch(list); } @@ -198,9 +198,9 @@ void MediaLibrary::Update() if (Mpd.Version() > 13) { TagList noalbum_list; - Mpd.StartFieldSearch(MPD_TAG_ITEM_FILENAME); + Mpd.StartFieldSearch(MPD_TAG_FILE); Mpd.AddSearch(Config.media_lib_primary_tag, Artists->Current()); - Mpd.AddSearch(MPD_TAG_ITEM_ALBUM, ""); + Mpd.AddSearch(MPD_TAG_ALBUM, ""); Mpd.CommitSearch(noalbum_list); if (!noalbum_list.empty()) Albums->AddOption(std::make_pair("", SearchConstraints("", ""))); @@ -209,9 +209,9 @@ void MediaLibrary::Update() for (TagList::const_iterator it = list.begin(); it != list.end(); ++it) { TagList l; - Mpd.StartFieldSearch(MPD_TAG_ITEM_DATE); + Mpd.StartFieldSearch(MPD_TAG_DATE); Mpd.AddSearch(Config.media_lib_primary_tag, Artists->Current()); - Mpd.AddSearch(MPD_TAG_ITEM_ALBUM, *it); + Mpd.AddSearch(MPD_TAG_ALBUM, *it); Mpd.CommitSearch(l); if (l.empty()) { @@ -237,17 +237,17 @@ void MediaLibrary::Update() for (TagList::const_iterator i = artists.begin(); i != artists.end(); ++i) { TagList albums; - Mpd.StartFieldSearch(MPD_TAG_ITEM_ALBUM); + Mpd.StartFieldSearch(MPD_TAG_ALBUM); Mpd.AddSearch(Config.media_lib_primary_tag, *i); Mpd.CommitSearch(albums); for (TagList::const_iterator j = albums.begin(); j != albums.end(); ++j) { - if (Config.media_lib_primary_tag != MPD_TAG_ITEM_DATE) + if (Config.media_lib_primary_tag != MPD_TAG_DATE) { TagList years; - Mpd.StartFieldSearch(MPD_TAG_ITEM_DATE); + Mpd.StartFieldSearch(MPD_TAG_DATE); Mpd.AddSearch(Config.media_lib_primary_tag, *i); - Mpd.AddSearch(MPD_TAG_ITEM_ALBUM, *j); + Mpd.AddSearch(MPD_TAG_ALBUM, *j); Mpd.CommitSearch(years); if (!years.empty()) { @@ -292,9 +292,9 @@ void MediaLibrary::Update() } else { - Mpd.AddSearch(MPD_TAG_ITEM_ALBUM, Albums->Current().second.Album); + Mpd.AddSearch(MPD_TAG_ALBUM, Albums->Current().second.Album); if (!Albums->Current().second.Album.empty()) // for - Mpd.AddSearch(MPD_TAG_ITEM_DATE, Albums->Current().second.Year); + Mpd.AddSearch(MPD_TAG_DATE, Albums->Current().second.Year); } Mpd.CommitSearch(list); diff --git a/src/mpdpp.cpp b/src/mpdpp.cpp index 9534d4f4..ae4f19a0 100644 --- a/src/mpdpp.cpp +++ b/src/mpdpp.cpp @@ -50,18 +50,18 @@ Connection::Connection() : itsConnection(0), Connection::~Connection() { if (itsConnection) - mpd_closeConnection(itsConnection); + mpd_connection_free(itsConnection); if (itsOldStatus) - mpd_freeStatus(itsOldStatus); + mpd_status_free(itsOldStatus); if (itsCurrentStatus) - mpd_freeStatus(itsCurrentStatus); + mpd_status_free(itsCurrentStatus); } bool Connection::Connect() { if (!isConnected && !itsConnection) { - itsConnection = mpd_newConnection(itsHost.c_str(), itsPort, itsTimeout); + itsConnection = mpd_connection_new(itsHost.c_str(), itsPort, itsTimeout*1000 /* timeout is in ms now */); isConnected = 1; if (CheckForErrors()) return false; @@ -81,11 +81,11 @@ bool Connection::Connected() const void Connection::Disconnect() { if (itsConnection) - mpd_closeConnection(itsConnection); + mpd_connection_free(itsConnection); if (itsOldStatus) - mpd_freeStatus(itsOldStatus); + mpd_status_free(itsOldStatus); if (itsCurrentStatus) - mpd_freeStatus(itsCurrentStatus); + mpd_status_free(itsCurrentStatus); itsConnection = 0; itsCurrentStatus = 0; itsOldStatus = 0; @@ -96,7 +96,10 @@ void Connection::Disconnect() float Connection::Version() const { - return itsConnection ? itsConnection->version[1] + itsConnection->version[2]*0.1 : 0; + if (!isConnected) + return 0; + const unsigned *version = mpd_connection_get_server_version(itsConnection); + return version[1] + version[2]*0.1; } void Connection::SetHostname(const std::string &host) @@ -111,10 +114,9 @@ void Connection::SetHostname(const std::string &host) itsHost = host; } -void Connection::SendPassword() const +bool Connection::SendPassword() const { - mpd_sendPasswordCommand(itsConnection, itsPassword.c_str()); - mpd_finishCommand(itsConnection); + return mpd_run_password(itsConnection, itsPassword.c_str()); } void Connection::SetStatusUpdater(StatusUpdater updater, void *data) @@ -140,13 +142,12 @@ void Connection::UpdateStatus() return; if (itsOldStatus) - mpd_freeStatus(itsOldStatus); + mpd_status_free(itsOldStatus); itsOldStatus = itsCurrentStatus; itsCurrentStatus = 0; - mpd_sendStatusCommand(itsConnection); - itsCurrentStatus = mpd_getStatus(itsConnection); + itsCurrentStatus = mpd_run_status(itsConnection); if (!itsMaxPlaylistLength) itsMaxPlaylistLength = GetPlaylistLength(); @@ -174,175 +175,132 @@ void Connection::UpdateStatus() } else { - itsChanges.Playlist = itsOldStatus->playlist != itsCurrentStatus->playlist; - itsChanges.SongID = itsOldStatus->songid != itsCurrentStatus->songid; - itsChanges.Database = itsOldStatus->updatingDb && !itsCurrentStatus->updatingDb; - itsChanges.DBUpdating = itsOldStatus->updatingDb != itsCurrentStatus->updatingDb; - itsChanges.Volume = itsOldStatus->volume != itsCurrentStatus->volume; - itsChanges.ElapsedTime = itsOldStatus->elapsedTime != itsCurrentStatus->elapsedTime; - itsChanges.Crossfade = itsOldStatus->crossfade != itsCurrentStatus->crossfade; - itsChanges.Random = itsOldStatus->random != itsCurrentStatus->random; - itsChanges.Repeat = itsOldStatus->repeat != itsCurrentStatus->repeat; - itsChanges.Single = itsOldStatus->single != itsCurrentStatus->single; - itsChanges.Consume = itsOldStatus->consume != itsCurrentStatus->consume; - itsChanges.PlayerState = itsOldStatus->state != itsCurrentStatus->state; + itsChanges.Playlist = mpd_status_get_queue_version(itsOldStatus) != mpd_status_get_queue_version(itsCurrentStatus); + itsChanges.SongID = mpd_status_get_song_id(itsOldStatus) != mpd_status_get_song_id(itsCurrentStatus); + itsChanges.Database = mpd_status_get_update_id(itsOldStatus) != mpd_status_get_update_id(itsCurrentStatus); + itsChanges.DBUpdating = itsChanges.Database; + itsChanges.Volume = mpd_status_get_volume(itsOldStatus) != mpd_status_get_volume(itsCurrentStatus); + itsChanges.ElapsedTime = mpd_status_get_elapsed_time(itsOldStatus) != mpd_status_get_elapsed_time(itsCurrentStatus); + itsChanges.Crossfade = mpd_status_get_crossfade(itsOldStatus) != mpd_status_get_crossfade(itsCurrentStatus); + itsChanges.Random = mpd_status_get_random(itsOldStatus) != mpd_status_get_random(itsCurrentStatus); + itsChanges.Repeat = mpd_status_get_repeat(itsOldStatus) != mpd_status_get_repeat(itsCurrentStatus); + itsChanges.Single = mpd_status_get_single(itsOldStatus) != mpd_status_get_single(itsCurrentStatus); + itsChanges.Consume = mpd_status_get_consume(itsOldStatus) != mpd_status_get_consume(itsCurrentStatus); + itsChanges.PlayerState = mpd_status_get_state(itsOldStatus) != mpd_status_get_state(itsCurrentStatus); itsChanges.StatusFlags = itsChanges.Repeat || itsChanges.Random || itsChanges.Single || itsChanges.Consume || itsChanges.Crossfade || itsChanges.DBUpdating; } itsUpdater(this, itsChanges, itsErrorHandlerUserdata); } } -void Connection::UpdateDirectory(const std::string &path) +bool Connection::UpdateDirectory(const std::string &path) { - if (isConnected) - { - mpd_sendUpdateCommand(itsConnection, path.c_str()); - mpd_finishCommand(itsConnection); - if (!itsConnection->error && itsUpdater) - { - itsCurrentStatus->updatingDb = 1; - StatusChanges ch; - ch.DBUpdating = 1; - ch.StatusFlags = 1; - itsUpdater(this, ch, itsErrorHandlerUserdata); - } - } + if (!isConnected) + return false; + + if (!mpd_run_update(itsConnection, path.c_str())) + return false; + UpdateStatus(); + return true; } -void Connection::Execute(const std::string &command) const +bool Connection::Execute(const std::string &command) const { - if (isConnected) - { - mpd_executeCommand(itsConnection, command.c_str()); - if (!isCommandsListEnabled) - mpd_finishCommand(itsConnection); - } + if (!isConnected) + return false; + mpd_send_command(itsConnection, command.c_str()); + return isCommandsListEnabled || mpd_response_finish(itsConnection); } void Connection::Play() const { - if (isConnected) - PlayID(-1); + if (!isConnected) + return; + (isCommandsListEnabled ? mpd_send_play : mpd_run_play)(itsConnection); } void Connection::Play(int pos) const { - if (isConnected) - { - mpd_sendPlayCommand(itsConnection, pos); - if (!isCommandsListEnabled) - mpd_finishCommand(itsConnection); - } + if (!isConnected) + return; + (isCommandsListEnabled ? mpd_send_play_pos : mpd_run_play_pos)(itsConnection, pos); } void Connection::PlayID(int id) const { - if (isConnected) - { - mpd_sendPlayIdCommand(itsConnection, id); - if (!isCommandsListEnabled) - mpd_finishCommand(itsConnection); - } + if (!isConnected) + return; + (isCommandsListEnabled ? mpd_send_play_id : mpd_run_play_id)(itsConnection, id); } void Connection::Pause() const { - if (isConnected) - { - mpd_sendPauseCommand(itsConnection, itsCurrentStatus->state != psPause); - if (!isCommandsListEnabled) - mpd_finishCommand(itsConnection); - } + if (!isConnected) + return; + (isCommandsListEnabled ? mpd_send_toggle_pause : mpd_run_toggle_pause)(itsConnection); } void Connection::Stop() const { - if (isConnected) - { - mpd_sendStopCommand(itsConnection); - if (!isCommandsListEnabled) - mpd_finishCommand(itsConnection); - } + if (!isConnected) + return; + (isCommandsListEnabled ? mpd_send_stop : mpd_run_stop)(itsConnection); } void Connection::Next() const { - if (isConnected) - { - mpd_sendNextCommand(itsConnection); - if (!isCommandsListEnabled) - mpd_finishCommand(itsConnection); - } + if (!isConnected) + return; + (isCommandsListEnabled ? mpd_send_next : mpd_run_next)(itsConnection); } void Connection::Prev() const { - if (isConnected) - { - mpd_sendPrevCommand(itsConnection); - if (!isCommandsListEnabled) - mpd_finishCommand(itsConnection); - } + if (!isConnected) + return; + (isCommandsListEnabled ? mpd_send_previous : mpd_run_previous)(itsConnection); } -void Connection::Move(int from, int to) const +void Connection::Move(unsigned from, unsigned to) const { - if (isConnected) - { - mpd_sendMoveCommand(itsConnection, from, to); - if (!isCommandsListEnabled) - mpd_finishCommand(itsConnection); - } + if (!isConnected) + return; + (isCommandsListEnabled ? mpd_send_move : mpd_run_move)(itsConnection, from, to); } -void Connection::Swap(int from, int to) const +void Connection::Swap(unsigned from, unsigned to) const { - if (isConnected) - { - mpd_sendSwapCommand(itsConnection, from, to); - if (!isCommandsListEnabled) - mpd_finishCommand(itsConnection); - } + if (!isConnected) + return; + (isCommandsListEnabled ? mpd_send_swap : mpd_run_swap)(itsConnection, from, to); } -void Connection::Seek(int where) const +void Connection::Seek(unsigned where) const { - if (isConnected) - { - mpd_sendSeekCommand(itsConnection, itsCurrentStatus->song, where); - if (!isCommandsListEnabled) - mpd_finishCommand(itsConnection); - } + if (!isConnected) + return; + (isCommandsListEnabled ? mpd_send_seek_pos : mpd_run_seek_pos)(itsConnection, Mpd.GetCurrentSongPos(), where); } void Connection::Shuffle() const { - if (isConnected) - { - mpd_sendShuffleCommand(itsConnection); - if (!isCommandsListEnabled) - mpd_finishCommand(itsConnection); - } + if (!isConnected) + return; + (isCommandsListEnabled ? mpd_send_shuffle : mpd_run_shuffle)(itsConnection); } void Connection::ClearPlaylist() const { - if (isConnected) - { - mpd_sendClearCommand(itsConnection); - if (!isCommandsListEnabled) - mpd_finishCommand(itsConnection); - } + if (!isConnected) + return; + (isCommandsListEnabled ? mpd_send_clear : mpd_run_clear)(itsConnection); } void Connection::ClearPlaylist(const std::string &playlist) const { - if (isConnected) - { - mpd_sendPlaylistClearCommand(itsConnection, playlist.c_str()); - if (!isCommandsListEnabled) - mpd_finishCommand(itsConnection); - } + if (!isConnected) + return; + (isCommandsListEnabled ? mpd_send_playlist_clear : mpd_run_playlist_clear)(itsConnection, playlist.c_str()); } void Connection::AddToPlaylist(const std::string &path, const Song &s) const @@ -353,55 +311,37 @@ void Connection::AddToPlaylist(const std::string &path, const Song &s) const void Connection::AddToPlaylist(const std::string &path, const std::string &file) const { - if (isConnected) - { - mpd_sendPlaylistAddCommand(itsConnection, path.c_str(), file.c_str()); - if (!isCommandsListEnabled) - mpd_finishCommand(itsConnection); - } + if (!isConnected) + return; + (isCommandsListEnabled ? mpd_send_playlist_add : mpd_run_playlist_add)(itsConnection, path.c_str(), file.c_str()); } void Connection::Move(const std::string &path, int from, int to) const { - if (isConnected) - { - mpd_sendPlaylistMoveCommand(itsConnection, path.c_str(), from, to); - if (!isCommandsListEnabled) - mpd_finishCommand(itsConnection); - } + if (!isConnected) + return; + mpd_send_playlist_move(itsConnection, path.c_str(), from, to); + if (!isCommandsListEnabled) + mpd_response_finish(itsConnection); } void Connection::Rename(const std::string &from, const std::string &to) const { - if (isConnected) - { - mpd_sendRenameCommand(itsConnection, from.c_str(), to.c_str()); - if (!isCommandsListEnabled) - mpd_finishCommand(itsConnection); - } + if (!isConnected) + return; + (isCommandsListEnabled ? mpd_send_rename : mpd_run_rename)(itsConnection, from.c_str(), to.c_str()); } -void Connection::GetPlaylistChanges(long long id, SongList &v) const +void Connection::GetPlaylistChanges(unsigned version, SongList &v) const { if (isConnected) { - if (id < 0) - { - id = 0; + if (!version) v.reserve(GetPlaylistLength()); - } - mpd_sendPlChangesCommand(itsConnection, id); - while (mpd_InfoEntity *item = mpd_getNextInfoEntity(itsConnection)) - { - if (item->type == MPD_INFO_ENTITY_TYPE_SONG) - { - Song *s = new Song(item->info.song, 1); - item->info.song = 0; - v.push_back(s); - } - mpd_freeInfoEntity(item); - } - mpd_finishCommand(itsConnection); + mpd_send_queue_changes_meta(itsConnection, version); + while (mpd_song *s = mpd_recv_song(itsConnection)) + v.push_back(new Song(s, 1)); + mpd_response_finish(itsConnection); } } @@ -409,12 +349,10 @@ Song Connection::GetSong(const std::string &path) const { if (isConnected) { - mpd_sendListallInfoCommand(itsConnection, path.c_str()); - mpd_InfoEntity *item = mpd_getNextInfoEntity(itsConnection); - Song result = item->info.song; - item->info.song = 0; - mpd_freeInfoEntity(item); - mpd_finishCommand(itsConnection); + mpd_send_list_all_meta(itsConnection, path.c_str()); + mpd_song *s = mpd_recv_song(itsConnection); + Song result(s); + mpd_response_finish(itsConnection); return result; } else @@ -423,112 +361,67 @@ Song Connection::GetSong(const std::string &path) const int Connection::GetCurrentSongPos() const { - return isConnected && itsCurrentStatus ? (itsCurrentStatus->state == psPlay || itsCurrentStatus->state == psPause ? itsCurrentStatus->song : -1) : -1; + return itsCurrentStatus && isPlaying() ? mpd_status_get_song_pos(itsCurrentStatus) : -1; } Song Connection::GetCurrentSong() const { - if (isConnected && (GetState() == psPlay || GetState() == psPause)) - { - mpd_sendCurrentSongCommand(itsConnection); - if (mpd_InfoEntity *item = mpd_getNextInfoEntity(itsConnection)) - { - Song result = item->info.song; - item->info.song = 0; - mpd_freeInfoEntity(item); - return result; - } - else - return Song(); - mpd_finishCommand(itsConnection); - } - else - return Song(); + return Song(isConnected && isPlaying() ? mpd_run_current_song(itsConnection) : 0); } void Connection::GetPlaylistContent(const std::string &path, SongList &v) const { if (isConnected) { - mpd_sendListPlaylistInfoCommand(itsConnection, path.c_str()); - while (mpd_InfoEntity *item = mpd_getNextInfoEntity(itsConnection)) - { - if (item->type == MPD_INFO_ENTITY_TYPE_SONG) - { - Song *s = new Song(item->info.song); - item->info.song = 0; - v.push_back(s); - } - mpd_freeInfoEntity(item); - } - mpd_finishCommand(itsConnection); + mpd_send_list_playlist_meta(itsConnection, path.c_str()); + while (mpd_song *s = mpd_recv_song(itsConnection)) + v.push_back(new Song(s)); + mpd_response_finish(itsConnection); } } void Connection::SetRepeat(bool mode) const { - if (isConnected) - { - mpd_sendRepeatCommand(itsConnection, mode); - if (!isCommandsListEnabled) - mpd_finishCommand(itsConnection); - } + if (!isConnected) + return; + (isCommandsListEnabled ? mpd_send_repeat : mpd_run_repeat)(itsConnection, mode); } void Connection::SetRandom(bool mode) const { - if (isConnected) - { - mpd_sendRandomCommand(itsConnection, mode); - if (!isCommandsListEnabled) - mpd_finishCommand(itsConnection); - } + if (!isConnected) + return; + (isCommandsListEnabled ? mpd_send_random : mpd_run_random)(itsConnection, mode); } void Connection::SetSingle(bool mode) const { - if (isConnected) - { - mpd_sendSingleCommand(itsConnection, mode); - if (!isCommandsListEnabled) - mpd_finishCommand(itsConnection); - } + if (!isConnected) + return; + (isCommandsListEnabled ? mpd_send_single : mpd_run_single)(itsConnection, mode); } void Connection::SetConsume(bool mode) const { - if (isConnected) + if (!isConnected) + return; + (isCommandsListEnabled ? mpd_send_consume : mpd_run_consume)(itsConnection, mode); +} + +void Connection::SetVolume(unsigned vol) +{ + if (isConnected && vol <= 100) { - mpd_sendConsumeCommand(itsConnection, mode); - if (!isCommandsListEnabled) - mpd_finishCommand(itsConnection); + if (mpd_run_set_volume(itsConnection, vol) && itsUpdater) + UpdateStatus(); } } -void Connection::SetVolume(int vol) +void Connection::SetCrossfade(unsigned crossfade) const { - if (isConnected && vol >= 0 && vol <= 100) - { - mpd_sendSetvolCommand(itsConnection, vol); - mpd_finishCommand(itsConnection); - if (!itsConnection->error && itsUpdater) - { - itsCurrentStatus->volume = vol; - StatusChanges ch; - ch.Volume = 1; - itsUpdater(this, ch, itsStatusUpdaterUserdata); - } - } -} - -void Connection::SetCrossfade(int crossfade) const -{ - if (isConnected) - { - mpd_sendCrossfadeCommand(itsConnection, crossfade); - if (!isCommandsListEnabled) - mpd_finishCommand(itsConnection); - } + if (!isConnected) + return; + (isCommandsListEnabled ? mpd_send_crossfade : mpd_run_crossfade)(itsConnection, crossfade); } int Connection::AddSong(const std::string &path) @@ -538,17 +431,17 @@ int Connection::AddSong(const std::string &path) { if (GetPlaylistLength() < itsMaxPlaylistLength) { - id = mpd_sendAddIdCommand(itsConnection, path.c_str()); + id = mpd_send_add_id(itsConnection, path.c_str()); if (!isCommandsListEnabled) { - mpd_finishCommand(itsConnection); + mpd_response_finish(itsConnection); UpdateStatus(); } else id = 0; } else if (itsErrorHandler) - itsErrorHandler(this, MPD_ACK_ERROR_PLAYLIST_MAX, Message::FullPlaylist, itsErrorHandlerUserdata); + itsErrorHandler(this, MPD_SERVER_ERROR_PLAYLIST_MAX, Message::FullPlaylist, itsErrorHandlerUserdata); } return id; } @@ -562,8 +455,8 @@ void Connection::Add(const std::string &path) const { if (!isConnected) return; - mpd_sendAddCommand(itsConnection, path.c_str()); - mpd_finishCommand(itsConnection); + mpd_send_add(itsConnection, path.c_str()); + mpd_response_finish(itsConnection); } bool Connection::AddRandomSongs(size_t number) @@ -573,13 +466,13 @@ bool Connection::AddRandomSongs(size_t number) TagList files; - mpd_sendListallCommand(itsConnection, "/"); - while (char *file = mpd_getNextTag(itsConnection, MPD_TAG_ITEM_FILENAME)) + mpd_send_list_all(itsConnection, "/"); + while (mpd_pair *item = mpd_recv_pair_tag(itsConnection, MPD_TAG_FILE)) { - files.push_back(file); - delete [] file; + files.push_back(item->value); + mpd_return_pair(itsConnection, item); } - mpd_finishCommand(itsConnection); + mpd_response_finish(itsConnection); if (number > files.size()) { @@ -600,41 +493,36 @@ bool Connection::AddRandomSongs(size_t number) return true; } -void Connection::Delete(int pos) const +void Connection::Delete(unsigned pos) const { - if (isConnected) - { - mpd_sendDeleteCommand(itsConnection, pos); - if (!isCommandsListEnabled) - mpd_finishCommand(itsConnection); - } + if (!isConnected) + return; + mpd_send_delete(itsConnection, pos); + if (!isCommandsListEnabled) + mpd_response_finish(itsConnection); } -void Connection::DeleteID(int id) const +void Connection::DeleteID(unsigned id) const { - if (isConnected) - { - mpd_sendDeleteIdCommand(itsConnection, id); - if (!isCommandsListEnabled) - mpd_finishCommand(itsConnection); - } + if (!isConnected) + return; + mpd_send_delete_id(itsConnection, id); + if (!isCommandsListEnabled) + mpd_response_finish(itsConnection); } -void Connection::Delete(const std::string &playlist, int pos) const +void Connection::Delete(const std::string &playlist, unsigned pos) const { - if (isConnected) - { - mpd_sendPlaylistDeleteCommand(itsConnection, playlist.c_str(), pos); - if (!isCommandsListEnabled) - mpd_finishCommand(itsConnection); - } + if (!isConnected) + return; + (isCommandsListEnabled ? mpd_send_playlist_delete : mpd_run_playlist_delete)(itsConnection, playlist.c_str(), pos); } void Connection::StartCommandsList() { if (isConnected) { - mpd_sendCommandListBegin(itsConnection); + mpd_command_list_begin(itsConnection, 1); isCommandsListEnabled = 1; } @@ -644,11 +532,11 @@ bool Connection::CommitCommandsList() { if (isConnected) { - mpd_sendCommandListEnd(itsConnection); - mpd_finishCommand(itsConnection); + mpd_command_list_end(itsConnection); + mpd_response_finish(itsConnection); UpdateStatus(); if (GetPlaylistLength() == itsMaxPlaylistLength && itsErrorHandler) - itsErrorHandler(this, MPD_ACK_ERROR_PLAYLIST_MAX, Message::FullPlaylist, itsErrorHandlerUserdata); + itsErrorHandler(this, MPD_SERVER_ERROR_PLAYLIST_MAX, Message::FullPlaylist, itsErrorHandlerUserdata); isCommandsListEnabled = 0; } return !CheckForErrors(); @@ -656,21 +544,19 @@ bool Connection::CommitCommandsList() void Connection::DeletePlaylist(const std::string &name) const { - if (isConnected) - { - mpd_sendRmCommand(itsConnection, name.c_str()); - if (!isCommandsListEnabled) - mpd_finishCommand(itsConnection); - } + if (!isConnected) + return; + (isCommandsListEnabled ? mpd_send_rm : mpd_run_rm)(itsConnection, name.c_str()); } bool Connection::SavePlaylist(const std::string &name) const { if (isConnected) { - mpd_sendSaveCommand(itsConnection, name.c_str()); - mpd_finishCommand(itsConnection); - return !(itsConnection->error == MPD_ERROR_ACK && itsConnection->errorCode == MPD_ACK_ERROR_EXIST); + mpd_send_save(itsConnection, name.c_str()); + mpd_response_finish(itsConnection); + return !(mpd_connection_get_error(itsConnection) == MPD_ERROR_SERVER + && mpd_connection_get_server_error(itsConnection) == MPD_SERVER_ERROR_EXIST); } else return false; @@ -680,29 +566,29 @@ void Connection::GetPlaylists(TagList &v) const { if (isConnected) { + ItemList list; GetDirectory("/", list); for (ItemList::const_iterator it = list.begin(); it != list.end(); ++it) - { if (it->type == itPlaylist) v.push_back(it->name); - } FreeItemList(list); } } -void Connection::GetList(TagList &v, mpd_TagItems type) const +void Connection::GetList(TagList &v, mpd_tag_type type) const { if (isConnected) { - mpd_sendListCommand(itsConnection, type, 0); - while (char *item = mpd_getNextTag(itsConnection, type)) + mpd_search_db_tags(itsConnection, type); + mpd_search_commit(itsConnection); + while (mpd_pair *item = mpd_recv_pair_tag(itsConnection, type)) { - if (item[0] != 0) // do not push empty item - v.push_back(item); - delete [] item; + if (item->value[0] != 0) // do not push empty item + v.push_back(item->value); + mpd_return_pair(itsConnection, item); } - mpd_finishCommand(itsConnection); + mpd_response_finish(itsConnection); } } @@ -710,58 +596,52 @@ void Connection::GetAlbums(const std::string &artist, TagList &v) const { if (isConnected) { - mpd_sendListCommand(itsConnection, MPD_TABLE_ALBUM, artist.empty() ? 0 : artist.c_str()); - - while (char *item = mpd_getNextAlbum(itsConnection)) + mpd_search_db_tags(itsConnection, MPD_TAG_ALBUM); + if (!artist.empty()) + mpd_search_add_constraint(itsConnection, MPD_TAG_ARTIST, artist.c_str()); + mpd_search_commit(itsConnection); + while (mpd_pair *item = mpd_recv_pair_tag(itsConnection, MPD_TAG_ALBUM)) { - if (item[0] != 0) // do not push empty item - v.push_back(item); - delete [] item; + if (item->value[0] != 0) // do not push empty item + v.push_back(item->value); + mpd_return_pair(itsConnection, item); } - mpd_finishCommand(itsConnection); + mpd_response_finish(itsConnection); } } void Connection::StartSearch(bool exact_match) const { if (isConnected) - mpd_startSearch(itsConnection, exact_match); + mpd_search_db_songs(itsConnection, exact_match); } -void Connection::StartFieldSearch(mpd_TagItems item) +void Connection::StartFieldSearch(mpd_tag_type item) { if (isConnected) { itsSearchedField = item; - mpd_startFieldSearch(itsConnection, item); + mpd_search_db_tags(itsConnection, item); } } -void Connection::AddSearch(mpd_TagItems item, const std::string &str) const +void Connection::AddSearch(mpd_tag_type item, const std::string &str) const { // mpd version < 0.14.* doesn't support empty search constraints if (Version() < 14 && str.empty()) return; if (isConnected) - mpd_addConstraintSearch(itsConnection, item, str.c_str()); + mpd_search_add_constraint(itsConnection, item, str.c_str()); } void Connection::CommitSearch(SongList &v) const { if (isConnected) { - mpd_commitSearch(itsConnection); - while (mpd_InfoEntity *item = mpd_getNextInfoEntity(itsConnection)) - { - if (item->type == MPD_INFO_ENTITY_TYPE_SONG) - { - Song *s = new Song(item->info.song); - item->info.song = 0; - v.push_back(s); - } - mpd_freeInfoEntity(item); - } - mpd_finishCommand(itsConnection); + mpd_search_commit(itsConnection); + while (mpd_song *s = mpd_recv_song(itsConnection)) + v.push_back(new Song(s)); + mpd_response_finish(itsConnection); } } @@ -769,14 +649,14 @@ void Connection::CommitSearch(TagList &v) const { if (isConnected) { - mpd_commitSearch(itsConnection); - while (char *tag = mpd_getNextTag(itsConnection, itsSearchedField)) + mpd_search_commit(itsConnection); + while (mpd_pair *tag = mpd_recv_pair_tag(itsConnection, itsSearchedField)) { - if (tag[0] != 0) // do not push empty item - v.push_back(tag); - delete [] tag; + if (tag->value[0] != 0) // do not push empty item + v.push_back(tag->value); + mpd_return_pair(itsConnection, tag); } - mpd_finishCommand(itsConnection); + mpd_response_finish(itsConnection); } } @@ -784,30 +664,33 @@ void Connection::GetDirectory(const std::string &path, ItemList &v) const { if (isConnected) { - mpd_sendLsInfoCommand(itsConnection, path.c_str()); - while (mpd_InfoEntity *item = mpd_getNextInfoEntity(itsConnection)) + mpd_send_list_meta(itsConnection, path.c_str()); + while (mpd_entity *item = mpd_recv_entity(itsConnection)) { Item i; - switch (item->type) + switch (mpd_entity_get_type(item)) { - case MPD_INFO_ENTITY_TYPE_DIRECTORY: - i.name = item->info.directory->path; + case MPD_ENTITY_TYPE_DIRECTORY: + i.name = mpd_directory_get_path(mpd_entity_get_directory(item)); i.type = itDirectory; - break; - case MPD_INFO_ENTITY_TYPE_SONG: - i.song = new Song(item->info.song); - item->info.song = 0; + goto WRITE; + case MPD_ENTITY_TYPE_SONG: + i.song = new Song(mpd_song_dup(mpd_entity_get_song(item))); i.type = itSong; - break; - case MPD_INFO_ENTITY_TYPE_PLAYLISTFILE: - i.name = item->info.playlistFile->path; + goto WRITE; + case MPD_ENTITY_TYPE_PLAYLIST: + i.name = mpd_playlist_get_path(mpd_entity_get_playlist(item)); i.type = itPlaylist; + goto WRITE; + WRITE: + v.push_back(i); + break; + default: break; } - v.push_back(i); - mpd_freeInfoEntity(item); + mpd_entity_free(item); } - mpd_finishCommand(itsConnection); + mpd_response_finish(itsConnection); } } @@ -815,18 +698,10 @@ void Connection::GetDirectoryRecursive(const std::string &path, SongList &v) con { if (isConnected) { - mpd_sendListallInfoCommand(itsConnection, path.c_str()); - while (mpd_InfoEntity *item = mpd_getNextInfoEntity(itsConnection)) - { - if (item->type == MPD_INFO_ENTITY_TYPE_SONG) - { - Song *s = new Song(item->info.song); - item->info.song = 0; - v.push_back(s); - } - mpd_freeInfoEntity(item); - } - mpd_finishCommand(itsConnection); + mpd_send_list_all_meta(itsConnection, path.c_str()); + while (mpd_song *s = mpd_recv_song(itsConnection)) + v.push_back(new Song(s)); + mpd_response_finish(itsConnection); } } @@ -834,18 +709,10 @@ void Connection::GetSongs(const std::string &path, SongList &v) const { if (isConnected) { - mpd_sendLsInfoCommand(itsConnection, path.c_str()); - while (mpd_InfoEntity *item = mpd_getNextInfoEntity(itsConnection)) - { - if (item->type == MPD_INFO_ENTITY_TYPE_SONG) - { - Song *s = new Song(item->info.song); - item->info.song = 0; - v.push_back(s); - } - mpd_freeInfoEntity(item); - } - mpd_finishCommand(itsConnection); + mpd_send_list_meta(itsConnection, path.c_str()); + while (mpd_song *s = mpd_recv_song(itsConnection)) + v.push_back(new Song(s)); + mpd_response_finish(itsConnection); } } @@ -853,14 +720,13 @@ void Connection::GetDirectories(const std::string &path, TagList &v) const { if (isConnected) { - mpd_sendLsInfoCommand(itsConnection, path.c_str()); - while (mpd_InfoEntity *item = mpd_getNextInfoEntity(itsConnection)) + mpd_send_list_all(itsConnection, path.c_str()); + while (mpd_directory *dir = mpd_recv_directory(itsConnection)) { - if (item->type == MPD_INFO_ENTITY_TYPE_DIRECTORY) - v.push_back(item->info.directory->path); - mpd_freeInfoEntity(item); + v.push_back(mpd_directory_get_path(dir)); + mpd_directory_free(dir); } - mpd_finishCommand(itsConnection); + mpd_response_finish(itsConnection); } } @@ -868,59 +734,46 @@ void Connection::GetOutputs(OutputList &v) const { if (!isConnected) return; - mpd_sendOutputsCommand(itsConnection); - while (mpd_OutputEntity *output = mpd_getNextOutput(itsConnection)) + mpd_send_outputs(itsConnection); + while (mpd_output *output = mpd_recv_output(itsConnection)) { - v.push_back(std::make_pair(output->name, output->enabled)); - mpd_freeOutputElement(output); + v.push_back(std::make_pair(mpd_output_get_name(output), mpd_output_get_enabled(output))); + mpd_output_free(output); } - mpd_finishCommand(itsConnection); + mpd_response_finish(itsConnection); } bool Connection::EnableOutput(int id) { if (!isConnected) return false; - mpd_sendEnableOutputCommand(itsConnection, id); - mpd_finishCommand(itsConnection); - return !CheckForErrors(); + return mpd_run_enable_output(itsConnection, id); } bool Connection::DisableOutput(int id) { if (!isConnected) return false; - mpd_sendDisableOutputCommand(itsConnection, id); - mpd_finishCommand(itsConnection); - return !CheckForErrors(); + return mpd_run_disable_output(itsConnection, id); } int Connection::CheckForErrors() { - itsErrorCode = 0; - if (itsConnection->error) + if ((itsErrorCode = mpd_connection_get_error(itsConnection)) != MPD_ERROR_SUCCESS) { - itsErrorMessage = itsConnection->errorStr; - if (itsConnection->error == MPD_ERROR_ACK) + itsErrorMessage = mpd_connection_get_error_message(itsConnection); + if (itsErrorCode == MPD_ERROR_SERVER) { // this is to avoid setting too small max size as we check it before fetching current status // setting real max playlist length is in UpdateStatus() - if (itsConnection->errorCode == MPD_ACK_ERROR_PLAYLIST_MAX && itsMaxPlaylistLength == size_t(-1)) + itsErrorCode = mpd_connection_get_server_error(itsConnection); + if (itsErrorCode == MPD_SERVER_ERROR_PLAYLIST_MAX && itsMaxPlaylistLength == size_t(-1)) itsMaxPlaylistLength = 0; - - if (itsErrorHandler) - itsErrorHandler(this, itsConnection->errorCode, itsConnection->errorStr, itsErrorHandlerUserdata); - itsErrorCode = itsConnection->errorCode; } - else - { - if (itsErrorHandler) - itsErrorHandler(this, itsConnection->error, itsConnection->errorStr, itsErrorHandlerUserdata); - itsErrorCode = itsConnection->error; - Disconnect(); // the rest of errors are fatal to connection - } - if (itsConnection) - mpd_clearError(itsConnection); + if (!mpd_connection_clear_error(itsConnection)) + Disconnect(); + if (itsErrorHandler) + itsErrorHandler(this, itsErrorCode, itsErrorMessage.c_str(), itsErrorHandlerUserdata); } return itsErrorCode; } diff --git a/src/mpdpp.h b/src/mpdpp.h index 1fecf015..6f6a5d71 100644 --- a/src/mpdpp.h +++ b/src/mpdpp.h @@ -23,7 +23,7 @@ #include -#include "libmpdclient.h" +#include #include "song.h" namespace MPD @@ -96,14 +96,14 @@ namespace MPD void SetPort(int port) { itsPort = port; } void SetTimeout(int timeout) { itsTimeout = timeout; } void SetPassword(const std::string &password) { itsPassword = password; } - void SendPassword() const; + bool SendPassword() const; void SetStatusUpdater(StatusUpdater, void *); void SetErrorHandler(ErrorHandler, void *); void UpdateStatus(); - void UpdateDirectory(const std::string &); + bool UpdateDirectory(const std::string &); - void Execute(const std::string &) const; + bool Execute(const std::string &) const; void Play() const; void Play(int) const; @@ -112,31 +112,31 @@ namespace MPD void Stop() const; void Next() const; void Prev() const; - void Move(int, int) const; - void Swap(int, int) const; - void Seek(int) const; + void Move(unsigned, unsigned) const; + void Swap(unsigned, unsigned) const; + void Seek(unsigned) const; void Shuffle() const; void ClearPlaylist() const; bool isPlaying() const { return GetState() > psStop; } - PlayerState GetState() const { return isConnected && itsCurrentStatus ? PlayerState(itsCurrentStatus->state) : psUnknown; } - bool GetRepeat() const { return isConnected && itsCurrentStatus ? itsCurrentStatus->repeat : 0; } - bool GetRandom() const { return isConnected && itsCurrentStatus ? itsCurrentStatus->random : 0; } - bool GetSingle() const { return isConnected && itsCurrentStatus ? itsCurrentStatus->single : 0; } - bool GetConsume() const { return isConnected && itsCurrentStatus ? itsCurrentStatus->consume : 0; } - bool GetDBIsUpdating() const { return isConnected && itsCurrentStatus ? itsCurrentStatus->updatingDb : 0; } - int GetVolume() const { return isConnected && itsCurrentStatus ? itsCurrentStatus->volume : -1; } - int GetCrossfade() const { return isConnected && itsCurrentStatus ? itsCurrentStatus->crossfade : -1; } - long long GetPlaylistID() const { return isConnected && itsCurrentStatus ? itsCurrentStatus->playlist : -1; } - long long GetOldPlaylistID() const { return isConnected && itsOldStatus ? itsOldStatus->playlist : -1; } - int GetElapsedTime() const { return isConnected && itsCurrentStatus ? itsCurrentStatus->elapsedTime : -1; } - int GetTotalTime() const { return isConnected && itsCurrentStatus ? itsCurrentStatus->totalTime : 0; } - unsigned GetBitrate() const { return isConnected && itsCurrentStatus ? itsCurrentStatus->bitRate : 0; } + PlayerState GetState() const{ return itsCurrentStatus ? PlayerState(mpd_status_get_state(itsCurrentStatus)) : psUnknown; } + bool GetRepeat() const { return itsCurrentStatus ? mpd_status_get_repeat(itsCurrentStatus) : 0; } + bool GetRandom() const { return itsCurrentStatus ? mpd_status_get_random(itsCurrentStatus) : 0; } + bool GetSingle() const { return itsCurrentStatus ? mpd_status_get_single(itsCurrentStatus) : 0; } + bool GetConsume() const { return itsCurrentStatus ? mpd_status_get_consume(itsCurrentStatus) : 0; } + bool GetDBIsUpdating() const { return itsCurrentStatus ? mpd_status_get_update_id(itsCurrentStatus) : 0; } + int GetVolume() const { return itsCurrentStatus ? mpd_status_get_volume(itsCurrentStatus) : -1; } + unsigned GetCrossfade() const { return itsCurrentStatus ? mpd_status_get_crossfade(itsCurrentStatus) : 0; } + unsigned GetPlaylistID() const { return itsCurrentStatus ? mpd_status_get_queue_version(itsCurrentStatus) : 0; } + unsigned GetOldPlaylistID() const { return itsOldStatus ? mpd_status_get_queue_version(itsOldStatus) : 0; } + unsigned GetElapsedTime() const { return itsCurrentStatus ? mpd_status_get_elapsed_time(itsCurrentStatus) : 0; } + int GetTotalTime() const { return itsCurrentStatus ? mpd_status_get_total_time(itsCurrentStatus) : 0; } + unsigned GetBitrate() const { return itsCurrentStatus ? mpd_status_get_kbit_rate(itsCurrentStatus) : 0; } size_t GetMaxPlaylistLength() const { return itsMaxPlaylistLength; } - size_t GetPlaylistLength() const { return isConnected && itsCurrentStatus ? itsCurrentStatus->playlistLength : 0; } - void GetPlaylistChanges(long long, SongList &) const; + size_t GetPlaylistLength() const { return itsCurrentStatus ? mpd_status_get_queue_length(itsCurrentStatus) : 0; } + void GetPlaylistChanges(unsigned, SongList &) const; const std::string & GetErrorMessage() const { return itsErrorMessage; } int GetErrorCode() const { return itsErrorCode; } @@ -150,16 +150,16 @@ namespace MPD void SetRandom(bool) const; void SetSingle(bool) const; void SetConsume(bool) const; - void SetCrossfade(int) const; - void SetVolume(int); + void SetCrossfade(unsigned) const; + void SetVolume(unsigned); int AddSong(const std::string &); // returns id of added song int AddSong(const Song &); // returns id of added song bool AddRandomSongs(size_t); void Add(const std::string &path) const; - void Delete(int) const; - void DeleteID(int) const; - void Delete(const std::string &, int) const; + void Delete(unsigned) const; + void DeleteID(unsigned) const; + void Delete(const std::string &, unsigned) const; void StartCommandsList(); bool CommitCommandsList(); @@ -172,13 +172,13 @@ namespace MPD void Rename(const std::string &, const std::string &) const; void StartSearch(bool) const; - void StartFieldSearch(mpd_TagItems); - void AddSearch(mpd_TagItems, const std::string &) const; + void StartFieldSearch(mpd_tag_type); + void AddSearch(mpd_tag_type, const std::string &) const; void CommitSearch(SongList &) const; void CommitSearch(TagList &) const; void GetPlaylists(TagList &) const; - void GetList(TagList &, mpd_TagItems) const; + void GetList(TagList &, mpd_tag_type) const; void GetAlbums(const std::string &, TagList &) const; void GetDirectory(const std::string &, ItemList &) const; void GetDirectoryRecursive(const std::string &, SongList &) const; @@ -192,7 +192,7 @@ namespace MPD private: int CheckForErrors(); - mpd_Connection *itsConnection; + mpd_connection *itsConnection; bool isConnected; bool isCommandsListEnabled; @@ -205,8 +205,8 @@ namespace MPD int itsTimeout; std::string itsPassword; - mpd_Status *itsCurrentStatus; - mpd_Status *itsOldStatus; + mpd_status *itsCurrentStatus; + mpd_status *itsOldStatus; StatusChanges itsChanges; @@ -215,7 +215,7 @@ namespace MPD ErrorHandler itsErrorHandler; void *itsErrorHandlerUserdata; - mpd_TagItems itsSearchedField; + mpd_tag_type itsSearchedField; }; } diff --git a/src/ncmpcpp.cpp b/src/ncmpcpp.cpp index b087149e..d272e7f2 100644 --- a/src/ncmpcpp.cpp +++ b/src/ncmpcpp.cpp @@ -1816,7 +1816,7 @@ int main(int argc, char *argv[]) while (item != 'a' && item != 'y' && item != 'g' && item != 'c' && item != 'p'); curs_set(0); UnlockStatusbar(); - mpd_TagItems new_tagitem = IntoTagItem(item); + mpd_tag_type new_tagitem = IntoTagItem(item); if (new_tagitem != Config.media_lib_primary_tag) { Config.media_lib_primary_tag = new_tagitem; diff --git a/src/settings.cpp b/src/settings.cpp index 57303282..af1e10ba 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -279,7 +279,7 @@ void DefaultConfiguration(ncmpcpp_config &conf) conf.active_column_color = clRed; conf.window_border = brGreen; conf.active_window_border = brRed; - conf.media_lib_primary_tag = MPD_TAG_ITEM_ARTIST; + conf.media_lib_primary_tag = MPD_TAG_ARTIST; conf.colors_enabled = true; conf.fancy_scrolling = true; conf.playlist_show_remaining_time = false; diff --git a/src/settings.h b/src/settings.h index 1c1290e0..07151dbe 100644 --- a/src/settings.h +++ b/src/settings.h @@ -24,8 +24,9 @@ #include #include +#include + #include "home.h" -#include "libmpdclient.h" #include "ncmpcpp.h" #ifdef WIN32 @@ -170,7 +171,7 @@ struct ncmpcpp_config Border window_border; Border active_window_border; - mpd_TagItems media_lib_primary_tag; + mpd_tag_type media_lib_primary_tag; bool colors_enabled; bool fancy_scrolling; diff --git a/src/song.cpp b/src/song.cpp index 2ad8d45b..2c132a33 100644 --- a/src/song.cpp +++ b/src/song.cpp @@ -32,13 +32,24 @@ #include "error.h" #include "song.h" -MPD::Song::Song(mpd_Song *s, bool copy_ptr) : itsSong(s ? s : mpd_newSong()), +namespace +{ + unsigned calc_hash(const char *p) + { + unsigned hash = 5381; + while (*p) + hash = (hash << 5) + hash + *p++; + return hash; + } +} + +MPD::Song::Song(mpd_song *s, bool copy_ptr) : itsSong(s), itsSlash(std::string::npos), itsHash(0), copyPtr(copy_ptr), isLocalised(0) { - if (itsSong->file) + if (itsSong) SetHashAndSlash(); } @@ -49,18 +60,19 @@ MPD::Song::Song(const Song &s) : itsSong(0), copyPtr(s.copyPtr), isLocalised(s.isLocalised) { - itsSong = s.copyPtr ? s.itsSong : mpd_songDup(s.itsSong); + itsSong = s.copyPtr ? s.itsSong : mpd_song_dup(s.itsSong); } MPD::Song::~Song() { if (itsSong) - mpd_freeSong(itsSong); + mpd_song_free(itsSong); } std::string MPD::Song::GetLength() const { - return itsSong->time <= 0 ? "-:--" : ShowTime(itsSong->time); + unsigned len = mpd_song_get_duration(itsSong); + return !len ? "-:--" : ShowTime(len); } void MPD::Song::Localize() @@ -88,8 +100,8 @@ void MPD::Song::Localize() void MPD::Song::Clear() { if (itsSong) - mpd_freeSong(itsSong); - itsSong = mpd_newSong(); + mpd_song_free(itsSong); + itsSong = 0; itsNewName.clear(); itsSlash = std::string::npos; itsHash = 0; @@ -99,79 +111,88 @@ void MPD::Song::Clear() bool MPD::Song::Empty() const { - return !itsSong || (!itsSong->file && !itsSong->title && !itsSong->artist && !itsSong->album && !itsSong->date && !itsSong->track && !itsSong->genre && !itsSong->composer && !itsSong->performer && !itsSong->disc && !itsSong->comment); + return !itsSong;// || (!itsSong->file && !itsSong->title && !itsSong->artist && !itsSong->album && !itsSong->date && !itsSong->track && !itsSong->genre && !itsSong->composer && !itsSong->performer && !itsSong->disc && !itsSong->comment); } bool MPD::Song::isFromDB() const { - return (itsSong->file && itsSong->file[0] != '/') || itsSlash == std::string::npos; + return (mpd_song_get_uri(itsSong)[0] != '/') || itsSlash == std::string::npos; } bool MPD::Song::isStream() const { - return !strncmp(itsSong->file, "http://", 7); + return !strncmp(mpd_song_get_uri(itsSong), "http://", 7); } std::string MPD::Song::GetFile() const { - return !itsSong->file ? "" : itsSong->file; + return mpd_song_get_uri(itsSong); } std::string MPD::Song::GetName() const { - if (itsSong->name) - return itsSong->name; - else if (!itsSong->file) - return ""; + if (const char *name = mpd_song_get_tag(itsSong, MPD_TAG_NAME, 0)) + return name; else if (itsSlash != std::string::npos) - return itsSong->file+itsSlash+1; + return mpd_song_get_uri(itsSong)+itsSlash+1; else - return itsSong->file; + return mpd_song_get_uri(itsSong); } std::string MPD::Song::GetDirectory() const { - if (!itsSong->file || isStream()) + if (isStream()) return ""; else if (itsSlash == std::string::npos) return "/"; else - return std::string(itsSong->file, itsSlash); + return std::string(mpd_song_get_uri(itsSong), itsSlash); } std::string MPD::Song::GetArtist() const { - return !itsSong->artist ? "" : itsSong->artist; + if (const char *artist = mpd_song_get_tag(itsSong, MPD_TAG_ARTIST, 0)) + return artist; + else + return ""; } std::string MPD::Song::GetTitle() const { - return !itsSong->title ? "" : itsSong->title; + if (const char *title = mpd_song_get_tag(itsSong, MPD_TAG_TITLE, 0)) + return title; + else + return ""; } std::string MPD::Song::GetAlbum() const { - return !itsSong->album ? "" : itsSong->album; + if (const char *album = mpd_song_get_tag(itsSong, MPD_TAG_ALBUM, 0)) + return album; + else + return ""; } std::string MPD::Song::GetTrack() const { - if (!itsSong->track) + const char *track = mpd_song_get_tag(itsSong, MPD_TAG_TRACK, 0); + if (!track) return ""; - else if (itsSong->track[0] != '0' && !itsSong->track[1]) - return "0"+std::string(itsSong->track); + else if (track[0] != '0' && !track[1]) + return "0"+std::string(track); else - return itsSong->track; + return track; } std::string MPD::Song::GetTrackNumber() const { - if (!itsSong->track) + const char *track = mpd_song_get_tag(itsSong, MPD_TAG_TRACK, 0); + if (!track) return ""; - const char *slash = strrchr(itsSong->track, '/'); + const char *slash = strrchr(track, '/'); if (slash) { - std::string result(itsSong->track, slash-itsSong->track); + std::string result(track, slash-track); return result[0] != '0' && result.length() == 1 ? "0"+result : result; } else @@ -180,129 +201,147 @@ std::string MPD::Song::GetTrackNumber() const std::string MPD::Song::GetDate() const { - return !itsSong->date ? "" : itsSong->date; + if (const char *date = mpd_song_get_tag(itsSong, MPD_TAG_DATE, 0)) + return date; + else + return ""; } std::string MPD::Song::GetGenre() const { - return !itsSong->genre ? "" : itsSong->genre; + if (const char *genre = mpd_song_get_tag(itsSong, MPD_TAG_GENRE, 0)) + return genre; + else + return ""; } std::string MPD::Song::GetComposer() const { - return !itsSong->composer ? "" : itsSong->composer; + if (const char *composer = mpd_song_get_tag(itsSong, MPD_TAG_COMPOSER, 0)) + return composer; + else + return ""; } std::string MPD::Song::GetPerformer() const { - return !itsSong->performer ? "" : itsSong->performer; + if (const char *performer = mpd_song_get_tag(itsSong, MPD_TAG_PERFORMER, 0)) + return performer; + else + return ""; } std::string MPD::Song::GetDisc() const { - return !itsSong->disc ? "" : itsSong->disc; + if (const char *disc = mpd_song_get_tag(itsSong, MPD_TAG_DISC, 0)) + return disc; + else + return ""; } std::string MPD::Song::GetComment() const { - return !itsSong->comment ? "" : itsSong->comment; + if (const char *comment = mpd_song_get_tag(itsSong, MPD_TAG_COMMENT, 0)) + return comment; + else + return ""; } -void MPD::Song::SetFile(const std::string &str) +/*void MPD::Song::SetFile(const std::string &str) { if (itsSong->file) str_pool_put(itsSong->file); itsSong->file = str.empty() ? 0 : str_pool_get(str.c_str()); SetHashAndSlash(); -} +}*/ void MPD::Song::SetArtist(const std::string &str) { - if (itsSong->artist) - str_pool_put(itsSong->artist); - itsSong->artist = str.empty() ? 0 : str_pool_get(str.c_str()); + mpd_song_clear_tag(itsSong, MPD_TAG_ARTIST); + if (!str.empty()) + mpd_song_add_tag(itsSong, MPD_TAG_ARTIST, str.c_str()); } void MPD::Song::SetTitle(const std::string &str) { - if (itsSong->title) - str_pool_put(itsSong->title); - itsSong->title = str.empty() ? 0 : str_pool_get(str.c_str()); + mpd_song_clear_tag(itsSong, MPD_TAG_TITLE); + if (!str.empty()) + mpd_song_add_tag(itsSong, MPD_TAG_TITLE, str.c_str()); } void MPD::Song::SetAlbum(const std::string &str) { - if (itsSong->album) - str_pool_put(itsSong->album); - itsSong->album = str.empty() ? 0 : str_pool_get(str.c_str()); + mpd_song_clear_tag(itsSong, MPD_TAG_ALBUM); + if (!str.empty()) + mpd_song_add_tag(itsSong, MPD_TAG_ALBUM, str.c_str()); } void MPD::Song::SetTrack(const std::string &str) { - if (itsSong->track) - str_pool_put(itsSong->track); - itsSong->track = str.empty() ? 0 : str_pool_get(str.c_str()); + mpd_song_clear_tag(itsSong, MPD_TAG_TRACK); + if (!str.empty()) + mpd_song_add_tag(itsSong, MPD_TAG_TRACK, str.c_str()); } -void MPD::Song::SetTrack(int track) +void MPD::Song::SetTrack(unsigned track) { - if (itsSong->track) - str_pool_put(itsSong->track); - itsSong->track = str_pool_get(IntoStr(track).c_str()); + mpd_song_clear_tag(itsSong, MPD_TAG_TRACK); + if (track) + mpd_song_add_tag(itsSong, MPD_TAG_ARTIST, IntoStr(track).c_str()); } void MPD::Song::SetDate(const std::string &str) { - if (itsSong->date) - str_pool_put(itsSong->date); - itsSong->date = str.empty() ? 0 : str_pool_get(str.c_str()); + mpd_song_clear_tag(itsSong, MPD_TAG_DATE); + if (!str.empty()) + mpd_song_add_tag(itsSong, MPD_TAG_DATE, str.c_str()); } -void MPD::Song::SetDate(int year) +void MPD::Song::SetDate(unsigned year) { - if (itsSong->date) - str_pool_put(itsSong->date); - itsSong->date = str_pool_get(IntoStr(year).c_str()); + mpd_song_clear_tag(itsSong, MPD_TAG_DATE); + if (year) + mpd_song_add_tag(itsSong, MPD_TAG_DATE, IntoStr(year).c_str()); } void MPD::Song::SetGenre(const std::string &str) { - if (itsSong->genre) - str_pool_put(itsSong->genre); - itsSong->genre = str.empty() ? 0 : str_pool_get(str.c_str()); + mpd_song_clear_tag(itsSong, MPD_TAG_GENRE); + if (!str.empty()) + mpd_song_add_tag(itsSong, MPD_TAG_GENRE, str.c_str()); } void MPD::Song::SetComposer(const std::string &str) { - if (itsSong->composer) - str_pool_put(itsSong->composer); - itsSong->composer = str.empty() ? 0 : str_pool_get(str.c_str()); + mpd_song_clear_tag(itsSong, MPD_TAG_COMPOSER); + if (!str.empty()) + mpd_song_add_tag(itsSong, MPD_TAG_COMPOSER, str.c_str()); } void MPD::Song::SetPerformer(const std::string &str) { - if (itsSong->performer) - str_pool_put(itsSong->performer); - itsSong->performer = str.empty() ? 0 : str_pool_get(str.c_str()); + mpd_song_clear_tag(itsSong, MPD_TAG_PERFORMER); + if (!str.empty()) + mpd_song_add_tag(itsSong, MPD_TAG_PERFORMER, str.c_str()); } void MPD::Song::SetDisc(const std::string &str) { - if (itsSong->disc) - str_pool_put(itsSong->disc); - itsSong->disc = str.empty() ? 0 : str_pool_get(str.c_str()); + mpd_song_clear_tag(itsSong, MPD_TAG_DISC); + if (!str.empty()) + mpd_song_add_tag(itsSong, MPD_TAG_DISC, str.c_str()); } void MPD::Song::SetComment(const std::string &str) { - if (itsSong->comment) - str_pool_put(itsSong->comment); - itsSong->comment = str.empty() ? 0 : str_pool_get(str.c_str()); + mpd_song_clear_tag(itsSong, MPD_TAG_COMMENT); + if (!str.empty()) + mpd_song_add_tag(itsSong, MPD_TAG_COMMENT, str.c_str()); } -void MPD::Song::SetPosition(int pos) +void MPD::Song::SetPosition(unsigned pos) { - itsSong->pos = pos; + mpd_song_set_pos(itsSong, pos); } std::string MPD::Song::ParseFormat(std::string::const_iterator &it) const @@ -434,8 +473,8 @@ MPD::Song &MPD::Song::operator=(const MPD::Song &s) if (this == &s) return *this; if (itsSong) - mpd_freeSong(itsSong); - itsSong = s.copyPtr ? s.itsSong : mpd_songDup(s.itsSong); + mpd_song_free(itsSong); + itsSong = s.copyPtr ? s.itsSong : (s.itsSong ? mpd_song_dup(s.itsSong) : 0); itsNewName = s.itsNewName; itsSlash = s.itsSlash; itsHash = s.itsHash; @@ -484,13 +523,12 @@ void MPD::Song::ValidateFormat(const std::string &type, const std::string &s) void MPD::Song::SetHashAndSlash() { - if (!itsSong->file) - return; + const char *filename = mpd_song_get_uri(itsSong); if (!isStream()) { - const char *tmp = strrchr(itsSong->file, '/'); - itsSlash = tmp ? tmp-itsSong->file : std::string::npos; + const char *tmp = strrchr(filename, '/'); + itsSlash = tmp ? tmp-filename : std::string::npos; } - itsHash = calc_hash(itsSong->file); + itsHash = calc_hash(filename); } diff --git a/src/song.h b/src/song.h index 0f81e298..bc8442f9 100644 --- a/src/song.h +++ b/src/song.h @@ -23,7 +23,7 @@ #include -#include "libmpdclient.h" +#include namespace MPD { @@ -34,8 +34,8 @@ namespace MPD typedef void (Song::*SetFunction)(const std::string &); typedef std::string (Song::*GetFunction)() const; - Song() : itsSlash(std::string::npos), itsHash(0), copyPtr(0), isLocalised(0) { itsSong = mpd_newSong(); } - Song(mpd_Song *, bool = 0); + Song() : itsSong(0), itsSlash(std::string::npos), itsHash(0), copyPtr(0), isLocalised(0) { } + Song(mpd_song *, bool = 0); Song(const Song &); ~Song(); @@ -56,24 +56,24 @@ namespace MPD std::string GetLength() const; unsigned GetHash() const { return itsHash; } - int GetTotalLength() const { return itsSong->time < 0 ? 0 : itsSong->time; } - int GetPosition() const { return itsSong->pos; } - int GetID() const { return itsSong->id; } + unsigned GetTotalLength() const { return mpd_song_get_duration(itsSong); } + unsigned GetPosition() const { return mpd_song_get_pos(itsSong); } + unsigned GetID() const { return mpd_song_get_id(itsSong); } - void SetFile(const std::string &); + //void SetFile(const std::string &); void SetArtist(const std::string &); void SetTitle(const std::string &); void SetAlbum(const std::string &); void SetTrack(const std::string &); - void SetTrack(int); + void SetTrack(unsigned); void SetDate(const std::string &); - void SetDate(int); + void SetDate(unsigned); void SetGenre(const std::string &); void SetComposer(const std::string &); void SetPerformer(const std::string &); void SetDisc(const std::string &); void SetComment(const std::string &); - void SetPosition(int); + void SetPosition(unsigned); void SetNewName(const std::string &name) { itsNewName = name == GetName() ? "" : name; } std::string GetNewName() const { return itsNewName; } @@ -99,7 +99,7 @@ namespace MPD void SetHashAndSlash(); std::string ParseFormat(std::string::const_iterator &it) const; - mpd_Song *itsSong; + mpd_song *itsSong; std::string itsNewName; size_t itsSlash; unsigned itsHash; diff --git a/src/status.cpp b/src/status.cpp index 66b282d3..91525866 100644 --- a/src/status.cpp +++ b/src/status.cpp @@ -158,12 +158,11 @@ void TraceMpdStatus() void NcmpcppErrorCallback(Connection *, int errorid, const char *msg, void *) { - if (errorid == MPD_ACK_ERROR_PERMISSION) + if (errorid == MPD_SERVER_ERROR_PERMISSION) { wFooter->SetGetStringHelper(0); Statusbar() << "Password: "; - std::string password = wFooter->GetString(-1, 0, 1); - Mpd.SetPassword(password); + Mpd.SetPassword(wFooter->GetString(-1, 0, 1)); Mpd.SendPassword(); Mpd.UpdateStatus(); wFooter->SetGetStringHelper(StatusbarGetStringHelper); diff --git a/src/tag_editor.cpp b/src/tag_editor.cpp index a92bbec3..7b9445fb 100644 --- a/src/tag_editor.cpp +++ b/src/tag_editor.cpp @@ -236,7 +236,7 @@ void TagEditor::Update() { MPD::SongList l; Mpd.StartSearch(1); - Mpd.AddSearch(MPD_TAG_ITEM_ALBUM, *it); + Mpd.AddSearch(MPD_TAG_ALBUM, *it); Mpd.CommitSearch(l); if (!l.empty()) { @@ -285,7 +285,7 @@ void TagEditor::Update() if (Config.albums_in_tag_editor) { Mpd.StartSearch(1); - Mpd.AddSearch(MPD_TAG_ITEM_ALBUM, Albums->Current().second); + Mpd.AddSearch(MPD_TAG_ALBUM, Albums->Current().second); Mpd.CommitSearch(list); sort(list.begin(), list.end(), CaseInsensitiveSorting()); for (MPD::SongList::iterator it = list.begin(); it != list.end(); ++it)