]> code.delx.au - pulseaudio/blob - src/pulse/introspect.c
capture: Implement per-stream volume control for capture streams.
[pulseaudio] / src / pulse / introspect.c
1 /***
2 This file is part of PulseAudio.
3
4 Copyright 2004-2006 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
6
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.
11
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.
16
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
20 USA.
21 ***/
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <string.h>
28
29 #include <pulse/context.h>
30 #include <pulse/gccmacro.h>
31 #include <pulse/xmalloc.h>
32 #include <pulse/fork-detect.h>
33
34 #include <pulsecore/macro.h>
35 #include <pulsecore/core-util.h>
36 #include <pulsecore/pstream-util.h>
37
38 #include "internal.h"
39 #include "introspect.h"
40
41 /*** Statistics ***/
42
43 static void context_stat_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
44 pa_operation *o = userdata;
45 pa_stat_info i, *p = &i;
46
47 pa_assert(pd);
48 pa_assert(o);
49 pa_assert(PA_REFCNT_VALUE(o) >= 1);
50
51 pa_zero(i);
52
53 if (!o->context)
54 goto finish;
55
56 if (command != PA_COMMAND_REPLY) {
57 if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
58 goto finish;
59
60 p = NULL;
61 } else if (pa_tagstruct_getu32(t, &i.memblock_total) < 0 ||
62 pa_tagstruct_getu32(t, &i.memblock_total_size) < 0 ||
63 pa_tagstruct_getu32(t, &i.memblock_allocated) < 0 ||
64 pa_tagstruct_getu32(t, &i.memblock_allocated_size) < 0 ||
65 pa_tagstruct_getu32(t, &i.scache_size) < 0 ||
66 !pa_tagstruct_eof(t)) {
67 pa_context_fail(o->context, PA_ERR_PROTOCOL);
68 goto finish;
69 }
70
71 if (o->callback) {
72 pa_stat_info_cb_t cb = (pa_stat_info_cb_t) o->callback;
73 cb(o->context, p, o->userdata);
74 }
75
76 finish:
77 pa_operation_done(o);
78 pa_operation_unref(o);
79 }
80
81 pa_operation* pa_context_stat(pa_context *c, pa_stat_info_cb_t cb, void *userdata) {
82 return pa_context_send_simple_command(c, PA_COMMAND_STAT, context_stat_callback, (pa_operation_cb_t) cb, userdata);
83 }
84
85 /*** Server Info ***/
86
87 static void context_get_server_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
88 pa_operation *o = userdata;
89 pa_server_info i, *p = &i;
90
91 pa_assert(pd);
92 pa_assert(o);
93 pa_assert(PA_REFCNT_VALUE(o) >= 1);
94
95 pa_zero(i);
96
97 if (!o->context)
98 goto finish;
99
100 if (command != PA_COMMAND_REPLY) {
101 if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
102 goto finish;
103
104 p = NULL;
105 } else if (pa_tagstruct_gets(t, &i.server_name) < 0 ||
106 pa_tagstruct_gets(t, &i.server_version) < 0 ||
107 pa_tagstruct_gets(t, &i.user_name) < 0 ||
108 pa_tagstruct_gets(t, &i.host_name) < 0 ||
109 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
110 pa_tagstruct_gets(t, &i.default_sink_name) < 0 ||
111 pa_tagstruct_gets(t, &i.default_source_name) < 0 ||
112 pa_tagstruct_getu32(t, &i.cookie) < 0 ||
113 (o->context->version >= 15 &&
114 pa_tagstruct_get_channel_map(t, &i.channel_map) < 0) ||
115 !pa_tagstruct_eof(t)) {
116
117 pa_context_fail(o->context, PA_ERR_PROTOCOL);
118 goto finish;
119 }
120
121 if (p && o->context->version < 15)
122 pa_channel_map_init_extend(&i.channel_map, i.sample_spec.channels, PA_CHANNEL_MAP_DEFAULT);
123
124 if (o->callback) {
125 pa_server_info_cb_t cb = (pa_server_info_cb_t) o->callback;
126 cb(o->context, p, o->userdata);
127 }
128
129 finish:
130 pa_operation_done(o);
131 pa_operation_unref(o);
132 }
133
134 pa_operation* pa_context_get_server_info(pa_context *c, pa_server_info_cb_t cb, void *userdata) {
135 return pa_context_send_simple_command(c, PA_COMMAND_GET_SERVER_INFO, context_get_server_info_callback, (pa_operation_cb_t) cb, userdata);
136 }
137
138 /*** Sink Info ***/
139
140 static void context_get_sink_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
141 pa_operation *o = userdata;
142 int eol = 1;
143 pa_sink_info i;
144 uint32_t j;
145
146 pa_assert(pd);
147 pa_assert(o);
148 pa_assert(PA_REFCNT_VALUE(o) >= 1);
149
150 /* For safety incase someone use fail: outside the while loop below */
151 pa_zero(i);
152
153 if (!o->context)
154 goto finish;
155
156 if (command != PA_COMMAND_REPLY) {
157 if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
158 goto finish;
159
160 eol = -1;
161 } else {
162
163 while (!pa_tagstruct_eof(t)) {
164 pa_bool_t mute;
165 uint32_t flags;
166 uint32_t state;
167 const char *ap = NULL;
168
169 pa_zero(i);
170 i.proplist = pa_proplist_new();
171 i.base_volume = PA_VOLUME_NORM;
172 i.n_volume_steps = PA_VOLUME_NORM+1;
173 mute = FALSE;
174 state = PA_SINK_INVALID_STATE;
175 i.card = PA_INVALID_INDEX;
176
177 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
178 pa_tagstruct_gets(t, &i.name) < 0 ||
179 pa_tagstruct_gets(t, &i.description) < 0 ||
180 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
181 pa_tagstruct_get_channel_map(t, &i.channel_map) < 0 ||
182 pa_tagstruct_getu32(t, &i.owner_module) < 0 ||
183 pa_tagstruct_get_cvolume(t, &i.volume) < 0 ||
184 pa_tagstruct_get_boolean(t, &mute) < 0 ||
185 pa_tagstruct_getu32(t, &i.monitor_source) < 0 ||
186 pa_tagstruct_gets(t, &i.monitor_source_name) < 0 ||
187 pa_tagstruct_get_usec(t, &i.latency) < 0 ||
188 pa_tagstruct_gets(t, &i.driver) < 0 ||
189 pa_tagstruct_getu32(t, &flags) < 0 ||
190 (o->context->version >= 13 &&
191 (pa_tagstruct_get_proplist(t, i.proplist) < 0 ||
192 pa_tagstruct_get_usec(t, &i.configured_latency) < 0)) ||
193 (o->context->version >= 15 &&
194 (pa_tagstruct_get_volume(t, &i.base_volume) < 0 ||
195 pa_tagstruct_getu32(t, &state) < 0 ||
196 pa_tagstruct_getu32(t, &i.n_volume_steps) < 0 ||
197 pa_tagstruct_getu32(t, &i.card) < 0)) ||
198 (o->context->version >= 16 &&
199 (pa_tagstruct_getu32(t, &i.n_ports)))) {
200
201 goto fail;
202 }
203
204 if (o->context->version >= 16) {
205 if (i.n_ports > 0) {
206 i.ports = pa_xnew(pa_sink_port_info*, i.n_ports+1);
207 i.ports[0] = pa_xnew(pa_sink_port_info, i.n_ports);
208
209 for (j = 0; j < i.n_ports; j++) {
210 if (pa_tagstruct_gets(t, &i.ports[0][j].name) < 0 ||
211 pa_tagstruct_gets(t, &i.ports[0][j].description) < 0 ||
212 pa_tagstruct_getu32(t, &i.ports[0][j].priority) < 0) {
213
214 goto fail;
215 }
216
217 i.ports[j] = &i.ports[0][j];
218 }
219
220 i.ports[j] = NULL;
221 }
222
223 if (pa_tagstruct_gets(t, &ap) < 0)
224 goto fail;
225
226 if (ap) {
227 for (j = 0; j < i.n_ports; j++)
228 if (pa_streq(i.ports[j]->name, ap)) {
229 i.active_port = i.ports[j];
230 break;
231 }
232 }
233 }
234
235 if (o->context->version >= 21) {
236 uint8_t n_formats;
237 if (pa_tagstruct_getu8(t, &n_formats) < 0 || n_formats < 1)
238 goto fail;
239
240 i.formats = pa_xnew0(pa_format_info*, n_formats);
241
242 for (j = 0; j < n_formats; j++) {
243 i.n_formats++;
244 i.formats[j] = pa_format_info_new();
245
246 if (pa_tagstruct_get_format_info(t, i.formats[j]) < 0)
247 goto fail;
248 }
249 }
250
251 i.mute = (int) mute;
252 i.flags = (pa_sink_flags_t) flags;
253 i.state = (pa_sink_state_t) state;
254
255 if (o->callback) {
256 pa_sink_info_cb_t cb = (pa_sink_info_cb_t) o->callback;
257 cb(o->context, &i, 0, o->userdata);
258 }
259
260 if (i.formats) {
261 for (j = 0; j < i.n_formats; j++)
262 pa_format_info_free(i.formats[j]);
263 pa_xfree(i.formats);
264 }
265 if (i.ports) {
266 pa_xfree(i.ports[0]);
267 pa_xfree(i.ports);
268 }
269 pa_proplist_free(i.proplist);
270 }
271 }
272
273 if (o->callback) {
274 pa_sink_info_cb_t cb = (pa_sink_info_cb_t) o->callback;
275 cb(o->context, NULL, eol, o->userdata);
276 }
277
278 finish:
279 pa_operation_done(o);
280 pa_operation_unref(o);
281 return;
282
283 fail:
284 pa_assert(i.proplist);
285
286 pa_context_fail(o->context, PA_ERR_PROTOCOL);
287
288 if (i.formats) {
289 for (j = 0; j < i.n_formats; j++)
290 pa_format_info_free(i.formats[j]);
291 pa_xfree(i.formats);
292 }
293 if (i.ports) {
294 pa_xfree(i.ports[0]);
295 pa_xfree(i.ports);
296 }
297 pa_proplist_free(i.proplist);
298
299 goto finish;
300 }
301
302 pa_operation* pa_context_get_sink_info_list(pa_context *c, pa_sink_info_cb_t cb, void *userdata) {
303 return pa_context_send_simple_command(c, PA_COMMAND_GET_SINK_INFO_LIST, context_get_sink_info_callback, (pa_operation_cb_t) cb, userdata);
304 }
305
306 pa_operation* pa_context_get_sink_info_by_index(pa_context *c, uint32_t idx, pa_sink_info_cb_t cb, void *userdata) {
307 pa_tagstruct *t;
308 pa_operation *o;
309 uint32_t tag;
310
311 pa_assert(c);
312 pa_assert(PA_REFCNT_VALUE(c) >= 1);
313 pa_assert(cb);
314
315 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
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_SINK_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_sink_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_sink_info_by_name(pa_context *c, const char *name, pa_sink_info_cb_t cb, void *userdata) {
330 pa_tagstruct *t;
331 pa_operation *o;
332 uint32_t tag;
333
334 pa_assert(c);
335 pa_assert(PA_REFCNT_VALUE(c) >= 1);
336 pa_assert(cb);
337
338 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
339 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
340 PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
341
342 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
343
344 t = pa_tagstruct_command(c, PA_COMMAND_GET_SINK_INFO, &tag);
345 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
346 pa_tagstruct_puts(t, name);
347 pa_pstream_send_tagstruct(c->pstream, t);
348 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);
349
350 return o;
351 }
352
353 pa_operation* pa_context_set_sink_port_by_index(pa_context *c, uint32_t idx, const char*port, pa_context_success_cb_t cb, void *userdata) {
354 pa_operation *o;
355 pa_tagstruct *t;
356 uint32_t tag;
357
358 pa_assert(c);
359 pa_assert(PA_REFCNT_VALUE(c) >= 1);
360
361 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
362 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
363 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
364 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 16, PA_ERR_NOTSUPPORTED);
365
366 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
367
368 t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_PORT, &tag);
369 pa_tagstruct_putu32(t, idx);
370 pa_tagstruct_puts(t, NULL);
371 pa_tagstruct_puts(t, port);
372 pa_pstream_send_tagstruct(c->pstream, t);
373 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);
374
375 return o;
376 }
377
378 pa_operation* pa_context_set_sink_port_by_name(pa_context *c, const char *name, const char*port, pa_context_success_cb_t cb, void *userdata) {
379 pa_operation *o;
380 pa_tagstruct *t;
381 uint32_t tag;
382
383 pa_assert(c);
384 pa_assert(PA_REFCNT_VALUE(c) >= 1);
385
386 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
387 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
388 PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
389 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 16, PA_ERR_NOTSUPPORTED);
390
391 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
392
393 t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_PORT, &tag);
394 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
395 pa_tagstruct_puts(t, name);
396 pa_tagstruct_puts(t, port);
397 pa_pstream_send_tagstruct(c->pstream, t);
398 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);
399
400 return o;
401 }
402
403 /*** Source info ***/
404
405 static void context_get_source_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
406 pa_operation *o = userdata;
407 int eol = 1;
408 pa_source_info i;
409 uint32_t j;
410
411 pa_assert(pd);
412 pa_assert(o);
413 pa_assert(PA_REFCNT_VALUE(o) >= 1);
414
415 /* For safety incase someone use fail: outside the while loop below */
416 pa_zero(i);
417
418 if (!o->context)
419 goto finish;
420
421 if (command != PA_COMMAND_REPLY) {
422 if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
423 goto finish;
424
425 eol = -1;
426 } else {
427
428 while (!pa_tagstruct_eof(t)) {
429 pa_bool_t mute;
430 uint32_t flags;
431 uint32_t state;
432 const char *ap;
433
434 pa_zero(i);
435 i.proplist = pa_proplist_new();
436 i.base_volume = PA_VOLUME_NORM;
437 i.n_volume_steps = PA_VOLUME_NORM+1;
438 mute = FALSE;
439 state = PA_SOURCE_INVALID_STATE;
440 i.card = PA_INVALID_INDEX;
441
442 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
443 pa_tagstruct_gets(t, &i.name) < 0 ||
444 pa_tagstruct_gets(t, &i.description) < 0 ||
445 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
446 pa_tagstruct_get_channel_map(t, &i.channel_map) < 0 ||
447 pa_tagstruct_getu32(t, &i.owner_module) < 0 ||
448 pa_tagstruct_get_cvolume(t, &i.volume) < 0 ||
449 pa_tagstruct_get_boolean(t, &mute) < 0 ||
450 pa_tagstruct_getu32(t, &i.monitor_of_sink) < 0 ||
451 pa_tagstruct_gets(t, &i.monitor_of_sink_name) < 0 ||
452 pa_tagstruct_get_usec(t, &i.latency) < 0 ||
453 pa_tagstruct_gets(t, &i.driver) < 0 ||
454 pa_tagstruct_getu32(t, &flags) < 0 ||
455 (o->context->version >= 13 &&
456 (pa_tagstruct_get_proplist(t, i.proplist) < 0 ||
457 pa_tagstruct_get_usec(t, &i.configured_latency) < 0)) ||
458 (o->context->version >= 15 &&
459 (pa_tagstruct_get_volume(t, &i.base_volume) < 0 ||
460 pa_tagstruct_getu32(t, &state) < 0 ||
461 pa_tagstruct_getu32(t, &i.n_volume_steps) < 0 ||
462 pa_tagstruct_getu32(t, &i.card) < 0)) ||
463 (o->context->version >= 16 &&
464 (pa_tagstruct_getu32(t, &i.n_ports)))) {
465
466 goto fail;
467 }
468
469 if (o->context->version >= 16) {
470 if (i.n_ports > 0) {
471 i.ports = pa_xnew(pa_source_port_info*, i.n_ports+1);
472 i.ports[0] = pa_xnew(pa_source_port_info, i.n_ports);
473
474 for (j = 0; j < i.n_ports; j++) {
475 if (pa_tagstruct_gets(t, &i.ports[0][j].name) < 0 ||
476 pa_tagstruct_gets(t, &i.ports[0][j].description) < 0 ||
477 pa_tagstruct_getu32(t, &i.ports[0][j].priority) < 0) {
478
479 goto fail;
480 }
481
482 i.ports[j] = &i.ports[0][j];
483 }
484
485 i.ports[j] = NULL;
486 }
487
488 if (pa_tagstruct_gets(t, &ap) < 0)
489 goto fail;
490
491 if (ap) {
492 for (j = 0; j < i.n_ports; j++)
493 if (pa_streq(i.ports[j]->name, ap)) {
494 i.active_port = i.ports[j];
495 break;
496 }
497 }
498 }
499
500 if (o->context->version >= 22) {
501 uint8_t n_formats;
502 if (pa_tagstruct_getu8(t, &n_formats) < 0 || n_formats < 1)
503 goto fail;
504
505 i.formats = pa_xnew0(pa_format_info*, n_formats);
506
507 for (j = 0; j < n_formats; j++) {
508 i.n_formats++;
509 i.formats[j] = pa_format_info_new();
510
511 if (pa_tagstruct_get_format_info(t, i.formats[j]) < 0)
512 goto fail;
513 }
514 }
515
516 i.mute = (int) mute;
517 i.flags = (pa_source_flags_t) flags;
518 i.state = (pa_source_state_t) state;
519
520 if (o->callback) {
521 pa_source_info_cb_t cb = (pa_source_info_cb_t) o->callback;
522 cb(o->context, &i, 0, o->userdata);
523 }
524
525 if (i.formats) {
526 for (j = 0; j < i.n_formats; j++)
527 pa_format_info_free(i.formats[j]);
528 pa_xfree(i.formats);
529 }
530 if (i.ports) {
531 pa_xfree(i.ports[0]);
532 pa_xfree(i.ports);
533 }
534 pa_proplist_free(i.proplist);
535 }
536 }
537
538 if (o->callback) {
539 pa_source_info_cb_t cb = (pa_source_info_cb_t) o->callback;
540 cb(o->context, NULL, eol, o->userdata);
541 }
542
543 finish:
544 pa_operation_done(o);
545 pa_operation_unref(o);
546 return;
547
548 fail:
549 pa_assert(i.proplist);
550
551 pa_context_fail(o->context, PA_ERR_PROTOCOL);
552
553 if (i.formats) {
554 for (j = 0; j < i.n_formats; j++)
555 pa_format_info_free(i.formats[j]);
556 pa_xfree(i.formats);
557 }
558 if (i.ports) {
559 pa_xfree(i.ports[0]);
560 pa_xfree(i.ports);
561 }
562 pa_proplist_free(i.proplist);
563
564 goto finish;
565 }
566
567 pa_operation* pa_context_get_source_info_list(pa_context *c, pa_source_info_cb_t cb, void *userdata) {
568 return pa_context_send_simple_command(c, PA_COMMAND_GET_SOURCE_INFO_LIST, context_get_source_info_callback, (pa_operation_cb_t) cb, userdata);
569 }
570
571 pa_operation* pa_context_get_source_info_by_index(pa_context *c, uint32_t idx, pa_source_info_cb_t cb, void *userdata) {
572 pa_tagstruct *t;
573 pa_operation *o;
574 uint32_t tag;
575
576 pa_assert(c);
577 pa_assert(PA_REFCNT_VALUE(c) >= 1);
578 pa_assert(cb);
579
580 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
581 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
582
583 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
584
585 t = pa_tagstruct_command(c, PA_COMMAND_GET_SOURCE_INFO, &tag);
586 pa_tagstruct_putu32(t, idx);
587 pa_tagstruct_puts(t, NULL);
588 pa_pstream_send_tagstruct(c->pstream, t);
589 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);
590
591 return o;
592 }
593
594 pa_operation* pa_context_get_source_info_by_name(pa_context *c, const char *name, pa_source_info_cb_t cb, void *userdata) {
595 pa_tagstruct *t;
596 pa_operation *o;
597 uint32_t tag;
598
599 pa_assert(c);
600 pa_assert(PA_REFCNT_VALUE(c) >= 1);
601 pa_assert(cb);
602
603 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
604 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
605 PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
606
607 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
608
609 t = pa_tagstruct_command(c, PA_COMMAND_GET_SOURCE_INFO, &tag);
610 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
611 pa_tagstruct_puts(t, name);
612 pa_pstream_send_tagstruct(c->pstream, t);
613 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);
614
615 return o;
616 }
617
618 pa_operation* pa_context_set_source_port_by_index(pa_context *c, uint32_t idx, const char*port, pa_context_success_cb_t cb, void *userdata) {
619 pa_operation *o;
620 pa_tagstruct *t;
621 uint32_t tag;
622
623 pa_assert(c);
624 pa_assert(PA_REFCNT_VALUE(c) >= 1);
625
626 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
627 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
628 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
629 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 16, PA_ERR_NOTSUPPORTED);
630
631 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
632
633 t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_PORT, &tag);
634 pa_tagstruct_putu32(t, idx);
635 pa_tagstruct_puts(t, NULL);
636 pa_tagstruct_puts(t, port);
637 pa_pstream_send_tagstruct(c->pstream, t);
638 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);
639
640 return o;
641 }
642
643 pa_operation* pa_context_set_source_port_by_name(pa_context *c, const char *name, const char*port, pa_context_success_cb_t cb, void *userdata) {
644 pa_operation *o;
645 pa_tagstruct *t;
646 uint32_t tag;
647
648 pa_assert(c);
649 pa_assert(PA_REFCNT_VALUE(c) >= 1);
650
651 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
652 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
653 PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
654 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 16, PA_ERR_NOTSUPPORTED);
655
656 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
657
658 t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_PORT, &tag);
659 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
660 pa_tagstruct_puts(t, name);
661 pa_tagstruct_puts(t, port);
662 pa_pstream_send_tagstruct(c->pstream, t);
663 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);
664
665 return o;
666 }
667
668 /*** Client info ***/
669
670 static void context_get_client_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
671 pa_operation *o = userdata;
672 int eol = 1;
673
674 pa_assert(pd);
675 pa_assert(o);
676 pa_assert(PA_REFCNT_VALUE(o) >= 1);
677
678 if (!o->context)
679 goto finish;
680
681 if (command != PA_COMMAND_REPLY) {
682 if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
683 goto finish;
684
685 eol = -1;
686 } else {
687
688 while (!pa_tagstruct_eof(t)) {
689 pa_client_info i;
690
691 pa_zero(i);
692 i.proplist = pa_proplist_new();
693
694 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
695 pa_tagstruct_gets(t, &i.name) < 0 ||
696 pa_tagstruct_getu32(t, &i.owner_module) < 0 ||
697 pa_tagstruct_gets(t, &i.driver) < 0 ||
698 (o->context->version >= 13 && pa_tagstruct_get_proplist(t, i.proplist) < 0)) {
699
700 pa_context_fail(o->context, PA_ERR_PROTOCOL);
701 pa_proplist_free(i.proplist);
702 goto finish;
703 }
704
705 if (o->callback) {
706 pa_client_info_cb_t cb = (pa_client_info_cb_t) o->callback;
707 cb(o->context, &i, 0, o->userdata);
708 }
709
710 pa_proplist_free(i.proplist);
711 }
712 }
713
714 if (o->callback) {
715 pa_client_info_cb_t cb = (pa_client_info_cb_t) o->callback;
716 cb(o->context, NULL, eol, o->userdata);
717 }
718
719 finish:
720 pa_operation_done(o);
721 pa_operation_unref(o);
722 }
723
724 pa_operation* pa_context_get_client_info(pa_context *c, uint32_t idx, pa_client_info_cb_t cb, void *userdata) {
725 pa_tagstruct *t;
726 pa_operation *o;
727 uint32_t tag;
728
729 pa_assert(c);
730 pa_assert(PA_REFCNT_VALUE(c) >= 1);
731 pa_assert(cb);
732
733 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
734 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
735 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
736
737 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
738
739 t = pa_tagstruct_command(c, PA_COMMAND_GET_CLIENT_INFO, &tag);
740 pa_tagstruct_putu32(t, idx);
741 pa_pstream_send_tagstruct(c->pstream, t);
742 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);
743
744 return o;
745 }
746
747 pa_operation* pa_context_get_client_info_list(pa_context *c, pa_client_info_cb_t cb, void *userdata) {
748 return pa_context_send_simple_command(c, PA_COMMAND_GET_CLIENT_INFO_LIST, context_get_client_info_callback, (pa_operation_cb_t) cb, userdata);
749 }
750
751 /*** Card info ***/
752
753 static void context_get_card_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
754 pa_operation *o = userdata;
755 int eol = 1;
756
757 pa_assert(pd);
758 pa_assert(o);
759 pa_assert(PA_REFCNT_VALUE(o) >= 1);
760
761 if (!o->context)
762 goto finish;
763
764 if (command != PA_COMMAND_REPLY) {
765 if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
766 goto finish;
767
768 eol = -1;
769 } else {
770
771 while (!pa_tagstruct_eof(t)) {
772 pa_card_info i;
773 uint32_t j;
774 const char*ap;
775
776 pa_zero(i);
777
778 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
779 pa_tagstruct_gets(t, &i.name) < 0 ||
780 pa_tagstruct_getu32(t, &i.owner_module) < 0 ||
781 pa_tagstruct_gets(t, &i.driver) < 0 ||
782 pa_tagstruct_getu32(t, &i.n_profiles) < 0) {
783
784 pa_context_fail(o->context, PA_ERR_PROTOCOL);
785 goto finish;
786 }
787
788 if (i.n_profiles > 0) {
789 i.profiles = pa_xnew0(pa_card_profile_info, i.n_profiles+1);
790
791 for (j = 0; j < i.n_profiles; j++) {
792
793 if (pa_tagstruct_gets(t, &i.profiles[j].name) < 0 ||
794 pa_tagstruct_gets(t, &i.profiles[j].description) < 0 ||
795 pa_tagstruct_getu32(t, &i.profiles[j].n_sinks) < 0 ||
796 pa_tagstruct_getu32(t, &i.profiles[j].n_sources) < 0 ||
797 pa_tagstruct_getu32(t, &i.profiles[j].priority) < 0) {
798
799 pa_context_fail(o->context, PA_ERR_PROTOCOL);
800 pa_xfree(i.profiles);
801 goto finish;
802 }
803 }
804
805 /* Terminate with an extra NULL entry, just to make sure */
806 i.profiles[j].name = NULL;
807 i.profiles[j].description = NULL;
808 }
809
810 i.proplist = pa_proplist_new();
811
812 if (pa_tagstruct_gets(t, &ap) < 0 ||
813 pa_tagstruct_get_proplist(t, i.proplist) < 0) {
814
815 pa_context_fail(o->context, PA_ERR_PROTOCOL);
816 pa_xfree(i.profiles);
817 pa_proplist_free(i.proplist);
818 goto finish;
819 }
820
821 if (ap) {
822 for (j = 0; j < i.n_profiles; j++)
823 if (pa_streq(i.profiles[j].name, ap)) {
824 i.active_profile = &i.profiles[j];
825 break;
826 }
827 }
828
829 if (o->callback) {
830 pa_card_info_cb_t cb = (pa_card_info_cb_t) o->callback;
831 cb(o->context, &i, 0, o->userdata);
832 }
833
834 pa_proplist_free(i.proplist);
835 pa_xfree(i.profiles);
836 }
837 }
838
839 if (o->callback) {
840 pa_card_info_cb_t cb = (pa_card_info_cb_t) o->callback;
841 cb(o->context, NULL, eol, o->userdata);
842 }
843
844 finish:
845 pa_operation_done(o);
846 pa_operation_unref(o);
847 }
848
849 pa_operation* pa_context_get_card_info_by_index(pa_context *c, uint32_t idx, pa_card_info_cb_t cb, void *userdata) {
850 pa_tagstruct *t;
851 pa_operation *o;
852 uint32_t tag;
853
854 pa_assert(c);
855 pa_assert(PA_REFCNT_VALUE(c) >= 1);
856 pa_assert(cb);
857
858 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
859 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
860 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
861 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 15, PA_ERR_NOTSUPPORTED);
862
863 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
864
865 t = pa_tagstruct_command(c, PA_COMMAND_GET_CARD_INFO, &tag);
866 pa_tagstruct_putu32(t, idx);
867 pa_tagstruct_puts(t, NULL);
868 pa_pstream_send_tagstruct(c->pstream, t);
869 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_card_info_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
870
871 return o;
872 }
873
874 pa_operation* pa_context_get_card_info_by_name(pa_context *c, const char*name, pa_card_info_cb_t cb, void *userdata) {
875 pa_tagstruct *t;
876 pa_operation *o;
877 uint32_t tag;
878
879 pa_assert(c);
880 pa_assert(PA_REFCNT_VALUE(c) >= 1);
881 pa_assert(cb);
882
883 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
884 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
885 PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
886 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 15, PA_ERR_NOTSUPPORTED);
887
888 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
889
890 t = pa_tagstruct_command(c, PA_COMMAND_GET_CARD_INFO, &tag);
891 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
892 pa_tagstruct_puts(t, name);
893 pa_pstream_send_tagstruct(c->pstream, t);
894 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_card_info_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
895
896 return o;
897 }
898
899 pa_operation* pa_context_get_card_info_list(pa_context *c, pa_card_info_cb_t cb, void *userdata) {
900 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 15, PA_ERR_NOTSUPPORTED);
901
902 return pa_context_send_simple_command(c, PA_COMMAND_GET_CARD_INFO_LIST, context_get_card_info_callback, (pa_operation_cb_t) cb, userdata);
903 }
904
905 pa_operation* pa_context_set_card_profile_by_index(pa_context *c, uint32_t idx, const char*profile, pa_context_success_cb_t cb, void *userdata) {
906 pa_operation *o;
907 pa_tagstruct *t;
908 uint32_t tag;
909
910 pa_assert(c);
911 pa_assert(PA_REFCNT_VALUE(c) >= 1);
912
913 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
914 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
915 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
916 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 15, PA_ERR_NOTSUPPORTED);
917
918 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
919
920 t = pa_tagstruct_command(c, PA_COMMAND_SET_CARD_PROFILE, &tag);
921 pa_tagstruct_putu32(t, idx);
922 pa_tagstruct_puts(t, NULL);
923 pa_tagstruct_puts(t, profile);
924 pa_pstream_send_tagstruct(c->pstream, t);
925 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);
926
927 return o;
928 }
929
930 pa_operation* pa_context_set_card_profile_by_name(pa_context *c, const char *name, const char*profile, pa_context_success_cb_t cb, void *userdata) {
931 pa_operation *o;
932 pa_tagstruct *t;
933 uint32_t tag;
934
935 pa_assert(c);
936 pa_assert(PA_REFCNT_VALUE(c) >= 1);
937
938 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
939 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
940 PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
941 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 15, PA_ERR_NOTSUPPORTED);
942
943 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
944
945 t = pa_tagstruct_command(c, PA_COMMAND_SET_CARD_PROFILE, &tag);
946 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
947 pa_tagstruct_puts(t, name);
948 pa_tagstruct_puts(t, profile);
949 pa_pstream_send_tagstruct(c->pstream, t);
950 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);
951
952 return o;
953 }
954
955 /*** Module info ***/
956
957 static void context_get_module_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
958 pa_operation *o = userdata;
959 int eol = 1;
960
961 pa_assert(pd);
962 pa_assert(o);
963 pa_assert(PA_REFCNT_VALUE(o) >= 1);
964
965 if (!o->context)
966 goto finish;
967
968 if (command != PA_COMMAND_REPLY) {
969 if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
970 goto finish;
971
972 eol = -1;
973 } else {
974
975 while (!pa_tagstruct_eof(t)) {
976 pa_module_info i;
977 pa_bool_t auto_unload = FALSE;
978
979 pa_zero(i);
980 i.proplist = pa_proplist_new();
981
982 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
983 pa_tagstruct_gets(t, &i.name) < 0 ||
984 pa_tagstruct_gets(t, &i.argument) < 0 ||
985 pa_tagstruct_getu32(t, &i.n_used) < 0 ||
986 (o->context->version < 15 && pa_tagstruct_get_boolean(t, &auto_unload) < 0) ||
987 (o->context->version >= 15 && pa_tagstruct_get_proplist(t, i.proplist) < 0)) {
988 pa_context_fail(o->context, PA_ERR_PROTOCOL);
989 goto finish;
990 }
991
992 i.auto_unload = (int) auto_unload;
993
994 if (o->callback) {
995 pa_module_info_cb_t cb = (pa_module_info_cb_t) o->callback;
996 cb(o->context, &i, 0, o->userdata);
997 }
998
999 pa_proplist_free(i.proplist);
1000 }
1001 }
1002
1003 if (o->callback) {
1004 pa_module_info_cb_t cb = (pa_module_info_cb_t) o->callback;
1005 cb(o->context, NULL, eol, o->userdata);
1006 }
1007
1008 finish:
1009 pa_operation_done(o);
1010 pa_operation_unref(o);
1011 }
1012
1013 pa_operation* pa_context_get_module_info(pa_context *c, uint32_t idx, pa_module_info_cb_t cb, void *userdata) {
1014 pa_tagstruct *t;
1015 pa_operation *o;
1016 uint32_t tag;
1017
1018 pa_assert(c);
1019 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1020 pa_assert(cb);
1021
1022 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1023 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1024 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1025
1026 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1027
1028 t = pa_tagstruct_command(c, PA_COMMAND_GET_MODULE_INFO, &tag);
1029 pa_tagstruct_putu32(t, idx);
1030 pa_pstream_send_tagstruct(c->pstream, t);
1031 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);
1032
1033 return o;
1034 }
1035
1036 pa_operation* pa_context_get_module_info_list(pa_context *c, pa_module_info_cb_t cb, void *userdata) {
1037 return pa_context_send_simple_command(c, PA_COMMAND_GET_MODULE_INFO_LIST, context_get_module_info_callback, (pa_operation_cb_t) cb, userdata);
1038 }
1039
1040 /*** Sink input info ***/
1041
1042 static void context_get_sink_input_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1043 pa_operation *o = userdata;
1044 int eol = 1;
1045
1046 pa_assert(pd);
1047 pa_assert(o);
1048 pa_assert(PA_REFCNT_VALUE(o) >= 1);
1049
1050 if (!o->context)
1051 goto finish;
1052
1053 if (command != PA_COMMAND_REPLY) {
1054 if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
1055 goto finish;
1056
1057 eol = -1;
1058 } else {
1059
1060 while (!pa_tagstruct_eof(t)) {
1061 pa_sink_input_info i;
1062 pa_bool_t mute = FALSE, corked = FALSE, has_volume = FALSE, volume_writable = TRUE;
1063
1064 pa_zero(i);
1065 i.proplist = pa_proplist_new();
1066 i.format = pa_format_info_new();
1067
1068 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
1069 pa_tagstruct_gets(t, &i.name) < 0 ||
1070 pa_tagstruct_getu32(t, &i.owner_module) < 0 ||
1071 pa_tagstruct_getu32(t, &i.client) < 0 ||
1072 pa_tagstruct_getu32(t, &i.sink) < 0 ||
1073 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
1074 pa_tagstruct_get_channel_map(t, &i.channel_map) < 0 ||
1075 pa_tagstruct_get_cvolume(t, &i.volume) < 0 ||
1076 pa_tagstruct_get_usec(t, &i.buffer_usec) < 0 ||
1077 pa_tagstruct_get_usec(t, &i.sink_usec) < 0 ||
1078 pa_tagstruct_gets(t, &i.resample_method) < 0 ||
1079 pa_tagstruct_gets(t, &i.driver) < 0 ||
1080 (o->context->version >= 11 && pa_tagstruct_get_boolean(t, &mute) < 0) ||
1081 (o->context->version >= 13 && pa_tagstruct_get_proplist(t, i.proplist) < 0) ||
1082 (o->context->version >= 19 && pa_tagstruct_get_boolean(t, &corked) < 0) ||
1083 (o->context->version >= 20 && (pa_tagstruct_get_boolean(t, &has_volume) < 0 ||
1084 pa_tagstruct_get_boolean(t, &volume_writable) < 0)) ||
1085 (o->context->version >= 21 && pa_tagstruct_get_format_info(t, i.format) < 0)) {
1086
1087 pa_context_fail(o->context, PA_ERR_PROTOCOL);
1088 pa_proplist_free(i.proplist);
1089 pa_format_info_free(i.format);
1090 goto finish;
1091 }
1092
1093 i.mute = (int) mute;
1094 i.corked = (int) corked;
1095 i.has_volume = (int) has_volume;
1096 i.volume_writable = (int) volume_writable;
1097
1098 if (o->callback) {
1099 pa_sink_input_info_cb_t cb = (pa_sink_input_info_cb_t) o->callback;
1100 cb(o->context, &i, 0, o->userdata);
1101 }
1102
1103 pa_proplist_free(i.proplist);
1104 pa_format_info_free(i.format);
1105 }
1106 }
1107
1108 if (o->callback) {
1109 pa_sink_input_info_cb_t cb = (pa_sink_input_info_cb_t) o->callback;
1110 cb(o->context, NULL, eol, o->userdata);
1111 }
1112
1113 finish:
1114 pa_operation_done(o);
1115 pa_operation_unref(o);
1116 }
1117
1118 pa_operation* pa_context_get_sink_input_info(pa_context *c, uint32_t idx, pa_sink_input_info_cb_t cb, void *userdata) {
1119 pa_tagstruct *t;
1120 pa_operation *o;
1121 uint32_t tag;
1122
1123 pa_assert(c);
1124 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1125 pa_assert(cb);
1126
1127 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1128 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1129 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1130
1131 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1132
1133 t = pa_tagstruct_command(c, PA_COMMAND_GET_SINK_INPUT_INFO, &tag);
1134 pa_tagstruct_putu32(t, idx);
1135 pa_pstream_send_tagstruct(c->pstream, t);
1136 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);
1137
1138 return o;
1139 }
1140
1141 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) {
1142 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);
1143 }
1144
1145 /*** Source output info ***/
1146
1147 static void context_get_source_output_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1148 pa_operation *o = userdata;
1149 int eol = 1;
1150
1151 pa_assert(pd);
1152 pa_assert(o);
1153 pa_assert(PA_REFCNT_VALUE(o) >= 1);
1154
1155 if (!o->context)
1156 goto finish;
1157
1158 if (command != PA_COMMAND_REPLY) {
1159 if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
1160 goto finish;
1161
1162 eol = -1;
1163 } else {
1164
1165 while (!pa_tagstruct_eof(t)) {
1166 pa_source_output_info i;
1167 pa_bool_t mute = FALSE, corked = FALSE, has_volume = FALSE, volume_writable = TRUE;
1168
1169 pa_zero(i);
1170 i.proplist = pa_proplist_new();
1171
1172 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
1173 pa_tagstruct_gets(t, &i.name) < 0 ||
1174 pa_tagstruct_getu32(t, &i.owner_module) < 0 ||
1175 pa_tagstruct_getu32(t, &i.client) < 0 ||
1176 pa_tagstruct_getu32(t, &i.source) < 0 ||
1177 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
1178 pa_tagstruct_get_channel_map(t, &i.channel_map) < 0 ||
1179 pa_tagstruct_get_usec(t, &i.buffer_usec) < 0 ||
1180 pa_tagstruct_get_usec(t, &i.source_usec) < 0 ||
1181 pa_tagstruct_gets(t, &i.resample_method) < 0 ||
1182 pa_tagstruct_gets(t, &i.driver) < 0 ||
1183 (o->context->version >= 13 && pa_tagstruct_get_proplist(t, i.proplist) < 0) ||
1184 (o->context->version >= 19 && pa_tagstruct_get_boolean(t, &corked) < 0) ||
1185 (o->context->version >= 22 && (pa_tagstruct_get_cvolume(t, &i.volume) < 0 ||
1186 pa_tagstruct_get_boolean(t, &mute) < 0 ||
1187 pa_tagstruct_get_boolean(t, &has_volume) < 0 ||
1188 pa_tagstruct_get_boolean(t, &volume_writable) < 0))) {
1189
1190 pa_context_fail(o->context, PA_ERR_PROTOCOL);
1191 pa_proplist_free(i.proplist);
1192 goto finish;
1193 }
1194
1195 i.mute = (int) mute;
1196 i.corked = (int) corked;
1197 i.has_volume = (int) has_volume;
1198 i.volume_writable = (int) volume_writable;
1199
1200 if (o->callback) {
1201 pa_source_output_info_cb_t cb = (pa_source_output_info_cb_t) o->callback;
1202 cb(o->context, &i, 0, o->userdata);
1203 }
1204
1205 pa_proplist_free(i.proplist);
1206 }
1207 }
1208
1209 if (o->callback) {
1210 pa_source_output_info_cb_t cb = (pa_source_output_info_cb_t) o->callback;
1211 cb(o->context, NULL, eol, o->userdata);
1212 }
1213
1214 finish:
1215 pa_operation_done(o);
1216 pa_operation_unref(o);
1217 }
1218
1219 pa_operation* pa_context_get_source_output_info(pa_context *c, uint32_t idx, pa_source_output_info_cb_t cb, void *userdata) {
1220 pa_tagstruct *t;
1221 pa_operation *o;
1222 uint32_t tag;
1223
1224 pa_assert(c);
1225 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1226 pa_assert(cb);
1227
1228 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1229 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1230 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1231
1232 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1233
1234 t = pa_tagstruct_command(c, PA_COMMAND_GET_SOURCE_OUTPUT_INFO, &tag);
1235 pa_tagstruct_putu32(t, idx);
1236 pa_pstream_send_tagstruct(c->pstream, t);
1237 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);
1238
1239 return o;
1240 }
1241
1242 pa_operation* pa_context_get_source_output_info_list(pa_context *c, pa_source_output_info_cb_t cb, void *userdata) {
1243 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);
1244 }
1245
1246 /*** Volume manipulation ***/
1247
1248 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) {
1249 pa_operation *o;
1250 pa_tagstruct *t;
1251 uint32_t tag;
1252
1253 pa_assert(c);
1254 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1255 pa_assert(volume);
1256
1257 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1258 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1259 PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID);
1260
1261 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1262
1263 t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_VOLUME, &tag);
1264 pa_tagstruct_putu32(t, idx);
1265 pa_tagstruct_puts(t, NULL);
1266 pa_tagstruct_put_cvolume(t, volume);
1267 pa_pstream_send_tagstruct(c->pstream, t);
1268 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);
1269
1270 return o;
1271 }
1272
1273 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) {
1274 pa_operation *o;
1275 pa_tagstruct *t;
1276 uint32_t tag;
1277
1278 pa_assert(c);
1279 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1280 pa_assert(name);
1281 pa_assert(volume);
1282
1283 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1284 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1285 PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID);
1286 PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
1287
1288 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1289
1290 t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_VOLUME, &tag);
1291 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1292 pa_tagstruct_puts(t, name);
1293 pa_tagstruct_put_cvolume(t, volume);
1294 pa_pstream_send_tagstruct(c->pstream, t);
1295 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);
1296
1297 return o;
1298 }
1299
1300 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) {
1301 pa_operation *o;
1302 pa_tagstruct *t;
1303 uint32_t tag;
1304
1305 pa_assert(c);
1306 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1307
1308 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1309 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1310
1311 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1312
1313 t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_MUTE, &tag);
1314 pa_tagstruct_putu32(t, idx);
1315 pa_tagstruct_puts(t, NULL);
1316 pa_tagstruct_put_boolean(t, mute);
1317 pa_pstream_send_tagstruct(c->pstream, t);
1318 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);
1319
1320 return o;
1321 }
1322
1323 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) {
1324 pa_operation *o;
1325 pa_tagstruct *t;
1326 uint32_t tag;
1327
1328 pa_assert(c);
1329 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1330 pa_assert(name);
1331
1332 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1333 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1334 PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
1335
1336 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1337
1338 t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_MUTE, &tag);
1339 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1340 pa_tagstruct_puts(t, name);
1341 pa_tagstruct_put_boolean(t, mute);
1342 pa_pstream_send_tagstruct(c->pstream, t);
1343 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);
1344
1345 return o;
1346 }
1347
1348 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) {
1349 pa_operation *o;
1350 pa_tagstruct *t;
1351 uint32_t tag;
1352
1353 pa_assert(c);
1354 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1355 pa_assert(volume);
1356
1357 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1358 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1359 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1360 PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID);
1361
1362 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1363
1364 t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_INPUT_VOLUME, &tag);
1365 pa_tagstruct_putu32(t, idx);
1366 pa_tagstruct_put_cvolume(t, volume);
1367 pa_pstream_send_tagstruct(c->pstream, t);
1368 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);
1369
1370 return o;
1371 }
1372
1373 pa_operation* pa_context_set_sink_input_mute(pa_context *c, uint32_t idx, int mute, pa_context_success_cb_t cb, void *userdata) {
1374 pa_operation *o;
1375 pa_tagstruct *t;
1376 uint32_t tag;
1377
1378 pa_assert(c);
1379 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1380
1381 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1382 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1383 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1384 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED);
1385
1386 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1387
1388 t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_INPUT_MUTE, &tag);
1389 pa_tagstruct_putu32(t, idx);
1390 pa_tagstruct_put_boolean(t, mute);
1391 pa_pstream_send_tagstruct(c->pstream, t);
1392 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);
1393
1394 return o;
1395 }
1396
1397 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) {
1398 pa_operation *o;
1399 pa_tagstruct *t;
1400 uint32_t tag;
1401
1402 pa_assert(c);
1403 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1404 pa_assert(volume);
1405
1406 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1407 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1408 PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID);
1409
1410 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1411
1412 t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_VOLUME, &tag);
1413 pa_tagstruct_putu32(t, idx);
1414 pa_tagstruct_puts(t, NULL);
1415 pa_tagstruct_put_cvolume(t, volume);
1416 pa_pstream_send_tagstruct(c->pstream, t);
1417 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);
1418
1419 return o;
1420 }
1421
1422 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) {
1423 pa_operation *o;
1424 pa_tagstruct *t;
1425 uint32_t tag;
1426
1427 pa_assert(c);
1428 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1429 pa_assert(name);
1430 pa_assert(volume);
1431
1432 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1433 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1434 PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID);
1435 PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
1436
1437 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1438
1439 t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_VOLUME, &tag);
1440 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1441 pa_tagstruct_puts(t, name);
1442 pa_tagstruct_put_cvolume(t, volume);
1443 pa_pstream_send_tagstruct(c->pstream, t);
1444 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);
1445
1446 return o;
1447 }
1448
1449 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) {
1450 pa_operation *o;
1451 pa_tagstruct *t;
1452 uint32_t tag;
1453
1454 pa_assert(c);
1455 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1456
1457 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1458 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1459
1460 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1461
1462 t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_MUTE, &tag);
1463 pa_tagstruct_putu32(t, idx);
1464 pa_tagstruct_puts(t, NULL);
1465 pa_tagstruct_put_boolean(t, mute);
1466 pa_pstream_send_tagstruct(c->pstream, t);
1467 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);
1468
1469 return o;
1470 }
1471
1472 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) {
1473 pa_operation *o;
1474 pa_tagstruct *t;
1475 uint32_t tag;
1476
1477 pa_assert(c);
1478 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1479 pa_assert(name);
1480
1481 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1482 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1483 PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
1484
1485 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1486
1487 t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_MUTE, &tag);
1488 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1489 pa_tagstruct_puts(t, name);
1490 pa_tagstruct_put_boolean(t, mute);
1491 pa_pstream_send_tagstruct(c->pstream, t);
1492 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);
1493
1494 return o;
1495 }
1496
1497 pa_operation* pa_context_set_source_output_volume(pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata) {
1498 pa_operation *o;
1499 pa_tagstruct *t;
1500 uint32_t tag;
1501
1502 pa_assert(c);
1503 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1504 pa_assert(volume);
1505
1506 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1507 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1508 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1509 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 22, PA_ERR_NOTSUPPORTED);
1510 PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID);
1511
1512 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1513
1514 t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_OUTPUT_VOLUME, &tag);
1515 pa_tagstruct_putu32(t, idx);
1516 pa_tagstruct_put_cvolume(t, volume);
1517 pa_pstream_send_tagstruct(c->pstream, t);
1518 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);
1519
1520 return o;
1521 }
1522
1523 pa_operation* pa_context_set_source_output_mute(pa_context *c, uint32_t idx, int mute, pa_context_success_cb_t cb, void *userdata) {
1524 pa_operation *o;
1525 pa_tagstruct *t;
1526 uint32_t tag;
1527
1528 pa_assert(c);
1529 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1530
1531 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1532 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1533 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1534 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 22, PA_ERR_NOTSUPPORTED);
1535
1536 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1537
1538 t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_OUTPUT_MUTE, &tag);
1539 pa_tagstruct_putu32(t, idx);
1540 pa_tagstruct_put_boolean(t, mute);
1541 pa_pstream_send_tagstruct(c->pstream, t);
1542 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);
1543
1544 return o;
1545 }
1546
1547 /** Sample Cache **/
1548
1549 static void context_get_sample_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1550 pa_operation *o = userdata;
1551 int eol = 1;
1552
1553 pa_assert(pd);
1554 pa_assert(o);
1555 pa_assert(PA_REFCNT_VALUE(o) >= 1);
1556
1557 if (!o->context)
1558 goto finish;
1559
1560 if (command != PA_COMMAND_REPLY) {
1561 if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
1562 goto finish;
1563
1564 eol = -1;
1565 } else {
1566
1567 while (!pa_tagstruct_eof(t)) {
1568 pa_sample_info i;
1569 pa_bool_t lazy = FALSE;
1570
1571 pa_zero(i);
1572 i.proplist = pa_proplist_new();
1573
1574 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
1575 pa_tagstruct_gets(t, &i.name) < 0 ||
1576 pa_tagstruct_get_cvolume(t, &i.volume) < 0 ||
1577 pa_tagstruct_get_usec(t, &i.duration) < 0 ||
1578 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
1579 pa_tagstruct_get_channel_map(t, &i.channel_map) < 0 ||
1580 pa_tagstruct_getu32(t, &i.bytes) < 0 ||
1581 pa_tagstruct_get_boolean(t, &lazy) < 0 ||
1582 pa_tagstruct_gets(t, &i.filename) < 0 ||
1583 (o->context->version >= 13 && pa_tagstruct_get_proplist(t, i.proplist) < 0)) {
1584
1585 pa_context_fail(o->context, PA_ERR_PROTOCOL);
1586 goto finish;
1587 }
1588
1589 i.lazy = (int) lazy;
1590
1591 if (o->callback) {
1592 pa_sample_info_cb_t cb = (pa_sample_info_cb_t) o->callback;
1593 cb(o->context, &i, 0, o->userdata);
1594 }
1595
1596 pa_proplist_free(i.proplist);
1597 }
1598 }
1599
1600 if (o->callback) {
1601 pa_sample_info_cb_t cb = (pa_sample_info_cb_t) o->callback;
1602 cb(o->context, NULL, eol, o->userdata);
1603 }
1604
1605 finish:
1606 pa_operation_done(o);
1607 pa_operation_unref(o);
1608 }
1609
1610 pa_operation* pa_context_get_sample_info_by_name(pa_context *c, const char *name, pa_sample_info_cb_t cb, void *userdata) {
1611 pa_tagstruct *t;
1612 pa_operation *o;
1613 uint32_t tag;
1614
1615 pa_assert(c);
1616 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1617 pa_assert(cb);
1618
1619 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1620 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1621 PA_CHECK_VALIDITY_RETURN_NULL(c, name && *name, PA_ERR_INVALID);
1622
1623 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1624
1625 t = pa_tagstruct_command(c, PA_COMMAND_GET_SAMPLE_INFO, &tag);
1626 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1627 pa_tagstruct_puts(t, name);
1628 pa_pstream_send_tagstruct(c->pstream, t);
1629 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);
1630
1631 return o;
1632 }
1633
1634 pa_operation* pa_context_get_sample_info_by_index(pa_context *c, uint32_t idx, pa_sample_info_cb_t cb, void *userdata) {
1635 pa_tagstruct *t;
1636 pa_operation *o;
1637 uint32_t tag;
1638
1639 pa_assert(c);
1640 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1641 pa_assert(cb);
1642
1643 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1644 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1645 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1646
1647 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1648
1649 t = pa_tagstruct_command(c, PA_COMMAND_GET_SAMPLE_INFO, &tag);
1650 pa_tagstruct_putu32(t, idx);
1651 pa_tagstruct_puts(t, NULL);
1652 pa_pstream_send_tagstruct(c->pstream, t);
1653 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);
1654
1655 return o;
1656 }
1657
1658 pa_operation* pa_context_get_sample_info_list(pa_context *c, pa_sample_info_cb_t cb, void *userdata) {
1659 return pa_context_send_simple_command(c, PA_COMMAND_GET_SAMPLE_INFO_LIST, context_get_sample_info_callback, (pa_operation_cb_t) cb, userdata);
1660 }
1661
1662 static pa_operation* command_kill(pa_context *c, uint32_t command, uint32_t idx, pa_context_success_cb_t cb, void *userdata) {
1663 pa_operation *o;
1664 pa_tagstruct *t;
1665 uint32_t tag;
1666
1667 pa_assert(c);
1668 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1669
1670 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1671 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1672 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1673
1674 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1675
1676 t = pa_tagstruct_command(c, command, &tag);
1677 pa_tagstruct_putu32(t, idx);
1678 pa_pstream_send_tagstruct(c->pstream, t);
1679 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);
1680
1681 return o;
1682 }
1683
1684 pa_operation* pa_context_kill_client(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata) {
1685 return command_kill(c, PA_COMMAND_KILL_CLIENT, idx, cb, userdata);
1686 }
1687
1688 pa_operation* pa_context_kill_sink_input(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata) {
1689 return command_kill(c, PA_COMMAND_KILL_SINK_INPUT, idx, cb, userdata);
1690 }
1691
1692 pa_operation* pa_context_kill_source_output(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata) {
1693 return command_kill(c, PA_COMMAND_KILL_SOURCE_OUTPUT, idx, cb, userdata);
1694 }
1695
1696 static void context_index_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1697 pa_operation *o = userdata;
1698 uint32_t idx;
1699
1700 pa_assert(pd);
1701 pa_assert(o);
1702 pa_assert(PA_REFCNT_VALUE(o) >= 1);
1703
1704 if (!o->context)
1705 goto finish;
1706
1707 if (command != PA_COMMAND_REPLY) {
1708 if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
1709 goto finish;
1710
1711 idx = PA_INVALID_INDEX;
1712 } else if (pa_tagstruct_getu32(t, &idx) ||
1713 !pa_tagstruct_eof(t)) {
1714 pa_context_fail(o->context, PA_ERR_PROTOCOL);
1715 goto finish;
1716 }
1717
1718 if (o->callback) {
1719 pa_context_index_cb_t cb = (pa_context_index_cb_t) o->callback;
1720 cb(o->context, idx, o->userdata);
1721 }
1722
1723
1724 finish:
1725 pa_operation_done(o);
1726 pa_operation_unref(o);
1727 }
1728
1729 pa_operation* pa_context_load_module(pa_context *c, const char*name, const char *argument, pa_context_index_cb_t cb, void *userdata) {
1730 pa_operation *o;
1731 pa_tagstruct *t;
1732 uint32_t tag;
1733
1734 pa_assert(c);
1735 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1736
1737 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1738 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1739 PA_CHECK_VALIDITY_RETURN_NULL(c, name && *name, PA_ERR_INVALID);
1740
1741 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1742
1743 t = pa_tagstruct_command(c, PA_COMMAND_LOAD_MODULE, &tag);
1744 pa_tagstruct_puts(t, name);
1745 pa_tagstruct_puts(t, argument);
1746 pa_pstream_send_tagstruct(c->pstream, t);
1747 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_index_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1748
1749 return o;
1750 }
1751
1752 pa_operation* pa_context_unload_module(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata) {
1753 return command_kill(c, PA_COMMAND_UNLOAD_MODULE, idx, cb, userdata);
1754 }
1755
1756 /*** Autoload stuff ***/
1757
1758 PA_WARN_REFERENCE(pa_context_get_autoload_info_by_name, "Module auto-loading no longer supported.");
1759
1760 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) {
1761
1762 pa_assert(c);
1763 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1764
1765 PA_FAIL_RETURN_NULL(c, PA_ERR_OBSOLETE);
1766 }
1767
1768 PA_WARN_REFERENCE(pa_context_get_autoload_info_by_index, "Module auto-loading no longer supported.");
1769
1770 pa_operation* pa_context_get_autoload_info_by_index(pa_context *c, uint32_t idx, pa_autoload_info_cb_t cb, void *userdata) {
1771 pa_assert(c);
1772 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1773
1774 PA_FAIL_RETURN_NULL(c, PA_ERR_OBSOLETE);
1775 }
1776
1777 PA_WARN_REFERENCE(pa_context_get_autoload_info_list, "Module auto-loading no longer supported.");
1778
1779 pa_operation* pa_context_get_autoload_info_list(pa_context *c, pa_autoload_info_cb_t cb, void *userdata) {
1780 pa_assert(c);
1781 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1782
1783 PA_FAIL_RETURN_NULL(c, PA_ERR_OBSOLETE);
1784 }
1785
1786 PA_WARN_REFERENCE(pa_context_add_autoload, "Module auto-loading no longer supported.");
1787
1788 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) {
1789 pa_assert(c);
1790 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1791
1792 PA_FAIL_RETURN_NULL(c, PA_ERR_OBSOLETE);
1793 }
1794
1795 PA_WARN_REFERENCE(pa_context_remove_autoload_by_name, "Module auto-loading no longer supported.");
1796
1797 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) {
1798 pa_assert(c);
1799 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1800
1801 PA_FAIL_RETURN_NULL(c, PA_ERR_OBSOLETE);
1802 }
1803
1804 PA_WARN_REFERENCE(pa_context_remove_autoload_by_index, "Module auto-loading no longer supported.");
1805
1806 pa_operation* pa_context_remove_autoload_by_index(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void* userdata) {
1807 pa_assert(c);
1808 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1809
1810 PA_FAIL_RETURN_NULL(c, PA_ERR_OBSOLETE);
1811 }
1812
1813 pa_operation* pa_context_move_sink_input_by_name(pa_context *c, uint32_t idx, const char *sink_name, pa_context_success_cb_t cb, void* userdata) {
1814 pa_operation *o;
1815 pa_tagstruct *t;
1816 uint32_t tag;
1817
1818 pa_assert(c);
1819 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1820
1821 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1822 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1823 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 10, PA_ERR_NOTSUPPORTED);
1824 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1825 PA_CHECK_VALIDITY_RETURN_NULL(c, sink_name && *sink_name, PA_ERR_INVALID);
1826
1827 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1828
1829 t = pa_tagstruct_command(c, PA_COMMAND_MOVE_SINK_INPUT, &tag);
1830 pa_tagstruct_putu32(t, idx);
1831 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1832 pa_tagstruct_puts(t, sink_name);
1833 pa_pstream_send_tagstruct(c->pstream, t);
1834 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);
1835
1836 return o;
1837 }
1838
1839 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) {
1840 pa_operation *o;
1841 pa_tagstruct *t;
1842 uint32_t tag;
1843
1844 pa_assert(c);
1845 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1846
1847 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1848 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1849 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 10, PA_ERR_NOTSUPPORTED);
1850 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1851 PA_CHECK_VALIDITY_RETURN_NULL(c, sink_idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1852
1853 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1854
1855 t = pa_tagstruct_command(c, PA_COMMAND_MOVE_SINK_INPUT, &tag);
1856 pa_tagstruct_putu32(t, idx);
1857 pa_tagstruct_putu32(t, sink_idx);
1858 pa_tagstruct_puts(t, NULL);
1859 pa_pstream_send_tagstruct(c->pstream, t);
1860 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);
1861
1862 return o;
1863 }
1864
1865 pa_operation* pa_context_move_source_output_by_name(pa_context *c, uint32_t idx, const char *source_name, pa_context_success_cb_t cb, void* userdata) {
1866 pa_operation *o;
1867 pa_tagstruct *t;
1868 uint32_t tag;
1869
1870 pa_assert(c);
1871 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1872
1873 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1874 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1875 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 10, PA_ERR_NOTSUPPORTED);
1876 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1877 PA_CHECK_VALIDITY_RETURN_NULL(c, source_name && *source_name, PA_ERR_INVALID);
1878
1879 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1880
1881 t = pa_tagstruct_command(c, PA_COMMAND_MOVE_SOURCE_OUTPUT, &tag);
1882 pa_tagstruct_putu32(t, idx);
1883 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1884 pa_tagstruct_puts(t, source_name);
1885 pa_pstream_send_tagstruct(c->pstream, t);
1886 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);
1887
1888 return o;
1889 }
1890
1891 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) {
1892 pa_operation *o;
1893 pa_tagstruct *t;
1894 uint32_t tag;
1895
1896 pa_assert(c);
1897 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1898
1899 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1900 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1901 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 10, PA_ERR_NOTSUPPORTED);
1902 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1903 PA_CHECK_VALIDITY_RETURN_NULL(c, source_idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1904
1905 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1906
1907 t = pa_tagstruct_command(c, PA_COMMAND_MOVE_SOURCE_OUTPUT, &tag);
1908 pa_tagstruct_putu32(t, idx);
1909 pa_tagstruct_putu32(t, source_idx);
1910 pa_tagstruct_puts(t, NULL);
1911 pa_pstream_send_tagstruct(c->pstream, t);
1912 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);
1913
1914 return o;
1915 }
1916
1917 pa_operation* pa_context_suspend_sink_by_name(pa_context *c, const char *sink_name, int suspend, pa_context_success_cb_t cb, void* userdata) {
1918 pa_operation *o;
1919 pa_tagstruct *t;
1920 uint32_t tag;
1921
1922 pa_assert(c);
1923 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1924
1925 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1926 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1927 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED);
1928 PA_CHECK_VALIDITY_RETURN_NULL(c, !sink_name || *sink_name, PA_ERR_INVALID);
1929
1930 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1931
1932 t = pa_tagstruct_command(c, PA_COMMAND_SUSPEND_SINK, &tag);
1933 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1934 pa_tagstruct_puts(t, sink_name);
1935 pa_tagstruct_put_boolean(t, suspend);
1936 pa_pstream_send_tagstruct(c->pstream, t);
1937 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);
1938
1939 return o;
1940 }
1941
1942 pa_operation* pa_context_suspend_sink_by_index(pa_context *c, uint32_t idx, int suspend, pa_context_success_cb_t cb, void* userdata) {
1943 pa_operation *o;
1944 pa_tagstruct *t;
1945 uint32_t tag;
1946
1947 pa_assert(c);
1948 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1949
1950 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1951 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1952 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED);
1953
1954 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1955
1956 t = pa_tagstruct_command(c, PA_COMMAND_SUSPEND_SINK, &tag);
1957 pa_tagstruct_putu32(t, idx);
1958 pa_tagstruct_puts(t, idx == PA_INVALID_INDEX ? "" : NULL);
1959 pa_tagstruct_put_boolean(t, suspend);
1960 pa_pstream_send_tagstruct(c->pstream, t);
1961 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);
1962
1963 return o;
1964 }
1965
1966 pa_operation* pa_context_suspend_source_by_name(pa_context *c, const char *source_name, int suspend, pa_context_success_cb_t cb, void* userdata) {
1967 pa_operation *o;
1968 pa_tagstruct *t;
1969 uint32_t tag;
1970
1971 pa_assert(c);
1972 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1973
1974 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1975 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1976 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED);
1977 PA_CHECK_VALIDITY_RETURN_NULL(c, !source_name || *source_name, PA_ERR_INVALID);
1978
1979 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1980
1981 t = pa_tagstruct_command(c, PA_COMMAND_SUSPEND_SOURCE, &tag);
1982 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1983 pa_tagstruct_puts(t, source_name);
1984 pa_tagstruct_put_boolean(t, suspend);
1985 pa_pstream_send_tagstruct(c->pstream, t);
1986 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);
1987
1988 return o;
1989 }
1990
1991 pa_operation* pa_context_suspend_source_by_index(pa_context *c, uint32_t idx, int suspend, pa_context_success_cb_t cb, void* userdata) {
1992 pa_operation *o;
1993 pa_tagstruct *t;
1994 uint32_t tag;
1995
1996 pa_assert(c);
1997 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1998
1999 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
2000 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
2001 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED);
2002
2003 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
2004
2005 t = pa_tagstruct_command(c, PA_COMMAND_SUSPEND_SOURCE, &tag);
2006 pa_tagstruct_putu32(t, idx);
2007 pa_tagstruct_puts(t, idx == PA_INVALID_INDEX ? "" : NULL);
2008 pa_tagstruct_put_boolean(t, suspend);
2009 pa_pstream_send_tagstruct(c->pstream, t);
2010 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);
2011
2012 return o;
2013 }