ucm: add support for ControlEnum in ControlExists condition

Condition {
  Type ControlExists
  Control "name='Capture Input'"
  ControlEnum "Headphone Mic"
}

The result is true if the control exists, it is the enumerated
type and has the item with the ControlEnum text (name).

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
Jaroslav Kysela 2019-11-29 09:33:50 +01:00
parent 6eb4f8a724
commit 15970ebf7f

View file

@ -163,12 +163,12 @@ static int if_eval_regex_match(snd_use_case_mgr_t *uc_mgr, snd_config_t *eval)
static int if_eval_control_exists(snd_use_case_mgr_t *uc_mgr, snd_config_t *eval) static int if_eval_control_exists(snd_use_case_mgr_t *uc_mgr, snd_config_t *eval)
{ {
snd_ctl_t *ctl; snd_ctl_t *ctl;
const char *device = NULL, *ctldef; const char *device = NULL, *ctldef, *enumval = NULL, *name;
snd_ctl_elem_id_t *elem_id; snd_ctl_elem_id_t *elem_id;
snd_ctl_elem_info_t *elem_info; snd_ctl_elem_info_t *elem_info;
snd_ctl_elem_type_t type;
char *s; char *s;
int err; int err, i, items;
snd_ctl_elem_id_alloca(&elem_id); snd_ctl_elem_id_alloca(&elem_id);
snd_ctl_elem_info_alloca(&elem_info); snd_ctl_elem_info_alloca(&elem_info);
@ -185,6 +185,12 @@ static int if_eval_control_exists(snd_use_case_mgr_t *uc_mgr, snd_config_t *eval
return -EINVAL; return -EINVAL;
} }
err = get_string(eval, "ControlEnum", &enumval);
if (err < 0 && err != -ENOENT) {
uc_error("ControlExists error (If.Condition.ControlEnum)");
return -EINVAL;
}
err = uc_mgr_get_substituted_value(uc_mgr, &s, ctldef); err = uc_mgr_get_substituted_value(uc_mgr, &s, ctldef);
if (err < 0) if (err < 0)
return err; return err;
@ -216,6 +222,31 @@ static int if_eval_control_exists(snd_use_case_mgr_t *uc_mgr, snd_config_t *eval
if (err < 0) if (err < 0)
return 0; return 0;
if (enumval) {
type = snd_ctl_elem_info_get_type(elem_info);
if (type != SND_CTL_ELEM_TYPE_ENUMERATED)
return 0;
err = uc_mgr_get_substituted_value(uc_mgr, &s, enumval);
if (err < 0)
return err;
items = snd_ctl_elem_info_get_items(elem_info);
for (i = 0; i < items; i++) {
snd_ctl_elem_info_set_item(elem_info, i);
err = snd_ctl_elem_info(ctl, elem_info);
if (err < 0) {
free(s);
return err;
}
name = snd_ctl_elem_info_get_item_name(elem_info);
if (strcasecmp(name, s) == 0) {
free(s);
return 1;
}
}
free(s);
return 0;
}
return 1; return 1;
} }