Commit Diff


commit - 63f5223a7eb5d82638a680e8b83bb734360c1b26
commit + af27e631bb7de2e74c2bebd8caf8d5707fb9f223
blob - 6408cbef919f047b2eef8a780ddd0117104dec72
blob + aa433a02f0e66c2ac6450ca7bb10afa76c2f3bde
--- amused.c
+++ amused.c
@@ -411,6 +411,23 @@ main_playlist_advance(void)
 }
 
 void
+main_playlist_previous(void)
+{
+	const char *song;
+
+	for (;;) {
+		song = playlist_previous();
+		if (song == NULL)
+			return;
+
+		if (main_play_song(song))
+			break;
+
+		playlist_dropcurrent();
+	}
+}
+
+void
 main_restart_track(void)
 {
 	const char *song;
blob - 89bb9ef272a2ab3af68762223946812bf39b49cf
blob + 5a7e9925de5df941f9b4a4125173fe21e3f629ea
--- amused.h
+++ amused.h
@@ -43,6 +43,8 @@ enum imsg_type {
 	IMSG_CTL_FLUSH,
 	IMSG_CTL_SHOW,
 	IMSG_CTL_STATUS,
+	IMSG_CTL_NEXT,
+	IMSG_CTL_PREV,
 
 	IMSG_CTL_ERR,
 };
@@ -65,6 +67,8 @@ enum actions {
 	FLUSH,
 	SHOW,
 	STATUS,
+	PREV,
+	NEXT,
 };
 
 struct ctl_command;
@@ -95,6 +99,7 @@ int		imsg_compose_event(struct imsgev *, uint16_t, uin
 		    pid_t, int, const void *, uint16_t);
 int		main_send_player(uint16_t, int, const void *, uint16_t);
 void		main_playlist_advance(void);
+void		main_playlist_previous(void);
 void		main_restart_track(void);
 void		main_enqueue(struct imsgev *, struct imsg *);
 void		main_send_playlist(struct imsgev *);
blob - e46c1e47a7d9ba7269065026c5e40ec0af8f16a4
blob + e114270c47715e7def09409e57b3bb68fa9a80f7
--- control.c
+++ control.c
@@ -307,6 +307,14 @@ control_dispatch_imsg(int fd, short event, void *bula)
 			break;
 		case IMSG_CTL_STATUS:
 			main_send_status(&c->iev);
+			break;
+		case IMSG_CTL_NEXT:
+			main_send_player(IMSG_STOP, -1, NULL, 0);
+			main_playlist_advance();
+			break;
+		case IMSG_CTL_PREV:
+			main_send_player(IMSG_STOP, -1, NULL, 0);
+			main_playlist_previous();
 			break;
 		default:
 			log_debug("%s: error handling imsg %d", __func__,
blob - 7cb5487627250ddcbaeeea8240d2bd87d296bf7f
blob + 402b9f1d98e2f94cf7e04c0e5638b36b993c890e
--- ctl.c
+++ ctl.c
@@ -52,6 +52,8 @@ struct ctl_command ctl_commands[] = {
 	{ "flush",	FLUSH,		ctl_noarg,	"" },
 	{ "show",	SHOW,		ctl_noarg,	"" },
 	{ "status",	STATUS,		ctl_noarg,	"" },
+	{ "next",	NEXT,		ctl_noarg,	"" },
+	{ "prev",	PREV,		ctl_noarg,	"" },
 	{ NULL },
 };
 
@@ -276,7 +278,13 @@ ctlaction(struct parse_result *res)
 	case STATUS:
 		done = 0;
 		imsg_compose(ibuf, IMSG_CTL_STATUS, 0, 0, -1, NULL, 0);
+		break;
+	case NEXT:
+		imsg_compose(ibuf, IMSG_CTL_NEXT, 0, 0, -1, NULL, 0);
 		break;
+	case PREV:
+		imsg_compose(ibuf, IMSG_CTL_PREV, 0, 0, -1, NULL, 0);
+		break;
 	case NONE:
 		/* action not expected */
 		fatalx("invalid action %u", res->action);
blob - c8931b7db81980b7e55d276290bc9d1093b72de6
blob + 23f7cd2e63ec0aa98e5b364d97433bd52ad1c8cf
--- playlist.c
+++ playlist.c
@@ -78,6 +78,29 @@ playlist_advance(void)
 	return playlist.songs[play_off];
 }
 
+const char *
+playlist_previous(void)
+{
+	if (playlist.len == 0) {
+		play_state = STATE_STOPPED;
+		return NULL;
+	}
+
+	play_off--;
+	if (play_off < 0) {
+		if (repeat_all)
+			play_off = playlist.len - 1;
+		else {
+			play_state = STATE_STOPPED;
+			play_off = -1;
+			return NULL;
+		}
+	}
+
+	play_state = STATE_PLAYING;
+	return playlist.songs[play_off];
+}
+
 void
 playlist_reset(void)
 {
blob - 3f4ea37cca318baf7e9b932e6232fa814d018c4f
blob + 7f4fc4260740ed4701141bd6cd05c23d778f2f66
--- playlist.h
+++ playlist.h
@@ -39,6 +39,7 @@ extern ssize_t		 play_off;
 void			 playlist_enqueue(const char *);
 const char		*playlist_current(void);
 const char		*playlist_advance(void);
+const char		*playlist_previous(void);
 void			 playlist_reset(void);
 void			 playlist_truncate(void);
 void			 playlist_dropcurrent(void);