aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/protocol.xml21
-rw-r--r--src/command.c22
-rw-r--r--src/playlist.c20
-rw-r--r--src/playlist.h5
-rw-r--r--src/playlist_control.c2
-rw-r--r--src/playlist_state.c13
-rw-r--r--src/queue.c3
-rw-r--r--src/queue.h3
8 files changed, 87 insertions, 2 deletions
diff --git a/doc/protocol.xml b/doc/protocol.xml
index 8f5b4b9e8..fc833f7bf 100644
--- a/doc/protocol.xml
+++ b/doc/protocol.xml
@@ -217,6 +217,12 @@
</para>
</listitem>
<listitem>
+ <para>
+ <varname>smartstop</varname>:
+ <returnvalue>0 or 1</returnvalue>
+ </para>
+ </listitem>
+ <listitem>
<para>
<varname>playlist</varname>:
<returnvalue>31-bit unsigned integer, the playlist
@@ -402,6 +408,21 @@
</para>
</listitem>
</varlistentry>
+ <varlistentry id="command_smartstop">
+ <term>
+ <cmdsynopsis>
+ <command>smartstop</command>
+ <arg choice="req"><replaceable>STATE</replaceable></arg>
+ </cmdsynopsis>
+ </term>
+ <listitem>
+ <para>
+ Sets smartstop state to <varname>STATE</varname>,
+ <varname>STATE</varname> should be 0 or 1.
+ When smartstop is activated, playback is stopped after current song.
+ </para>
+ </listitem>
+ </varlistentry>
<varlistentry id="command_volume">
<term>
<cmdsynopsis>
diff --git a/src/command.c b/src/command.c
index 1b8c45f26..82b088587 100644
--- a/src/command.c
+++ b/src/command.c
@@ -59,6 +59,7 @@
#define COMMAND_STATUS_VOLUME "volume"
#define COMMAND_STATUS_STATE "state"
#define COMMAND_STATUS_REPEAT "repeat"
+#define COMMAND_STATUS_SMARTSTOP "smartstop"
#define COMMAND_STATUS_RANDOM "random"
#define COMMAND_STATUS_PLAYLIST "playlist"
#define COMMAND_STATUS_PLAYLIST_LENGTH "playlistlength"
@@ -469,6 +470,7 @@ handle_status(struct client *client,
COMMAND_STATUS_VOLUME ": %i\n"
COMMAND_STATUS_REPEAT ": %i\n"
COMMAND_STATUS_RANDOM ": %i\n"
+ COMMAND_STATUS_SMARTSTOP ": %i\n"
COMMAND_STATUS_PLAYLIST ": %li\n"
COMMAND_STATUS_PLAYLIST_LENGTH ": %i\n"
COMMAND_STATUS_CROSSFADE ": %i\n"
@@ -476,6 +478,7 @@ handle_status(struct client *client,
volume_level_get(),
getPlaylistRepeatStatus(&g_playlist),
getPlaylistRandomStatus(&g_playlist),
+ getPlaylistSmartstopStatus(&g_playlist),
getPlaylistVersion(&g_playlist),
getPlaylistLength(&g_playlist),
(int)(getPlayerCrossFade() + 0.5),
@@ -1093,6 +1096,24 @@ handle_repeat(struct client *client, G_GNUC_UNUSED int argc, char *argv[])
}
static enum command_return
+handle_smartstop(struct client *client, G_GNUC_UNUSED int argc, char *argv[])
+{
+ int status;
+
+ if (!check_int(client, &status, argv[1], need_integer))
+ return COMMAND_RETURN_ERROR;
+
+ if (status != 0 && status != 1) {
+ command_error(client, ACK_ERROR_ARG,
+ "\"%i\" is not 0 or 1", status);
+ return COMMAND_RETURN_ERROR;
+ }
+
+ setPlaylistSmartstopStatus(&g_playlist, status);
+ return COMMAND_RETURN_OK;
+}
+
+static enum command_return
handle_random(struct client *client, G_GNUC_UNUSED int argc, char *argv[])
{
int status;
@@ -1602,6 +1623,7 @@ static const struct command commands[] = {
{ "seekid", PERMISSION_CONTROL, 2, 2, handle_seekid },
{ "setvol", PERMISSION_CONTROL, 1, 1, handle_setvol },
{ "shuffle", PERMISSION_CONTROL, 0, 1, handle_shuffle },
+ { "smartstop", PERMISSION_CONTROL, 1, 1, handle_smartstop },
{ "stats", PERMISSION_READ, 0, 0, handle_stats },
{ "status", PERMISSION_READ, 0, 0, handle_status },
#ifdef ENABLE_SQLITE
diff --git a/src/playlist.c b/src/playlist.c
index 59923efc7..0ec46492a 100644
--- a/src/playlist.c
+++ b/src/playlist.c
@@ -261,6 +261,12 @@ getPlaylistRandomStatus(const struct playlist *playlist)
return playlist->queue.random;
}
+bool
+getPlaylistSmartstopStatus(const struct playlist *playlist)
+{
+ return playlist->queue.smartstop;
+}
+
void setPlaylistRepeatStatus(struct playlist *playlist, bool status)
{
if (status == playlist->queue.repeat)
@@ -286,6 +292,18 @@ static void orderPlaylist(struct playlist *playlist)
queue_restore_order(&playlist->queue);
}
+void setPlaylistSmartstopStatus(struct playlist *playlist, bool status)
+{
+ playlist->queue.smartstop = status;
+
+ /* if the last song is currently being played, the "next song"
+ might change when repeat mode is toggled */
+ playlist_update_queued_song(playlist,
+ playlist_get_queued_song(playlist));
+
+ idle_add(IDLE_OPTIONS);
+}
+
void setPlaylistRandomStatus(struct playlist *playlist, bool status)
{
const struct song *queued;
@@ -341,6 +359,8 @@ int getPlaylistNextSong(const struct playlist *playlist)
{
if (playlist->current >= 0)
{
+ if (playlist->queue.smartstop == 1)
+ return -1;
if (playlist->current + 1 < (int)queue_length(&playlist->queue))
return queue_order_to_position(&playlist->queue,
playlist->current + 1);
diff --git a/src/playlist.h b/src/playlist.h
index 41befe455..4e11ec421 100644
--- a/src/playlist.h
+++ b/src/playlist.h
@@ -179,6 +179,11 @@ getPlaylistRandomStatus(const struct playlist *playlist);
void setPlaylistRandomStatus(struct playlist *playlist, bool status);
+bool
+getPlaylistSmartstopStatus(const struct playlist *playlist);
+
+void setPlaylistSmartstopStatus(struct playlist *playlist, bool status);
+
int getPlaylistCurrentSong(const struct playlist *playlist);
int getPlaylistNextSong(const struct playlist *playlist);
diff --git a/src/playlist_control.c b/src/playlist_control.c
index 666bdc2ba..90aab5f29 100644
--- a/src/playlist_control.c
+++ b/src/playlist_control.c
@@ -152,6 +152,8 @@ nextSongInPlaylist(struct playlist *playlist)
next_order = queue_next_order(&playlist->queue, playlist->current);
if (next_order < 0) {
+ /* cancel smartstop */
+ playlist->queue.smartstop = false;
/* no song after this one: stop playback */
stopPlaylist(playlist);
return;
diff --git a/src/playlist_state.c b/src/playlist_state.c
index b6636fa54..6d1756eed 100644
--- a/src/playlist_state.c
+++ b/src/playlist_state.c
@@ -34,6 +34,7 @@
#define PLAYLIST_STATE_FILE_STATE "state: "
#define PLAYLIST_STATE_FILE_RANDOM "random: "
#define PLAYLIST_STATE_FILE_REPEAT "repeat: "
+#define PLAYLIST_STATE_FILE_SMARTSTOP "smartstop: "
#define PLAYLIST_STATE_FILE_CURRENT "current: "
#define PLAYLIST_STATE_FILE_TIME "time: "
#define PLAYLIST_STATE_FILE_CROSSFADE "crossfade: "
@@ -71,6 +72,8 @@ playlist_state_save(FILE *fp, const struct playlist *playlist)
playlist->queue.random);
fprintf(fp, "%s%i\n", PLAYLIST_STATE_FILE_REPEAT,
playlist->queue.repeat);
+ fprintf(fp, "%s%i\n", PLAYLIST_STATE_FILE_SMARTSTOP,
+ playlist->queue.smartstop);
fprintf(fp, "%s%i\n", PLAYLIST_STATE_FILE_CROSSFADE,
(int)(getPlayerCrossFade()));
fprintf(fp, "%s\n", PLAYLIST_STATE_FILE_PLAYLIST_BEGIN);
@@ -129,14 +132,20 @@ playlist_state_restore(FILE *fp, struct playlist *playlist)
} else if (g_str_has_prefix(buffer, PLAYLIST_STATE_FILE_TIME)) {
seek_time =
atoi(&(buffer[strlen(PLAYLIST_STATE_FILE_TIME)]));
- } else
- if (g_str_has_prefix(buffer, PLAYLIST_STATE_FILE_REPEAT)) {
+ } else if (g_str_has_prefix(buffer, PLAYLIST_STATE_FILE_REPEAT)) {
if (strcmp
(&(buffer[strlen(PLAYLIST_STATE_FILE_REPEAT)]),
"1") == 0) {
setPlaylistRepeatStatus(playlist, true);
} else
setPlaylistRepeatStatus(playlist, false);
+ } else if (g_str_has_prefix(buffer, PLAYLIST_STATE_FILE_SMARTSTOP)) {
+ if (strcmp
+ (&(buffer[strlen(PLAYLIST_STATE_FILE_SMARTSTOP)]),
+ "1") == 0) {
+ setPlaylistSmartstopStatus(playlist, true);
+ } else
+ setPlaylistSmartstopStatus(playlist, false);
} else if (g_str_has_prefix(buffer, PLAYLIST_STATE_FILE_CROSSFADE)) {
setPlayerCrossFade(atoi
(&
diff --git a/src/queue.c b/src/queue.c
index b9486cfe5..28da0e5a3 100644
--- a/src/queue.c
+++ b/src/queue.c
@@ -40,6 +40,8 @@ queue_next_order(const struct queue *queue, unsigned order)
{
assert(order < queue->length);
+ if (queue->smartstop)
+ return -1;
if (order + 1 < queue->length)
return order + 1;
else if (queue->repeat)
@@ -275,6 +277,7 @@ queue_init(struct queue *queue, unsigned max_length)
queue->version = 1;
queue->repeat = false;
queue->random = false;
+ queue->smartstop = false;
queue->items = g_new(struct queue_item, max_length);
queue->order = g_malloc(sizeof(queue->order[0]) *
diff --git a/src/queue.h b/src/queue.h
index 7f46c2e19..63b71d199 100644
--- a/src/queue.h
+++ b/src/queue.h
@@ -81,6 +81,9 @@ struct queue {
reached? */
bool repeat;
+ /** stop playing after that song. */
+ bool smartstop;
+
/** play back songs in random order? */
bool random;