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