|
Packit |
4a16fb |
/**
|
|
Packit |
4a16fb |
* \file control/control.c
|
|
Packit |
4a16fb |
* \brief CTL interface - parse ASCII identifiers and values
|
|
Packit |
4a16fb |
* \author Jaroslav Kysela <perex@perex.cz>
|
|
Packit |
4a16fb |
* \date 2010
|
|
Packit |
4a16fb |
*/
|
|
Packit |
4a16fb |
/*
|
|
Packit |
4a16fb |
* Control Interface - ASCII parser
|
|
Packit |
4a16fb |
* Copyright (c) 2010 by Jaroslav Kysela <perex@perex.cz>
|
|
Packit |
4a16fb |
*
|
|
Packit |
4a16fb |
*
|
|
Packit |
4a16fb |
* This library is free software; you can redistribute it and/or modify
|
|
Packit |
4a16fb |
* it under the terms of the GNU Lesser General Public License as
|
|
Packit |
4a16fb |
* published by the Free Software Foundation; either version 2.1 of
|
|
Packit |
4a16fb |
* the License, or (at your option) any later version.
|
|
Packit |
4a16fb |
*
|
|
Packit |
4a16fb |
* This program is distributed in the hope that it will be useful,
|
|
Packit |
4a16fb |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
4a16fb |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
4a16fb |
* GNU Lesser General Public License for more details.
|
|
Packit |
4a16fb |
*
|
|
Packit |
4a16fb |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
4a16fb |
* License along with this library; if not, write to the Free Software
|
|
Packit |
4a16fb |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
Packit |
4a16fb |
*
|
|
Packit |
4a16fb |
*/
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
#include <unistd.h>
|
|
Packit |
4a16fb |
#include <string.h>
|
|
Packit |
4a16fb |
#include <ctype.h>
|
|
Packit |
4a16fb |
#include <math.h>
|
|
Packit |
4a16fb |
#include "control_local.h"
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
/* Function to convert from percentage to volume. val = percentage */
|
|
Packit |
4a16fb |
|
|
Packit Service |
f36a15 |
static inline long int convert_prange1(long perc, long min, long max)
|
|
Packit |
4a16fb |
{
|
|
Packit Service |
f36a15 |
long tmp;
|
|
Packit |
4a16fb |
|
|
Packit Service |
f36a15 |
#ifdef HAVE_SOFT_FLOAT
|
|
Packit Service |
f36a15 |
tmp = perc * (max - min);
|
|
Packit Service |
f36a15 |
tmp = tmp / 100 + ((tmp % 100) < 50 ? 0 : 1);
|
|
Packit Service |
f36a15 |
#else
|
|
Packit Service |
f36a15 |
tmp = rint((double)perc * (double)(max - min) * 0.01);
|
|
Packit |
4a16fb |
#endif
|
|
Packit Service |
f36a15 |
if (tmp == 0 && perc > 0)
|
|
Packit Service |
f36a15 |
tmp++;
|
|
Packit Service |
f36a15 |
return tmp + min;
|
|
Packit Service |
f36a15 |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
#define check_range(val, min, max) \
|
|
Packit |
4a16fb |
((val < min) ? (min) : ((val > max) ? (max) : (val)))
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
static long get_integer(const char **ptr, long min, long max)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
long val = min;
|
|
Packit |
4a16fb |
char *p = (char *)*ptr, *s;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
if (*p == ':')
|
|
Packit |
4a16fb |
p++;
|
|
Packit |
4a16fb |
if (*p == '\0' || (!isdigit(*p) && *p != '-'))
|
|
Packit |
4a16fb |
goto out;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
s = p;
|
|
Packit |
4a16fb |
val = strtol(s, &p, 0);
|
|
Packit |
4a16fb |
if (*p == '.') {
|
|
Packit |
4a16fb |
p++;
|
|
Packit |
4a16fb |
(void)strtol(p, &p, 10);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
if (*p == '%') {
|
|
Packit |
4a16fb |
val = (long)convert_prange1(strtod(s, NULL), min, max);
|
|
Packit |
4a16fb |
p++;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
val = check_range(val, min, max);
|
|
Packit |
4a16fb |
if (*p == ',')
|
|
Packit |
4a16fb |
p++;
|
|
Packit |
4a16fb |
out:
|
|
Packit |
4a16fb |
*ptr = p;
|
|
Packit |
4a16fb |
return val;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
static long long get_integer64(const char **ptr, long long min, long long max)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
long long val = min;
|
|
Packit |
4a16fb |
char *p = (char *)*ptr, *s;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
if (*p == ':')
|
|
Packit |
4a16fb |
p++;
|
|
Packit |
4a16fb |
if (*p == '\0' || (!isdigit(*p) && *p != '-'))
|
|
Packit |
4a16fb |
goto out;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
s = p;
|
|
Packit |
4a16fb |
val = strtol(s, &p, 0);
|
|
Packit |
4a16fb |
if (*p == '.') {
|
|
Packit |
4a16fb |
p++;
|
|
Packit |
4a16fb |
(void)strtol(p, &p, 10);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
if (*p == '%') {
|
|
Packit |
4a16fb |
val = (long long)convert_prange1(strtod(s, NULL), min, max);
|
|
Packit |
4a16fb |
p++;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
val = check_range(val, min, max);
|
|
Packit |
4a16fb |
if (*p == ',')
|
|
Packit |
4a16fb |
p++;
|
|
Packit |
4a16fb |
out:
|
|
Packit |
4a16fb |
*ptr = p;
|
|
Packit |
4a16fb |
return val;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
/**
|
|
Packit |
4a16fb |
* \brief return ASCII CTL element identifier name
|
|
Packit |
4a16fb |
* \param id CTL identifier
|
|
Packit |
4a16fb |
* \return ascii identifier of CTL element
|
|
Packit |
4a16fb |
*
|
|
Packit |
4a16fb |
* The string is allocated using strdup().
|
|
Packit |
4a16fb |
*/
|
|
Packit |
4a16fb |
char *snd_ctl_ascii_elem_id_get(snd_ctl_elem_id_t *id)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
unsigned int index, device, subdevice;
|
|
Packit |
4a16fb |
char buf[256], buf1[32];
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
snprintf(buf, sizeof(buf), "numid=%u,iface=%s,name='%s'",
|
|
Packit |
4a16fb |
snd_ctl_elem_id_get_numid(id),
|
|
Packit |
4a16fb |
snd_ctl_elem_iface_name(
|
|
Packit |
4a16fb |
snd_ctl_elem_id_get_interface(id)),
|
|
Packit |
4a16fb |
snd_ctl_elem_id_get_name(id));
|
|
Packit |
4a16fb |
buf[sizeof(buf)-1] = '\0';
|
|
Packit |
4a16fb |
index = snd_ctl_elem_id_get_index(id);
|
|
Packit |
4a16fb |
device = snd_ctl_elem_id_get_device(id);
|
|
Packit |
4a16fb |
subdevice = snd_ctl_elem_id_get_subdevice(id);
|
|
Packit |
4a16fb |
if (index) {
|
|
Packit |
4a16fb |
snprintf(buf1, sizeof(buf1), ",index=%u", index);
|
|
Packit |
4a16fb |
if (strlen(buf) + strlen(buf1) < sizeof(buf))
|
|
Packit |
4a16fb |
strcat(buf, buf1);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
if (device) {
|
|
Packit |
4a16fb |
snprintf(buf1, sizeof(buf1), ",device=%u", device);
|
|
Packit |
4a16fb |
if (strlen(buf) + strlen(buf1) < sizeof(buf))
|
|
Packit |
4a16fb |
strcat(buf, buf1);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
if (subdevice) {
|
|
Packit |
4a16fb |
snprintf(buf1, sizeof(buf1), ",subdevice=%u", subdevice);
|
|
Packit |
4a16fb |
if (strlen(buf) + strlen(buf1) < sizeof(buf))
|
|
Packit |
4a16fb |
strcat(buf, buf1);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
return strdup(buf);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
#ifndef DOC_HIDDEN
|
|
Packit |
4a16fb |
/* used by UCM parser, too */
|
|
Packit |
4a16fb |
int __snd_ctl_ascii_elem_id_parse(snd_ctl_elem_id_t *dst, const char *str,
|
|
Packit |
4a16fb |
const char **ret_ptr)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
int c, size, numid;
|
|
Packit |
4a16fb |
int err = -EINVAL;
|
|
Packit |
4a16fb |
char *ptr;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
while (isspace(*str))
|
|
Packit |
4a16fb |
str++;
|
|
Packit |
4a16fb |
if (!(*str))
|
|
Packit |
4a16fb |
goto out;
|
|
Packit |
4a16fb |
snd_ctl_elem_id_set_interface(dst, SND_CTL_ELEM_IFACE_MIXER); /* default */
|
|
Packit |
4a16fb |
while (*str) {
|
|
Packit |
4a16fb |
if (!strncasecmp(str, "numid=", 6)) {
|
|
Packit |
4a16fb |
str += 6;
|
|
Packit |
4a16fb |
numid = atoi(str);
|
|
Packit |
4a16fb |
if (numid <= 0) {
|
|
Packit |
4a16fb |
fprintf(stderr, "amixer: Invalid numid %d\n", numid);
|
|
Packit |
4a16fb |
goto out;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
snd_ctl_elem_id_set_numid(dst, atoi(str));
|
|
Packit |
4a16fb |
while (isdigit(*str))
|
|
Packit |
4a16fb |
str++;
|
|
Packit |
4a16fb |
} else if (!strncasecmp(str, "iface=", 6)) {
|
|
Packit |
4a16fb |
str += 6;
|
|
Packit |
4a16fb |
if (!strncasecmp(str, "card", 4)) {
|
|
Packit |
4a16fb |
snd_ctl_elem_id_set_interface(dst, SND_CTL_ELEM_IFACE_CARD);
|
|
Packit |
4a16fb |
str += 4;
|
|
Packit |
4a16fb |
} else if (!strncasecmp(str, "mixer", 5)) {
|
|
Packit |
4a16fb |
snd_ctl_elem_id_set_interface(dst, SND_CTL_ELEM_IFACE_MIXER);
|
|
Packit |
4a16fb |
str += 5;
|
|
Packit |
4a16fb |
} else if (!strncasecmp(str, "pcm", 3)) {
|
|
Packit |
4a16fb |
snd_ctl_elem_id_set_interface(dst, SND_CTL_ELEM_IFACE_PCM);
|
|
Packit |
4a16fb |
str += 3;
|
|
Packit |
4a16fb |
} else if (!strncasecmp(str, "rawmidi", 7)) {
|
|
Packit |
4a16fb |
snd_ctl_elem_id_set_interface(dst, SND_CTL_ELEM_IFACE_RAWMIDI);
|
|
Packit |
4a16fb |
str += 7;
|
|
Packit |
4a16fb |
} else if (!strncasecmp(str, "timer", 5)) {
|
|
Packit |
4a16fb |
snd_ctl_elem_id_set_interface(dst, SND_CTL_ELEM_IFACE_TIMER);
|
|
Packit |
4a16fb |
str += 5;
|
|
Packit |
4a16fb |
} else if (!strncasecmp(str, "sequencer", 9)) {
|
|
Packit |
4a16fb |
snd_ctl_elem_id_set_interface(dst, SND_CTL_ELEM_IFACE_SEQUENCER);
|
|
Packit |
4a16fb |
str += 9;
|
|
Packit |
4a16fb |
} else {
|
|
Packit |
4a16fb |
goto out;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
} else if (!strncasecmp(str, "name=", 5)) {
|
|
Packit |
4a16fb |
char buf[64];
|
|
Packit |
4a16fb |
str += 5;
|
|
Packit |
4a16fb |
ptr = buf;
|
|
Packit |
4a16fb |
size = 0;
|
|
Packit |
4a16fb |
if (*str == '\'' || *str == '\"') {
|
|
Packit |
4a16fb |
c = *str++;
|
|
Packit |
4a16fb |
while (*str && *str != c) {
|
|
Packit |
4a16fb |
if (size < (int)sizeof(buf)) {
|
|
Packit |
4a16fb |
*ptr++ = *str;
|
|
Packit |
4a16fb |
size++;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
str++;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
if (*str == c)
|
|
Packit |
4a16fb |
str++;
|
|
Packit |
4a16fb |
} else {
|
|
Packit |
4a16fb |
while (*str && *str != ',') {
|
|
Packit |
4a16fb |
if (size < (int)sizeof(buf)) {
|
|
Packit |
4a16fb |
*ptr++ = *str;
|
|
Packit |
4a16fb |
size++;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
str++;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
*ptr = '\0';
|
|
Packit |
4a16fb |
snd_ctl_elem_id_set_name(dst, buf);
|
|
Packit |
4a16fb |
} else if (!strncasecmp(str, "index=", 6)) {
|
|
Packit |
4a16fb |
str += 6;
|
|
Packit |
4a16fb |
snd_ctl_elem_id_set_index(dst, atoi(str));
|
|
Packit |
4a16fb |
while (isdigit(*str))
|
|
Packit |
4a16fb |
str++;
|
|
Packit |
4a16fb |
} else if (!strncasecmp(str, "device=", 7)) {
|
|
Packit |
4a16fb |
str += 7;
|
|
Packit |
4a16fb |
snd_ctl_elem_id_set_device(dst, atoi(str));
|
|
Packit |
4a16fb |
while (isdigit(*str))
|
|
Packit |
4a16fb |
str++;
|
|
Packit |
4a16fb |
} else if (!strncasecmp(str, "subdevice=", 10)) {
|
|
Packit |
4a16fb |
str += 10;
|
|
Packit |
4a16fb |
snd_ctl_elem_id_set_subdevice(dst, atoi(str));
|
|
Packit |
4a16fb |
while (isdigit(*str))
|
|
Packit |
4a16fb |
str++;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
if (*str == ',') {
|
|
Packit |
4a16fb |
str++;
|
|
Packit |
4a16fb |
} else {
|
|
Packit |
4a16fb |
/* when ret_ptr is given, allow to terminate gracefully
|
|
Packit |
4a16fb |
* at the next space letter
|
|
Packit |
4a16fb |
*/
|
|
Packit |
4a16fb |
if (ret_ptr && isspace(*str))
|
|
Packit |
4a16fb |
break;
|
|
Packit |
4a16fb |
if (*str)
|
|
Packit |
4a16fb |
goto out;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
err = 0;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
out:
|
|
Packit |
4a16fb |
if (ret_ptr)
|
|
Packit |
4a16fb |
*ret_ptr = str;
|
|
Packit |
4a16fb |
return err;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
#endif
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
/**
|
|
Packit |
4a16fb |
* \brief parse ASCII string as CTL element identifier
|
|
Packit |
4a16fb |
* \param dst destination CTL identifier
|
|
Packit |
4a16fb |
* \param str source ASCII string
|
|
Packit |
4a16fb |
* \return zero on success, otherwise a negative error code
|
|
Packit |
4a16fb |
*/
|
|
Packit |
4a16fb |
int snd_ctl_ascii_elem_id_parse(snd_ctl_elem_id_t *dst, const char *str)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
return __snd_ctl_ascii_elem_id_parse(dst, str, NULL);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
static int get_ctl_enum_item_index(snd_ctl_t *handle,
|
|
Packit |
4a16fb |
snd_ctl_elem_info_t *info,
|
|
Packit |
4a16fb |
const char **ptrp)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
char *ptr = (char *)*ptrp;
|
|
Packit |
4a16fb |
int items, i, len;
|
|
Packit |
4a16fb |
const char *name;
|
|
Packit |
4a16fb |
char end;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
items = snd_ctl_elem_info_get_items(info);
|
|
Packit |
4a16fb |
if (items <= 0)
|
|
Packit |
4a16fb |
return -1;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
for (i = 0; i < items; i++) {
|
|
Packit |
4a16fb |
snd_ctl_elem_info_set_item(info, i);
|
|
Packit |
4a16fb |
if (snd_ctl_elem_info(handle, info) < 0)
|
|
Packit |
4a16fb |
return -1;
|
|
Packit |
4a16fb |
name = snd_ctl_elem_info_get_item_name(info);
|
|
Packit |
4a16fb |
end = *ptr;
|
|
Packit |
4a16fb |
if (end == '\'' || end == '"')
|
|
Packit |
4a16fb |
ptr++;
|
|
Packit |
4a16fb |
else
|
|
Packit |
4a16fb |
end = '\0';
|
|
Packit |
4a16fb |
len = strlen(name);
|
|
Packit |
4a16fb |
if (strncmp(name, ptr, len) == 0) {
|
|
Packit |
4a16fb |
if (ptr[len] == end || ptr[len] == ',' || ptr[len] == '\n') {
|
|
Packit |
4a16fb |
ptr += len;
|
|
Packit |
4a16fb |
*ptrp = ptr;
|
|
Packit |
4a16fb |
return i;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
return -1;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit Service |
f36a15 |
static unsigned int get_ctl_type_max_elements(snd_ctl_elem_type_t type)
|
|
Packit Service |
f36a15 |
{
|
|
Packit Service |
f36a15 |
struct snd_ctl_elem_value value;
|
|
Packit Service |
f36a15 |
|
|
Packit Service |
f36a15 |
switch (type) {
|
|
Packit Service |
f36a15 |
case SND_CTL_ELEM_TYPE_BOOLEAN:
|
|
Packit Service |
f36a15 |
case SND_CTL_ELEM_TYPE_INTEGER:
|
|
Packit Service |
f36a15 |
return ARRAY_SIZE(value.value.integer.value);
|
|
Packit Service |
f36a15 |
case SND_CTL_ELEM_TYPE_INTEGER64:
|
|
Packit Service |
f36a15 |
return ARRAY_SIZE(value.value.integer64.value);
|
|
Packit Service |
f36a15 |
case SND_CTL_ELEM_TYPE_ENUMERATED:
|
|
Packit Service |
f36a15 |
return ARRAY_SIZE(value.value.enumerated.item);
|
|
Packit Service |
f36a15 |
case SND_CTL_ELEM_TYPE_BYTES:
|
|
Packit Service |
f36a15 |
return ARRAY_SIZE(value.value.bytes.data);
|
|
Packit Service |
f36a15 |
default:
|
|
Packit Service |
f36a15 |
return 0;
|
|
Packit Service |
f36a15 |
}
|
|
Packit Service |
f36a15 |
}
|
|
Packit Service |
f36a15 |
|
|
Packit |
4a16fb |
/**
|
|
Packit |
4a16fb |
* \brief parse ASCII string as CTL element value
|
|
Packit |
4a16fb |
* \param handle CTL handle
|
|
Packit |
4a16fb |
* \param dst destination CTL element value
|
|
Packit |
4a16fb |
* \param info CTL element info structure
|
|
Packit |
4a16fb |
* \param value source ASCII string
|
|
Packit |
4a16fb |
* \return zero on success, otherwise a negative error code
|
|
Packit |
4a16fb |
*
|
|
Packit |
4a16fb |
* Note: For toggle command, the dst must contain previous (current)
|
|
Packit |
4a16fb |
* state (do the #snd_ctl_elem_read call to obtain it).
|
|
Packit |
4a16fb |
*/
|
|
Packit |
4a16fb |
int snd_ctl_ascii_value_parse(snd_ctl_t *handle,
|
|
Packit |
4a16fb |
snd_ctl_elem_value_t *dst,
|
|
Packit |
4a16fb |
snd_ctl_elem_info_t *info,
|
|
Packit |
4a16fb |
const char *value)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
const char *ptr = value;
|
|
Packit |
4a16fb |
snd_ctl_elem_id_t myid = {0};
|
|
Packit |
4a16fb |
snd_ctl_elem_type_t type;
|
|
Packit |
4a16fb |
unsigned int idx, count;
|
|
Packit |
4a16fb |
long tmp;
|
|
Packit |
4a16fb |
long long tmp64;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
snd_ctl_elem_info_get_id(info, &myid);
|
|
Packit |
4a16fb |
type = snd_ctl_elem_info_get_type(info);
|
|
Packit |
4a16fb |
count = snd_ctl_elem_info_get_count(info);
|
|
Packit |
4a16fb |
snd_ctl_elem_value_set_id(dst, &myid);
|
|
Packit Service |
f36a15 |
|
|
Packit Service |
f36a15 |
if (count > get_ctl_type_max_elements(type))
|
|
Packit Service |
f36a15 |
count = get_ctl_type_max_elements(type);
|
|
Packit |
4a16fb |
|
|
Packit Service |
f36a15 |
for (idx = 0; idx < count && ptr && *ptr; idx++) {
|
|
Packit |
4a16fb |
if (*ptr == ',')
|
|
Packit |
4a16fb |
goto skip;
|
|
Packit |
4a16fb |
switch (type) {
|
|
Packit |
4a16fb |
case SND_CTL_ELEM_TYPE_BOOLEAN:
|
|
Packit |
4a16fb |
tmp = 0;
|
|
Packit |
4a16fb |
if (!strncasecmp(ptr, "on", 2) ||
|
|
Packit |
4a16fb |
!strncasecmp(ptr, "up", 2)) {
|
|
Packit |
4a16fb |
tmp = 1;
|
|
Packit |
4a16fb |
ptr += 2;
|
|
Packit |
4a16fb |
} else if (!strncasecmp(ptr, "yes", 3)) {
|
|
Packit |
4a16fb |
tmp = 1;
|
|
Packit |
4a16fb |
ptr += 3;
|
|
Packit |
4a16fb |
} else if (!strncasecmp(ptr, "toggle", 6)) {
|
|
Packit |
4a16fb |
tmp = snd_ctl_elem_value_get_boolean(dst, idx);
|
|
Packit |
4a16fb |
tmp = tmp > 0 ? 0 : 1;
|
|
Packit |
4a16fb |
ptr += 6;
|
|
Packit |
4a16fb |
} else if (isdigit(*ptr)) {
|
|
Packit |
4a16fb |
tmp = atoi(ptr) > 0 ? 1 : 0;
|
|
Packit |
4a16fb |
while (isdigit(*ptr))
|
|
Packit |
4a16fb |
ptr++;
|
|
Packit |
4a16fb |
} else {
|
|
Packit |
4a16fb |
while (*ptr && *ptr != ',')
|
|
Packit |
4a16fb |
ptr++;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
snd_ctl_elem_value_set_boolean(dst, idx, tmp);
|
|
Packit |
4a16fb |
break;
|
|
Packit |
4a16fb |
case SND_CTL_ELEM_TYPE_INTEGER:
|
|
Packit |
4a16fb |
tmp = get_integer(&ptr,
|
|
Packit |
4a16fb |
snd_ctl_elem_info_get_min(info),
|
|
Packit |
4a16fb |
snd_ctl_elem_info_get_max(info));
|
|
Packit |
4a16fb |
snd_ctl_elem_value_set_integer(dst, idx, tmp);
|
|
Packit |
4a16fb |
break;
|
|
Packit |
4a16fb |
case SND_CTL_ELEM_TYPE_INTEGER64:
|
|
Packit |
4a16fb |
tmp64 = get_integer64(&ptr,
|
|
Packit |
4a16fb |
snd_ctl_elem_info_get_min64(info),
|
|
Packit |
4a16fb |
snd_ctl_elem_info_get_max64(info));
|
|
Packit |
4a16fb |
snd_ctl_elem_value_set_integer64(dst, idx, tmp64);
|
|
Packit |
4a16fb |
break;
|
|
Packit |
4a16fb |
case SND_CTL_ELEM_TYPE_ENUMERATED:
|
|
Packit |
4a16fb |
tmp = get_ctl_enum_item_index(handle, info, &ptr);
|
|
Packit |
4a16fb |
if (tmp < 0)
|
|
Packit |
4a16fb |
tmp = get_integer(&ptr, 0,
|
|
Packit |
4a16fb |
snd_ctl_elem_info_get_items(info) - 1);
|
|
Packit |
4a16fb |
snd_ctl_elem_value_set_enumerated(dst, idx, tmp);
|
|
Packit |
4a16fb |
break;
|
|
Packit |
4a16fb |
case SND_CTL_ELEM_TYPE_BYTES:
|
|
Packit |
4a16fb |
tmp = get_integer(&ptr, 0, 255);
|
|
Packit |
4a16fb |
snd_ctl_elem_value_set_byte(dst, idx, tmp);
|
|
Packit |
4a16fb |
break;
|
|
Packit |
4a16fb |
default:
|
|
Packit |
4a16fb |
break;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
skip:
|
|
Packit |
4a16fb |
if (!strchr(value, ','))
|
|
Packit |
4a16fb |
ptr = value;
|
|
Packit |
4a16fb |
else if (*ptr == ',')
|
|
Packit |
4a16fb |
ptr++;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
return 0;
|
|
Packit |
4a16fb |
}
|