The device pointer can be used to navigate from a port to the sink or source. I found this useful when routing a stream to a port. As an unrelated change (perhaps should be in a separate patch) I moved the pa_device_prototype_set_device() calls in pa_sink_put() and pa_source_put() to happen a bit later, because the previous location was a bit illogical (in the middle of volume initialization code). --- src/pulsecore/device-port.c | 6 ++++++ src/pulsecore/device-port.h | 6 ++++++ src/pulsecore/sink.c | 17 ++++++++++++++--- src/pulsecore/source.c | 17 ++++++++++++++--- 4 files changed, 40 insertions(+), 6 deletions(-) diff --git a/src/pulsecore/device-port.c b/src/pulsecore/device-port.c index 76d52ae..9511940 100644 --- a/src/pulsecore/device-port.c +++ b/src/pulsecore/device-port.c @@ -197,6 +197,12 @@ fail: return NULL; } +void pa_device_port_set_device(pa_device_port *port, void *device) { + pa_assert(port); + + port->device = device; +} + void pa_device_port_set_latency_offset(pa_device_port *p, int64_t offset) { uint32_t state; pa_core *core; diff --git a/src/pulsecore/device-port.h b/src/pulsecore/device-port.h index 7e580c1..79feaf8 100644 --- a/src/pulsecore/device-port.h +++ b/src/pulsecore/device-port.h @@ -43,6 +43,10 @@ struct pa_device_port { pa_core *core; pa_card *card; + /* Points to a sink or source, or may also be NULL if the port doesn't + * belong to any currently existing sink or source. */ + void *device; + char *name; char *description; @@ -83,6 +87,8 @@ void pa_device_port_new_data_done(pa_device_port_new_data *data); pa_device_port *pa_device_port_new(pa_core *c, pa_device_port_new_data *data, size_t extra); +void pa_device_port_set_device(pa_device_port *port, void *device); + /* The port's available status has changed */ void pa_device_port_set_available(pa_device_port *p, pa_available_t available); diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index c2aea32..70894f2 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -597,6 +597,9 @@ void pa_sink_enable_decibel_volume(pa_sink *s, bool enable) { /* Called from main context */ void pa_sink_put(pa_sink* s) { + pa_device_port *port; + void *state; + pa_sink_assert_ref(s); pa_assert_ctl_context(); @@ -656,9 +659,6 @@ void pa_sink_put(pa_sink* s) { * place where he is supposed to place his changes. */ s->reference_volume = s->real_volume; - if (s->prototype) - pa_device_prototype_set_device(s->prototype, s); - s->thread_info.soft_volume = s->soft_volume; s->thread_info.soft_muted = s->muted; pa_sw_cvolume_multiply(&s->thread_info.current_hw_volume, &s->soft_volume, &s->real_volume); @@ -675,6 +675,12 @@ void pa_sink_put(pa_sink* s) { pa_assert(s->monitor_source->thread_info.min_latency == s->thread_info.min_latency); pa_assert(s->monitor_source->thread_info.max_latency == s->thread_info.max_latency); + if (s->prototype) + pa_device_prototype_set_device(s->prototype, s); + + PA_HASHMAP_FOREACH(port, s->ports, state) + pa_device_port_set_device(port, s); + if (s->suspend_cause) pa_assert_se(sink_set_state(s, PA_SINK_SUSPENDED) == 0); else @@ -695,6 +701,8 @@ void pa_sink_put(pa_sink* s) { /* Called from main context */ void pa_sink_unlink(pa_sink* s) { bool linked; + pa_device_port *port; + void *state; pa_sink_input *i, *j = NULL; pa_assert(s); @@ -716,6 +724,9 @@ void pa_sink_unlink(pa_sink* s) { if (s->node) pa_node_unlink(s->node); + PA_HASHMAP_FOREACH(port, s->ports, state) + pa_device_port_set_device(port, NULL); + if (s->prototype) pa_device_prototype_set_device(s->prototype, NULL); diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c index 0ccdcb3..44d2f70 100644 --- a/src/pulsecore/source.c +++ b/src/pulsecore/source.c @@ -559,6 +559,9 @@ void pa_source_enable_decibel_volume(pa_source *s, bool enable) { /* Called from main context */ void pa_source_put(pa_source *s) { + pa_device_port *port; + void *state; + pa_source_assert_ref(s); pa_assert_ctl_context(); @@ -618,9 +621,6 @@ void pa_source_put(pa_source *s) { * place where he is supposed to place his changes. */ s->reference_volume = s->real_volume; - if (s->prototype) - pa_device_prototype_set_device(s->prototype, s); - s->thread_info.soft_volume = s->soft_volume; s->thread_info.soft_muted = s->muted; pa_sw_cvolume_multiply(&s->thread_info.current_hw_volume, &s->soft_volume, &s->real_volume); @@ -631,6 +631,12 @@ void pa_source_put(pa_source *s) { pa_assert(!(s->flags & PA_SOURCE_DECIBEL_VOLUME) || s->n_volume_steps == PA_VOLUME_NORM+1); pa_assert(!(s->flags & PA_SOURCE_DYNAMIC_LATENCY) == (s->thread_info.fixed_latency != 0)); + if (s->prototype) + pa_device_prototype_set_device(s->prototype, s); + + PA_HASHMAP_FOREACH(port, s->ports, state) + pa_device_port_set_device(port, s); + if (s->suspend_cause) pa_assert_se(source_set_state(s, PA_SOURCE_SUSPENDED) == 0); else @@ -649,6 +655,8 @@ void pa_source_put(pa_source *s) { /* Called from main context */ void pa_source_unlink(pa_source *s) { bool linked; + pa_device_port *port; + void *state; pa_source_output *o, *j = NULL; pa_assert(s); @@ -665,6 +673,9 @@ void pa_source_unlink(pa_source *s) { if (s->node) pa_node_unlink(s->node); + PA_HASHMAP_FOREACH(port, s->ports, state) + pa_device_port_set_device(port, NULL); + if (s->prototype) pa_device_prototype_set_device(s->prototype, NULL); -- 1.8.3.1