mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-29 05:40:25 -04:00
ucm: allow bind modifier to specific instances, other fixes
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
parent
a16008023e
commit
37c7e2843f
5 changed files with 67 additions and 17 deletions
|
|
@ -467,14 +467,36 @@ static int is_modifier_supported(snd_use_case_mgr_t *uc_mgr,
|
||||||
struct use_case_modifier *modifier)
|
struct use_case_modifier *modifier)
|
||||||
{
|
{
|
||||||
struct dev_list *device;
|
struct dev_list *device;
|
||||||
struct list_head *pos;
|
struct use_case_device *adev;
|
||||||
|
struct list_head *pos, *pos1;
|
||||||
|
char *cpos;
|
||||||
|
int dlen, len;
|
||||||
|
|
||||||
list_for_each(pos, &modifier->dev_list) {
|
list_for_each(pos, &modifier->dev_list) {
|
||||||
device = list_entry(pos, struct dev_list, list);
|
device = list_entry(pos, struct dev_list, list);
|
||||||
if (find(&uc_mgr->active_devices,
|
cpos = strchr(device->name, '.');
|
||||||
struct use_case_device, active_list, name, device->name))
|
if (cpos) {
|
||||||
return 1;
|
if (find(&uc_mgr->active_devices,
|
||||||
|
struct use_case_device, active_list,
|
||||||
|
name, device->name))
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
dlen = strlen(device->name);
|
||||||
|
list_for_each(pos1, &uc_mgr->active_devices) {
|
||||||
|
adev = list_entry(pos1, struct use_case_device,
|
||||||
|
active_list);
|
||||||
|
cpos = strchr(adev->name, '.');
|
||||||
|
if (cpos)
|
||||||
|
len = cpos - adev->name;
|
||||||
|
else
|
||||||
|
len = strlen(adev->name);
|
||||||
|
if (len != dlen)
|
||||||
|
continue;
|
||||||
|
if (memcmp(adev->name, device->name, len))
|
||||||
|
continue;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -497,6 +519,7 @@ static struct use_case_modifier *
|
||||||
modifier = list_entry(pos, struct use_case_modifier, list);
|
modifier = list_entry(pos, struct use_case_modifier, list);
|
||||||
|
|
||||||
strncpy(name, modifier->name, sizeof(name));
|
strncpy(name, modifier->name, sizeof(name));
|
||||||
|
name[sizeof(name)-1] = '\0';
|
||||||
cpos = strchr(name, '.');
|
cpos = strchr(name, '.');
|
||||||
if (!cpos)
|
if (!cpos)
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -1397,8 +1420,8 @@ int snd_use_case_set(snd_use_case_mgr_t *uc_mgr,
|
||||||
const char *identifier,
|
const char *identifier,
|
||||||
const char *value)
|
const char *value)
|
||||||
{
|
{
|
||||||
char *str, *str1;
|
char *str, *str1;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
pthread_mutex_lock(&uc_mgr->mutex);
|
pthread_mutex_lock(&uc_mgr->mutex);
|
||||||
if (strcmp(identifier, "_verb") == 0)
|
if (strcmp(identifier, "_verb") == 0)
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,27 @@ int parse_string(snd_config_t *n, char **res)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse safe ID
|
||||||
|
*/
|
||||||
|
int parse_is_name_safe(char *name)
|
||||||
|
{
|
||||||
|
if (strchr(name, '.')) {
|
||||||
|
uc_error("char '.' now allowed in '%s'", name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int parse_get_safe_id(snd_config_t *n, const char **id)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = snd_config_get_id(n, id);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
return parse_is_name_safe((char *)(*id));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse transition
|
* Parse transition
|
||||||
|
|
@ -367,13 +388,13 @@ static int parse_value(snd_use_case_mgr_t *uc_mgr ATTRIBUTE_UNUSED,
|
||||||
/*
|
/*
|
||||||
* Parse Modifier Use cases
|
* Parse Modifier Use cases
|
||||||
*
|
*
|
||||||
* # Each modifier is described in new section. N modifier are allowed
|
* # Each modifier is described in new section. N modifiers are allowed
|
||||||
* SectionModifier."Capture Voice" {
|
* SectionModifier."Capture Voice".0 {
|
||||||
*
|
*
|
||||||
* Comment "Record voice call"
|
* Comment "Record voice call"
|
||||||
* SupportedDevice [
|
* SupportedDevice [
|
||||||
* "x"
|
* "x" # all x device instances
|
||||||
* "y"
|
* "y.0" # device y instance 0 only
|
||||||
* ]
|
* ]
|
||||||
*
|
*
|
||||||
* EnableSequence [
|
* EnableSequence [
|
||||||
|
|
@ -411,6 +432,8 @@ static int parse_modifier(snd_use_case_mgr_t *uc_mgr,
|
||||||
snd_config_t *n;
|
snd_config_t *n;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
if (!parse_is_name_safe(name))
|
||||||
|
return -EINVAL;
|
||||||
/* allocate modifier */
|
/* allocate modifier */
|
||||||
modifier = calloc(1, sizeof(*modifier));
|
modifier = calloc(1, sizeof(*modifier));
|
||||||
if (modifier == NULL)
|
if (modifier == NULL)
|
||||||
|
|
@ -421,7 +444,7 @@ static int parse_modifier(snd_use_case_mgr_t *uc_mgr,
|
||||||
INIT_LIST_HEAD(&modifier->dev_list);
|
INIT_LIST_HEAD(&modifier->dev_list);
|
||||||
INIT_LIST_HEAD(&modifier->value_list);
|
INIT_LIST_HEAD(&modifier->value_list);
|
||||||
list_add_tail(&modifier->list, &verb->modifier_list);
|
list_add_tail(&modifier->list, &verb->modifier_list);
|
||||||
err = snd_config_get_id(cfg, &id);
|
err = parse_get_safe_id(cfg, &id);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
modifier->name = malloc(strlen(name) + strlen(id) + 2);
|
modifier->name = malloc(strlen(name) + strlen(id) + 2);
|
||||||
|
|
@ -496,7 +519,7 @@ static int parse_modifier(snd_use_case_mgr_t *uc_mgr,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (list_empty(&modifier->dev_list)) {
|
if (list_empty(&modifier->dev_list)) {
|
||||||
uc_error("error: %s: modifier missing supported device sequence");
|
uc_error("error: %s: modifier missing supported device sequence", modifier->name);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -541,6 +564,8 @@ static int parse_device_index(snd_use_case_mgr_t *uc_mgr,
|
||||||
snd_config_t *n;
|
snd_config_t *n;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
if (!parse_is_name_safe(name))
|
||||||
|
return -EINVAL;
|
||||||
device = calloc(1, sizeof(*device));
|
device = calloc(1, sizeof(*device));
|
||||||
if (device == NULL)
|
if (device == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
@ -549,7 +574,7 @@ static int parse_device_index(snd_use_case_mgr_t *uc_mgr,
|
||||||
INIT_LIST_HEAD(&device->transition_list);
|
INIT_LIST_HEAD(&device->transition_list);
|
||||||
INIT_LIST_HEAD(&device->value_list);
|
INIT_LIST_HEAD(&device->value_list);
|
||||||
list_add_tail(&device->list, &verb->device_list);
|
list_add_tail(&device->list, &verb->device_list);
|
||||||
if (snd_config_get_id(cfg, &id) < 0)
|
if (parse_get_safe_id(cfg, &id) < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
device->name = malloc(strlen(name) + strlen(id) + 2);
|
device->name = malloc(strlen(name) + strlen(id) + 2);
|
||||||
if (device->name == NULL)
|
if (device->name == NULL)
|
||||||
|
|
@ -904,7 +929,7 @@ static int parse_master_section(snd_use_case_mgr_t *uc_mgr, snd_config_t *cfg,
|
||||||
uc_error("unknown field %s in master section");
|
uc_error("unknown field %s in master section");
|
||||||
}
|
}
|
||||||
|
|
||||||
uc_dbg("use_case_name %s file %s end %d", use_case_name, file, end);
|
uc_dbg("use_case_name %s file '%s'", use_case_name, file);
|
||||||
|
|
||||||
/* do we have both use case name and file ? */
|
/* do we have both use case name and file ? */
|
||||||
if (!file) {
|
if (!file) {
|
||||||
|
|
|
||||||
|
|
@ -192,7 +192,7 @@ struct snd_use_case_mgr {
|
||||||
#ifdef UC_MGR_DEBUG
|
#ifdef UC_MGR_DEBUG
|
||||||
#define uc_dbg SNDERR
|
#define uc_dbg SNDERR
|
||||||
#else
|
#else
|
||||||
#define uc_dbg(fmt, arg...)
|
#define uc_dbg(fmt, arg...) do { } while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void uc_mgr_error(const char *fmt, ...);
|
void uc_mgr_error(const char *fmt, ...);
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ SectionDevice."Device1".0 {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SectionModifier."Modifier1" {
|
SectionModifier."Modifier1".0 {
|
||||||
SupportedDevice [
|
SupportedDevice [
|
||||||
"Device1"
|
"Device1"
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -8,4 +8,6 @@ SectionUseCase."Case1" {
|
||||||
SectionDefaults [
|
SectionDefaults [
|
||||||
exec "my prg"
|
exec "my prg"
|
||||||
msleep 1
|
msleep 1
|
||||||
|
cdev "hw:0"
|
||||||
|
cset "name='PCM Playback Volume' 50%"
|
||||||
]
|
]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue