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