/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <strings.h>
#include <locale.h>
#include <libintl.h>
#include <stdarg.h>
#include <stddef.h>
#include <fcntl.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/soundcard.h>
#include <libdevinfo.h>
#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
#endif
#define _(s) gettext(s)
/*
* These are borrowed from sys/audio/audio_common.h, where the values
* are protected by _KERNEL.
*/
#define AUDIO_MINOR_MIXER (0)
/*
* Column display information
* All are related to the types enumerated in col_t and any change should be
* reflected in the corresponding indices and offsets for all the variables
* accordingly. Most tweaks to the display can be done by adjusting the
* values here.
*/
/* types of columns displayed */
/* corresponding sizes of columns; does not include trailing null */
/* corresponding sizes of columns, indexed by col_t value */
static int col_sz[] = {
};
/* used by callers of the printing function */
typedef struct col_prt {
char *col_dv;
char *col_nm;
char *col_val;
char *col_sel;
} col_prt_t;
/* columns displayed in order with vopt = 0 */
/* tells the printing function what members to use; follows col_dpy[] */
};
/* columns displayed in order with vopt = 1 */
/* tells the printing function what members to use; follows col_dpy_vopt[] */
};
/* columns displayed in order with tofile = 1 */
sizeof (*col_dpy_tofile);
/* tells the printing function what members to use; follows col_dpy_tofile[] */
};
/*
* mixer and control accounting
*/
typedef struct cinfo {
} cinfo_t;
typedef struct device {
int cmax;
int mfd;
} device_t;
/*PRINTFLIKE1*/
static void
{
}
/*PRINTFLIKE1*/
static void
{
}
static void
{
int i;
}
if (*dpp) {
}
for (i = 0; i < d->cmax; i++) {
}
if (d->mfd >= 0)
free(d);
}
static void
free_devices(void)
{
free_device(d);
}
}
/*
* adds to the end of global devices and returns a pointer to the new entry
*/
static device_t *
alloc_device(void)
{
device_t *p;
d->mfd = -1;
devices = d;
} else {
p->nextp = d;
}
return (d);
}
/*
* cinfop->enump needs to be present
* idx should be: >= 0 to < cinfop->ci.maxvalue
*/
static char *
{
return (NULL);
}
/*
* caller fills in d->mixer.devnode; func fills in the rest
*/
static int
{
int i;
perror(_("Error opening device"));
return (errno);
}
d->cmax = -1;
perror(_("Error getting control count"));
return (errno);
}
for (i = 0; i < d->cmax; i++) {
perror(_("Error getting control info"));
return (errno);
}
perror(_("Error getting enum info"));
return (errno);
}
}
}
return (0);
}
static int
load_devices(void)
{
int i;
device_t *d;
/* already loaded */
return (0);
}
warn(_("Error opening mixer\n"));
goto OUT;
}
perror(_("Error getting system information"));
goto OUT;
}
d = alloc_device();
continue;
}
free_device(d);
continue;
}
if ((rv = get_device_info(d)) != 0) {
free_device(d);
goto OUT;
}
}
rv = 0;
OUT:
if (fd >= 0)
return (rv);
}
static int
{
switch (type) {
case MIXT_ONOFF:
case MIXT_ENUM:
case MIXT_MONOSLIDER:
case MIXT_STEREOSLIDER:
return (1);
default:
return (0);
}
}
static void
{
int i;
int *col_dpyp;
int col_cnt;
int col_type;
int width;
char *colstr;
} else if (vopt) {
} else {
}
line[0] = '\0';
for (i = 0; i < col_cnt; i++) {
if (i < col_cnt - 1)
}
}
static void
{
if (sfp) {
} else {
}
}
static int
{
char *str;
int i;
perror(_("Error reading control\n"));
return (rv);
}
} else {
return (0);
}
/*
* convert the control value into a string
*/
case MIXT_ONOFF:
break;
case MIXT_MONOSLIDER:
break;
case MIXT_STEREOSLIDER:
break;
case MIXT_ENUM:
warn(_("Bad enum index %d for control '%s'\n"),
return (EINVAL);
}
break;
default:
return (0);
}
/*
*/
case MIXT_ONOFF:
break;
case MIXT_MONOSLIDER:
break;
case MIXT_STEREOSLIDER:
break;
case MIXT_ENUM:
/*
* display the first choice on the same line, then display
* the rest on multiple lines
*/
selbuf[0] = 0;
continue;
sizeof (selbuf)) {
break;
}
}
}
idx = i;
break;
default:
}
}
/* non-verbose mode prints don't display the enum values */
return (0);
}
/* print leftover enum value selections */
selbuf[0] = 0;
continue;
sizeof (selbuf)) {
break;
}
}
}
idx = i;
}
return (0);
}
static int
{
char *str;
int i;
case MIXT_ONOFF:
break;
case MIXT_MONOSLIDER:
break;
case MIXT_STEREOSLIDER:
*rstr = '\0';
rstr++;
rstr--;
*rstr = ':';
} else {
}
break;
case MIXT_ENUM:
continue;
break;
}
}
warn(_("Invalid enumeration value\n"));
return (EINVAL);
}
break;
default:
return (EINVAL);
}
if (vopt) {
}
perror(_("Error writing control"));
return (rv);
}
rv = 0;
return (rv);
}
static void
help(void)
{
#define HELP_STR _( \
"audioctl list-devices\n" \
" list all audio devices\n" \
"\n" \
"audioctl show-device [ -v ] [ -d <device> ]\n" \
" display information about an audio device\n" \
"\n" \
"audioctl show-control [ -v ] [ -d <device> ] [ <control> ... ]\n" \
" get the value of a specific control (all if not specified)\n" \
"\n" \
"audioctl set-control [ -v ] [ -d <device> ] <control> <value>\n" \
" set the value of a specific control\n" \
"\n" \
"audioctl save-controls [ -d <device> ] [ -f ] <file>\n" \
" save all control settings for the device to a file\n" \
"\n" \
"audioctl load-controls [ -d <device> ] <file>\n" \
" restore previously saved control settings to device\n" \
"\n" \
"audioctl help\n" \
" show this message.\n")
}
{
/* Not a device node! */
return (0);
}
}
static device_t *
{
device_t *d;
/*
* User may have specified:
*
*
* We can canonicalize these by looking at the dev_t though.
*/
if (load_devices() != 0) {
return (NULL);
}
}
if (*name == '/') {
/* if we have a full path, convert to the devt */
warn(_("No such audio device.\n"));
return (NULL);
}
}
return (d);
}
return (d);
}
}
warn(_("No such audio device.\n"));
return (NULL);
}
int
{
int optc;
int verbose = 0;
device_t *d;
switch (optc) {
case 'v':
verbose++;
break;
default:
help();
return (-1);
}
}
if (argc != 0) {
help();
return (-1);
}
if (load_devices() != 0) {
return (-1);
}
continue;
if (verbose) {
} else {
}
}
return (0);
}
int
{
int optc;
device_t *d;
switch (optc) {
case 'd':
break;
case 'v':
break;
default:
help();
return (-1);
}
}
if (argc != 0) {
help();
return (-1);
}
return (ENODEV);
}
}
return (0);
}
int
{
int optc;
int rval = 0;
int verbose = 0;
device_t *d;
int i;
int j;
int rv;
char *n;
switch (optc) {
case 'd':
break;
case 'v':
verbose++;
break;
default:
help();
return (-1);
}
}
return (ENODEV);
}
if (argc == 0) {
/* do them all! */
for (i = 0; i < d->cmax; i++) {
}
return (rval);
}
for (i = 0; i < argc; i++) {
for (j = 0; j < d->cmax; j++) {
break;
}
}
/* Didn't find requested control */
if (j == d->cmax) {
}
}
return (rval);
}
int
{
int optc;
int rval = 0;
int verbose = 0;
device_t *d;
char *cname;
char *value;
int i;
int found;
int rv;
char *n;
switch (optc) {
case 'd':
break;
case 'v':
verbose = 1;
break;
default:
help();
return (-1);
}
}
if (argc != 2) {
help();
return (-1);
}
return (ENODEV);
}
continue;
}
found = 1;
}
if (!found) {
}
return (rval);
}
int
{
int optc;
int rval = 0;
device_t *d;
char *fname;
int i;
int rv;
int fd;
int mode;
switch (optc) {
case 'd':
break;
case 'f':
break;
default:
help();
return (-1);
}
}
if (argc != 1) {
help();
return (-1);
}
return (ENODEV);
}
perror(_("Failed to create file"));
return (errno);
}
perror(_("Unable to open file\n"));
return (errno);
}
}
print_header(fp, 0);
for (i = 0; i < d->cmax; i++) {
}
return (rval);
}
int
{
int optc;
int rval = 0;
device_t *d;
char *fname;
char *cname;
char *value;
int i;
int rv;
int lineno = 0;
int found;
switch (optc) {
case 'd':
break;
default:
help();
return (-1);
}
}
if (argc != 1) {
help();
return (-1);
}
return (ENODEV);
}
perror(_("Unable to open file"));
return (errno);
}
lineno++;
/* read in the rest of the line and discard it */
continue;
}
continue;
}
/* we have a good line ... */
/* skip comments and blank lines */
continue;
}
continue;
}
/* save and restore requires an exact match */
continue;
}
found = 1;
}
if (!found) {
}
}
return (rval);
}
int
{
const char *link;
int num;
int fd;
int num_offset;
return (DI_WALK_CONTINUE);
}
if (verbose) {
} else {
msg(_("Unable to open device %s: %s\n"),
}
}
return (DI_WALK_CONTINUE);
}
if (verbose) {
}
if (verbose) {
}
} else {
if (verbose) {
msg(_("done.\n"));
}
}
return (DI_WALK_CONTINUE);
}
int
{
int optc;
int verbose = 0;
switch (optc) {
case 'v':
verbose = 1;
break;
default:
help();
return (-1);
}
}
if (argc != 0) {
help();
return (-1);
}
perror(_("Unable to initialize devlink handle"));
return (-1);
}
mixer_walker) != 0) {
perror(_("Unable to walk devlinks"));
return (-1);
}
return (0);
}
int
{
int rv = 0;
int opt;
(void) textdomain(TEXT_DOMAIN);
switch (opt) {
case 'h':
help();
rv = 0;
goto OUT;
default:
break;
}
}
if (rv) {
goto OUT;
}
if (argc < 1) {
help();
help();
rv = 0;
} else {
help();
}
OUT:
free_devices();
return (rv);
}