* 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
This commit is contained in:
Lennart Poettering 2006-02-20 22:41:02 +00:00
parent 98cb6aa4a3
commit 71b3bff681
20 changed files with 784 additions and 515 deletions

View file

@ -12,6 +12,7 @@ Fixes:
- don't build ipv4 and ipv6 modules seperately - don't build ipv4 and ipv6 modules seperately
- change pa_log to not require \n - change pa_log to not require \n
- proper use of memcpy in procotol-esound.c so we don't get alignment problems - proper use of memcpy in procotol-esound.c so we don't get alignment problems
- sigpipe
Features: Features:
- add radio module - add radio module

View file

@ -47,8 +47,8 @@ AM_CFLAGS = -I$(top_srcdir)/src
AM_CFLAGS += $(PTHREAD_CFLAGS) -D_POSIX_PTHREAD_SEMANTICS AM_CFLAGS += $(PTHREAD_CFLAGS) -D_POSIX_PTHREAD_SEMANTICS
AM_CFLAGS += $(LTDLINCL) AM_CFLAGS += $(LTDLINCL)
AM_CFLAGS += $(LIBSAMPLERATE_CFLAGS) $(LIBSNDFILE_CFLAGS) AM_CFLAGS += $(LIBSAMPLERATE_CFLAGS) $(LIBSNDFILE_CFLAGS)
AM_CFLAGS += -DDLSEARCHPATH=\"$(modlibdir)\" #AM_CFLAGS += -DDLSEARCHPATH=\"$(modlibdir)\"
#AM_CFLAGS += -DDLSEARCHPATH=\"$(shell pwd)\" AM_CFLAGS += -DDLSEARCHPATH=\"$(shell pwd)\"
AM_CFLAGS += -DDEFAULT_CONFIG_DIR=\"$(DEFAULT_CONFIG_DIR)\" AM_CFLAGS += -DDEFAULT_CONFIG_DIR=\"$(DEFAULT_CONFIG_DIR)\"
AM_CFLAGS += -DPOLYPAUDIO_BINARY=\"$(POLYPAUDIO_BINARY)\" AM_CFLAGS += -DPOLYPAUDIO_BINARY=\"$(POLYPAUDIO_BINARY)\"

View file

