]> code.delx.au - pulseaudio/blob - src/pulse/introspect.c
add protocol support for muting sink inputs and suspending sinks/sources
[pulseaudio] / src / pulse / introspect.c
1 /* $Id$ */
2
3 /***
4 This file is part of PulseAudio.
5
6 Copyright 2004-2006 Lennart Poettering
7 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
8
9 PulseAudio is free software; you can redistribute it and/or modify
10 it under the terms of the GNU Lesser General Public License as published
11 by the Free Software Foundation; either version 2 of the License,
12 or (at your option) any later version.
13
14 PulseAudio is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public License
20 along with PulseAudio; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22 USA.
23 ***/
24
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28
29 #include <assert.h>
30
31 #include <pulse/context.h>
32
33 #include <pulsecore/gccmacro.h>
34 #include <pulsecore/pstream-util.h>
35
36 #include "internal.h"
37
38 #include "introspect.h"
39
40 /*** Statistics ***/
41
42 static void context_stat_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
43 pa_operation *o = userdata;
44 pa_stat_info i, *p = &i;
45
46 assert(pd);
47 assert(o);
48 assert(o->ref >= 1);
49
50 memset(&i, 0, sizeof(i));
51
52 if (!o->context)
53 goto finish;
54
55 if (command != PA_COMMAND_REPLY) {
56 if (pa_context_handle_error(o->context, command, t) < 0)
57 goto finish;
58
59 p = NULL;
60 } else if (pa_tagstruct_getu32(t, &i.memblock_total) < 0 ||
61 pa_tagstruct_getu32(t, &i.memblock_total_size) < 0 ||
62 pa_tagstruct_getu32(t, &i.memblock_allocated) < 0 ||
63 pa_tagstruct_getu32(t, &i.memblock_allocated_size) < 0 ||
64 pa_tagstruct_getu32(t, &i.scache_size) < 0) {
65 pa_context_fail(o->context, PA_ERR_PROTOCOL);
66 goto finish;
67 }
68
69 if (o->callback) {
70 pa_stat_info_cb_t cb = (pa_stat_info_cb_t) o->callback;
71 cb(o->context, p, o->userdata);
72 }
73
74 finish:
75 pa_operation_done(o);
76 pa_operation_unref(o);
77 }
78
79 pa_operation* pa_context_stat(pa_context *c, pa_stat_info_cb_t cb, void *userdata) {
80 return pa_context_send_simple_command(c, PA_COMMAND_STAT, context_stat_callback, (pa_operation_cb_t) cb, userdata);
81 }
82
83 /*** Server Info ***/
84
85 static void context_get_server_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
86 pa_operation *o = userdata;
87 pa_server_info i, *p = &i;
88
89 assert(pd);
90 assert(o);
91 assert(o->ref >= 1);
92
93 memset(&i, 0, sizeof(i));
94
95 if (!o->context)
96 goto finish;
97
98 if (command != PA_COMMAND_REPLY) {
99 if (pa_context_handle_error(o->context, command, t) < 0)
100 goto finish;
101
102 p = NULL;
103 } else if (pa_tagstruct_gets(t, &i.server_name) < 0 ||
104 pa_tagstruct_gets(t, &i.server_version) < 0 ||
105 pa_tagstruct_gets(t, &i.user_name) < 0 ||
106 pa_tagstruct_gets(t, &i.host_name) < 0 ||
107 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
108 pa_tagstruct_gets(t, &i.default_sink_name) < 0 ||
109 pa_tagstruct_gets(t, &i.default_source_name) < 0 ||
110 pa_tagstruct_getu32(t, &i.cookie) < 0) {
111
112 pa_context_fail(o->context, PA_ERR_PROTOCOL);
113 goto finish;
114 }
115
116 if (o->callback) {
117 pa_server_info_cb_t cb = (pa_server_info_cb_t) o->callback;
118 cb(o->context, p, o->userdata);
119 }
120
121 finish:
122 pa_operation_done(o);
123 pa_operation_unref(o);
124 }
125
126 pa_operation* pa_context_get_server_info(pa_context *c, pa_server_info_cb_t cb, void *userdata) {
127 return pa_context_send_simple_command(c, PA_COMMAND_GET_SERVER_INFO, context_get_server_info_callback, (pa_operation_cb_t) cb, userdata);
128 }
129
130 /*** Sink Info ***/
131
132 static void context_get_sink_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
133 pa_operation *o = userdata;
134 int eol = 1;
135
136 assert(pd);
137 assert(o);
138 assert(o->ref >= 1);
139
140 if (!o->context)
141 goto finish;
142
143 if (command != PA_COMMAND_REPLY) {
144 if (pa_context_handle_error(o->context, command, t) < 0)
145 goto finish;
146
147 eol = -1;
148 } else {
149 uint32_t flags;
150
151 while (!pa_tagstruct_eof(t)) {
152 pa_sink_info i;
153 memset(&i, 0, sizeof(i));
154
155 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
156 pa_tagstruct_gets(t, &i.name) < 0 ||
157 pa_tagstruct_gets(t, &i.description) < 0 ||
158 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
159 pa_tagstruct_get_channel_map(t, &i.channel_map) < 0 ||
160 pa_tagstruct_getu32(t, &i.owner_module) < 0 ||
161 pa_tagstruct_get_cvolume(t, &i.volume) < 0 ||
162 pa_tagstruct_get_boolean(t, &i.mute) < 0 ||
163 pa_tagstruct_getu32(t, &i.monitor_source) < 0 ||
164 pa_tagstruct_gets(t, &i.monitor_source_name) < 0 ||
165 pa_tagstruct_get_usec(t, &i.latency) < 0 ||
166 pa_tagstruct_gets(t, &i.driver) < 0 ||
167 pa_tagstruct_getu32(t, &flags) < 0) {
168
169 pa_context_fail(o->context, PA_ERR_PROTOCOL);
170 goto finish;
171 }
172
173 i.flags = (pa_sink_flags_t) flags;
174
175 if (o->callback) {
176 pa_sink_info_cb_t cb = (pa_sink_info_cb_t) o->callback;
177 cb(o->context, &i, 0, o->userdata);
178 }
179 }
180 }
181
182 if (o->callback) {
183 pa_sink_info_cb_t cb = (pa_sink_info_cb_t) o->callback;
184 cb(o->context, NULL, eol, o->userdata);
185 }
186
187 finish:
188 pa_operation_done(o);
189 pa_operation_unref(o);
190 }
191
192 pa_operation* pa_context_get_sink_info_list(pa_context *c, pa_sink_info_cb_t cb, void *userdata) {
193 return pa_context_send_simple_command(c, PA_COMMAND_GET_SINK_INFO_LIST, context_get_sink_info_callback, (pa_operation_cb_t) cb, userdata);
194 }
195
196 pa_operation* pa_context_get_sink_info_by_index(pa_context *c, uint32_t idx, pa_sink_info_cb_t cb, void *userdata) {
197 pa_tagstruct *t;
198 pa_operation *o;
199 uint32_t tag;
200
201 assert(c);
202 assert(c->ref >= 1);
203 assert(cb);
204
205 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
206
207 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
208
209 t = pa_tagstruct_command(c, PA_COMMAND_GET_SINK_INFO, &tag);
210 pa_tagstruct_putu32(t, idx);
211 pa_tagstruct_puts(t, NULL);
212 pa_pstream_send_tagstruct(c->pstream, t);
213 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_sink_info_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
214
215 return o;
216 }
217
218 pa_operation* pa_context_get_sink_info_by_name(pa_context *c, const char *name, pa_sink_info_cb_t cb, void *userdata) {
219 pa_tagstruct *t;
220 pa_operation *o;
221 uint32_t tag;
222
223 assert(c);
224 assert(c->ref >= 1);
225 assert(cb);
226
227 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
228 PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
229
230 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
231
232 t = pa_tagstruct_command(c, PA_COMMAND_GET_SINK_INFO, &tag);
233 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
234 pa_tagstruct_puts(t, name);
235 pa_pstream_send_tagstruct(c->pstream, t);
236 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_sink_info_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
237
238 return o;
239 }
240
241 /*** Source info ***/
242
243 static void context_get_source_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
244 pa_operation *o = userdata;
245 int eol = 1;
246
247 assert(pd);
248 assert(o);
249 assert(o->ref >= 1);
250
251 if (!o->context)
252 goto finish;
253
254 if (command != PA_COMMAND_REPLY) {
255 if (pa_context_handle_error(o->context, command, t) < 0)
256 goto finish;
257
258 eol = -1;
259 } else {
260
261 while (!pa_tagstruct_eof(t)) {
262 pa_source_info i;
263 uint32_t flags;
264 memset(&i, 0, sizeof(i));
265
266 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
267 pa_tagstruct_gets(t, &i.name) < 0 ||
268 pa_tagstruct_gets(t, &i.description) < 0 ||
269 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
270 pa_tagstruct_get_channel_map(t, &i.channel_map) < 0 ||
271 pa_tagstruct_getu32(t, &i.owner_module) < 0 ||
272 pa_tagstruct_get_cvolume(t, &i.volume) < 0 ||
273 pa_tagstruct_get_boolean(t, &i.mute) < 0 ||
274 pa_tagstruct_getu32(t, &i.monitor_of_sink) < 0 ||
275 pa_tagstruct_gets(t, &i.monitor_of_sink_name) < 0 ||
276 pa_tagstruct_get_usec(t, &i.latency) < 0 ||
277 pa_tagstruct_gets(t, &i.driver) < 0 ||
278 pa_tagstruct_getu32(t, &flags) < 0) {
279
280 pa_context_fail(o->context, PA_ERR_PROTOCOL);
281 goto finish;
282 }
283
284 i.flags = (pa_source_flags_t) flags;
285
286 if (o->callback) {
287 pa_source_info_cb_t cb = (pa_source_info_cb_t) o->callback;
288 cb(o->context, &i, 0, o->userdata);
289 }
290 }
291 }
292
293 if (o->callback) {
294 pa_source_info_cb_t cb = (pa_source_info_cb_t) o->callback;
295 cb(o->context, NULL, eol, o->userdata);
296 }
297
298 finish:
299 pa_operation_done(o);
300 pa_operation_unref(o);
301 }
302
303 pa_operation* pa_context_get_source_info_list(pa_context *c, pa_source_info_cb_t cb, void *userdata) {
304 return pa_context_send_simple_command(c, PA_COMMAND_GET_SOURCE_INFO_LIST, context_get_source_info_callback, (pa_operation_cb_t) cb, userdata);
305 }
306
307 pa_operation* pa_context_get_source_info_by_index(pa_context *c, uint32_t idx, pa_source_info_cb_t cb, void *userdata) {
308 pa_tagstruct *t;
309 pa_operation *o;
310 uint32_t tag;
311
312 assert(c);
313 assert(c->ref >= 1);
314 assert(cb);
315
316 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
317
318 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
319
320 t = pa_tagstruct_command(c, PA_COMMAND_GET_SOURCE_INFO, &tag);
321 pa_tagstruct_putu32(t, idx);
322 pa_tagstruct_puts(t, NULL);
323 pa_pstream_send_tagstruct(c->pstream, t);
324 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_source_info_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
325
326 return o;
327 }
328
329 pa_operation* pa_context_get_source_info_by_name(pa_context *c, const char *name, pa_source_info_cb_t cb, void *userdata) {
330 pa_tagstruct *t;
331 pa_operation *o;
332 uint32_t tag;
333
334 assert(c);
335 assert(c->ref >= 1);
336 assert(cb);
337
338 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
339 PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
340
341 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
342
343 t = pa_tagstruct_command(c, PA_COMMAND_GET_SOURCE_INFO, &tag);
344 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
345 pa_tagstruct_puts(t, name);
346 pa_pstream_send_tagstruct(c->pstream, t);
347 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_source_info_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
348
349 return o;
350 }
351
352 /*** Client info ***/
353
354 static void context_get_client_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
355 pa_operation *o = userdata;
356 int eol = 1;
357
358 assert(pd);
359 assert(o);
360 assert(o->ref >= 1);
361
362 if (!o->context)
363 goto finish;
364
365 if (command != PA_COMMAND_REPLY) {
366 if (pa_context_handle_error(o->context, command, t) < 0)
367 goto finish;
368
369 eol = -1;
370 } else {
371
372 while (!pa_tagstruct_eof(t)) {
373 pa_client_info i;
374 memset(&i, 0, sizeof(i));
375
376 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
377 pa_tagstruct_gets(t, &i.name) < 0 ||
378 pa_tagstruct_getu32(t, &i.owner_module) < 0 ||
379 pa_tagstruct_gets(t, &i.driver) < 0 ) {
380 pa_context_fail(o->context, PA_ERR_PROTOCOL);
381 goto finish;
382 }
383
384 if (o->callback) {
385 pa_client_info_cb_t cb = (pa_client_info_cb_t) o->callback;
386 cb(o->context, &i, 0, o->userdata);
387 }
388 }
389 }
390
391 if (o->callback) {
392 pa_client_info_cb_t cb = (pa_client_info_cb_t) o->callback;
393 cb(o->context, NULL, eol, o->userdata);
394 }
395
396 finish:
397 pa_operation_done(o);
398 pa_operation_unref(o);
399 }
400
401 pa_operation* pa_context_get_client_info(pa_context *c, uint32_t idx, pa_client_info_cb_t cb, void *userdata) {
402 pa_tagstruct *t;
403 pa_operation *o;
404 uint32_t tag;
405
406 assert(c);
407 assert(c->ref >= 1);
408 assert(cb);
409
410 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
411 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
412
413 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
414
415 t = pa_tagstruct_command(c, PA_COMMAND_GET_CLIENT_INFO, &tag);
416 pa_tagstruct_putu32(t, idx);
417 pa_pstream_send_tagstruct(c->pstream, t);
418 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_client_info_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
419
420 return o;
421 }
422
423 pa_operation* pa_context_get_client_info_list(pa_context *c, pa_client_info_cb_t cb, void *userdata) {
424 return pa_context_send_simple_command(c, PA_COMMAND_GET_CLIENT_INFO_LIST, context_get_client_info_callback, (pa_operation_cb_t) cb, userdata);
425 }
426
427 /*** Module info ***/
428
429 static void context_get_module_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
430 pa_operation *o = userdata;
431 int eol = 1;
432
433 assert(pd);
434 assert(o);
435 assert(o->ref >= 1);
436
437 if (!o->context)
438 goto finish;
439
440 if (command != PA_COMMAND_REPLY) {
441 if (pa_context_handle_error(o->context, command, t) < 0)
442 goto finish;
443
444 eol = -1;
445 } else {
446
447 while (!pa_tagstruct_eof(t)) {
448 pa_module_info i;
449 memset(&i, 0, sizeof(i));
450
451 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
452 pa_tagstruct_gets(t, &i.name) < 0 ||
453 pa_tagstruct_gets(t, &i.argument) < 0 ||
454 pa_tagstruct_getu32(t, &i.n_used) < 0 ||
455 pa_tagstruct_get_boolean(t, &i.auto_unload) < 0) {
456 pa_context_fail(o->context, PA_ERR_PROTOCOL);
457 goto finish;
458 }
459
460 if (o->callback) {
461 pa_module_info_cb_t cb = (pa_module_info_cb_t) o->callback;
462 cb(o->context, &i, 0, o->userdata);
463 }
464 }
465 }
466
467 if (o->callback) {
468 pa_module_info_cb_t cb = (pa_module_info_cb_t) o->callback;
469 cb(o->context, NULL, eol, o->userdata);
470 }
471
472 finish:
473 pa_operation_done(o);
474 pa_operation_unref(o);
475 }
476
477 pa_operation* pa_context_get_module_info(pa_context *c, uint32_t idx, pa_module_info_cb_t cb, void *userdata) {
478 pa_tagstruct *t;
479 pa_operation *o;
480 uint32_t tag;
481
482 assert(c);
483 assert(c->ref >= 1);
484 assert(cb);
485
486 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
487 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
488
489 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
490
491 t = pa_tagstruct_command(c, PA_COMMAND_GET_MODULE_INFO, &tag);
492 pa_tagstruct_putu32(t, idx);
493 pa_pstream_send_tagstruct(c->pstream, t);
494 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_module_info_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
495
496 return o;
497 }
498
499 pa_operation* pa_context_get_module_info_list(pa_context *c, pa_module_info_cb_t cb, void *userdata) {
500 return pa_context_send_simple_command(c, PA_COMMAND_GET_MODULE_INFO_LIST, context_get_module_info_callback, (pa_operation_cb_t) cb, userdata);
501 }
502
503 /*** Sink input info ***/
504
505 static void context_get_sink_input_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
506 pa_operation *o = userdata;
507 int eol = 1;
508
509 assert(pd);
510 assert(o);
511 assert(o->ref >= 1);
512
513 if (!o->context)
514 goto finish;
515
516 if (command != PA_COMMAND_REPLY) {
517 if (pa_context_handle_error(o->context, command, t) < 0)
518 goto finish;
519
520 eol = -1;
521 } else {
522
523 while (!pa_tagstruct_eof(t)) {
524 pa_sink_input_info i;
525 memset(&i, 0, sizeof(i));
526
527 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
528 pa_tagstruct_gets(t, &i.name) < 0 ||
529 pa_tagstruct_getu32(t, &i.owner_module) < 0 ||
530 pa_tagstruct_getu32(t, &i.client) < 0 ||
531 pa_tagstruct_getu32(t, &i.sink) < 0 ||
532 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
533 pa_tagstruct_get_channel_map(t, &i.channel_map) < 0 ||
534 pa_tagstruct_get_cvolume(t, &i.volume) < 0 ||
535 pa_tagstruct_get_usec(t, &i.buffer_usec) < 0 ||
536 pa_tagstruct_get_usec(t, &i.sink_usec) < 0 ||
537 pa_tagstruct_gets(t, &i.resample_method) < 0 ||
538 pa_tagstruct_gets(t, &i.driver) < 0 ||
539 (o->context->version >= 11 && pa_tagstruct_get_boolean(t, &i.mute) < 0)) {
540
541 pa_context_fail(o->context, PA_ERR_PROTOCOL);
542 goto finish;
543 }
544
545 if (o->callback) {
546 pa_sink_input_info_cb_t cb = (pa_sink_input_info_cb_t) o->callback;
547 cb(o->context, &i, 0, o->userdata);
548 }
549 }
550 }
551
552 if (o->callback) {
553 pa_sink_input_info_cb_t cb = (pa_sink_input_info_cb_t) o->callback;
554 cb(o->context, NULL, eol, o->userdata);
555 }
556
557 finish:
558 pa_operation_done(o);
559 pa_operation_unref(o);
560 }
561
562 pa_operation* pa_context_get_sink_input_info(pa_context *c, uint32_t idx, pa_sink_input_info_cb_t cb, void *userdata) {
563 pa_tagstruct *t;
564 pa_operation *o;
565 uint32_t tag;
566
567 assert(c);
568 assert(c->ref >= 1);
569 assert(cb);
570
571 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
572 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
573
574 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
575
576 t = pa_tagstruct_command(c, PA_COMMAND_GET_SINK_INPUT_INFO, &tag);
577 pa_tagstruct_putu32(t, idx);
578 pa_pstream_send_tagstruct(c->pstream, t);
579 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_sink_input_info_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
580
581 return o;
582 }
583
584 pa_operation* pa_context_get_sink_input_info_list(pa_context *c, void (*cb)(pa_context *c, const pa_sink_input_info*i, int is_last, void *userdata), void *userdata) {
585 return pa_context_send_simple_command(c, PA_COMMAND_GET_SINK_INPUT_INFO_LIST, context_get_sink_input_info_callback, (pa_operation_cb_t) cb, userdata);
586 }
587
588 /*** Source output info ***/
589
590 static void context_get_source_output_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
591 pa_operation *o = userdata;
592 int eol = 1;
593
594 assert(pd);
595 assert(o);
596 assert(o->ref >= 1);
597
598 if (!o->context)
599 goto finish;
600
601 if (command != PA_COMMAND_REPLY) {
602 if (pa_context_handle_error(o->context, command, t) < 0)
603 goto finish;
604
605 eol = -1;
606 } else {
607
608 while (!pa_tagstruct_eof(t)) {
609 pa_source_output_info i;
610
611 memset(&i, 0, sizeof(i));
612
613 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
614 pa_tagstruct_gets(t, &i.name) < 0 ||
615 pa_tagstruct_getu32(t, &i.owner_module) < 0 ||
616 pa_tagstruct_getu32(t, &i.client) < 0 ||
617 pa_tagstruct_getu32(t, &i.source) < 0 ||
618 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
619 pa_tagstruct_get_channel_map(t, &i.channel_map) < 0 ||
620 pa_tagstruct_get_usec(t, &i.buffer_usec) < 0 ||
621 pa_tagstruct_get_usec(t, &i.source_usec) < 0 ||
622 pa_tagstruct_gets(t, &i.resample_method) < 0 ||
623 pa_tagstruct_gets(t, &i.driver) < 0) {
624
625 pa_context_fail(o->context, PA_ERR_PROTOCOL);
626 goto finish;
627 }
628
629 if (o->callback) {
630 pa_source_output_info_cb_t cb = (pa_source_output_info_cb_t) o->callback;
631 cb(o->context, &i, 0, o->userdata);
632 }
633 }
634 }
635
636 if (o->callback) {
637 pa_source_output_info_cb_t cb = (pa_source_output_info_cb_t) o->callback;
638 cb(o->context, NULL, eol, o->userdata);
639 }
640
641 finish:
642 pa_operation_done(o);
643 pa_operation_unref(o);
644 }
645
646 pa_operation* pa_context_get_source_output_info(pa_context *c, uint32_t idx, pa_source_output_info_cb_t cb, void *userdata) {
647 pa_tagstruct *t;
648 pa_operation *o;
649 uint32_t tag;
650
651 assert(c);
652 assert(c->ref >= 1);
653 assert(cb);
654
655 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
656 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
657
658 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
659
660 t = pa_tagstruct_command(c, PA_COMMAND_GET_SOURCE_OUTPUT_INFO, &tag);
661 pa_tagstruct_putu32(t, idx);
662 pa_pstream_send_tagstruct(c->pstream, t);
663 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_source_output_info_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
664
665 return o;
666 }
667
668 pa_operation* pa_context_get_source_output_info_list(pa_context *c, pa_source_output_info_cb_t cb, void *userdata) {
669 return pa_context_send_simple_command(c, PA_COMMAND_GET_SOURCE_OUTPUT_INFO_LIST, context_get_source_output_info_callback, (pa_operation_cb_t) cb, userdata);
670 }
671
672 /*** Volume manipulation ***/
673
674 pa_operation* pa_context_set_sink_volume_by_index(pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata) {
675 pa_operation *o;
676 pa_tagstruct *t;
677 uint32_t tag;
678
679 assert(c);
680 assert(c->ref >= 1);
681 assert(volume);
682
683 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
684 PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID);
685
686 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
687
688 t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_VOLUME, &tag);
689 pa_tagstruct_putu32(t, idx);
690 pa_tagstruct_puts(t, NULL);
691 pa_tagstruct_put_cvolume(t, volume);
692 pa_pstream_send_tagstruct(c->pstream, t);
693 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);
694
695 return o;
696 }
697
698 pa_operation* pa_context_set_sink_volume_by_name(pa_context *c, const char *name, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata) {
699 pa_operation *o;
700 pa_tagstruct *t;
701 uint32_t tag;
702
703 assert(c);
704 assert(c->ref >= 1);
705 assert(name);
706 assert(volume);
707
708 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
709 PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID);
710 PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
711
712 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
713
714 t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_VOLUME, &tag);
715 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
716 pa_tagstruct_puts(t, name);
717 pa_tagstruct_put_cvolume(t, volume);
718 pa_pstream_send_tagstruct(c->pstream, t);
719 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);
720
721 return o;
722 }
723
724 pa_operation* pa_context_set_sink_mute_by_index(pa_context *c, uint32_t idx, int mute, pa_context_success_cb_t cb, void *userdata) {
725 pa_operation *o;
726 pa_tagstruct *t;
727 uint32_t tag;
728
729 assert(c);
730 assert(c->ref >= 1);
731
732 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
733
734 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
735
736 t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_MUTE, &tag);
737 pa_tagstruct_putu32(t, idx);
738 pa_tagstruct_puts(t, NULL);
739 pa_tagstruct_put_boolean(t, mute);
740 pa_pstream_send_tagstruct(c->pstream, t);
741 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);
742
743 return o;
744 }
745
746 pa_operation* pa_context_set_sink_mute_by_name(pa_context *c, const char *name, int mute, pa_context_success_cb_t cb, void *userdata) {
747 pa_operation *o;
748 pa_tagstruct *t;
749 uint32_t tag;
750
751 assert(c);
752 assert(c->ref >= 1);
753 assert(name);
754
755 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
756 PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
757
758 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
759
760 t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_MUTE, &tag);
761 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
762 pa_tagstruct_puts(t, name);
763 pa_tagstruct_put_boolean(t, mute);
764 pa_pstream_send_tagstruct(c->pstream, t);
765 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);
766
767 return o;
768 }
769
770 pa_operation* pa_context_set_sink_input_volume(pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata) {
771 pa_operation *o;
772 pa_tagstruct *t;
773 uint32_t tag;
774
775 assert(c);
776 assert(c->ref >= 1);
777 assert(volume);
778
779 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
780 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
781 PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID);
782
783 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
784
785 t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_INPUT_VOLUME, &tag);
786 pa_tagstruct_putu32(t, idx);
787 pa_tagstruct_put_cvolume(t, volume);
788 pa_pstream_send_tagstruct(c->pstream, t);
789 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);
790
791 return o;
792 }
793
794 pa_operation* pa_context_set_sink_input_mute(pa_context *c, uint32_t idx, int mute, pa_context_success_cb_t cb, void *userdata) {
795 pa_operation *o;
796 pa_tagstruct *t;
797 uint32_t tag;
798
799 assert(c);
800 assert(c->ref >= 1);
801
802 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
803 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
804 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED);
805
806 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
807
808 t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_INPUT_MUTE, &tag);
809 pa_tagstruct_putu32(t, idx);
810 pa_tagstruct_put_boolean(t, mute);
811 pa_pstream_send_tagstruct(c->pstream, t);
812 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);
813
814 return o;
815 }
816
817 pa_operation* pa_context_set_source_volume_by_index(pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata) {
818 pa_operation *o;
819 pa_tagstruct *t;
820 uint32_t tag;
821
822 assert(c);
823 assert(c->ref >= 1);
824 assert(volume);
825
826 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
827 PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID);
828
829 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
830
831 t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_VOLUME, &tag);
832 pa_tagstruct_putu32(t, idx);
833 pa_tagstruct_puts(t, NULL);
834 pa_tagstruct_put_cvolume(t, volume);
835 pa_pstream_send_tagstruct(c->pstream, t);
836 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);
837
838 return o;
839 }
840
841 pa_operation* pa_context_set_source_volume_by_name(pa_context *c, const char *name, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata) {
842 pa_operation *o;
843 pa_tagstruct *t;
844 uint32_t tag;
845
846 assert(c);
847 assert(c->ref >= 1);
848 assert(name);
849 assert(volume);
850
851 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
852 PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID);
853 PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
854
855 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
856
857 t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_VOLUME, &tag);
858 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
859 pa_tagstruct_puts(t, name);
860 pa_tagstruct_put_cvolume(t, volume);
861 pa_pstream_send_tagstruct(c->pstream, t);
862 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);
863
864 return o;
865 }
866
867 pa_operation* pa_context_set_source_mute_by_index(pa_context *c, uint32_t idx, int mute, pa_context_success_cb_t cb, void *userdata) {
868 pa_operation *o;
869 pa_tagstruct *t;
870 uint32_t tag;
871
872 assert(c);
873 assert(c->ref >= 1);
874
875 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
876
877 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
878
879 t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_MUTE, &tag);
880 pa_tagstruct_putu32(t, idx);
881 pa_tagstruct_puts(t, NULL);
882 pa_tagstruct_put_boolean(t, mute);
883 pa_pstream_send_tagstruct(c->pstream, t);
884 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);
885
886 return o;
887 }
888
889 pa_operation* pa_context_set_source_mute_by_name(pa_context *c, const char *name, int mute, pa_context_success_cb_t cb, void *userdata) {
890 pa_operation *o;
891 pa_tagstruct *t;
892 uint32_t tag;
893
894 assert(c);
895 assert(c->ref >= 1);
896 assert(name);
897
898 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
899 PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
900
901 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
902
903 t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_MUTE, &tag);
904 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
905 pa_tagstruct_puts(t, name);
906 pa_tagstruct_put_boolean(t, mute);
907 pa_pstream_send_tagstruct(c->pstream, t);
908 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);
909
910 return o;
911 }
912
913 /** Sample Cache **/
914
915 static void context_get_sample_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
916 pa_operation *o = userdata;
917 int eol = 1;
918
919 assert(pd);
920 assert(o);
921 assert(o->ref >= 1);
922
923 if (!o->context)
924 goto finish;
925
926 if (command != PA_COMMAND_REPLY) {
927 if (pa_context_handle_error(o->context, command, t) < 0)
928 goto finish;
929
930 eol = -1;
931 } else {
932
933 while (!pa_tagstruct_eof(t)) {
934 pa_sample_info i;
935
936 memset(&i, 0, sizeof(i));
937
938 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
939 pa_tagstruct_gets(t, &i.name) < 0 ||
940 pa_tagstruct_get_cvolume(t, &i.volume) < 0 ||
941 pa_tagstruct_get_usec(t, &i.duration) < 0 ||
942 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
943 pa_tagstruct_get_channel_map(t, &i.channel_map) < 0 ||
944 pa_tagstruct_getu32(t, &i.bytes) < 0 ||
945 pa_tagstruct_get_boolean(t, &i.lazy) < 0 ||
946 pa_tagstruct_gets(t, &i.filename) < 0) {
947
948 pa_context_fail(o->context, PA_ERR_PROTOCOL);
949 goto finish;
950 }
951
952 if (o->callback) {
953 pa_sample_info_cb_t cb = (pa_sample_info_cb_t) o->callback;
954 cb(o->context, &i, 0, o->userdata);
955 }
956 }
957 }
958
959 if (o->callback) {
960 pa_sample_info_cb_t cb = (pa_sample_info_cb_t) o->callback;
961 cb(o->context, NULL, eol, o->userdata);
962 }
963
964 finish:
965 pa_operation_done(o);
966 pa_operation_unref(o);
967 }
968
969 pa_operation* pa_context_get_sample_info_by_name(pa_context *c, const char *name, pa_sample_info_cb_t cb, void *userdata) {
970 pa_tagstruct *t;
971 pa_operation *o;
972 uint32_t tag;
973
974 assert(c);
975 assert(c->ref >= 1);
976 assert(cb);
977
978 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
979 PA_CHECK_VALIDITY_RETURN_NULL(c, name && *name, PA_ERR_INVALID);
980
981 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
982
983 t = pa_tagstruct_command(c, PA_COMMAND_GET_SAMPLE_INFO, &tag);
984 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
985 pa_tagstruct_puts(t, name);
986 pa_pstream_send_tagstruct(c->pstream, t);
987 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_sample_info_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
988
989 return o;
990 }
991
992 pa_operation* pa_context_get_sample_info_by_index(pa_context *c, uint32_t idx, pa_sample_info_cb_t cb, void *userdata) {
993 pa_tagstruct *t;
994 pa_operation *o;
995 uint32_t tag;
996
997 assert(c);
998 assert(c->ref >= 1);
999 assert(cb);
1000
1001 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1002 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1003
1004 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1005
1006 t = pa_tagstruct_command(c, PA_COMMAND_GET_SAMPLE_INFO, &tag);
1007 pa_tagstruct_putu32(t, idx);
1008 pa_tagstruct_puts(t, NULL);
1009 pa_pstream_send_tagstruct(c->pstream, t);
1010 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_sample_info_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1011
1012 return o;
1013 }
1014
1015 pa_operation* pa_context_get_sample_info_list(pa_context *c, pa_sample_info_cb_t cb, void *userdata) {
1016 return pa_context_send_simple_command(c, PA_COMMAND_GET_SAMPLE_INFO_LIST, context_get_sample_info_callback, (pa_operation_cb_t) cb, userdata);
1017 }
1018
1019 static pa_operation* command_kill(pa_context *c, uint32_t command, uint32_t idx, pa_context_success_cb_t cb, void *userdata) {
1020 pa_operation *o;
1021 pa_tagstruct *t;
1022 uint32_t tag;
1023
1024 assert(c);
1025 assert(c->ref >= 1);
1026
1027 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1028 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1029
1030 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1031
1032 t = pa_tagstruct_command(c, command, &tag);
1033 pa_tagstruct_putu32(t, idx);
1034 pa_pstream_send_tagstruct(c->pstream, t);
1035 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);
1036
1037 return o;
1038 }
1039
1040 pa_operation* pa_context_kill_client(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata) {
1041 return command_kill(c, PA_COMMAND_KILL_CLIENT, idx, cb, userdata);
1042 }
1043
1044 pa_operation* pa_context_kill_sink_input(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata) {
1045 return command_kill(c, PA_COMMAND_KILL_SINK_INPUT, idx, cb, userdata);
1046 }
1047
1048 pa_operation* pa_context_kill_source_output(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata) {
1049 return command_kill(c, PA_COMMAND_KILL_SOURCE_OUTPUT, idx, cb, userdata);
1050 }
1051
1052 static void context_index_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
1053 pa_operation *o = userdata;
1054 uint32_t idx;
1055
1056 assert(pd);
1057 assert(o);
1058 assert(o->ref >= 1);
1059
1060 if (!o->context)
1061 goto finish;
1062
1063 if (command != PA_COMMAND_REPLY) {
1064 if (pa_context_handle_error(o->context, command, t) < 0)
1065 goto finish;
1066
1067 idx = PA_INVALID_INDEX;
1068 } else if (pa_tagstruct_getu32(t, &idx) ||
1069 !pa_tagstruct_eof(t)) {
1070 pa_context_fail(o->context, PA_ERR_PROTOCOL);
1071 goto finish;
1072 }
1073
1074 if (o->callback) {
1075 pa_context_index_cb_t cb = (pa_context_index_cb_t) o->callback;
1076 cb(o->context, idx, o->userdata);
1077 }
1078
1079
1080 finish:
1081 pa_operation_done(o);
1082 pa_operation_unref(o);
1083 }
1084
1085 pa_operation* pa_context_load_module(pa_context *c, const char*name, const char *argument, pa_context_index_cb_t cb, void *userdata) {
1086 pa_operation *o;
1087 pa_tagstruct *t;
1088 uint32_t tag;
1089
1090 assert(c);
1091 assert(c->ref >= 1);
1092
1093 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1094 PA_CHECK_VALIDITY_RETURN_NULL(c, name && *name, PA_ERR_INVALID);
1095
1096 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1097
1098 t = pa_tagstruct_command(c, PA_COMMAND_LOAD_MODULE, &tag);
1099 pa_tagstruct_puts(t, name);
1100 pa_tagstruct_puts(t, argument);
1101 pa_pstream_send_tagstruct(c->pstream, t);
1102 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_index_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1103
1104 return o;
1105 }
1106
1107 pa_operation* pa_context_unload_module(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata) {
1108 return command_kill(c, PA_COMMAND_UNLOAD_MODULE, idx, cb, userdata);
1109 }
1110
1111 /*** Autoload stuff ***/
1112
1113 static void context_get_autoload_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
1114 pa_operation *o = userdata;
1115 int eol = 1;
1116
1117 assert(pd);
1118 assert(o);
1119 assert(o->ref >= 1);
1120
1121 if (!o->context)
1122 goto finish;
1123
1124 if (command != PA_COMMAND_REPLY) {
1125 if (pa_context_handle_error(o->context, command, t) < 0)
1126 goto finish;
1127
1128 eol = -1;
1129 } else {
1130
1131 while (!pa_tagstruct_eof(t)) {
1132 pa_autoload_info i;
1133
1134 memset(&i, 0, sizeof(i));
1135
1136 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
1137 pa_tagstruct_gets(t, &i.name) < 0 ||
1138 pa_tagstruct_getu32(t, &i.type) < 0 ||
1139 pa_tagstruct_gets(t, &i.module) < 0 ||
1140 pa_tagstruct_gets(t, &i.argument) < 0) {
1141 pa_context_fail(o->context, PA_ERR_PROTOCOL);
1142 goto finish;
1143 }
1144
1145 if (o->callback) {
1146 pa_autoload_info_cb_t cb = (pa_autoload_info_cb_t) o->callback;
1147 cb(o->context, &i, 0, o->userdata);
1148 }
1149 }
1150 }
1151
1152 if (o->callback) {
1153 pa_autoload_info_cb_t cb = (pa_autoload_info_cb_t) o->callback;
1154 cb(o->context, NULL, eol, o->userdata);
1155 }
1156
1157 finish:
1158 pa_operation_done(o);
1159 pa_operation_unref(o);
1160 }
1161
1162 pa_operation* pa_context_get_autoload_info_by_name(pa_context *c, const char *name, pa_autoload_type_t type, pa_autoload_info_cb_t cb, void *userdata) {
1163 pa_tagstruct *t;
1164 pa_operation *o;
1165 uint32_t tag;
1166
1167 assert(c);
1168 assert(c->ref >= 1);
1169 assert(cb);
1170
1171 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1172 PA_CHECK_VALIDITY_RETURN_NULL(c, name && *name, PA_ERR_INVALID);
1173 PA_CHECK_VALIDITY_RETURN_NULL(c, type == PA_AUTOLOAD_SINK || type == PA_AUTOLOAD_SOURCE, PA_ERR_INVALID);
1174
1175 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1176
1177 t = pa_tagstruct_command(c, PA_COMMAND_GET_AUTOLOAD_INFO, &tag);
1178 pa_tagstruct_puts(t, name);
1179 pa_tagstruct_putu32(t, type);
1180 pa_pstream_send_tagstruct(c->pstream, t);
1181 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_autoload_info_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1182
1183 return o;
1184 }
1185
1186 pa_operation* pa_context_get_autoload_info_by_index(pa_context *c, uint32_t idx, pa_autoload_info_cb_t cb, void *userdata) {
1187 pa_tagstruct *t;
1188 pa_operation *o;
1189 uint32_t tag;
1190
1191 assert(c);
1192 assert(c->ref >= 1);
1193 assert(cb);
1194
1195 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1196 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1197
1198 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1199
1200 t = pa_tagstruct_command(c, PA_COMMAND_GET_AUTOLOAD_INFO, &tag);
1201 pa_tagstruct_putu32(t, idx);
1202 pa_pstream_send_tagstruct(c->pstream, t);
1203 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_autoload_info_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1204
1205 return o;
1206 }
1207
1208 pa_operation* pa_context_get_autoload_info_list(pa_context *c, pa_autoload_info_cb_t cb, void *userdata) {
1209 return pa_context_send_simple_command(c, PA_COMMAND_GET_AUTOLOAD_INFO_LIST, context_get_autoload_info_callback, (pa_operation_cb_t) cb, userdata);
1210 }
1211
1212 pa_operation* pa_context_add_autoload(pa_context *c, const char *name, pa_autoload_type_t type, const char *module, const char*argument, pa_context_index_cb_t cb, void* userdata) {
1213 pa_operation *o;
1214 pa_tagstruct *t;
1215 uint32_t tag;
1216
1217 assert(c);
1218 assert(c->ref >= 1);
1219
1220 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1221 PA_CHECK_VALIDITY_RETURN_NULL(c, name && *name, PA_ERR_INVALID);
1222 PA_CHECK_VALIDITY_RETURN_NULL(c, type == PA_AUTOLOAD_SINK || type == PA_AUTOLOAD_SOURCE, PA_ERR_INVALID);
1223 PA_CHECK_VALIDITY_RETURN_NULL(c, module && *module, PA_ERR_INVALID);
1224
1225 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1226
1227 t = pa_tagstruct_command(c, PA_COMMAND_ADD_AUTOLOAD, &tag);
1228 pa_tagstruct_puts(t, name);
1229 pa_tagstruct_putu32(t, type);
1230 pa_tagstruct_puts(t, module);
1231 pa_tagstruct_puts(t, argument);
1232 pa_pstream_send_tagstruct(c->pstream, t);
1233 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_index_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1234
1235 return o;
1236 }
1237
1238 pa_operation* pa_context_remove_autoload_by_name(pa_context *c, const char *name, pa_autoload_type_t type, pa_context_success_cb_t cb, void* userdata) {
1239 pa_operation *o;
1240 pa_tagstruct *t;
1241 uint32_t tag;
1242
1243 assert(c);
1244 assert(c->ref >= 1);
1245
1246 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1247 PA_CHECK_VALIDITY_RETURN_NULL(c, name && *name, PA_ERR_INVALID);
1248 PA_CHECK_VALIDITY_RETURN_NULL(c, type == PA_AUTOLOAD_SINK || type == PA_AUTOLOAD_SOURCE, PA_ERR_INVALID);
1249
1250 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1251
1252 t = pa_tagstruct_command(c, PA_COMMAND_REMOVE_AUTOLOAD, &tag);
1253 pa_tagstruct_puts(t, name);
1254 pa_tagstruct_putu32(t, type);
1255 pa_pstream_send_tagstruct(c->pstream, t);
1256 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);
1257
1258 return o;
1259 }
1260
1261 pa_operation* pa_context_remove_autoload_by_index(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void* userdata) {
1262 pa_operation *o;
1263 pa_tagstruct *t;
1264 uint32_t tag;
1265
1266 assert(c);
1267 assert(c->ref >= 1);
1268
1269 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1270 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1271
1272 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1273
1274 t = pa_tagstruct_command(c, PA_COMMAND_REMOVE_AUTOLOAD, &tag);
1275 pa_tagstruct_putu32(t, idx);
1276 pa_pstream_send_tagstruct(c->pstream, t);
1277 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);
1278
1279 return o;
1280 }
1281
1282 pa_operation* pa_context_move_sink_input_by_name(pa_context *c, uint32_t idx, char *sink_name, pa_context_success_cb_t cb, void* userdata) {
1283 pa_operation *o;
1284 pa_tagstruct *t;
1285 uint32_t tag;
1286
1287 assert(c);
1288 assert(c->ref >= 1);
1289
1290 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1291 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 10, PA_ERR_NOTSUPPORTED);
1292 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1293 PA_CHECK_VALIDITY_RETURN_NULL(c, sink_name && *sink_name, PA_ERR_INVALID);
1294
1295 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1296
1297 t = pa_tagstruct_command(c, PA_COMMAND_MOVE_SINK_INPUT, &tag);
1298 pa_tagstruct_putu32(t, idx);
1299 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1300 pa_tagstruct_puts(t, sink_name);
1301 pa_pstream_send_tagstruct(c->pstream, t);
1302 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);
1303
1304 return o;
1305 }
1306
1307 pa_operation* pa_context_move_sink_input_by_index(pa_context *c, uint32_t idx, uint32_t sink_idx, pa_context_success_cb_t cb, void* userdata) {
1308 pa_operation *o;
1309 pa_tagstruct *t;
1310 uint32_t tag;
1311
1312 assert(c);
1313 assert(c->ref >= 1);
1314
1315 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1316 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 10, PA_ERR_NOTSUPPORTED);
1317 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1318 PA_CHECK_VALIDITY_RETURN_NULL(c, sink_idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1319
1320 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1321
1322 t = pa_tagstruct_command(c, PA_COMMAND_MOVE_SINK_INPUT, &tag);
1323 pa_tagstruct_putu32(t, idx);
1324 pa_tagstruct_putu32(t, sink_idx);
1325 pa_tagstruct_puts(t, NULL);
1326 pa_pstream_send_tagstruct(c->pstream, t);
1327 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);
1328
1329 return o;
1330 }
1331
1332 pa_operation* pa_context_move_source_output_by_name(pa_context *c, uint32_t idx, char *source_name, pa_context_success_cb_t cb, void* userdata) {
1333 pa_operation *o;
1334 pa_tagstruct *t;
1335 uint32_t tag;
1336
1337 assert(c);
1338 assert(c->ref >= 1);
1339
1340 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1341 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 10, PA_ERR_NOTSUPPORTED);
1342 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1343 PA_CHECK_VALIDITY_RETURN_NULL(c, source_name && *source_name, PA_ERR_INVALID);
1344
1345 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1346
1347 t = pa_tagstruct_command(c, PA_COMMAND_MOVE_SOURCE_OUTPUT, &tag);
1348 pa_tagstruct_putu32(t, idx);
1349 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1350 pa_tagstruct_puts(t, source_name);
1351 pa_pstream_send_tagstruct(c->pstream, t);
1352 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);
1353
1354 return o;
1355 }
1356
1357 pa_operation* pa_context_move_source_output_by_index(pa_context *c, uint32_t idx, uint32_t source_idx, pa_context_success_cb_t cb, void* userdata) {
1358 pa_operation *o;
1359 pa_tagstruct *t;
1360 uint32_t tag;
1361
1362 assert(c);
1363 assert(c->ref >= 1);
1364
1365 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1366 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 10, PA_ERR_NOTSUPPORTED);
1367 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1368 PA_CHECK_VALIDITY_RETURN_NULL(c, source_idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1369
1370 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1371
1372 t = pa_tagstruct_command(c, PA_COMMAND_MOVE_SOURCE_OUTPUT, &tag);
1373 pa_tagstruct_putu32(t, idx);
1374 pa_tagstruct_putu32(t, source_idx);
1375 pa_tagstruct_puts(t, NULL);
1376 pa_pstream_send_tagstruct(c->pstream, t);
1377 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);
1378
1379 return o;
1380 }
1381
1382 pa_operation* pa_context_suspend_sink_by_name(pa_context *c, char *sink_name, int suspend, pa_context_success_cb_t cb, void* userdata) {
1383 pa_operation *o;
1384 pa_tagstruct *t;
1385 uint32_t tag;
1386
1387 assert(c);
1388 assert(c->ref >= 1);
1389
1390 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1391 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED);
1392 PA_CHECK_VALIDITY_RETURN_NULL(c, !sink_name || *sink_name, PA_ERR_INVALID);
1393
1394 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1395
1396 t = pa_tagstruct_command(c, PA_COMMAND_SUSPEND_SINK, &tag);
1397 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1398 pa_tagstruct_puts(t, sink_name);
1399 pa_tagstruct_put_boolean(t, suspend);
1400 pa_pstream_send_tagstruct(c->pstream, t);
1401 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);
1402
1403 return o;
1404 }
1405
1406 pa_operation* pa_context_suspend_sink_by_index(pa_context *c, uint32_t idx, int suspend, pa_context_success_cb_t cb, void* userdata) {
1407 pa_operation *o;
1408 pa_tagstruct *t;
1409 uint32_t tag;
1410
1411 assert(c);
1412 assert(c->ref >= 1);
1413
1414 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1415 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED);
1416
1417 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1418
1419 t = pa_tagstruct_command(c, PA_COMMAND_SUSPEND_SINK, &tag);
1420 pa_tagstruct_putu32(t, idx);
1421 pa_tagstruct_puts(t, idx == PA_INVALID_INDEX ? "" : NULL);
1422 pa_tagstruct_put_boolean(t, suspend);
1423 pa_pstream_send_tagstruct(c->pstream, t);
1424 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);
1425
1426 return o;
1427 }
1428
1429 pa_operation* pa_context_suspend_source_by_name(pa_context *c, char *source_name, int suspend, pa_context_success_cb_t cb, void* userdata) {
1430 pa_operation *o;
1431 pa_tagstruct *t;
1432 uint32_t tag;
1433
1434 assert(c);
1435 assert(c->ref >= 1);
1436
1437 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1438 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED);
1439 PA_CHECK_VALIDITY_RETURN_NULL(c, !source_name || *source_name, PA_ERR_INVALID);
1440
1441 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1442
1443 t = pa_tagstruct_command(c, PA_COMMAND_SUSPEND_SOURCE, &tag);
1444 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1445 pa_tagstruct_puts(t, source_name);
1446 pa_tagstruct_put_boolean(t, suspend);
1447 pa_pstream_send_tagstruct(c->pstream, t);
1448 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);
1449
1450 return o;
1451 }
1452
1453 pa_operation* pa_context_suspend_source_by_index(pa_context *c, uint32_t idx, int suspend, pa_context_success_cb_t cb, void* userdata) {
1454 pa_operation *o;
1455 pa_tagstruct *t;
1456 uint32_t tag;
1457
1458 assert(c);
1459 assert(c->ref >= 1);
1460
1461 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1462 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED);
1463
1464 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1465
1466 t = pa_tagstruct_command(c, PA_COMMAND_SUSPEND_SOURCE, &tag);
1467 pa_tagstruct_putu32(t, idx);
1468 pa_tagstruct_puts(t, idx == PA_INVALID_INDEX ? "" : NULL);
1469 pa_tagstruct_put_boolean(t, suspend);
1470 pa_pstream_send_tagstruct(c->pstream, t);
1471 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);
1472
1473 return o;
1474 }