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
49 #include <pulse/version.h>
50 #include <pulse/xmalloc.h>
51 #include <pulse/utf8.h>
52 #include <pulse/util.h>
53 #include <pulse/i18n.h>
54 #include <pulse/mainloop.h>
55 #include <pulse/timeval.h>
57 #include <pulsecore/core-error.h>
58 #include <pulsecore/native-common.h>
59 #include <pulsecore/pdispatch.h>
60 #include <pulsecore/pstream.h>
61 #include <pulsecore/hashmap.h>
62 #include <pulsecore/socket-client.h>
63 #include <pulsecore/pstream-util.h>
64 #include <pulsecore/core-rtclock.h>
65 #include <pulsecore/core-util.h>
66 #include <pulsecore/log.h>
67 #include <pulsecore/socket.h>
68 #include <pulsecore/socket-util.h>
69 #include <pulsecore/creds.h>
70 #include <pulsecore/macro.h>
71 #include <pulsecore/proplist-util.h>
75 #include "client-conf.h"
76 #include "fork-detect.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
,
102 [PA_COMMAND_PLAYBACK_BUFFER_ATTR_CHANGED
] = pa_command_stream_buffer_attr
,
103 [PA_COMMAND_RECORD_BUFFER_ATTR_CHANGED
] = pa_command_stream_buffer_attr
105 static void context_free(pa_context
*c
);
108 static DBusHandlerResult
filter_cb(DBusConnection
*bus
, DBusMessage
*message
, void *userdata
);
111 pa_context
*pa_context_new(pa_mainloop_api
*mainloop
, const char *name
) {
112 return pa_context_new_with_proplist(mainloop
, name
, NULL
);
115 static void reset_callbacks(pa_context
*c
) {
118 c
->state_callback
= NULL
;
119 c
->state_userdata
= NULL
;
121 c
->subscribe_callback
= NULL
;
122 c
->subscribe_userdata
= NULL
;
124 c
->event_callback
= NULL
;
125 c
->event_userdata
= NULL
;
127 c
->ext_device_manager
.callback
= NULL
;
128 c
->ext_device_manager
.userdata
= NULL
;
130 c
->ext_stream_restore
.callback
= NULL
;
131 c
->ext_stream_restore
.userdata
= NULL
;
134 pa_context
*pa_context_new_with_proplist(pa_mainloop_api
*mainloop
, const char *name
, pa_proplist
*p
) {
139 if (pa_detect_fork())
144 c
= pa_xnew0(pa_context
, 1);
147 c
->proplist
= p
? pa_proplist_copy(p
) : pa_proplist_new();
150 pa_proplist_sets(c
->proplist
, PA_PROP_APPLICATION_NAME
, name
);
153 c
->system_bus
= c
->session_bus
= NULL
;
155 c
->mainloop
= mainloop
;
156 c
->playback_streams
= pa_hashmap_new(pa_idxset_trivial_hash_func
, pa_idxset_trivial_compare_func
);
157 c
->record_streams
= pa_hashmap_new(pa_idxset_trivial_hash_func
, pa_idxset_trivial_compare_func
);
158 c
->client_index
= PA_INVALID_INDEX
;
159 c
->use_rtclock
= pa_mainloop_is_our_api(mainloop
);
161 PA_LLIST_HEAD_INIT(pa_stream
, c
->streams
);
162 PA_LLIST_HEAD_INIT(pa_operation
, c
->operations
);
165 c
->state
= PA_CONTEXT_UNCONNECTED
;
171 pa_check_signal_is_blocked(SIGPIPE
);
175 c
->conf
= pa_client_conf_new();
176 pa_client_conf_load(c
->conf
, NULL
);
178 pa_client_conf_from_x11(c
->conf
, NULL
);
180 pa_client_conf_env(c
->conf
);
182 if (!(c
->mempool
= pa_mempool_new(!c
->conf
->disable_shm
, c
->conf
->shm_size
))) {
184 if (!c
->conf
->disable_shm
)
185 c
->mempool
= pa_mempool_new(FALSE
, c
->conf
->shm_size
);
196 static void context_unlink(pa_context
*c
) {
201 s
= c
->streams
? pa_stream_ref(c
->streams
) : NULL
;
203 pa_stream
*n
= s
->next
? pa_stream_ref(s
->next
) : NULL
;
204 pa_stream_set_state(s
, c
->state
== PA_CONTEXT_FAILED
? PA_STREAM_FAILED
: PA_STREAM_TERMINATED
);
209 while (c
->operations
)
210 pa_operation_cancel(c
->operations
);
213 pa_pdispatch_unref(c
->pdispatch
);
218 pa_pstream_unlink(c
->pstream
);
219 pa_pstream_unref(c
->pstream
);
224 pa_socket_client_unref(c
->client
);
231 static void context_free(pa_context
*c
) {
239 dbus_connection_remove_filter(pa_dbus_wrap_connection_get(c
->system_bus
), filter_cb
, c
);
240 pa_dbus_wrap_connection_free(c
->system_bus
);
243 if (c
->session_bus
) {
245 dbus_connection_remove_filter(pa_dbus_wrap_connection_get(c
->session_bus
), filter_cb
, c
);
246 pa_dbus_wrap_connection_free(c
->session_bus
);
250 if (c
->record_streams
)
251 pa_hashmap_free(c
->record_streams
, NULL
, NULL
);
252 if (c
->playback_streams
)
253 pa_hashmap_free(c
->playback_streams
, NULL
, NULL
);
256 pa_mempool_free(c
->mempool
);
259 pa_client_conf_free(c
->conf
);
261 pa_strlist_free(c
->server_list
);
264 pa_proplist_free(c
->proplist
);
270 pa_context
* pa_context_ref(pa_context
*c
) {
272 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
278 void pa_context_unref(pa_context
*c
) {
280 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
282 if (PA_REFCNT_DEC(c
) <= 0)
286 void pa_context_set_state(pa_context
*c
, pa_context_state_t st
) {
288 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
297 if (c
->state_callback
)
298 c
->state_callback(c
, c
->state_userdata
);
300 if (st
== PA_CONTEXT_FAILED
|| st
== PA_CONTEXT_TERMINATED
)
306 int pa_context_set_error(pa_context
*c
, int error
) {
307 pa_assert(error
>= 0);
308 pa_assert(error
< PA_ERR_MAX
);
316 void pa_context_fail(pa_context
*c
, int error
) {
318 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
320 pa_context_set_error(c
, error
);
321 pa_context_set_state(c
, PA_CONTEXT_FAILED
);
324 static void pstream_die_callback(pa_pstream
*p
, void *userdata
) {
325 pa_context
*c
= userdata
;
330 pa_context_fail(c
, PA_ERR_CONNECTIONTERMINATED
);
333 static void pstream_packet_callback(pa_pstream
*p
, pa_packet
*packet
, const pa_creds
*creds
, void *userdata
) {
334 pa_context
*c
= userdata
;
342 if (pa_pdispatch_run(c
->pdispatch
, packet
, creds
, c
) < 0)
343 pa_context_fail(c
, PA_ERR_PROTOCOL
);
348 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
) {
349 pa_context
*c
= userdata
;
354 pa_assert(chunk
->length
> 0);
356 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
360 if ((s
= pa_hashmap_get(c
->record_streams
, PA_UINT32_TO_PTR(channel
)))) {
362 if (chunk
->memblock
) {
363 pa_memblockq_seek(s
->record_memblockq
, offset
, seek
, TRUE
);
364 pa_memblockq_push_align(s
->record_memblockq
, chunk
);
366 pa_memblockq_seek(s
->record_memblockq
, offset
+chunk
->length
, seek
, TRUE
);
368 if (s
->read_callback
) {
371 if ((l
= pa_memblockq_get_length(s
->record_memblockq
)) > 0)
372 s
->read_callback(s
, l
, s
->read_userdata
);
379 int pa_context_handle_error(pa_context
*c
, uint32_t command
, pa_tagstruct
*t
, pa_bool_t fail
) {
382 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
384 if (command
== PA_COMMAND_ERROR
) {
387 if (pa_tagstruct_getu32(t
, &err
) < 0 ||
388 !pa_tagstruct_eof(t
)) {
389 pa_context_fail(c
, PA_ERR_PROTOCOL
);
393 } else if (command
== PA_COMMAND_TIMEOUT
)
394 err
= PA_ERR_TIMEOUT
;
396 pa_context_fail(c
, PA_ERR_PROTOCOL
);
401 pa_context_fail(c
, PA_ERR_PROTOCOL
);
405 if (err
>= PA_ERR_MAX
)
406 err
= PA_ERR_UNKNOWN
;
409 pa_context_fail(c
, (int) err
);
413 pa_context_set_error(c
, (int) err
);
418 static void setup_complete_callback(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
419 pa_context
*c
= userdata
;
423 pa_assert(c
->state
== PA_CONTEXT_AUTHORIZING
|| c
->state
== PA_CONTEXT_SETTING_NAME
);
427 if (command
!= PA_COMMAND_REPLY
) {
428 pa_context_handle_error(c
, command
, t
, TRUE
);
433 case PA_CONTEXT_AUTHORIZING
: {
435 pa_bool_t shm_on_remote
= FALSE
;
437 if (pa_tagstruct_getu32(t
, &c
->version
) < 0 ||
438 !pa_tagstruct_eof(t
)) {
439 pa_context_fail(c
, PA_ERR_PROTOCOL
);
443 /* Minimum supported version */
444 if (c
->version
< 8) {
445 pa_context_fail(c
, PA_ERR_VERSION
);
449 /* Starting with protocol version 13 the MSB of the version
450 tag reflects if shm is available for this connection or
452 if (c
->version
>= 13) {
453 shm_on_remote
= !!(c
->version
& 0x80000000U
);
454 c
->version
&= 0x7FFFFFFFU
;
457 pa_log_debug("Protocol version: remote %u, local %u", c
->version
, PA_PROTOCOL_VERSION
);
459 /* Enable shared memory support if possible */
461 if (c
->version
< 10 || (c
->version
>= 13 && !shm_on_remote
))
466 /* Only enable SHM if both sides are owned by the same
467 * user. This is a security measure because otherwise
468 * data private to the user might leak. */
471 const pa_creds
*creds
;
472 if (!(creds
= pa_pdispatch_creds(pd
)) || getuid() != creds
->uid
)
477 pa_log_debug("Negotiated SHM: %s", pa_yes_no(c
->do_shm
));
478 pa_pstream_enable_shm(c
->pstream
, c
->do_shm
);
480 reply
= pa_tagstruct_command(c
, PA_COMMAND_SET_CLIENT_NAME
, &tag
);
482 if (c
->version
>= 13) {
483 pa_init_proplist(c
->proplist
);
484 pa_tagstruct_put_proplist(reply
, c
->proplist
);
486 pa_tagstruct_puts(reply
, pa_proplist_gets(c
->proplist
, PA_PROP_APPLICATION_NAME
));
488 pa_pstream_send_tagstruct(c
->pstream
, reply
);
489 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, setup_complete_callback
, c
, NULL
);
491 pa_context_set_state(c
, PA_CONTEXT_SETTING_NAME
);
495 case PA_CONTEXT_SETTING_NAME
:
497 if ((c
->version
>= 13 && (pa_tagstruct_getu32(t
, &c
->client_index
) < 0 ||
498 c
->client_index
== PA_INVALID_INDEX
)) ||
499 !pa_tagstruct_eof(t
)) {
500 pa_context_fail(c
, PA_ERR_PROTOCOL
);
504 pa_context_set_state(c
, PA_CONTEXT_READY
);
508 pa_assert_not_reached();
515 static void setup_context(pa_context
*c
, pa_iochannel
*io
) {
524 pa_assert(!c
->pstream
);
525 c
->pstream
= pa_pstream_new(c
->mainloop
, io
, c
->mempool
);
527 pa_pstream_set_die_callback(c
->pstream
, pstream_die_callback
, c
);
528 pa_pstream_set_recieve_packet_callback(c
->pstream
, pstream_packet_callback
, c
);
529 pa_pstream_set_recieve_memblock_callback(c
->pstream
, pstream_memblock_callback
, c
);
531 pa_assert(!c
->pdispatch
);
532 c
->pdispatch
= pa_pdispatch_new(c
->mainloop
, c
->use_rtclock
, command_table
, PA_COMMAND_MAX
);
534 if (!c
->conf
->cookie_valid
)
535 pa_log_info(_("No cookie loaded. Attempting to connect without."));
537 t
= pa_tagstruct_command(c
, PA_COMMAND_AUTH
, &tag
);
540 pa_mempool_is_shared(c
->mempool
) &&
543 pa_log_debug("SHM possible: %s", pa_yes_no(c
->do_shm
));
545 /* Starting with protocol version 13 we use the MSB of the version
546 * tag for informing the other side if we could do SHM or not */
547 pa_tagstruct_putu32(t
, PA_PROTOCOL_VERSION
| (c
->do_shm
? 0x80000000U
: 0));
548 pa_tagstruct_put_arbitrary(t
, c
->conf
->cookie
, sizeof(c
->conf
->cookie
));
554 if (pa_iochannel_creds_supported(io
))
555 pa_iochannel_creds_enable(io
);
557 ucred
.uid
= getuid();
558 ucred
.gid
= getgid();
560 pa_pstream_send_tagstruct_with_creds(c
->pstream
, t
, &ucred
);
563 pa_pstream_send_tagstruct(c
->pstream
, t
);
566 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, setup_complete_callback
, c
, NULL
);
568 pa_context_set_state(c
, PA_CONTEXT_AUTHORIZING
);
573 #ifdef ENABLE_LEGACY_RUNTIME_DIR
574 static char *get_old_legacy_runtime_dir(void) {
578 if (!pa_get_user_name(u
, sizeof(u
)))
581 p
= pa_sprintf_malloc("/tmp/pulse-%s", u
);
583 if (stat(p
, &st
) < 0) {
588 if (st
.st_uid
!= getuid()) {
596 static char *get_very_old_legacy_runtime_dir(void) {
600 if (!pa_get_home_dir(h
, sizeof(h
)))
603 p
= pa_sprintf_malloc("%s/.pulse", h
);
605 if (stat(p
, &st
) < 0) {
610 if (st
.st_uid
!= getuid()) {
619 static pa_strlist
*prepend_per_user(pa_strlist
*l
) {
622 #ifdef ENABLE_LEGACY_RUNTIME_DIR
625 /* The very old per-user instance path (< 0.9.11). This is supported only to ease upgrades */
626 if ((legacy_dir
= get_very_old_legacy_runtime_dir())) {
627 char *p
= pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
, legacy_dir
);
628 l
= pa_strlist_prepend(l
, p
);
630 pa_xfree(legacy_dir
);
633 /* The old per-user instance path (< 0.9.12). This is supported only to ease upgrades */
634 if ((legacy_dir
= get_old_legacy_runtime_dir())) {
635 char *p
= pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
, legacy_dir
);
636 l
= pa_strlist_prepend(l
, p
);
638 pa_xfree(legacy_dir
);
642 /* The per-user instance */
643 if ((ufn
= pa_runtime_path(PA_NATIVE_DEFAULT_UNIX_SOCKET
))) {
644 l
= pa_strlist_prepend(l
, ufn
);
653 static int context_autospawn(pa_context
*c
) {
660 if (sigaction(SIGCHLD
, NULL
, &sa
) < 0) {
661 pa_log_debug("sigaction() failed: %s", pa_cstrerror(errno
));
662 pa_context_fail(c
, PA_ERR_INTERNAL
);
666 if ((sa
.sa_flags
& SA_NOCLDWAIT
) || sa
.sa_handler
== SIG_IGN
) {
667 pa_log_debug("Process disabled waitpid(), cannot autospawn.");
668 pa_context_fail(c
, PA_ERR_CONNECTIONREFUSED
);
672 pa_log_debug("Trying to autospawn...");
674 if (c
->spawn_api
.prefork
)
675 c
->spawn_api
.prefork();
677 if ((pid
= fork()) < 0) {
678 pa_log_error(_("fork(): %s"), pa_cstrerror(errno
));
679 pa_context_fail(c
, PA_ERR_INTERNAL
);
681 if (c
->spawn_api
.postfork
)
682 c
->spawn_api
.postfork();
688 const char *state
= NULL
;
689 const char * argv
[32];
692 if (c
->spawn_api
.atfork
)
693 c
->spawn_api
.atfork();
695 /* We leave most of the cleaning up of the process environment
696 * to the executable. We only clean up the file descriptors to
697 * make sure the executable can actually be loaded
702 argv
[n
++] = c
->conf
->daemon_binary
;
703 argv
[n
++] = "--start";
705 while (n
< PA_ELEMENTSOF(argv
)-1) {
708 if (!(a
= pa_split_spaces(c
->conf
->extra_arguments
, &state
)))
715 pa_assert(n
<= PA_ELEMENTSOF(argv
));
717 execv(argv
[0], (char * const *) argv
);
723 if (c
->spawn_api
.postfork
)
724 c
->spawn_api
.postfork();
727 r
= waitpid(pid
, &status
, 0);
728 } while (r
< 0 && errno
== EINTR
);
732 if (errno
!= ESRCH
) {
733 pa_log(_("waitpid(): %s"), pa_cstrerror(errno
));
734 pa_context_fail(c
, PA_ERR_INTERNAL
);
738 /* hmm, something already reaped our child, so we assume
739 * startup worked, even if we cannot know */
741 } else if (!WIFEXITED(status
) || WEXITSTATUS(status
) != 0) {
742 pa_context_fail(c
, PA_ERR_CONNECTIONREFUSED
);
757 #endif /* OS_IS_WIN32 */
759 static void on_connection(pa_socket_client
*client
, pa_iochannel
*io
, void *userdata
);
762 static void track_pulseaudio_on_dbus(pa_context
*c
, DBusBusType type
, pa_dbus_wrap_connection
**conn
) {
768 dbus_error_init(&error
);
770 if (!(*conn
= pa_dbus_wrap_connection_new(c
->mainloop
, c
->use_rtclock
, type
, &error
)) || dbus_error_is_set(&error
)) {
771 pa_log_warn("Unable to contact DBUS: %s: %s", error
.name
, error
.message
);
775 if (!dbus_connection_add_filter(pa_dbus_wrap_connection_get(*conn
), filter_cb
, c
, NULL
)) {
776 pa_log_warn("Failed to add filter function");
779 c
->filter_added
= TRUE
;
781 if (pa_dbus_add_matches(
782 pa_dbus_wrap_connection_get(*conn
), &error
,
783 "type='signal',sender='" DBUS_SERVICE_DBUS
"',interface='" DBUS_INTERFACE_DBUS
"',member='NameOwnerChanged',arg0='org.pulseaudio.Server',arg1=''", NULL
) < 0) {
785 pa_log_warn("Unable to track org.pulseaudio.Server: %s: %s", error
.name
, error
.message
);
793 pa_dbus_wrap_connection_free(*conn
);
797 dbus_error_free(&error
);
801 static int try_next_connection(pa_context
*c
) {
806 pa_assert(!c
->client
);
812 c
->server_list
= pa_strlist_pop(c
->server_list
, &u
);
817 if (c
->do_autospawn
) {
819 if ((r
= context_autospawn(c
)) < 0)
822 /* Autospawn only once */
823 c
->do_autospawn
= FALSE
;
825 /* Connect only to per-user sockets this time */
826 c
->server_list
= prepend_per_user(c
->server_list
);
828 /* Retry connection */
834 if (c
->no_fail
&& !c
->server_specified
) {
836 track_pulseaudio_on_dbus(c
, DBUS_BUS_SESSION
, &c
->session_bus
);
838 track_pulseaudio_on_dbus(c
, DBUS_BUS_SYSTEM
, &c
->system_bus
);
841 pa_context_fail(c
, PA_ERR_CONNECTIONREFUSED
);
846 pa_log_debug("Trying to connect to %s...", u
);
849 c
->server
= pa_xstrdup(u
);
851 if (!(c
->client
= pa_socket_client_new_string(c
->mainloop
, c
->use_rtclock
, u
, PA_NATIVE_DEFAULT_PORT
)))
854 c
->is_local
= !!pa_socket_client_is_local(c
->client
);
855 pa_socket_client_set_callback(c
->client
, on_connection
, c
);
867 static void on_connection(pa_socket_client
*client
, pa_iochannel
*io
, void *userdata
) {
868 pa_context
*c
= userdata
;
869 int saved_errno
= errno
;
873 pa_assert(c
->state
== PA_CONTEXT_CONNECTING
);
877 pa_socket_client_unref(client
);
881 /* Try the next item in the list */
882 if (saved_errno
== ECONNREFUSED
||
883 saved_errno
== ETIMEDOUT
||
884 saved_errno
== EHOSTUNREACH
) {
885 try_next_connection(c
);
889 pa_context_fail(c
, PA_ERR_CONNECTIONREFUSED
);
893 setup_context(c
, io
);
900 static DBusHandlerResult
filter_cb(DBusConnection
*bus
, DBusMessage
*message
, void *userdata
) {
901 pa_context
*c
= userdata
;
902 pa_bool_t is_session
;
908 if (c
->state
!= PA_CONTEXT_CONNECTING
)
914 /* FIXME: We probably should check if this is actually the NameOwnerChanged we were looking for */
916 is_session
= c
->session_bus
&& bus
== pa_dbus_wrap_connection_get(c
->session_bus
);
917 pa_log_debug("Rock!! PulseAudio might be back on %s bus", is_session
? "session" : "system");
920 /* The user instance via PF_LOCAL */
921 c
->server_list
= prepend_per_user(c
->server_list
);
923 /* The system wide instance via PF_LOCAL */
924 c
->server_list
= pa_strlist_prepend(c
->server_list
, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
);
927 try_next_connection(c
);
930 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
934 int pa_context_connect(
937 pa_context_flags_t flags
,
938 const pa_spawn_api
*api
) {
943 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
945 PA_CHECK_VALIDITY(c
, !pa_detect_fork(), PA_ERR_FORKED
);
946 PA_CHECK_VALIDITY(c
, c
->state
== PA_CONTEXT_UNCONNECTED
, PA_ERR_BADSTATE
);
947 PA_CHECK_VALIDITY(c
, !(flags
& ~(PA_CONTEXT_NOAUTOSPAWN
|PA_CONTEXT_NOFAIL
)), PA_ERR_INVALID
);
948 PA_CHECK_VALIDITY(c
, !server
|| *server
, PA_ERR_INVALID
);
951 c
->conf
->autospawn
= FALSE
;
953 server
= c
->conf
->default_server
;
957 c
->no_fail
= !!(flags
& PA_CONTEXT_NOFAIL
);
958 c
->server_specified
= !!server
;
959 pa_assert(!c
->server_list
);
962 if (!(c
->server_list
= pa_strlist_parse(server
))) {
963 pa_context_fail(c
, PA_ERR_INVALIDSERVER
);
970 /* Prepend in reverse order */
972 /* Follow the X display */
973 if (c
->conf
->auto_connect_display
) {
974 if ((d
= getenv("DISPLAY"))) {
975 d
= pa_xstrndup(d
, strcspn(d
, ":"));
978 c
->server_list
= pa_strlist_prepend(c
->server_list
, d
);
984 /* Add TCP/IP on the localhost */
985 if (c
->conf
->auto_connect_localhost
) {
986 c
->server_list
= pa_strlist_prepend(c
->server_list
, "tcp6:[::1]");
987 c
->server_list
= pa_strlist_prepend(c
->server_list
, "tcp4:127.0.0.1");
990 /* The system wide instance via PF_LOCAL */
991 c
->server_list
= pa_strlist_prepend(c
->server_list
, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET
);
993 /* The user instance via PF_LOCAL */
994 c
->server_list
= prepend_per_user(c
->server_list
);
997 /* Set up autospawning */
998 if (!(flags
& PA_CONTEXT_NOAUTOSPAWN
) && c
->conf
->autospawn
) {
1001 pa_log_debug("Not doing autospawn since we are root.");
1003 c
->do_autospawn
= TRUE
;
1006 c
->spawn_api
= *api
;
1010 pa_context_set_state(c
, PA_CONTEXT_CONNECTING
);
1011 r
= try_next_connection(c
);
1014 pa_context_unref(c
);
1019 void pa_context_disconnect(pa_context
*c
) {
1021 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1023 if (pa_detect_fork())
1026 if (PA_CONTEXT_IS_GOOD(c
->state
))
1027 pa_context_set_state(c
, PA_CONTEXT_TERMINATED
);
1030 pa_context_state_t
pa_context_get_state(pa_context
*c
) {
1032 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1037 int pa_context_errno(pa_context
*c
) {
1040 return PA_ERR_INVALID
;
1042 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1047 void pa_context_set_state_callback(pa_context
*c
, pa_context_notify_cb_t cb
, void *userdata
) {
1049 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1051 if (pa_detect_fork())
1054 if (c
->state
== PA_CONTEXT_TERMINATED
|| c
->state
== PA_CONTEXT_FAILED
)
1057 c
->state_callback
= cb
;
1058 c
->state_userdata
= userdata
;
1061 void pa_context_set_event_callback(pa_context
*c
, pa_context_event_cb_t cb
, void *userdata
) {
1063 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1065 if (pa_detect_fork())
1068 if (c
->state
== PA_CONTEXT_TERMINATED
|| c
->state
== PA_CONTEXT_FAILED
)
1071 c
->event_callback
= cb
;
1072 c
->event_userdata
= userdata
;
1075 int pa_context_is_pending(pa_context
*c
) {
1077 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1079 PA_CHECK_VALIDITY(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1080 PA_CHECK_VALIDITY(c
, PA_CONTEXT_IS_GOOD(c
->state
), PA_ERR_BADSTATE
);
1082 return (c
->pstream
&& pa_pstream_is_pending(c
->pstream
)) ||
1083 (c
->pdispatch
&& pa_pdispatch_is_pending(c
->pdispatch
)) ||
1087 static void set_dispatch_callbacks(pa_operation
*o
);
1089 static void pdispatch_drain_callback(pa_pdispatch
*pd
, void *userdata
) {
1090 set_dispatch_callbacks(userdata
);
1093 static void pstream_drain_callback(pa_pstream
*s
, void *userdata
) {
1094 set_dispatch_callbacks(userdata
);
1097 static void set_dispatch_callbacks(pa_operation
*o
) {
1101 pa_assert(PA_REFCNT_VALUE(o
) >= 1);
1102 pa_assert(o
->context
);
1103 pa_assert(PA_REFCNT_VALUE(o
->context
) >= 1);
1104 pa_assert(o
->context
->state
== PA_CONTEXT_READY
);
1106 pa_pstream_set_drain_callback(o
->context
->pstream
, NULL
, NULL
);
1107 pa_pdispatch_set_drain_callback(o
->context
->pdispatch
, NULL
, NULL
);
1109 if (pa_pdispatch_is_pending(o
->context
->pdispatch
)) {
1110 pa_pdispatch_set_drain_callback(o
->context
->pdispatch
, pdispatch_drain_callback
, o
);
1114 if (pa_pstream_is_pending(o
->context
->pstream
)) {
1115 pa_pstream_set_drain_callback(o
->context
->pstream
, pstream_drain_callback
, o
);
1121 pa_context_notify_cb_t cb
= (pa_context_notify_cb_t
) o
->callback
;
1122 cb(o
->context
, o
->userdata
);
1125 pa_operation_done(o
);
1126 pa_operation_unref(o
);
1130 pa_operation
* pa_context_drain(pa_context
*c
, pa_context_notify_cb_t cb
, void *userdata
) {
1134 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1136 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1137 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1138 PA_CHECK_VALIDITY_RETURN_NULL(c
, pa_context_is_pending(c
), PA_ERR_BADSTATE
);
1140 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1141 set_dispatch_callbacks(pa_operation_ref(o
));
1146 void pa_context_simple_ack_callback(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1147 pa_operation
*o
= userdata
;
1152 pa_assert(PA_REFCNT_VALUE(o
) >= 1);
1157 if (command
!= PA_COMMAND_REPLY
) {
1158 if (pa_context_handle_error(o
->context
, command
, t
, FALSE
) < 0)
1162 } else if (!pa_tagstruct_eof(t
)) {
1163 pa_context_fail(o
->context
, PA_ERR_PROTOCOL
);
1168 pa_context_success_cb_t cb
= (pa_context_success_cb_t
) o
->callback
;
1169 cb(o
->context
, success
, o
->userdata
);
1173 pa_operation_done(o
);
1174 pa_operation_unref(o
);
1177 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
) {
1183 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1185 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1186 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1188 o
= pa_operation_new(c
, NULL
, cb
, userdata
);
1190 t
= pa_tagstruct_command(c
, command
, &tag
);
1191 pa_pstream_send_tagstruct(c
->pstream
, t
);
1192 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, internal_cb
, pa_operation_ref(o
), (pa_free_cb_t
) pa_operation_unref
);
1197 pa_operation
* pa_context_exit_daemon(pa_context
*c
, pa_context_success_cb_t cb
, void *userdata
) {
1199 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1201 return pa_context_send_simple_command(c
, PA_COMMAND_EXIT
, pa_context_simple_ack_callback
, (pa_operation_cb_t
) cb
, userdata
);
1204 pa_operation
* pa_context_set_default_sink(pa_context
*c
, const char *name
, pa_context_success_cb_t cb
, void *userdata
) {
1210 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1212 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1213 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1215 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1216 t
= pa_tagstruct_command(c
, PA_COMMAND_SET_DEFAULT_SINK
, &tag
);
1217 pa_tagstruct_puts(t
, name
);
1218 pa_pstream_send_tagstruct(c
->pstream
, t
);
1219 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
);
1224 pa_operation
* pa_context_set_default_source(pa_context
*c
, const char *name
, pa_context_success_cb_t cb
, void *userdata
) {
1230 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1232 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1233 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1235 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1236 t
= pa_tagstruct_command(c
, PA_COMMAND_SET_DEFAULT_SOURCE
, &tag
);
1237 pa_tagstruct_puts(t
, name
);
1238 pa_pstream_send_tagstruct(c
->pstream
, t
);
1239 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
);
1244 int pa_context_is_local(pa_context
*c
) {
1246 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1248 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, -1);
1249 PA_CHECK_VALIDITY_RETURN_ANY(c
, PA_CONTEXT_IS_GOOD(c
->state
), PA_ERR_BADSTATE
, -1);
1251 return !!c
->is_local
;
1254 pa_operation
* pa_context_set_name(pa_context
*c
, const char *name
, pa_context_success_cb_t cb
, void *userdata
) {
1258 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1261 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1262 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1264 if (c
->version
>= 13) {
1265 pa_proplist
*p
= pa_proplist_new();
1267 pa_proplist_sets(p
, PA_PROP_APPLICATION_NAME
, name
);
1268 o
= pa_context_proplist_update(c
, PA_UPDATE_REPLACE
, p
, cb
, userdata
);
1269 pa_proplist_free(p
);
1274 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1275 t
= pa_tagstruct_command(c
, PA_COMMAND_SET_CLIENT_NAME
, &tag
);
1276 pa_tagstruct_puts(t
, name
);
1277 pa_pstream_send_tagstruct(c
->pstream
, t
);
1278 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
);
1284 const char* pa_get_library_version(void) {
1285 return PACKAGE_VERSION
;
1288 const char* pa_context_get_server(pa_context
*c
) {
1290 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1292 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1293 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->server
, PA_ERR_NOENTITY
);
1295 if (*c
->server
== '{') {
1296 char *e
= strchr(c
->server
+1, '}');
1297 return e
? e
+1 : c
->server
;
1303 uint32_t pa_context_get_protocol_version(pa_context
*c
) {
1304 return PA_PROTOCOL_VERSION
;
1307 uint32_t pa_context_get_server_protocol_version(pa_context
*c
) {
1309 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1311 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, PA_INVALID_INDEX
);
1312 PA_CHECK_VALIDITY_RETURN_ANY(c
, PA_CONTEXT_IS_GOOD(c
->state
), PA_ERR_BADSTATE
, PA_INVALID_INDEX
);
1317 pa_tagstruct
*pa_tagstruct_command(pa_context
*c
, uint32_t command
, uint32_t *tag
) {
1323 t
= pa_tagstruct_new(NULL
, 0);
1324 pa_tagstruct_putu32(t
, command
);
1325 pa_tagstruct_putu32(t
, *tag
= c
->ctag
++);
1330 uint32_t pa_context_get_index(pa_context
*c
) {
1332 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1334 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, PA_INVALID_INDEX
);
1335 PA_CHECK_VALIDITY_RETURN_ANY(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
, PA_INVALID_INDEX
);
1336 PA_CHECK_VALIDITY_RETURN_ANY(c
, c
->version
>= 13, PA_ERR_NOTSUPPORTED
, PA_INVALID_INDEX
);
1338 return c
->client_index
;
1341 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
) {
1347 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1349 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1350 PA_CHECK_VALIDITY_RETURN_NULL(c
, mode
== PA_UPDATE_SET
|| mode
== PA_UPDATE_MERGE
|| mode
== PA_UPDATE_REPLACE
, PA_ERR_INVALID
);
1351 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1352 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->version
>= 13, PA_ERR_NOTSUPPORTED
);
1354 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1356 t
= pa_tagstruct_command(c
, PA_COMMAND_UPDATE_CLIENT_PROPLIST
, &tag
);
1357 pa_tagstruct_putu32(t
, (uint32_t) mode
);
1358 pa_tagstruct_put_proplist(t
, p
);
1360 pa_pstream_send_tagstruct(c
->pstream
, t
);
1361 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
);
1363 /* Please note that we don't update c->proplist here, because we
1364 * don't export that field */
1369 pa_operation
*pa_context_proplist_remove(pa_context
*c
, const char *const keys
[], pa_context_success_cb_t cb
, void *userdata
) {
1373 const char * const *k
;
1376 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1378 PA_CHECK_VALIDITY_RETURN_NULL(c
, !pa_detect_fork(), PA_ERR_FORKED
);
1379 PA_CHECK_VALIDITY_RETURN_NULL(c
, keys
&& keys
[0], PA_ERR_INVALID
);
1380 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->state
== PA_CONTEXT_READY
, PA_ERR_BADSTATE
);
1381 PA_CHECK_VALIDITY_RETURN_NULL(c
, c
->version
>= 13, PA_ERR_NOTSUPPORTED
);
1383 o
= pa_operation_new(c
, NULL
, (pa_operation_cb_t
) cb
, userdata
);
1385 t
= pa_tagstruct_command(c
, PA_COMMAND_REMOVE_CLIENT_PROPLIST
, &tag
);
1387 for (k
= keys
; *k
; k
++)
1388 pa_tagstruct_puts(t
, *k
);
1390 pa_tagstruct_puts(t
, NULL
);
1392 pa_pstream_send_tagstruct(c
->pstream
, t
);
1393 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
);
1395 /* Please note that we don't update c->proplist here, because we
1396 * don't export that field */
1401 void pa_command_extension(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1402 pa_context
*c
= userdata
;
1407 pa_assert(command
== PA_COMMAND_EXTENSION
);
1410 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1414 if (c
->version
< 15) {
1415 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1419 if (pa_tagstruct_getu32(t
, &idx
) < 0 ||
1420 pa_tagstruct_gets(t
, &name
) < 0) {
1421 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1425 if (!strcmp(name
, "module-stream-restore"))
1426 pa_ext_stream_restore_command(c
, tag
, t
);
1427 else if (!strcmp(name
, "module-device-manager"))
1428 pa_ext_device_manager_command(c
, tag
, t
);
1430 pa_log(_("Received message for unknown extension '%s'"), name
);
1433 pa_context_unref(c
);
1437 void pa_command_client_event(pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, pa_tagstruct
*t
, void *userdata
) {
1438 pa_context
*c
= userdata
;
1439 pa_proplist
*pl
= NULL
;
1443 pa_assert(command
== PA_COMMAND_CLIENT_EVENT
);
1446 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1450 if (c
->version
< 15) {
1451 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1455 pl
= pa_proplist_new();
1457 if (pa_tagstruct_gets(t
, &event
) < 0 ||
1458 pa_tagstruct_get_proplist(t
, pl
) < 0 ||
1459 !pa_tagstruct_eof(t
) || !event
) {
1460 pa_context_fail(c
, PA_ERR_PROTOCOL
);
1464 if (c
->event_callback
)
1465 c
->event_callback(c
, event
, pl
, c
->event_userdata
);
1468 pa_context_unref(c
);
1471 pa_proplist_free(pl
);
1474 pa_time_event
* pa_context_rttime_new(pa_context
*c
, pa_usec_t usec
, pa_time_event_cb_t cb
, void *userdata
) {
1478 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1479 pa_assert(c
->mainloop
);
1481 if (usec
== PA_USEC_INVALID
)
1482 return c
->mainloop
->time_new(c
->mainloop
, NULL
, cb
, userdata
);
1484 pa_timeval_rtstore(&tv
, usec
, c
->use_rtclock
);
1486 return c
->mainloop
->time_new(c
->mainloop
, &tv
, cb
, userdata
);
1489 void pa_context_rttime_restart(pa_context
*c
, pa_time_event
*e
, pa_usec_t usec
) {
1493 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1494 pa_assert(c
->mainloop
);
1497 if (usec
== PA_USEC_INVALID
)
1498 c
->mainloop
->time_restart(e
, NULL
);
1500 pa_timeval_rtstore(&tv
, usec
, c
->use_rtclock
);
1501 c
->mainloop
->time_restart(e
, &tv
);
1505 size_t pa_context_get_tile_size(pa_context
*c
, const pa_sample_spec
*ss
) {
1509 pa_assert(PA_REFCNT_VALUE(c
) >= 1);
1511 PA_CHECK_VALIDITY_RETURN_ANY(c
, !pa_detect_fork(), PA_ERR_FORKED
, (size_t) -1);
1512 PA_CHECK_VALIDITY_RETURN_ANY(c
, !ss
|| pa_sample_spec_valid(ss
), PA_ERR_INVALID
, (size_t) -1);
1514 fs
= ss
? pa_frame_size(ss
) : 1;
1515 mbs
= PA_ROUND_DOWN(pa_mempool_block_size_max(c
->mempool
), fs
);
1516 return PA_MAX(mbs
, fs
);