@ -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); static void command_request(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
#endif #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 #ifdef TUNNEL_SINK
[PA_COMMAND_REQUEST] = command_request, [PA_COMMAND_REQUEST] = command_request,
#endif #endif

View file

@ -72,7 +72,7 @@
#define AUTOSPAWN_LOCK "autospawn.lock" #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_REQUEST] = pa_command_request,
[PA_COMMAND_OVERFLOW] = pa_command_overflow_or_underflow, [PA_COMMAND_OVERFLOW] = pa_command_overflow_or_underflow,
[PA_COMMAND_UNDERFLOW] = 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 *pa_context_new(pa_mainloop_api *mainloop, const char *name) {
pa_context *c; 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->ref = 1;
c->name = pa_xstrdup(name); c->name = pa_xstrdup(name);
c->mainloop = mainloop; c->mainloop = mainloop;
@ -106,7 +108,6 @@ pa_context *pa_context_new(pa_mainloop_api *mainloop, const char *name) {
c->pdispatch = NULL; c->pdispatch = NULL;
c->playback_streams = pa_dynarray_new(); c->playback_streams = pa_dynarray_new();
c->record_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_stream, c->streams);
PA_LLIST_HEAD_INIT(pa_operation, c->operations); 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) { pa_context* pa_context_ref(pa_context *c) {
assert(c && c->ref >= 1); assert(c);
assert(c->ref >= 1);
c->ref++; c->ref++;
return c; return c;
} }
void pa_context_unref(pa_context *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); context_free(c);
} }
void pa_context_set_state(pa_context *c, pa_context_state_t st) { void pa_context_set_state(pa_context *c, pa_context_state_t st) {
assert(c); assert(c);
assert(c->ref >= 1);
if (c->state == st) if (c->state == st)
return; 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) { void pa_context_fail(pa_context *c, int error) {
assert(c); assert(c);
assert(c->ref >= 1);
pa_context_set_error(c, error); pa_context_set_error(c, error);
pa_context_set_state(c, PA_CONTEXT_FAILED); pa_context_set_state(c, PA_CONTEXT_FAILED);
} }
int pa_context_set_error(pa_context *c, int error) { 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) if (c)
c->error = error; 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) { static void pstream_die_callback(pa_pstream *p, void *userdata) {
pa_context *c = userdata; pa_context *c = userdata;
assert(p && c);
assert(p);
assert(c);
pa_context_fail(c, PA_ERR_CONNECTIONTERMINATED); pa_context_fail(c, PA_ERR_CONNECTIONTERMINATED);
} }
static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, void *userdata) { static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, void *userdata) {
pa_context *c = userdata; pa_context *c = userdata;
assert(p && packet && c);
assert(p);
assert(packet);
assert(c);
pa_context_ref(c); pa_context_ref(c);
if (pa_pdispatch_run(c->pdispatch, packet, c) < 0) { if (pa_pdispatch_run(c->pdispatch, packet, c) < 0)
pa_log(__FILE__": invalid packet.\n");
pa_context_fail(c, PA_ERR_PROTOCOL); pa_context_fail(c, PA_ERR_PROTOCOL);
}
pa_context_unref(c); 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->memblock);
assert(chunk->length); assert(chunk->length);
assert(c); assert(c);
assert(c->ref >= 1);
pa_context_ref(c); 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) { int pa_context_handle_error(pa_context *c, uint32_t command, pa_tagstruct *t) {
assert(c); assert(c);
assert(c->ref >= 1);
if (command == PA_COMMAND_ERROR) { if (command == PA_COMMAND_ERROR) {
assert(t); 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) { static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_context *c = 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); pa_context_ref(c);
@ -364,13 +380,14 @@ finish:
static void setup_context(pa_context *c, pa_iochannel *io) { static void setup_context(pa_context *c, pa_iochannel *io) {
pa_tagstruct *t; pa_tagstruct *t;
uint32_t tag; uint32_t tag;
assert(c && io);
assert(c);
assert(io);
pa_context_ref(c); pa_context_ref(c);
assert(!c->pstream); assert(!c->pstream);
c->pstream = pa_pstream_new(c->mainloop, io, c->memblock_stat); 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_die_callback(c->pstream, pstream_die_callback, c);
pa_pstream_set_recieve_packet_callback(c->pstream, pstream_packet_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); assert(!c->pdispatch);
c->pdispatch = pa_pdispatch_new(c->mainloop, command_table, PA_COMMAND_MAX); c->pdispatch = pa_pdispatch_new(c->mainloop, command_table, PA_COMMAND_MAX);
assert(c->pdispatch);
if (!c->conf->cookie_valid) { if (!c->conf->cookie_valid) {
pa_context_fail(c, PA_ERR_AUTHKEY); 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); t = pa_tagstruct_new(NULL, 0);
assert(t);
pa_tagstruct_putu32(t, PA_COMMAND_AUTH); pa_tagstruct_putu32(t, PA_COMMAND_AUTH);
pa_tagstruct_putu32(t, tag = c->ctag++); pa_tagstruct_putu32(t, tag = c->ctag++);
pa_tagstruct_put_arbitrary(t, c->conf->cookie, sizeof(c->conf->cookie)); 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) { static int try_next_connection(pa_context *c) {
char *u = NULL; char *u = NULL;
int r = -1; int r = -1;
assert(c && !c->client);
assert(c);
assert(!c->client);
for (;;) { for (;;) {
if (u) pa_xfree(u);
pa_xfree(u);
u = NULL; u = NULL;
c->server_list = pa_strlist_pop(c->server_list, &u); c->server_list = pa_strlist_pop(c->server_list, &u);
@ -560,15 +576,17 @@ static int try_next_connection(pa_context *c) {
r = 0; r = 0;
finish: finish:
if (u) pa_xfree(u);
pa_xfree(u);
return r; return r;
} }
static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userdata) { static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userdata) {
pa_context *c = 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); pa_context_ref(c);
@ -593,9 +611,19 @@ finish:
pa_context_unref(c); 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; 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) if (!server)
server = c->conf->default_server; server = c->conf->default_server;
@ -658,27 +686,36 @@ finish:
void pa_context_disconnect(pa_context *c) { void pa_context_disconnect(pa_context *c) {
assert(c); assert(c);
assert(c->ref >= 1);
pa_context_set_state(c, PA_CONTEXT_TERMINATED); pa_context_set_state(c, PA_CONTEXT_TERMINATED);
} }
pa_context_state_t pa_context_get_state(pa_context *c) { 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; return c->state;
} }
int pa_context_errno(pa_context *c) { int pa_context_errno(pa_context *c) {
assert(c && c->ref >= 1); assert(c);
assert(c->ref >= 1);
return c->error; return c->error;
} }
void pa_context_set_state_callback(pa_context *c, pa_context_notify_cb_t cb, void *userdata) { 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_callback = cb;
c->state_userdata = userdata; c->state_userdata = userdata;
} }
int pa_context_is_pending(pa_context *c) { 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("pstream: %i\n", pa_pstream_is_pending(c->pstream)); */
/* pa_log("pdispatch: %i\n", pa_pdispatch_is_pending(c->pdispatch)); */ /* 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) { static void set_dispatch_callbacks(pa_operation *o) {
int done = 1; 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_pstream_set_drain_callback(o->context->pstream, NULL, NULL);
pa_pdispatch_set_drain_callback(o->context->pdispatch, 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); pa_operation_ref(o);
else { else {
if (o->callback) { if (o->callback) {
void (*cb)(pa_context *c, void *userdata); pa_context_notify_cb_t cb = (pa_context_notify_cb_t) o->callback;
cb = (void (*)(pa_context*, void*)) o->callback;
cb(o->context, o->userdata); 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* pa_context_drain(pa_context *c, pa_context_notify_cb_t cb, void *userdata) {
pa_operation *o; pa_operation *o;
assert(c && c->ref >= 1);
assert(c);
if (c->state != PA_CONTEXT_READY) assert(c->ref >= 1);
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;
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)); set_dispatch_callbacks(pa_operation_ref(o));
return 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) { 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; pa_operation *o = userdata;
int success = 1; 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 (command != PA_COMMAND_REPLY) {
if (pa_context_handle_error(o->context, command, t) < 0) if (pa_context_handle_error(o->context, command, t) < 0)
@ -786,67 +815,95 @@ finish:
pa_operation_unref(o); 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_tagstruct *t;
pa_operation *o; pa_operation *o;
uint32_t tag; uint32_t tag;
assert(c && cb);
o = pa_operation_new(c, NULL); assert(c);
o->callback = cb; assert(c->ref >= 1);
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_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); t = pa_tagstruct_new(NULL, 0);
pa_tagstruct_putu32(t, command); pa_tagstruct_putu32(t, command);
pa_tagstruct_putu32(t, tag = c->ctag++); pa_tagstruct_putu32(t, tag = c->ctag++);
pa_pstream_send_tagstruct(c->pstream, t); 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_operation* pa_context_set_default_sink(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) {
pa_tagstruct *t; pa_tagstruct *t;
pa_operation *o; pa_operation *o;
uint32_t tag; uint32_t tag;
assert(c && cb);
assert(c);
assert(c->ref >= 1);
o = pa_operation_new(c, NULL); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
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); t = pa_tagstruct_new(NULL, 0);
pa_tagstruct_putu32(t, PA_COMMAND_SET_DEFAULT_SINK); pa_tagstruct_putu32(t, PA_COMMAND_SET_DEFAULT_SINK);
pa_tagstruct_putu32(t, tag = c->ctag++); pa_tagstruct_putu32(t, tag = c->ctag++);
pa_tagstruct_puts(t, name); pa_tagstruct_puts(t, name);
pa_pstream_send_tagstruct(c->pstream, t); 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_operation* pa_context_set_default_source(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) {
pa_tagstruct *t; pa_tagstruct *t;
pa_operation *o; pa_operation *o;
uint32_t tag; uint32_t tag;
assert(c && cb);
o = pa_operation_new(c, NULL); assert(c);
o->callback = (pa_operation_callback_t) cb; assert(c->ref >= 1);
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); t = pa_tagstruct_new(NULL, 0);
pa_tagstruct_putu32(t, PA_COMMAND_SET_DEFAULT_SOURCE); pa_tagstruct_putu32(t, PA_COMMAND_SET_DEFAULT_SOURCE);
pa_tagstruct_putu32(t, tag = c->ctag++); pa_tagstruct_putu32(t, tag = c->ctag++);
pa_tagstruct_puts(t, name); pa_tagstruct_puts(t, name);
pa_pstream_send_tagstruct(c->pstream, t); 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) { int pa_context_is_local(pa_context *c) {
assert(c); assert(c);
return c->local; 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_tagstruct *t;
pa_operation *o; pa_operation *o;
uint32_t tag; uint32_t tag;
assert(c && name && cb);
o = pa_operation_new(c, NULL); assert(c);
o->callback = (pa_operation_callback_t) cb; assert(c->ref >= 1);
o->userdata = userdata; 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); t = pa_tagstruct_new(NULL, 0);
pa_tagstruct_putu32(t, PA_COMMAND_SET_CLIENT_NAME); pa_tagstruct_putu32(t, PA_COMMAND_SET_CLIENT_NAME);
pa_tagstruct_putu32(t, tag = c->ctag++); pa_tagstruct_putu32(t, tag = c->ctag++);
pa_tagstruct_puts(t, name); pa_tagstruct_puts(t, name);
pa_pstream_send_tagstruct(c->pstream, t); 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) { 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) { const char* pa_context_get_server(pa_context *c) {
assert(c);
assert(c->ref >= 1);
if (!c->server) if (!c->server)
return NULL; return NULL;

View file

@ -95,10 +95,10 @@ void pa_context_disconnect(pa_context *c);
/** Drain the context. If there is nothing to drain, the function returns NULL */ /** 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); 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 /** Tell the daemon to exit. The returned operation is unlikely to
* connection is terminated when the daemon quits, thus this operation * complete succesfully, since the daemon probably died before
* would never complete. */ * returning a success notification */
void pa_context_exit_daemon(pa_context *c); 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 */ /** 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); pa_operation* pa_context_set_default_sink(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata);

View file

@ -128,7 +128,7 @@ struct pa_stream {
void *underflow_userdata; void *underflow_userdata;
}; };
typedef void (*pa_operation_callback_t)(void); typedef void (*pa_operation_cb_t)(void);
struct pa_operation { struct pa_operation {
int ref; int ref;
@ -138,7 +138,7 @@ struct pa_operation {
pa_operation_state_t state; pa_operation_state_t state;
void *userdata; 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); 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_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); 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_operation_done(pa_operation *o);
void pa_create_stream_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); 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)); \ return -pa_context_set_error((context), (error)); \
} while(0) } 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 { \ #define PA_CHECK_VALIDITY_RETURN_ANY(context, expression, error, value) do { \
if (!(expression)) { \ if (!(expression)) { \
@ -183,4 +177,7 @@ void pa_stream_trash_ipol(pa_stream *s);
} \ } \
} while(0) } while(0)
#define PA_CHECK_VALIDITY_RETURN_NULL(context, expression, error) PA_CHECK_VALIDITY_RETURN_ANY(context, expression, error, NULL)
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -36,11 +36,12 @@
* of a certain kind, use the pa_context_xxx_list() functions. The * of a certain kind, use the pa_context_xxx_list() functions. The
* specified callback function is called once for each entry. The * specified callback function is called once for each entry. The
* enumeration is finished by a call to the callback function with * enumeration is finished by a call to the callback function with
* is_last=1 and i=NULL. Strings referenced in pa_xxx_info structures * eol=1 and i=NULL. Strings referenced in pa_xxx_info structures and
* and the structures themselves point to internal memory that may not * the structures themselves point to internal memory that may not be
* be modified. That memory is only valid during the call to the * modified. That memory is only valid during the call to the callback
* callback function. A deep copy is required if you need this data * function. A deep copy is required if you need this data outside the
* outside the callback functions. An error is signalled by a call to * the callback function with i=NULL and is_last=0. * 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 * 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 * 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 */ const char *driver; /**< Driver name. \since 0.9 */
} pa_sink_info; } 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 */ /** 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 */ /** 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 */ /** 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 */ /** Stores information about sources */
typedef struct pa_source_info { typedef struct pa_source_info {
@ -86,14 +90,17 @@ typedef struct pa_source_info {
const char *driver; /**< Driver name \since 0.9 */ const char *driver; /**< Driver name \since 0.9 */
} pa_source_info; } 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 */ /** 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 */ /** 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 */ /** 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 */ /** Server information */
typedef struct pa_server_info { 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 */ uint32_t cookie; /**< A random cookie for identifying this instance of polypaudio. \since 0.8 */
} pa_server_info; } 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 */ /** 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 */ /** Stores information about modules */
typedef struct pa_module_info { 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 */ int auto_unload; /**< Non-zero if this is an autoloaded module */
} pa_module_info; } 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 */ /** 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 */ /** 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 */ /** Stores information about clients */
typedef struct pa_client_info { typedef struct pa_client_info {
@ -133,11 +146,14 @@ typedef struct pa_client_info {
const char *driver; /**< Driver name \since 0.9 */ const char *driver; /**< Driver name \since 0.9 */
} pa_client_info; } 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 */ /** 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 */ /** 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 */ /** Stores information about sink inputs */
typedef struct pa_sink_input_info { typedef struct pa_sink_input_info {
@ -155,11 +171,14 @@ typedef struct pa_sink_input_info {
const char *driver; /**< Driver name \since 0.9 */ const char *driver; /**< Driver name \since 0.9 */
} pa_sink_input_info; } 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 */ /** 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 */ /** 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 */ /** Stores information about source outputs */
typedef struct pa_source_output_info { typedef struct pa_source_output_info {
@ -176,20 +195,23 @@ typedef struct pa_source_output_info {
const char *driver; /**< Driver name \since 0.9 */ const char *driver; /**< Driver name \since 0.9 */
} pa_source_output_info; } 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 */ /** 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 */ /** 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 */ /** 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 */ /** 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 */ /** 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 */ /** Memory block statistics */
typedef struct pa_stat_info { 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 */ uint32_t scache_size; /**< Total size of all sample cache entries. \since 0.4 */
} pa_stat_info; } 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 */ /** 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 */ /** Stores information about sample cache entries */
typedef struct pa_sample_info { 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 */ 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; } 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 */ /** 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 */ /** 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. */ /** 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 */ /** 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 */ /** 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 */ /** 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 */ /** 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 */ /** 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 */ /** Type of an autoload entry. \since 0.5 */
typedef enum pa_autoload_type { typedef enum pa_autoload_type {
@ -255,23 +286,26 @@ typedef struct pa_autoload_info {
const char *argument; /**< Argument string for module */ const char *argument; /**< Argument string for module */
} pa_autoload_info; } pa_autoload_info;
/** Get info about a specific autoload entry. \since 0.6 */ /** Callback prototype for pa_context_get_autoload_info_by_name() and firends */
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); 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 */ /** 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_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, pa_autoload_info_cb_t cb, void *userdata);
/** Get the complete list of autoload entries. \since 0.5 */ /** 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 */ /** 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 */ /** 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 */ /** 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 PA_C_DECL_END

View file

@ -31,7 +31,7 @@
#include "operation.h" #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; pa_operation *o;
assert(c); 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->stream = s ? pa_stream_ref(s) : NULL;
o->state = PA_OPERATION_RUNNING; o->state = PA_OPERATION_RUNNING;
o->userdata = NULL; o->callback = cb;
o->callback = NULL; o->userdata = userdata;
PA_LLIST_PREPEND(pa_operation, o->context->operations, o); PA_LLIST_PREPEND(pa_operation, o->context->operations, o);
return pa_operation_ref(o); return pa_operation_ref(o);

View file

@ -34,15 +34,17 @@
#include "scache.h" #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; pa_tagstruct *t;
uint32_t tag; 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); pa_stream_ref(s);
s->state = PA_STREAM_CREATING;
s->direction = PA_STREAM_UPLOAD; s->direction = PA_STREAM_UPLOAD;
t = pa_tagstruct_new(NULL, 0); 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_pstream_send_tagstruct(s->context->pstream, t);
pa_pdispatch_register_reply(s->context->pdispatch, tag, DEFAULT_TIMEOUT, pa_create_stream_callback, s); 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); 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; pa_tagstruct *t;
uint32_t tag; uint32_t tag;
assert(s); assert(s);
if (!s->channel_valid || !s->context->state == PA_CONTEXT_READY) PA_CHECK_VALIDITY(s->context, s->channel_valid, PA_ERR_BADSTATE);
return; PA_CHECK_VALIDITY(s->context, s->context->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
pa_stream_ref(s); pa_stream_ref(s);
t = pa_tagstruct_new(NULL, 0); t = pa_tagstruct_new(NULL, 0);
assert(t);
pa_tagstruct_putu32(t, PA_COMMAND_FINISH_UPLOAD_STREAM); pa_tagstruct_putu32(t, PA_COMMAND_FINISH_UPLOAD_STREAM);
pa_tagstruct_putu32(t, tag = s->context->ctag++); pa_tagstruct_putu32(t, tag = s->context->ctag++);
pa_tagstruct_putu32(t, s->channel); 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_pdispatch_register_reply(s->context->pdispatch, tag, DEFAULT_TIMEOUT, pa_stream_disconnect_callback, s);
pa_stream_unref(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_operation *o;
pa_tagstruct *t; pa_tagstruct *t;
uint32_t tag; uint32_t tag;
assert(c && name && *name && (!dev || *dev));
o = pa_operation_new(c, NULL); assert(c);
o->callback = (pa_operation_callback_t) cb; assert(c->ref >= 1);
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);
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) if (!dev)
dev = c->conf->default_sink; dev = c->conf->default_sink;
t = pa_tagstruct_new(NULL, 0); t = pa_tagstruct_new(NULL, 0);
assert(t);
pa_tagstruct_putu32(t, PA_COMMAND_PLAY_SAMPLE); pa_tagstruct_putu32(t, PA_COMMAND_PLAY_SAMPLE);
pa_tagstruct_putu32(t, tag = c->ctag++); 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_puts(t, dev);
pa_tagstruct_putu32(t, volume); pa_tagstruct_putu32(t, volume);
pa_tagstruct_puts(t, name); pa_tagstruct_puts(t, name);
pa_pstream_send_tagstruct(c->pstream, t); 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* pa_context_remove_sample(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) {
pa_operation *o; pa_operation *o;
pa_tagstruct *t; pa_tagstruct *t;
uint32_t tag; uint32_t tag;
assert(c && name);
o = pa_operation_new(c, NULL); assert(c);
o->callback = (pa_operation_callback_t) cb; assert(c->ref >= 1);
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); t = pa_tagstruct_new(NULL, 0);
assert(t);
pa_tagstruct_putu32(t, PA_COMMAND_REMOVE_SAMPLE); pa_tagstruct_putu32(t, PA_COMMAND_REMOVE_SAMPLE);
pa_tagstruct_putu32(t, tag = c->ctag++); pa_tagstruct_putu32(t, tag = c->ctag++);
pa_tagstruct_puts(t, name); pa_tagstruct_puts(t, name);
pa_pstream_send_tagstruct(c->pstream, t); 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;
} }

View file

@ -34,11 +34,11 @@
PA_C_DECL_BEGIN PA_C_DECL_BEGIN
/** Make this stream a sample upload stream */ /** 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 /** Finish the sample upload, the stream name will become the sample name. You cancel a samp
* le upload by issuing pa_stream_disconnect() */ * 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 */ /** 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( pa_operation* pa_context_play_sample(

View file

@ -44,7 +44,7 @@ pa_stream *pa_stream_new(pa_context *c, const char *name, const pa_sample_spec *
assert(c); assert(c);
PA_CHECK_VALIDITY_RETURN_NULL(c, ss && pa_sample_spec_valid(ss), PA_ERR_INVALID); 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 = pa_xnew(pa_stream, 1);
s->ref = 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_context *c = userdata;
pa_stream *s; pa_stream *s;
uint32_t channel; 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); 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))) if (!(s = pa_dynarray_get(command == PA_COMMAND_PLAYBACK_STREAM_KILLED ? c->playback_streams : c->record_streams, channel)))
goto finish; goto finish;
c->error = PA_ERR_KILLED; pa_context_set_error(c, PA_ERR_KILLED);
pa_stream_set_state(s, PA_STREAM_FAILED); pa_stream_set_state(s, PA_STREAM_FAILED);
finish: finish:
@ -214,7 +218,11 @@ void pa_command_request(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32
pa_stream *s; pa_stream *s;
pa_context *c = userdata; pa_context *c = userdata;
uint32_t bytes, channel; 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); 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) { 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 *s = userdata;
pa_stream_ref(s); 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; s->ipol_requested = 1;
} }
pa_gettimeofday(&tv2); pa_gettimeofday(&next);
pa_timeval_add(&tv2, LATENCY_IPOL_INTERVAL_USEC); pa_timeval_add(&next, LATENCY_IPOL_INTERVAL_USEC);
m->time_restart(e, &next);
m->time_restart(e, &tv2);
pa_stream_unref(s); 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) { 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; 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); pa_stream_ref(s);
if (command != PA_COMMAND_REPLY) { 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) { if (s->direction == PA_STREAM_RECORD) {
assert(!s->record_memblockq); assert(!s->record_memblockq);
s->record_memblockq = pa_memblockq_new( s->record_memblockq = pa_memblockq_new(
0, 0,
s->buffer_attr.maxlength, s->buffer_attr.maxlength,
@ -330,12 +342,10 @@ void pa_create_stream_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED
0, 0,
NULL, NULL,
s->context->memblock_stat); s->context->memblock_stat);
assert(s->record_memblockq);
} }
s->channel_valid = 1; s->channel_valid = 1;
pa_dynarray_put((s->direction == PA_STREAM_RECORD) ? s->context->record_streams : s->context->playback_streams, s->channel, s); 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) { if (s->interpolate) {
struct timeval tv; 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); 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); s->write_callback(s, s->requested_bytes, s->write_userdata);
finish: finish:
@ -371,8 +383,10 @@ static int create_stream(
assert(s->ref >= 1); assert(s->ref >= 1);
PA_CHECK_VALIDITY(s->context, s->state == PA_STREAM_UNCONNECTED, PA_ERR_BADSTATE); 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, 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); pa_stream_ref(s);
@ -395,17 +409,10 @@ static int create_stream(
s->buffer_attr.fragsize = s->buffer_attr.tlength/100; s->buffer_attr.fragsize = s->buffer_attr.tlength/100;
} }
pa_stream_set_state(s, PA_STREAM_CREATING);
t = pa_tagstruct_new(NULL, 0); t = pa_tagstruct_new(NULL, 0);
assert(t);
if (!dev) { if (!dev)
if (s->direction == PA_STREAM_PLAYBACK) dev = s->direction == PA_STREAM_PLAYBACK ? s->context->conf->default_sink : s->context->conf->default_source;
dev = s->context->conf->default_sink;
else
dev = s->context->conf->default_source;
}
pa_tagstruct_put( pa_tagstruct_put(
t, t,
@ -422,6 +429,7 @@ static int create_stream(
if (s->direction == PA_STREAM_PLAYBACK) { if (s->direction == PA_STREAM_PLAYBACK) {
pa_cvolume cv; pa_cvolume cv;
pa_tagstruct_put( pa_tagstruct_put(
t, t,
PA_TAG_U32, s->buffer_attr.tlength, PA_TAG_U32, s->buffer_attr.tlength,
@ -430,10 +438,8 @@ static int create_stream(
PA_TAG_U32, s->syncid, PA_TAG_U32, s->syncid,
PA_TAG_INVALID); PA_TAG_INVALID);
if (!volume) { if (!volume)
pa_cvolume_reset(&cv, s->sample_spec.channels); volume = pa_cvolume_reset(&cv, s->sample_spec.channels);
volume = &cv;
}
pa_tagstruct_put_cvolume(t, volume); pa_tagstruct_put_cvolume(t, volume);
} else } else
@ -442,6 +448,8 @@ static int create_stream(
pa_pstream_send_tagstruct(s->context->pstream, t); pa_pstream_send_tagstruct(s->context->pstream, t);
pa_pdispatch_register_reply(s->context->pdispatch, tag, DEFAULT_TIMEOUT, pa_create_stream_callback, s); 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); pa_stream_unref(s);
return 0; return 0;
} }
@ -484,7 +492,6 @@ int pa_stream_write(
assert(s); assert(s);
assert(s->ref >= 1); assert(s->ref >= 1);
assert(s->context);
assert(data); assert(data);
PA_CHECK_VALIDITY(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE);
@ -495,14 +502,13 @@ int pa_stream_write(
if (length <= 0) if (length <= 0)
return 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); 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); chunk.memblock = pa_memblock_new(length, s->context->memblock_stat);
assert(chunk.memblock && chunk.memblock->data);
memcpy(chunk.memblock->data, data, length); memcpy(chunk.memblock->data, data, length);
} }
chunk.index = 0; chunk.index = 0;
chunk.length = length; chunk.length = length;
@ -580,7 +586,7 @@ size_t pa_stream_readable_size(pa_stream *s) {
return pa_memblockq_get_length(s->record_memblockq); 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_operation *o;
pa_tagstruct *t; pa_tagstruct *t;
uint32_t tag; 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->state == PA_STREAM_READY, PA_ERR_BADSTATE);
PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->direction == PA_STREAM_PLAYBACK, 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 = pa_operation_new(s->context, s, (pa_operation_cb_t) cb, userdata);
o->callback = (pa_operation_callback_t) cb;
o->userdata = userdata;
t = pa_tagstruct_new(NULL, 0); t = pa_tagstruct_new(NULL, 0);
pa_tagstruct_putu32(t, PA_COMMAND_DRAIN_PLAYBACK_STREAM); 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_operation *o = userdata;
pa_latency_info i, *p = NULL; pa_latency_info i, *p = NULL;
struct timeval local, remote, now; 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 (command != PA_COMMAND_REPLY) {
if (pa_context_handle_error(o->context, command, t) < 0) 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) { 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); cb(o->stream, p, o->userdata);
} }
@ -667,7 +675,7 @@ finish:
pa_operation_unref(o); 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; uint32_t tag;
pa_operation *o; pa_operation *o;
pa_tagstruct *t; 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->state == PA_STREAM_READY, PA_ERR_BADSTATE);
PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->direction != PA_STREAM_UPLOAD, 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 = pa_operation_new(s->context, s, (pa_operation_cb_t) cb, userdata);
o->callback = (pa_operation_callback_t) cb;
o->userdata = userdata;
t = pa_tagstruct_new(NULL, 0); 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); 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) { 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; pa_stream *s = userdata;
assert(pd && s && s->ref >= 1);
assert(pd);
assert(s);
assert(s->ref >= 1);
pa_stream_ref(s); 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) { 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; pa_operation *o = userdata;
int success = 1; 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 (command != PA_COMMAND_REPLY) {
if (pa_context_handle_error(o->context, command, t) < 0) 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) { 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); cb(o->stream, success, o->userdata);
} }
@ -811,11 +824,16 @@ finish:
pa_operation_unref(o); 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_operation *o;
pa_tagstruct *t; pa_tagstruct *t;
uint32_t tag; 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->interpolate) {
if (!s->corked && b) 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; s->corked = b;
o = pa_operation_new(s->context, s); o = pa_operation_new(s->context, s, (pa_operation_cb_t) cb, userdata);
assert(o);
o->callback = (pa_operation_callback_t) cb;
o->userdata = userdata;
t = pa_tagstruct_new(NULL, 0); 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, 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, tag = s->context->ctag++);
pa_tagstruct_putu32(t, s->channel); 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); 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_tagstruct *t;
pa_operation *o; pa_operation *o;
uint32_t tag; uint32_t tag;
assert(s && s->ref >= 1 && s->state == PA_STREAM_READY);
o = pa_operation_new(s->context, s); assert(s);
o->callback = (pa_operation_callback_t) cb; assert(s->ref >= 1);
o->userdata = userdata;
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); t = pa_tagstruct_new(NULL, 0);
pa_tagstruct_putu32(t, command); 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); 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; 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; 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; 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; 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; 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; 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_operation *o;
pa_tagstruct *t; pa_tagstruct *t;
uint32_t tag; 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); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE);
assert(o); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->direction != PA_STREAM_UPLOAD, PA_ERR_BADSTATE);
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); 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, 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, tag = s->context->ctag++);
pa_tagstruct_putu32(t, s->channel); 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) { uint64_t pa_stream_get_counter(pa_stream *s) {
assert(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; return s->counter;
} }
pa_usec_t pa_stream_get_time(pa_stream *s, const pa_latency_info *i) { pa_usec_t pa_stream_get_time(pa_stream *s, const pa_latency_info *i) {
pa_usec_t usec; pa_usec_t usec;
assert(s); 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); 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) { static pa_usec_t time_counter_diff(pa_stream *s, pa_usec_t t, pa_usec_t c, int *negative) {
assert(s); assert(s);
assert(s->ref >= 1);
if (negative) if (negative)
*negative = 0; *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 pa_stream_get_latency(pa_stream *s, const pa_latency_info *i, int *negative) {
pa_usec_t t, c; 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); t = pa_stream_get_time(s, i);
c = pa_bytes_to_usec(s->counter, &s->sample_spec); 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) { const pa_sample_spec* pa_stream_get_sample_spec(pa_stream *s) {
assert(s); assert(s);
assert(s->ref >= 1);
return &s->sample_spec; return &s->sample_spec;
} }
const pa_channel_map* pa_stream_get_channel_map(pa_stream *s) { const pa_channel_map* pa_stream_get_channel_map(pa_stream *s) {
assert(s); assert(s);
assert(s->ref >= 1);
return &s->channel_map; return &s->channel_map;
} }
void pa_stream_trash_ipol(pa_stream *s) { void pa_stream_trash_ipol(pa_stream *s) {
assert(s); assert(s);
assert(s->ref >= 1);
if (!s->interpolate) if (!s->interpolate)
return; 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 pa_stream_get_interpolated_time(pa_stream *s) {
pa_usec_t usec; 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) if (s->corked)
usec = s->ipol_usec; usec = s->ipol_usec;
else { 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 pa_stream_get_interpolated_latency(pa_stream *s, int *negative) {
pa_usec_t t, c; 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); t = pa_stream_get_interpolated_time(s);
c = pa_bytes_to_usec(s->counter, &s->sample_spec); c = pa_bytes_to_usec(s->counter, &s->sample_spec);
return time_counter_diff(s, t, c, negative); return time_counter_diff(s, t, c, negative);

View file

@ -37,7 +37,11 @@ void pa_command_subscribe_event(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSE
pa_context *c = userdata; pa_context *c = userdata;
pa_subscription_event_type_t e; pa_subscription_event_type_t e;
uint32_t index; 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); 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_operation *o;
pa_tagstruct *t; pa_tagstruct *t;
uint32_t tag; uint32_t tag;
assert(c);
o = pa_operation_new(c, NULL); assert(c);
o->callback = (pa_operation_callback_t) cb; assert(c->ref >= 1);
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); t = pa_tagstruct_new(NULL, 0);
pa_tagstruct_putu32(t, PA_COMMAND_SUBSCRIBE); pa_tagstruct_putu32(t, PA_COMMAND_SUBSCRIBE);
pa_tagstruct_putu32(t, tag = c->ctag++); pa_tagstruct_putu32(t, tag = c->ctag++);
pa_tagstruct_putu32(t, m); pa_tagstruct_putu32(t, m);
pa_pstream_send_tagstruct(c->pstream, t); 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) { void pa_context_set_subscribe_callback(pa_context *c, pa_context_subscribe_cb_t cb, void *userdata) {
assert(c); assert(c);
assert(c->ref >= 1);
c->subscribe_callback = cb; c->subscribe_callback = cb;
c->subscribe_userdata = userdata; c->subscribe_userdata = userdata;
} }

View file

@ -40,7 +40,7 @@ struct pa_iochannel {
int ifd, ofd; int ifd, ofd;
pa_mainloop_api* mainloop; pa_mainloop_api* mainloop;
pa_iochannel_callback_t callback; pa_iochannel_cb_t callback;
void*userdata; void*userdata;
int readable; int readable;
@ -242,7 +242,7 @@ ssize_t pa_iochannel_read(pa_iochannel*io, void*data, size_t l) {
return r; 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); assert(io);
io->callback = _callback; io->callback = _callback;

View file

@ -57,8 +57,8 @@ int pa_iochannel_is_hungup(pa_iochannel*io);
void pa_iochannel_set_noclose(pa_iochannel*io, int b); 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 */ /* 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); typedef void (*pa_iochannel_cb_t)(pa_iochannel*io, void *userdata);
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);
/* In case the file descriptor is a socket, return a pretty-printed string in *s which describes the peer connected */ /* 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); void pa_iochannel_socket_peer_to_string(pa_iochannel*io, char*s, size_t l);

View file

@ -94,7 +94,7 @@ static const char *command_names[PA_COMMAND_MAX] = {
struct reply_info { struct reply_info {
pa_pdispatch *pdispatch; pa_pdispatch *pdispatch;
PA_LLIST_FIELDS(struct reply_info); PA_LLIST_FIELDS(struct reply_info);
pa_pdispatch_callback_t callback; pa_pdispatch_cb_t callback;
void *userdata; void *userdata;
uint32_t tag; uint32_t tag;
pa_time_event *time_event; pa_time_event *time_event;
@ -103,7 +103,7 @@ struct reply_info {
struct pa_pdispatch { struct pa_pdispatch {
int ref; int ref;
pa_mainloop_api *mainloop; pa_mainloop_api *mainloop;
const pa_pdispatch_callback_t *callback_table; const pa_pdispatch_cb_t *callback_table;
unsigned n_commands; unsigned n_commands;
PA_LLIST_HEAD(struct reply_info, replies); PA_LLIST_HEAD(struct reply_info, replies);
pa_pdispatch_drain_callback drain_callback; pa_pdispatch_drain_callback drain_callback;
@ -121,7 +121,7 @@ static void reply_info_free(struct reply_info *r) {
pa_xfree(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; pa_pdispatch *pd;
assert(mainloop); 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) { 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; void *userdata;
uint32_t tag; uint32_t tag;
assert(r); assert(r);
@ -210,7 +210,7 @@ int pa_pdispatch_run(pa_pdispatch *pd, pa_packet*packet, void *userdata) {
run_action(pd, r, command, ts); run_action(pd, r, command, ts);
} else if (pd->callback_table && (command < pd->n_commands) && pd->callback_table[command]) { } 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); (*c)(pd, command, tag, ts, userdata);
} else { } 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); 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 reply_info *r;
struct timeval tv; struct timeval tv;
assert(pd && pd->ref >= 1 && cb); assert(pd && pd->ref >= 1 && cb);

View file

@ -29,15 +29,15 @@
typedef struct pa_pdispatch pa_pdispatch; 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); void pa_pdispatch_unref(pa_pdispatch *pd);
pa_pdispatch* pa_pdispatch_ref(pa_pdispatch *pd); pa_pdispatch* pa_pdispatch_ref(pa_pdispatch *pd);
int pa_pdispatch_run(pa_pdispatch *pd, pa_packet*p, void *userdata); 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); int pa_pdispatch_is_pending(pa_pdispatch *pd);

View file

@ -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_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 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_ERROR] = NULL,
[PA_COMMAND_TIMEOUT] = NULL, [PA_COMMAND_TIMEOUT] = NULL,
[PA_COMMAND_REPLY] = NULL, [PA_COMMAND_REPLY] = NULL,

View file

@ -51,8 +51,6 @@ enum {
PA_TAG_CVOLUME = 'v' PA_TAG_CVOLUME = 'v'
}; };
pa_tagstruct *pa_tagstruct_new(const uint8_t* data, size_t length); pa_tagstruct *pa_tagstruct_new(const uint8_t* data, size_t length);
void pa_tagstruct_free(pa_tagstruct*t); void pa_tagstruct_free(pa_tagstruct*t);
uint8_t* pa_tagstruct_free_data(pa_tagstruct*t, size_t *l); uint8_t* pa_tagstruct_free_data(pa_tagstruct*t, size_t *l);

View file

@ -559,7 +559,7 @@ static void context_state_callback(pa_context *c, void *userdata) {
break; break;
case EXIT: case EXIT:
pa_context_exit_daemon(c); pa_operation_unref(pa_context_exit_daemon(c, NULL, NULL));
drain(); drain();
case LIST: case LIST: