aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libmpdclient.h33
-rw-r--r--src/main.c15
-rw-r--r--src/mpdclient.h3
-rw-r--r--src/screen.c6
-rw-r--r--src/screen_file.c6
-rw-r--r--src/screen_play.c56
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: