2 This file is part of PulseAudio.
4 Copyright 2004-2008 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
7 PulseAudio is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published
9 by the Free Software Foundation; either version 2.1 of the License,
10 or (at your option) any later version.
12 PulseAudio is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with PulseAudio; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
30 #include <sys/types.h>
38 #ifdef HAVE_SYS_WAIT_H
42 #ifdef HAVE_SYS_SOCKET_H
43 #include <sys/socket.h>
52 #include <pulse/version.h>
53 #include <pulse/xmalloc.h>
54 #include <pulse/utf8.h>
55 #include <pulse/util.h>
56 #include <pulse/i18n.h>
58 #include <pulsecore/winsock.h>
59 #include <pulsecore/core-error.h>
61 #include <pulsecore/native-common.h>
62 #include <pulsecore/pdispatch.h>
63 #include <pulsecore/pstream.h>
64 #include <pulsecore/dynarray.h>
65 #include <pulsecore/socket-client.h>
66 #include <pulsecore/pstream-util.h>
67 #include <pulsecore/core-util.h>
68 #include <pulsecore/log.h>
69 #include <pulsecore/socket-util.h>
70 #include <pulsecore/creds.h>
71 #include <pulsecore/macro.h>
72 #include <pulsecore/proplist-util.h>
76 #include "client-conf.h"
79 #include "client-conf-x11.h"
84 void pa_command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
86 static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = {
87 [PA_COMMAND_REQUEST] = pa_command_request,
88 [PA_COMMAND_OVERFLOW] = pa_command_overflow_or_underflow,
89 [PA_COMMAND_UNDERFLOW] = pa_command_overflow_or_underflow,
90 [PA_COMMAND_PLAYBACK_STREAM_KILLED] = pa_command_stream_killed,
91 [PA_COMMAND_RECORD_STREAM_KILLED] = pa_command_stream_killed,
92 [PA_COMMAND_PLAYBACK_STREAM_MOVED] = pa_command_stream_moved,
93 [PA_COMMAND_RECORD_STREAM_MOVED] = pa_command_stream_moved,
94 [PA_COMMAND_PLAYBACK_STREAM_SUSPENDED] = pa_command_stream_suspended,
95 [PA_COMMAND_RECORD_STREAM_SUSPENDED] = pa_command_stream_suspended,
96 [PA_COMMAND_STARTED] = pa_command_stream_started,
97 [PA_COMMAND_SUBSCRIBE_EVENT] = pa_command_subscribe_event,
98 [PA_COMMAND_EXTENSION] = pa_command_extension,
99 [PA_COMMAND_PLAYBACK_STREAM_EVENT] = pa_command_stream_event,
100 [PA_COMMAND_RECORD_STREAM_EVENT] = pa_command_stream_event,
101 [PA_COMMAND_CLIENT_EVENT] = pa_command_client_event
103 static void context_free(pa_context *c);
105 pa_context *pa_context_new(pa_mainloop_api *mainloop, const char *name) {
106 return pa_context_new_with_proplist(mainloop, name, NULL);
109 static void reset_callbacks(pa_context *c) {
112 c->state_callback = NULL;
113 c->state_userdata = NULL;
115 c->subscribe_callback = NULL;
116 c->subscribe_userdata = NULL;
118 c->event_callback = NULL;
119 c->event_userdata = NULL;
121 c->ext_stream_restore.callback = NULL;
122 c->ext_stream_restore.userdata = NULL;
125 pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char *name, pa_proplist *p) {
132 c = pa_xnew(pa_context, 1);
135 c->proplist = p ? pa_proplist_copy(p) : pa_proplist_new();
138 pa_proplist_sets(c->proplist, PA_PROP_APPLICATION_NAME, name);
140 c->mainloop = mainloop;
144 c->playback_streams = pa_dynarray_new();
145 c->record_streams = pa_dynarray_new();
146 c->client_index = PA_INVALID_INDEX;
148 PA_LLIST_HEAD_INIT(pa_stream, c->streams);
149 PA_LLIST_HEAD_INIT(pa_operation, c->operations);
152 c->state = PA_CONTEXT_UNCONNECTED;
159 c->server_list = NULL;
164 c->do_autospawn = FALSE;
165 memset(&c->spawn_api, 0, sizeof(c->spawn_api));
169 pa_check_signal_is_blocked(SIGPIPE);
173 c->conf = pa_client_conf_new();
175 pa_client_conf_from_x11(c->conf, NULL);
177 pa_client_conf_load(c->conf, NULL);
178 pa_client_conf_env(c->conf);
180 if (!(c->mempool = pa_mempool_new(!c->conf->disable_shm, c->conf->shm_size))) {
182 if (!c->conf->disable_shm)
183 c->mempool = pa_mempool_new(FALSE, c->conf->shm_size);
194 static void context_unlink(pa_context *c) {
199 s = c->streams ? pa_stream_ref(c->streams) : NULL;
201 pa_stream *n = s->next ? pa_stream_ref(s->next) : NULL;
202 pa_stream_set_state(s, c->state == PA_CONTEXT_FAILED ? PA_STREAM_FAILED : PA_STREAM_TERMINATED);
207 while (c->operations)
208 pa_operation_cancel(c->operations);
211 pa_pdispatch_unref(c->pdispatch);
216 pa_pstream_unlink(c->pstream);
217 pa_pstream_unref(c->pstream);
222 pa_socket_client_unref(c->client);
229 static void context_free(pa_context *c) {
234 if (c->record_streams)
235 pa_dynarray_free(c->record_streams, NULL, NULL);
236 if (c->playback_streams)
237 pa_dynarray_free(c->playback_streams, NULL, NULL);
240 pa_mempool_free(c->mempool);
243 pa_client_conf_free(c->conf);
245 pa_strlist_free(c->server_list);
248 pa_proplist_free(c->proplist);
254 pa_context* pa_context_ref(pa_context *c) {
256 pa_assert(PA_REFCNT_VALUE(c) >= 1);
262 void pa_context_unref(pa_context *c) {
264 pa_assert(PA_REFCNT_VALUE(c) >= 1);
266 if (PA_REFCNT_DEC(c) <= 0)
270 void pa_context_set_state(pa_context *c, pa_context_state_t st) {
272 pa_assert(PA_REFCNT_VALUE(c) >= 1);
281 if (c->state_callback)
282 c->state_callback(c, c->state_userdata);
284 if (st == PA_CONTEXT_FAILED || st == PA_CONTEXT_TERMINATED)
290 int pa_context_set_error(pa_context *c, int error) {
291 pa_assert(error >= 0);
292 pa_assert(error < PA_ERR_MAX);
300 void pa_context_fail(pa_context *c, int error) {
302 pa_assert(PA_REFCNT_VALUE(c) >= 1);
304 pa_context_set_error(c, error);
305 pa_context_set_state(c, PA_CONTEXT_FAILED);
308 static void pstream_die_callback(pa_pstream *p, void *userdata) {
309 pa_context *c = userdata;
314 pa_context_fail(c, PA_ERR_CONNECTIONTERMINATED);
317 static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const pa_creds *creds, void *userdata) {
318 pa_context *c = userdata;
326 if (pa_pdispatch_run(c->pdispatch, packet, creds, c) < 0)
327 pa_context_fail(c, PA_ERR_PROTOCOL);
332 static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t offset, pa_seek_mode_t seek, const pa_memchunk *chunk, void *userdata) {
333 pa_context *c = userdata;
338 pa_assert(chunk->length > 0);
340 pa_assert(PA_REFCNT_VALUE(c) >= 1);
344 if ((s = pa_dynarray_get(c->record_streams, channel))) {
346 if (chunk->memblock) {
347 pa_memblockq_seek(s->record_memblockq, offset, seek);
348 pa_memblockq_push_align(s->record_memblockq, chunk);
350 pa_memblockq_seek(s->record_memblockq, offset+chunk->length, seek);
352 if (s->read_callback) {
355 if ((l = pa_memblockq_get_length(s->record_memblockq)) > 0)
356 s->read_callback(s, l, s->read_userdata);
363 int pa_context_handle_error(pa_context *c, uint32_t command, pa_tagstruct *t, pa_bool_t fail) {
366 pa_assert(PA_REFCNT_VALUE(c) >= 1);
368 if (command == PA_COMMAND_ERROR) {
371 if (pa_tagstruct_getu32(t, &err) < 0 ||
372 !pa_tagstruct_eof(t)) {
373 pa_context_fail(c, PA_ERR_PROTOCOL);
377 } else if (command == PA_COMMAND_TIMEOUT)
378 err = PA_ERR_TIMEOUT;
380 pa_context_fail(c, PA_ERR_PROTOCOL);
385 pa_context_fail(c, PA_ERR_PROTOCOL);
389 if (err >= PA_ERR_MAX)
390 err = PA_ERR_UNKNOWN;
393 pa_context_fail(c, (int) err);
397 pa_context_set_error(c, (int) err);
402 static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
403 pa_context *c = userdata;
407 pa_assert(c->state == PA_CONTEXT_AUTHORIZING || c->state == PA_CONTEXT_SETTING_NAME);
411 if (command != PA_COMMAND_REPLY) {
412 pa_context_handle_error(c, command, t, TRUE);
417 case PA_CONTEXT_AUTHORIZING: {
419 pa_bool_t shm_on_remote = FALSE;
421 if (pa_tagstruct_getu32(t, &c->version) < 0 ||
422 !pa_tagstruct_eof(t)) {
423 pa_context_fail(c, PA_ERR_PROTOCOL);
427 /* Minimum supported version */
428 if (c->version < 8) {
429 pa_context_fail(c, PA_ERR_VERSION);
433 /* Starting with protocol version 13 the MSB of the version
434 tag reflects if shm is available for this connection or
436 if (c->version >= 13) {
437 shm_on_remote = !!(c->version & 0x80000000U);
438 c->version &= 0x7FFFFFFFU;
441 pa_log_debug("Protocol version: remote %u, local %u", c->version, PA_PROTOCOL_VERSION);
443 /* Enable shared memory support if possible */
445 if (c->version < 10 || (c->version >= 13 && !shm_on_remote))
450 /* Only enable SHM if both sides are owned by the same
451 * user. This is a security measure because otherwise
452 * data private to the user might leak. */
455 const pa_creds *creds;
456 if (!(creds = pa_pdispatch_creds(pd)) || getuid() != creds->uid)
461 pa_log_debug("Negotiated SHM: %s", pa_yes_no(c->do_shm));
462 pa_pstream_enable_shm(c->pstream, c->do_shm);
464 reply = pa_tagstruct_command(c, PA_COMMAND_SET_CLIENT_NAME, &tag);
466 if (c->version >= 13) {
467 pa_init_proplist(c->proplist);
468 pa_tagstruct_put_proplist(reply, c->proplist);
470 pa_tagstruct_puts(reply, pa_proplist_gets(c->proplist, PA_PROP_APPLICATION_NAME));
472 pa_pstream_send_tagstruct(c->pstream, reply);
473 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, setup_complete_callback, c, NULL);
475 pa_context_set_state(c, PA_CONTEXT_SETTING_NAME);
479 case PA_CONTEXT_SETTING_NAME :
481 if ((c->version >= 13 && (pa_tagstruct_getu32(t, &c->client_index) < 0 ||
482 c->client_index == PA_INVALID_INDEX)) ||
483 !pa_tagstruct_eof(t)) {
484 pa_context_fail(c, PA_ERR_PROTOCOL);
488 pa_context_set_state(c, PA_CONTEXT_READY);
492 pa_assert_not_reached();
499 static void setup_context(pa_context *c, pa_iochannel *io) {
508 pa_assert(!c->pstream);
509 c->pstream = pa_pstream_new(c->mainloop, io, c->mempool);
511 pa_pstream_set_die_callback(c->pstream, pstream_die_callback, c);
512 pa_pstream_set_recieve_packet_callback(c->pstream, pstream_packet_callback, c);
513 pa_pstream_set_recieve_memblock_callback(c->pstream, pstream_memblock_callback, c);
515 pa_assert(!c->pdispatch);
516 c->pdispatch = pa_pdispatch_new(c->mainloop, command_table, PA_COMMAND_MAX);
518 if (!c->conf->cookie_valid)
519 pa_log_info(_("No cookie loaded. Attempting to connect without."));
521 t = pa_tagstruct_command(c, PA_COMMAND_AUTH, &tag);
524 pa_mempool_is_shared(c->mempool) &&
527 pa_log_debug("SHM possible: %s", pa_yes_no(c->do_shm));
529 /* Starting with protocol version 13 we use the MSB of the version
530 * tag for informing the other side if we could do SHM or not */
531 pa_tagstruct_putu32(t, PA_PROTOCOL_VERSION | (c->do_shm ? 0x80000000U : 0));
532 pa_tagstruct_put_arbitrary(t, c->conf->cookie, sizeof(c->conf->cookie));
538 if (pa_iochannel_creds_supported(io))
539 pa_iochannel_creds_enable(io);
541 ucred.uid = getuid();
542 ucred.gid = getgid();
544 pa_pstream_send_tagstruct_with_creds(c->pstream, t, &ucred);
547 pa_pstream_send_tagstruct(c->pstream, t);
550 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, setup_complete_callback, c, NULL);
552 pa_context_set_state(c, PA_CONTEXT_AUTHORIZING);
557 #ifdef ENABLE_LEGACY_RUNTIME_DIR
558 static char *get_old_legacy_runtime_dir(void) {
562 if (!pa_get_user_name(u, sizeof(u)))
565 p = pa_sprintf_malloc("/tmp/pulse-%s", u);
567 if (stat(p, &st) < 0) {
572 if (st.st_uid != getuid()) {
580 static char *get_very_old_legacy_runtime_dir(void) {
584 if (!pa_get_home_dir(h, sizeof(h)))
587 p = pa_sprintf_malloc("%s/.pulse", h);
589 if (stat(p, &st) < 0) {
594 if (st.st_uid != getuid()) {
603 static pa_strlist *prepend_per_user(pa_strlist *l) {
606 #ifdef ENABLE_LEGACY_RUNTIME_DIR
607 static char *legacy_dir;
609 /* The very old per-user instance path (< 0.9.11). This is supported only to ease upgrades */
610 if ((legacy_dir = get_very_old_legacy_runtime_dir())) {
611 char *p = pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET, legacy_dir);
612 l = pa_strlist_prepend(l, p);
614 pa_xfree(legacy_dir);
617 /* The old per-user instance path (< 0.9.12). This is supported only to ease upgrades */
618 if ((legacy_dir = get_old_legacy_runtime_dir())) {
619 char *p = pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET, legacy_dir);
620 l = pa_strlist_prepend(l, p);
622 pa_xfree(legacy_dir);
626 /* The per-user instance */
627 if ((ufn = pa_runtime_path(PA_NATIVE_DEFAULT_UNIX_SOCKET))) {
628 l = pa_strlist_prepend(l, ufn);
637 static int context_autospawn(pa_context *c) {
641 pa_log_debug("Trying to autospawn...");
645 if (c->spawn_api.prefork)
646 c->spawn_api.prefork();
648 if ((pid = fork()) < 0) {
649 pa_log_error(_("fork(): %s"), pa_cstrerror(errno));
650 pa_context_fail(c, PA_ERR_INTERNAL);
652 if (c->spawn_api.postfork)
653 c->spawn_api.postfork();
659 const char *state = NULL;
661 const char * argv[MAX_ARGS+1];
664 if (c->spawn_api.atfork)
665 c->spawn_api.atfork();
673 argv[n++] = c->conf->daemon_binary;
674 argv[n++] = "--start";
676 while (n < MAX_ARGS) {
679 if (!(a = pa_split_spaces(c->conf->extra_arguments, &state)))
687 execv(argv[0], (char * const *) argv);
694 if (c->spawn_api.postfork)
695 c->spawn_api.postfork();
698 r = waitpid(pid, &status, 0);
699 } while (r < 0 && errno == EINTR);
702 pa_log(_("waitpid(): %s"), pa_cstrerror(errno));
703 pa_context_fail(c, PA_ERR_INTERNAL);
705 } else if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
706 pa_context_fail(c, PA_ERR_CONNECTIONREFUSED);
721 #endif /* OS_IS_WIN32 */
723 static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userdata);
725 static int try_next_connection(pa_context *c) {
730 pa_assert(!c->client);
736 c->server_list = pa_strlist_pop(c->server_list, &u);
741 if (c->do_autospawn) {
743 if ((r = context_autospawn(c)) < 0)
746 /* Autospawn only once */
747 c->do_autospawn = FALSE;
749 /* Connect only to per-user sockets this time */
750 c->server_list = prepend_per_user(c->server_list);
752 /* Retry connection */
757 pa_context_fail(c, PA_ERR_CONNECTIONREFUSED);
761 pa_log_debug("Trying to connect to %s...", u);
764 c->server = pa_xstrdup(u);
766 if (!(c->client = pa_socket_client_new_string(c->mainloop, u, PA_NATIVE_DEFAULT_PORT)))
769 c->is_local = !!pa_socket_client_is_local(c->client);
770 pa_socket_client_set_callback(c->client, on_connection, c);
782 static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userdata) {
783 pa_context *c = userdata;
784 int saved_errno = errno;
788 pa_assert(c->state == PA_CONTEXT_CONNECTING);
792 pa_socket_client_unref(client);
796 /* Try the item in the list */
797 if (saved_errno == ECONNREFUSED ||
798 saved_errno == ETIMEDOUT ||
799 saved_errno == EHOSTUNREACH) {
800 try_next_connection(c);
804 pa_context_fail(c, PA_ERR_CONNECTIONREFUSED);
808 setup_context(c, io);
814 int pa_context_connect(
817 pa_context_flags_t flags,
818 const pa_spawn_api *api) {
823 pa_assert(PA_REFCNT_VALUE(c) >= 1);
825 PA_CHECK_VALIDITY(c, c->state == PA_CONTEXT_UNCONNECTED, PA_ERR_BADSTATE);
826 PA_CHECK_VALIDITY(c, !(flags & ~PA_CONTEXT_NOAUTOSPAWN), PA_ERR_INVALID);
827 PA_CHECK_VALIDITY(c, !server || *server, PA_ERR_INVALID);
830 server = c->conf->default_server;
834 pa_assert(!c->server_list);
837 if (!(c->server_list = pa_strlist_parse(server))) {
838 pa_context_fail(c, PA_ERR_INVALIDSERVER);
845 /* Prepend in reverse order */
847 /* Follow the X display */
848 if ((d = getenv("DISPLAY"))) {
851 if ((e = strchr(d, ':')))
855 c->server_list = pa_strlist_prepend(c->server_list, d);
860 /* Add TCP/IP on the localhost */
861 c->server_list = pa_strlist_prepend(c->server_list, "tcp6:[::1]");
862 c->server_list = pa_strlist_prepend(c->server_list, "tcp4:127.0.0.1");
864 /* The system wide instance via PF_LOCAL */
865 c->server_list = pa_strlist_prepend(c->server_list, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET);
867 /* The user instance via PF_LOCAL */
868 c->server_list = prepend_per_user(c->server_list);
870 /* Set up autospawning */
871 if (!(flags & PA_CONTEXT_NOAUTOSPAWN) && c->conf->autospawn) {
874 pa_log_debug("Not doing autospawn since we are root.");
876 c->do_autospawn = TRUE;
884 pa_context_set_state(c, PA_CONTEXT_CONNECTING);
885 r = try_next_connection(c);
893 void pa_context_disconnect(pa_context *c) {
895 pa_assert(PA_REFCNT_VALUE(c) >= 1);
897 if (PA_CONTEXT_IS_GOOD(c->state))
898 pa_context_set_state(c, PA_CONTEXT_TERMINATED);
901 pa_context_state_t pa_context_get_state(pa_context *c) {
903 pa_assert(PA_REFCNT_VALUE(c) >= 1);
908 int pa_context_errno(pa_context *c) {
910 pa_assert(PA_REFCNT_VALUE(c) >= 1);
915 void pa_context_set_state_callback(pa_context *c, pa_context_notify_cb_t cb, void *userdata) {
917 pa_assert(PA_REFCNT_VALUE(c) >= 1);
919 if (c->state == PA_CONTEXT_TERMINATED || c->state == PA_CONTEXT_FAILED)
922 c->state_callback = cb;
923 c->state_userdata = userdata;
926 void pa_context_set_event_callback(pa_context *c, pa_context_event_cb_t cb, void *userdata) {
928 pa_assert(PA_REFCNT_VALUE(c) >= 1);
930 if (c->state == PA_CONTEXT_TERMINATED || c->state == PA_CONTEXT_FAILED)
933 c->event_callback = cb;
934 c->event_userdata = userdata;
937 int pa_context_is_pending(pa_context *c) {
939 pa_assert(PA_REFCNT_VALUE(c) >= 1);
941 PA_CHECK_VALIDITY(c, PA_CONTEXT_IS_GOOD(c->state), PA_ERR_BADSTATE);
943 return (c->pstream && pa_pstream_is_pending(c->pstream)) ||
944 (c->pdispatch && pa_pdispatch_is_pending(c->pdispatch)) ||
948 static void set_dispatch_callbacks(pa_operation *o);
950 static void pdispatch_drain_callback(pa_pdispatch*pd, void *userdata) {
951 set_dispatch_callbacks(userdata);
954 static void pstream_drain_callback(pa_pstream *s, void *userdata) {
955 set_dispatch_callbacks(userdata);
958 static void set_dispatch_callbacks(pa_operation *o) {
962 pa_assert(PA_REFCNT_VALUE(o) >= 1);
963 pa_assert(o->context);
964 pa_assert(PA_REFCNT_VALUE(o->context) >= 1);
965 pa_assert(o->context->state == PA_CONTEXT_READY);
967 pa_pstream_set_drain_callback(o->context->pstream, NULL, NULL);
968 pa_pdispatch_set_drain_callback(o->context->pdispatch, NULL, NULL);
970 if (pa_pdispatch_is_pending(o->context->pdispatch)) {
971 pa_pdispatch_set_drain_callback(o->context->pdispatch, pdispatch_drain_callback, o);
975 if (pa_pstream_is_pending(o->context->pstream)) {
976 pa_pstream_set_drain_callback(o->context->pstream, pstream_drain_callback, o);
982 pa_context_notify_cb_t cb = (pa_context_notify_cb_t) o->callback;
983 cb(o->context, o->userdata);
986 pa_operation_done(o);
987 pa_operation_unref(o);
991 pa_operation* pa_context_drain(pa_context *c, pa_context_notify_cb_t cb, void *userdata) {
995 pa_assert(PA_REFCNT_VALUE(c) >= 1);
997 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
998 PA_CHECK_VALIDITY_RETURN_NULL(c, pa_context_is_pending(c), PA_ERR_BADSTATE);
1000 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1001 set_dispatch_callbacks(pa_operation_ref(o));
1006 void pa_context_simple_ack_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1007 pa_operation *o = userdata;
1012 pa_assert(PA_REFCNT_VALUE(o) >= 1);
1017 if (command != PA_COMMAND_REPLY) {
1018 if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
1022 } else if (!pa_tagstruct_eof(t)) {
1023 pa_context_fail(o->context, PA_ERR_PROTOCOL);
1028 pa_context_success_cb_t cb = (pa_context_success_cb_t) o->callback;
1029 cb(o->context, success, o->userdata);
1033 pa_operation_done(o);
1034 pa_operation_unref(o);
1037 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) {
1043 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1045 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1047 o = pa_operation_new(c, NULL, cb, userdata);
1049 t = pa_tagstruct_command(c, command, &tag);
1050 pa_pstream_send_tagstruct(c->pstream, t);
1051 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, internal_cb, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1056 pa_operation* pa_context_exit_daemon(pa_context *c, pa_context_success_cb_t cb, void *userdata) {
1058 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1060 return pa_context_send_simple_command(c, PA_COMMAND_EXIT, pa_context_simple_ack_callback, (pa_operation_cb_t) cb, userdata);
1063 pa_operation* pa_context_set_default_sink(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) {
1069 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1071 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1073 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1074 t = pa_tagstruct_command(c, PA_COMMAND_SET_DEFAULT_SINK, &tag);
1075 pa_tagstruct_puts(t, name);
1076 pa_pstream_send_tagstruct(c->pstream, t);
1077 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1082 pa_operation* pa_context_set_default_source(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) {
1088 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1090 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1092 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1093 t = pa_tagstruct_command(c, PA_COMMAND_SET_DEFAULT_SOURCE, &tag);
1094 pa_tagstruct_puts(t, name);
1095 pa_pstream_send_tagstruct(c->pstream, t);
1096 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1101 int pa_context_is_local(pa_context *c) {
1103 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1105 PA_CHECK_VALIDITY_RETURN_ANY(c, PA_CONTEXT_IS_GOOD(c->state), PA_ERR_BADSTATE, -1);
1107 return !!c->is_local;
1110 pa_operation* pa_context_set_name(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) {
1114 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1117 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1119 if (c->version >= 13) {
1120 pa_proplist *p = pa_proplist_new();
1122 pa_proplist_sets(p, PA_PROP_APPLICATION_NAME, name);
1123 o = pa_context_proplist_update(c, PA_UPDATE_REPLACE, p, cb, userdata);
1124 pa_proplist_free(p);
1129 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1130 t = pa_tagstruct_command(c, PA_COMMAND_SET_CLIENT_NAME, &tag);
1131 pa_tagstruct_puts(t, name);
1132 pa_pstream_send_tagstruct(c->pstream, t);
1133 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1139 const char* pa_get_library_version(void) {
1140 return PACKAGE_VERSION;
1143 const char* pa_context_get_server(pa_context *c) {
1145 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1150 if (*c->server == '{') {
1151 char *e = strchr(c->server+1, '}');
1152 return e ? e+1 : c->server;
1158 uint32_t pa_context_get_protocol_version(pa_context *c) {
1159 return PA_PROTOCOL_VERSION;
1162 uint32_t pa_context_get_server_protocol_version(pa_context *c) {
1164 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1166 PA_CHECK_VALIDITY_RETURN_ANY(c, PA_CONTEXT_IS_GOOD(c->state), PA_ERR_BADSTATE, PA_INVALID_INDEX);
1171 pa_tagstruct *pa_tagstruct_command(pa_context *c, uint32_t command, uint32_t *tag) {
1177 t = pa_tagstruct_new(NULL, 0);
1178 pa_tagstruct_putu32(t, command);
1179 pa_tagstruct_putu32(t, *tag = c->ctag++);
1184 uint32_t pa_context_get_index(pa_context *c) {
1186 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1188 PA_CHECK_VALIDITY_RETURN_ANY(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE, PA_INVALID_INDEX);
1189 PA_CHECK_VALIDITY_RETURN_ANY(c, c->version >= 13, PA_ERR_NOTSUPPORTED, PA_INVALID_INDEX);
1191 return c->client_index;
1194 pa_operation *pa_context_proplist_update(pa_context *c, pa_update_mode_t mode, pa_proplist *p, pa_context_success_cb_t cb, void *userdata) {
1200 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1202 PA_CHECK_VALIDITY_RETURN_NULL(c, mode == PA_UPDATE_SET || mode == PA_UPDATE_MERGE || mode == PA_UPDATE_REPLACE, PA_ERR_INVALID);
1203 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1204 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 13, PA_ERR_NOTSUPPORTED);
1206 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1208 t = pa_tagstruct_command(c, PA_COMMAND_UPDATE_CLIENT_PROPLIST, &tag);
1209 pa_tagstruct_putu32(t, (uint32_t) mode);
1210 pa_tagstruct_put_proplist(t, p);
1212 pa_pstream_send_tagstruct(c->pstream, t);
1213 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1215 /* Please note that we don't update c->proplist here, because we
1216 * don't export that field */
1221 pa_operation *pa_context_proplist_remove(pa_context *c, const char *const keys[], pa_context_success_cb_t cb, void *userdata) {
1225 const char * const *k;
1228 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1230 PA_CHECK_VALIDITY_RETURN_NULL(c, keys && keys[0], PA_ERR_INVALID);
1231 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1232 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 13, PA_ERR_NOTSUPPORTED);
1234 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1236 t = pa_tagstruct_command(c, PA_COMMAND_REMOVE_CLIENT_PROPLIST, &tag);
1238 for (k = keys; *k; k++)
1239 pa_tagstruct_puts(t, *k);
1241 pa_tagstruct_puts(t, NULL);
1243 pa_pstream_send_tagstruct(c->pstream, t);
1244 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1246 /* Please note that we don't update c->proplist here, because we
1247 * don't export that field */
1252 void pa_command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1253 pa_context *c = userdata;
1258 pa_assert(command == PA_COMMAND_EXTENSION);
1261 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1265 if (c->version < 15) {
1266 pa_context_fail(c, PA_ERR_PROTOCOL);
1270 if (pa_tagstruct_getu32(t, &idx) < 0 ||
1271 pa_tagstruct_gets(t, &name) < 0) {
1272 pa_context_fail(c, PA_ERR_PROTOCOL);
1276 if (!strcmp(name, "module-stream-restore"))
1277 pa_ext_stream_restore_command(c, tag, t);
1279 pa_log(_("Received message for unknown extension '%s'"), name);
1282 pa_context_unref(c);
1286 void pa_command_client_event(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1287 pa_context *c = userdata;
1288 pa_proplist *pl = NULL;
1292 pa_assert(command == PA_COMMAND_CLIENT_EVENT);
1295 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1299 if (c->version < 15) {
1300 pa_context_fail(c, PA_ERR_PROTOCOL);
1304 pl = pa_proplist_new();
1306 if (pa_tagstruct_gets(t, &event) < 0 ||
1307 pa_tagstruct_get_proplist(t, pl) < 0 ||
1308 !pa_tagstruct_eof(t) || !event) {
1309 pa_context_fail(c, PA_ERR_PROTOCOL);
1313 if (c->event_callback)
1314 c->event_callback(c, event, pl, c->event_userdata);
1317 pa_context_unref(c);
1320 pa_proplist_free(pl);