Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/mixer/mixer.c
Show All 18 Lines | |||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
* THE SOFTWARE. | * THE SOFTWARE. | ||||
* | * | ||||
* $FreeBSD$ | * $FreeBSD$ | ||||
*/ | */ | ||||
#include <err.h> | #include <err.h> | ||||
#include <errno.h> | #include <errno.h> | ||||
#include <mixer.h> | |||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
#include <mixer.h> | #define C_VOL 0 | ||||
#define C_MUT 1 | |||||
#define C_SRC 2 | |||||
static void usage(void) __dead2; | static void usage(void) __dead2; | ||||
static void initctls(struct mixer *); | static void initctls(struct mixer *); | ||||
static void printall(struct mixer *, int); | static void printall(struct mixer *, int); | ||||
static void printminfo(struct mixer *, int); | static void printminfo(struct mixer *, int); | ||||
static void printdev(struct mixer *, int); | static void printdev(struct mixer *, int); | ||||
static void printrecsrc(struct mixer *, int); /* XXX: change name */ | static void printrecsrc(struct mixer *, int); /* XXX: change name */ | ||||
/* Control handlers */ | /* Control handlers */ | ||||
Show All 14 Lines | |||||
}; | }; | ||||
int | int | ||||
main(int argc, char *argv[]) | main(int argc, char *argv[]) | ||||
{ | { | ||||
struct mixer *m; | struct mixer *m; | ||||
mix_ctl_t *cp; | mix_ctl_t *cp; | ||||
char *name = NULL, buf[NAME_MAX]; | char *name = NULL, buf[NAME_MAX]; | ||||
char *p, *bufp, *devstr, *ctlstr, *valstr = NULL; | char *p, *q, *devstr, *ctlstr, *valstr = NULL; | ||||
int dunit, i, n, pall = 1; | int dunit, i, n, pall = 1; | ||||
int aflag = 0, dflag = 0, oflag = 0, sflag = 0; | int aflag = 0, dflag = 0, oflag = 0, sflag = 0; | ||||
int ch; | int ch; | ||||
while ((ch = getopt(argc, argv, "ad:f:hos")) != -1) { | while ((ch = getopt(argc, argv, "ad:f:hos")) != -1) { | ||||
switch (ch) { | switch (ch) { | ||||
case 'a': | case 'a': | ||||
aflag = 1; | aflag = 1; | ||||
break; | break; | ||||
case 'd': | case 'd': | ||||
dunit = strtol(optarg, NULL, 10); | dunit = strtol(optarg, NULL, 10); | ||||
if (errno == EINVAL || errno == ERANGE) | if (errno == EINVAL || errno == ERANGE) | ||||
err(1, "strtol"); | err(1, "strtol"); | ||||
dflag = 1; | dflag = 1; | ||||
break; | break; | ||||
case 'f': | case 'f': | ||||
name = optarg; | name = optarg; | ||||
break; | break; | ||||
case 'o': | case 'o': | ||||
oflag = 1; | oflag = 1; | ||||
break; | break; | ||||
case 's': | case 's': | ||||
sflag = 1; | sflag = 1; | ||||
break; | break; | ||||
case 'h': /* FALLTROUGH */ | case 'h': /* FALLTHROUGH */ | ||||
case '?': | case '?': | ||||
default: | default: | ||||
usage(); | usage(); | ||||
} | } | ||||
} | } | ||||
argc -= optind; | argc -= optind; | ||||
argv += optind; | argv += optind; | ||||
Show All 28 Lines | main(int argc, char *argv[]) | ||||
if (sflag) { | if (sflag) { | ||||
printrecsrc(m, oflag); | printrecsrc(m, oflag); | ||||
(void)mixer_close(m); | (void)mixer_close(m); | ||||
return (0); | return (0); | ||||
} | } | ||||
parse: | parse: | ||||
while (argc > 0) { | while (argc > 0) { | ||||
if ((p = bufp = strdup(*argv)) == NULL) | if ((p = strdup(*argv)) == NULL) | ||||
err(1, "strdup(%s)", *argv); | err(1, "strdup(%s)", *argv); | ||||
/* Split the string into device, control and value. */ | /* Split the string into device, control and value. */ | ||||
devstr = strsep(&p, "."); | devstr = strsep(&p, ".="); | ||||
if ((m->dev = mixer_get_dev_byname(m, devstr)) == NULL) { | if ((m->dev = mixer_get_dev_byname(m, devstr)) == NULL) { | ||||
warnx("%s: no such device", devstr); | warnx("%s: no such device", devstr); | ||||
goto next; | goto next; | ||||
} | } | ||||
/* Input: `dev`. */ | /* Input: `dev`. */ | ||||
if (p == NULL) { | if (p == NULL) { | ||||
printdev(m, 1); | printdev(m, 1); | ||||
pall = 0; | pall = 0; | ||||
goto next; | goto next; | ||||
} else { | |||||
for (q = p; (*q >= '0' && *q <= '9') || *q == '.'; q++) | |||||
hselasky: Should this loop also check for "." characters, so that you can either do:
dev=80 or dev = 0. | |||||
Done Inline ActionsIt should. I totally forgot about that. My bad :-) christos: It should. I totally forgot about that. My bad :-) | |||||
; /* nothing */ | |||||
/* Input: `dev=N` -> shorthand for `dev.volume=N`. */ | |||||
if (*q == '\0') { | |||||
cp = mixer_get_ctl(m->dev, C_VOL); | |||||
cp->mod(cp->parent_dev, p); | |||||
goto next; | |||||
} | } | ||||
} | |||||
ctlstr = strsep(&p, "="); | ctlstr = strsep(&p, "="); | ||||
if ((cp = mixer_get_ctl_byname(m->dev, ctlstr)) == NULL) { | if ((cp = mixer_get_ctl_byname(m->dev, ctlstr)) == NULL) { | ||||
warnx("%s.%s: no such control", devstr, ctlstr); | warnx("%s.%s: no such control", devstr, ctlstr); | ||||
goto next; | goto next; | ||||
} | } | ||||
/* Input: `dev.control`. */ | /* Input: `dev.control`. */ | ||||
if (p == NULL) { | if (p == NULL) { | ||||
Show All 27 Lines | |||||
} | } | ||||
static void | static void | ||||
initctls(struct mixer *m) | initctls(struct mixer *m) | ||||
{ | { | ||||
struct mix_dev *dp; | struct mix_dev *dp; | ||||
int rc = 0; | int rc = 0; | ||||
#define C_VOL 0 | |||||
#define C_MUT 1 | |||||
#define C_SRC 2 | |||||
TAILQ_FOREACH(dp, &m->devs, devs) { | TAILQ_FOREACH(dp, &m->devs, devs) { | ||||
rc += mixer_add_ctl(dp, C_VOL, "volume", mod_volume, print_volume); | rc += mixer_add_ctl(dp, C_VOL, "volume", mod_volume, print_volume); | ||||
rc += mixer_add_ctl(dp, C_MUT, "mute", mod_mute, print_mute); | rc += mixer_add_ctl(dp, C_MUT, "mute", mod_mute, print_mute); | ||||
rc += mixer_add_ctl(dp, C_SRC, "recsrc", mod_recsrc, print_recsrc); | rc += mixer_add_ctl(dp, C_SRC, "recsrc", mod_recsrc, print_recsrc); | ||||
} | } | ||||
if (rc) { | if (rc) { | ||||
(void)mixer_close(m); | (void)mixer_close(m); | ||||
err(1, "cannot make controls"); | err(1, "cannot make controls"); | ||||
▲ Show 20 Lines • Show All 78 Lines • ▼ Show 20 Lines | if (!oflag) | ||||
printf("%s: ", m->mi.name); | printf("%s: ", m->mi.name); | ||||
TAILQ_FOREACH(dp, &m->devs, devs) { | TAILQ_FOREACH(dp, &m->devs, devs) { | ||||
if (MIX_ISRECSRC(m, dp->devno)) { | if (MIX_ISRECSRC(m, dp->devno)) { | ||||
if (n++ && !oflag) | if (n++ && !oflag) | ||||
printf(", "); | printf(", "); | ||||
printf("%s", dp->name); | printf("%s", dp->name); | ||||
if (oflag) | if (oflag) | ||||
printf(".%s=+%s", | printf(".%s=+%s", | ||||
mixer_get_ctl(dp, C_SRC)->name, | mixer_get_ctl(dp, C_SRC)->name, n ? " " : ""); | ||||
n ? " " : ""); | |||||
} | } | ||||
} | } | ||||
printf("\n"); | printf("\n"); | ||||
} | } | ||||
static int | static int | ||||
mod_dunit(struct mix_dev *d, void *p) | mod_dunit(struct mix_dev *d, void *p) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 193 Lines • Show Last 20 Lines |
Should this loop also check for "." characters, so that you can either do:
dev=80 or dev = 0.80 ?
--HPS