]> git.alsa-project.org Git - alsa-lib.git/commitdiff
ucm: allow bind modifier to specific instances, other fixes
authorJaroslav Kysela <perex@perex.cz>
Mon, 31 Jan 2011 13:24:19 +0000 (14:24 +0100)
committerJaroslav Kysela <perex@perex.cz>
Mon, 31 Jan 2011 13:24:19 +0000 (14:24 +0100)
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
src/ucm/main.c
src/ucm/parser.c
src/ucm/ucm_local.h
test/ucm/TestHDA/Case1.conf
test/ucm/TestHDA/TestHDA.conf

index 030c9b1ce63983f99848a3931ad950e3fdb753f5..377f5609c2916a5de8bc457b05a99f4a2c3fa122 100644 (file)
@@ -467,14 +467,36 @@ static int is_modifier_supported(snd_use_case_mgr_t *uc_mgr,
        struct use_case_modifier *modifier)
 {
        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) {
                device = list_entry(pos, struct dev_list, list);
-               if (find(&uc_mgr->active_devices,
-                   struct use_case_device, active_list, name, device->name))
-                       return 1;
-               
+               cpos = strchr(device->name, '.');
+               if (cpos) {
+                       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;
 }
@@ -497,6 +519,7 @@ static struct use_case_modifier *
                modifier = list_entry(pos, struct use_case_modifier, list);
 
                strncpy(name, modifier->name, sizeof(name));
+               name[sizeof(name)-1] = '\0';
                cpos = strchr(name, '.');
                if (!cpos)
                        continue;
@@ -1397,8 +1420,8 @@ int snd_use_case_set(snd_use_case_mgr_t *uc_mgr,
                      const char *identifier,
                      const char *value)
 {
-       char *str, *str1;
-        int err;
+       char *str, *str1;
+       int err;
 
        pthread_mutex_lock(&uc_mgr->mutex);
        if (strcmp(identifier, "_verb") == 0)
index 010191ce057ea28d71cc29bc7332a4e2bab37dad..e8d246138dfed468286ddf9863db1a3e5afbe7ad 100644 (file)
@@ -56,6 +56,27 @@ int parse_string(snd_config_t *n, char **res)
        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
@@ -367,13 +388,13 @@ static int parse_value(snd_use_case_mgr_t *uc_mgr ATTRIBUTE_UNUSED,
 /*
  * Parse Modifier Use cases
  *
- *     # Each modifier is described in new section. N modifier are allowed
- *     SectionModifier."Capture Voice" {
+ *     # Each modifier is described in new section. N modifiers are allowed
+ *     SectionModifier."Capture Voice".0 {
  *
  *             Comment "Record voice call"
  *             SupportedDevice [
- *                     "x"
- *                     "y"
+ *                     "x"             # all x device instances
+ *                     "y.0"           # device y instance 0 only
  *             ]
  *
  *             EnableSequence [
@@ -411,6 +432,8 @@ static int parse_modifier(snd_use_case_mgr_t *uc_mgr,
        snd_config_t *n;
        int err;
 
+       if (!parse_is_name_safe(name))
+               return -EINVAL;
        /* allocate modifier */
        modifier = calloc(1, sizeof(*modifier));
        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->value_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)
                return err;
        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)) {
-               uc_error("error: %s: modifier missing supported device sequence");
+               uc_error("error: %s: modifier missing supported device sequence", modifier->name);
                return -EINVAL;
        }
 
@@ -541,6 +564,8 @@ static int parse_device_index(snd_use_case_mgr_t *uc_mgr,
        snd_config_t *n;
        int err;
        
+       if (!parse_is_name_safe(name))
+               return -EINVAL;
        device = calloc(1, sizeof(*device));
        if (device == NULL)
                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->value_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;
        device->name = malloc(strlen(name) + strlen(id) + 2);
        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_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 ? */
        if (!file) {
index 13e82da958dcedf86cc84fc6dc8f5fd6dbd5197b..1b00ea2120d801389d1fd1c7db651e992276ca41 100644 (file)
@@ -192,7 +192,7 @@ struct snd_use_case_mgr {
 #ifdef UC_MGR_DEBUG
 #define uc_dbg SNDERR
 #else
-#define uc_dbg(fmt, arg...)
+#define uc_dbg(fmt, arg...) do { } while (0)
 #endif
 
 void uc_mgr_error(const char *fmt, ...);
index 3d8cddf8f5784672c232273aa8d4ab59aebe5603..81b2445844daa6e05bc47118c1593eb5df76f2c7 100644 (file)
@@ -18,7 +18,7 @@ SectionDevice."Device1".0 {
        
 }
 
-SectionModifier."Modifier1" {
+SectionModifier."Modifier1".0 {
        SupportedDevice [
                "Device1"
        ]
index 9b93b96e5d3a30d5e0000be70ae04f33606999bb..41dd74c8ada5431e398ef9ad08b705ff57e27df5 100644 (file)
@@ -8,4 +8,6 @@ SectionUseCase."Case1" {
 SectionDefaults [
        exec "my prg"
        msleep 1
+       cdev "hw:0"
+       cset "name='PCM Playback Volume' 50%"
 ]