From 43887d160fcdc58c8185bc7401a5f2c700a1ecf1 Mon Sep 17 00:00:00 2001 From: chme Date: Wed, 7 Feb 2018 23:06:41 +0100 Subject: [PATCH] [mpd] Refactor commands to enable/disable/toggle/volume for outputs --- src/mpd.c | 323 +++++++++++++----------------------------------------- 1 file changed, 74 insertions(+), 249 deletions(-) diff --git a/src/mpd.c b/src/mpd.c index 4754a57a..4ed69eb1 100644 --- a/src/mpd.c +++ b/src/mpd.c @@ -212,31 +212,21 @@ struct output char *name; unsigned selected; - - struct output *next; }; -struct outputs +struct output_get_param { - unsigned int count; - unsigned int active; - struct output *outputs; + unsigned short shortid; + struct output *output; }; static void -free_outputs(struct output *outputs) +free_output(struct output *output) { - struct output *temp; - struct output *next; - - temp = outputs; - next = outputs ? outputs->next : NULL; - while (temp) + if (output) { - free(temp->name); - free(temp); - temp = next; - next = next ? next->next : NULL; + free(output->name); + free(output); } } @@ -3575,28 +3565,23 @@ mpd_command_password(struct evbuffer *evbuf, int argc, char **argv, char **errms * the shortid of output_get_param matches the given speaker/output spk. */ static void -outputs_enum_cb(struct spk_info *spk, void *arg) +output_get_cb(struct spk_info *spk, void *arg) { - struct outputs *outputs; - struct output *output; + struct output_get_param *param = arg; - outputs = (struct outputs *)arg; + if (!param->output + && param->shortid == (unsigned short) spk->id) + { + param->output = calloc(1, sizeof(struct output)); - output = (struct output*)malloc(sizeof(struct output)); + param->output->id = spk->id; + param->output->shortid = (unsigned short) spk->id; + param->output->name = strdup(spk->name); + param->output->selected = spk->selected; - output->id = spk->id; - output->shortid = (unsigned short) spk->id; - output->name = strdup(spk->name); - output->selected = spk->selected; - - output->next = outputs->outputs; - outputs->outputs = output; - outputs->count++; - if (spk->selected) - outputs->active++; - - DPRINTF(E_DBG, L_MPD, "Output enum: shortid %d, id %" PRIu64 ", name '%s', selected %d\n", - output->shortid, output->id, output->name, output->selected); + DPRINTF(E_DBG, L_MPD, "Output found: shortid %d, id %" PRIu64 ", name '%s', selected %d\n", + param->output->shortid, param->output->id, param->output->name, param->output->selected); + } } /* @@ -3606,20 +3591,10 @@ outputs_enum_cb(struct spk_info *spk, void *arg) static int mpd_command_disableoutput(struct evbuffer *evbuf, int argc, char **argv, char **errmsg, struct mpd_client_ctx *ctx) { - struct outputs outputs; - struct output *output; + struct output_get_param param; uint32_t num; - uint64_t *ids; - int nspk; - int i; int ret; - if (argc < 2) - { - *errmsg = safe_asprintf("Missing argument for command 'disableoutput'"); - return ACK_ERROR_ARG; - } - ret = safe_atou32(argv[1], &num); if (ret < 0) { @@ -3627,57 +3602,21 @@ mpd_command_disableoutput(struct evbuffer *evbuf, int argc, char **argv, char ** return ACK_ERROR_ARG; } - outputs.count = 0; - outputs.active = 0; - outputs.outputs = NULL; + memset(¶m, 0, sizeof(struct output_get_param)); + param.shortid = num; - player_speaker_enumerate(outputs_enum_cb, &outputs); + player_speaker_enumerate(output_get_cb, ¶m); - nspk = outputs.active; - output = outputs.outputs; - while (output) + if (param.output && param.output->selected) { - if (output->shortid == num && output->selected) + ret = player_speaker_disable(param.output->id); + free_output(param.output); + + if (ret < 0) { - nspk--; - break; + *errmsg = safe_asprintf("Speakers deactivation failed: %d", num); + return ACK_ERROR_UNKNOWN; } - output = output->next; - } - - if (nspk == outputs.active) - { - DPRINTF(E_LOG, L_MPD, "No speaker to deactivate\n"); - free_outputs(outputs.outputs); - return 0; - } - - ids = (uint64_t *)malloc((nspk + 1) * sizeof(uint64_t)); - - ids[0] = nspk; - - i = 1; - output = outputs.outputs; - while (output) - { - if (output->shortid != num && output->selected) - { - ids[i] = output->id; - i++; - } - - output = output->next; - } - - ret = player_speaker_set(ids); - - free(ids); - free_outputs(outputs.outputs); - - if (ret < 0) - { - *errmsg = safe_asprintf("Speakers deactivation failed: %d", num); - return ACK_ERROR_UNKNOWN; } return 0; @@ -3690,20 +3629,10 @@ mpd_command_disableoutput(struct evbuffer *evbuf, int argc, char **argv, char ** static int mpd_command_enableoutput(struct evbuffer *evbuf, int argc, char **argv, char **errmsg, struct mpd_client_ctx *ctx) { - struct outputs outputs; - struct output *output; + struct output_get_param param; uint32_t num; - uint64_t *ids; - int nspk; - int i; int ret; - if (argc < 2) - { - *errmsg = safe_asprintf("Missing argument for command 'enableoutput'"); - return ACK_ERROR_ARG; - } - ret = safe_atou32(argv[1], &num); if (ret < 0) { @@ -3711,58 +3640,21 @@ mpd_command_enableoutput(struct evbuffer *evbuf, int argc, char **argv, char **e return ACK_ERROR_ARG; } - outputs.count = 0; - outputs.active = 0; - outputs.outputs = NULL; + memset(¶m, 0, sizeof(struct output_get_param)); + param.shortid = num; - player_speaker_enumerate(outputs_enum_cb, &outputs); + player_speaker_enumerate(output_get_cb, ¶m); - nspk = outputs.active; - output = outputs.outputs; - while (output) + if (param.output && !param.output->selected) { - if (output->shortid == num && !output->selected) + ret = player_speaker_enable(param.output->id); + free_output(param.output); + + if (ret < 0) { - nspk++; - break; + *errmsg = safe_asprintf("Speakers deactivation failed: %d", num); + return ACK_ERROR_UNKNOWN; } - output = output->next; - } - - if (nspk == outputs.active) - { - DPRINTF(E_LOG, L_MPD, "No speaker to activate\n"); - free_outputs(outputs.outputs); - return 0; - } - - ids = (uint64_t *)malloc((nspk + 1) * sizeof(uint64_t)); - - ids[0] = nspk; - - i = 1; - output = outputs.outputs; - while (output) - { - if (output->shortid == num || output->selected) - { - ids[i] = output->id; - i++; - } - - output = output->next; - } - - ret = player_speaker_set(ids); - - if (ids) - free(ids); - free_outputs(outputs.outputs); - - if (ret < 0) - { - *errmsg = safe_asprintf("Speakers activation failed: %d", num); - return ACK_ERROR_UNKNOWN; } return 0; @@ -3775,20 +3667,10 @@ mpd_command_enableoutput(struct evbuffer *evbuf, int argc, char **argv, char **e static int mpd_command_toggleoutput(struct evbuffer *evbuf, int argc, char **argv, char **errmsg, struct mpd_client_ctx *ctx) { - struct outputs outputs; - struct output *output; + struct output_get_param param; uint32_t num; - uint64_t *ids; - int nspk; - int i; int ret; - if (argc < 2) - { - *errmsg = safe_asprintf("Missing argument for command 'toggleoutput'"); - return ACK_ERROR_ARG; - } - ret = safe_atou32(argv[1], &num); if (ret < 0) { @@ -3796,64 +3678,25 @@ mpd_command_toggleoutput(struct evbuffer *evbuf, int argc, char **argv, char **e return ACK_ERROR_ARG; } - outputs.count = 0; - outputs.active = 0; - outputs.outputs = NULL; + memset(¶m, 0, sizeof(struct output_get_param)); + param.shortid = num; - player_speaker_enumerate(outputs_enum_cb, &outputs); + player_speaker_enumerate(output_get_cb, ¶m); - nspk = outputs.active; - output = outputs.outputs; - while (output) + if (param.output) { - if (output->shortid == num && !output->selected) + if (param.output->selected) + ret = player_speaker_disable(param.output->id); + else + ret = player_speaker_enable(param.output->id); + + free_output(param.output); + + if (ret < 0) { - nspk++; - break; + *errmsg = safe_asprintf("Toggle speaker failed: %d", num); + return ACK_ERROR_UNKNOWN; } - else if (output->shortid == num && output->selected) - { - nspk--; - break; - } - output = output->next; - } - - if (nspk == outputs.active) - { - DPRINTF(E_LOG, L_MPD, "No speaker to de/activate\n"); - free_outputs(outputs.outputs); - return 0; - } - - ids = (uint64_t *)malloc((nspk + 1) * sizeof(uint64_t)); - - ids[0] = nspk; - - i = 1; - output = outputs.outputs; - while (output) - { - if ((output->shortid == num && !output->selected) - || (output->shortid != num && output->selected)) - { - ids[i] = output->id; - i++; - } - - output = output->next; - } - - ret = player_speaker_set(ids); - - if (ids) - free(ids); - free_outputs(outputs.outputs); - - if (ret < 0) - { - *errmsg = safe_asprintf("Speakers de/activation failed: %d", num); - return ACK_ERROR_UNKNOWN; } return 0; @@ -3888,7 +3731,7 @@ speaker_enum_cb(struct spk_info *spk, void *arg) } /* - * Command handler function for 'outputs' + * Command handler function for 'output' * Returns a lists with the avaiable speakers. */ static int @@ -3902,43 +3745,31 @@ mpd_command_outputs(struct evbuffer *evbuf, int argc, char **argv, char **errmsg static int outputvolume_set(uint32_t shortid, int volume, char **errmsg) { - struct outputs outputs; - struct output *output; + struct output_get_param param; int ret; - outputs.count = 0; - outputs.active = 0; - outputs.outputs = NULL; + memset(¶m, 0, sizeof(struct output_get_param)); + param.shortid = shortid; - player_speaker_enumerate(outputs_enum_cb, &outputs); + player_speaker_enumerate(output_get_cb, ¶m); - output = outputs.outputs; - while (output) + if (param.output) { - if (output->shortid == shortid) + ret = player_volume_setabs_speaker(param.output->id, volume); + free_output(param.output); + + if (ret < 0) { - break; + *errmsg = safe_asprintf("Setting volume to %d for speaker with short-id %d failed", volume, shortid); + return ACK_ERROR_UNKNOWN; } - output = output->next; } - - if (!output) + else { - free_outputs(outputs.outputs); *errmsg = safe_asprintf("No speaker found for short id: %d", shortid); return ACK_ERROR_UNKNOWN; } - ret = player_volume_setabs_speaker(output->id, volume); - - free_outputs(outputs.outputs); - - if (ret < 0) - { - *errmsg = safe_asprintf("Setting volume to %d for speaker with short-id %d failed", volume, shortid); - return ACK_ERROR_UNKNOWN; - } - return 0; } @@ -3949,12 +3780,6 @@ mpd_command_outputvolume(struct evbuffer *evbuf, int argc, char **argv, char **e int volume; int ret; - if (argc < 3) - { - *errmsg = safe_asprintf("Missing argument for command 'outputvolume'"); - return ACK_ERROR_ARG; - } - ret = safe_atou32(argv[1], &shortid); if (ret < 0) { @@ -4335,9 +4160,9 @@ static struct mpd_command mpd_handlers[] = { "ping", mpd_command_ignore, -1 }, // Audio output devices - { "disableoutput", mpd_command_disableoutput, -1 }, - { "enableoutput", mpd_command_enableoutput, -1 }, - { "toggleoutput", mpd_command_toggleoutput, -1 }, + { "disableoutput", mpd_command_disableoutput, 2 }, + { "enableoutput", mpd_command_enableoutput, 2 }, + { "toggleoutput", mpd_command_toggleoutput, 2 }, { "outputs", mpd_command_outputs, -1 }, // Reflection @@ -4356,7 +4181,7 @@ static struct mpd_command mpd_handlers[] = { "sendmessage", mpd_command_sendmessage, -1 }, // Forked-daapd commands (not supported by mpd) - { "outputvolume", mpd_command_outputvolume, -1 }, + { "outputvolume", mpd_command_outputvolume, 3 }, // NULL command to terminate loop { NULL, NULL, -1 }