From 71b3bff6816b857a6a9613cc45b06f0b9e5a65e1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 20 Feb 2006 22:41:02 +0000 Subject: [PATCH] * modify pa_context_exit_daemon() to return a pa_operation object * add callback prototypes to all introspection functions in client lib * add proper validity checking and error handling to all functions in the client lib * other minor cleanups * todo update git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@531 fefdeb5f-60dc-0310-8127-8f9354f1896f --- doc/todo | 1 + src/Makefile.am | 4 +- src/modules/module-tunnel.c | 2 +- src/polyp/context.c | 228 +++++++----- src/polyp/context.h | 8 +- src/polyp/internal.h | 15 +- src/polyp/introspect.c | 591 +++++++++++++++++++------------- src/polyp/introspect.h | 110 ++++-- src/polyp/operation.c | 6 +- src/polyp/scache.c | 57 +-- src/polyp/scache.h | 4 +- src/polyp/stream.c | 217 +++++++----- src/polyp/subscribe.c | 20 +- src/polypcore/iochannel.c | 4 +- src/polypcore/iochannel.h | 4 +- src/polypcore/pdispatch.c | 12 +- src/polypcore/pdispatch.h | 6 +- src/polypcore/protocol-native.c | 2 +- src/polypcore/tagstruct.h | 2 - src/utils/pactl.c | 2 +- 20 files changed, 782 insertions(+), 513 deletions(-) diff --git a/doc/todo b/doc/todo index 280747fe0..1fc55df96 100644 --- a/doc/todo +++ b/doc/todo @@ -12,6 +12,7 @@ Fixes: - don't build ipv4 and ipv6 modules seperately - change pa_log to not require \n - proper use of memcpy in procotol-esound.c so we don't get alignment problems +- sigpipe Features: - add radio module diff --git a/src/Makefile.am b/src/Makefile.am index 5581d77ed..ed97f4905 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -47,8 +47,8 @@ AM_CFLAGS = -I$(top_srcdir)/src AM_CFLAGS += $(PTHREAD_CFLAGS) -D_POSIX_PTHREAD_SEMANTICS AM_CFLAGS += $(LTDLINCL) AM_CFLAGS += $(LIBSAMPLERATE_CFLAGS) $(LIBSNDFILE_CFLAGS) -AM_CFLAGS += -DDLSEARCHPATH=\"$(modlibdir)\" -#AM_CFLAGS += -DDLSEARCHPATH=\"$(shell pwd)\" +#AM_CFLAGS += -DDLSEARCHPATH=\"$(modlibdir)\" +AM_CFLAGS += -DDLSEARCHPATH=\"$(shell pwd)\" AM_CFLAGS += -DDEFAULT_CONFIG_DIR=\"$(DEFAULT_CONFIG_DIR)\" AM_CFLAGS += -DPOLYPAUDIO_BINARY=\"$(POLYPAUDIO_BINARY)\" diff --git a/src/modules/module-tunnel.c b/src/modules/module-tunnel.c index 3ecca7457..136702fc6 100644 --- a/src/modules/module-tunnel.c +++ b/src/modules/module-tunnel.c @@ -94,7 +94,7 @@ static void command_stream_killed(pa_pdispatch *pd, uint32_t command, uint32_t t static void command_request(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); #endif -static const pa_pdispatch_callback_t command_table[PA_COMMAND_MAX] = { +static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = { #ifdef TUNNEL_SINK [PA_COMMAND_REQUEST] = command_request, #endif diff --git a/src/polyp/context.c b/src/polyp/context.c index 00c097107..2cb9e7e38 100644 --- a/src/polyp/context.c +++ b/src/polyp/context.c @@ -72,7 +72,7 @@ #define AUTOSPAWN_LOCK "autospawn.lock" -static const pa_pdispatch_callback_t command_table[PA_COMMAND_MAX] = { +static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = { [PA_COMMAND_REQUEST] = pa_command_request, [PA_COMMAND_OVERFLOW] = pa_command_overflow_or_underflow, [PA_COMMAND_UNDERFLOW] = pa_command_overflow_or_underflow, @@ -95,9 +95,11 @@ static void unlock_autospawn_lock_file(pa_context *c) { pa_context *pa_context_new(pa_mainloop_api *mainloop, const char *name) { pa_context *c; - assert(mainloop && name); - c = pa_xmalloc(sizeof(pa_context)); + assert(mainloop); + assert(name); + + c = pa_xnew(pa_context, 1); c->ref = 1; c->name = pa_xstrdup(name); c->mainloop = mainloop; @@ -106,7 +108,6 @@ pa_context *pa_context_new(pa_mainloop_api *mainloop, const char *name) { c->pdispatch = NULL; c->playback_streams = pa_dynarray_new(); c->record_streams = pa_dynarray_new(); - assert(c->playback_streams && c->record_streams); PA_LLIST_HEAD_INIT(pa_stream, c->streams); PA_LLIST_HEAD_INIT(pa_operation, c->operations); @@ -182,20 +183,24 @@ static void context_free(pa_context *c) { } pa_context* pa_context_ref(pa_context *c) { - assert(c && c->ref >= 1); + assert(c); + assert(c->ref >= 1); + c->ref++; return c; } void pa_context_unref(pa_context *c) { - assert(c && c->ref >= 1); + assert(c); + assert(c->ref >= 1); - if ((--(c->ref)) == 0) + if (--c->ref <= 0) context_free(c); } void pa_context_set_state(pa_context *c, pa_context_state_t st) { assert(c); + assert(c->ref >= 1); if (c->state == st) return; @@ -237,13 +242,15 @@ void pa_context_set_state(pa_context *c, pa_context_state_t st) { void pa_context_fail(pa_context *c, int error) { assert(c); - + assert(c->ref >= 1); + pa_context_set_error(c, error); pa_context_set_state(c, PA_CONTEXT_FAILED); } int pa_context_set_error(pa_context *c, int error) { - assert(error >= 0 && error < PA_ERR_MAX); + assert(error >= 0); + assert(error < PA_ERR_MAX); if (c) c->error = error; @@ -253,20 +260,24 @@ int pa_context_set_error(pa_context *c, int error) { static void pstream_die_callback(pa_pstream *p, void *userdata) { pa_context *c = userdata; - assert(p && c); + + assert(p); + assert(c); + pa_context_fail(c, PA_ERR_CONNECTIONTERMINATED); } static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, void *userdata) { pa_context *c = userdata; - assert(p && packet && c); + + assert(p); + assert(packet); + assert(c); pa_context_ref(c); - if (pa_pdispatch_run(c->pdispatch, packet, c) < 0) { - pa_log(__FILE__": invalid packet.\n"); + if (pa_pdispatch_run(c->pdispatch, packet, c) < 0) pa_context_fail(c, PA_ERR_PROTOCOL); - } pa_context_unref(c); } @@ -280,6 +291,7 @@ static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t o assert(chunk->memblock); assert(chunk->length); assert(c); + assert(c->ref >= 1); pa_context_ref(c); @@ -301,6 +313,7 @@ static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t o int pa_context_handle_error(pa_context *c, uint32_t command, pa_tagstruct *t) { assert(c); + assert(c->ref >= 1); if (command == PA_COMMAND_ERROR) { assert(t); @@ -322,7 +335,10 @@ int pa_context_handle_error(pa_context *c, uint32_t command, pa_tagstruct *t) { static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { pa_context *c = userdata; - assert(pd && c && (c->state == PA_CONTEXT_AUTHORIZING || c->state == PA_CONTEXT_SETTING_NAME)); + + assert(pd); + assert(c); + assert(c->state == PA_CONTEXT_AUTHORIZING || c->state == PA_CONTEXT_SETTING_NAME); pa_context_ref(c); @@ -364,13 +380,14 @@ finish: static void setup_context(pa_context *c, pa_iochannel *io) { pa_tagstruct *t; uint32_t tag; - assert(c && io); + + assert(c); + assert(io); pa_context_ref(c); assert(!c->pstream); c->pstream = pa_pstream_new(c->mainloop, io, c->memblock_stat); - assert(c->pstream); pa_pstream_set_die_callback(c->pstream, pstream_die_callback, c); pa_pstream_set_recieve_packet_callback(c->pstream, pstream_packet_callback, c); @@ -378,7 +395,6 @@ static void setup_context(pa_context *c, pa_iochannel *io) { assert(!c->pdispatch); c->pdispatch = pa_pdispatch_new(c->mainloop, command_table, PA_COMMAND_MAX); - assert(c->pdispatch); if (!c->conf->cookie_valid) { pa_context_fail(c, PA_ERR_AUTHKEY); @@ -386,7 +402,6 @@ static void setup_context(pa_context *c, pa_iochannel *io) { } t = pa_tagstruct_new(NULL, 0); - assert(t); pa_tagstruct_putu32(t, PA_COMMAND_AUTH); pa_tagstruct_putu32(t, tag = c->ctag++); pa_tagstruct_put_arbitrary(t, c->conf->cookie, sizeof(c->conf->cookie)); @@ -522,11 +537,12 @@ fail: static int try_next_connection(pa_context *c) { char *u = NULL; int r = -1; - assert(c && !c->client); + + assert(c); + assert(!c->client); for (;;) { - if (u) - pa_xfree(u); + pa_xfree(u); u = NULL; c->server_list = pa_strlist_pop(c->server_list, &u); @@ -560,15 +576,17 @@ static int try_next_connection(pa_context *c) { r = 0; finish: - if (u) - pa_xfree(u); + pa_xfree(u); return r; } static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userdata) { pa_context *c = userdata; - assert(client && c && c->state == PA_CONTEXT_CONNECTING); + + assert(client); + assert(c); + assert(c->state == PA_CONTEXT_CONNECTING); pa_context_ref(c); @@ -593,9 +611,19 @@ finish: pa_context_unref(c); } -int pa_context_connect(pa_context *c, const char *server, pa_context_flags_t flags, const pa_spawn_api *api) { +int pa_context_connect( + pa_context *c, + const char *server, + pa_context_flags_t flags, + const pa_spawn_api *api) { + int r = -1; - assert(c && c->ref >= 1 && c->state == PA_CONTEXT_UNCONNECTED); + + assert(c); + assert(c->ref >= 1); + + PA_CHECK_VALIDITY(c, c->state == PA_CONTEXT_UNCONNECTED, PA_ERR_BADSTATE); + PA_CHECK_VALIDITY(c, !(flags & ~PA_CONTEXT_NOAUTOSPAWN), PA_ERR_INVALID); if (!server) server = c->conf->default_server; @@ -658,27 +686,36 @@ finish: void pa_context_disconnect(pa_context *c) { assert(c); + assert(c->ref >= 1); + pa_context_set_state(c, PA_CONTEXT_TERMINATED); } pa_context_state_t pa_context_get_state(pa_context *c) { - assert(c && c->ref >= 1); + assert(c); + assert(c->ref >= 1); + return c->state; } int pa_context_errno(pa_context *c) { - assert(c && c->ref >= 1); + assert(c); + assert(c->ref >= 1); + return c->error; } void pa_context_set_state_callback(pa_context *c, pa_context_notify_cb_t cb, void *userdata) { - assert(c && c->ref >= 1); + assert(c); + assert(c->ref >= 1); + c->state_callback = cb; c->state_userdata = userdata; } int pa_context_is_pending(pa_context *c) { - assert(c && c->ref >= 1); + assert(c); + assert(c->ref >= 1); /* pa_log("pstream: %i\n", pa_pstream_is_pending(c->pstream)); */ /* pa_log("pdispatch: %i\n", pa_pdispatch_is_pending(c->pdispatch)); */ @@ -700,7 +737,12 @@ static void pstream_drain_callback(PA_GCC_UNUSED pa_pstream *s, void *userdata) static void set_dispatch_callbacks(pa_operation *o) { int done = 1; - assert(o && o->context && o->context->ref >= 1 && o->ref >= 1 && o->context->state == PA_CONTEXT_READY); + + assert(o); + assert(o->ref >= 1); + assert(o->context); + assert(o->context->ref >= 1); + assert(o->context->state == PA_CONTEXT_READY); pa_pstream_set_drain_callback(o->context->pstream, NULL, NULL); pa_pdispatch_set_drain_callback(o->context->pdispatch, NULL, NULL); @@ -719,8 +761,7 @@ static void set_dispatch_callbacks(pa_operation *o) { pa_operation_ref(o); else { if (o->callback) { - void (*cb)(pa_context *c, void *userdata); - cb = (void (*)(pa_context*, void*)) o->callback; + pa_context_notify_cb_t cb = (pa_context_notify_cb_t) o->callback; cb(o->context, o->userdata); } @@ -732,39 +773,27 @@ static void set_dispatch_callbacks(pa_operation *o) { pa_operation* pa_context_drain(pa_context *c, pa_context_notify_cb_t cb, void *userdata) { pa_operation *o; - assert(c && c->ref >= 1); - - if (c->state != PA_CONTEXT_READY) - return NULL; - - if (!pa_context_is_pending(c)) - return NULL; - - o = pa_operation_new(c, NULL); - assert(o); - o->callback = (pa_operation_callback_t) cb; - o->userdata = userdata; + + assert(c); + assert(c->ref >= 1); + PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); + PA_CHECK_VALIDITY_RETURN_NULL(c, pa_context_is_pending(c), PA_ERR_BADSTATE); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); set_dispatch_callbacks(pa_operation_ref(o)); return o; } -void pa_context_exit_daemon(pa_context *c) { - pa_tagstruct *t; - assert(c && c->ref >= 1); - - t = pa_tagstruct_new(NULL, 0); - assert(t); - pa_tagstruct_putu32(t, PA_COMMAND_EXIT); - pa_tagstruct_putu32(t, c->ctag++); - pa_pstream_send_tagstruct(c->pstream, t); -} - void pa_context_simple_ack_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { pa_operation *o = userdata; int success = 1; - assert(pd && o && o->context && o->ref >= 1); + + assert(pd); + assert(o); + assert(o->ref >= 1); + assert(o->context); if (command != PA_COMMAND_REPLY) { if (pa_context_handle_error(o->context, command, t) < 0) @@ -786,67 +815,95 @@ finish: pa_operation_unref(o); } -pa_operation* pa_context_send_simple_command(pa_context *c, uint32_t command, void (*internal_callback)(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata), void (*cb)(void), void *userdata) { +pa_operation* pa_context_exit_daemon(pa_context *c, pa_context_success_cb_t cb, void *userdata) { pa_tagstruct *t; pa_operation *o; uint32_t tag; - assert(c && cb); - o = pa_operation_new(c, NULL); - o->callback = cb; - o->userdata = userdata; + assert(c); + assert(c->ref >= 1); + + PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); + + t = pa_tagstruct_new(NULL, 0); + pa_tagstruct_putu32(t, PA_COMMAND_EXIT); + pa_tagstruct_putu32(t, tag = c->ctag++); + 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)); + + return o; +} + +pa_operation* pa_context_send_simple_command(pa_context *c, uint32_t command, pa_pdispatch_cb_t internal_cb, pa_operation_cb_t cb, void *userdata) { + pa_tagstruct *t; + pa_operation *o; + uint32_t tag; + + assert(c); + assert(c->ref >= 1); + + PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); + + o = pa_operation_new(c, NULL, cb, o->userdata); t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, command); pa_tagstruct_putu32(t, tag = c->ctag++); pa_pstream_send_tagstruct(c->pstream, t); - pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, internal_callback, o); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, internal_cb, pa_operation_ref(o)); - return pa_operation_ref(o); + return o; } pa_operation* pa_context_set_default_sink(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) { pa_tagstruct *t; pa_operation *o; uint32_t tag; - assert(c && cb); + + assert(c); + assert(c->ref >= 1); + + PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); - o = pa_operation_new(c, NULL); - o->callback = (pa_operation_callback_t) cb; - o->userdata = userdata; + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, PA_COMMAND_SET_DEFAULT_SINK); pa_tagstruct_putu32(t, tag = c->ctag++); pa_tagstruct_puts(t, name); pa_pstream_send_tagstruct(c->pstream, t); - pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, o); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o)); - return pa_operation_ref(o); + return o; } pa_operation* pa_context_set_default_source(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) { pa_tagstruct *t; pa_operation *o; uint32_t tag; - assert(c && cb); - o = pa_operation_new(c, NULL); - o->callback = (pa_operation_callback_t) cb; - o->userdata = userdata; + assert(c); + assert(c->ref >= 1); + + PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, PA_COMMAND_SET_DEFAULT_SOURCE); pa_tagstruct_putu32(t, tag = c->ctag++); pa_tagstruct_puts(t, name); pa_pstream_send_tagstruct(c->pstream, t); - pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, o); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o)); - return pa_operation_ref(o); + return o; } int pa_context_is_local(pa_context *c) { assert(c); + return c->local; } @@ -854,20 +911,23 @@ pa_operation* pa_context_set_name(pa_context *c, const char *name, pa_context_su pa_tagstruct *t; pa_operation *o; uint32_t tag; - assert(c && name && cb); - o = pa_operation_new(c, NULL); - o->callback = (pa_operation_callback_t) cb; - o->userdata = userdata; + assert(c); + assert(c->ref >= 1); + assert(name); + + PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, PA_COMMAND_SET_CLIENT_NAME); pa_tagstruct_putu32(t, tag = c->ctag++); pa_tagstruct_puts(t, name); pa_pstream_send_tagstruct(c->pstream, t); - pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, o); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o)); - return pa_operation_ref(o); + return o; } const char* pa_get_library_version(void) { @@ -875,6 +935,8 @@ const char* pa_get_library_version(void) { } const char* pa_context_get_server(pa_context *c) { + assert(c); + assert(c->ref >= 1); if (!c->server) return NULL; diff --git a/src/polyp/context.h b/src/polyp/context.h index db268759f..73bcb698a 100644 --- a/src/polyp/context.h +++ b/src/polyp/context.h @@ -95,10 +95,10 @@ void pa_context_disconnect(pa_context *c); /** Drain the context. If there is nothing to drain, the function returns NULL */ pa_operation* pa_context_drain(pa_context *c, pa_context_notify_cb_t cb, void *userdata); -/** Tell the daemon to exit. No operation object is returned as the - * connection is terminated when the daemon quits, thus this operation - * would never complete. */ -void pa_context_exit_daemon(pa_context *c); +/** Tell the daemon to exit. The returned operation is unlikely to + * complete succesfully, since the daemon probably died before + * returning a success notification */ +pa_operation* pa_context_exit_daemon(pa_context *c, pa_context_success_cb_t cb, void *userdata); /** Set the name of the default sink. \since 0.4 */ pa_operation* pa_context_set_default_sink(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata); diff --git a/src/polyp/internal.h b/src/polyp/internal.h index e9e0246ff..9907fae08 100644 --- a/src/polyp/internal.h +++ b/src/polyp/internal.h @@ -128,7 +128,7 @@ struct pa_stream { void *underflow_userdata; }; -typedef void (*pa_operation_callback_t)(void); +typedef void (*pa_operation_cb_t)(void); struct pa_operation { int ref; @@ -138,7 +138,7 @@ struct pa_operation { pa_operation_state_t state; void *userdata; - pa_operation_callback_t callback; + pa_operation_cb_t callback; }; void pa_command_request(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); @@ -146,7 +146,7 @@ void pa_command_stream_killed(pa_pdispatch *pd, uint32_t command, uint32_t tag, void pa_command_subscribe_event(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); void pa_command_overflow_or_underflow(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -pa_operation *pa_operation_new(pa_context *c, pa_stream *s); +pa_operation *pa_operation_new(pa_context *c, pa_stream *s, pa_operation_cb_t callback, void *userdata); void pa_operation_done(pa_operation *o); void pa_create_stream_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); @@ -169,12 +169,6 @@ void pa_stream_trash_ipol(pa_stream *s); return -pa_context_set_error((context), (error)); \ } while(0) -#define PA_CHECK_VALIDITY_RETURN_NULL(context, expression, error) do { \ - if (!(expression)) { \ - pa_context_set_error((context), (error)); \ - return NULL; \ - } \ -} while(0) #define PA_CHECK_VALIDITY_RETURN_ANY(context, expression, error, value) do { \ if (!(expression)) { \ @@ -183,4 +177,7 @@ void pa_stream_trash_ipol(pa_stream *s); } \ } while(0) +#define PA_CHECK_VALIDITY_RETURN_NULL(context, expression, error) PA_CHECK_VALIDITY_RETURN_ANY(context, expression, error, NULL) + + #endif diff --git a/src/polyp/introspect.c b/src/polyp/introspect.c index 404cead5e..043d2076e 100644 --- a/src/polyp/introspect.c +++ b/src/polyp/introspect.c @@ -39,7 +39,11 @@ static void context_stat_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { pa_operation *o = userdata; pa_stat_info i, *p = &i; - assert(pd && o && o->context && o->ref >= 1); + + assert(pd); + assert(o); + assert(o->ref >= 1); + assert(o->context); if (command != PA_COMMAND_REPLY) { if (pa_context_handle_error(o->context, command, t) < 0) @@ -57,7 +61,7 @@ static void context_stat_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNU } if (o->callback) { - void (*cb)(pa_context *s, const pa_stat_info*_i, void *_userdata) = (void (*)(pa_context *s, const pa_stat_info*_i, void *_userdata)) o->callback; + pa_stat_info_cb_t cb = (pa_stat_info_cb_t) o->callback; cb(o->context, p, o->userdata); } @@ -66,8 +70,8 @@ finish: pa_operation_unref(o); } -pa_operation* pa_context_stat(pa_context *c, void (*cb)(pa_context *c, const pa_stat_info*i, void *userdata), void *userdata) { - return pa_context_send_simple_command(c, PA_COMMAND_STAT, context_stat_callback, (pa_operation_callback_t) cb, userdata); +pa_operation* pa_context_stat(pa_context *c, pa_stat_info_cb_t cb, void *userdata) { + return pa_context_send_simple_command(c, PA_COMMAND_STAT, context_stat_callback, (pa_operation_cb_t) cb, userdata); } /*** Server Info ***/ @@ -75,7 +79,11 @@ pa_operation* pa_context_stat(pa_context *c, void (*cb)(pa_context *c, const pa_ static void context_get_server_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { pa_operation *o = userdata; pa_server_info i, *p = &i; - assert(pd && o && o->context && o->ref >= 1); + + assert(pd); + assert(o); + assert(o->ref >= 1); + assert(o->context); if (command != PA_COMMAND_REPLY) { if (pa_context_handle_error(o->context, command, t) < 0) @@ -97,7 +105,7 @@ static void context_get_server_info_callback(pa_pdispatch *pd, uint32_t command, } if (o->callback) { - void (*cb)(pa_context *s, const pa_server_info*_i, void *_userdata) = (void (*)(pa_context *s, const pa_server_info*_i, void *_userdata)) o->callback; + pa_server_info_cb_t cb = (pa_server_info_cb_t) o->callback; cb(o->context, p, o->userdata); } @@ -106,22 +114,26 @@ finish: pa_operation_unref(o); } -pa_operation* pa_context_get_server_info(pa_context *c, void (*cb)(pa_context *c, const pa_server_info*i, void *userdata), void *userdata) { - return pa_context_send_simple_command(c, PA_COMMAND_GET_SERVER_INFO, context_get_server_info_callback, (pa_operation_callback_t) cb, userdata); +pa_operation* pa_context_get_server_info(pa_context *c, pa_server_info_cb_t cb, void *userdata) { + return pa_context_send_simple_command(c, PA_COMMAND_GET_SERVER_INFO, context_get_server_info_callback, (pa_operation_cb_t) cb, userdata); } /*** Sink Info ***/ static void context_get_sink_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { pa_operation *o = userdata; - int eof = 1; - assert(pd && o && o->context && o->ref >= 1); + int eol = 1; + + assert(pd); + assert(o); + assert(o->ref >= 1); + assert(o->context); if (command != PA_COMMAND_REPLY) { if (pa_context_handle_error(o->context, command, t) < 0) goto finish; - eof = -1; + eol = -1; } else { while (!pa_tagstruct_eof(t)) { @@ -144,15 +156,15 @@ static void context_get_sink_info_callback(pa_pdispatch *pd, uint32_t command, P } if (o->callback) { - void (*cb)(pa_context *s, const pa_sink_info*_i, int _eof, void *_userdata) = (void (*)(pa_context *s, const pa_sink_info*_i, int _eof, void *_userdata)) o->callback; + pa_sink_info_cb_t cb = (pa_sink_info_cb_t) o->callback; cb(o->context, &i, 0, o->userdata); } } } if (o->callback) { - void (*cb)(pa_context *s, const pa_sink_info*_i, int _eof, void *_userdata) = (void (*)(pa_context *s, const pa_sink_info*_i, int _eof, void *_userdata)) o->callback; - cb(o->context, NULL, eof, o->userdata); + pa_sink_info_cb_t cb = (pa_sink_info_cb_t) o->callback; + cb(o->context, NULL, eol, o->userdata); } finish: @@ -160,19 +172,22 @@ finish: pa_operation_unref(o); } -pa_operation* pa_context_get_sink_info_list(pa_context *c, void (*cb)(pa_context *c, const pa_sink_info *i, int is_last, void *userdata), void *userdata) { - return pa_context_send_simple_command(c, PA_COMMAND_GET_SINK_INFO_LIST, context_get_sink_info_callback, (pa_operation_callback_t) cb, userdata); +pa_operation* pa_context_get_sink_info_list(pa_context *c, pa_sink_info_cb_t cb, void *userdata) { + return pa_context_send_simple_command(c, PA_COMMAND_GET_SINK_INFO_LIST, context_get_sink_info_callback, (pa_operation_cb_t) cb, userdata); } -pa_operation* pa_context_get_sink_info_by_index(pa_context *c, uint32_t idx, void (*cb)(pa_context *c, const pa_sink_info *i, int is_last, void *userdata), void *userdata) { +pa_operation* pa_context_get_sink_info_by_index(pa_context *c, uint32_t idx, pa_sink_info_cb_t cb, void *userdata) { pa_tagstruct *t; pa_operation *o; uint32_t tag; - assert(c && cb); + + assert(c); + assert(c->ref >= 1); + assert(cb); - o = pa_operation_new(c, NULL); - o->callback = (pa_operation_callback_t) cb; - o->userdata = userdata; + PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, PA_COMMAND_GET_SINK_INFO); @@ -180,20 +195,24 @@ pa_operation* pa_context_get_sink_info_by_index(pa_context *c, uint32_t idx, voi pa_tagstruct_putu32(t, idx); pa_tagstruct_puts(t, NULL); pa_pstream_send_tagstruct(c->pstream, t); - pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_sink_info_callback, o); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_sink_info_callback, pa_operation_ref(o)); - return pa_operation_ref(o); + return o; } -pa_operation* pa_context_get_sink_info_by_name(pa_context *c, const char *name, void (*cb)(pa_context *c, const pa_sink_info *i, int is_last, void *userdata), void *userdata) { +pa_operation* pa_context_get_sink_info_by_name(pa_context *c, const char *name, pa_sink_info_cb_t cb, void *userdata) { pa_tagstruct *t; pa_operation *o; uint32_t tag; - assert(c && cb); + + assert(c); + assert(c->ref >= 1); + assert(cb); - o = pa_operation_new(c, NULL); - o->callback = (pa_operation_callback_t) cb; - o->userdata = userdata; + 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); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, PA_COMMAND_GET_SINK_INFO); @@ -201,23 +220,27 @@ pa_operation* pa_context_get_sink_info_by_name(pa_context *c, const char *name, pa_tagstruct_putu32(t, PA_INVALID_INDEX); pa_tagstruct_puts(t, name); pa_pstream_send_tagstruct(c->pstream, t); - pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_sink_info_callback, o); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_sink_info_callback, pa_operation_ref(o)); - return pa_operation_ref(o); + return o; } /*** Source info ***/ static void context_get_source_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { pa_operation *o = userdata; - int eof = 1; - assert(pd && o && o->context && o->ref >= 1); + int eol = 1; + + assert(pd); + assert(o); + assert(o->ref >= 1); + assert(o->context); if (command != PA_COMMAND_REPLY) { if (pa_context_handle_error(o->context, command, t) < 0) goto finish; - eof = -1; + eol = -1; } else { while (!pa_tagstruct_eof(t)) { @@ -239,15 +262,15 @@ static void context_get_source_info_callback(pa_pdispatch *pd, uint32_t command, } if (o->callback) { - void (*cb)(pa_context *s, const pa_source_info*_i, int _eof, void *_userdata) = (void (*)(pa_context *s, const pa_source_info*_i, int _eof, void *_userdata)) o->callback; + pa_source_info_cb_t cb = (pa_source_info_cb_t) o->callback; cb(o->context, &i, 0, o->userdata); } } } if (o->callback) { - void (*cb)(pa_context *s, const pa_source_info*_i, int _eof, void *_userdata) = (void (*)(pa_context *s, const pa_source_info*_i, int _eof, void *_userdata)) o->callback; - cb(o->context, NULL, eof, o->userdata); + pa_source_info_cb_t cb = (pa_source_info_cb_t) o->callback; + cb(o->context, NULL, eol, o->userdata); } finish: @@ -255,40 +278,47 @@ finish: pa_operation_unref(o); } -pa_operation* pa_context_get_source_info_list(pa_context *c, void (*cb)(pa_context *c, const pa_source_info *i, int is_last, void *userdata), void *userdata) { - return pa_context_send_simple_command(c, PA_COMMAND_GET_SOURCE_INFO_LIST, context_get_source_info_callback, (pa_operation_callback_t) cb, userdata); +pa_operation* pa_context_get_source_info_list(pa_context *c, pa_source_info_cb_t cb, void *userdata) { + return pa_context_send_simple_command(c, PA_COMMAND_GET_SOURCE_INFO_LIST, context_get_source_info_callback, (pa_operation_cb_t) cb, userdata); } -pa_operation* pa_context_get_source_info_by_index(pa_context *c, uint32_t idx, void (*cb)(pa_context *c, const pa_source_info *i, int is_last, void *userdata), void *userdata) { +pa_operation* pa_context_get_source_info_by_index(pa_context *c, uint32_t idx, pa_source_info_cb_t cb, void *userdata) { pa_tagstruct *t; pa_operation *o; uint32_t tag; - assert(c && cb); - o = pa_operation_new(c, NULL); - o->callback = (pa_operation_callback_t) cb; - o->userdata = userdata; + assert(c); + assert(c->ref >= 1); + assert(cb); + PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); + t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, PA_COMMAND_GET_SOURCE_INFO); pa_tagstruct_putu32(t, tag = c->ctag++); pa_tagstruct_putu32(t, idx); pa_tagstruct_puts(t, NULL); pa_pstream_send_tagstruct(c->pstream, t); - pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_source_info_callback, o); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_source_info_callback, pa_operation_ref(o)); - return pa_operation_ref(o); + return o; } -pa_operation* pa_context_get_source_info_by_name(pa_context *c, const char *name, void (*cb)(pa_context *c, const pa_source_info *i, int is_last, void *userdata), void *userdata) { +pa_operation* pa_context_get_source_info_by_name(pa_context *c, const char *name, pa_source_info_cb_t cb, void *userdata) { pa_tagstruct *t; pa_operation *o; uint32_t tag; - assert(c && cb); - o = pa_operation_new(c, NULL); - o->callback = (pa_operation_callback_t) cb; - o->userdata = userdata; + assert(c); + assert(c->ref >= 1); + assert(cb); + + 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); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, PA_COMMAND_GET_SOURCE_INFO); @@ -305,14 +335,18 @@ pa_operation* pa_context_get_source_info_by_name(pa_context *c, const char *name static void context_get_client_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { pa_operation *o = userdata; - int eof = 1; - assert(pd && o && o->context && o->ref >= 1); + int eol = 1; + + assert(pd); + assert(o); + assert(o->ref >= 1); + assert(o->context); if (command != PA_COMMAND_REPLY) { if (pa_context_handle_error(o->context, command, t) < 0) goto finish; - eof = -1; + eol = -1; } else { while (!pa_tagstruct_eof(t)) { @@ -327,15 +361,15 @@ static void context_get_client_info_callback(pa_pdispatch *pd, uint32_t command, } if (o->callback) { - void (*cb)(pa_context *s, const pa_client_info*_i, int _eof, void *_userdata) = (void (*)(pa_context *s, const pa_client_info*_i, int _eof, void *_userdata)) o->callback; + pa_client_info_cb_t cb = (pa_client_info_cb_t) o->callback; cb(o->context, &i, 0, o->userdata); } } } if (o->callback) { - void (*cb)(pa_context *s, const pa_client_info*_i, int _eof, void *_userdata) = (void (*)(pa_context *s, const pa_client_info*_i, int _eof, void *_userdata)) o->callback; - cb(o->context, NULL, eof, o->userdata); + pa_client_info_cb_t cb = (pa_client_info_cb_t) o->callback; + cb(o->context, NULL, eol, o->userdata); } finish: @@ -343,42 +377,50 @@ finish: pa_operation_unref(o); } -pa_operation* pa_context_get_client_info(pa_context *c, uint32_t idx, void (*cb)(pa_context *c, const pa_client_info*i, int is_last, void *userdata), void *userdata) { +pa_operation* pa_context_get_client_info(pa_context *c, uint32_t idx, pa_client_info_cb_t cb, void *userdata) { pa_tagstruct *t; pa_operation *o; uint32_t tag; - assert(c && cb); - o = pa_operation_new(c, NULL); - o->callback = (pa_operation_callback_t) cb; - o->userdata = userdata; + assert(c); + assert(c->ref >= 1); + assert(cb); + + 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); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, PA_COMMAND_GET_CLIENT_INFO); pa_tagstruct_putu32(t, tag = c->ctag++); pa_tagstruct_putu32(t, idx); pa_pstream_send_tagstruct(c->pstream, t); - pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_client_info_callback, o); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_client_info_callback, pa_operation_ref(o)); - return pa_operation_ref(o); + return o; } -pa_operation* pa_context_get_client_info_list(pa_context *c, void (*cb)(pa_context *c, const pa_client_info*i, int is_last, void *userdata), void *userdata) { - return pa_context_send_simple_command(c, PA_COMMAND_GET_CLIENT_INFO_LIST, context_get_client_info_callback, (pa_operation_callback_t) cb, userdata); +pa_operation* pa_context_get_client_info_list(pa_context *c, pa_client_info_cb_t cb, void *userdata) { + return pa_context_send_simple_command(c, PA_COMMAND_GET_CLIENT_INFO_LIST, context_get_client_info_callback, (pa_operation_cb_t) cb, userdata); } /*** Module info ***/ static void context_get_module_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { pa_operation *o = userdata; - int eof = 1; - assert(pd && o && o->context && o->ref >= 1); + int eol = 1; + assert(pd); + assert(o); + assert(o->ref >= 1); + assert(o->context); + if (command != PA_COMMAND_REPLY) { if (pa_context_handle_error(o->context, command, t) < 0) goto finish; - eof = -1; + eol = -1; } else { while (!pa_tagstruct_eof(t)) { @@ -394,15 +436,15 @@ static void context_get_module_info_callback(pa_pdispatch *pd, uint32_t command, } if (o->callback) { - void (*cb)(pa_context *s, const pa_module_info*_i, int _eof, void *_userdata) = (void (*)(pa_context *s, const pa_module_info*_i, int _eof, void *_userdata)) o->callback; + pa_module_info_cb_t cb = (pa_module_info_cb_t) o->callback; cb(o->context, &i, 0, o->userdata); } } } if (o->callback) { - void (*cb)(pa_context *s, const pa_module_info*_i, int _eof, void *_userdata) = (void (*)(pa_context *s, const pa_module_info*_i, int _eof, void *_userdata)) o->callback; - cb(o->context, NULL, eof, o->userdata); + pa_module_info_cb_t cb = (pa_module_info_cb_t) o->callback; + cb(o->context, NULL, eol, o->userdata); } finish: @@ -410,42 +452,50 @@ finish: pa_operation_unref(o); } -pa_operation* pa_context_get_module_info(pa_context *c, uint32_t idx, void (*cb)(pa_context *c, const pa_module_info*i, int is_last, void *userdata), void *userdata) { +pa_operation* pa_context_get_module_info(pa_context *c, uint32_t idx, pa_module_info_cb_t cb, void *userdata) { pa_tagstruct *t; pa_operation *o; uint32_t tag; - assert(c && cb); - o = pa_operation_new(c, NULL); - o->callback = (pa_operation_callback_t) cb; - o->userdata = userdata; + assert(c); + assert(c->ref >= 1); + assert(cb); + + 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); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, PA_COMMAND_GET_MODULE_INFO); pa_tagstruct_putu32(t, tag = c->ctag++); pa_tagstruct_putu32(t, idx); pa_pstream_send_tagstruct(c->pstream, t); - pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_module_info_callback, o); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_module_info_callback, pa_operation_ref(o)); - return pa_operation_ref(o); + return o; } -pa_operation* pa_context_get_module_info_list(pa_context *c, void (*cb)(pa_context *c, const pa_module_info*i, int is_last, void *userdata), void *userdata) { - return pa_context_send_simple_command(c, PA_COMMAND_GET_MODULE_INFO_LIST, context_get_module_info_callback, (pa_operation_callback_t) cb, userdata); +pa_operation* pa_context_get_module_info_list(pa_context *c, pa_module_info_cb_t cb, void *userdata) { + return pa_context_send_simple_command(c, PA_COMMAND_GET_MODULE_INFO_LIST, context_get_module_info_callback, (pa_operation_cb_t) cb, userdata); } /*** Sink input info ***/ static void context_get_sink_input_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { pa_operation *o = userdata; - int eof = 1; - assert(pd && o && o->context && o->ref >= 1); + int eol = 1; + + assert(pd); + assert(o); + assert(o->ref >= 1); + assert(o->context); if (command != PA_COMMAND_REPLY) { if (pa_context_handle_error(o->context, command, t) < 0) goto finish; - eof = -1; + eol = -1; } else { while (!pa_tagstruct_eof(t)) { @@ -469,15 +519,15 @@ static void context_get_sink_input_info_callback(pa_pdispatch *pd, uint32_t comm } if (o->callback) { - void (*cb)(pa_context *s, const pa_sink_input_info*_i, int _eof, void *_userdata) = (void (*)(pa_context *s, const pa_sink_input_info*_i, int _eof, void *_userdata)) o->callback; + pa_sink_input_info_cb_t cb = (pa_sink_input_info_cb_t) o->callback; cb(o->context, &i, 0, o->userdata); } } } if (o->callback) { - void (*cb)(pa_context *s, const pa_sink_input_info*_i, int _eof, void *_userdata) = (void (*)(pa_context *s, const pa_sink_input_info*_i, int _eof, void *_userdata)) o->callback; - cb(o->context, NULL, eof, o->userdata); + pa_sink_input_info_cb_t cb = (pa_sink_input_info_cb_t) o->callback; + cb(o->context, NULL, eol, o->userdata); } finish: @@ -485,42 +535,50 @@ finish: pa_operation_unref(o); } -pa_operation* pa_context_get_sink_input_info(pa_context *c, uint32_t idx, void (*cb)(pa_context *c, const pa_sink_input_info*i, int is_last, void *userdata), void *userdata) { +pa_operation* pa_context_get_sink_input_info(pa_context *c, uint32_t idx, pa_sink_input_info_cb_t cb, void *userdata) { pa_tagstruct *t; pa_operation *o; uint32_t tag; - assert(c && cb); - o = pa_operation_new(c, NULL); - o->callback = (pa_operation_callback_t) cb; - o->userdata = userdata; + assert(c); + assert(c->ref >= 1); + assert(cb); + + 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); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, PA_COMMAND_GET_SINK_INPUT_INFO); pa_tagstruct_putu32(t, tag = c->ctag++); pa_tagstruct_putu32(t, idx); pa_pstream_send_tagstruct(c->pstream, t); - pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_sink_input_info_callback, o); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_sink_input_info_callback, pa_operation_ref(o)); - return pa_operation_ref(o); + return o; } pa_operation* pa_context_get_sink_input_info_list(pa_context *c, void (*cb)(pa_context *c, const pa_sink_input_info*i, int is_last, void *userdata), void *userdata) { - return pa_context_send_simple_command(c, PA_COMMAND_GET_SINK_INPUT_INFO_LIST, context_get_sink_input_info_callback, (pa_operation_callback_t) cb, userdata); + return pa_context_send_simple_command(c, PA_COMMAND_GET_SINK_INPUT_INFO_LIST, context_get_sink_input_info_callback, (pa_operation_cb_t) cb, userdata); } /*** Source output info ***/ static void context_get_source_output_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { pa_operation *o = userdata; - int eof = 1; - assert(pd && o && o->context && o->ref >= 1); + int eol = 1; + + assert(pd); + assert(o); + assert(o->ref >= 1); + assert(o->context); if (command != PA_COMMAND_REPLY) { if (pa_context_handle_error(o->context, command, t) < 0) goto finish; - eof = -1; + eol = -1; } else { while (!pa_tagstruct_eof(t)) { @@ -543,15 +601,15 @@ static void context_get_source_output_info_callback(pa_pdispatch *pd, uint32_t c } if (o->callback) { - void (*cb)(pa_context *s, const pa_source_output_info*_i, int _eof, void *_userdata) = (void (*)(pa_context *s, const pa_source_output_info*_i, int _eof, void *_userdata)) o->callback; + pa_source_output_info_cb_t cb = (pa_source_output_info_cb_t) o->callback; cb(o->context, &i, 0, o->userdata); } } } if (o->callback) { - void (*cb)(pa_context *s, const pa_source_output_info*_i, int _eof, void *_userdata) = (void (*)(pa_context *s, const pa_source_output_info*_i, int _eof, void *_userdata))o->callback; - cb(o->context, NULL, eof, o->userdata); + pa_source_output_info_cb_t cb = (pa_source_output_info_cb_t) o->callback; + cb(o->context, NULL, eol, o->userdata); } finish: @@ -559,41 +617,49 @@ finish: pa_operation_unref(o); } -pa_operation* pa_context_get_source_output_info(pa_context *c, uint32_t idx, void (*cb)(pa_context *c, const pa_source_output_info*i, int is_last, void *userdata), void *userdata) { +pa_operation* pa_context_get_source_output_info(pa_context *c, uint32_t idx, pa_source_output_info_cb_t cb, void *userdata) { pa_tagstruct *t; pa_operation *o; uint32_t tag; - assert(c && cb); - o = pa_operation_new(c, NULL); - o->callback = (pa_operation_callback_t) cb; - o->userdata = userdata; + assert(c); + assert(c->ref >= 1); + assert(cb); + + 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); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, PA_COMMAND_GET_SOURCE_OUTPUT_INFO); pa_tagstruct_putu32(t, tag = c->ctag++); pa_tagstruct_putu32(t, idx); pa_pstream_send_tagstruct(c->pstream, t); - pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_source_output_info_callback, o); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_source_output_info_callback, pa_operation_ref(o)); - return pa_operation_ref(o); + return o; } -pa_operation* pa_context_get_source_output_info_list(pa_context *c, void (*cb)(pa_context *c, const pa_source_output_info*i, int is_last, void *userdata), void *userdata) { - return pa_context_send_simple_command(c, PA_COMMAND_GET_SOURCE_OUTPUT_INFO_LIST, context_get_source_output_info_callback, (pa_operation_callback_t) cb, userdata); +pa_operation* pa_context_get_source_output_info_list(pa_context *c, pa_source_output_info_cb_t cb, void *userdata) { + return pa_context_send_simple_command(c, PA_COMMAND_GET_SOURCE_OUTPUT_INFO_LIST, context_get_source_output_info_callback, (pa_operation_cb_t) cb, userdata); } /*** Volume manipulation ***/ -pa_operation* pa_context_set_sink_volume_by_index(pa_context *c, uint32_t idx, const pa_cvolume *volume, void (*cb)(pa_context *c, int success, void *userdata), void *userdata) { +pa_operation* pa_context_set_sink_volume_by_index(pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata) { pa_operation *o; pa_tagstruct *t; uint32_t tag; - assert(c && idx != PA_INVALID_INDEX); - o = pa_operation_new(c, NULL); - o->callback = (pa_operation_callback_t) cb; - o->userdata = userdata; + assert(c); + assert(c->ref >= 1); + assert(volume); + + PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); + PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, PA_COMMAND_SET_SINK_VOLUME); @@ -602,20 +668,26 @@ pa_operation* pa_context_set_sink_volume_by_index(pa_context *c, uint32_t idx, c pa_tagstruct_puts(t, NULL); pa_tagstruct_put_cvolume(t, volume); pa_pstream_send_tagstruct(c->pstream, t); - pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, o); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o)); - return pa_operation_ref(o); + return o; } -pa_operation* pa_context_set_sink_volume_by_name(pa_context *c, const char *name, const pa_cvolume *volume, void (*cb)(pa_context *c, int success, void *userdata), void *userdata) { +pa_operation* pa_context_set_sink_volume_by_name(pa_context *c, const char *name, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata) { pa_operation *o; pa_tagstruct *t; uint32_t tag; - assert(c && name); - o = pa_operation_new(c, NULL); - o->callback = (pa_operation_callback_t) cb; - o->userdata = userdata; + assert(c); + assert(c->ref >= 1); + assert(name); + assert(volume); + + PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); + PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID); + PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, PA_COMMAND_SET_SINK_VOLUME); @@ -624,20 +696,25 @@ pa_operation* pa_context_set_sink_volume_by_name(pa_context *c, const char *name pa_tagstruct_puts(t, name); pa_tagstruct_put_cvolume(t, volume); pa_pstream_send_tagstruct(c->pstream, t); - pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, o); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o)); - return pa_operation_ref(o); + return o; } -pa_operation* pa_context_set_sink_input_volume(pa_context *c, uint32_t idx, const pa_cvolume *volume, void (*cb)(pa_context *c, int success, void *userdata), void *userdata) { +pa_operation* pa_context_set_sink_input_volume(pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata) { pa_operation *o; pa_tagstruct *t; uint32_t tag; - assert(c && idx != PA_INVALID_INDEX); - o = pa_operation_new(c, NULL); - o->callback = (pa_operation_callback_t) cb; - o->userdata = userdata; + assert(c); + assert(c->ref >= 1); + assert(volume); + + 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, pa_cvolume_valid(volume), PA_ERR_INVALID); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, PA_COMMAND_SET_SINK_INPUT_VOLUME); @@ -645,23 +722,27 @@ pa_operation* pa_context_set_sink_input_volume(pa_context *c, uint32_t idx, cons pa_tagstruct_putu32(t, idx); pa_tagstruct_put_cvolume(t, volume); pa_pstream_send_tagstruct(c->pstream, t); - pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, o); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o)); - return pa_operation_ref(o); + return o; } /** Sample Cache **/ static void context_get_sample_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { pa_operation *o = userdata; - int eof = 1; - assert(pd && o && o->context && o->ref >= 1); + int eol = 1; + + assert(pd); + assert(o); + assert(o->ref >= 1); + assert(o->context); if (command != PA_COMMAND_REPLY) { if (pa_context_handle_error(o->context, command, t) < 0) goto finish; - eof = -1; + eol = -1; } else { while (!pa_tagstruct_eof(t)) { @@ -682,15 +763,15 @@ static void context_get_sample_info_callback(pa_pdispatch *pd, uint32_t command, } if (o->callback) { - void (*cb)(pa_context *s, const pa_sample_info*_i, int _eof, void *_userdata) = (void (*)(pa_context *s, const pa_sample_info*_i, int _eof, void *_userdata)) o->callback; + pa_sample_info_cb_t cb = (pa_sample_info_cb_t) o->callback; cb(o->context, &i, 0, o->userdata); } } } if (o->callback) { - void (*cb)(pa_context *s, const pa_sample_info*_i, int _eof, void *_userdata) = (void (*)(pa_context *s, const pa_sample_info*_i, int _eof, void *_userdata)) o->callback; - cb(o->context, NULL, eof, o->userdata); + pa_sample_info_cb_t cb = (pa_sample_info_cb_t) o->callback; + cb(o->context, NULL, eol, o->userdata); } finish: @@ -698,15 +779,19 @@ finish: pa_operation_unref(o); } -pa_operation* pa_context_get_sample_info_by_name(pa_context *c, const char *name, void (*cb)(pa_context *c, const pa_sample_info *i, int is_last, void *userdata), void *userdata) { +pa_operation* pa_context_get_sample_info_by_name(pa_context *c, const char *name, pa_sample_info_cb_t cb, void *userdata) { pa_tagstruct *t; pa_operation *o; uint32_t tag; - assert(c && cb && name); + + assert(c); + assert(c->ref >= 1); + assert(cb); + + 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); - o = pa_operation_new(c, NULL); - o->callback = (pa_operation_callback_t) cb; - o->userdata = userdata; + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, PA_COMMAND_GET_SAMPLE_INFO); @@ -714,20 +799,24 @@ pa_operation* pa_context_get_sample_info_by_name(pa_context *c, const char *name pa_tagstruct_putu32(t, PA_INVALID_INDEX); pa_tagstruct_puts(t, name); pa_pstream_send_tagstruct(c->pstream, t); - pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_sample_info_callback, o); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_sample_info_callback, pa_operation_ref(o)); - return pa_operation_ref(o); + return o; } -pa_operation* pa_context_get_sample_info_by_index(pa_context *c, uint32_t idx, void (*cb)(pa_context *c, const pa_sample_info *i, int is_last, void *userdata), void *userdata) { +pa_operation* pa_context_get_sample_info_by_index(pa_context *c, uint32_t idx, pa_sample_info_cb_t cb, void *userdata) { pa_tagstruct *t; pa_operation *o; uint32_t tag; - assert(c && cb); - o = pa_operation_new(c, NULL); - o->callback = (pa_operation_callback_t) cb; - o->userdata = userdata; + assert(c); + assert(c->ref >= 1); + assert(cb); + + 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); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, PA_COMMAND_GET_SAMPLE_INFO); @@ -735,81 +824,93 @@ pa_operation* pa_context_get_sample_info_by_index(pa_context *c, uint32_t idx, v pa_tagstruct_putu32(t, idx); pa_tagstruct_puts(t, NULL); pa_pstream_send_tagstruct(c->pstream, t); - pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_sample_info_callback, o); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_sample_info_callback, pa_operation_ref(o)); - return pa_operation_ref(o); + return o; } -pa_operation* pa_context_get_sample_info_list(pa_context *c, void (*cb)(pa_context *c, const pa_sample_info *i, int is_last, void *userdata), void *userdata) { - return pa_context_send_simple_command(c, PA_COMMAND_GET_SAMPLE_INFO_LIST, context_get_sample_info_callback, (pa_operation_callback_t) cb, userdata); +pa_operation* pa_context_get_sample_info_list(pa_context *c, pa_sample_info_cb_t cb, void *userdata) { + return pa_context_send_simple_command(c, PA_COMMAND_GET_SAMPLE_INFO_LIST, context_get_sample_info_callback, (pa_operation_cb_t) cb, userdata); } -static pa_operation* command_kill(pa_context *c, uint32_t command, uint32_t idx, void (*cb)(pa_context *c, int success, void *userdata), void *userdata) { +static pa_operation* command_kill(pa_context *c, uint32_t command, uint32_t idx, pa_context_success_cb_t cb, void *userdata) { pa_operation *o; pa_tagstruct *t; uint32_t tag; - assert(c && idx != PA_INVALID_INDEX); - o = pa_operation_new(c, NULL); - o->callback = (pa_operation_callback_t) cb; - o->userdata = userdata; + assert(c); + assert(c->ref >= 1); + + 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); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, command); pa_tagstruct_putu32(t, tag = c->ctag++); pa_tagstruct_putu32(t, idx); pa_pstream_send_tagstruct(c->pstream, t); - pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, o); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o)); - return pa_operation_ref(o); + return o; } -pa_operation* pa_context_kill_client(pa_context *c, uint32_t idx, void (*cb)(pa_context *c, int success, void *userdata), void *userdata) { +pa_operation* pa_context_kill_client(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata) { return command_kill(c, PA_COMMAND_KILL_CLIENT, idx, cb, userdata); } -pa_operation* pa_context_kill_sink_input(pa_context *c, uint32_t idx, void (*cb)(pa_context *c, int success, void *userdata), void *userdata) { +pa_operation* pa_context_kill_sink_input(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata) { return command_kill(c, PA_COMMAND_KILL_SINK_INPUT, idx, cb, userdata); } -pa_operation* pa_context_kill_source_output(pa_context *c, uint32_t idx, void (*cb)(pa_context *c, int success, void *userdata), void *userdata) { +pa_operation* pa_context_kill_source_output(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata) { return command_kill(c, PA_COMMAND_KILL_SOURCE_OUTPUT, idx, cb, userdata); } -static void load_module_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { +static void context_index_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { pa_operation *o = userdata; - uint32_t idx = -1; - assert(pd && o && o->context && o->ref >= 1); + uint32_t idx; + assert(pd); + assert(o); + assert(o->ref >= 1); + assert(o->context); + if (command != PA_COMMAND_REPLY) { if (pa_context_handle_error(o->context, command, t) < 0) goto finish; - } else if (pa_tagstruct_getu32(t, &idx) < 0 || + idx = PA_INVALID_INDEX; + } else if (pa_tagstruct_getu32(t, &idx) || !pa_tagstruct_eof(t)) { pa_context_fail(o->context, PA_ERR_PROTOCOL); goto finish; } - + if (o->callback) { - void (*cb)(pa_context *c, uint32_t _idx, void *_userdata) = (void (*)(pa_context *c, uint32_t _idx, void *_userdata)) o->callback; + pa_context_index_cb_t cb = (pa_context_index_cb_t) o->callback; cb(o->context, idx, o->userdata); } + finish: pa_operation_done(o); pa_operation_unref(o); } -pa_operation* pa_context_load_module(pa_context *c, const char*name, const char *argument, void (*cb)(pa_context *c, uint32_t idx, void *userdata), void *userdata) { +pa_operation* pa_context_load_module(pa_context *c, const char*name, const char *argument, pa_context_index_cb_t cb, void *userdata) { pa_operation *o; pa_tagstruct *t; uint32_t tag; - assert(c && name && argument); + + assert(c); + assert(c->ref >= 1); + + 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); - o = pa_operation_new(c, NULL); - o->callback = (pa_operation_callback_t) cb; - o->userdata = userdata; + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, PA_COMMAND_LOAD_MODULE); @@ -817,12 +918,12 @@ pa_operation* pa_context_load_module(pa_context *c, const char*name, const char pa_tagstruct_puts(t, name); pa_tagstruct_puts(t, argument); pa_pstream_send_tagstruct(c->pstream, t); - pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, load_module_callback, o); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_index_callback, pa_operation_ref(o)); - return pa_operation_ref(o); + return o; } -pa_operation* pa_context_unload_module(pa_context *c, uint32_t idx, void (*cb)(pa_context *c, int success, void *userdata), void *userdata) { +pa_operation* pa_context_unload_module(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata) { return command_kill(c, PA_COMMAND_UNLOAD_MODULE, idx, cb, userdata); } @@ -830,14 +931,18 @@ pa_operation* pa_context_unload_module(pa_context *c, uint32_t idx, void (*cb)(p static void context_get_autoload_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { pa_operation *o = userdata; - int eof = 1; - assert(pd && o && o->context && o->ref >= 1); + int eol = 1; + + assert(pd); + assert(o); + assert(o->ref >= 1); + assert(o->context); if (command != PA_COMMAND_REPLY) { if (pa_context_handle_error(o->context, command, t) < 0) goto finish; - eof = -1; + eol = -1; } else { while (!pa_tagstruct_eof(t)) { @@ -853,15 +958,15 @@ static void context_get_autoload_info_callback(pa_pdispatch *pd, uint32_t comman } if (o->callback) { - void (*cb)(pa_context *s, const pa_autoload_info*_i, int _eof, void *_userdata) = (void (*)(pa_context *s, const pa_autoload_info*_i, int _eof, void *_userdata)) o->callback; + pa_autoload_info_cb_t cb = (pa_autoload_info_cb_t) o->callback; cb(o->context, &i, 0, o->userdata); } } } if (o->callback) { - void (*cb)(pa_context *s, const pa_autoload_info*_i, int _eof, void *_userdata) = (void (*)(pa_context *s, const pa_autoload_info*_i, int _eof, void *_userdata)) o->callback; - cb(o->context, NULL, eof, o->userdata); + pa_autoload_info_cb_t cb = (pa_autoload_info_cb_t) o->callback; + cb(o->context, NULL, eol, o->userdata); } finish: @@ -869,15 +974,20 @@ finish: pa_operation_unref(o); } -pa_operation* pa_context_get_autoload_info_by_name(pa_context *c, const char *name, pa_autoload_type_t type, void (*cb)(pa_context *c, const pa_autoload_info *i, int is_last, void *userdata), void *userdata) { +pa_operation* pa_context_get_autoload_info_by_name(pa_context *c, const char *name, pa_autoload_type_t type, pa_autoload_info_cb_t cb, void *userdata) { pa_tagstruct *t; pa_operation *o; uint32_t tag; - assert(c && cb && name); - o = pa_operation_new(c, NULL); - o->callback = (pa_operation_callback_t) cb; - o->userdata = userdata; + assert(c); + assert(c->ref >= 1); + assert(cb); + + 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, type == PA_AUTOLOAD_SINK || type == PA_AUTOLOAD_SOURCE, PA_ERR_INVALID); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, PA_COMMAND_GET_AUTOLOAD_INFO); @@ -885,71 +995,53 @@ pa_operation* pa_context_get_autoload_info_by_name(pa_context *c, const char *na pa_tagstruct_puts(t, name); pa_tagstruct_putu32(t, type); pa_pstream_send_tagstruct(c->pstream, t); - pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_autoload_info_callback, o); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_autoload_info_callback, pa_operation_ref(o)); - return pa_operation_ref(o); + return o; } -pa_operation* pa_context_get_autoload_info_by_index(pa_context *c, uint32_t idx, void (*cb)(pa_context *c, const pa_autoload_info *i, int is_last, void *userdata), void *userdata) { +pa_operation* pa_context_get_autoload_info_by_index(pa_context *c, uint32_t idx, pa_autoload_info_cb_t cb, void *userdata) { pa_tagstruct *t; pa_operation *o; uint32_t tag; - assert(c && cb && idx != PA_INVALID_INDEX); + + assert(c); + assert(c->ref >= 1); + assert(cb); + + 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); - o = pa_operation_new(c, NULL); - o->callback = (pa_operation_callback_t) cb; - o->userdata = userdata; + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, PA_COMMAND_GET_AUTOLOAD_INFO); pa_tagstruct_putu32(t, tag = c->ctag++); pa_tagstruct_putu32(t, idx); pa_pstream_send_tagstruct(c->pstream, t); - pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_autoload_info_callback, o); - - return pa_operation_ref(o); -} + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_autoload_info_callback, pa_operation_ref(o)); -pa_operation* pa_context_get_autoload_info_list(pa_context *c, void (*cb)(pa_context *c, const pa_autoload_info *i, int is_last, void *userdata), void *userdata) { - return pa_context_send_simple_command(c, PA_COMMAND_GET_AUTOLOAD_INFO_LIST, context_get_autoload_info_callback, (pa_operation_callback_t) cb, userdata); + return o; } -static void context_add_autoload_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { - pa_operation *o = userdata; - uint32_t idx; - assert(pd && o && o->context && o->ref >= 1); - - if (command != PA_COMMAND_REPLY) { - if (pa_context_handle_error(o->context, command, t) < 0) - goto finish; - - idx = PA_INVALID_INDEX; - } else if (pa_tagstruct_getu32(t, &idx) || - !pa_tagstruct_eof(t)) { - pa_context_fail(o->context, PA_ERR_PROTOCOL); - goto finish; - } - - if (o->callback) { - void (*cb)(pa_context *s, uint32_t _idx, void *_userdata) = (void (*)(pa_context *s, uint32_t _idx, void *_userdata)) o->callback; - cb(o->context, idx, o->userdata); - } - - -finish: - pa_operation_done(o); - pa_operation_unref(o); +pa_operation* pa_context_get_autoload_info_list(pa_context *c, pa_autoload_info_cb_t cb, void *userdata) { + return pa_context_send_simple_command(c, PA_COMMAND_GET_AUTOLOAD_INFO_LIST, context_get_autoload_info_callback, (pa_operation_cb_t) cb, userdata); } -pa_operation* pa_context_add_autoload(pa_context *c, const char *name, pa_autoload_type_t type, const char *module, const char*argument, void (*cb)(pa_context *c, int success, void *userdata), void* userdata) { +pa_operation* pa_context_add_autoload(pa_context *c, const char *name, pa_autoload_type_t type, const char *module, const char*argument, pa_context_index_cb_t cb, void* userdata) { pa_operation *o; pa_tagstruct *t; uint32_t tag; - assert(c && name && module && argument); - o = pa_operation_new(c, NULL); - o->callback = (pa_operation_callback_t) cb; - o->userdata = userdata; + assert(c); + assert(c->ref >= 1); + + 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, type == PA_AUTOLOAD_SINK || type == PA_AUTOLOAD_SOURCE, PA_ERR_INVALID); + PA_CHECK_VALIDITY_RETURN_NULL(c, module && *module, PA_ERR_INVALID); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, PA_COMMAND_ADD_AUTOLOAD); @@ -959,20 +1051,24 @@ pa_operation* pa_context_add_autoload(pa_context *c, const char *name, pa_autolo pa_tagstruct_puts(t, module); pa_tagstruct_puts(t, argument); pa_pstream_send_tagstruct(c->pstream, t); - pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_add_autoload_callback, o); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_index_callback, pa_operation_ref(o)); - return pa_operation_ref(o); + return o; } -pa_operation* pa_context_remove_autoload_by_name(pa_context *c, const char *name, pa_autoload_type_t type, void (*cb)(pa_context *c, int success, void *userdata), void* userdata) { +pa_operation* pa_context_remove_autoload_by_name(pa_context *c, const char *name, pa_autoload_type_t type, pa_context_success_cb_t cb, void* userdata) { pa_operation *o; pa_tagstruct *t; uint32_t tag; - assert(c && name); - o = pa_operation_new(c, NULL); - o->callback = (pa_operation_callback_t) cb; - o->userdata = userdata; + assert(c); + assert(c->ref >= 1); + + 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, type == PA_AUTOLOAD_SINK || type == PA_AUTOLOAD_SOURCE, PA_ERR_INVALID); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, PA_COMMAND_REMOVE_AUTOLOAD); @@ -980,27 +1076,30 @@ pa_operation* pa_context_remove_autoload_by_name(pa_context *c, const char *name pa_tagstruct_puts(t, name); pa_tagstruct_putu32(t, type); pa_pstream_send_tagstruct(c->pstream, t); - pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, o); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o)); - return pa_operation_ref(o); + return o; } -pa_operation* pa_context_remove_autoload_by_index(pa_context *c, uint32_t idx, void (*cb)(pa_context *c, int success, void *userdata), void* userdata) { +pa_operation* pa_context_remove_autoload_by_index(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void* userdata) { pa_operation *o; pa_tagstruct *t; uint32_t tag; - assert(c && idx != PA_INVALID_INDEX); - o = pa_operation_new(c, NULL); - o->callback = (pa_operation_callback_t) cb; - o->userdata = userdata; + assert(c); + assert(c->ref >= 1); + + 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); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, PA_COMMAND_REMOVE_AUTOLOAD); pa_tagstruct_putu32(t, tag = c->ctag++); pa_tagstruct_putu32(t, idx); pa_pstream_send_tagstruct(c->pstream, t); - pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, o); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o)); - return pa_operation_ref(o); + return o; } diff --git a/src/polyp/introspect.h b/src/polyp/introspect.h index 0abb54cf2..d4ff65fb4 100644 --- a/src/polyp/introspect.h +++ b/src/polyp/introspect.h @@ -36,11 +36,12 @@ * of a certain kind, use the pa_context_xxx_list() functions. The * specified callback function is called once for each entry. The * enumeration is finished by a call to the callback function with - * is_last=1 and i=NULL. Strings referenced in pa_xxx_info structures - * and the structures themselves point to internal memory that may not - * be modified. That memory is only valid during the call to the - * callback function. A deep copy is required if you need this data - * outside the callback functions. An error is signalled by a call to * the callback function with i=NULL and is_last=0. + * eol=1 and i=NULL. Strings referenced in pa_xxx_info structures and + * the structures themselves point to internal memory that may not be + * modified. That memory is only valid during the call to the callback + * function. A deep copy is required if you need this data outside the + * callback functions. An error is signalled by a call to the callback + * function with i=NULL and eol=0. * * When using the routines that ask fo a single entry only, a callback * with the same signature is used. However, no finishing call to the @@ -63,14 +64,17 @@ typedef struct pa_sink_info { const char *driver; /**< Driver name. \since 0.9 */ } pa_sink_info; +/** Callback prototype for pa_context_get_sink_info_by_name() and friends */ +typedef void (*pa_sink_info_cb_t)(pa_context *c, const pa_sink_info *i, int eol, void *userdata); + /** Get information about a sink by its name */ -pa_operation* pa_context_get_sink_info_by_name(pa_context *c, const char *name, void (*cb)(pa_context *c, const pa_sink_info *i, int is_last, void *userdata), void *userdata); +pa_operation* pa_context_get_sink_info_by_name(pa_context *c, const char *name, pa_sink_info_cb_t cb, void *userdata); /** Get information about a sink by its index */ -pa_operation* pa_context_get_sink_info_by_index(pa_context *c, uint32_t id, void (*cb)(pa_context *c, const pa_sink_info *i, int is_last, void *userdata), void *userdata); +pa_operation* pa_context_get_sink_info_by_index(pa_context *c, uint32_t id, pa_sink_info_cb_t cb, void *userdata); /** Get the complete sink list */ -pa_operation* pa_context_get_sink_info_list(pa_context *c, void (*cb)(pa_context *c, const pa_sink_info *i, int is_last, void *userdata), void *userdata); +pa_operation* pa_context_get_sink_info_list(pa_context *c, pa_sink_info_cb_t cb, void *userdata); /** Stores information about sources */ typedef struct pa_source_info { @@ -86,14 +90,17 @@ typedef struct pa_source_info { const char *driver; /**< Driver name \since 0.9 */ } pa_source_info; +/** Callback prototype for pa_context_get_source_info_by_name() and friends */ +typedef void (*pa_source_info_cb_t)(pa_context *c, const pa_source_info *i, int eol, void *userdata); + /** Get information about a source by its name */ -pa_operation* pa_context_get_source_info_by_name(pa_context *c, const char *name, void (*cb)(pa_context *c, const pa_source_info *i, int is_last, void *userdata), void *userdata); +pa_operation* pa_context_get_source_info_by_name(pa_context *c, const char *name, pa_source_info_cb_t cb, void *userdata); /** Get information about a source by its index */ -pa_operation* pa_context_get_source_info_by_index(pa_context *c, uint32_t id, void (*cb)(pa_context *c, const pa_source_info *i, int is_last, void *userdata), void *userdata); +pa_operation* pa_context_get_source_info_by_index(pa_context *c, uint32_t id, pa_source_info_cb_t cb, void *userdata); /** Get the complete source list */ -pa_operation* pa_context_get_source_info_list(pa_context *c, void (*cb)(pa_context *c, const pa_source_info *i, int is_last, void *userdata), void *userdata); +pa_operation* pa_context_get_source_info_list(pa_context *c, pa_source_info_cb_t cb, void *userdata); /** Server information */ typedef struct pa_server_info { @@ -107,8 +114,11 @@ typedef struct pa_server_info { uint32_t cookie; /**< A random cookie for identifying this instance of polypaudio. \since 0.8 */ } pa_server_info; +/** Callback prototype for pa_context_get_server_info() */ +typedef void (*pa_server_info_cb_t) (pa_context *c, const pa_server_info*i, void *userdata); + /** Get some information about the server */ -pa_operation* pa_context_get_server_info(pa_context *c, void (*cb)(pa_context *c, const pa_server_info*i, void *userdata), void *userdata); +pa_operation* pa_context_get_server_info(pa_context *c, pa_server_info_cb_t cb, void *userdata); /** Stores information about modules */ typedef struct pa_module_info { @@ -119,11 +129,14 @@ typedef struct pa_module_info { int auto_unload; /**< Non-zero if this is an autoloaded module */ } pa_module_info; +/** Callback prototype for pa_context_get_module_info() and firends*/ +typedef void (*pa_module_info_cb_t) (pa_context *c, const pa_module_info*i, int eol, void *userdata); + /** Get some information about a module by its index */ -pa_operation* pa_context_get_module_info(pa_context *c, uint32_t idx, void (*cb)(pa_context *c, const pa_module_info*i, int is_last, void *userdata), void *userdata); +pa_operation* pa_context_get_module_info(pa_context *c, uint32_t idx, pa_module_info_cb_t cb, void *userdata); /** Get the complete list of currently loaded modules */ -pa_operation* pa_context_get_module_info_list(pa_context *c, void (*cb)(pa_context *c, const pa_module_info*i, int is_last, void *userdata), void *userdata); +pa_operation* pa_context_get_module_info_list(pa_context *c, pa_module_info_cb_t cb, void *userdata); /** Stores information about clients */ typedef struct pa_client_info { @@ -133,11 +146,14 @@ typedef struct pa_client_info { const char *driver; /**< Driver name \since 0.9 */ } pa_client_info; +/** Callback prototype for pa_context_get_client_info() and firends*/ +typedef void (*pa_client_info_cb_t) (pa_context *c, const pa_client_info*i, int eol, void *userdata); + /** Get information about a client by its index */ -pa_operation* pa_context_get_client_info(pa_context *c, uint32_t idx, void (*cb)(pa_context *c, const pa_client_info*i, int is_last, void *userdata), void *userdata); +pa_operation* pa_context_get_client_info(pa_context *c, uint32_t idx, pa_client_info_cb_t cb, void *userdata); /** Get the complete client list */ -pa_operation* pa_context_get_client_info_list(pa_context *c, void (*cb)(pa_context *c, const pa_client_info*i, int is_last, void *userdata), void *userdata); +pa_operation* pa_context_get_client_info_list(pa_context *c, pa_client_info_cb_t cb, void *userdata); /** Stores information about sink inputs */ typedef struct pa_sink_input_info { @@ -155,11 +171,14 @@ typedef struct pa_sink_input_info { const char *driver; /**< Driver name \since 0.9 */ } pa_sink_input_info; +/** Callback prototype for pa_context_get_sink_input_info() and firends*/ +typedef void (*pa_sink_input_info_cb_t) (pa_context *c, const pa_sink_input_info *i, int eol, void *userdata); + /** Get some information about a sink input by its index */ -pa_operation* pa_context_get_sink_input_info(pa_context *c, uint32_t idx, void (*cb)(pa_context *c, const pa_sink_input_info*i, int is_last, void *userdata), void *userdata); +pa_operation* pa_context_get_sink_input_info(pa_context *c, uint32_t idx, pa_sink_input_info_cb_t cb, void *userdata); /** Get the complete sink input list */ -pa_operation* pa_context_get_sink_input_info_list(pa_context *c, void (*cb)(pa_context *c, const pa_sink_input_info*i, int is_last, void *userdata), void *userdata); +pa_operation* pa_context_get_sink_input_info_list(pa_context *c, pa_sink_input_info_cb_t cb, void *userdata); /** Stores information about source outputs */ typedef struct pa_source_output_info { @@ -176,20 +195,23 @@ typedef struct pa_source_output_info { const char *driver; /**< Driver name \since 0.9 */ } pa_source_output_info; +/** Callback prototype for pa_context_get_source_output_info() and firends*/ +typedef void (*pa_source_output_info_cb_t) (pa_context *c, const pa_source_output_info *i, int eol, void *userdata); + /** Get information about a source output by its index */ -pa_operation* pa_context_get_source_output_info(pa_context *c, uint32_t idx, void (*cb)(pa_context *c, const pa_source_output_info*i, int is_last, void *userdata), void *userdata); +pa_operation* pa_context_get_source_output_info(pa_context *c, uint32_t idx, pa_source_output_info_cb_t cb, void *userdata); /** Get the complete list of source outputs */ -pa_operation* pa_context_get_source_output_info_list(pa_context *c, void (*cb)(pa_context *c, const pa_source_output_info*i, int is_last, void *userdata), void *userdata); +pa_operation* pa_context_get_source_output_info_list(pa_context *c, pa_source_output_info_cb_t cb, void *userdata); /** Set the volume of a sink device specified by its index */ -pa_operation* pa_context_set_sink_volume_by_index(pa_context *c, uint32_t idx, const pa_cvolume *volume, void (*cb)(pa_context *c, int success, void *userdata), void *userdata); +pa_operation* pa_context_set_sink_volume_by_index(pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata); /** Set the volume of a sink device specified by its name */ -pa_operation* pa_context_set_sink_volume_by_name(pa_context *c, const char *name, const pa_cvolume *volume, void (*cb)(pa_context *c, int success, void *userdata), void *userdata); +pa_operation* pa_context_set_sink_volume_by_name(pa_context *c, const char *name, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata); /** Set the volume of a sink input stream */ -pa_operation* pa_context_set_sink_input_volume(pa_context *c, uint32_t idx, const pa_cvolume *volume, void (*cb)(pa_context *c, int success, void *userdata), void *userdata); +pa_operation* pa_context_set_sink_input_volume(pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata); /** Memory block statistics */ typedef struct pa_stat_info { @@ -200,8 +222,11 @@ typedef struct pa_stat_info { uint32_t scache_size; /**< Total size of all sample cache entries. \since 0.4 */ } pa_stat_info; +/** Callback prototype for pa_context_stat() */ +typedef void (*pa_stat_info_cb_t) (pa_context *c, const pa_stat_info *i, void *userdata); + /** Get daemon memory block statistics */ -pa_operation* pa_context_stat(pa_context *c, void (*cb)(pa_context *c, const pa_stat_info *i, void *userdata), void *userdata); +pa_operation* pa_context_stat(pa_context *c, pa_stat_info_cb_t cb, void *userdata); /** Stores information about sample cache entries */ typedef struct pa_sample_info { @@ -216,29 +241,35 @@ typedef struct pa_sample_info { const char *filename; /**< In case this is a lazy cache entry, the filename for the sound file to be loaded on demand. \since 0.5 */ } pa_sample_info; +/** Callback prototype for pa_context_get_sample_info_by_name() and firends */ +typedef void (*pa_sample_info_cb_t)(pa_context *c, const pa_sample_info *i, int eol, void *userdata); + /** Get information about a sample by its name */ -pa_operation* pa_context_get_sample_info_by_name(pa_context *c, const char *name, void (*cb)(pa_context *c, const pa_sample_info *i, int is_last, void *userdata), void *userdata); +pa_operation* pa_context_get_sample_info_by_name(pa_context *c, const char *name, pa_sample_info_cb_t cb, void *userdata); /** Get information about a sample by its index */ -pa_operation* pa_context_get_sample_info_by_index(pa_context *c, uint32_t idx, void (*cb)(pa_context *c, const pa_sample_info *i, int is_last, void *userdata), void *userdata); +pa_operation* pa_context_get_sample_info_by_index(pa_context *c, uint32_t idx, pa_sample_info_cb_t cb, void *userdata); /** Get the complete list of samples stored in the daemon. */ -pa_operation* pa_context_get_sample_info_list(pa_context *c, void (*cb)(pa_context *c, const pa_sample_info *i, int is_last, void *userdata), void *userdata); +pa_operation* pa_context_get_sample_info_list(pa_context *c, pa_sample_info_cb_t cb, void *userdata); /** Kill a client. \since 0.5 */ -pa_operation* pa_context_kill_client(pa_context *c, uint32_t idx, void (*cb)(pa_context *c, int success, void *userdata), void *userdata); +pa_operation* pa_context_kill_client(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata); /** Kill a sink input. \since 0.5 */ -pa_operation* pa_context_kill_sink_input(pa_context *c, uint32_t idx, void (*cb)(pa_context *c, int success, void *userdata), void *userdata); +pa_operation* pa_context_kill_sink_input(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata); /** Kill a source output. \since 0.5 */ -pa_operation* pa_context_kill_source_output(pa_context *c, uint32_t idx, void (*cb)(pa_context *c, int success, void *userdata), void *userdata); +pa_operation* pa_context_kill_source_output(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata); + +/** Callback prototype for pa_context_load_module() and pa_context_add_autoload() */ +typedef void (*pa_context_index_cb_t)(pa_context *c, uint32_t idx, void *userdata); /** Load a module. \since 0.5 */ -pa_operation* pa_context_load_module(pa_context *c, const char*name, const char *argument, void (*cb)(pa_context *c, uint32_t idx, void *userdata), void *userdata); +pa_operation* pa_context_load_module(pa_context *c, const char*name, const char *argument, pa_context_index_cb_t cb, void *userdata); /** Unload a module. \since 0.5 */ -pa_operation* pa_context_unload_module(pa_context *c, uint32_t idx, void (*cb)(pa_context *c, int success, void *userdata), void *userdata); +pa_operation* pa_context_unload_module(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata); /** Type of an autoload entry. \since 0.5 */ typedef enum pa_autoload_type { @@ -255,23 +286,26 @@ typedef struct pa_autoload_info { const char *argument; /**< Argument string for module */ } pa_autoload_info; +/** Callback prototype for pa_context_get_autoload_info_by_name() and firends */ +typedef void (*pa_autoload_info_cb_t)(pa_context *c, const pa_autoload_info *i, int eol, void *userdata); + /** Get info about a specific autoload entry. \since 0.6 */ -pa_operation* pa_context_get_autoload_info_by_name(pa_context *c, const char *name, pa_autoload_type_t type, void (*cb)(pa_context *c, const pa_autoload_info *i, int is_last, void *userdata), void *userdata); +pa_operation* pa_context_get_autoload_info_by_name(pa_context *c, const char *name, pa_autoload_type_t type, pa_autoload_info_cb_t cb, void *userdata); /** Get info about a specific autoload entry. \since 0.6 */ -pa_operation* pa_context_get_autoload_info_by_index(pa_context *c, uint32_t idx, void (*cb)(pa_context *c, const pa_autoload_info *i, int is_last, void *userdata), void *userdata); +pa_operation* pa_context_get_autoload_info_by_index(pa_context *c, uint32_t idx, pa_autoload_info_cb_t cb, void *userdata); /** Get the complete list of autoload entries. \since 0.5 */ -pa_operation* pa_context_get_autoload_info_list(pa_context *c, void (*cb)(pa_context *c, const pa_autoload_info *i, int is_last, void *userdata), void *userdata); +pa_operation* pa_context_get_autoload_info_list(pa_context *c, pa_autoload_info_cb_t cb, void *userdata); /** Add a new autoload entry. \since 0.5 */ -pa_operation* pa_context_add_autoload(pa_context *c, const char *name, pa_autoload_type_t type, const char *module, const char*argument, void (*cb)(pa_context *c, int idx, void *userdata), void* userdata); +pa_operation* pa_context_add_autoload(pa_context *c, const char *name, pa_autoload_type_t type, const char *module, const char*argument, pa_context_index_cb_t, void* userdata); /** Remove an autoload entry. \since 0.6 */ -pa_operation* pa_context_remove_autoload_by_name(pa_context *c, const char *name, pa_autoload_type_t type, void (*cb)(pa_context *c, int success, void *userdata), void* userdata); +pa_operation* pa_context_remove_autoload_by_name(pa_context *c, const char *name, pa_autoload_type_t type, pa_context_success_cb_t cb, void* userdata); /** Remove an autoload entry. \since 0.6 */ -pa_operation* pa_context_remove_autoload_by_index(pa_context *c, uint32_t idx, void (*cb)(pa_context *c, int success, void *userdata), void* userdata); +pa_operation* pa_context_remove_autoload_by_index(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void* userdata); PA_C_DECL_END diff --git a/src/polyp/operation.c b/src/polyp/operation.c index 5440cf9ea..0216888c4 100644 --- a/src/polyp/operation.c +++ b/src/polyp/operation.c @@ -31,7 +31,7 @@ #include "operation.h" -pa_operation *pa_operation_new(pa_context *c, pa_stream *s) { +pa_operation *pa_operation_new(pa_context *c, pa_stream *s, pa_operation_cb_t cb, void *userdata) { pa_operation *o; assert(c); @@ -41,8 +41,8 @@ pa_operation *pa_operation_new(pa_context *c, pa_stream *s) { o->stream = s ? pa_stream_ref(s) : NULL; o->state = PA_OPERATION_RUNNING; - o->userdata = NULL; - o->callback = NULL; + o->callback = cb; + o->userdata = userdata; PA_LLIST_PREPEND(pa_operation, o->context->operations, o); return pa_operation_ref(o); diff --git a/src/polyp/scache.c b/src/polyp/scache.c index f6a3a7e64..792d7cbfc 100644 --- a/src/polyp/scache.c +++ b/src/polyp/scache.c @@ -34,15 +34,17 @@ #include "scache.h" -void pa_stream_connect_upload(pa_stream *s, size_t length) { +int pa_stream_connect_upload(pa_stream *s, size_t length) { pa_tagstruct *t; uint32_t tag; - assert(s && length); + assert(s); + PA_CHECK_VALIDITY(s->context, s->state == PA_STREAM_UNCONNECTED, PA_ERR_BADSTATE); + PA_CHECK_VALIDITY(s->context, length <= 0, PA_ERR_INVALID); + pa_stream_ref(s); - s->state = PA_STREAM_CREATING; s->direction = PA_STREAM_UPLOAD; t = pa_tagstruct_new(NULL, 0); @@ -54,22 +56,23 @@ void pa_stream_connect_upload(pa_stream *s, size_t length) { pa_pstream_send_tagstruct(s->context->pstream, t); pa_pdispatch_register_reply(s->context->pdispatch, tag, DEFAULT_TIMEOUT, pa_create_stream_callback, s); + pa_stream_set_state(s, PA_STREAM_CREATING); + pa_stream_unref(s); + return 0; } -void pa_stream_finish_upload(pa_stream *s) { +int pa_stream_finish_upload(pa_stream *s) { pa_tagstruct *t; uint32_t tag; assert(s); - if (!s->channel_valid || !s->context->state == PA_CONTEXT_READY) - return; + PA_CHECK_VALIDITY(s->context, s->channel_valid, PA_ERR_BADSTATE); + PA_CHECK_VALIDITY(s->context, s->context->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); pa_stream_ref(s); t = pa_tagstruct_new(NULL, 0); - assert(t); - pa_tagstruct_putu32(t, PA_COMMAND_FINISH_UPLOAD_STREAM); pa_tagstruct_putu32(t, tag = s->context->ctag++); pa_tagstruct_putu32(t, s->channel); @@ -77,53 +80,59 @@ void pa_stream_finish_upload(pa_stream *s) { pa_pdispatch_register_reply(s->context->pdispatch, tag, DEFAULT_TIMEOUT, pa_stream_disconnect_callback, s); pa_stream_unref(s); + return 0; } -pa_operation * pa_context_play_sample(pa_context *c, const char *name, const char *dev, uint32_t volume, pa_context_success_cb_t cb, void *userdata) { +pa_operation *pa_context_play_sample(pa_context *c, const char *name, const char *dev, pa_volume_t volume, pa_context_success_cb_t cb, void *userdata) { pa_operation *o; pa_tagstruct *t; uint32_t tag; - assert(c && name && *name && (!dev || *dev)); - o = pa_operation_new(c, NULL); - o->callback = (pa_operation_callback_t) cb; - o->userdata = userdata; + assert(c); + assert(c->ref >= 1); + + 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, !dev || *dev, PA_ERR_INVALID); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); if (!dev) dev = c->conf->default_sink; t = pa_tagstruct_new(NULL, 0); - assert(t); pa_tagstruct_putu32(t, PA_COMMAND_PLAY_SAMPLE); pa_tagstruct_putu32(t, tag = c->ctag++); - pa_tagstruct_putu32(t, (uint32_t) -1); + pa_tagstruct_putu32(t, PA_INVALID_INDEX); pa_tagstruct_puts(t, dev); pa_tagstruct_putu32(t, volume); pa_tagstruct_puts(t, name); pa_pstream_send_tagstruct(c->pstream, t); - pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, o); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o)); - return pa_operation_ref(o); + return o; } pa_operation* pa_context_remove_sample(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) { pa_operation *o; pa_tagstruct *t; uint32_t tag; - assert(c && name); - o = pa_operation_new(c, NULL); - o->callback = (pa_operation_callback_t) cb; - o->userdata = userdata; + assert(c); + assert(c->ref >= 1); + + 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); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); t = pa_tagstruct_new(NULL, 0); - assert(t); pa_tagstruct_putu32(t, PA_COMMAND_REMOVE_SAMPLE); pa_tagstruct_putu32(t, tag = c->ctag++); pa_tagstruct_puts(t, name); pa_pstream_send_tagstruct(c->pstream, t); - pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, o); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o)); - return pa_operation_ref(o); + return o; } diff --git a/src/polyp/scache.h b/src/polyp/scache.h index 3480d8766..cdb47cab5 100644 --- a/src/polyp/scache.h +++ b/src/polyp/scache.h @@ -34,11 +34,11 @@ PA_C_DECL_BEGIN /** Make this stream a sample upload stream */ -void pa_stream_connect_upload(pa_stream *s, size_t length); +int pa_stream_connect_upload(pa_stream *s, size_t length); /** Finish the sample upload, the stream name will become the sample name. You cancel a samp * le upload by issuing pa_stream_disconnect() */ -void pa_stream_finish_upload(pa_stream *s); +int pa_stream_finish_upload(pa_stream *s); /** Play a sample from the sample cache to the specified device. If the latter is NULL use the default sink. Returns an operation object */ pa_operation* pa_context_play_sample( diff --git a/src/polyp/stream.c b/src/polyp/stream.c index 88971085b..1ffb4c16a 100644 --- a/src/polyp/stream.c +++ b/src/polyp/stream.c @@ -44,7 +44,7 @@ pa_stream *pa_stream_new(pa_context *c, const char *name, const pa_sample_spec * assert(c); PA_CHECK_VALIDITY_RETURN_NULL(c, ss && pa_sample_spec_valid(ss), PA_ERR_INVALID); - PA_CHECK_VALIDITY_RETURN_NULL(c, !map || pa_channel_map_valid(map), PA_ERR_INVALID); + PA_CHECK_VALIDITY_RETURN_NULL(c, !map || (pa_channel_map_valid(map) && map->channels == ss->channels), PA_ERR_INVALID); s = pa_xnew(pa_stream, 1); s->ref = 1; @@ -190,7 +190,11 @@ void pa_command_stream_killed(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED pa_context *c = userdata; pa_stream *s; uint32_t channel; - assert(pd && (command == PA_COMMAND_PLAYBACK_STREAM_KILLED || command == PA_COMMAND_RECORD_STREAM_KILLED) && t && c); + + assert(pd); + assert(command == PA_COMMAND_PLAYBACK_STREAM_KILLED || command == PA_COMMAND_RECORD_STREAM_KILLED); + assert(t); + assert(c); pa_context_ref(c); @@ -203,7 +207,7 @@ void pa_command_stream_killed(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED if (!(s = pa_dynarray_get(command == PA_COMMAND_PLAYBACK_STREAM_KILLED ? c->playback_streams : c->record_streams, channel))) goto finish; - c->error = PA_ERR_KILLED; + pa_context_set_error(c, PA_ERR_KILLED); pa_stream_set_state(s, PA_STREAM_FAILED); finish: @@ -214,7 +218,11 @@ void pa_command_request(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32 pa_stream *s; pa_context *c = userdata; uint32_t bytes, channel; - assert(pd && command == PA_COMMAND_REQUEST && t && c); + + assert(pd); + assert(command == PA_COMMAND_REQUEST); + assert(t); + assert(c); pa_context_ref(c); @@ -276,7 +284,7 @@ finish: } static void ipol_callback(pa_mainloop_api *m, pa_time_event *e, PA_GCC_UNUSED const struct timeval *tv, void *userdata) { - struct timeval tv2; + struct timeval next; pa_stream *s = userdata; pa_stream_ref(s); @@ -288,10 +296,9 @@ static void ipol_callback(pa_mainloop_api *m, pa_time_event *e, PA_GCC_UNUSED co s->ipol_requested = 1; } - pa_gettimeofday(&tv2); - pa_timeval_add(&tv2, LATENCY_IPOL_INTERVAL_USEC); - - m->time_restart(e, &tv2); + pa_gettimeofday(&next); + pa_timeval_add(&next, LATENCY_IPOL_INTERVAL_USEC); + m->time_restart(e, &next); pa_stream_unref(s); } @@ -299,8 +306,12 @@ static void ipol_callback(pa_mainloop_api *m, pa_time_event *e, PA_GCC_UNUSED co void pa_create_stream_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { pa_stream *s = userdata; - assert(pd && s && s->state == PA_STREAM_CREATING); - + + assert(pd); + assert(t); + assert(s); + assert(s->state == PA_STREAM_CREATING); + pa_stream_ref(s); if (command != PA_COMMAND_REPLY) { @@ -321,6 +332,7 @@ void pa_create_stream_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED if (s->direction == PA_STREAM_RECORD) { assert(!s->record_memblockq); + s->record_memblockq = pa_memblockq_new( 0, s->buffer_attr.maxlength, @@ -330,12 +342,10 @@ void pa_create_stream_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED 0, NULL, s->context->memblock_stat); - assert(s->record_memblockq); } s->channel_valid = 1; pa_dynarray_put((s->direction == PA_STREAM_RECORD) ? s->context->record_streams : s->context->playback_streams, s->channel, s); - pa_stream_set_state(s, PA_STREAM_READY); if (s->interpolate) { struct timeval tv; @@ -348,7 +358,9 @@ void pa_create_stream_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED s->ipol_event = s->mainloop->time_new(s->mainloop, &tv, &ipol_callback, s); } - if (s->requested_bytes && s->ref > 1 && s->write_callback) + pa_stream_set_state(s, PA_STREAM_READY); + + if (s->requested_bytes > 0 && s->ref > 1 && s->write_callback) s->write_callback(s, s->requested_bytes, s->write_userdata); finish: @@ -371,8 +383,10 @@ static int create_stream( assert(s->ref >= 1); PA_CHECK_VALIDITY(s->context, s->state == PA_STREAM_UNCONNECTED, PA_ERR_BADSTATE); - PA_CHECK_VALIDITY(s->context, (flags & ~(PA_STREAM_START_CORKED|PA_STREAM_INTERPOLATE_LATENCY)) == 0, PA_ERR_INVALID); + PA_CHECK_VALIDITY(s->context, !(flags & ~(PA_STREAM_START_CORKED|PA_STREAM_INTERPOLATE_LATENCY)), PA_ERR_INVALID); PA_CHECK_VALIDITY(s->context, direction == PA_STREAM_PLAYBACK || flags == 0, PA_ERR_INVALID); + PA_CHECK_VALIDITY(s->context, !volume || volume->channels == s->sample_spec.channels, PA_ERR_INVALID); + PA_CHECK_VALIDITY(s->context, !sync_stream || (direction == PA_STREAM_PLAYBACK && sync_stream->direction == PA_STREAM_PLAYBACK), PA_ERR_INVALID); pa_stream_ref(s); @@ -395,17 +409,10 @@ static int create_stream( s->buffer_attr.fragsize = s->buffer_attr.tlength/100; } - pa_stream_set_state(s, PA_STREAM_CREATING); - t = pa_tagstruct_new(NULL, 0); - assert(t); - if (!dev) { - if (s->direction == PA_STREAM_PLAYBACK) - dev = s->context->conf->default_sink; - else - dev = s->context->conf->default_source; - } + if (!dev) + dev = s->direction == PA_STREAM_PLAYBACK ? s->context->conf->default_sink : s->context->conf->default_source; pa_tagstruct_put( t, @@ -422,6 +429,7 @@ static int create_stream( if (s->direction == PA_STREAM_PLAYBACK) { pa_cvolume cv; + pa_tagstruct_put( t, PA_TAG_U32, s->buffer_attr.tlength, @@ -430,10 +438,8 @@ static int create_stream( PA_TAG_U32, s->syncid, PA_TAG_INVALID); - if (!volume) { - pa_cvolume_reset(&cv, s->sample_spec.channels); - volume = &cv; - } + if (!volume) + volume = pa_cvolume_reset(&cv, s->sample_spec.channels); pa_tagstruct_put_cvolume(t, volume); } else @@ -442,6 +448,8 @@ static int create_stream( pa_pstream_send_tagstruct(s->context->pstream, t); pa_pdispatch_register_reply(s->context->pdispatch, tag, DEFAULT_TIMEOUT, pa_create_stream_callback, s); + pa_stream_set_state(s, PA_STREAM_CREATING); + pa_stream_unref(s); return 0; } @@ -484,7 +492,6 @@ int pa_stream_write( assert(s); assert(s->ref >= 1); - assert(s->context); assert(data); PA_CHECK_VALIDITY(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE); @@ -495,14 +502,13 @@ int pa_stream_write( if (length <= 0) return 0; - if (free_cb) { + if (free_cb) chunk.memblock = pa_memblock_new_user((void*) data, length, free_cb, 1, s->context->memblock_stat); - assert(chunk.memblock && chunk.memblock->data); - } else { + else { chunk.memblock = pa_memblock_new(length, s->context->memblock_stat); - assert(chunk.memblock && chunk.memblock->data); memcpy(chunk.memblock->data, data, length); } + chunk.index = 0; chunk.length = length; @@ -580,7 +586,7 @@ size_t pa_stream_readable_size(pa_stream *s) { return pa_memblockq_get_length(s->record_memblockq); } -pa_operation * pa_stream_drain(pa_stream *s, void (*cb) (pa_stream*s, int success, void *userdata), void *userdata) { +pa_operation * pa_stream_drain(pa_stream *s, pa_stream_success_cb_t cb, void *userdata) { pa_operation *o; pa_tagstruct *t; uint32_t tag; @@ -591,9 +597,7 @@ pa_operation * pa_stream_drain(pa_stream *s, void (*cb) (pa_stream*s, int succes PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->direction == PA_STREAM_PLAYBACK, PA_ERR_BADSTATE); - o = pa_operation_new(s->context, s); - o->callback = (pa_operation_callback_t) cb; - o->userdata = userdata; + o = pa_operation_new(s->context, s, (pa_operation_cb_t) cb, userdata); t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, PA_COMMAND_DRAIN_PLAYBACK_STREAM); @@ -609,7 +613,11 @@ static void stream_get_latency_info_callback(pa_pdispatch *pd, uint32_t command, pa_operation *o = userdata; pa_latency_info i, *p = NULL; struct timeval local, remote, now; - assert(pd && o && o->stream && o->context); + + assert(pd); + assert(o); + assert(o->stream); + assert(o->context); if (command != PA_COMMAND_REPLY) { if (pa_context_handle_error(o->context, command, t) < 0) @@ -658,7 +666,7 @@ static void stream_get_latency_info_callback(pa_pdispatch *pd, uint32_t command, } if (o->callback) { - void (*cb)(pa_stream *s, const pa_latency_info *_i, void *_userdata) = (void (*)(pa_stream *s, const pa_latency_info *_i, void *_userdata)) o->callback; + pa_stream_get_latency_info_cb_t cb = (pa_stream_get_latency_info_cb_t) o->callback; cb(o->stream, p, o->userdata); } @@ -667,7 +675,7 @@ finish: pa_operation_unref(o); } -pa_operation* pa_stream_get_latency_info(pa_stream *s, void (*cb)(pa_stream *p, const pa_latency_info*i, void *userdata), void *userdata) { +pa_operation* pa_stream_get_latency_info(pa_stream *s, pa_stream_get_latency_info_cb_t cb, void *userdata) { uint32_t tag; pa_operation *o; pa_tagstruct *t; @@ -679,9 +687,7 @@ pa_operation* pa_stream_get_latency_info(pa_stream *s, void (*cb)(pa_stream *p, PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->direction != PA_STREAM_UPLOAD, PA_ERR_BADSTATE); - o = pa_operation_new(s->context, s); - o->callback = (pa_operation_callback_t) cb; - o->userdata = userdata; + o = pa_operation_new(s->context, s, (pa_operation_cb_t) cb, userdata); t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_GET_PLAYBACK_LATENCY : PA_COMMAND_GET_RECORD_LATENCY); @@ -700,7 +706,10 @@ pa_operation* pa_stream_get_latency_info(pa_stream *s, void (*cb)(pa_stream *p, void pa_stream_disconnect_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { pa_stream *s = userdata; - assert(pd && s && s->ref >= 1); + + assert(pd); + assert(s); + assert(s->ref >= 1); pa_stream_ref(s); @@ -789,7 +798,11 @@ void pa_stream_set_underflow_callback(pa_stream *s, pa_stream_notify_cb_t cb, vo void pa_stream_simple_ack_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { pa_operation *o = userdata; int success = 1; - assert(pd && o && o->context && o->ref >= 1); + + assert(pd); + assert(o); + assert(o->context); + assert(o->ref >= 1); if (command != PA_COMMAND_REPLY) { if (pa_context_handle_error(o->context, command, t) < 0) @@ -802,7 +815,7 @@ void pa_stream_simple_ack_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UN } if (o->callback) { - void (*cb)(pa_stream *s, int _success, void *_userdata) = (void (*)(pa_stream *s, int _success, void *_userdata)) o->callback; + pa_stream_success_cb_t cb = (pa_stream_success_cb_t) o->callback; cb(o->stream, success, o->userdata); } @@ -811,11 +824,16 @@ finish: pa_operation_unref(o); } -pa_operation* pa_stream_cork(pa_stream *s, int b, void (*cb) (pa_stream*s, int success, void *userdata), void *userdata) { +pa_operation* pa_stream_cork(pa_stream *s, int b, pa_stream_success_cb_t cb, void *userdata) { pa_operation *o; pa_tagstruct *t; uint32_t tag; - assert(s && s->ref >= 1 && s->state == PA_STREAM_READY); + + assert(s); + assert(s->ref >= 1); + + PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE); + PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->direction != PA_STREAM_UPLOAD, PA_ERR_BADSTATE); if (s->interpolate) { if (!s->corked && b) @@ -828,13 +846,9 @@ pa_operation* pa_stream_cork(pa_stream *s, int b, void (*cb) (pa_stream*s, int s s->corked = b; - o = pa_operation_new(s->context, s); - assert(o); - o->callback = (pa_operation_callback_t) cb; - o->userdata = userdata; + o = pa_operation_new(s->context, s, (pa_operation_cb_t) cb, userdata); t = pa_tagstruct_new(NULL, 0); - assert(t); pa_tagstruct_putu32(t, s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_CORK_PLAYBACK_STREAM : PA_COMMAND_CORK_RECORD_STREAM); pa_tagstruct_putu32(t, tag = s->context->ctag++); pa_tagstruct_putu32(t, s->channel); @@ -847,15 +861,17 @@ pa_operation* pa_stream_cork(pa_stream *s, int b, void (*cb) (pa_stream*s, int s return pa_operation_ref(o); } -static pa_operation* stream_send_simple_command(pa_stream *s, uint32_t command, void (*cb)(pa_stream *s, int success, void *userdata), void *userdata) { +static pa_operation* stream_send_simple_command(pa_stream *s, uint32_t command, pa_stream_success_cb_t cb, void *userdata) { pa_tagstruct *t; pa_operation *o; uint32_t tag; - assert(s && s->ref >= 1 && s->state == PA_STREAM_READY); - o = pa_operation_new(s->context, s); - o->callback = (pa_operation_callback_t) cb; - o->userdata = userdata; + assert(s); + assert(s->ref >= 1); + + PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE); + + o = pa_operation_new(s->context, s, (pa_operation_cb_t) cb, userdata); t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, command); @@ -867,40 +883,54 @@ static pa_operation* stream_send_simple_command(pa_stream *s, uint32_t command, return pa_operation_ref(o); } -pa_operation* pa_stream_flush(pa_stream *s, void (*cb)(pa_stream *s, int success, void *userdata), void *userdata) { +pa_operation* pa_stream_flush(pa_stream *s, pa_stream_success_cb_t cb, void *userdata) { pa_operation *o; - o = stream_send_simple_command(s, s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_FLUSH_PLAYBACK_STREAM : PA_COMMAND_FLUSH_RECORD_STREAM, cb, userdata); - pa_operation_unref(pa_stream_get_latency_info(s, NULL, NULL)); + + PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->direction != PA_STREAM_UPLOAD, PA_ERR_BADSTATE); + + if ((o = stream_send_simple_command(s, s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_FLUSH_PLAYBACK_STREAM : PA_COMMAND_FLUSH_RECORD_STREAM, cb, userdata))) + pa_operation_unref(pa_stream_get_latency_info(s, NULL, NULL)); + return o; } -pa_operation* pa_stream_prebuf(pa_stream *s, void (*cb)(pa_stream *s, int success, void *userdata), void *userdata) { +pa_operation* pa_stream_prebuf(pa_stream *s, pa_stream_success_cb_t cb, void *userdata) { pa_operation *o; - o = stream_send_simple_command(s, PA_COMMAND_PREBUF_PLAYBACK_STREAM, cb, userdata); - pa_operation_unref(pa_stream_get_latency_info(s, NULL, NULL)); + + PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->direction == PA_STREAM_PLAYBACK, PA_ERR_BADSTATE); + + if ((o = stream_send_simple_command(s, PA_COMMAND_PREBUF_PLAYBACK_STREAM, cb, userdata))) + pa_operation_unref(pa_stream_get_latency_info(s, NULL, NULL)); + return o; } -pa_operation* pa_stream_trigger(pa_stream *s, void (*cb)(pa_stream *s, int success, void *userdata), void *userdata) { +pa_operation* pa_stream_trigger(pa_stream *s, pa_stream_success_cb_t cb, void *userdata) { pa_operation *o; - o = stream_send_simple_command(s, PA_COMMAND_TRIGGER_PLAYBACK_STREAM, cb, userdata); - pa_operation_unref(pa_stream_get_latency_info(s, NULL, NULL)); + + PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->direction == PA_STREAM_PLAYBACK, PA_ERR_BADSTATE); + + if ((o = stream_send_simple_command(s, PA_COMMAND_TRIGGER_PLAYBACK_STREAM, cb, userdata))) + pa_operation_unref(pa_stream_get_latency_info(s, NULL, NULL)); + return o; } -pa_operation* pa_stream_set_name(pa_stream *s, const char *name, void(*cb)(pa_stream*c, int success, void *userdata), void *userdata) { +pa_operation* pa_stream_set_name(pa_stream *s, const char *name, pa_stream_success_cb_t cb, void *userdata) { pa_operation *o; pa_tagstruct *t; uint32_t tag; - assert(s && s->ref >= 1 && s->state == PA_STREAM_READY && name && s->direction != PA_STREAM_UPLOAD); + + assert(s); + assert(s->ref >= 1); + assert(name); - o = pa_operation_new(s->context, s); - assert(o); - o->callback = (pa_operation_callback_t) cb; - o->userdata = userdata; + PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE); + PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->direction != PA_STREAM_UPLOAD, PA_ERR_BADSTATE); + + o = pa_operation_new(s->context, s, (pa_operation_cb_t) cb, userdata); t = pa_tagstruct_new(NULL, 0); - assert(t); pa_tagstruct_putu32(t, s->direction == PA_STREAM_RECORD ? PA_COMMAND_SET_RECORD_STREAM_NAME : PA_COMMAND_SET_PLAYBACK_STREAM_NAME); pa_tagstruct_putu32(t, tag = s->context->ctag++); pa_tagstruct_putu32(t, s->channel); @@ -913,12 +943,21 @@ pa_operation* pa_stream_set_name(pa_stream *s, const char *name, void(*cb)(pa_st uint64_t pa_stream_get_counter(pa_stream *s) { assert(s); + assert(s->ref >= 1); + + PA_CHECK_VALIDITY_RETURN_ANY(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE, (uint64_t) -1); + return s->counter; } pa_usec_t pa_stream_get_time(pa_stream *s, const pa_latency_info *i) { pa_usec_t usec; + assert(s); + assert(s->ref >= 1); + + PA_CHECK_VALIDITY_RETURN_ANY(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE, (pa_usec_t) -1); + PA_CHECK_VALIDITY_RETURN_ANY(s->context, s->direction != PA_STREAM_UPLOAD, PA_ERR_BADSTATE, (pa_usec_t) -1); usec = pa_bytes_to_usec(i->counter, &s->sample_spec); @@ -950,6 +989,7 @@ pa_usec_t pa_stream_get_time(pa_stream *s, const pa_latency_info *i) { static pa_usec_t time_counter_diff(pa_stream *s, pa_usec_t t, pa_usec_t c, int *negative) { assert(s); + assert(s->ref >= 1); if (negative) *negative = 0; @@ -968,8 +1008,14 @@ static pa_usec_t time_counter_diff(pa_stream *s, pa_usec_t t, pa_usec_t c, int * pa_usec_t pa_stream_get_latency(pa_stream *s, const pa_latency_info *i, int *negative) { pa_usec_t t, c; - assert(s && i); + assert(s); + assert(s->ref >= 1); + assert(i); + + PA_CHECK_VALIDITY_RETURN_ANY(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE, (pa_usec_t) -1); + PA_CHECK_VALIDITY_RETURN_ANY(s->context, s->direction != PA_STREAM_UPLOAD, PA_ERR_BADSTATE, (pa_usec_t) -1); + t = pa_stream_get_time(s, i); c = pa_bytes_to_usec(s->counter, &s->sample_spec); @@ -978,18 +1024,21 @@ pa_usec_t pa_stream_get_latency(pa_stream *s, const pa_latency_info *i, int *neg const pa_sample_spec* pa_stream_get_sample_spec(pa_stream *s) { assert(s); - + assert(s->ref >= 1); + return &s->sample_spec; } const pa_channel_map* pa_stream_get_channel_map(pa_stream *s) { assert(s); + assert(s->ref >= 1); return &s->channel_map; } void pa_stream_trash_ipol(pa_stream *s) { assert(s); + assert(s->ref >= 1); if (!s->interpolate) return; @@ -1000,8 +1049,14 @@ void pa_stream_trash_ipol(pa_stream *s) { pa_usec_t pa_stream_get_interpolated_time(pa_stream *s) { pa_usec_t usec; - assert(s && s->interpolate); + assert(s); + assert(s->ref >= 1); + + PA_CHECK_VALIDITY_RETURN_ANY(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE, (pa_usec_t) -1); + PA_CHECK_VALIDITY_RETURN_ANY(s->context, s->direction != PA_STREAM_UPLOAD, PA_ERR_BADSTATE, (pa_usec_t) -1); + PA_CHECK_VALIDITY_RETURN_ANY(s->context, s->interpolate, PA_ERR_BADSTATE, (pa_usec_t) -1); + if (s->corked) usec = s->ipol_usec; else { @@ -1021,8 +1076,14 @@ pa_usec_t pa_stream_get_interpolated_time(pa_stream *s) { pa_usec_t pa_stream_get_interpolated_latency(pa_stream *s, int *negative) { pa_usec_t t, c; - assert(s && s->interpolate); + assert(s); + assert(s->ref >= 1); + + PA_CHECK_VALIDITY_RETURN_ANY(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE, (pa_usec_t) -1); + PA_CHECK_VALIDITY_RETURN_ANY(s->context, s->direction != PA_STREAM_UPLOAD, PA_ERR_BADSTATE, (pa_usec_t) -1); + PA_CHECK_VALIDITY_RETURN_ANY(s->context, s->interpolate, PA_ERR_BADSTATE, (pa_usec_t) -1); + t = pa_stream_get_interpolated_time(s); c = pa_bytes_to_usec(s->counter, &s->sample_spec); return time_counter_diff(s, t, c, negative); diff --git a/src/polyp/subscribe.c b/src/polyp/subscribe.c index 97f76cb79..65849b6d4 100644 --- a/src/polyp/subscribe.c +++ b/src/polyp/subscribe.c @@ -37,7 +37,11 @@ void pa_command_subscribe_event(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSE pa_context *c = userdata; pa_subscription_event_type_t e; uint32_t index; - assert(pd && command == PA_COMMAND_SUBSCRIBE_EVENT && t && c); + + assert(pd); + assert(command == PA_COMMAND_SUBSCRIBE_EVENT); + assert(t); + assert(c); pa_context_ref(c); @@ -60,24 +64,28 @@ pa_operation* pa_context_subscribe(pa_context *c, pa_subscription_mask_t m, pa_c pa_operation *o; pa_tagstruct *t; uint32_t tag; + assert(c); + assert(c->ref >= 1); - o = pa_operation_new(c, NULL); - o->callback = (pa_operation_callback_t) cb; - o->userdata = userdata; + PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, PA_COMMAND_SUBSCRIBE); pa_tagstruct_putu32(t, tag = c->ctag++); pa_tagstruct_putu32(t, m); pa_pstream_send_tagstruct(c->pstream, t); - pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, o); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o)); - return pa_operation_ref(o); + return o; } void pa_context_set_subscribe_callback(pa_context *c, pa_context_subscribe_cb_t cb, void *userdata) { assert(c); + assert(c->ref >= 1); + c->subscribe_callback = cb; c->subscribe_userdata = userdata; } diff --git a/src/polypcore/iochannel.c b/src/polypcore/iochannel.c index c33f593ed..89b061c27 100644 --- a/src/polypcore/iochannel.c +++ b/src/polypcore/iochannel.c @@ -40,7 +40,7 @@ struct pa_iochannel { int ifd, ofd; pa_mainloop_api* mainloop; - pa_iochannel_callback_t callback; + pa_iochannel_cb_t callback; void*userdata; int readable; @@ -242,7 +242,7 @@ ssize_t pa_iochannel_read(pa_iochannel*io, void*data, size_t l) { return r; } -void pa_iochannel_set_callback(pa_iochannel*io, pa_iochannel_callback_t _callback, void *userdata) { +void pa_iochannel_set_callback(pa_iochannel*io, pa_iochannel_cb_t _callback, void *userdata) { assert(io); io->callback = _callback; diff --git a/src/polypcore/iochannel.h b/src/polypcore/iochannel.h index 7d355d8f0..977fe2c36 100644 --- a/src/polypcore/iochannel.h +++ b/src/polypcore/iochannel.h @@ -57,8 +57,8 @@ int pa_iochannel_is_hungup(pa_iochannel*io); void pa_iochannel_set_noclose(pa_iochannel*io, int b); /* Set the callback function that is called whenever data becomes available for read or write */ -typedef void (*pa_iochannel_callback_t)(pa_iochannel*io, void *userdata); -void pa_iochannel_set_callback(pa_iochannel*io, pa_iochannel_callback_t callback, void *userdata); +typedef void (*pa_iochannel_cb_t)(pa_iochannel*io, void *userdata); +void pa_iochannel_set_callback(pa_iochannel*io, pa_iochannel_cb_t callback, void *userdata); /* In case the file descriptor is a socket, return a pretty-printed string in *s which describes the peer connected */ void pa_iochannel_socket_peer_to_string(pa_iochannel*io, char*s, size_t l); diff --git a/src/polypcore/pdispatch.c b/src/polypcore/pdispatch.c index fbb1b6974..c082b8cc5 100644 --- a/src/polypcore/pdispatch.c +++ b/src/polypcore/pdispatch.c @@ -94,7 +94,7 @@ static const char *command_names[PA_COMMAND_MAX] = { struct reply_info { pa_pdispatch *pdispatch; PA_LLIST_FIELDS(struct reply_info); - pa_pdispatch_callback_t callback; + pa_pdispatch_cb_t callback; void *userdata; uint32_t tag; pa_time_event *time_event; @@ -103,7 +103,7 @@ struct reply_info { struct pa_pdispatch { int ref; pa_mainloop_api *mainloop; - const pa_pdispatch_callback_t *callback_table; + const pa_pdispatch_cb_t *callback_table; unsigned n_commands; PA_LLIST_HEAD(struct reply_info, replies); pa_pdispatch_drain_callback drain_callback; @@ -121,7 +121,7 @@ static void reply_info_free(struct reply_info *r) { pa_xfree(r); } -pa_pdispatch* pa_pdispatch_new(pa_mainloop_api *mainloop, const pa_pdispatch_callback_t*table, unsigned entries) { +pa_pdispatch* pa_pdispatch_new(pa_mainloop_api *mainloop, const pa_pdispatch_cb_t*table, unsigned entries) { pa_pdispatch *pd; assert(mainloop); @@ -149,7 +149,7 @@ static void pdispatch_free(pa_pdispatch *pd) { } static void run_action(pa_pdispatch *pd, struct reply_info *r, uint32_t command, pa_tagstruct *ts) { - pa_pdispatch_callback_t callback; + pa_pdispatch_cb_t callback; void *userdata; uint32_t tag; assert(r); @@ -210,7 +210,7 @@ int pa_pdispatch_run(pa_pdispatch *pd, pa_packet*packet, void *userdata) { run_action(pd, r, command, ts); } else if (pd->callback_table && (command < pd->n_commands) && pd->callback_table[command]) { - const pa_pdispatch_callback_t *c = pd->callback_table+command; + const pa_pdispatch_cb_t *c = pd->callback_table+command; (*c)(pd, command, tag, ts, userdata); } else { @@ -236,7 +236,7 @@ static void timeout_callback(pa_mainloop_api*m, pa_time_event*e, PA_GCC_UNUSED c run_action(r->pdispatch, r, PA_COMMAND_TIMEOUT, NULL); } -void pa_pdispatch_register_reply(pa_pdispatch *pd, uint32_t tag, int timeout, pa_pdispatch_callback_t cb, void *userdata) { +void pa_pdispatch_register_reply(pa_pdispatch *pd, uint32_t tag, int timeout, pa_pdispatch_cb_t cb, void *userdata) { struct reply_info *r; struct timeval tv; assert(pd && pd->ref >= 1 && cb); diff --git a/src/polypcore/pdispatch.h b/src/polypcore/pdispatch.h index 27d2d61f9..31533d57f 100644 --- a/src/polypcore/pdispatch.h +++ b/src/polypcore/pdispatch.h @@ -29,15 +29,15 @@ typedef struct pa_pdispatch pa_pdispatch; -typedef void (*pa_pdispatch_callback_t)(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); +typedef void (*pa_pdispatch_cb_t)(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -pa_pdispatch* pa_pdispatch_new(pa_mainloop_api *m, const pa_pdispatch_callback_t*table, unsigned entries); +pa_pdispatch* pa_pdispatch_new(pa_mainloop_api *m, const pa_pdispatch_cb_t*table, unsigned entries); void pa_pdispatch_unref(pa_pdispatch *pd); pa_pdispatch* pa_pdispatch_ref(pa_pdispatch *pd); int pa_pdispatch_run(pa_pdispatch *pd, pa_packet*p, void *userdata); -void pa_pdispatch_register_reply(pa_pdispatch *pd, uint32_t tag, int timeout, pa_pdispatch_callback_t callback, void *userdata); +void pa_pdispatch_register_reply(pa_pdispatch *pd, uint32_t tag, int timeout, pa_pdispatch_cb_t callback, void *userdata); int pa_pdispatch_is_pending(pa_pdispatch *pd); diff --git a/src/polypcore/protocol-native.c b/src/polypcore/protocol-native.c index 21800e6c5..1bca1c1ed 100644 --- a/src/polypcore/protocol-native.c +++ b/src/polypcore/protocol-native.c @@ -174,7 +174,7 @@ static void command_get_autoload_info_list(pa_pdispatch *pd, uint32_t command, u static void command_cork_record_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); static void command_flush_record_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -static const pa_pdispatch_callback_t command_table[PA_COMMAND_MAX] = { +static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = { [PA_COMMAND_ERROR] = NULL, [PA_COMMAND_TIMEOUT] = NULL, [PA_COMMAND_REPLY] = NULL, diff --git a/src/polypcore/tagstruct.h b/src/polypcore/tagstruct.h index 59db67b07..0ed751710 100644 --- a/src/polypcore/tagstruct.h +++ b/src/polypcore/tagstruct.h @@ -51,8 +51,6 @@ enum { PA_TAG_CVOLUME = 'v' }; - - pa_tagstruct *pa_tagstruct_new(const uint8_t* data, size_t length); void pa_tagstruct_free(pa_tagstruct*t); uint8_t* pa_tagstruct_free_data(pa_tagstruct*t, size_t *l); diff --git a/src/utils/pactl.c b/src/utils/pactl.c index e3305f0f5..86c4e7be1 100644 --- a/src/utils/pactl.c +++ b/src/utils/pactl.c @@ -559,7 +559,7 @@ static void context_state_callback(pa_context *c, void *userdata) { break; case EXIT: - pa_context_exit_daemon(c); + pa_operation_unref(pa_context_exit_daemon(c, NULL, NULL)); drain(); case LIST: -- 2.34.1