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"
77 #include "fork-detect.h"
80 #include "client-conf-x11.h"
85 void pa_command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
87 static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = {
88 [PA_COMMAND_REQUEST] = pa_command_request,
89 [PA_COMMAND_OVERFLOW] = pa_command_overflow_or_underflow,
90 [PA_COMMAND_UNDERFLOW] = pa_command_overflow_or_underflow,
91 [PA_COMMAND_PLAYBACK_STREAM_KILLED] = pa_command_stream_killed,
92 [PA_COMMAND_RECORD_STREAM_KILLED] = pa_command_stream_killed,
93 [PA_COMMAND_PLAYBACK_STREAM_MOVED] = pa_command_stream_moved,
94 [PA_COMMAND_RECORD_STREAM_MOVED] = pa_command_stream_moved,
95 [PA_COMMAND_PLAYBACK_STREAM_SUSPENDED] = pa_command_stream_suspended,
96 [PA_COMMAND_RECORD_STREAM_SUSPENDED] = pa_command_stream_suspended,
97 [PA_COMMAND_STARTED] = pa_command_stream_started,
98 [PA_COMMAND_SUBSCRIBE_EVENT] = pa_command_subscribe_event,
99 [PA_COMMAND_EXTENSION] = pa_command_extension,
100 [PA_COMMAND_PLAYBACK_STREAM_EVENT] = pa_command_stream_event,
101 [PA_COMMAND_RECORD_STREAM_EVENT] = pa_command_stream_event,
102 [PA_COMMAND_CLIENT_EVENT] = pa_command_client_event
104 static void context_free(pa_context *c);
106 pa_context *pa_context_new(pa_mainloop_api *mainloop, const char *name) {
107 return pa_context_new_with_proplist(mainloop, name, NULL);
110 static void reset_callbacks(pa_context *c) {
113 c->state_callback = NULL;
114 c->state_userdata = NULL;
116 c->subscribe_callback = NULL;
117 c->subscribe_userdata = NULL;
119 c->event_callback = NULL;
120 c->event_userdata = NULL;
122 c->ext_stream_restore.callback = NULL;
123 c->ext_stream_restore.userdata = NULL;
126 pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char *name, pa_proplist *p) {
131 if (pa_detect_fork())
136 c = pa_xnew(pa_context, 1);
139 c->proplist = p ? pa_proplist_copy(p) : pa_proplist_new();
142 pa_proplist_sets(c->proplist, PA_PROP_APPLICATION_NAME, name);
144 c->mainloop = mainloop;
148 c->playback_streams = pa_dynarray_new();
149 c->record_streams = pa_dynarray_new();
150 c->client_index = PA_INVALID_INDEX;
152 PA_LLIST_HEAD_INIT(pa_stream, c->streams);
153 PA_LLIST_HEAD_INIT(pa_operation, c->operations);
156 c->state = PA_CONTEXT_UNCONNECTED;
163 c->server_list = NULL;
168 c->do_autospawn = FALSE;
169 memset(&c->spawn_api, 0, sizeof(c->spawn_api));
173 pa_check_signal_is_blocked(SIGPIPE);
177 c->conf = pa_client_conf_new();
179 pa_client_conf_from_x11(c->conf, NULL);
181 pa_client_conf_load(c->conf, NULL);
182 pa_client_conf_env(c->conf);
184 if (!(c->mempool = pa_mempool_new(!c->conf->disable_shm, c->conf->shm_size))) {
186 if (!c->conf->disable_shm)
187 c->mempool = pa_mempool_new(FALSE, c->conf->shm_size);
198 static void context_unlink(pa_context *c) {
203 s = c->streams ? pa_stream_ref(c->streams) : NULL;
205 pa_stream *n = s->next ? pa_stream_ref(s->next) : NULL;
206 pa_stream_set_state(s, c->state == PA_CONTEXT_FAILED ? PA_STREAM_FAILED : PA_STREAM_TERMINATED);
211 while (c->operations)
212 pa_operation_cancel(c->operations);
215 pa_pdispatch_unref(c->pdispatch);
220 pa_pstream_unlink(c->pstream);
221 pa_pstream_unref(c->pstream);
226 pa_socket_client_unref(c->client);
233 static void context_free(pa_context *c) {
238 if (c->record_streams)
239 pa_dynarray_free(c->record_streams, NULL, NULL);
240 if (c->playback_streams)
241 pa_dynarray_free(c->playback_streams, NULL, NULL);
244 pa_mempool_free(c->mempool);
247 pa_client_conf_free(c->conf);
249 pa_strlist_free(c->server_list);
252 pa_proplist_free(c->proplist);
258 pa_context* pa_context_ref(pa_context *c) {
260 pa_assert(PA_REFCNT_VALUE(c) >= 1);
266 void pa_context_unref(pa_context *c) {
268 pa_assert(PA_REFCNT_VALUE(c) >= 1);
270 if (PA_REFCNT_DEC(c) <= 0)
274 void pa_context_set_state(pa_context *c, pa_context_state_t st) {
276 pa_assert(PA_REFCNT_VALUE(c) >= 1);
285 if (c->state_callback)
286 c->state_callback(c, c->state_userdata);
288 if (st == PA_CONTEXT_FAILED || st == PA_CONTEXT_TERMINATED)
294 int pa_context_set_error(pa_context *c, int error) {
295 pa_assert(error >= 0);
296 pa_assert(error < PA_ERR_MAX);
304 void pa_context_fail(pa_context *c, int error) {
306 pa_assert(PA_REFCNT_VALUE(c) >= 1);
308 pa_context_set_error(c, error);
309 pa_context_set_state(c, PA_CONTEXT_FAILED);
312 static void pstream_die_callback(pa_pstream *p, void *userdata) {
313 pa_context *c = userdata;
318 pa_context_fail(c, PA_ERR_CONNECTIONTERMINATED);
321 static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const pa_creds *creds, void *userdata) {
322 pa_context *c = userdata;
330 if (pa_pdispatch_run(c->pdispatch, packet, creds, c) < 0)
331 pa_context_fail(c, PA_ERR_PROTOCOL);
336 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) {
337 pa_context *c = userdata;
342 pa_assert(chunk->length > 0);
344 pa_assert(PA_REFCNT_VALUE(c) >= 1);
348 if ((s = pa_dynarray_get(c->record_streams, channel))) {
350 if (chunk->memblock) {
351 pa_memblockq_seek(s->record_memblockq, offset, seek);
352 pa_memblockq_push_align(s->record_memblockq, chunk);
354 pa_memblockq_seek(s->record_memblockq, offset+chunk->length, seek);
356 if (s->read_callback) {
359 if ((l = pa_memblockq_get_length(s->record_memblockq)) > 0)
360 s->read_callback(s, l, s->read_userdata);
367 int pa_context_handle_error(pa_context *c, uint32_t command, pa_tagstruct *t, pa_bool_t fail) {
370 pa_assert(PA_REFCNT_VALUE(c) >= 1);
372 if (command == PA_COMMAND_ERROR) {
375 if (pa_tagstruct_getu32(t, &err) < 0 ||
376 !pa_tagstruct_eof(t)) {
377 pa_context_fail(c, PA_ERR_PROTOCOL);
381 } else if (command == PA_COMMAND_TIMEOUT)
382 err = PA_ERR_TIMEOUT;
384 pa_context_fail(c, PA_ERR_PROTOCOL);
389 pa_context_fail(c, PA_ERR_PROTOCOL);
393 if (err >= PA_ERR_MAX)
394 err = PA_ERR_UNKNOWN;
397 pa_context_fail(c, (int) err);
401 pa_context_set_error(c, (int) err);
406 static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
407 pa_context *c = userdata;
411 pa_assert(c->state == PA_CONTEXT_AUTHORIZING || c->state == PA_CONTEXT_SETTING_NAME);
415 if (command != PA_COMMAND_REPLY) {
416 pa_context_handle_error(c, command, t, TRUE);
421 case PA_CONTEXT_AUTHORIZING: {
423 pa_bool_t shm_on_remote = FALSE;
425 if (pa_tagstruct_getu32(t, &c->version) < 0 ||
426 !pa_tagstruct_eof(t)) {
427 pa_context_fail(c, PA_ERR_PROTOCOL);
431 /* Minimum supported version */
432 if (c->version < 8) {
433 pa_context_fail(c, PA_ERR_VERSION);
437 /* Starting with protocol version 13 the MSB of the version
438 tag reflects if shm is available for this connection or
440 if (c->version >= 13) {
441 shm_on_remote = !!(c->version & 0x80000000U);
442 c->version &= 0x7FFFFFFFU;
445 pa_log_debug("Protocol version: remote %u, local %u", c->version, PA_PROTOCOL_VERSION);
447 /* Enable shared memory support if possible */
449 if (c->version < 10 || (c->version >= 13 && !shm_on_remote))
454 /* Only enable SHM if both sides are owned by the same
455 * user. This is a security measure because otherwise
456 * data private to the user might leak. */
459 const pa_creds *creds;
460 if (!(creds = pa_pdispatch_creds(pd)) || getuid() != creds->uid)
465 pa_log_debug("Negotiated SHM: %s", pa_yes_no(c->do_shm));
466 pa_pstream_enable_shm(c->pstream, c->do_shm);
468 reply = pa_tagstruct_command(c, PA_COMMAND_SET_CLIENT_NAME, &tag);
470 if (c->version >= 13) {
471 pa_init_proplist(c->proplist);
472 pa_tagstruct_put_proplist(reply, c->proplist);
474 pa_tagstruct_puts(reply, pa_proplist_gets(c->proplist, PA_PROP_APPLICATION_NAME));
476 pa_pstream_send_tagstruct(c->pstream, reply);
477 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, setup_complete_callback, c, NULL);
479 pa_context_set_state(c, PA_CONTEXT_SETTING_NAME);
483 case PA_CONTEXT_SETTING_NAME :
485 if ((c->version >= 13 && (pa_tagstruct_getu32(t, &c->client_index) < 0 ||
486 c->client_index == PA_INVALID_INDEX)) ||
487 !pa_tagstruct_eof(t)) {
488 pa_context_fail(c, PA_ERR_PROTOCOL);
492 pa_context_set_state(c, PA_CONTEXT_READY);
496 pa_assert_not_reached();
503 static void setup_context(pa_context *c, pa_iochannel *io) {
512 pa_assert(!c->pstream);
513 c->pstream = pa_pstream_new(c->mainloop, io, c->mempool);
515 pa_pstream_set_die_callback(c->pstream, pstream_die_callback, c);
516 pa_pstream_set_recieve_packet_callback(c->pstream, pstream_packet_callback, c);
517 pa_pstream_set_recieve_memblock_callback(c->pstream, pstream_memblock_callback, c);
519 pa_assert(!c->pdispatch);
520 c->pdispatch = pa_pdispatch_new(c->mainloop, command_table, PA_COMMAND_MAX);
522 if (!c->conf->cookie_valid)
523 pa_log_info(_("No cookie loaded. Attempting to connect without."));
525 t = pa_tagstruct_command(c, PA_COMMAND_AUTH, &tag);
528 pa_mempool_is_shared(c->mempool) &&
531 pa_log_debug("SHM possible: %s", pa_yes_no(c->do_shm));
533 /* Starting with protocol version 13 we use the MSB of the version
534 * tag for informing the other side if we could do SHM or not */
535 pa_tagstruct_putu32(t, PA_PROTOCOL_VERSION | (c->do_shm ? 0x80000000U : 0));
536 pa_tagstruct_put_arbitrary(t, c->conf->cookie, sizeof(c->conf->cookie));
542 if (pa_iochannel_creds_supported(io))
543 pa_iochannel_creds_enable(io);
545 ucred.uid = getuid();
546 ucred.gid = getgid();
548 pa_pstream_send_tagstruct_with_creds(c->pstream, t, &ucred);
551 pa_pstream_send_tagstruct(c->pstream, t);
554 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, setup_complete_callback, c, NULL);
556 pa_context_set_state(c, PA_CONTEXT_AUTHORIZING);
561 #ifdef ENABLE_LEGACY_RUNTIME_DIR
562 static char *get_old_legacy_runtime_dir(void) {
566 if (!pa_get_user_name(u, sizeof(u)))
569 p = pa_sprintf_malloc("/tmp/pulse-%s", u);
571 if (stat(p, &st) < 0) {
576 if (st.st_uid != getuid()) {
584 static char *get_very_old_legacy_runtime_dir(void) {
588 if (!pa_get_home_dir(h, sizeof(h)))
591 p = pa_sprintf_malloc("%s/.pulse", h);
593 if (stat(p, &st) < 0) {
598 if (st.st_uid != getuid()) {
607 static pa_strlist *prepend_per_user(pa_strlist *l) {
610 #ifdef ENABLE_LEGACY_RUNTIME_DIR
611 static char *legacy_dir;
613 /* The very old per-user instance path (< 0.9.11). This is supported only to ease upgrades */
614 if ((legacy_dir = get_very_old_legacy_runtime_dir())) {
615 char *p = pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET, legacy_dir);
616 l = pa_strlist_prepend(l, p);
618 pa_xfree(legacy_dir);
621 /* The old per-user instance path (< 0.9.12). This is supported only to ease upgrades */
622 if ((legacy_dir = get_old_legacy_runtime_dir())) {
623 char *p = pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET, legacy_dir);
624 l = pa_strlist_prepend(l, p);
626 pa_xfree(legacy_dir);
630 /* The per-user instance */
631 if ((ufn = pa_runtime_path(PA_NATIVE_DEFAULT_UNIX_SOCKET))) {
632 l = pa_strlist_prepend(l, ufn);
641 static int context_autospawn(pa_context *c) {
645 pa_log_debug("Trying to autospawn...");
649 if (c->spawn_api.prefork)
650 c->spawn_api.prefork();
652 if ((pid = fork()) < 0) {
653 pa_log_error(_("fork(): %s"), pa_cstrerror(errno));
654 pa_context_fail(c, PA_ERR_INTERNAL);
656 if (c->spawn_api.postfork)
657 c->spawn_api.postfork();
663 const char *state = NULL;
665 const char * argv[MAX_ARGS+1];
668 if (c->spawn_api.atfork)
669 c->spawn_api.atfork();
677 argv[n++] = c->conf->daemon_binary;
678 argv[n++] = "--start";
680 while (n < MAX_ARGS) {
683 if (!(a = pa_split_spaces(c->conf->extra_arguments, &state)))
691 execv(argv[0], (char * const *) argv);
698 if (c->spawn_api.postfork)
699 c->spawn_api.postfork();
702 r = waitpid(pid, &status, 0);
703 } while (r < 0 && errno == EINTR);
706 pa_log(_("waitpid(): %s"), pa_cstrerror(errno));
707 pa_context_fail(c, PA_ERR_INTERNAL);
709 } else if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
710 pa_context_fail(c, PA_ERR_CONNECTIONREFUSED);
725 #endif /* OS_IS_WIN32 */
727 static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userdata);
729 static int try_next_connection(pa_context *c) {
734 pa_assert(!c->client);
740 c->server_list = pa_strlist_pop(c->server_list, &u);
745 if (c->do_autospawn) {
747 if ((r = context_autospawn(c)) < 0)
750 /* Autospawn only once */
751 c->do_autospawn = FALSE;
753 /* Connect only to per-user sockets this time */
754 c->server_list = prepend_per_user(c->server_list);
756 /* Retry connection */
761 pa_context_fail(c, PA_ERR_CONNECTIONREFUSED);
765 pa_log_debug("Trying to connect to %s...", u);
768 c->server = pa_xstrdup(u);
770 if (!(c->client = pa_socket_client_new_string(c->mainloop, u, PA_NATIVE_DEFAULT_PORT)))
773 c->is_local = !!pa_socket_client_is_local(c->client);
774 pa_socket_client_set_callback(c->client, on_connection, c);
786 static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userdata) {
787 pa_context *c = userdata;
788 int saved_errno = errno;
792 pa_assert(c->state == PA_CONTEXT_CONNECTING);
796 pa_socket_client_unref(client);
800 /* Try the item in the list */
801 if (saved_errno == ECONNREFUSED ||
802 saved_errno == ETIMEDOUT ||
803 saved_errno == EHOSTUNREACH) {
804 try_next_connection(c);
808 pa_context_fail(c, PA_ERR_CONNECTIONREFUSED);
812 setup_context(c, io);
818 int pa_context_connect(
821 pa_context_flags_t flags,
822 const pa_spawn_api *api) {
827 pa_assert(PA_REFCNT_VALUE(c) >= 1);
829 PA_CHECK_VALIDITY(c, !pa_detect_fork(), PA_ERR_FORKED);
830 PA_CHECK_VALIDITY(c, c->state == PA_CONTEXT_UNCONNECTED, PA_ERR_BADSTATE);
831 PA_CHECK_VALIDITY(c, !(flags & ~PA_CONTEXT_NOAUTOSPAWN), PA_ERR_INVALID);
832 PA_CHECK_VALIDITY(c, !server || *server, PA_ERR_INVALID);
835 server = c->conf->default_server;
839 pa_assert(!c->server_list);
842 if (!(c->server_list = pa_strlist_parse(server))) {
843 pa_context_fail(c, PA_ERR_INVALIDSERVER);
850 /* Prepend in reverse order */
852 /* Follow the X display */
853 if ((d = getenv("DISPLAY"))) {
856 if ((e = strchr(d, ':')))
860 c->server_list = pa_strlist_prepend(c->server_list, d);
865 /* Add TCP/IP on the localhost */
866 c->server_list = pa_strlist_prepend(c->server_list, "tcp6:[::1]");
867 c->server_list = pa_strlist_prepend(c->server_list, "tcp4:127.0.0.1");
869 /* The system wide instance via PF_LOCAL */
870 c->server_list = pa_strlist_prepend(c->server_list, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET);
872 /* The user instance via PF_LOCAL */
873 c->server_list = prepend_per_user(c->server_list);
875 /* Set up autospawning */
876 if (!(flags & PA_CONTEXT_NOAUTOSPAWN) && c->conf->autospawn) {
879 pa_log_debug("Not doing autospawn since we are root.");
881 c->do_autospawn = TRUE;
889 pa_context_set_state(c, PA_CONTEXT_CONNECTING);
890 r = try_next_connection(c);
898 void pa_context_disconnect(pa_context *c) {
900 pa_assert(PA_REFCNT_VALUE(c) >= 1);
902 if (pa_detect_fork())
905 if (PA_CONTEXT_IS_GOOD(c->state))
906 pa_context_set_state(c, PA_CONTEXT_TERMINATED);
909 pa_context_state_t pa_context_get_state(pa_context *c) {
911 pa_assert(PA_REFCNT_VALUE(c) >= 1);
916 int pa_context_errno(pa_context *c) {
918 pa_assert(PA_REFCNT_VALUE(c) >= 1);
923 void pa_context_set_state_callback(pa_context *c, pa_context_notify_cb_t cb, void *userdata) {
925 pa_assert(PA_REFCNT_VALUE(c) >= 1);
927 if (pa_detect_fork())
930 if (c->state == PA_CONTEXT_TERMINATED || c->state == PA_CONTEXT_FAILED)
933 c->state_callback = cb;
934 c->state_userdata = userdata;
937 void pa_context_set_event_callback(pa_context *c, pa_context_event_cb_t cb, void *userdata) {
939 pa_assert(PA_REFCNT_VALUE(c) >= 1);
941 if (pa_detect_fork())
944 if (c->state == PA_CONTEXT_TERMINATED || c->state == PA_CONTEXT_FAILED)
947 c->event_callback = cb;
948 c->event_userdata = userdata;
951 int pa_context_is_pending(pa_context *c) {
953 pa_assert(PA_REFCNT_VALUE(c) >= 1);
955 PA_CHECK_VALIDITY(c, !pa_detect_fork(), PA_ERR_FORKED);
956 PA_CHECK_VALIDITY(c, PA_CONTEXT_IS_GOOD(c->state), PA_ERR_BADSTATE);
958 return (c->pstream && pa_pstream_is_pending(c->pstream)) ||
959 (c->pdispatch && pa_pdispatch_is_pending(c->pdispatch)) ||
963 static void set_dispatch_callbacks(pa_operation *o);
965 static void pdispatch_drain_callback(pa_pdispatch*pd, void *userdata) {
966 set_dispatch_callbacks(userdata);
969 static void pstream_drain_callback(pa_pstream *s, void *userdata) {
970 set_dispatch_callbacks(userdata);
973 static void set_dispatch_callbacks(pa_operation *o) {
977 pa_assert(PA_REFCNT_VALUE(o) >= 1);
978 pa_assert(o->context);
979 pa_assert(PA_REFCNT_VALUE(o->context) >= 1);
980 pa_assert(o->context->state == PA_CONTEXT_READY);
982 pa_pstream_set_drain_callback(o->context->pstream, NULL, NULL);
983 pa_pdispatch_set_drain_callback(o->context->pdispatch, NULL, NULL);
985 if (pa_pdispatch_is_pending(o->context->pdispatch)) {
986 pa_pdispatch_set_drain_callback(o->context->pdispatch, pdispatch_drain_callback, o);
990 if (pa_pstream_is_pending(o->context->pstream)) {
991 pa_pstream_set_drain_callback(o->context->pstream, pstream_drain_callback, o);
997 pa_context_notify_cb_t cb = (pa_context_notify_cb_t) o->callback;
998 cb(o->context, o->userdata);
1001 pa_operation_done(o);
1002 pa_operation_unref(o);
1006 pa_operation* pa_context_drain(pa_context *c, pa_context_notify_cb_t cb, void *userdata) {
1010 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1012 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1013 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1014 PA_CHECK_VALIDITY_RETURN_NULL(c, pa_context_is_pending(c), PA_ERR_BADSTATE);
1016 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1017 set_dispatch_callbacks(pa_operation_ref(o));
1022 void pa_context_simple_ack_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1023 pa_operation *o = userdata;
1028 pa_assert(PA_REFCNT_VALUE(o) >= 1);
1033 if (command != PA_COMMAND_REPLY) {
1034 if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
1038 } else if (!pa_tagstruct_eof(t)) {
1039 pa_context_fail(o->context, PA_ERR_PROTOCOL);
1044 pa_context_success_cb_t cb = (pa_context_success_cb_t) o->callback;
1045 cb(o->context, success, o->userdata);
1049 pa_operation_done(o);
1050 pa_operation_unref(o);
1053 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) {
1059 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1061 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1062 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1064 o = pa_operation_new(c, NULL, cb, userdata);
1066 t = pa_tagstruct_command(c, command, &tag);
1067 pa_pstream_send_tagstruct(c->pstream, t);
1068 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, internal_cb, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1073 pa_operation* pa_context_exit_daemon(pa_context *c, pa_context_success_cb_t cb, void *userdata) {
1075 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1077 return pa_context_send_simple_command(c, PA_COMMAND_EXIT, pa_context_simple_ack_callback, (pa_operation_cb_t) cb, userdata);
1080 pa_operation* pa_context_set_default_sink(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) {
1086 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1088 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1089 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1091 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1092 t = pa_tagstruct_command(c, PA_COMMAND_SET_DEFAULT_SINK, &tag);
1093 pa_tagstruct_puts(t, name);
1094 pa_pstream_send_tagstruct(c->pstream, t);
1095 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);
1100 pa_operation* pa_context_set_default_source(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) {
1106 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1108 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1109 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1111 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1112 t = pa_tagstruct_command(c, PA_COMMAND_SET_DEFAULT_SOURCE, &tag);
1113 pa_tagstruct_puts(t, name);
1114 pa_pstream_send_tagstruct(c->pstream, t);
1115 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);
1120 int pa_context_is_local(pa_context *c) {
1122 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1124 PA_CHECK_VALIDITY_RETURN_ANY(c, !pa_detect_fork(), PA_ERR_FORKED, -1);
1125 PA_CHECK_VALIDITY_RETURN_ANY(c, PA_CONTEXT_IS_GOOD(c->state), PA_ERR_BADSTATE, -1);
1127 return !!c->is_local;
1130 pa_operation* pa_context_set_name(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) {
1134 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1137 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1138 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1140 if (c->version >= 13) {
1141 pa_proplist *p = pa_proplist_new();
1143 pa_proplist_sets(p, PA_PROP_APPLICATION_NAME, name);
1144 o = pa_context_proplist_update(c, PA_UPDATE_REPLACE, p, cb, userdata);
1145 pa_proplist_free(p);
1150 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1151 t = pa_tagstruct_command(c, PA_COMMAND_SET_CLIENT_NAME, &tag);
1152 pa_tagstruct_puts(t, name);
1153 pa_pstream_send_tagstruct(c->pstream, t);
1154 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);
1160 const char* pa_get_library_version(void) {
1161 return PACKAGE_VERSION;
1164 const char* pa_context_get_server(pa_context *c) {
1166 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1168 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1169 PA_CHECK_VALIDITY_RETURN_NULL(c, c->server, PA_ERR_NOENTITY);
1171 if (*c->server == '{') {
1172 char *e = strchr(c->server+1, '}');
1173 return e ? e+1 : c->server;
1179 uint32_t pa_context_get_protocol_version(pa_context *c) {
1180 return PA_PROTOCOL_VERSION;
1183 uint32_t pa_context_get_server_protocol_version(pa_context *c) {
1185 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1187 PA_CHECK_VALIDITY_RETURN_ANY(c, !pa_detect_fork(), PA_ERR_FORKED, PA_INVALID_INDEX);
1188 PA_CHECK_VALIDITY_RETURN_ANY(c, PA_CONTEXT_IS_GOOD(c->state), PA_ERR_BADSTATE, PA_INVALID_INDEX);
1193 pa_tagstruct *pa_tagstruct_command(pa_context *c, uint32_t command, uint32_t *tag) {
1199 t = pa_tagstruct_new(NULL, 0);
1200 pa_tagstruct_putu32(t, command);
1201 pa_tagstruct_putu32(t, *tag = c->ctag++);
1206 uint32_t pa_context_get_index(pa_context *c) {
1208 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1210 PA_CHECK_VALIDITY_RETURN_ANY(c, !pa_detect_fork(), PA_ERR_FORKED, PA_INVALID_INDEX);
1211 PA_CHECK_VALIDITY_RETURN_ANY(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE, PA_INVALID_INDEX);
1212 PA_CHECK_VALIDITY_RETURN_ANY(c, c->version >= 13, PA_ERR_NOTSUPPORTED, PA_INVALID_INDEX);
1214 return c->client_index;
1217 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) {
1223 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1225 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1226 PA_CHECK_VALIDITY_RETURN_NULL(c, mode == PA_UPDATE_SET || mode == PA_UPDATE_MERGE || mode == PA_UPDATE_REPLACE, PA_ERR_INVALID);
1227 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1228 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 13, PA_ERR_NOTSUPPORTED);
1230 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1232 t = pa_tagstruct_command(c, PA_COMMAND_UPDATE_CLIENT_PROPLIST, &tag);
1233 pa_tagstruct_putu32(t, (uint32_t) mode);
1234 pa_tagstruct_put_proplist(t, p);
1236 pa_pstream_send_tagstruct(c->pstream, t);
1237 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);
1239 /* Please note that we don't update c->proplist here, because we
1240 * don't export that field */
1245 pa_operation *pa_context_proplist_remove(pa_context *c, const char *const keys[], pa_context_success_cb_t cb, void *userdata) {
1249 const char * const *k;
1252 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1254 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1255 PA_CHECK_VALIDITY_RETURN_NULL(c, keys && keys[0], PA_ERR_INVALID);
1256 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1257 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 13, PA_ERR_NOTSUPPORTED);
1259 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1261 t = pa_tagstruct_command(c, PA_COMMAND_REMOVE_CLIENT_PROPLIST, &tag);
1263 for (k = keys; *k; k++)
1264 pa_tagstruct_puts(t, *k);
1266 pa_tagstruct_puts(t, NULL);
1268 pa_pstream_send_tagstruct(c->pstream, t);
1269 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);
1271 /* Please note that we don't update c->proplist here, because we
1272 * don't export that field */
1277 void pa_command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1278 pa_context *c = userdata;
1283 pa_assert(command == PA_COMMAND_EXTENSION);
1286 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1290 if (c->version < 15) {
1291 pa_context_fail(c, PA_ERR_PROTOCOL);
1295 if (pa_tagstruct_getu32(t, &idx) < 0 ||
1296 pa_tagstruct_gets(t, &name) < 0) {
1297 pa_context_fail(c, PA_ERR_PROTOCOL);
1301 if (!strcmp(name, "module-stream-restore"))
1302 pa_ext_stream_restore_command(c, tag, t);
1304 pa_log(_("Received message for unknown extension '%s'"), name);
1307 pa_context_unref(c);
1311 void pa_command_client_event(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1312 pa_context *c = userdata;
1313 pa_proplist *pl = NULL;
1317 pa_assert(command == PA_COMMAND_CLIENT_EVENT);
1320 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1324 if (c->version < 15) {
1325 pa_context_fail(c, PA_ERR_PROTOCOL);
1329 pl = pa_proplist_new();
1331 if (pa_tagstruct_gets(t, &event) < 0 ||
1332 pa_tagstruct_get_proplist(t, pl) < 0 ||
1333 !pa_tagstruct_eof(t) || !event) {
1334 pa_context_fail(c, PA_ERR_PROTOCOL);
1338 if (c->event_callback)
1339 c->event_callback(c, event, pl, c->event_userdata);
1342 pa_context_unref(c);
1345 pa_proplist_free(pl);