On 04/12/2012 01:59 PM, Tanu Kaskinen wrote: > --- > 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); Just a random dive-in here: is it possible that the pa_proplist_new has not been called for the last port, therefore pa_proplist_free will raise an assertion failure? > + } > + > 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); > } > } > -- David Henningsson, Canonical Ltd. http://launchpad.net/~diwic