From 475a2f4e8f019c70fd938abcecb199451551f8b8 Mon Sep 17 00:00:00 2001 From: chme Date: Sat, 19 Apr 2014 08:35:07 +0200 Subject: [PATCH] added support for the playqueueedit remove command --- src/httpd_dacp.c | 36 ++++++++++++++++++++++++++++++++ src/player.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++ src/player.h | 3 +++ 3 files changed, 93 insertions(+) diff --git a/src/httpd_dacp.c b/src/httpd_dacp.c index d80b0d89..ac4bdfd9 100644 --- a/src/httpd_dacp.c +++ b/src/httpd_dacp.c @@ -1462,6 +1462,38 @@ dacp_reply_playqueueedit_move(struct evhttp_request *req, struct evbuffer *evbuf evhttp_send_reply(req, HTTP_NOCONTENT, "No Content", evbuf); } +static void +dacp_reply_playqueueedit_remove(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query) +{ + /* + * Handles the remove command. + * Exampe request (removes song at position 1 in the playqueue): + * ?command=remove&items=1&session-id=100 + */ + int ret; + + const char *itemsparam; + int item_index; + + itemsparam = evhttp_find_header(query, "items"); + if (itemsparam) + { + ret = safe_atoi32(itemsparam, &item_index); + if (ret < 0) + { + DPRINTF(E_LOG, L_DACP, "Invalid edit-params remove item value in playqueue-edit request\n"); + + dmap_send_error(req, "cacr", "Invalid request"); + return; + } + + player_queue_remove(item_index); + } + + /* 204 No Content is the canonical reply */ + evhttp_send_reply(req, HTTP_NOCONTENT, "No Content", evbuf); +} + static void dacp_reply_playqueueedit(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query) { @@ -1507,6 +1539,8 @@ dacp_reply_playqueueedit(struct evhttp_request *req, struct evbuffer *evbuf, cha ?command=move&edit-params='edit-param.move-pair:3,0'&session-id=100 -> move song from playqueue position 3 to be played after song at position 0 + ?command=remove&items=1&session-id=100 + -> remove song on position 1 from the playqueue */ s = daap_session_find(req, query, evbuf); @@ -1530,6 +1564,8 @@ dacp_reply_playqueueedit(struct evhttp_request *req, struct evbuffer *evbuf, cha dacp_reply_playqueueedit_add(req, evbuf, uri, query); else if (strcmp(param, "move") == 0) dacp_reply_playqueueedit_move(req, evbuf, uri, query); + else if (strcmp(param, "remove") == 0) + dacp_reply_playqueueedit_remove(req, evbuf, uri, query); else { DPRINTF(E_LOG, L_DACP, "Unknown playqueue-edit command %s\n", param); diff --git a/src/player.c b/src/player.c index e93557e1..7a12f558 100644 --- a/src/player.c +++ b/src/player.c @@ -3421,6 +3421,42 @@ static int queue_move(struct player_command *cmd) return 0; } +static int queue_remove(struct player_command *cmd) +{ + struct player_source *ps_src = NULL; + + DPRINTF(E_LOG, L_PLAYER, "Remove song from position %d\n", cmd->arg.ps_pos[0]); + + struct player_source *ps_tmp = cur_playing ? cur_playing : cur_streaming; + if (!ps_tmp) + { + DPRINTF(E_DBG, L_PLAYER, "Current playing/streaming song not found\n"); + return 0; + } + + int i = 0; + for (i = 0; i <= cmd->arg.ps_pos[0]; ++i) + { + if (i == cmd->arg.ps_pos[0]) + ps_src = ps_tmp; + + ps_tmp = shuffle ? ps_tmp->shuffle_next : ps_tmp->pl_next; + } + + if (ps_src) + { + ps_src->shuffle_prev->shuffle_next = ps_src->shuffle_next; + ps_src->shuffle_next->shuffle_prev = ps_src->shuffle_prev; + + ps_src->pl_prev->pl_next = ps_src->pl_next; + ps_src->pl_next->pl_prev = ps_src->pl_prev; + + source_free(ps_src); + } + + return 0; +} + static int queue_clear(struct player_command *cmd) { @@ -3914,6 +3950,24 @@ player_queue_move(int ps_pos_from, int ps_pos_to) return ret; } +int player_queue_remove(int ps_pos_remove) +{ + struct player_command cmd; + int ret; + + command_init(&cmd); + + cmd.func = queue_remove; + cmd.func_bh = NULL; + cmd.arg.ps_pos[0] = ps_pos_remove; + + ret = sync_command(&cmd); + + command_deinit(&cmd); + + return ret; +} + void player_queue_clear(void) { diff --git a/src/player.h b/src/player.h index 2c8c3bda..8b9f7aa5 100644 --- a/src/player.h +++ b/src/player.h @@ -148,6 +148,9 @@ player_queue_add(struct player_source *ps); int player_queue_move(int ps_pos_from, int ps_pos_to); +int +player_queue_remove(int ps_pos_remove); + void player_queue_clear(void);