Modifications to the playqueue-clear command:

- do not stop playback when clearing the UpNext queue
- clear history, if mode=0x68697374 ("hist")
This commit is contained in:
chme 2014-05-17 14:06:50 +02:00
parent ce209bae7a
commit b7cb0da2c2
3 changed files with 127 additions and 39 deletions

View File

@ -1219,51 +1219,50 @@ dacp_reply_playqueuecontents(struct evhttp_request *req, struct evbuffer *evbuf,
DPRINTF(E_LOG, L_DACP, "Invalid span value in playqueue-contents request\n"); DPRINTF(E_LOG, L_DACP, "Invalid span value in playqueue-contents request\n");
} }
songlist = NULL;
i = 0; i = 0;
n = 0; // count of songs in songlist n = 0; // count of songs in songlist
player_get_status(&status); songlist = evbuffer_new();
if (!songlist)
/* Get queue and make songlist only if playing or paused */
if (status.status != PLAY_STOPPED)
{ {
songlist = evbuffer_new(); DPRINTF(E_LOG, L_DACP, "Could not allocate songlist evbuffer for playqueue-contents\n");
if (!songlist)
{
DPRINTF(E_LOG, L_DACP, "Could not allocate songlist evbuffer for playqueue-contents\n");
dmap_send_error(req, "ceQR", "Out of memory"); dmap_send_error(req, "ceQR", "Out of memory");
return; return;
} }
/* /*
* If the span parameter is negativ make song list for Previously Played, * If the span parameter is negativ make song list for Previously Played,
* otherwise make song list for Up Next and begin with first song after playlist position. * otherwise make song list for Up Next and begin with first song after playlist position.
*/ */
if (span < 0) if (span < 0)
{
history = player_history_get();
if (abs(span) > history->count)
{ {
history = player_history_get(); start_index = history->start_index;
if (abs(span) > history->count)
{
start_index = history->start_index;
}
else
{
start_index = (history->start_index + history->count - abs(span)) % MAX_HISTORY_COUNT;
}
for (n = 0; n < history->count && n < abs(span); n++)
{
ret = playqueuecontents_add_source(songlist, history->id[(start_index + n) % MAX_HISTORY_COUNT], (n + 1), status.plid);
if (ret < 0)
{
DPRINTF(E_LOG, L_DACP, "Could not add song to songlist for playqueue-contents\n");
dmap_send_error(req, "ceQR", "Out of memory");
return;
}
}
} }
else else
{
start_index = (history->start_index + history->count - abs(span)) % MAX_HISTORY_COUNT;
}
for (n = 0; n < history->count && n < abs(span); n++)
{
ret = playqueuecontents_add_source(songlist, history->id[(start_index + n) % MAX_HISTORY_COUNT], (n + 1), status.plid);
if (ret < 0)
{
DPRINTF(E_LOG, L_DACP, "Could not add song to songlist for playqueue-contents\n");
dmap_send_error(req, "ceQR", "Out of memory");
return;
}
}
}
else
{
player_get_status(&status);
/* Get queue and make songlist only if playing or paused */
if (status.status != PLAY_STOPPED)
{ {
/* Fast forward to song currently being played */ /* Fast forward to song currently being played */
head = player_queue_get(); head = player_queue_get();
@ -1271,7 +1270,7 @@ dacp_reply_playqueuecontents(struct evhttp_request *req, struct evbuffer *evbuf,
{ {
ps = head; ps = head;
while ((ps->id != status.id) && (ps = next_ps(ps, status.shuffle)) && (ps != head)) while ((ps->id != status.id) && (ps = next_ps(ps, status.shuffle)) && (ps != head))
i++; i++;
while ((n < abs(span)) && (ps = next_ps(ps, status.shuffle)) && (ps != head)) while ((n < abs(span)) && (ps = next_ps(ps, status.shuffle)) && (ps != head))
{ {
@ -1365,6 +1364,32 @@ dacp_reply_playqueuecontents(struct evhttp_request *req, struct evbuffer *evbuf,
httpd_send_reply(req, HTTP_OK, "OK", evbuf); httpd_send_reply(req, HTTP_OK, "OK", evbuf);
} }
static void
dacp_reply_playqueueedit_clear(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query)
{
const char *param;
int clear_hist;
clear_hist = 0;
param = evhttp_find_header(query, "mode");
/*
* The mode parameter contains the playlist to be cleared.
* If mode=0x68697374 (hex representation of the ascii string "hist") clear the history,
* otherwise the current playlist.
*/
if (strcmp(param,"0x68697374") == 0)
clear_hist = 1;
player_queue_empty(clear_hist);
dmap_add_container(evbuf, "cacr", 24); /* 8 + len */
dmap_add_int(evbuf, "mstt", 200); /* 12 */
dmap_add_int(evbuf, "miid", 0); /* 12 */
httpd_send_reply(req, HTTP_OK, "OK", evbuf);
}
static void static void
dacp_reply_playqueueedit_add(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query) dacp_reply_playqueueedit_add(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query)
{ {
@ -1630,7 +1655,7 @@ dacp_reply_playqueueedit(struct evhttp_request *req, struct evbuffer *evbuf, cha
} }
if (strcmp(param, "clear") == 0) if (strcmp(param, "clear") == 0)
dacp_reply_cue_clear(req, evbuf, uri, query); dacp_reply_playqueueedit_clear(req, evbuf, uri, query);
else if (strcmp(param, "playnow") == 0) else if (strcmp(param, "playnow") == 0)
dacp_reply_cue_play(req, evbuf, uri, query); dacp_reply_cue_play(req, evbuf, uri, query);
else if (strcmp(param, "add") == 0) else if (strcmp(param, "add") == 0)

View File

@ -3588,6 +3588,50 @@ queue_clear(struct player_command *cmd)
return 0; return 0;
} }
static int
queue_empty(struct player_command *cmd)
{
int clear_hist;
struct player_source *ps;
clear_hist = cmd->arg.intval;
if (clear_hist)
{
memset(history, 0, sizeof(struct player_history));
}
else
{
if (!source_head || !cur_streaming)
return 0;
// Stop playback if playing and streaming song are not the same
if (!cur_playing || cur_playing != cur_streaming)
{
playback_stop(cmd);
queue_clear(cmd);
return 0;
}
// Set head to the current playing song
shuffle_head = cur_playing;
source_head = cur_playing;
// Free all items in the queue except the current playing song
for (ps = source_head->pl_next; ps != source_head; ps = ps->pl_next)
{
source_free(ps);
}
// Make the queue circular again
source_head->pl_next = source_head;
source_head->pl_prev = source_head;
source_head->shuffle_next = source_head;
source_head->shuffle_prev = source_head;
}
return 0;
}
static int static int
queue_plid(struct player_command *cmd) queue_plid(struct player_command *cmd)
{ {
@ -4111,6 +4155,22 @@ player_queue_clear(void)
command_deinit(&cmd); command_deinit(&cmd);
} }
void
player_queue_empty(int clear_hist)
{
struct player_command cmd;
command_init(&cmd);
cmd.func = queue_empty;
cmd.func_bh = NULL;
cmd.arg.intval = clear_hist;
sync_command(&cmd);
command_deinit(&cmd);
}
void void
player_queue_plid(uint32_t plid) player_queue_plid(uint32_t plid)
{ {

View File

@ -173,6 +173,9 @@ player_queue_remove(int ps_pos_remove);
void void
player_queue_clear(void); player_queue_clear(void);
void
player_queue_empty(int clear_hist);
void void
player_queue_plid(uint32_t plid); player_queue_plid(uint32_t plid);