diff options
-rw-r--r-- | src/libmpdclient.h | 33 | ||||
-rw-r--r-- | src/main.c | 15 | ||||
-rw-r--r-- | src/mpdclient.h | 3 | ||||
-rw-r--r-- | src/screen.c | 6 | ||||
-rw-r--r-- | src/screen_file.c | 6 | ||||
-rw-r--r-- | src/screen_play.c | 56 |
6 files changed, 93 insertions, 26 deletions
diff --git a/src/libmpdclient.h b/src/libmpdclient.h index 1b5f02dfe..0cce02028 100644 --- a/src/libmpdclient.h +++ b/src/libmpdclient.h @@ -44,12 +44,14 @@ #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 6 -#define MPD_ACK_ERROR_PLAYLIST_MAX 7 -#define MPD_ACK_ERROR_SYSTEM 8 -#define MPD_ACK_ERROR_PLAYLIST_LOAD 9 -#define MPD_ACK_ERROR_UPDATE_ALREADY 10 -#define MPD_ACK_ERROR_PLAYER_SYNC 11 + +#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" { @@ -136,10 +138,12 @@ typedef struct mpd_Status { int state; /* crossfade setting in seconds */ int crossfade; - /* if in PLAY or PAUSE state, this is the position of the currently + /* 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 @@ -165,6 +169,7 @@ 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); @@ -214,9 +219,10 @@ typedef struct _mpd_Song { char * name; /* length of song in seconds, check that it is not MPD_SONG_NO_TIME */ int time; - /* if plchanges or playlistinfo used, is the position of the song in - * the playlist */ + /* 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; @@ -327,6 +333,8 @@ void mpd_freeInfoEntity(mpd_InfoEntity * entity); /* 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 */ @@ -335,10 +343,14 @@ void mpd_sendPlaylistInfoCommand(mpd_Connection * connection, int songNum); /* use this to get the changes in the playlist since version _playlist_ */ void mpd_sendPlChangesCommand(mpd_Connection * connection, long long playlist); +/* recursivel fetches all songs/dir/playlists in "dir* (no metadata is + * returned) */ void mpd_sendListallCommand(mpd_Connection * connection, const char * dir); +/* same as sendListallCommand, but also metadata is returned */ void mpd_sendListallInfoCommand(mpd_Connection * connection, const char * dir); +/* non-recursive version of ListallInfo */ void mpd_sendLsInfoCommand(mpd_Connection * connection, const char * dir); #define MPD_TABLE_ARTIST 0 @@ -442,6 +454,9 @@ 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); #ifdef __cplusplus diff --git a/src/main.c b/src/main.c index e996233a0..81522f9d7 100644 --- a/src/main.c +++ b/src/main.c @@ -57,7 +57,7 @@ error_callback(mpdclient_t *c, gint error, gchar *msg) gint code = GET_ACK_ERROR_CODE(error); error = error & 0xFF; - D("Error [%d:%d]> \"%s\"\n", error, c->connection->errorCode, msg); + D("Error [%d:%d]> \"%s\"\n", error, code, msg); switch(error) { case MPD_ERROR_CONNPORT: @@ -69,8 +69,8 @@ error_callback(mpdclient_t *c, gint error, gchar *msg) break; default: screen_status_printf("%s", msg); - doupdate(); beep(); + doupdate(); connected = FALSE; } } @@ -87,6 +87,8 @@ exit_and_cleanup(void) } g_free(options.host); g_free(options.password); + g_free(options.list_format); + g_free(options.status_format); if( timer ) g_timer_destroy(timer); } @@ -184,6 +186,15 @@ main(int argc, const char *argv[]) mpd->connection->version[1], mpd->connection->version[2]); + if( !MPD_VERSION(mpd, 0,11,0) ) + { + fprintf(stderr, "MPD version %d.%d.%d is to old (0.11.0 needed).\n", + mpd->connection->version[0], + mpd->connection->version[1], + mpd->connection->version[2]); + exit(EXIT_FAILURE); + } + /* initialize curses */ screen_init(mpd); diff --git a/src/mpdclient.h b/src/mpdclient.h index 391a5d224..50b8e9a92 100644 --- a/src/mpdclient.h +++ b/src/mpdclient.h @@ -2,6 +2,9 @@ #define MPDCLIENT_H #include "libmpdclient.h" +#define MPD_VERSION(c,x,y,z) (c->connection->version[0]*10000+c->connection->version[1]*100+c->connection->version[2] >= \ + x*10000+y*100+z) + /****************************************************************************/ /* Playlist */ /****************************************************************************/ diff --git a/src/screen.c b/src/screen.c index 76d04fa22..8beab97f2 100644 --- a/src/screen.c +++ b/src/screen.c @@ -264,7 +264,7 @@ paint_status_window(mpdclient_t *c) { if( status->totalTime > 0 ) { - if( seek_id == c->song->id ) + if( c->song && seek_id == c->song->id ) elapsedTime = seek_target_time; snprintf(screen->buf, screen->buf_size, " [%i:%02i/%i:%02i]", @@ -736,8 +736,10 @@ screen_cmd(mpdclient_t *c, command_t cmd) seek_target_time++; if( seek_target_time < c->status->totalTime ) break; - seek_target_time=0; + seek_target_time = c->status->totalTime; + /* seek_target_time=0; */ } + break; /* fall through... */ case CMD_TRACK_NEXT: if( !IS_STOPPED(c->status->state) ) diff --git a/src/screen_file.c b/src/screen_file.c index f4a8c3dc0..f26333a21 100644 --- a/src/screen_file.c +++ b/src/screen_file.c @@ -26,6 +26,7 @@ #include "config.h" #include "ncmpc.h" +#include "options.h" #include "support.h" #include "mpdclient.h" #include "strfsong.h" @@ -305,12 +306,12 @@ handle_delete(screen_t *screen, mpdclient_t *c) plf = entity->info.playlistFile; str = utf8_to_locale(basename(plf->path)); - snprintf(buf, BUFSIZE, _("Delete playlist %s [y/n] ? "), str); + snprintf(buf, BUFSIZE, _("Delete playlist %s [%s/%s] ? "), str, YES, NO); g_free(str); key = tolower(screen_getch(screen->status_window.w, buf)); if( key==KEY_RESIZE ) screen_resize(); - if( key!='y' ) + if( key != YES[0] ) { screen_status_printf(_("Aborted!")); return 0; @@ -318,7 +319,6 @@ handle_delete(screen_t *screen, mpdclient_t *c) if( mpdclient_cmd_delete_playlist(c, plf->path) ) { - beep(); return -1; } screen_status_printf(_("Playlist deleted!")); diff --git a/src/screen_play.c b/src/screen_play.c index 73c0bc679..9d3cef8be 100644 --- a/src/screen_play.c +++ b/src/screen_play.c @@ -18,6 +18,7 @@ * */ +#include <ctype.h> #include <stdlib.h> #include <string.h> #include <glib.h> @@ -108,18 +109,53 @@ center_playing_item(screen_t *screen, mpdclient_t *c) } static int -handle_save_playlist(screen_t *screen, mpdclient_t *c) +handle_save_playlist(screen_t *screen, mpdclient_t *c, char *name) { - char *filename; + gchar *filename; + gint error; - filename=screen_getstr(screen->status_window.w, _("Save playlist as: ")); - filename=trim(filename); + if( name==NULL ) + { + /* query the user for a filename */ + filename=screen_getstr(screen->status_window.w, _("Save playlist as: ")); + filename=trim(filename); + } + else + { + filename=g_strdup(name); + } if( filename==NULL || filename[0]=='\0' ) return -1; /* send save command to mpd */ - if( mpdclient_cmd_save_playlist(c, filename) ) + D("Saving playlist as \'%s \'...\n", filename); + if( (error=mpdclient_cmd_save_playlist(c, filename)) ) { - beep(); + gint code = GET_ACK_ERROR_CODE(error); + + if( code == MPD_ACK_ERROR_EXIST ) + { + char buf[256]; + int key; + + snprintf(buf, 256, _("Replace %s [%s/%s] ? "), filename, YES, NO); + key = tolower(screen_getch(screen->status_window.w, buf)); + if( key == YES[0] ) + { + char *filename_utf8 = locale_to_utf8(filename); + + if( mpdclient_cmd_delete_playlist(c, filename_utf8) ) + { + g_free(filename); + g_free(filename_utf8); + return -1; + } + g_free(filename_utf8); + error = handle_save_playlist(screen, c, filename); + g_free(filename); + return error; + } + } + g_free(filename); return -1; } /* success */ @@ -219,22 +255,22 @@ play_cmd(screen_t *screen, mpdclient_t *c, command_t cmd) { case CMD_PLAY: mpdclient_cmd_play(c, lw->selected); - break; + return 1; case CMD_DELETE: mpdclient_cmd_delete(c, lw->selected); return 1; case CMD_SAVE_PLAYLIST: - handle_save_playlist(screen, c); + handle_save_playlist(screen, c, NULL); return 1; case CMD_SCREEN_UPDATE: center_playing_item(screen, c); return 1; case CMD_LIST_MOVE_UP: mpdclient_cmd_move(c, lw->selected, lw->selected-1); - break; + return 1; case CMD_LIST_MOVE_DOWN: mpdclient_cmd_move(c, lw->selected, lw->selected+1); - break; + return 1; case CMD_LIST_FIND: case CMD_LIST_RFIND: case CMD_LIST_FIND_NEXT: |