OSDN Git Service

control: add _snd_ctl_open_child()
authorJaroslav Kysela <perex@perex.cz>
Mon, 29 Mar 2021 10:19:21 +0000 (12:19 +0200)
committerJaroslav Kysela <perex@perex.cz>
Wed, 7 Apr 2021 14:22:45 +0000 (16:22 +0200)
To support internal plugins, add internal _snd_ctl_open_child()
function like _snd_pcm_open_slave().

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
src/control/control.c
src/control/control_local.h

index 17d1baa..08e8d34 100644 (file)
@@ -1469,20 +1469,44 @@ static int snd_ctl_open_conf(snd_ctl_t **ctlp, const char *name,
        return err;
 }
 
-static int snd_ctl_open_noupdate(snd_ctl_t **ctlp, snd_config_t *root, const char *name, int mode)
+static int snd_ctl_open_noupdate(snd_ctl_t **ctlp, snd_config_t *root,
+                                const char *name, int mode, int hop)
 {
        int err;
        snd_config_t *ctl_conf;
+       const char *str;
+
        err = snd_config_search_definition(root, "ctl", name, &ctl_conf);
        if (err < 0) {
                SNDERR("Invalid CTL %s", name);
                return err;
        }
-       err = snd_ctl_open_conf(ctlp, name, root, ctl_conf, mode);
+       if (snd_config_get_string(ctl_conf, &str) >= 0)
+               err = snd_ctl_open_noupdate(ctlp, root, str, mode, hop + 1);
+       else {
+               snd_config_set_hop(ctl_conf, hop);
+               err = snd_ctl_open_conf(ctlp, name, root, ctl_conf, mode);
+       }
        snd_config_delete(ctl_conf);
        return err;
 }
 
+#ifndef DOC_HIDDEN
+int _snd_ctl_open_named_child(snd_ctl_t **pctl, const char *name,
+                             snd_config_t *root, snd_config_t *conf,
+                             int mode, snd_config_t *parent_conf)
+{
+       const char *str;
+       int hop;
+
+       if ((hop = snd_config_check_hop(parent_conf)) < 0)
+               return hop;
+       if (snd_config_get_string(conf, &str) >= 0)
+               return snd_ctl_open_noupdate(pctl, root, str, mode, hop + 1);
+       return snd_ctl_open_conf(pctl, name, root, conf, mode);
+}
+#endif
+
 /**
  * \brief Opens a CTL
  * \param ctlp Returned CTL handle
@@ -1499,7 +1523,7 @@ int snd_ctl_open(snd_ctl_t **ctlp, const char *name, int mode)
        err = snd_config_update_ref(&top);
        if (err < 0)
                return err;
-       err = snd_ctl_open_noupdate(ctlp, top, name, mode);
+       err = snd_ctl_open_noupdate(ctlp, top, name, mode, 0);
        snd_config_unref(top);
        return err;
 }
@@ -1516,7 +1540,7 @@ int snd_ctl_open_lconf(snd_ctl_t **ctlp, const char *name,
                       int mode, snd_config_t *lconf)
 {
        assert(ctlp && name && lconf);
-       return snd_ctl_open_noupdate(ctlp, lconf, name, mode);
+       return snd_ctl_open_noupdate(ctlp, lconf, name, mode, 0);
 }
 
 /**
@@ -1533,7 +1557,7 @@ int snd_ctl_open_fallback(snd_ctl_t **ctlp, snd_config_t *root,
 {
        int err;
        assert(ctlp && name && root);
-       err = snd_ctl_open_noupdate(ctlp, root, name, mode);
+       err = snd_ctl_open_noupdate(ctlp, root, name, mode, 0);
        if (err >= 0) {
                free((*ctlp)->name);
                (*ctlp)->name = orig_name ? strdup(orig_name) : NULL;
@@ -3532,4 +3556,3 @@ void snd_ctl_elem_value_set_iec958(snd_ctl_elem_value_t *obj, const snd_aes_iec9
        assert(obj && ptr);
        memcpy(&obj->value.iec958, ptr, sizeof(obj->value.iec958));
 }
-
index 9e20547..b3f6ee7 100644 (file)
@@ -107,6 +107,16 @@ int INTERNAL(snd_ctl_elem_info_get_dimensions)(const snd_ctl_elem_info_t *obj);
 int INTERNAL(snd_ctl_elem_info_get_dimension)(const snd_ctl_elem_info_t *obj, unsigned int idx);
 #endif /* INTERNAL */
 
+int _snd_ctl_open_named_child(snd_ctl_t **pctl, const char *name,
+                             snd_config_t *root, snd_config_t *conf,
+                             int mode, snd_config_t *parent_conf);
+static inline int
+_snd_ctl_open_child(snd_ctl_t **pctl, snd_config_t *root,
+                   snd_config_t *conf, int mode, snd_config_t *parent_conf)
+{
+       return _snd_ctl_open_named_child(pctl, NULL, root, conf, mode, parent_conf);
+}
+
 int __snd_ctl_add_elem_set(snd_ctl_t *ctl, snd_ctl_elem_info_t *info,
                           unsigned int element_count,
                           unsigned int member_count);