]> code.delx.au - pulseaudio/blob - src/pulse/context.c
648024c3825269bb6bc4a6f7e72bfa889aeafbce
[pulseaudio] / src / pulse / context.c
1 /* $Id$ */
2
3 /***
4 This file is part of PulseAudio.
5
6 PulseAudio is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published
8 by the Free Software Foundation; either version 2 of the License,
9 or (at your option) any later version.
10
11 PulseAudio is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with PulseAudio; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 USA.
20 ***/
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <stdio.h>
27 #include <assert.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <sys/types.h>
31 #include <unistd.h>
32 #include <sys/stat.h>
33 #include <errno.h>
34 #include <signal.h>
35 #include <limits.h>
36
37 #ifdef HAVE_SYS_WAIT_H
38 #include <sys/wait.h>
39 #endif
40
41 #ifdef HAVE_SYS_SOCKET_H
42 #include <sys/socket.h>
43 #endif
44 #ifdef HAVE_NETDB_H
45 #include <netdb.h>
46 #endif
47
48 #include "../pulsecore/winsock.h"
49
50 #include <pulsecore/core-error.h>
51 #include <pulse/version.h>
52 #include <pulse/xmalloc.h>
53
54 #include <pulsecore/native-common.h>
55 #include <pulsecore/pdispatch.h>
56 #include <pulsecore/pstream.h>
57 #include <pulsecore/dynarray.h>
58 #include <pulsecore/socket-client.h>
59 #include <pulsecore/pstream-util.h>
60 #include <pulsecore/core-util.h>
61 #include <pulsecore/log.h>
62 #include <pulsecore/socket-util.h>
63
64 #include "internal.h"
65
66 #include "client-conf.h"
67
68 #ifdef HAVE_X11
69 #include "client-conf-x11.h"
70 #endif
71
72 #include "context.h"
73
74 #define AUTOSPAWN_LOCK "autospawn.lock"
75
76 static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = {
77 [PA_COMMAND_REQUEST] = pa_command_request,
78 [PA_COMMAND_OVERFLOW] = pa_command_overflow_or_underflow,
79 [PA_COMMAND_UNDERFLOW] = pa_command_overflow_or_underflow,
80 [PA_COMMAND_PLAYBACK_STREAM_KILLED] = pa_command_stream_killed,
81 [PA_COMMAND_RECORD_STREAM_KILLED] = pa_command_stream_killed,
82 [PA_COMMAND_SUBSCRIBE_EVENT] = pa_command_subscribe_event
83 };
84
85 static void unlock_autospawn_lock_file(pa_context *c) {
86 assert(c);
87
88 if (c->autospawn_lock_fd >= 0) {
89 char lf[PATH_MAX];
90 pa_runtime_path(AUTOSPAWN_LOCK, lf, sizeof(lf));
91
92 pa_unlock_lockfile(lf, c->autospawn_lock_fd);
93 c->autospawn_lock_fd = -1;
94 }
95 }
96
97 pa_context *pa_context_new(pa_mainloop_api *mainloop, const char *name) {
98 pa_context *c;
99
100 assert(mainloop);
101 assert(name);
102
103 c = pa_xnew(pa_context, 1);
104 c->ref = 1;
105 c->name = pa_xstrdup(name);
106 c->mainloop = mainloop;
107 c->client = NULL;
108 c->pstream = NULL;
109 c->pdispatch = NULL;
110 c->playback_streams = pa_dynarray_new();
111 c->record_streams = pa_dynarray_new();
112
113 PA_LLIST_HEAD_INIT(pa_stream, c->streams);
114 PA_LLIST_HEAD_INIT(pa_operation, c->operations);
115
116 c->error = PA_OK;
117 c->state = PA_CONTEXT_UNCONNECTED;
118 c->ctag = 0;
119 c->csyncid = 0;
120
121 c->state_callback = NULL;
122 c->state_userdata = NULL;
123
124 c->subscribe_callback = NULL;
125 c->subscribe_userdata = NULL;
126
127 c->memblock_stat = pa_memblock_stat_new();
128 c->local = -1;
129 c->server_list = NULL;
130 c->server = NULL;
131 c->autospawn_lock_fd = -1;
132 memset(&c->spawn_api, 0, sizeof(c->spawn_api));
133 c->do_autospawn = 0;
134
135 #ifdef SIGPIPE
136 pa_check_signal_is_blocked(SIGPIPE);
137 #endif
138
139 c->conf = pa_client_conf_new();
140 pa_client_conf_load(c->conf, NULL);
141 #ifdef HAVE_X11
142 pa_client_conf_from_x11(c->conf, NULL);
143 #endif
144 pa_client_conf_env(c->conf);
145
146 return c;
147 }
148
149 static void context_free(pa_context *c) {
150 assert(c);
151
152 unlock_autospawn_lock_file(c);
153
154 while (c->operations)
155 pa_operation_cancel(c->operations);
156
157 while (c->streams)
158 pa_stream_set_state(c->streams, PA_STREAM_TERMINATED);
159
160 if (c->client)
161 pa_socket_client_unref(c->client);
162 if (c->pdispatch)
163 pa_pdispatch_unref(c->pdispatch);
164 if (c->pstream) {
165 pa_pstream_close(c->pstream);
166 pa_pstream_unref(c->pstream);
167 }
168
169 if (c->record_streams)
170 pa_dynarray_free(c->record_streams, NULL, NULL);
171 if (c->playback_streams)
172 pa_dynarray_free(c->playback_streams, NULL, NULL);
173
174 pa_memblock_stat_unref(c->memblock_stat);
175
176 if (c->conf)
177 pa_client_conf_free(c->conf);
178
179 pa_strlist_free(c->server_list);
180
181 pa_xfree(c->name);
182 pa_xfree(c->server);
183 pa_xfree(c);
184 }
185
186 pa_context* pa_context_ref(pa_context *c) {
187 assert(c);
188 assert(c->ref >= 1);
189
190 c->ref++;
191 return c;
192 }
193
194 void pa_context_unref(pa_context *c) {
195 assert(c);
196 assert(c->ref >= 1);
197
198 if (--c->ref <= 0)
199 context_free(c);
200 }
201
202 void pa_context_set_state(pa_context *c, pa_context_state_t st) {
203 assert(c);
204 assert(c->ref >= 1);
205
206 if (c->state == st)
207 return;
208
209 pa_context_ref(c);
210
211 c->state = st;
212 if (c->state_callback)
213 c->state_callback(c, c->state_userdata);
214
215 if (st == PA_CONTEXT_FAILED || st == PA_CONTEXT_TERMINATED) {
216 pa_stream *s;
217
218 s = c->streams ? pa_stream_ref(c->streams) : NULL;
219 while (s) {
220 pa_stream *n = s->next ? pa_stream_ref(s->next) : NULL;
221 pa_stream_set_state(s, st == PA_CONTEXT_FAILED ? PA_STREAM_FAILED : PA_STREAM_TERMINATED);
222 pa_stream_unref(s);
223 s = n;
224 }
225
226 if (c->pdispatch)
227 pa_pdispatch_unref(c->pdispatch);
228 c->pdispatch = NULL;
229
230 if (c->pstream) {
231 pa_pstream_close(c->pstream);
232 pa_pstream_unref(c->pstream);
233 }
234 c->pstream = NULL;
235
236 if (c->client)
237 pa_socket_client_unref(c->client);
238 c->client = NULL;
239 }
240
241 pa_context_unref(c);
242 }
243
244 void pa_context_fail(pa_context *c, int error) {
245 assert(c);
246 assert(c->ref >= 1);
247
248 pa_context_set_error(c, error);
249 pa_context_set_state(c, PA_CONTEXT_FAILED);
250 }
251
252 int pa_context_set_error(pa_context *c, int error) {
253 assert(error >= 0);
254 assert(error < PA_ERR_MAX);
255
256 if (c)
257 c->error = error;
258
259 return error;
260 }
261
262 static void pstream_die_callback(pa_pstream *p, void *userdata) {
263 pa_context *c = userdata;
264
265 assert(p);
266 assert(c);
267
268 pa_context_fail(c, PA_ERR_CONNECTIONTERMINATED);
269 }
270
271 static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const void *creds, void *userdata) {
272 pa_context *c = userdata;
273
274 assert(p);
275 assert(packet);
276 assert(c);
277
278 pa_context_ref(c);
279
280 if (pa_pdispatch_run(c->pdispatch, packet, creds, c) < 0)
281 pa_context_fail(c, PA_ERR_PROTOCOL);
282
283 pa_context_unref(c);
284 }
285
286 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) {
287 pa_context *c = userdata;
288 pa_stream *s;
289
290 assert(p);
291 assert(chunk);
292 assert(chunk->memblock);
293 assert(chunk->length);
294 assert(c);
295 assert(c->ref >= 1);
296
297 pa_context_ref(c);
298
299 if ((s = pa_dynarray_get(c->record_streams, channel))) {
300
301 assert(seek == PA_SEEK_RELATIVE && offset == 0);
302
303 pa_memblockq_seek(s->record_memblockq, offset, seek);
304 pa_memblockq_push_align(s->record_memblockq, chunk);
305
306 if (s->read_callback) {
307 size_t l;
308
309 if ((l = pa_memblockq_get_length(s->record_memblockq)) > 0)
310 s->read_callback(s, l, s->read_userdata);
311 }
312 }
313
314 pa_context_unref(c);
315 }
316
317 int pa_context_handle_error(pa_context *c, uint32_t command, pa_tagstruct *t) {
318 assert(c);
319 assert(c->ref >= 1);
320
321 if (command == PA_COMMAND_ERROR) {
322 assert(t);
323
324 if (pa_tagstruct_getu32(t, &c->error) < 0) {
325 pa_context_fail(c, PA_ERR_PROTOCOL);
326 return -1;
327
328 }
329 } else if (command == PA_COMMAND_TIMEOUT)
330 c->error = PA_ERR_TIMEOUT;
331 else {
332 pa_context_fail(c, PA_ERR_PROTOCOL);
333 return -1;
334 }
335
336 return 0;
337 }
338
339 static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
340 pa_context *c = userdata;
341
342 assert(pd);
343 assert(c);
344 assert(c->state == PA_CONTEXT_AUTHORIZING || c->state == PA_CONTEXT_SETTING_NAME);
345
346 pa_context_ref(c);
347
348 if (command != PA_COMMAND_REPLY) {
349
350 if (pa_context_handle_error(c, command, t) < 0)
351 pa_context_fail(c, PA_ERR_PROTOCOL);
352
353 pa_context_fail(c, c->error);
354 goto finish;
355 }
356
357 switch(c->state) {
358 case PA_CONTEXT_AUTHORIZING: {
359 pa_tagstruct *reply;
360
361 if (pa_tagstruct_getu32(t, &c->version) < 0 ||
362 !pa_tagstruct_eof(t)) {
363 pa_context_fail(c, PA_ERR_PROTOCOL);
364 goto finish;
365 }
366
367 /* Minimum supported version */
368 if (c->version < 8) {
369 pa_context_fail(c, PA_ERR_VERSION);
370 goto finish;
371 }
372
373 reply = pa_tagstruct_command(c, PA_COMMAND_SET_CLIENT_NAME, &tag);
374 pa_tagstruct_puts(reply, c->name);
375 pa_pstream_send_tagstruct(c->pstream, reply);
376 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, setup_complete_callback, c, NULL);
377
378 pa_context_set_state(c, PA_CONTEXT_SETTING_NAME);
379 break;
380 }
381
382 case PA_CONTEXT_SETTING_NAME :
383 pa_context_set_state(c, PA_CONTEXT_READY);
384 break;
385
386 default:
387 assert(0);
388 }
389
390 finish:
391 pa_context_unref(c);
392 }
393
394 static void setup_context(pa_context *c, pa_iochannel *io) {
395 pa_tagstruct *t;
396 uint32_t tag;
397
398 assert(c);
399 assert(io);
400
401 pa_context_ref(c);
402
403 assert(!c->pstream);
404 c->pstream = pa_pstream_new(c->mainloop, io, c->memblock_stat);
405
406 pa_pstream_set_die_callback(c->pstream, pstream_die_callback, c);
407 pa_pstream_set_recieve_packet_callback(c->pstream, pstream_packet_callback, c);
408 pa_pstream_set_recieve_memblock_callback(c->pstream, pstream_memblock_callback, c);
409
410 assert(!c->pdispatch);
411 c->pdispatch = pa_pdispatch_new(c->mainloop, command_table, PA_COMMAND_MAX);
412
413 if (!c->conf->cookie_valid) {
414 pa_context_fail(c, PA_ERR_AUTHKEY);
415 goto finish;
416 }
417
418 t = pa_tagstruct_command(c, PA_COMMAND_AUTH, &tag);
419 pa_tagstruct_putu32(t, PA_PROTOCOL_VERSION);
420 pa_tagstruct_put_arbitrary(t, c->conf->cookie, sizeof(c->conf->cookie));
421 pa_pstream_send_tagstruct_with_creds(c->pstream, t, 1);
422 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, setup_complete_callback, c, NULL);
423
424 pa_context_set_state(c, PA_CONTEXT_AUTHORIZING);
425
426 finish:
427
428 pa_context_unref(c);
429 }
430
431 static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userdata);
432
433 #ifndef OS_IS_WIN32
434
435 static int context_connect_spawn(pa_context *c) {
436 pid_t pid;
437 int status, r;
438 int fds[2] = { -1, -1} ;
439 pa_iochannel *io;
440
441 pa_context_ref(c);
442
443 if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
444 pa_log(__FILE__": socketpair(): %s", pa_cstrerror(errno));
445 pa_context_fail(c, PA_ERR_INTERNAL);
446 goto fail;
447 }
448
449 pa_fd_set_cloexec(fds[0], 1);
450
451 pa_socket_low_delay(fds[0]);
452 pa_socket_low_delay(fds[1]);
453
454 if (c->spawn_api.prefork)
455 c->spawn_api.prefork();
456
457 if ((pid = fork()) < 0) {
458 pa_log(__FILE__": fork(): %s", pa_cstrerror(errno));
459 pa_context_fail(c, PA_ERR_INTERNAL);
460
461 if (c->spawn_api.postfork)
462 c->spawn_api.postfork();
463
464 goto fail;
465 } else if (!pid) {
466 /* Child */
467
468 char t[128];
469 const char *state = NULL;
470 #define MAX_ARGS 64
471 const char * argv[MAX_ARGS+1];
472 int n;
473
474 /* Not required, since fds[0] has CLOEXEC enabled anyway */
475 close(fds[0]);
476
477 if (c->spawn_api.atfork)
478 c->spawn_api.atfork();
479
480 /* Setup argv */
481
482 n = 0;
483
484 argv[n++] = c->conf->daemon_binary;
485 argv[n++] = "--daemonize=yes";
486
487 snprintf(t, sizeof(t), "-Lmodule-native-protocol-fd fd=%i", fds[1]);
488 argv[n++] = strdup(t);
489
490 while (n < MAX_ARGS) {
491 char *a;
492
493 if (!(a = pa_split_spaces(c->conf->extra_arguments, &state)))
494 break;
495
496 argv[n++] = a;
497 }
498
499 argv[n++] = NULL;
500
501 execv(argv[0], (char * const *) argv);
502 _exit(1);
503 #undef MAX_ARGS
504 }
505
506 /* Parent */
507
508 r = waitpid(pid, &status, 0);
509
510 if (c->spawn_api.postfork)
511 c->spawn_api.postfork();
512
513 if (r < 0) {
514 pa_log(__FILE__": waitpid(): %s", pa_cstrerror(errno));
515 pa_context_fail(c, PA_ERR_INTERNAL);
516 goto fail;
517 } else if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
518 pa_context_fail(c, PA_ERR_CONNECTIONREFUSED);
519 goto fail;
520 }
521
522 close(fds[1]);
523
524 c->local = 1;
525
526 io = pa_iochannel_new(c->mainloop, fds[0], fds[0]);
527
528 setup_context(c, io);
529 unlock_autospawn_lock_file(c);
530
531 pa_context_unref(c);
532
533 return 0;
534
535 fail:
536 if (fds[0] != -1)
537 close(fds[0]);
538 if (fds[1] != -1)
539 close(fds[1]);
540
541 unlock_autospawn_lock_file(c);
542
543 pa_context_unref(c);
544
545 return -1;
546 }
547
548 #endif /* OS_IS_WIN32 */
549
550 static int try_next_connection(pa_context *c) {
551 char *u = NULL;
552 int r = -1;
553
554 assert(c);
555 assert(!c->client);
556
557 for (;;) {
558 pa_xfree(u);
559 u = NULL;
560
561 c->server_list = pa_strlist_pop(c->server_list, &u);
562
563 if (!u) {
564
565 #ifndef OS_IS_WIN32
566 if (c->do_autospawn) {
567 r = context_connect_spawn(c);
568 goto finish;
569 }
570 #endif
571
572 pa_context_fail(c, PA_ERR_CONNECTIONREFUSED);
573 goto finish;
574 }
575
576 pa_log_debug(__FILE__": Trying to connect to %s...", u);
577
578 pa_xfree(c->server);
579 c->server = pa_xstrdup(u);
580
581 if (!(c->client = pa_socket_client_new_string(c->mainloop, u, PA_NATIVE_DEFAULT_PORT)))
582 continue;
583
584 c->local = pa_socket_client_is_local(c->client);
585 pa_socket_client_set_callback(c->client, on_connection, c);
586 break;
587 }
588
589 r = 0;
590
591 finish:
592 pa_xfree(u);
593
594 return r;
595 }
596
597 static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userdata) {
598 pa_context *c = userdata;
599
600 assert(client);
601 assert(c);
602 assert(c->state == PA_CONTEXT_CONNECTING);
603
604 pa_context_ref(c);
605
606 pa_socket_client_unref(client);
607 c->client = NULL;
608
609 if (!io) {
610 /* Try the item in the list */
611 if (errno == ECONNREFUSED || errno == ETIMEDOUT || errno == EHOSTUNREACH) {
612 try_next_connection(c);
613 goto finish;
614 }
615
616 pa_context_fail(c, PA_ERR_CONNECTIONREFUSED);
617 goto finish;
618 }
619
620 unlock_autospawn_lock_file(c);
621 setup_context(c, io);
622
623 finish:
624 pa_context_unref(c);
625 }
626
627 int pa_context_connect(
628 pa_context *c,
629 const char *server,
630 pa_context_flags_t flags,
631 const pa_spawn_api *api) {
632
633 int r = -1;
634
635 assert(c);
636 assert(c->ref >= 1);
637
638 PA_CHECK_VALIDITY(c, c->state == PA_CONTEXT_UNCONNECTED, PA_ERR_BADSTATE);
639 PA_CHECK_VALIDITY(c, !(flags & ~PA_CONTEXT_NOAUTOSPAWN), PA_ERR_INVALID);
640 PA_CHECK_VALIDITY(c, !server || *server, PA_ERR_INVALID);
641
642 if (!server)
643 server = c->conf->default_server;
644
645 pa_context_ref(c);
646
647 assert(!c->server_list);
648
649 if (server) {
650 if (!(c->server_list = pa_strlist_parse(server))) {
651 pa_context_fail(c, PA_ERR_INVALIDSERVER);
652 goto finish;
653 }
654 } else {
655 char *d;
656 char ufn[PATH_MAX];
657
658 /* Prepend in reverse order */
659
660 if ((d = getenv("DISPLAY"))) {
661 char *e;
662 d = pa_xstrdup(d);
663 if ((e = strchr(d, ':')))
664 *e = 0;
665
666 if (*d)
667 c->server_list = pa_strlist_prepend(c->server_list, d);
668
669 pa_xfree(d);
670 }
671
672 c->server_list = pa_strlist_prepend(c->server_list, "tcp6:localhost");
673 c->server_list = pa_strlist_prepend(c->server_list, "localhost");
674 c->server_list = pa_strlist_prepend(c->server_list, pa_runtime_path(PA_NATIVE_DEFAULT_UNIX_SOCKET, ufn, sizeof(ufn)));
675
676 /* Wrap the connection attempts in a single transaction for sane autospawn locking */
677 if (!(flags & PA_CONTEXT_NOAUTOSPAWN) && c->conf->autospawn) {
678 char lf[PATH_MAX];
679
680 pa_runtime_path(AUTOSPAWN_LOCK, lf, sizeof(lf));
681 pa_make_secure_parent_dir(lf);
682 assert(c->autospawn_lock_fd <= 0);
683 c->autospawn_lock_fd = pa_lock_lockfile(lf);
684
685 if (api)
686 c->spawn_api = *api;
687 c->do_autospawn = 1;
688 }
689
690 }
691
692 pa_context_set_state(c, PA_CONTEXT_CONNECTING);
693 r = try_next_connection(c);
694
695 finish:
696 pa_context_unref(c);
697
698 return r;
699 }
700
701 void pa_context_disconnect(pa_context *c) {
702 assert(c);
703 assert(c->ref >= 1);
704
705 pa_context_set_state(c, PA_CONTEXT_TERMINATED);
706 }
707
708 pa_context_state_t pa_context_get_state(pa_context *c) {
709 assert(c);
710 assert(c->ref >= 1);
711
712 return c->state;
713 }
714
715 int pa_context_errno(pa_context *c) {
716 assert(c);
717 assert(c->ref >= 1);
718
719 return c->error;
720 }
721
722 void pa_context_set_state_callback(pa_context *c, pa_context_notify_cb_t cb, void *userdata) {
723 assert(c);
724 assert(c->ref >= 1);
725
726 c->state_callback = cb;
727 c->state_userdata = userdata;
728 }
729
730 int pa_context_is_pending(pa_context *c) {
731 assert(c);
732 assert(c->ref >= 1);
733
734 PA_CHECK_VALIDITY(c,
735 c->state == PA_CONTEXT_CONNECTING ||
736 c->state == PA_CONTEXT_AUTHORIZING ||
737 c->state == PA_CONTEXT_SETTING_NAME ||
738 c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
739
740 return (c->pstream && pa_pstream_is_pending(c->pstream)) ||
741 (c->pdispatch && pa_pdispatch_is_pending(c->pdispatch)) ||
742 c->client;
743 }
744
745 static void set_dispatch_callbacks(pa_operation *o);
746
747 static void pdispatch_drain_callback(PA_GCC_UNUSED pa_pdispatch*pd, void *userdata) {
748 set_dispatch_callbacks(userdata);
749 }
750
751 static void pstream_drain_callback(PA_GCC_UNUSED pa_pstream *s, void *userdata) {
752 set_dispatch_callbacks(userdata);
753 }
754
755 static void set_dispatch_callbacks(pa_operation *o) {
756 int done = 1;
757
758 assert(o);
759 assert(o->ref >= 1);
760 assert(o->context);
761 assert(o->context->ref >= 1);
762 assert(o->context->state == PA_CONTEXT_READY);
763
764 pa_pstream_set_drain_callback(o->context->pstream, NULL, NULL);
765 pa_pdispatch_set_drain_callback(o->context->pdispatch, NULL, NULL);
766
767 if (pa_pdispatch_is_pending(o->context->pdispatch)) {
768 pa_pdispatch_set_drain_callback(o->context->pdispatch, pdispatch_drain_callback, o);
769 done = 0;
770 }
771
772 if (pa_pstream_is_pending(o->context->pstream)) {
773 pa_pstream_set_drain_callback(o->context->pstream, pstream_drain_callback, o);
774 done = 0;
775 }
776
777 if (done) {
778 if (o->callback) {
779 pa_context_notify_cb_t cb = (pa_context_notify_cb_t) o->callback;
780 cb(o->context, o->userdata);
781 }
782
783 pa_operation_done(o);
784 pa_operation_unref(o);
785 }
786 }
787
788 pa_operation* pa_context_drain(pa_context *c, pa_context_notify_cb_t cb, void *userdata) {
789 pa_operation *o;
790
791 assert(c);
792 assert(c->ref >= 1);
793
794 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
795 PA_CHECK_VALIDITY_RETURN_NULL(c, pa_context_is_pending(c), PA_ERR_BADSTATE);
796
797 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
798 set_dispatch_callbacks(pa_operation_ref(o));
799
800 return o;
801 }
802
803 void pa_context_simple_ack_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
804 pa_operation *o = userdata;
805 int success = 1;
806
807 assert(pd);
808 assert(o);
809 assert(o->ref >= 1);
810
811 if (!o->context)
812 goto finish;
813
814 if (command != PA_COMMAND_REPLY) {
815 if (pa_context_handle_error(o->context, command, t) < 0)
816 goto finish;
817
818 success = 0;
819 } else if (!pa_tagstruct_eof(t)) {
820 pa_context_fail(o->context, PA_ERR_PROTOCOL);
821 goto finish;
822 }
823
824 if (o->callback) {
825 pa_context_success_cb_t cb = (pa_context_success_cb_t) o->callback;
826 cb(o->context, success, o->userdata);
827 }
828
829 finish:
830 pa_operation_done(o);
831 pa_operation_unref(o);
832 }
833
834 pa_operation* pa_context_exit_daemon(pa_context *c, pa_context_success_cb_t cb, void *userdata) {
835 pa_tagstruct *t;
836 pa_operation *o;
837 uint32_t tag;
838
839 assert(c);
840 assert(c->ref >= 1);
841
842 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
843
844 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
845
846 t = pa_tagstruct_command(c, PA_COMMAND_EXIT, &tag);
847 pa_pstream_send_tagstruct(c->pstream, t);
848 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);
849
850 return o;
851 }
852
853 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) {
854 pa_tagstruct *t;
855 pa_operation *o;
856 uint32_t tag;
857
858 assert(c);
859 assert(c->ref >= 1);
860
861 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
862
863 o = pa_operation_new(c, NULL, cb, userdata);
864
865 t = pa_tagstruct_command(c, command, &tag);
866 pa_pstream_send_tagstruct(c->pstream, t);
867 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, internal_cb, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
868
869 return o;
870 }
871
872 pa_operation* pa_context_set_default_sink(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) {
873 pa_tagstruct *t;
874 pa_operation *o;
875 uint32_t tag;
876
877 assert(c);
878 assert(c->ref >= 1);
879
880 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
881
882 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
883
884 t = pa_tagstruct_command(c, PA_COMMAND_SET_DEFAULT_SINK, &tag);
885 pa_tagstruct_puts(t, name);
886 pa_pstream_send_tagstruct(c->pstream, t);
887 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);
888
889 return o;
890 }
891
892 pa_operation* pa_context_set_default_source(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) {
893 pa_tagstruct *t;
894 pa_operation *o;
895 uint32_t tag;
896
897 assert(c);
898 assert(c->ref >= 1);
899
900 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
901
902 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
903
904 t = pa_tagstruct_command(c, PA_COMMAND_SET_DEFAULT_SOURCE, &tag);
905 pa_tagstruct_puts(t, name);
906 pa_pstream_send_tagstruct(c->pstream, t);
907 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);
908
909 return o;
910 }
911
912 int pa_context_is_local(pa_context *c) {
913 assert(c);
914
915 return c->local;
916 }
917
918 pa_operation* pa_context_set_name(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) {
919 pa_tagstruct *t;
920 pa_operation *o;
921 uint32_t tag;
922
923 assert(c);
924 assert(c->ref >= 1);
925 assert(name);
926
927 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
928
929 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
930
931 t = pa_tagstruct_command(c, PA_COMMAND_SET_CLIENT_NAME, &tag);
932 pa_tagstruct_puts(t, name);
933 pa_pstream_send_tagstruct(c->pstream, t);
934 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);
935
936 return o;
937 }
938
939 const char* pa_get_library_version(void) {
940 return PACKAGE_VERSION;
941 }
942
943 const char* pa_context_get_server(pa_context *c) {
944 assert(c);
945 assert(c->ref >= 1);
946
947 if (!c->server)
948 return NULL;
949
950 if (*c->server == '{') {
951 char *e = strchr(c->server+1, '}');
952 return e ? e+1 : c->server;
953 }
954
955 return c->server;
956 }
957
958 uint32_t pa_context_get_protocol_version(PA_GCC_UNUSED pa_context *c) {
959 return PA_PROTOCOL_VERSION;
960 }
961
962 uint32_t pa_context_get_server_protocol_version(pa_context *c) {
963 assert(c);
964 assert(c->ref >= 1);
965
966 return c->version;
967 }
968
969 pa_tagstruct *pa_tagstruct_command(pa_context *c, uint32_t command, uint32_t *tag) {
970 pa_tagstruct *t;
971
972 assert(c);
973 assert(tag);
974
975 t = pa_tagstruct_new(NULL, 0);
976 pa_tagstruct_putu32(t, command);
977 pa_tagstruct_putu32(t, *tag = c->ctag++);
978
979 return t;
980 }