]> code.delx.au - pulseaudio/blob - src/pulse/introspect.c
014eadfc30028adc934065d40a538702e3c81a4d
[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 i.format = pa_format_info_new();
1172
1173 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
1174 pa_tagstruct_gets(t, &i.name) < 0 ||
1175 pa_tagstruct_getu32(t, &i.owner_module) < 0 ||
1176 pa_tagstruct_getu32(t, &i.client) < 0 ||
1177 pa_tagstruct_getu32(t, &i.source) < 0 ||
1178 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
1179 pa_tagstruct_get_channel_map(t, &i.channel_map) < 0 ||
1180 pa_tagstruct_get_usec(t, &i.buffer_usec) < 0 ||
1181 pa_tagstruct_get_usec(t, &i.source_usec) < 0 ||
1182 pa_tagstruct_gets(t, &i.resample_method) < 0 ||
1183 pa_tagstruct_gets(t, &i.driver) < 0 ||
1184 (o->context->version >= 13 && pa_tagstruct_get_proplist(t, i.proplist) < 0) ||
1185 (o->context->version >= 19 && pa_tagstruct_get_boolean(t, &corked) < 0) ||
1186 (o->context->version >= 22 && (pa_tagstruct_get_cvolume(t, &i.volume) < 0 ||
1187 pa_tagstruct_get_boolean(t, &mute) < 0 ||
1188 pa_tagstruct_get_boolean(t, &has_volume) < 0 ||
1189 pa_tagstruct_get_boolean(t, &volume_writable) < 0 ||
1190 pa_tagstruct_get_format_info(t, i.format) < 0))) {
1191
1192 pa_context_fail(o->context, PA_ERR_PROTOCOL);
1193 pa_proplist_free(i.proplist);
1194 pa_format_info_free(i.format);
1195 goto finish;
1196 }
1197
1198 i.mute = (int) mute;
1199 i.corked = (int) corked;
1200 i.has_volume = (int) has_volume;
1201 i.volume_writable = (int) volume_writable;
1202
1203 if (o->callback) {
1204 pa_source_output_info_cb_t cb = (pa_source_output_info_cb_t) o->callback;
1205 cb(o->context, &i, 0, o->userdata);
1206 }
1207
1208 pa_proplist_free(i.proplist);
1209 pa_format_info_free(i.format);
1210 }
1211 }
1212
1213 if (o->callback) {
1214 pa_source_output_info_cb_t cb = (pa_source_output_info_cb_t) o->callback;
1215 cb(o->context, NULL, eol, o->userdata);
1216 }
1217
1218 finish:
1219 pa_operation_done(o);
1220 pa_operation_unref(o);
1221 }
1222
1223 pa_operation* pa_context_get_source_output_info(pa_context *c, uint32_t idx, pa_source_output_info_cb_t cb, void *userdata) {
1224 pa_tagstruct *t;
1225 pa_operation *o;
1226 uint32_t tag;
1227
1228 pa_assert(c);
1229 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1230 pa_assert(cb);
1231
1232 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1233 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1234 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1235
1236 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1237
1238 t = pa_tagstruct_command(c, PA_COMMAND_GET_SOURCE_OUTPUT_INFO, &tag);
1239 pa_tagstruct_putu32(t, idx);
1240 pa_pstream_send_tagstruct(c->pstream, t);
1241 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);
1242
1243 return o;
1244 }
1245
1246 pa_operation* pa_context_get_source_output_info_list(pa_context *c, pa_source_output_info_cb_t cb, void *userdata) {
1247 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);
1248 }
1249
1250 /*** Volume manipulation ***/
1251
1252 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) {
1253 pa_operation *o;
1254 pa_tagstruct *t;
1255 uint32_t tag;
1256
1257 pa_assert(c);
1258 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1259 pa_assert(volume);
1260
1261 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1262 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1263 PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID);
1264
1265 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1266
1267 t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_VOLUME, &tag);
1268 pa_tagstruct_putu32(t, idx);
1269 pa_tagstruct_puts(t, NULL);
1270 pa_tagstruct_put_cvolume(t, volume);
1271 pa_pstream_send_tagstruct(c->pstream, t);
1272 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);
1273
1274 return o;
1275 }
1276
1277 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) {
1278 pa_operation *o;
1279 pa_tagstruct *t;
1280 uint32_t tag;
1281
1282 pa_assert(c);
1283 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1284 pa_assert(name);
1285 pa_assert(volume);
1286
1287 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1288 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1289 PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID);
1290 PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
1291
1292 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1293
1294 t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_VOLUME, &tag);
1295 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1296 pa_tagstruct_puts(t, name);
1297 pa_tagstruct_put_cvolume(t, volume);
1298 pa_pstream_send_tagstruct(c->pstream, t);
1299 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);
1300
1301 return o;
1302 }
1303
1304 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) {
1305 pa_operation *o;
1306 pa_tagstruct *t;
1307 uint32_t tag;
1308
1309 pa_assert(c);
1310 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1311
1312 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1313 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1314
1315 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1316
1317 t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_MUTE, &tag);
1318 pa_tagstruct_putu32(t, idx);
1319 pa_tagstruct_puts(t, NULL);
1320 pa_tagstruct_put_boolean(t, mute);
1321 pa_pstream_send_tagstruct(c->pstream, t);
1322 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);
1323
1324 return o;
1325 }
1326
1327 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) {
1328 pa_operation *o;
1329 pa_tagstruct *t;
1330 uint32_t tag;
1331
1332 pa_assert(c);
1333 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1334 pa_assert(name);
1335
1336 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1337 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1338 PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
1339
1340 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1341
1342 t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_MUTE, &tag);
1343 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1344 pa_tagstruct_puts(t, name);
1345 pa_tagstruct_put_boolean(t, mute);
1346 pa_pstream_send_tagstruct(c->pstream, t);
1347 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);
1348
1349 return o;
1350 }
1351
1352 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) {
1353 pa_operation *o;
1354 pa_tagstruct *t;
1355 uint32_t tag;
1356
1357 pa_assert(c);
1358 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1359 pa_assert(volume);
1360
1361 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1362 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1363 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1364 PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID);
1365
1366 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1367
1368 t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_INPUT_VOLUME, &tag);
1369 pa_tagstruct_putu32(t, idx);
1370 pa_tagstruct_put_cvolume(t, volume);
1371 pa_pstream_send_tagstruct(c->pstream, t);
1372 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);
1373
1374 return o;
1375 }
1376
1377 pa_operation* pa_context_set_sink_input_mute(pa_context *c, uint32_t idx, int mute, pa_context_success_cb_t cb, void *userdata) {
1378 pa_operation *o;
1379 pa_tagstruct *t;
1380 uint32_t tag;
1381
1382 pa_assert(c);
1383 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1384
1385 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1386 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1387 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1388 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED);
1389
1390 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1391
1392 t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_INPUT_MUTE, &tag);
1393 pa_tagstruct_putu32(t, idx);
1394 pa_tagstruct_put_boolean(t, mute);
1395 pa_pstream_send_tagstruct(c->pstream, t);
1396 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);
1397
1398 return o;
1399 }
1400
1401 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) {
1402 pa_operation *o;
1403 pa_tagstruct *t;
1404 uint32_t tag;
1405
1406 pa_assert(c);
1407 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1408 pa_assert(volume);
1409
1410 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1411 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1412 PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID);
1413
1414 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1415
1416 t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_VOLUME, &tag);
1417 pa_tagstruct_putu32(t, idx);
1418 pa_tagstruct_puts(t, NULL);
1419 pa_tagstruct_put_cvolume(t, volume);
1420 pa_pstream_send_tagstruct(c->pstream, t);
1421 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);
1422
1423 return o;
1424 }
1425
1426 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) {
1427 pa_operation *o;
1428 pa_tagstruct *t;
1429 uint32_t tag;
1430
1431 pa_assert(c);
1432 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1433 pa_assert(name);
1434 pa_assert(volume);
1435
1436 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1437 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1438 PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID);
1439 PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *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_SET_SOURCE_VOLUME, &tag);
1444 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1445 pa_tagstruct_puts(t, name);
1446 pa_tagstruct_put_cvolume(t, volume);
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_set_source_mute_by_index(pa_context *c, uint32_t idx, int mute, pa_context_success_cb_t cb, void *userdata) {
1454 pa_operation *o;
1455 pa_tagstruct *t;
1456 uint32_t tag;
1457
1458 pa_assert(c);
1459 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1460
1461 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1462 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1463
1464 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1465
1466 t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_MUTE, &tag);
1467 pa_tagstruct_putu32(t, idx);
1468 pa_tagstruct_puts(t, NULL);
1469 pa_tagstruct_put_boolean(t, mute);
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 }
1475
1476 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) {
1477 pa_operation *o;
1478 pa_tagstruct *t;
1479 uint32_t tag;
1480
1481 pa_assert(c);
1482 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1483 pa_assert(name);
1484
1485 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1486 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1487 PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
1488
1489 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1490
1491 t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_MUTE, &tag);
1492 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1493 pa_tagstruct_puts(t, name);
1494 pa_tagstruct_put_boolean(t, mute);
1495 pa_pstream_send_tagstruct(c->pstream, t);
1496 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);
1497
1498 return o;
1499 }
1500
1501 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) {
1502 pa_operation *o;
1503 pa_tagstruct *t;
1504 uint32_t tag;
1505
1506 pa_assert(c);
1507 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1508 pa_assert(volume);
1509
1510 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1511 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1512 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1513 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 22, PA_ERR_NOTSUPPORTED);
1514 PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID);
1515
1516 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1517
1518 t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_OUTPUT_VOLUME, &tag);
1519 pa_tagstruct_putu32(t, idx);
1520 pa_tagstruct_put_cvolume(t, volume);
1521 pa_pstream_send_tagstruct(c->pstream, t);
1522 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);
1523
1524 return o;
1525 }
1526
1527 pa_operation* pa_context_set_source_output_mute(pa_context *c, uint32_t idx, int mute, pa_context_success_cb_t cb, void *userdata) {
1528 pa_operation *o;
1529 pa_tagstruct *t;
1530 uint32_t tag;
1531
1532 pa_assert(c);
1533 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1534
1535 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1536 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1537 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1538 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 22, PA_ERR_NOTSUPPORTED);
1539
1540 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1541
1542 t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_OUTPUT_MUTE, &tag);
1543 pa_tagstruct_putu32(t, idx);
1544 pa_tagstruct_put_boolean(t, mute);
1545 pa_pstream_send_tagstruct(c->pstream, t);
1546 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);
1547
1548 return o;
1549 }
1550
1551 /** Sample Cache **/
1552
1553 static void context_get_sample_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1554 pa_operation *o = userdata;
1555 int eol = 1;
1556
1557 pa_assert(pd);
1558 pa_assert(o);
1559 pa_assert(PA_REFCNT_VALUE(o) >= 1);
1560
1561 if (!o->context)
1562 goto finish;
1563
1564 if (command != PA_COMMAND_REPLY) {
1565 if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
1566 goto finish;
1567
1568 eol = -1;
1569 } else {
1570
1571 while (!pa_tagstruct_eof(t)) {
1572 pa_sample_info i;
1573 pa_bool_t lazy = FALSE;
1574
1575 pa_zero(i);
1576 i.proplist = pa_proplist_new();
1577
1578 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
1579 pa_tagstruct_gets(t, &i.name) < 0 ||
1580 pa_tagstruct_get_cvolume(t, &i.volume) < 0 ||
1581 pa_tagstruct_get_usec(t, &i.duration) < 0 ||
1582 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
1583 pa_tagstruct_get_channel_map(t, &i.channel_map) < 0 ||
1584 pa_tagstruct_getu32(t, &i.bytes) < 0 ||
1585 pa_tagstruct_get_boolean(t, &lazy) < 0 ||
1586 pa_tagstruct_gets(t, &i.filename) < 0 ||
1587 (o->context->version >= 13 && pa_tagstruct_get_proplist(t, i.proplist) < 0)) {
1588
1589 pa_context_fail(o->context, PA_ERR_PROTOCOL);
1590 goto finish;
1591 }
1592
1593 i.lazy = (int) lazy;
1594
1595 if (o->callback) {
1596 pa_sample_info_cb_t cb = (pa_sample_info_cb_t) o->callback;
1597 cb(o->context, &i, 0, o->userdata);
1598 }
1599
1600 pa_proplist_free(i.proplist);
1601 }
1602 }
1603
1604 if (o->callback) {
1605 pa_sample_info_cb_t cb = (pa_sample_info_cb_t) o->callback;
1606 cb(o->context, NULL, eol, o->userdata);
1607 }
1608
1609 finish:
1610 pa_operation_done(o);
1611 pa_operation_unref(o);
1612 }
1613
1614 pa_operation* pa_context_get_sample_info_by_name(pa_context *c, const char *name, pa_sample_info_cb_t cb, void *userdata) {
1615 pa_tagstruct *t;
1616 pa_operation *o;
1617 uint32_t tag;
1618
1619 pa_assert(c);
1620 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1621 pa_assert(cb);
1622
1623 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1624 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1625 PA_CHECK_VALIDITY_RETURN_NULL(c, name && *name, PA_ERR_INVALID);
1626
1627 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1628
1629 t = pa_tagstruct_command(c, PA_COMMAND_GET_SAMPLE_INFO, &tag);
1630 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1631 pa_tagstruct_puts(t, name);
1632 pa_pstream_send_tagstruct(c->pstream, t);
1633 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);
1634
1635 return o;
1636 }
1637
1638 pa_operation* pa_context_get_sample_info_by_index(pa_context *c, uint32_t idx, pa_sample_info_cb_t cb, void *userdata) {
1639 pa_tagstruct *t;
1640 pa_operation *o;
1641 uint32_t tag;
1642
1643 pa_assert(c);
1644 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1645 pa_assert(cb);
1646
1647 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1648 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1649 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1650
1651 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1652
1653 t = pa_tagstruct_command(c, PA_COMMAND_GET_SAMPLE_INFO, &tag);
1654 pa_tagstruct_putu32(t, idx);
1655 pa_tagstruct_puts(t, NULL);
1656 pa_pstream_send_tagstruct(c->pstream, t);
1657 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);
1658
1659 return o;
1660 }
1661
1662 pa_operation* pa_context_get_sample_info_list(pa_context *c, pa_sample_info_cb_t cb, void *userdata) {
1663 return pa_context_send_simple_command(c, PA_COMMAND_GET_SAMPLE_INFO_LIST, context_get_sample_info_callback, (pa_operation_cb_t) cb, userdata);
1664 }
1665
1666 static pa_operation* command_kill(pa_context *c, uint32_t command, uint32_t idx, pa_context_success_cb_t cb, void *userdata) {
1667 pa_operation *o;
1668 pa_tagstruct *t;
1669 uint32_t tag;
1670
1671 pa_assert(c);
1672 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1673
1674 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1675 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1676 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1677
1678 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1679
1680 t = pa_tagstruct_command(c, command, &tag);
1681 pa_tagstruct_putu32(t, idx);
1682 pa_pstream_send_tagstruct(c->pstream, t);
1683 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);
1684
1685 return o;
1686 }
1687
1688 pa_operation* pa_context_kill_client(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata) {
1689 return command_kill(c, PA_COMMAND_KILL_CLIENT, idx, cb, userdata);
1690 }
1691
1692 pa_operation* pa_context_kill_sink_input(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata) {
1693 return command_kill(c, PA_COMMAND_KILL_SINK_INPUT, idx, cb, userdata);
1694 }
1695
1696 pa_operation* pa_context_kill_source_output(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata) {
1697 return command_kill(c, PA_COMMAND_KILL_SOURCE_OUTPUT, idx, cb, userdata);
1698 }
1699
1700 static void context_index_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1701 pa_operation *o = userdata;
1702 uint32_t idx;
1703
1704 pa_assert(pd);
1705 pa_assert(o);
1706 pa_assert(PA_REFCNT_VALUE(o) >= 1);
1707
1708 if (!o->context)
1709 goto finish;
1710
1711 if (command != PA_COMMAND_REPLY) {
1712 if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
1713 goto finish;
1714
1715 idx = PA_INVALID_INDEX;
1716 } else if (pa_tagstruct_getu32(t, &idx) ||
1717 !pa_tagstruct_eof(t)) {
1718 pa_context_fail(o->context, PA_ERR_PROTOCOL);
1719 goto finish;
1720 }
1721
1722 if (o->callback) {
1723 pa_context_index_cb_t cb = (pa_context_index_cb_t) o->callback;
1724 cb(o->context, idx, o->userdata);
1725 }
1726
1727
1728 finish:
1729 pa_operation_done(o);
1730 pa_operation_unref(o);
1731 }
1732
1733 pa_operation* pa_context_load_module(pa_context *c, const char*name, const char *argument, pa_context_index_cb_t cb, void *userdata) {
1734 pa_operation *o;
1735 pa_tagstruct *t;
1736 uint32_t tag;
1737
1738 pa_assert(c);
1739 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1740
1741 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1742 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1743 PA_CHECK_VALIDITY_RETURN_NULL(c, name && *name, PA_ERR_INVALID);
1744
1745 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1746
1747 t = pa_tagstruct_command(c, PA_COMMAND_LOAD_MODULE, &tag);
1748 pa_tagstruct_puts(t, name);
1749 pa_tagstruct_puts(t, argument);
1750 pa_pstream_send_tagstruct(c->pstream, t);
1751 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_index_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1752
1753 return o;
1754 }
1755
1756 pa_operation* pa_context_unload_module(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata) {
1757 return command_kill(c, PA_COMMAND_UNLOAD_MODULE, idx, cb, userdata);
1758 }
1759
1760 /*** Autoload stuff ***/
1761
1762 PA_WARN_REFERENCE(pa_context_get_autoload_info_by_name, "Module auto-loading no longer supported.");
1763
1764 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) {
1765
1766 pa_assert(c);
1767 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1768
1769 PA_FAIL_RETURN_NULL(c, PA_ERR_OBSOLETE);
1770 }
1771
1772 PA_WARN_REFERENCE(pa_context_get_autoload_info_by_index, "Module auto-loading no longer supported.");
1773
1774 pa_operation* pa_context_get_autoload_info_by_index(pa_context *c, uint32_t idx, pa_autoload_info_cb_t cb, void *userdata) {
1775 pa_assert(c);
1776 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1777
1778 PA_FAIL_RETURN_NULL(c, PA_ERR_OBSOLETE);
1779 }
1780
1781 PA_WARN_REFERENCE(pa_context_get_autoload_info_list, "Module auto-loading no longer supported.");
1782
1783 pa_operation* pa_context_get_autoload_info_list(pa_context *c, pa_autoload_info_cb_t cb, void *userdata) {
1784 pa_assert(c);
1785 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1786
1787 PA_FAIL_RETURN_NULL(c, PA_ERR_OBSOLETE);
1788 }
1789
1790 PA_WARN_REFERENCE(pa_context_add_autoload, "Module auto-loading no longer supported.");
1791
1792 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) {
1793 pa_assert(c);
1794 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1795
1796 PA_FAIL_RETURN_NULL(c, PA_ERR_OBSOLETE);
1797 }
1798
1799 PA_WARN_REFERENCE(pa_context_remove_autoload_by_name, "Module auto-loading no longer supported.");
1800
1801 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) {
1802 pa_assert(c);
1803 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1804
1805 PA_FAIL_RETURN_NULL(c, PA_ERR_OBSOLETE);
1806 }
1807
1808 PA_WARN_REFERENCE(pa_context_remove_autoload_by_index, "Module auto-loading no longer supported.");
1809
1810 pa_operation* pa_context_remove_autoload_by_index(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void* userdata) {
1811 pa_assert(c);
1812 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1813
1814 PA_FAIL_RETURN_NULL(c, PA_ERR_OBSOLETE);
1815 }
1816
1817 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) {
1818 pa_operation *o;
1819 pa_tagstruct *t;
1820 uint32_t tag;
1821
1822 pa_assert(c);
1823 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1824
1825 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1826 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1827 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 10, PA_ERR_NOTSUPPORTED);
1828 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1829 PA_CHECK_VALIDITY_RETURN_NULL(c, sink_name && *sink_name, PA_ERR_INVALID);
1830
1831 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1832
1833 t = pa_tagstruct_command(c, PA_COMMAND_MOVE_SINK_INPUT, &tag);
1834 pa_tagstruct_putu32(t, idx);
1835 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1836 pa_tagstruct_puts(t, sink_name);
1837 pa_pstream_send_tagstruct(c->pstream, t);
1838 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);
1839
1840 return o;
1841 }
1842
1843 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) {
1844 pa_operation *o;
1845 pa_tagstruct *t;
1846 uint32_t tag;
1847
1848 pa_assert(c);
1849 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1850
1851 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1852 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1853 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 10, PA_ERR_NOTSUPPORTED);
1854 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1855 PA_CHECK_VALIDITY_RETURN_NULL(c, sink_idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1856
1857 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1858
1859 t = pa_tagstruct_command(c, PA_COMMAND_MOVE_SINK_INPUT, &tag);
1860 pa_tagstruct_putu32(t, idx);
1861 pa_tagstruct_putu32(t, sink_idx);
1862 pa_tagstruct_puts(t, NULL);
1863 pa_pstream_send_tagstruct(c->pstream, t);
1864 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);
1865
1866 return o;
1867 }
1868
1869 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) {
1870 pa_operation *o;
1871 pa_tagstruct *t;
1872 uint32_t tag;
1873
1874 pa_assert(c);
1875 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1876
1877 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1878 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1879 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 10, PA_ERR_NOTSUPPORTED);
1880 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1881 PA_CHECK_VALIDITY_RETURN_NULL(c, source_name && *source_name, PA_ERR_INVALID);
1882
1883 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1884
1885 t = pa_tagstruct_command(c, PA_COMMAND_MOVE_SOURCE_OUTPUT, &tag);
1886 pa_tagstruct_putu32(t, idx);
1887 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1888 pa_tagstruct_puts(t, source_name);
1889 pa_pstream_send_tagstruct(c->pstream, t);
1890 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);
1891
1892 return o;
1893 }
1894
1895 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) {
1896 pa_operation *o;
1897 pa_tagstruct *t;
1898 uint32_t tag;
1899
1900 pa_assert(c);
1901 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1902
1903 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1904 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1905 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 10, PA_ERR_NOTSUPPORTED);
1906 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1907 PA_CHECK_VALIDITY_RETURN_NULL(c, source_idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1908
1909 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1910
1911 t = pa_tagstruct_command(c, PA_COMMAND_MOVE_SOURCE_OUTPUT, &tag);
1912 pa_tagstruct_putu32(t, idx);
1913 pa_tagstruct_putu32(t, source_idx);
1914 pa_tagstruct_puts(t, NULL);
1915 pa_pstream_send_tagstruct(c->pstream, t);
1916 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);
1917
1918 return o;
1919 }
1920
1921 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) {
1922 pa_operation *o;
1923 pa_tagstruct *t;
1924 uint32_t tag;
1925
1926 pa_assert(c);
1927 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1928
1929 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1930 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1931 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED);
1932 PA_CHECK_VALIDITY_RETURN_NULL(c, !sink_name || *sink_name, PA_ERR_INVALID);
1933
1934 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1935
1936 t = pa_tagstruct_command(c, PA_COMMAND_SUSPEND_SINK, &tag);
1937 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1938 pa_tagstruct_puts(t, sink_name);
1939 pa_tagstruct_put_boolean(t, suspend);
1940 pa_pstream_send_tagstruct(c->pstream, t);
1941 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);
1942
1943 return o;
1944 }
1945
1946 pa_operation* pa_context_suspend_sink_by_index(pa_context *c, uint32_t idx, int suspend, pa_context_success_cb_t cb, void* userdata) {
1947 pa_operation *o;
1948 pa_tagstruct *t;
1949 uint32_t tag;
1950
1951 pa_assert(c);
1952 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1953
1954 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1955 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1956 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED);
1957
1958 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1959
1960 t = pa_tagstruct_command(c, PA_COMMAND_SUSPEND_SINK, &tag);
1961 pa_tagstruct_putu32(t, idx);
1962 pa_tagstruct_puts(t, idx == PA_INVALID_INDEX ? "" : NULL);
1963 pa_tagstruct_put_boolean(t, suspend);
1964 pa_pstream_send_tagstruct(c->pstream, t);
1965 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);
1966
1967 return o;
1968 }
1969
1970 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) {
1971 pa_operation *o;
1972 pa_tagstruct *t;
1973 uint32_t tag;
1974
1975 pa_assert(c);
1976 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1977
1978 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1979 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1980 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED);
1981 PA_CHECK_VALIDITY_RETURN_NULL(c, !source_name || *source_name, PA_ERR_INVALID);
1982
1983 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1984
1985 t = pa_tagstruct_command(c, PA_COMMAND_SUSPEND_SOURCE, &tag);
1986 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1987 pa_tagstruct_puts(t, source_name);
1988 pa_tagstruct_put_boolean(t, suspend);
1989 pa_pstream_send_tagstruct(c->pstream, t);
1990 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);
1991
1992 return o;
1993 }
1994
1995 pa_operation* pa_context_suspend_source_by_index(pa_context *c, uint32_t idx, int suspend, pa_context_success_cb_t cb, void* userdata) {
1996 pa_operation *o;
1997 pa_tagstruct *t;
1998 uint32_t tag;
1999
2000 pa_assert(c);
2001 pa_assert(PA_REFCNT_VALUE(c) >= 1);
2002
2003 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
2004 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
2005 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED);
2006
2007 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
2008
2009 t = pa_tagstruct_command(c, PA_COMMAND_SUSPEND_SOURCE, &tag);
2010 pa_tagstruct_putu32(t, idx);
2011 pa_tagstruct_puts(t, idx == PA_INVALID_INDEX ? "" : NULL);
2012 pa_tagstruct_put_boolean(t, suspend);
2013 pa_pstream_send_tagstruct(c->pstream, t);
2014 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);
2015
2016 return o;
2017 }