[pulseaudio-discuss] [PATCH 4/4] Profiles can have sink and source ports, and announce that through the API.
David Henningsson
david.henningsson at canonical.com
Thu Jul 7 04:23:29 PDT 2011
Signed-off-by: David Henningsson <david.henningsson at canonical.com>
---
src/pulse/introspect.c | 139 +++++++++++++++++++++++----------------
src/pulse/introspect.h | 4 +
src/pulsecore/card.c | 2 +
src/pulsecore/card.h | 4 +
src/pulsecore/device-port.c | 11 +++
src/pulsecore/device-port.h | 4 +-
src/pulsecore/protocol-native.c | 25 +++++++
src/pulsecore/sink.c | 20 +-----
src/pulsecore/source.c | 20 +-----
9 files changed, 136 insertions(+), 93 deletions(-)
diff --git a/src/pulse/introspect.c b/src/pulse/introspect.c
index d1a0ed1..399d092 100644
--- a/src/pulse/introspect.c
+++ b/src/pulse/introspect.c
@@ -134,6 +134,42 @@ pa_operation* pa_context_get_server_info(pa_context *c, pa_server_info_cb_t cb,
/*** Sink Info ***/
+static int read_sink_ports(pa_tagstruct *t, pa_operation *o, uint32_t* n_sink_ports, pa_sink_port_info*** sink_ports) {
+ int err = 0;
+ uint32_t n_ports, j;
+ pa_sink_port_info** ports;
+
+ if (o->context->version < 16 || (err = pa_tagstruct_getu32(t, &n_ports)) < 0 || n_ports == 0) {
+ *n_sink_ports = 0;
+ *sink_ports = NULL;
+ return err;
+ }
+
+ ports = pa_xnew(pa_sink_port_info*, n_ports+1);
+ ports[0] = pa_xnew0(pa_sink_port_info, n_ports);
+
+ for (j = 0; j < n_ports; j++) {
+ if (pa_tagstruct_gets(t, &ports[0][j].name) < 0 ||
+ pa_tagstruct_gets(t, &ports[0][j].description) < 0 ||
+ pa_tagstruct_getu32(t, &ports[0][j].priority) < 0) {
+
+ return -1;
+ }
+ if (o->context->version >= JACK_DETECTION_PROTOCOL_VERSION) {
+ uint32_t av;
+ if (pa_tagstruct_getu32(t, &av) < 0 || av > PA_PORT_AVAILABLE_YES)
+ return -1;
+ ports[0][j].available = av;
+ }
+ ports[j] = &ports[0][j];
+ }
+
+ ports[j] = NULL;
+ *n_sink_ports = n_ports;
+ *sink_ports = ports;
+ return 0;
+}
+
static void context_get_sink_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_operation *o = userdata;
int eol = 1;
@@ -191,39 +227,14 @@ static void context_get_sink_info_callback(pa_pdispatch *pd, uint32_t command, u
(pa_tagstruct_get_volume(t, &i.base_volume) < 0 ||
pa_tagstruct_getu32(t, &state) < 0 ||
pa_tagstruct_getu32(t, &i.n_volume_steps) < 0 ||
- pa_tagstruct_getu32(t, &i.card) < 0)) ||
- (o->context->version >= 16 &&
- (pa_tagstruct_getu32(t, &i.n_ports)))) {
+ pa_tagstruct_getu32(t, &i.card) < 0))) {
goto fail;
}
if (o->context->version >= 16) {
- if (i.n_ports > 0) {
- i.ports = pa_xnew(pa_sink_port_info*, i.n_ports+1);
- i.ports[0] = pa_xnew(pa_sink_port_info, i.n_ports);
-
- for (j = 0; j < i.n_ports; j++) {
- if (pa_tagstruct_gets(t, &i.ports[0][j].name) < 0 ||
- pa_tagstruct_gets(t, &i.ports[0][j].description) < 0 ||
- pa_tagstruct_getu32(t, &i.ports[0][j].priority) < 0) {
-
- goto fail;
- }
-
- i.ports[0][j].available = PA_PORT_AVAILABLE_UNKNOWN;
- if (o->context->version >= JACK_DETECTION_PROTOCOL_VERSION) {
- uint32_t av;
- if (pa_tagstruct_getu32(t, &av) < 0 || av > PA_PORT_AVAILABLE_YES)
- goto fail;
- i.ports[0][j].available = av;
- }
-
- i.ports[j] = &i.ports[0][j];
- }
-
- i.ports[j] = NULL;
- }
+ if (read_sink_ports(t, o, &i.n_ports, &i.ports) < 0)
+ goto fail;
if (pa_tagstruct_gets(t, &ap) < 0)
goto fail;
@@ -407,6 +418,43 @@ pa_operation* pa_context_set_sink_port_by_name(pa_context *c, const char *name,
/*** Source info ***/
+static int read_source_ports(pa_tagstruct *t, pa_operation *o, uint32_t* n_source_ports, pa_source_port_info*** source_ports) {
+ int err = 0;
+ uint32_t n_ports, j;
+ pa_source_port_info** ports;
+
+ pa_log_debug("read_source_ports");
+ if (o->context->version < 16 || (err = pa_tagstruct_getu32(t, &n_ports)) < 0 || n_ports == 0) {
+ *n_source_ports = 0;
+ *source_ports = NULL;
+ return err;
+ }
+
+ ports = pa_xnew(pa_source_port_info*, n_ports+1);
+ ports[0] = pa_xnew0(pa_source_port_info, n_ports);
+
+ for (j = 0; j < n_ports; j++) {
+ if (pa_tagstruct_gets(t, &ports[0][j].name) < 0 ||
+ pa_tagstruct_gets(t, &ports[0][j].description) < 0 ||
+ pa_tagstruct_getu32(t, &ports[0][j].priority) < 0) {
+
+ return -1;
+ }
+ if (o->context->version >= JACK_DETECTION_PROTOCOL_VERSION) {
+ uint32_t av;
+ if (pa_tagstruct_getu32(t, &av) < 0 || av > PA_PORT_AVAILABLE_YES)
+ return -1;
+ ports[0][j].available = av;
+ }
+ ports[j] = &ports[0][j];
+ }
+
+ ports[j] = NULL;
+ *n_source_ports = n_ports;
+ *source_ports = ports;
+ return 0;
+}
+
static void context_get_source_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_operation *o = userdata;
int eol = 1;
@@ -464,39 +512,14 @@ static void context_get_source_info_callback(pa_pdispatch *pd, uint32_t command,
(pa_tagstruct_get_volume(t, &i.base_volume) < 0 ||
pa_tagstruct_getu32(t, &state) < 0 ||
pa_tagstruct_getu32(t, &i.n_volume_steps) < 0 ||
- pa_tagstruct_getu32(t, &i.card) < 0)) ||
- (o->context->version >= 16 &&
- (pa_tagstruct_getu32(t, &i.n_ports)))) {
+ pa_tagstruct_getu32(t, &i.card) < 0))) {
goto fail;
}
if (o->context->version >= 16) {
- if (i.n_ports > 0) {
- i.ports = pa_xnew(pa_source_port_info*, i.n_ports+1);
- i.ports[0] = pa_xnew(pa_source_port_info, i.n_ports);
-
- for (j = 0; j < i.n_ports; j++) {
- if (pa_tagstruct_gets(t, &i.ports[0][j].name) < 0 ||
- pa_tagstruct_gets(t, &i.ports[0][j].description) < 0 ||
- pa_tagstruct_getu32(t, &i.ports[0][j].priority) < 0) {
-
- goto fail;
- }
-
- i.ports[0][j].available = PA_PORT_AVAILABLE_UNKNOWN;
- if (o->context->version >= JACK_DETECTION_PROTOCOL_VERSION) {
- uint32_t av;
- if (pa_tagstruct_getu32(t, &av) < 0 || av > PA_PORT_AVAILABLE_YES)
- goto fail;
- i.ports[0][j].available = av;
- }
-
- i.ports[j] = &i.ports[0][j];
- }
-
- i.ports[j] = NULL;
- }
+ if (read_source_ports(t, o, &i.n_ports, &i.ports) < 0)
+ goto fail;
if (pa_tagstruct_gets(t, &ap) < 0)
goto fail;
@@ -813,6 +836,10 @@ static void context_get_card_info_callback(pa_pdispatch *pd, uint32_t command, u
pa_xfree(i.profiles);
goto finish;
}
+ if (o->context->version >= JACK_DETECTION_PROTOCOL_VERSION) {
+ read_sink_ports(t, o, &i.profiles[j].n_sink_ports, &i.profiles[j].sink_ports);
+ read_source_ports(t, o, &i.profiles[j].n_source_ports, &i.profiles[j].source_ports);
+ }
}
/* Terminate with an extra NULL entry, just to make sure */
diff --git a/src/pulse/introspect.h b/src/pulse/introspect.h
index 8e4cc97..259c57b 100644
--- a/src/pulse/introspect.h
+++ b/src/pulse/introspect.h
@@ -452,6 +452,10 @@ typedef struct pa_card_profile_info {
uint32_t n_sinks; /**< Number of sinks this profile would create */
uint32_t n_sources; /**< Number of sources this profile would create */
uint32_t priority; /**< The higher this value is the more useful this profile is as a default */
+ uint32_t n_sink_ports; /**< Number of entries in sink_ports array \since MERGE_OF_JACK_DETECTION */
+ pa_sink_port_info** sink_ports; /**< Array of available output ports, or NULL. Array is terminated by an entry set to NULL. The number of entries is stored in n_sink_ports. \since MERGE_OF_JACK_DETECTION */
+ uint32_t n_source_ports; /**< Number of entries in source_ports array \since MERGE_OF_JACK_DETECTION */
+ pa_source_port_info** source_ports; /**< Array of available input ports, or NULL. Array is terminated by an entry set to NULL. The number of entries is stored in n_source_ports. \since MERGE_OF_JACK_DETECTION */
} pa_card_profile_info;
/** Stores information about cards. Please note that this structure
diff --git a/src/pulsecore/card.c b/src/pulsecore/card.c
index feaa444..f1c5be5 100644
--- a/src/pulsecore/card.c
+++ b/src/pulsecore/card.c
@@ -56,6 +56,8 @@ pa_card_profile *pa_card_profile_new(const char *name, const char *description,
void pa_card_profile_free(pa_card_profile *c) {
pa_assert(c);
+ pa_device_port_hashmap_free(c->sink_ports);
+ pa_device_port_hashmap_free(c->source_ports);
pa_xfree(c->name);
pa_xfree(c->description);
pa_xfree(c);
diff --git a/src/pulsecore/card.h b/src/pulsecore/card.h
index 2d691b6..a50a6c1 100644
--- a/src/pulsecore/card.h
+++ b/src/pulsecore/card.h
@@ -28,6 +28,7 @@ typedef struct pa_card pa_card;
#include <pulsecore/core.h>
#include <pulsecore/module.h>
#include <pulsecore/idxset.h>
+#include <pulsecore/device-port.h>
typedef struct pa_card_profile {
char *name;
@@ -42,6 +43,9 @@ typedef struct pa_card_profile {
unsigned max_sink_channels;
unsigned max_source_channels;
+ pa_hashmap *sink_ports;
+ pa_hashmap *source_ports;
+
/* .. followed by some implementation specific data */
} pa_card_profile;
diff --git a/src/pulsecore/device-port.c b/src/pulsecore/device-port.c
index d80b144..9e6ad43 100644
--- a/src/pulsecore/device-port.c
+++ b/src/pulsecore/device-port.c
@@ -51,3 +51,14 @@ pa_device_port *pa_device_port_new(const char *name, const char *description, si
return p;
}
+
+void pa_device_port_hashmap_free(pa_hashmap *h) {
+ if (h) {
+ pa_device_port *p;
+
+ while ((p = pa_hashmap_steal_first(h)))
+ pa_device_port_unref(p);
+
+ pa_hashmap_free(h, NULL, NULL);
+ }
+}
diff --git a/src/pulsecore/device-port.h b/src/pulsecore/device-port.h
index fa866a1..d28fa2a 100644
--- a/src/pulsecore/device-port.h
+++ b/src/pulsecore/device-port.h
@@ -53,6 +53,8 @@ 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);
-/*void pa_device_port_free(pa_device_port *p); */
+
+
+void pa_device_port_hashmap_free(pa_hashmap *h);
#endif
diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
index 4dcc07c..6e7b190 100644
--- a/src/pulsecore/protocol-native.c
+++ b/src/pulsecore/protocol-native.c
@@ -3195,6 +3195,26 @@ static void client_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_c
pa_tagstruct_put_proplist(t, client->proplist);
}
+static void device_ports_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_hashmap *ports) {
+ void *state = NULL;
+ pa_device_port *p;
+
+ if (!ports) {
+ pa_tagstruct_putu32(t, 0);
+ return;
+ }
+
+ pa_tagstruct_putu32(t, pa_hashmap_size(ports));
+ PA_HASHMAP_FOREACH(p, ports, state) {
+ pa_tagstruct_puts(t, p->name);
+ pa_tagstruct_puts(t, p->description);
+ pa_tagstruct_putu32(t, p->priority);
+ if (c->version >= JACK_DETECTION_PROTOCOL_VERSION)
+ pa_tagstruct_putu32(t, p->available);
+ }
+
+}
+
static void card_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_card *card) {
void *state = NULL;
pa_card_profile *p;
@@ -3216,6 +3236,11 @@ static void card_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_car
pa_tagstruct_putu32(t, p->n_sinks);
pa_tagstruct_putu32(t, p->n_sources);
pa_tagstruct_putu32(t, p->priority);
+
+ if (c->version >= JACK_DETECTION_PROTOCOL_VERSION) {
+ device_ports_fill_tagstruct(c, t, p->sink_ports);
+ device_ports_fill_tagstruct(c, t, p->source_ports);
+ }
}
}
diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
index 7dd0868..9a24301 100644
--- a/src/pulsecore/sink.c
+++ b/src/pulsecore/sink.c
@@ -131,15 +131,7 @@ void pa_sink_new_data_done(pa_sink_new_data *data) {
pa_proplist_free(data->proplist);
- if (data->ports) {
- pa_device_port *p;
-
- while ((p = pa_hashmap_steal_first(data->ports)))
- pa_device_port_unref(p);
-
- pa_hashmap_free(data->ports, NULL, NULL);
- }
-
+ pa_device_port_hashmap_free(data->ports);
pa_xfree(data->name);
pa_xfree(data->active_port);
}
@@ -587,15 +579,7 @@ static void sink_free(pa_object *o) {
if (s->proplist)
pa_proplist_free(s->proplist);
- if (s->ports) {
- pa_device_port *p;
-
- while ((p = pa_hashmap_steal_first(s->ports)))
- pa_device_port_unref(p);
-
- pa_hashmap_free(s->ports, NULL, NULL);
- }
-
+ pa_device_port_hashmap_free(s->ports);
pa_xfree(s);
}
diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c
index eaedd4e..80df806 100644
--- a/src/pulsecore/source.c
+++ b/src/pulsecore/source.c
@@ -123,15 +123,7 @@ void pa_source_new_data_done(pa_source_new_data *data) {
pa_proplist_free(data->proplist);
- if (data->ports) {
- pa_device_port *p;
-
- while ((p = pa_hashmap_steal_first(data->ports)))
- pa_device_port_unref(p);
-
- pa_hashmap_free(data->ports, NULL, NULL);
- }
-
+ pa_device_port_hashmap_free(data->ports);
pa_xfree(data->name);
pa_xfree(data->active_port);
}
@@ -519,15 +511,7 @@ static void source_free(pa_object *o) {
if (s->proplist)
pa_proplist_free(s->proplist);
- if (s->ports) {
- pa_device_port *p;
-
- while ((p = pa_hashmap_steal_first(s->ports)))
- pa_device_port_unref(p);
-
- pa_hashmap_free(s->ports, NULL, NULL);
- }
-
+ pa_device_port_hashmap_free(s->ports);
pa_xfree(s);
}
--
1.7.4.1
More information about the pulseaudio-discuss
mailing list