mirror of
https://github.com/owntone/owntone-server.git
synced 2025-02-26 04:49:18 -05:00
[mpd] Refactor commands to enable/disable/toggle/volume for outputs
This commit is contained in:
parent
decf9f1329
commit
43887d160f
323
src/mpd.c
323
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 }
|
||||
|
Loading…
x
Reference in New Issue
Block a user