This will allow simplifying card implementations in later patches. Ports can be added automatically to sinks and sources via the prototype, and profiles can be added automatically to ports. --- src/modules/alsa/alsa-mixer.c | 26 +++++++++++++++++++++++++ src/modules/bluetooth/module-bluetooth-device.c | 2 ++ src/pulsecore/card.c | 4 ++++ src/pulsecore/card.h | 1 + 4 files changed, 33 insertions(+) diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c index 1e08ec3..c5af98e 100644 --- a/src/modules/alsa/alsa-mixer.c +++ b/src/modules/alsa/alsa-mixer.c @@ -3384,17 +3384,43 @@ pa_alsa_mapping *pa_alsa_mapping_get(pa_alsa_profile_set *ps, const char *name) pa_device_prototype *pa_alsa_mapping_create_device_prototype(pa_alsa_mapping *mapping, pa_direction_t direction) { pa_device_prototype *prototype; + bool use_ucm; + pa_alsa_path_set *path_set = NULL; + pa_device_port *port; + unsigned idx; pa_assert(mapping); prototype = pa_device_prototype_new(direction); + use_ucm = mapping->profile_set->use_ucm; if (direction == PA_DIRECTION_OUTPUT) { pa_assert(!mapping->sink_prototype); mapping->sink_prototype = prototype; + + if (!use_ucm) + path_set = mapping->output_path_set; } else { pa_assert(!mapping->source_prototype); mapping->source_prototype = prototype; + + if (!use_ucm) + path_set = mapping->output_path_set; + } + + if (use_ucm) { + pa_alsa_ucm_mapping_context *context = &mapping->ucm_context; + + PA_DYNARRAY_FOREACH(port, context->ports, idx) + pa_hashmap_put(prototype->ports, port->name, port); + } else { + pa_alsa_path *path; + void *state; + + PA_HASHMAP_FOREACH(path, path_set->paths, state) { + PA_DYNARRAY_FOREACH(port, path->ports, idx) + pa_hashmap_put(prototype->ports, port->name, port); + } } return prototype; diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index f44eb2f..676f36a 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -2320,8 +2320,10 @@ static int add_card(struct userdata *u) { * supports one direction, because it makes the code simpler. Having an * extra prototype does no harm. */ u->sink_prototype = pa_device_prototype_new(PA_DIRECTION_OUTPUT); + pa_hashmap_put(u->sink_prototype->ports, u->output_port->name, u->output_port); pa_card_new_data_add_device_prototype(&data, u->sink_prototype); u->source_prototype = pa_device_prototype_new(PA_DIRECTION_INPUT); + pa_hashmap_put(u->source_prototype->ports, u->input_port->name, u->input_port); pa_card_new_data_add_device_prototype(&data, u->source_prototype); PA_LLIST_FOREACH(uuid, device->uuids) { diff --git a/src/pulsecore/card.c b/src/pulsecore/card.c index 7f57e02..3e2ec69 100644 --- a/src/pulsecore/card.c +++ b/src/pulsecore/card.c @@ -43,6 +43,7 @@ pa_device_prototype *pa_device_prototype_new(pa_direction_t direction) { prototype = pa_xnew0(pa_device_prototype, 1); prototype->direction = direction; + prototype->ports = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); return prototype; } @@ -50,6 +51,9 @@ pa_device_prototype *pa_device_prototype_new(pa_direction_t direction) { void pa_device_prototype_free(pa_device_prototype *prototype) { pa_assert(prototype); + if (prototype->ports) + pa_hashmap_free(prototype->ports); + pa_xfree(prototype); } diff --git a/src/pulsecore/card.h b/src/pulsecore/card.h index 850dfa1..e46b86d 100644 --- a/src/pulsecore/card.h +++ b/src/pulsecore/card.h @@ -53,6 +53,7 @@ typedef enum pa_available { * https://bugs.freedesktop.org/show_bug.cgi?id=72523 ). */ typedef struct pa_device_prototype { pa_direction_t direction; + pa_hashmap *ports; /* Port name -> pa_device_port. Populate this before calling pa_card_new_data_add_device_prototype(). */ void *device; /* Either pa_sink or pa_source, depending on the direction. */ } pa_device_prototype; -- 1.8.3.1