summaryrefslogtreecommitdiff
path: root/amixer
diff options
context:
space:
mode:
Diffstat (limited to 'amixer')
-rw-r--r--amixer/amixer.c176
1 files changed, 95 insertions, 81 deletions
diff --git a/amixer/amixer.c b/amixer/amixer.c
index a839e1e..9c15f8c 100644
--- a/amixer/amixer.c
+++ b/amixer/amixer.c
@@ -1369,67 +1369,35 @@ static int get_enum_item_index(snd_mixer_elem_t *elem, char **ptrp)
return -1;
}
-static int sset(unsigned int argc, char *argv[], int roflag, int keep_handle)
+static int sset_enum(snd_mixer_elem_t *elem, unsigned int argc, char **argv)
{
- int err, check_flag;
- unsigned int idx;
- snd_mixer_selem_channel_id_t chn;
- unsigned int channels = ~0U;
- unsigned int dir = 3, okflag = 3;
- static snd_mixer_t *handle = NULL;
- snd_mixer_elem_t *elem;
- snd_mixer_selem_id_t *sid;
- snd_mixer_selem_id_alloca(&sid);
+ unsigned int idx, chn = 0;
+ int check_flag = -1;
- if (argc < 1) {
- fprintf(stderr, "Specify a scontrol identifier: 'name',index\n");
- return 1;
- }
- if (parse_simple_id(argv[0], sid)) {
- fprintf(stderr, "Wrong scontrol identifier: %s\n", argv[0]);
- return 1;
- }
- if (!roflag && argc < 2) {
- fprintf(stderr, "Specify what you want to set...\n");
- return 1;
- }
- if (handle == NULL) {
- if ((err = snd_mixer_open(&handle, 0)) < 0) {
- error("Mixer %s open error: %s\n", card, snd_strerror(err));
- return err;
- }
- if (smixer_level == 0 && (err = snd_mixer_attach(handle, card)) < 0) {
- error("Mixer attach %s error: %s", card, snd_strerror(err));
- snd_mixer_close(handle);
- handle = NULL;
- return err;
- }
- if ((err = snd_mixer_selem_register(handle, smixer_level > 0 ? &smixer_options : NULL, NULL)) < 0) {
- error("Mixer register error: %s", snd_strerror(err));
- snd_mixer_close(handle);
- handle = NULL;
- return err;
- }
- err = snd_mixer_load(handle);
- if (err < 0) {
- error("Mixer %s load error: %s", card, snd_strerror(err));
- snd_mixer_close(handle);
- handle = NULL;
- return err;
+ for (idx = 1; idx < argc; idx++) {
+ char *ptr = argv[idx];
+ while (*ptr) {
+ int ival = get_enum_item_index(elem, &ptr);
+ if (ival < 0)
+ return check_flag;
+ if (snd_mixer_selem_set_enum_item(elem, chn, ival) >= 0)
+ check_flag = 1;
+ /* skip separators */
+ while (*ptr == ',' || isspace(*ptr))
+ ptr++;
}
}
- elem = snd_mixer_find_selem(handle, sid);
- if (!elem) {
- if (ignore_error)
- return 0;
- error("Unable to find simple control '%s',%i\n", snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid));
- snd_mixer_close(handle);
- handle = NULL;
- return -ENOENT;
- }
- if (roflag)
- goto __skip_write;
- check_flag = 0;
+ return check_flag;
+}
+
+static int sset_channels(snd_mixer_elem_t *elem, unsigned int argc, char **argv)
+{
+ unsigned int channels = ~0U;
+ unsigned int dir = 3, okflag = 3;
+ unsigned int idx;
+ snd_mixer_selem_channel_id_t chn;
+ int check_flag = -1;
+
for (idx = 1; idx < argc; idx++) {
char *ptr = argv[idx], *optr;
int multi, firstchn = 1;
@@ -1447,19 +1415,6 @@ static int sset(unsigned int argc, char *argv[], int roflag, int keep_handle)
if (!(channels & (1 << chn)))
continue;
- /* enum control */
- if (snd_mixer_selem_is_enumerated(elem)) {
- int idx = get_enum_item_index(elem, &ptr);
- if (idx < 0) {
- break;
- } else {
- if (snd_mixer_selem_set_enum_item(elem, chn, idx) >= 0)
- check_flag = 1;
- }
- if (!multi)
- ptr = optr;
- continue;
- }
if ((dir & 1) && snd_mixer_selem_has_playback_channel(elem, chn)) {
sptr = ptr;
@@ -1540,35 +1495,94 @@ static int sset(unsigned int argc, char *argv[], int roflag, int keep_handle)
if (dir & 2)
error("Unknown capture setup '%s'..", ptr);
}
- if (! keep_handle) {
- snd_mixer_close(handle);
- handle = NULL;
- }
- return 0;
+ return 0; /* just skip it */
}
if (!multi)
ptr = optr;
firstchn = 0;
}
}
- if (!check_flag) {
- error("Invalid command!");
- if (! keep_handle) {
+ return check_flag;
+}
+
+static int sset(unsigned int argc, char *argv[], int roflag, int keep_handle)
+{
+ int err = 0;
+ static snd_mixer_t *handle = NULL;
+ snd_mixer_elem_t *elem;
+ snd_mixer_selem_id_t *sid;
+ snd_mixer_selem_id_alloca(&sid);
+
+ if (argc < 1) {
+ fprintf(stderr, "Specify a scontrol identifier: 'name',index\n");
+ return 1;
+ }
+ if (parse_simple_id(argv[0], sid)) {
+ fprintf(stderr, "Wrong scontrol identifier: %s\n", argv[0]);
+ return 1;
+ }
+ if (!roflag && argc < 2) {
+ fprintf(stderr, "Specify what you want to set...\n");
+ return 1;
+ }
+ if (handle == NULL) {
+ if ((err = snd_mixer_open(&handle, 0)) < 0) {
+ error("Mixer %s open error: %s\n", card, snd_strerror(err));
+ return err;
+ }
+ if (smixer_level == 0 && (err = snd_mixer_attach(handle, card)) < 0) {
+ error("Mixer attach %s error: %s", card, snd_strerror(err));
snd_mixer_close(handle);
handle = NULL;
+ return err;
+ }
+ if ((err = snd_mixer_selem_register(handle, smixer_level > 0 ? &smixer_options : NULL, NULL)) < 0) {
+ error("Mixer register error: %s", snd_strerror(err));
+ snd_mixer_close(handle);
+ handle = NULL;
+ return err;
+ }
+ err = snd_mixer_load(handle);
+ if (err < 0) {
+ error("Mixer %s load error: %s", card, snd_strerror(err));
+ snd_mixer_close(handle);
+ handle = NULL;
+ return err;
+ }
+ }
+ elem = snd_mixer_find_selem(handle, sid);
+ if (!elem) {
+ if (ignore_error)
+ return 0;
+ error("Unable to find simple control '%s',%i\n", snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid));
+ snd_mixer_close(handle);
+ handle = NULL;
+ return -ENOENT;
+ }
+ if (!roflag) {
+ /* enum control */
+ if (snd_mixer_selem_is_enumerated(elem))
+ err = sset_enum(elem, argc, argv);
+ else
+ err = sset_channels(elem, argc, argv);
+
+ if (!err)
+ goto done;
+ if (err < 0) {
+ error("Invalid command!");
+ goto done;
}
- return 1;
}
- __skip_write:
if (!quiet) {
printf("Simple mixer control '%s',%i\n", snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid));
show_selem(handle, sid, " ", 1);
}
+ done:
if (! keep_handle) {
snd_mixer_close(handle);
handle = NULL;
}
- return 0;
+ return err < 0 ? 1 : 0;
}
static void events_info(snd_hctl_elem_t *helem)