--- PROTOCOL | 10 ++++-- configure.ac | 2 +- src/modules/module-tunnel.c | 5 +++ src/pulse/introspect.c | 64 +++++++++++++++++++++++++++------------ src/pulse/introspect.h | 2 ++ src/pulsecore/protocol-native.c | 4 +++ 6 files changed, 64 insertions(+), 23 deletions(-) diff --git a/PROTOCOL b/PROTOCOL index acd53ba..eb35978 100644 --- a/PROTOCOL +++ b/PROTOCOL @@ -287,8 +287,8 @@ New field in PA_COMMAND_UNDERFLOW: ## v24, implemented by >= 2.0 New field in all commands that send/receive port introspection data -(PA_COMMAND_GET_(SOURCE|SINK)_OUTPUT_INFO, -PA_COMMAND_GET_(SOURCE|SINK)_OUTPUT_INFO_LIST): +(PA_COMMAND_GET_(SOURCE|SINK)_INFO, +PA_COMMAND_GET_(SOURCE|SINK)_INFO_LIST): uint32_t available @@ -321,6 +321,12 @@ PA_COMMAND_GET_CARD_INFO_LIST), the following is added: Profile names must match earlier sent profile names for the same card. +## v27, implemented by >= 3.0 + +New field at the end of each port entry in sink and source info: + + proplist + #### If you just changed the protocol, read this ## module-tunnel depends on the sink/source/sink-input/source-input protocol diff --git a/configure.ac b/configure.ac index def0d96..d6cec92 100644 --- a/configure.ac +++ b/configure.ac @@ -36,7 +36,7 @@ AC_SUBST(PA_MINOR, pa_minor) AC_SUBST(PA_MAJORMINOR, pa_major.pa_minor) AC_SUBST(PA_API_VERSION, 12) -AC_SUBST(PA_PROTOCOL_VERSION, 26) +AC_SUBST(PA_PROTOCOL_VERSION, 27) # The stable ABI for client applications, for the version info x:y:z # always will hold y=z diff --git a/src/modules/module-tunnel.c b/src/modules/module-tunnel.c index 4490d4e..be3aef1 100644 --- a/src/modules/module-tunnel.c +++ b/src/modules/module-tunnel.c @@ -1021,6 +1021,11 @@ static int read_ports(struct userdata *u, pa_tagstruct *t) pa_log("Parse failure"); return -PA_ERR_PROTOCOL; } + + if (u->version >= 27 && pa_tagstruct_get_proplist(t, NULL) < 0) { + pa_log("Protocol error: failed to read port proplist."); + return -PA_ERR_PROTOCOL; + } } if (pa_tagstruct_gets(t, &s) < 0) { /* active port */ diff --git a/src/pulse/introspect.c b/src/pulse/introspect.c index 38a9d1c..be65fdd 100644 --- a/src/pulse/introspect.c +++ b/src/pulse/introspect.c @@ -200,29 +200,33 @@ static void context_get_sink_info_callback(pa_pdispatch *pd, uint32_t command, u 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); + i.ports = pa_xnew0(pa_sink_port_info*, i.n_ports+1); + i.ports[0] = pa_xnew0(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) { + i.ports[j] = &i.ports[0][j]; + + if (pa_tagstruct_gets(t, &i.ports[j]->name) < 0 || + pa_tagstruct_gets(t, &i.ports[j]->description) < 0 || + pa_tagstruct_getu32(t, &i.ports[j]->priority) < 0) { goto fail; } - i.ports[0][j].available = PA_PORT_AVAILABLE_UNKNOWN; + i.ports[j]->available = PA_PORT_AVAILABLE_UNKNOWN; if (o->context->version >= 24) { 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]->available = av; } - i.ports[j] = &i.ports[0][j]; + i.ports[j]->proplist = pa_proplist_new(); + if (o->context->version >= 27) { + if (pa_tagstruct_get_proplist(t, i.ports[j]->proplist) < 0) + goto fail; + } } - - i.ports[j] = NULL; } if (pa_tagstruct_gets(t, &ap) < 0) @@ -268,6 +272,9 @@ static void context_get_sink_info_callback(pa_pdispatch *pd, uint32_t command, u pa_xfree(i.formats); } if (i.ports) { + for (j = 0; i.ports[j]; j++) + pa_proplist_free(i.ports[j]->proplist); + pa_xfree(i.ports[0]); pa_xfree(i.ports); } @@ -296,6 +303,11 @@ fail: pa_xfree(i.formats); } if (i.ports) { + for (j = 0; i.ports[j]; j++) { + if (i.ports[j]->proplist) + pa_proplist_free(i.ports[j]->proplist); + } + pa_xfree(i.ports[0]); pa_xfree(i.ports); } @@ -473,29 +485,33 @@ static void context_get_source_info_callback(pa_pdispatch *pd, uint32_t command, 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); + i.ports = pa_xnew0(pa_source_port_info*, i.n_ports+1); + i.ports[0] = pa_xnew0(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) { + i.ports[j] = &i.ports[0][j]; + + if (pa_tagstruct_gets(t, &i.ports[j]->name) < 0 || + pa_tagstruct_gets(t, &i.ports[j]->description) < 0 || + pa_tagstruct_getu32(t, &i.ports[j]->priority) < 0) { goto fail; } - i.ports[0][j].available = PA_PORT_AVAILABLE_UNKNOWN; + i.ports[j]->available = PA_PORT_AVAILABLE_UNKNOWN; if (o->context->version >= 24) { 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]->available = av; } - i.ports[j] = &i.ports[0][j]; + i.ports[j]->proplist = pa_proplist_new(); + if (o->context->version >= 27) { + if (pa_tagstruct_get_proplist(t, i.ports[j]->proplist) < 0 ) + goto fail; + } } - - i.ports[j] = NULL; } if (pa_tagstruct_gets(t, &ap) < 0) @@ -541,6 +557,9 @@ static void context_get_source_info_callback(pa_pdispatch *pd, uint32_t command, pa_xfree(i.formats); } if (i.ports) { + for (j = 0; i.ports[j]; j++) + pa_proplist_free(i.ports[j]->proplist); + pa_xfree(i.ports[0]); pa_xfree(i.ports); } @@ -569,6 +588,11 @@ fail: pa_xfree(i.formats); } if (i.ports) { + for (j = 0; i.ports[j]; j++) { + if (i.ports[j]->proplist) + pa_proplist_free(i.ports[j]->proplist); + } + pa_xfree(i.ports[0]); pa_xfree(i.ports); } diff --git a/src/pulse/introspect.h b/src/pulse/introspect.h index 224432c..ad3f2c3 100644 --- a/src/pulse/introspect.h +++ b/src/pulse/introspect.h @@ -203,6 +203,7 @@ typedef struct pa_sink_port_info { const char *description; /**< Description of this port */ uint32_t priority; /**< The higher this value is the more useful this port is as a default */ int available; /**< A flags (see #pa_port_available),indicating availability status of this port. \since 2.0 */ + pa_proplist *proplist; /**< Port property list. \since 3.0 */ } pa_sink_port_info; /** Stores information about sinks. Please note that this structure @@ -283,6 +284,7 @@ typedef struct pa_source_port_info { const char *description; /**< Description of this port */ uint32_t priority; /**< The higher this value is the more useful this port is as a default */ int available; /**< A flags (see #pa_port_available) indicating availability status of this port. \since 2.0 */ + pa_proplist *proplist; /**< Port property list. \since 3.0 */ } pa_source_port_info; /** Stores information about sources. Please note that this structure diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index 487eb7a..d5e7c9a 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -3126,6 +3126,8 @@ static void sink_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_sin pa_tagstruct_putu32(t, p->priority); if (c->version >= 24) pa_tagstruct_putu32(t, p->available); + if (c->version >= 27) + pa_tagstruct_put_proplist(t, p->proplist); } } @@ -3199,6 +3201,8 @@ static void source_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_s pa_tagstruct_putu32(t, p->priority); if (c->version >= 24) pa_tagstruct_putu32(t, p->available); + if (c->version >= 27) + pa_tagstruct_put_proplist(t, p->proplist); } } -- 1.7.10