From ec9ecfc6fa8963cfda62b49108f0d7fa1264b887 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 9 Sep 2002 14:27:18 +0000 Subject: [PATCH] added the handling of enum controls, using the recent addition to alsa-lib. now alsamixer can control the enumerated items, such like ice1712's routing table. not implemented: enum items with more than two channels. --- alsamixer/alsamixer.c | 110 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 91 insertions(+), 19 deletions(-) diff --git a/alsamixer/alsamixer.c b/alsamixer/alsamixer.c index 1184725..f27bd36 100644 --- a/alsamixer/alsamixer.c +++ b/alsamixer/alsamixer.c @@ -200,6 +200,7 @@ enum { MIXER_ELEM_FRONT, MIXER_ELEM_REAR, MIXER_ELEM_CENTER, MIXER_ELEM_WOOFER, MIXER_ELEM_CAPTURE, + MIXER_ELEM_ENUM, MIXER_ELEM_END }; @@ -207,6 +208,7 @@ enum { #define MIXER_ELEM_CAPTURE_SWITCH 0x100 /* bit */ #define MIXER_ELEM_MUTE_SWITCH 0x200 /* bit */ #define MIXER_ELEM_CAPTURE_SUFFIX 0x400 +#define MIXER_ELEM_HAS_VOLUME 0x800 /* left and right channels for each type */ static snd_mixer_selem_channel_id_t mixer_elem_chn[][2] = { @@ -484,7 +486,7 @@ mixer_calc_volume(snd_mixer_elem_t *elem, if (type != MIXER_ELEM_CAPTURE) snd_mixer_selem_get_playback_volume_range(elem, &min, &max); else - snd_mixer_selem_get_capture_volume_range(elem, &min, &max); + snd_mixer_selem_get_capture_volume_range(elem, &min, &max); vol1 = (vol < 0) ? -vol : vol; if (vol1 > 0) { if (vol1 > 100) @@ -504,6 +506,27 @@ mixer_calc_volume(snd_mixer_elem_t *elem, return CLAMP(vol1, min, max); } +/* update enum list */ +static void update_enum_list(snd_mixer_elem_t *elem, int chn, int delta) +{ + int eidx; + if (snd_mixer_selem_get_enum_item(elem, chn, &eidx) < 0) + return; + if (delta < 0) { + eidx--; + if (eidx < 0) + return; + } else { + int items = snd_mixer_selem_get_enum_items(elem); + if (items < 0) + return; + eidx++; + if (eidx >= items) + return; + } + snd_mixer_selem_set_enum_item(elem, chn, eidx); +} + /* set new channel values */ static void @@ -541,8 +564,7 @@ mixer_write_cbar (int elem_index) if ((mixer_volume_delta[MIXER_CHN_LEFT] || mixer_volume_delta[MIXER_CHN_RIGHT] || mixer_balance_volumes) && - ((type != MIXER_ELEM_CAPTURE && snd_mixer_selem_has_playback_volume(elem)) || - (type == MIXER_ELEM_CAPTURE && snd_mixer_selem_has_capture_volume(elem)))) { + (mixer_type[elem_index] & MIXER_ELEM_HAS_VOLUME)) { int mono; int joined; mono = (chn_right == SND_MIXER_SCHN_UNKNOWN); @@ -597,8 +619,6 @@ mixer_write_cbar (int elem_index) } } } - mixer_volume_delta[MIXER_CHN_LEFT] = mixer_volume_delta[MIXER_CHN_RIGHT] = 0; - mixer_balance_volumes = 0; /* mute */ @@ -645,9 +665,46 @@ mixer_write_cbar (int elem_index) } } mixer_toggle_capture = 0; + + /* enum list + */ + if (type == MIXER_ELEM_ENUM) { + if (mixer_volume_delta[MIXER_CHN_LEFT]) + update_enum_list(elem, MIXER_CHN_LEFT, mixer_volume_delta[MIXER_CHN_LEFT]); + if (mixer_volume_delta[MIXER_CHN_RIGHT]) + update_enum_list(elem, MIXER_CHN_RIGHT, mixer_volume_delta[MIXER_CHN_RIGHT]); + } + + mixer_volume_delta[MIXER_CHN_LEFT] = mixer_volume_delta[MIXER_CHN_RIGHT] = 0; + mixer_balance_volumes = 0; } +static void display_enum_list(snd_mixer_elem_t *elem, int y, int x) +{ + int i, cury, ch, err; + + /* clear */ + mixer_dc(DC_TEXT); + for (i = mixer_cbar_height + 3, cury = y; i > 0; i--, cury--) + mvaddstr(cury, x, " "); + + cury = y - 4; + for (ch = 0; ch < 2; ch++) { + int eidx, ofs; + char tmp[9]; + err = snd_mixer_selem_get_enum_item(elem, ch, &eidx); + if (err < 0) + break; + if (snd_mixer_selem_get_enum_item_name(elem, eidx, sizeof(tmp) - 1, tmp) < 0) + break; + tmp[8] = 0; + ofs = (8 - strlen(tmp)) / 2; + mvaddstr(cury, x + ofs, tmp); + cury += 2; + } +} + static void mixer_update_cbar (int elem_index) { @@ -761,17 +818,24 @@ mixer_update_cbar (int elem_index) */ mixer_dc (DC_BACK); mvaddstr (y, x, " "); - mixer_dc (DC_TEXT); - sprintf (string, "%ld", vleft); - mvaddstr (y, x + 3 - strlen (string), string); - mixer_dc (DC_CBAR_FRAME); - mvaddch (y, x + 3, '<'); - mvaddch (y, x + 4, '>'); - mixer_dc (DC_TEXT); - sprintf (string, "%ld", vright); - mvaddstr (y, x + 5, string); + if (mixer_type[elem_index] & MIXER_ELEM_HAS_VOLUME) { + mixer_dc (DC_TEXT); + sprintf (string, "%ld", vleft); + mvaddstr (y, x + 3 - strlen (string), string); + mixer_dc (DC_CBAR_FRAME); + mvaddch (y, x + 3, '<'); + mvaddch (y, x + 4, '>'); + mixer_dc (DC_TEXT); + sprintf (string, "%ld", vright); + mvaddstr (y, x + 5, string); + } y--; + if (type == MIXER_ELEM_ENUM) { + display_enum_list(elem, y, x); + return; + } + /* left/right bar */ mixer_dc (DC_CBAR_FRAME); @@ -1444,11 +1508,17 @@ __again: if (ok) { sid = (snd_mixer_selem_id_t *)(((char *)mixer_sid) + snd_mixer_selem_id_sizeof() * idx); mixer_grpidx[elem_index] = idx; - mixer_type[elem_index] = i; - if (i == 0 && snd_mixer_selem_has_playback_switch(elem)) - mixer_type[elem_index] |= MIXER_ELEM_MUTE_SWITCH; - if (i == 0 && snd_mixer_selem_has_capture_switch(elem)) - mixer_type[elem_index] |= MIXER_ELEM_CAPTURE_SWITCH; + if (snd_mixer_selem_is_enumerated(elem)) { + mixer_type[elem_index] = MIXER_ELEM_ENUM; + } else { + mixer_type[elem_index] = i; + if (i == 0 && snd_mixer_selem_has_playback_switch(elem)) + mixer_type[elem_index] |= MIXER_ELEM_MUTE_SWITCH; + if (snd_mixer_selem_has_playback_volume(elem)) + mixer_type[elem_index] |= MIXER_ELEM_HAS_VOLUME; + if (i == 0 && snd_mixer_selem_has_capture_switch(elem)) + mixer_type[elem_index] |= MIXER_ELEM_CAPTURE_SWITCH; + } elem_index++; nelems_added++; if (elem_index >= mixer_n_elems) @@ -1463,6 +1533,8 @@ __again: mixer_type[elem_index] |= MIXER_ELEM_CAPTURE_SWITCH; if (nelems_added) mixer_type[elem_index] |= MIXER_ELEM_CAPTURE_SUFFIX; + if (snd_mixer_selem_has_capture_volume(elem)) + mixer_type[elem_index] |= MIXER_ELEM_HAS_VOLUME; elem_index++; if (elem_index >= mixer_n_elems) break;