From 914ef89e559c7b34159a0431b1e230da0eef96be Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 17 Jun 2009 04:54:11 +0200 Subject: libpulse: implement client side for sink/source port selection commands --- src/pulse/introspect.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) (limited to 'src/pulse/introspect.c') diff --git a/src/pulse/introspect.c b/src/pulse/introspect.c index ac8a11aa..0c45f99f 100644 --- a/src/pulse/introspect.c +++ b/src/pulse/introspect.c @@ -271,6 +271,56 @@ pa_operation* pa_context_get_sink_info_by_name(pa_context *c, const char *name, return o; } +pa_operation* pa_context_set_sink_port_by_index(pa_context *c, uint32_t idx, const char*port, pa_context_success_cb_t cb, void *userdata) { + pa_operation *o; + pa_tagstruct *t; + uint32_t tag; + + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + + PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED); + PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); + PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID); + PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 16, PA_ERR_NOTSUPPORTED); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); + + t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_PORT, &tag); + pa_tagstruct_putu32(t, idx); + pa_tagstruct_puts(t, NULL); + pa_tagstruct_puts(t, port); + pa_pstream_send_tagstruct(c->pstream, t); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref); + + return o; +} + +pa_operation* pa_context_set_sink_port_by_name(pa_context *c, const char *name, const char*port, pa_context_success_cb_t cb, void *userdata) { + pa_operation *o; + pa_tagstruct *t; + uint32_t tag; + + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + + PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED); + PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); + PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID); + PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 16, PA_ERR_NOTSUPPORTED); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); + + t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_PORT, &tag); + pa_tagstruct_putu32(t, PA_INVALID_INDEX); + pa_tagstruct_puts(t, name); + pa_tagstruct_puts(t, port); + pa_pstream_send_tagstruct(c->pstream, t); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref); + + return o; +} + /*** Source info ***/ static void context_get_source_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { @@ -406,6 +456,56 @@ pa_operation* pa_context_get_source_info_by_name(pa_context *c, const char *name return o; } +pa_operation* pa_context_set_source_port_by_index(pa_context *c, uint32_t idx, const char*port, pa_context_success_cb_t cb, void *userdata) { + pa_operation *o; + pa_tagstruct *t; + uint32_t tag; + + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + + PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED); + PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); + PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID); + PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 16, PA_ERR_NOTSUPPORTED); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); + + t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_PORT, &tag); + pa_tagstruct_putu32(t, idx); + pa_tagstruct_puts(t, NULL); + pa_tagstruct_puts(t, port); + pa_pstream_send_tagstruct(c->pstream, t); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref); + + return o; +} + +pa_operation* pa_context_set_source_port_by_name(pa_context *c, const char *name, const char*port, pa_context_success_cb_t cb, void *userdata) { + pa_operation *o; + pa_tagstruct *t; + uint32_t tag; + + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + + PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED); + PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); + PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID); + PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 16, PA_ERR_NOTSUPPORTED); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); + + t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_PORT, &tag); + pa_tagstruct_putu32(t, PA_INVALID_INDEX); + pa_tagstruct_puts(t, name); + pa_tagstruct_puts(t, port); + pa_pstream_send_tagstruct(c->pstream, t); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref); + + return o; +} + /*** Client info ***/ static void context_get_client_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -- cgit From 46b8ca21d1ef56df298cfa9412e73fdf17cbea49 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 17 Jun 2009 23:17:37 +0200 Subject: native-protocol: allow enumerating ports --- src/pulse/introspect.c | 110 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 97 insertions(+), 13 deletions(-) (limited to 'src/pulse/introspect.c') diff --git a/src/pulse/introspect.c b/src/pulse/introspect.c index 0c45f99f..ab67f596 100644 --- a/src/pulse/introspect.c +++ b/src/pulse/introspect.c @@ -49,7 +49,7 @@ static void context_stat_callback(pa_pdispatch *pd, uint32_t command, uint32_t t pa_assert(o); pa_assert(PA_REFCNT_VALUE(o) >= 1); - memset(&i, 0, sizeof(i)); + pa_zero(i); if (!o->context) goto finish; @@ -93,7 +93,7 @@ static void context_get_server_info_callback(pa_pdispatch *pd, uint32_t command, pa_assert(o); pa_assert(PA_REFCNT_VALUE(o) >= 1); - memset(&i, 0, sizeof(i)); + pa_zero(i); if (!o->context) goto finish; @@ -161,8 +161,10 @@ static void context_get_sink_info_callback(pa_pdispatch *pd, uint32_t command, u pa_bool_t mute; uint32_t flags; uint32_t state; + uint32_t j; + const char *ap = NULL; - memset(&i, 0, sizeof(i)); + pa_zero(i); i.proplist = pa_proplist_new(); i.base_volume = PA_VOLUME_NORM; i.n_volume_steps = PA_VOLUME_NORM+1; @@ -190,13 +192,53 @@ 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))) { + pa_tagstruct_getu32(t, &i.card) < 0)) || + (o->context->version >= 16 && + (pa_tagstruct_getu32(t, &i.n_ports)))) { pa_context_fail(o->context, PA_ERR_PROTOCOL); pa_proplist_free(i.proplist); goto finish; } + 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) { + + pa_context_fail(o->context, PA_ERR_PROTOCOL); + pa_xfree(i.ports); + pa_xfree(i.ports[0]); + pa_proplist_free(i.proplist); + goto finish; + } + + i.ports[j] = &i.ports[0][j]; + } + + i.ports[j] = NULL; + } + + if (pa_tagstruct_gets(t, &ap) < 0) { + pa_context_fail(o->context, PA_ERR_PROTOCOL); + pa_xfree(i.ports[0]); + pa_xfree(i.ports); + pa_proplist_free(i.proplist); + goto finish; + } + + if (ap) { + for (j = 0; j < i.n_ports; j++) + if (pa_streq(i.ports[j]->name, ap)) { + i.active_port = i.ports[j]; + break; + } + } + i.mute = (int) mute; i.flags = (pa_sink_flags_t) flags; i.state = (pa_sink_state_t) state; @@ -346,8 +388,10 @@ static void context_get_source_info_callback(pa_pdispatch *pd, uint32_t command, pa_bool_t mute; uint32_t flags; uint32_t state; + unsigned j; + const char *ap; - memset(&i, 0, sizeof(i)); + pa_zero(i); i.proplist = pa_proplist_new(); i.base_volume = PA_VOLUME_NORM; i.n_volume_steps = PA_VOLUME_NORM+1; @@ -375,13 +419,53 @@ 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))) { + pa_tagstruct_getu32(t, &i.card) < 0)) || + (o->context->version >= 16 && + (pa_tagstruct_getu32(t, &i.n_ports)))) { pa_context_fail(o->context, PA_ERR_PROTOCOL); pa_proplist_free(i.proplist); goto finish; } + 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) { + + pa_context_fail(o->context, PA_ERR_PROTOCOL); + pa_xfree(i.ports[0]); + pa_xfree(i.ports); + pa_proplist_free(i.proplist); + goto finish; + } + + i.ports[j] = &i.ports[0][j]; + } + + i.ports[j] = NULL; + } + + if (pa_tagstruct_gets(t, &ap) < 0) { + pa_context_fail(o->context, PA_ERR_PROTOCOL); + pa_xfree(i.ports[0]); + pa_xfree(i.ports); + pa_proplist_free(i.proplist); + goto finish; + } + + if (ap) { + for (j = 0; j < i.n_ports; j++) + if (pa_streq(i.ports[j]->name, ap)) { + i.active_port = i.ports[j]; + break; + } + } + i.mute = (int) mute; i.flags = (pa_source_flags_t) flags; i.state = (pa_source_state_t) state; @@ -529,7 +613,7 @@ static void context_get_client_info_callback(pa_pdispatch *pd, uint32_t command, while (!pa_tagstruct_eof(t)) { pa_client_info i; - memset(&i, 0, sizeof(i)); + pa_zero(i); i.proplist = pa_proplist_new(); if (pa_tagstruct_getu32(t, &i.index) < 0 || @@ -614,7 +698,7 @@ static void context_get_card_info_callback(pa_pdispatch *pd, uint32_t command, u uint32_t j; const char*ap; - memset(&i, 0, sizeof(i)); + pa_zero(i); if (pa_tagstruct_getu32(t, &i.index) < 0 || pa_tagstruct_gets(t, &i.name) < 0 || @@ -627,7 +711,7 @@ static void context_get_card_info_callback(pa_pdispatch *pd, uint32_t command, u } if (i.n_profiles > 0) { - i.profiles = pa_xnew(pa_card_profile_info, i.n_profiles+1); + i.profiles = pa_xnew0(pa_card_profile_info, i.n_profiles+1); for (j = 0; j < i.n_profiles; j++) { @@ -815,7 +899,7 @@ static void context_get_module_info_callback(pa_pdispatch *pd, uint32_t command, pa_module_info i; pa_bool_t auto_unload = FALSE; - memset(&i, 0, sizeof(i)); + pa_zero(i); i.proplist = pa_proplist_new(); if (pa_tagstruct_getu32(t, &i.index) < 0 || @@ -900,7 +984,7 @@ static void context_get_sink_input_info_callback(pa_pdispatch *pd, uint32_t comm pa_sink_input_info i; pa_bool_t mute = FALSE; - memset(&i, 0, sizeof(i)); + pa_zero(i); i.proplist = pa_proplist_new(); if (pa_tagstruct_getu32(t, &i.index) < 0 || @@ -994,7 +1078,7 @@ static void context_get_source_output_info_callback(pa_pdispatch *pd, uint32_t c while (!pa_tagstruct_eof(t)) { pa_source_output_info i; - memset(&i, 0, sizeof(i)); + pa_zero(i); i.proplist = pa_proplist_new(); if (pa_tagstruct_getu32(t, &i.index) < 0 || @@ -1336,7 +1420,7 @@ static void context_get_sample_info_callback(pa_pdispatch *pd, uint32_t command, pa_sample_info i; pa_bool_t lazy = FALSE; - memset(&i, 0, sizeof(i)); + pa_zero(i); i.proplist = pa_proplist_new(); if (pa_tagstruct_getu32(t, &i.index) < 0 || -- cgit