3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore/*
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * CDDL HEADER START
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore *
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * The contents of this file are subject to the terms of the
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * Common Development and Distribution License (the "License").
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * You may not use this file except in compliance with the License.
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore *
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * or http://www.opensolaris.org/os/licensing.
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * See the License for the specific language governing permissions
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * and limitations under the License.
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore *
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * When distributing Covered Code, include this CDDL HEADER in each
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * If applicable, add the following below this CDDL HEADER, with the
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * fields enclosed by brackets "[]" replaced with your own identifying
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * information: Portions Copyright [yyyy] [name of copyright owner]
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore *
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * CDDL HEADER END
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore */
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore/*
99bddabb317e8d8aa0ea11dcce9425dbf7f9258dGarrett D'Amore * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * Use is subject to license terms.
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore */
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore#include <stdio.h>
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore#include <stdlib.h>
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore#include <errno.h>
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore#include <string.h>
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore#include <strings.h>
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore#include <locale.h>
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore#include <libintl.h>
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore#include <stdarg.h>
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore#include <stddef.h>
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore#include <sys/types.h>
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore#include <sys/stat.h>
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore#include <sys/mkdev.h>
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore#include <fcntl.h>
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore#include <unistd.h>
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore#include <ctype.h>
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore#include <sys/param.h>
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore#include <sys/soundcard.h>
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore#include <libdevinfo.h>
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore#endif
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore#define _(s) gettext(s)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore#define MAXLINE 1024
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore#define AUDIO_CTRL_STEREO_LEFT(v) ((uint8_t)((v) & 0xff))
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore#define AUDIO_CTRL_STEREO_RIGHT(v) ((uint8_t)(((v) >> 8) & 0xff))
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore#define AUDIO_CTRL_STEREO_VAL(l, r) (((l) & 0xff) | (((r) & 0xff) << 8))
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore/*
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * These are borrowed from sys/audio/audio_common.h, where the values
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * are protected by _KERNEL.
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore */
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore#define AUDIO_MN_TYPE_NBITS (4)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore#define AUDIO_MN_TYPE_MASK ((1U << AUDIO_MN_TYPE_NBITS) - 1)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore#define AUDIO_MINOR_MIXER (0)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore/*
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * Column display information
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * All are related to the types enumerated in col_t and any change should be
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * reflected in the corresponding indices and offsets for all the variables
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * accordingly. Most tweaks to the display can be done by adjusting the
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * values here.
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore */
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore/* types of columns displayed */
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amoretypedef enum { COL_DV = 0, COL_NM, COL_VAL, COL_SEL} col_t;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore/* corresponding sizes of columns; does not include trailing null */
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore#define COL_DV_SZ 16
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore#define COL_NM_SZ 24
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore#define COL_VAL_SZ 10
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore#define COL_SEL_SZ 20
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore#define COL_MAX_SZ 64
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore/* corresponding sizes of columns, indexed by col_t value */
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amorestatic int col_sz[] = {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore COL_DV_SZ, COL_NM_SZ, COL_VAL_SZ, COL_SEL_SZ
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore};
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore/* used by callers of the printing function */
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amoretypedef struct col_prt {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore char *col_dv;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore char *col_nm;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore char *col_val;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore char *col_sel;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore} col_prt_t;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore/* columns displayed in order with vopt = 0 */
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amorestatic int col_dpy[] = {COL_NM, COL_VAL};
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amorestatic int col_dpy_len = sizeof (col_dpy) / sizeof (*col_dpy);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore/* tells the printing function what members to use; follows col_dpy[] */
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amorestatic size_t col_dpy_prt[] = {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore offsetof(col_prt_t, col_nm),
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore offsetof(col_prt_t, col_val),
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore};
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore/* columns displayed in order with vopt = 1 */
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amorestatic int col_dpy_vopt[] = { COL_DV, COL_NM, COL_VAL, COL_SEL};
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amorestatic int col_dpy_vopt_len = sizeof (col_dpy_vopt) / sizeof (*col_dpy_vopt);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore/* tells the printing function what members to use; follows col_dpy_vopt[] */
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amorestatic size_t col_dpy_prt_vopt[] = {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore offsetof(col_prt_t, col_dv),
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore offsetof(col_prt_t, col_nm),
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore offsetof(col_prt_t, col_val),
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore offsetof(col_prt_t, col_sel)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore};
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore/* columns displayed in order with tofile = 1 */
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amorestatic int col_dpy_tofile[] = { COL_NM, COL_VAL};
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amorestatic int col_dpy_tofile_len = sizeof (col_dpy_tofile) /
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore sizeof (*col_dpy_tofile);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore/* tells the printing function what members to use; follows col_dpy_tofile[] */
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amorestatic size_t col_dpy_prt_tofile[] = {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore offsetof(col_prt_t, col_nm),
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore offsetof(col_prt_t, col_val)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore};
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore/*
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * mixer and control accounting
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore */
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amoretypedef struct cinfo {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore oss_mixext ci;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore oss_mixer_enuminfo *enump;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore} cinfo_t;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amoretypedef struct device {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore oss_card_info card;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore oss_mixerinfo mixer;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int cmax;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore cinfo_t *controls;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int mfd;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore dev_t devt;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore struct device *nextp;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore} device_t;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amorestatic device_t *devices = NULL;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore/*PRINTFLIKE1*/
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amorestatic void
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amoremsg(char *fmt, ...)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore{
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore va_list ap;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore va_start(ap, fmt);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (void) vprintf(fmt, ap);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore va_end(ap);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore}
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore/*PRINTFLIKE1*/
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amorestatic void
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amorewarn(char *fmt, ...)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore{
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore va_list ap;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore va_start(ap, fmt);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (void) vfprintf(stderr, fmt, ap);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore va_end(ap);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore}
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amorestatic void
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amorefree_device(device_t *d)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore{
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int i;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore device_t **dpp;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore dpp = &devices;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore while ((*dpp) && ((*dpp) != d)) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore dpp = &((*dpp)->nextp);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (*dpp) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore *dpp = d->nextp;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore for (i = 0; i < d->cmax; i++) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (d->controls[i].enump != NULL)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore free(d->controls[i].enump);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (d->mfd >= 0)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (void) close(d->mfd);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore free(d);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore}
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amorestatic void
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amorefree_devices(void)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore{
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore device_t *d = devices;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore while ((d = devices) != NULL) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore free_device(d);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore devices = NULL;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore}
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore/*
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * adds to the end of global devices and returns a pointer to the new entry
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore */
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amorestatic device_t *
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amorealloc_device(void)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore{
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore device_t *p;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore device_t *d = calloc(1, sizeof (*d));
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore d->card.card = -1;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore d->mixer.dev = -1;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore d->mfd = -1;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (devices == NULL) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore devices = d;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore } else {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore for (p = devices; p->nextp != NULL; p = p->nextp) {}
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore p->nextp = d;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (d);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore}
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore/*
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * cinfop->enump needs to be present
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * idx should be: >= 0 to < cinfop->ci.maxvalue
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore */
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amorestatic char *
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amoreget_enum_str(cinfo_t *cinfop, int idx)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore{
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int sz = sizeof (*cinfop->ci.enum_present) * 8;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (cinfop->ci.enum_present[idx / sz] & (1 << (idx % sz)))
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (cinfop->enump->strings + cinfop->enump->strindex[idx]);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (NULL);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore}
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore/*
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * caller fills in d->mixer.devnode; func fills in the rest
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore */
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amorestatic int
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amoreget_device_info(device_t *d)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore{
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int fd = -1;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int i;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore cinfo_t *ci;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if ((fd = open(d->mixer.devnode, O_RDWR)) < 0) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore perror(_("Error opening device"));
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (errno);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore d->mfd = fd;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore d->cmax = -1;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (ioctl(fd, SNDCTL_MIX_NREXT, &d->cmax) < 0) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore perror(_("Error getting control count"));
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (errno);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore d->controls = calloc(d->cmax, sizeof (*d->controls));
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore for (i = 0; i < d->cmax; i++) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore ci = &d->controls[i];
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore ci->ci.dev = -1;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore ci->ci.ctrl = i;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (ioctl(fd, SNDCTL_MIX_EXTINFO, &ci->ci) < 0) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore perror(_("Error getting control info"));
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (errno);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (ci->ci.type == MIXT_ENUM) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore ci->enump = calloc(1, sizeof (*ci->enump));
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore ci->enump->dev = -1;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore ci->enump->ctrl = ci->ci.ctrl;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (ioctl(fd, SNDCTL_MIX_ENUMINFO, ci->enump) < 0) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore perror(_("Error getting enum info"));
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (errno);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (0);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore}
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amorestatic int
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amoreload_devices(void)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore{
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int rv = -1;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int fd = -1;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int i;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore oss_sysinfo si;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore device_t *d;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore if (devices != NULL) {
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore /* already loaded */
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore return (0);
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore }
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if ((fd = open("/dev/mixer", O_RDWR)) < 0) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore rv = errno;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore warn(_("Error opening mixer\n"));
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore goto OUT;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (ioctl(fd, SNDCTL_SYSINFO, &si) < 0) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore rv = errno;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore perror(_("Error getting system information"));
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore goto OUT;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore for (i = 0; i < si.nummixers; i++) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore struct stat sbuf;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore d = alloc_device();
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore d->mixer.dev = i;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (ioctl(fd, SNDCTL_MIXERINFO, &d->mixer) != 0) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore continue;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore d->card.card = d->mixer.card_number;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if ((ioctl(fd, SNDCTL_CARDINFO, &d->card) != 0) ||
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (stat(d->mixer.devnode, &sbuf) != 0) ||
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore ((sbuf.st_mode & S_IFCHR) == 0)) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore warn(_("Device present: %s\n"), d->mixer.devnode);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore free_device(d);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore continue;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore d->devt = makedev(major(sbuf.st_rdev),
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore minor(sbuf.st_rdev) & ~(AUDIO_MN_TYPE_MASK));
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if ((rv = get_device_info(d)) != 0) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore free_device(d);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore goto OUT;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore rv = 0;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'AmoreOUT:
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (fd >= 0)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (void) close(fd);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (rv);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore}
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amorestatic int
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amorectype_valid(int type)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore{
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore switch (type) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore case MIXT_ONOFF:
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore case MIXT_ENUM:
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore case MIXT_MONOSLIDER:
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore case MIXT_STEREOSLIDER:
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (1);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore default:
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (0);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore}
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amorestatic void
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amoreprint_control_line(FILE *sfp, col_prt_t *colp, int vopt)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore{
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int i;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore size_t *col_prtp;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int *col_dpyp;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int col_cnt;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int col_type;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int width;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore char *colstr;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore char cbuf[COL_MAX_SZ + 1];
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore char line[128];
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore char *colsep = " ";
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (sfp != NULL) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore col_prtp = col_dpy_prt_tofile;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore col_dpyp = col_dpy_tofile;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore col_cnt = col_dpy_tofile_len;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore } else if (vopt) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore col_prtp = col_dpy_prt_vopt;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore col_dpyp = col_dpy_vopt;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore col_cnt = col_dpy_vopt_len;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore } else {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore col_prtp = col_dpy_prt;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore col_dpyp = col_dpy;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore col_cnt = col_dpy_len;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore line[0] = '\0';
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore for (i = 0; i < col_cnt; i++) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore col_type = col_dpyp[i];
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore width = col_sz[col_type];
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore colstr = *(char **)(((size_t)colp) + col_prtp[i]);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (void) snprintf(cbuf, sizeof (cbuf), "%- *s",
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore width > 0 ? width : 1,
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (colstr == NULL) ? "" : colstr);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (void) strlcat(line, cbuf, sizeof (line));
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (i < col_cnt - 1)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (void) strlcat(line, colsep, sizeof (line));
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (void) fprintf(sfp ? sfp : stdout, "%s\n", line);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore}
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amorestatic void
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amoreprint_header(FILE *sfp, int vopt)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore{
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore col_prt_t col;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (sfp) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore col.col_nm = _("#CONTROL");
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore col.col_val = _("VALUE");
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore } else {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore col.col_dv = _("DEVICE");
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore col.col_nm = _("CONTROL");
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore col.col_val = _("VALUE");
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore col.col_sel = _("POSSIBLE");
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore print_control_line(sfp, &col, vopt);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore}
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amorestatic int
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amoreprint_control(FILE *sfp, device_t *d, cinfo_t *cinfop, int vopt)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore{
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int mfd = d->mfd;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore char *devnm = d->card.shortname;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore oss_mixer_value cval;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore char *str;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int i;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int idx = -1;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int rv = -1;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore char valbuf[COL_VAL_SZ + 1];
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore char selbuf[COL_SEL_SZ + 1];
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore col_prt_t col;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore cval.dev = -1;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore cval.ctrl = cinfop->ci.ctrl;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (ctype_valid(cinfop->ci.type)) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (ioctl(mfd, SNDCTL_MIX_READ, &cval) < 0) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore rv = errno;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore perror(_("Error reading control\n"));
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (rv);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore } else {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (0);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore /*
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * convert the control value into a string
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore */
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore switch (cinfop->ci.type) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore case MIXT_ONOFF:
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (void) snprintf(valbuf, sizeof (valbuf), "%s",
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore cval.value ? _("on") : _("off"));
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore break;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore case MIXT_MONOSLIDER:
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (void) snprintf(valbuf, sizeof (valbuf), "%d",
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore cval.value & 0xff);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore break;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore case MIXT_STEREOSLIDER:
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (void) snprintf(valbuf, sizeof (valbuf), "%d:%d",
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (int)AUDIO_CTRL_STEREO_LEFT(cval.value),
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (int)AUDIO_CTRL_STEREO_RIGHT(cval.value));
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore break;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore case MIXT_ENUM:
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore str = get_enum_str(cinfop, cval.value);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (str == NULL) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore warn(_("Bad enum index %d for control '%s'\n"),
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore cval.value, cinfop->ci.extname);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (EINVAL);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (void) snprintf(valbuf, sizeof (valbuf), "%s", str);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore break;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore default:
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (0);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore /*
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * possible control values (range/selection)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore */
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore switch (cinfop->ci.type) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore case MIXT_ONOFF:
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (void) snprintf(selbuf, sizeof (selbuf), _("on,off"));
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore break;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore case MIXT_MONOSLIDER:
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (void) snprintf(selbuf, sizeof (selbuf), "%d-%d",
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore cinfop->ci.minvalue, cinfop->ci.maxvalue);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore break;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore case MIXT_STEREOSLIDER:
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (void) snprintf(selbuf, sizeof (selbuf), "%d-%d:%d-%d",
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore cinfop->ci.minvalue, cinfop->ci.maxvalue,
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore cinfop->ci.minvalue, cinfop->ci.maxvalue);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore break;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore case MIXT_ENUM:
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore /*
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * display the first choice on the same line, then display
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * the rest on multiple lines
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore */
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore selbuf[0] = 0;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore for (i = 0; i < cinfop->ci.maxvalue; i++) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore str = get_enum_str(cinfop, i);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (str == NULL)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore continue;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if ((strlen(str) + 1 + strlen(selbuf)) >=
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore sizeof (selbuf)) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore break;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (strlen(selbuf)) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (void) strlcat(selbuf, ",", sizeof (selbuf));
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (void) strlcat(selbuf, str, sizeof (selbuf));
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore idx = i;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore break;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore default:
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (void) snprintf(selbuf, sizeof (selbuf), "-");
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore col.col_dv = devnm;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore col.col_nm = strlen(cinfop->ci.extname) ?
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore cinfop->ci.extname : cinfop->ci.id;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore while (strchr(col.col_nm, '_') != NULL) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore col.col_nm = strchr(col.col_nm, '_') + 1;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore col.col_val = valbuf;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore col.col_sel = selbuf;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore print_control_line(sfp, &col, vopt);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
99bddabb317e8d8aa0ea11dcce9425dbf7f9258dGarrett D'Amore /* non-verbose mode prints don't display the enum values */
99bddabb317e8d8aa0ea11dcce9425dbf7f9258dGarrett D'Amore if ((!vopt) || (sfp != NULL)) {
99bddabb317e8d8aa0ea11dcce9425dbf7f9258dGarrett D'Amore return (0);
99bddabb317e8d8aa0ea11dcce9425dbf7f9258dGarrett D'Amore }
99bddabb317e8d8aa0ea11dcce9425dbf7f9258dGarrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore /* print leftover enum value selections */
99bddabb317e8d8aa0ea11dcce9425dbf7f9258dGarrett D'Amore while ((idx >= 0) && (idx < cinfop->ci.maxvalue)) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore selbuf[0] = 0;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore for (i = idx; i < cinfop->ci.maxvalue; i++) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore str = get_enum_str(cinfop, i);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (str == NULL)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore continue;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if ((strlen(str) + 1 + strlen(selbuf)) >=
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore sizeof (selbuf)) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore break;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (strlen(selbuf)) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (void) strlcat(selbuf, ",", sizeof (selbuf));
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (void) strlcat(selbuf, str, sizeof (selbuf));
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore idx = i;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore col.col_dv = NULL;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore col.col_nm = NULL;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore col.col_val = NULL;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore col.col_sel = selbuf;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore print_control_line(sfp, &col, vopt);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (0);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore}
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amorestatic int
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amoreset_device_control(device_t *d, cinfo_t *cinfop, char *wstr, int vopt)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore{
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int mfd = d->mfd;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore oss_mixer_value cval;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int wlen = strlen(wstr);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int lval, rval;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore char *lstr, *rstr;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore char *str;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int i;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int rv = -1;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore cval.dev = -1;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore cval.ctrl = cinfop->ci.ctrl;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore cval.value = 0;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore switch (cinfop->ci.type) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore case MIXT_ONOFF:
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore cval.value = (strncmp(_("on"), wstr, wlen) == 0) ? 1 : 0;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore break;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore case MIXT_MONOSLIDER:
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore cval.value = atoi(wstr);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore break;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore case MIXT_STEREOSLIDER:
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore lstr = wstr;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore rstr = strchr(wstr, ':');
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (rstr != NULL) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore *rstr = '\0';
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore rstr++;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore rval = atoi(rstr);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore lval = atoi(lstr);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore rstr--;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore *rstr = ':';
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore } else {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore lval = atoi(lstr);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore rval = lval;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore cval.value = AUDIO_CTRL_STEREO_VAL(lval, rval);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore break;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore case MIXT_ENUM:
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore for (i = 0; i < cinfop->ci.maxvalue; i++) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore str = get_enum_str(cinfop, i);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (str == NULL)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore continue;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (strncmp(wstr, str, wlen) == 0) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore cval.value = i;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore break;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (i >= cinfop->ci.maxvalue) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore warn(_("Invalid enumeration value\n"));
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (EINVAL);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore break;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore default:
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore warn(_("Unsupported control type: %d\n"), cinfop->ci.type);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (EINVAL);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (vopt) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore msg(_("%s: '%s' set to '%s'\n"), d->card.shortname,
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore cinfop->ci.extname, wstr);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (ioctl(mfd, SNDCTL_MIX_WRITE, &cval) < 0) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore rv = errno;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore perror(_("Error writing control"));
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (rv);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore rv = 0;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (rv);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore}
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amorestatic void
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amorehelp(void)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore{
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore#define HELP_STR _( \
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore"audioctl list-devices\n" \
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore" list all audio devices\n" \
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore"\n" \
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore"audioctl show-device [ -v ] [ -d <device> ]\n" \
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore" display information about an audio device\n" \
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore"\n" \
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore"audioctl show-control [ -v ] [ -d <device> ] [ <control> ... ]\n" \
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore" get the value of a specific control (all if not specified)\n" \
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore"\n" \
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore"audioctl set-control [ -v ] [ -d <device> ] <control> <value>\n" \
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore" set the value of a specific control\n" \
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore"\n" \
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore"audioctl save-controls [ -d <device> ] [ -f ] <file>\n" \
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore" save all control settings for the device to a file\n" \
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore"\n" \
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore"audioctl load-controls [ -d <device> ] <file>\n" \
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore" restore previously saved control settings to device\n" \
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore"\n" \
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore"audioctl help\n" \
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore" show this message.\n")
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (void) fprintf(stderr, HELP_STR);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore}
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amoredev_t
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amoredevice_devt(char *name)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore{
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore struct stat sbuf;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if ((stat(name, &sbuf) != 0) ||
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore ((sbuf.st_mode & S_IFCHR) == 0)) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore /* Not a device node! */
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (0);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (makedev(major(sbuf.st_rdev),
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore minor(sbuf.st_rdev) & ~(AUDIO_MN_TYPE_MASK)));
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore}
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amorestatic device_t *
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amorefind_device(char *name)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore{
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore dev_t devt;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore device_t *d;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore /*
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * User may have specified:
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore *
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * /dev/dsp[<num>]
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * /dev/mixer[<num>]
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * /dev/audio[<num>9]
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * /dev/audioctl[<num>]
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * /dev/sound/<num>{,ctl,dsp,mixer}
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * /dev/sound/<driver>:<num>{,ctl,dsp,mixer}
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore *
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore * We can canonicalize these by looking at the dev_t though.
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore */
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore if (load_devices() != 0) {
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore return (NULL);
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore }
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (name == NULL)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore name = getenv("AUDIODEV");
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if ((name == NULL) ||
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (strcmp(name, "/dev/mixer") == 0)) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore /* /dev/mixer node doesn't point to real hw */
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore name = "/dev/dsp";
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (*name == '/') {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore /* if we have a full path, convert to the devt */
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if ((devt = device_devt(name)) == 0) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore warn(_("No such audio device.\n"));
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (NULL);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore name = NULL;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore for (d = devices; d != NULL; d = d->nextp) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore oss_card_info *card = &d->card;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if ((name) && (strcmp(name, card->shortname) == 0)) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (d);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (devt == d->devt) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (d);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore warn(_("No such audio device.\n"));
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (NULL);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore}
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amoreint
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amoredo_list_devices(int argc, char **argv)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore{
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int optc;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int verbose = 0;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore device_t *d;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore while ((optc = getopt(argc, argv, "v")) != EOF) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore switch (optc) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore case 'v':
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore verbose++;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore break;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore default:
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore help();
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (-1);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore argc -= optind;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore argv += optind;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (argc != 0) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore help();
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (-1);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore if (load_devices() != 0) {
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore return (-1);
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore }
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore for (d = devices; d != NULL; d = d->nextp) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if ((d->mixer.enabled == 0) && (!verbose))
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore continue;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (verbose) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore msg(_("%s (%s)\n"), d->card.shortname,
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore d->mixer.devnode);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore } else {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore msg(_("%s\n"), d->card.shortname);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (0);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore}
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amoreint
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amoredo_show_device(int argc, char **argv)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore{
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int optc;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore char *devname = NULL;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore device_t *d;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore while ((optc = getopt(argc, argv, "d:v")) != EOF) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore switch (optc) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore case 'd':
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore devname = optarg;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore break;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore case 'v':
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore break;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore default:
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore help();
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (-1);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore argc -= optind;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore argv += optind;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (argc != 0) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore help();
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (-1);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if ((d = find_device(devname)) == NULL) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (ENODEV);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore msg(_("Device: %s\n"), d->mixer.devnode);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore msg(_(" Name = %s\n"), d->card.shortname);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore msg(_(" Config = %s\n"), d->card.longname);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (strlen(d->card.hw_info)) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore msg(_(" HW Info = %s"), d->card.hw_info);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (0);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore}
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amoreint
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amoredo_show_control(int argc, char **argv)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore{
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int optc;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int rval = 0;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int verbose = 0;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore device_t *d;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore char *devname = NULL;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int i;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int j;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int rv;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore char *n;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore cinfo_t *cinfop;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore while ((optc = getopt(argc, argv, "d:v")) != EOF) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore switch (optc) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore case 'd':
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore devname = optarg;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore break;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore case 'v':
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore verbose++;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore break;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore default:
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore help();
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (-1);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore argc -= optind;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore argv += optind;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if ((d = find_device(devname)) == NULL) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (ENODEV);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore print_header(NULL, verbose);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (argc == 0) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore /* do them all! */
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore for (i = 0; i < d->cmax; i++) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore cinfop = &d->controls[i];
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore rv = print_control(NULL, d, cinfop, verbose);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore rval = rval ? rval : rv;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (rval);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore for (i = 0; i < argc; i++) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore for (j = 0; j < d->cmax; j++) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore cinfop = &d->controls[j];
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore n = strrchr(cinfop->ci.extname, '_');
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore n = n ? n + 1 : cinfop->ci.extname;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (strcmp(argv[i], n) == 0) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore rv = print_control(NULL, d, cinfop, verbose);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore rval = rval ? rval : rv;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore break;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore /* Didn't find requested control */
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (j == d->cmax) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore warn(_("No such control: %s\n"), argv[i]);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore rval = rval ? rval : ENODEV;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (rval);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore}
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amoreint
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amoredo_set_control(int argc, char **argv)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore{
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int optc;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int rval = 0;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int verbose = 0;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore device_t *d;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore char *devname = NULL;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore char *cname;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore char *value;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int i;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int found;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int rv;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore char *n;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore cinfo_t *cinfop;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore while ((optc = getopt(argc, argv, "d:v")) != EOF) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore switch (optc) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore case 'd':
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore devname = optarg;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore break;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore case 'v':
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore verbose = 1;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore break;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore default:
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore help();
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (-1);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore argc -= optind;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore argv += optind;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (argc != 2) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore help();
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (-1);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore cname = argv[0];
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore value = argv[1];
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if ((d = find_device(devname)) == NULL) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (ENODEV);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore for (i = 0, found = 0; i < d->cmax; i++) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore cinfop = &d->controls[i];
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore n = strrchr(cinfop->ci.extname, '_');
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore n = n ? n + 1 : cinfop->ci.extname;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (strcmp(cname, n) != 0) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore continue;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore found = 1;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore rv = set_device_control(d, cinfop, value, verbose);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore rval = rval ? rval : rv;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (!found) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore warn(_("No such control: %s\n"), cname);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (rval);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore}
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amoreint
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amoredo_save_controls(int argc, char **argv)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore{
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int optc;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int rval = 0;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore device_t *d;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore char *devname = NULL;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore char *fname;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int i;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int rv;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore cinfo_t *cinfop;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore FILE *fp;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int fd;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int mode;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore mode = O_WRONLY | O_CREAT | O_EXCL;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore while ((optc = getopt(argc, argv, "d:f")) != EOF) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore switch (optc) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore case 'd':
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore devname = optarg;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore break;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore case 'f':
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore mode &= ~O_EXCL;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore mode |= O_TRUNC;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore break;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore default:
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore help();
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (-1);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore argc -= optind;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore argv += optind;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (argc != 1) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore help();
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (-1);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore fname = argv[0];
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if ((d = find_device(devname)) == NULL) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (ENODEV);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if ((fd = open(fname, mode, 0666)) < 0) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore perror(_("Failed to create file"));
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (errno);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if ((fp = fdopen(fd, "w")) == NULL) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore perror(_("Unable to open file\n"));
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (void) close(fd);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (void) unlink(fname);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (errno);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (void) fprintf(fp, "# Device: %s\n", d->mixer.devnode);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (void) fprintf(fp, "# Name = %s\n", d->card.shortname);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (void) fprintf(fp, "# Config = %s\n", d->card.longname);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (strlen(d->card.hw_info)) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (void) fprintf(fp, "# HW Info = %s", d->card.hw_info);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (void) fprintf(fp, "#\n");
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore print_header(fp, 0);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore for (i = 0; i < d->cmax; i++) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore cinfop = &d->controls[i];
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore rv = print_control(fp, d, cinfop, 0);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore rval = rval ? rval : rv;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (void) fclose(fp);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (rval);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore}
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amoreint
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amoredo_load_controls(int argc, char **argv)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore{
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int optc;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int rval = 0;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore device_t *d;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore char *devname = NULL;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore char *fname;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore char *cname;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore char *value;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int i;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int rv;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore cinfo_t *cinfop;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore FILE *fp;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore char linebuf[MAXLINE];
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int lineno = 0;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int found;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore while ((optc = getopt(argc, argv, "d:")) != EOF) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore switch (optc) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore case 'd':
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore devname = optarg;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore break;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore default:
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore help();
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (-1);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore argc -= optind;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore argv += optind;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (argc != 1) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore help();
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (-1);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore fname = argv[0];
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if ((d = find_device(devname)) == NULL) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (ENODEV);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if ((fp = fopen(fname, "r")) == NULL) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore perror(_("Unable to open file"));
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (errno);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore while (fgets(linebuf, sizeof (linebuf), fp) != NULL) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore lineno++;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (linebuf[strlen(linebuf) - 1] != '\n') {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore warn(_("Warning: line too long at line %d\n"), lineno);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore /* read in the rest of the line and discard it */
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore while (fgets(linebuf, sizeof (linebuf), fp) != NULL &&
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (linebuf[strlen(linebuf) - 1] != '\n')) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore continue;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore continue;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore /* we have a good line ... */
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore cname = strtok(linebuf, " \t\n");
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore /* skip comments and blank lines */
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if ((cname == NULL) || (cname[0] == '#')) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore continue;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore value = strtok(NULL, " \t\n");
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if ((value == NULL) || (*cname == 0)) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore warn(_("Warning: missing value at line %d\n"), lineno);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore continue;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore for (i = 0, found = 0; i < d->cmax; i++) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore /* save and restore requires an exact match */
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore cinfop = &d->controls[i];
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (strcmp(cinfop->ci.extname, cname) != 0) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore continue;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore found = 1;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore rv = set_device_control(d, cinfop, value, 0);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore rval = rval ? rval : rv;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (!found) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore warn(_("No such control: %s\n"), cname);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (void) fclose(fp);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (rval);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore}
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amoreint
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amoremixer_walker(di_devlink_t dlink, void *arg)
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore{
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore const char *link;
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore int num;
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore int fd;
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore int verbose = *(int *)arg;
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore int num_offset;
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore num_offset = sizeof ("/dev/mixer") - 1;
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore link = di_devlink_path(dlink);
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore if ((link == NULL) ||
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore (strncmp(link, "/dev/mixer", num_offset) != 0) ||
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore (!isdigit(link[num_offset]))) {
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore return (DI_WALK_CONTINUE);
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore }
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore num = atoi(link + num_offset);
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore if ((fd = open(link, O_RDWR)) < 0) {
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore if (verbose) {
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore if (errno == ENOENT) {
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore msg(_("Device %s not present.\n"), link);
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore } else {
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore msg(_("Unable to open device %s: %s\n"),
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore link, strerror(errno));
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore }
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore }
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore return (DI_WALK_CONTINUE);
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore }
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore if (verbose) {
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore msg(_("Initializing link %s: "), link);
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore }
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore if (ioctl(fd, SNDCTL_SUN_SEND_NUMBER, &num) != 0) {
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore if (verbose) {
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore msg(_("failed: %s\n"), strerror(errno));
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore }
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore } else {
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore if (verbose) {
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore msg(_("done.\n"));
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore }
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore }
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore (void) close(fd);
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore return (DI_WALK_CONTINUE);
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore}
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amoreint
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amoredo_init_devices(int argc, char **argv)
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore{
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore int optc;
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore di_devlink_handle_t dlh;
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore int verbose = 0;
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore while ((optc = getopt(argc, argv, "v")) != EOF) {
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore switch (optc) {
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore case 'v':
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore verbose = 1;
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore break;
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore default:
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore help();
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore return (-1);
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore }
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore }
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore argc -= optind;
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore argv += optind;
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore if (argc != 0) {
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore help();
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore return (-1);
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore }
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore dlh = di_devlink_init(NULL, 0);
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore if (dlh == NULL) {
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore perror(_("Unable to initialize devlink handle"));
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore return (-1);
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore }
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore if (di_devlink_walk(dlh, "^mixer", NULL, 0, &verbose,
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore mixer_walker) != 0) {
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore perror(_("Unable to walk devlinks"));
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore return (-1);
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore }
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore return (0);
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore}
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amoreint
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amoremain(int argc, char **argv)
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore{
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int rv = 0;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore int opt;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (void) setlocale(LC_ALL, "");
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore (void) textdomain(TEXT_DOMAIN);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore while ((opt = getopt(argc, argv, "h")) != EOF) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore switch (opt) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore case 'h':
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore help();
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore rv = 0;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore goto OUT;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore default:
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore rv = EINVAL;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore break;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (rv) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore goto OUT;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore argc -= optind;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore argv += optind;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore if (argc < 1) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore help();
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore rv = EINVAL;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore } else if (strcmp(argv[0], "help") == 0) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore help();
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore rv = 0;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore } else if (strcmp(argv[0], "list-devices") == 0) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore rv = do_list_devices(argc, argv);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore } else if (strcmp(argv[0], "show-device") == 0) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore rv = do_show_device(argc, argv);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore } else if (strcmp(argv[0], "show-control") == 0) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore rv = do_show_control(argc, argv);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore } else if (strcmp(argv[0], "set-control") == 0) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore rv = do_set_control(argc, argv);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore } else if (strcmp(argv[0], "load-controls") == 0) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore rv = do_load_controls(argc, argv);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore } else if (strcmp(argv[0], "save-controls") == 0) {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore rv = do_save_controls(argc, argv);
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore } else if (strcmp(argv[0], "init-devices") == 0) {
aef5f291eda20993128ff27fe48afa3097634eafGarrett D'Amore rv = do_init_devices(argc, argv);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore } else {
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore help();
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore rv = EINVAL;
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore }
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'AmoreOUT:
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore free_devices();
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore return (rv);
3ccb19668faa3e1b7734ae03b4d31a4c00da3240Garrett D'Amore}