The recommended way of setting available status is to call pa_device_port_set_available, which will send subscriptions to relevant card, sink and source. It will also fire a hook. Signed-off-by: David Henningsson <david.henningsson at canonical.com> --- src/pulsecore/core.h | 1 + src/pulsecore/device-port.c | 44 +++++++++++++++++++++++++++++++++++++++++- src/pulsecore/device-port.h | 12 ++++++++++- 3 files changed, 54 insertions(+), 3 deletions(-) diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h index d0641cf..ba21fa9 100644 --- a/src/pulsecore/core.h +++ b/src/pulsecore/core.h @@ -113,6 +113,7 @@ typedef enum pa_core_hook { PA_CORE_HOOK_CARD_PUT, PA_CORE_HOOK_CARD_UNLINK, PA_CORE_HOOK_CARD_PROFILE_CHANGED, + PA_CORE_HOOK_PORT_AVAILABLE_CHANGED, PA_CORE_HOOK_MAX } pa_core_hook_t; diff --git a/src/pulsecore/device-port.c b/src/pulsecore/device-port.c index 753702a..030069a 100644 --- a/src/pulsecore/device-port.c +++ b/src/pulsecore/device-port.c @@ -21,11 +21,50 @@ USA. ***/ - #include "device-port.h" +#include <pulsecore/card.h> PA_DEFINE_PUBLIC_CLASS(pa_device_port, pa_object); +void pa_device_port_set_available(pa_device_port *p, pa_port_available_t status) +{ + uint32_t state; + pa_card *card; + pa_source *source; + pa_sink *sink; + pa_core *core; + + pa_assert(p); + + if (p->available == status) + return; + + pa_assert(status != PA_PORT_AVAILABLE_UNKNOWN); + + p->available = status; + pa_log_debug("Setting port %s to status %s", p->name, status == PA_PORT_AVAILABLE_YES ? "yes" : "no"); + + /* Post subscriptions to everyone who own us */ +#if 0 +/* This stuff is temporarily commented out while figuring out whether to actually do this or to + add a PA_SUBSCRIPTION_EVENT_PORT instead (and the consequences of doing so) */ + pa_assert_se(core = p->core); + PA_IDXSET_FOREACH(card, core->cards, state) + if (p == pa_hashmap_get(card->ports, p->name)) + pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_CARD|PA_SUBSCRIPTION_EVENT_CHANGE, card->index); + if (p->is_output) + PA_IDXSET_FOREACH(sink, core->sinks, state) + if (p == pa_hashmap_get(sink->ports, p->name)) + pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, sink->index); + if (p->is_input) + PA_IDXSET_FOREACH(source, core->sources, state) + if (p == pa_hashmap_get(source->ports, p->name)) + pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, source->index); +#endif + + pa_hook_fire(&core->hooks[PA_CORE_HOOK_PORT_AVAILABLE_CHANGED], p); +} + static void device_port_free(pa_object *o) { pa_device_port *p = PA_DEVICE_PORT(o); @@ -40,7 +79,7 @@ static void device_port_free(pa_object *o) { } -pa_device_port *pa_device_port_new(const char *name, const char *description, size_t extra) { +pa_device_port *pa_device_port_new(const char *name, const char *description, pa_core *c, size_t extra) { pa_device_port *p; pa_assert(name); @@ -50,6 +89,7 @@ pa_device_port *pa_device_port_new(const char *name, const char *description, si p->name = pa_xstrdup(name); p->description = pa_xstrdup(description); + p->core = c; p->priority = 0; p->available = PA_PORT_AVAILABLE_UNKNOWN; p->profiles = NULL; diff --git a/src/pulsecore/device-port.h b/src/pulsecore/device-port.h index f997c77..5775b9c 100644 --- a/src/pulsecore/device-port.h +++ b/src/pulsecore/device-port.h @@ -35,10 +35,15 @@ #include <pulsecore/object.h> #include <pulsecore/hashmap.h> +/* Note: Including core.h here leads to circular references + (device-port.h -> core.h -> sink.h -> device-port.h), hence the line below instead */ +typedef struct pa_core pa_core; + typedef struct pa_device_port pa_device_port; struct pa_device_port { pa_object parent; /* Needed for reference counting */ + pa_core *core; char *name; char *description; @@ -58,8 +63,13 @@ PA_DECLARE_PUBLIC_CLASS(pa_device_port); #define PA_DEVICE_PORT_DATA(d) ((void*) ((uint8_t*) d + PA_ALIGN(sizeof(pa_device_port)))) -pa_device_port *pa_device_port_new(const char *name, const char *description, size_t extra); +pa_device_port *pa_device_port_new(const char *name, const char *description, pa_core *c, size_t extra); void pa_device_port_hashmap_free(pa_hashmap *h); +#include <pulsecore/core.h> + +/* The port's available status has changed */ +void pa_device_port_set_available(pa_device_port *p, pa_port_available_t available); + #endif -- 1.7.5.4