]> code.delx.au - pulseaudio/blob - src/pulse/introspect.c
introspect: Add functions to handle the latency offset.
[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 if (i->proplist)
768 pa_proplist_free(i->proplist);
769
770 pa_xfree(i->profiles);
771
772 if (i->ports) {
773 uint32_t j;
774
775 for (j = 0; j < i->n_ports; j++) {
776 if (i->ports[j]) {
777 if (i->ports[j]->profiles)
778 pa_xfree(i->ports[j]->profiles);
779 if (i->ports[j]->proplist)
780 pa_proplist_free(i->ports[j]->proplist);
781 }
782 }
783
784 pa_xfree(i->ports[0]);
785 pa_xfree(i->ports);
786 }
787 }
788
789 static int fill_card_port_info(pa_context *context, pa_tagstruct* t, pa_card_info* i) {
790 uint32_t j, k, l;
791
792 if (pa_tagstruct_getu32(t, &i->n_ports) < 0)
793 return -PA_ERR_PROTOCOL;
794
795 if (i->n_ports == 0) {
796 i->ports = NULL;
797 return 0;
798 }
799
800 i->ports = pa_xnew0(pa_card_port_info*, i->n_ports+1);
801 i->ports[0] = pa_xnew0(pa_card_port_info, i->n_ports);
802
803 for (j = 0; j < i->n_ports; j++) {
804 uint8_t direction;
805 uint32_t available;
806 pa_card_port_info* port = i->ports[j] = &i->ports[0][j];
807
808 port->proplist = pa_proplist_new();
809
810 if (pa_tagstruct_gets(t, &port->name) < 0 ||
811 pa_tagstruct_gets(t, &port->description) < 0 ||
812 pa_tagstruct_getu32(t, &port->priority) < 0 ||
813 pa_tagstruct_getu32(t, &available) < 0 ||
814 pa_tagstruct_getu8(t, &direction) < 0 ||
815 pa_tagstruct_get_proplist(t, port->proplist) < 0 ||
816 pa_tagstruct_getu32(t, &port->n_profiles) < 0) {
817
818 return -PA_ERR_PROTOCOL;
819 }
820
821 if (available > PA_PORT_AVAILABLE_YES ||
822 direction > PA_DIRECTION_OUTPUT + PA_DIRECTION_INPUT) {
823
824 return -PA_ERR_PROTOCOL;
825 }
826
827 port->direction = direction;
828 port->available = available;
829
830 if (port->n_profiles > 0) {
831 port->profiles = pa_xnew0(pa_card_profile_info*, i->n_profiles+1);
832
833 for (k = 0; k < port->n_profiles; k++) {
834 const char* profilename;
835
836 if (pa_tagstruct_gets(t, &profilename) < 0)
837 return -PA_ERR_PROTOCOL;
838
839 for (l = 0; l < i->n_profiles; l++) {
840 if (pa_streq(i->profiles[l].name, profilename)) {
841 port->profiles[k] = &i->profiles[l];
842 break;
843 }
844 }
845
846 if (l >= i->n_profiles)
847 return -PA_ERR_PROTOCOL;
848 }
849 }
850 if (context->version >= 27) {
851 if (pa_tagstruct_gets64(t, &port->latency_offset) < 0)
852 return -PA_ERR_PROTOCOL;
853 } else
854 port->latency_offset = 0;
855 }
856
857 return 0;
858 }
859
860 static void context_get_card_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
861 pa_operation *o = userdata;
862 int eol = 1;
863 pa_card_info i;
864
865 pa_assert(pd);
866 pa_assert(o);
867 pa_assert(PA_REFCNT_VALUE(o) >= 1);
868
869 if (!o->context)
870 goto finish;
871
872 if (command != PA_COMMAND_REPLY) {
873 if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
874 goto finish;
875
876 eol = -1;
877 } else {
878
879 while (!pa_tagstruct_eof(t)) {
880 uint32_t j;
881 const char*ap;
882
883 pa_zero(i);
884
885 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
886 pa_tagstruct_gets(t, &i.name) < 0 ||
887 pa_tagstruct_getu32(t, &i.owner_module) < 0 ||
888 pa_tagstruct_gets(t, &i.driver) < 0 ||
889 pa_tagstruct_getu32(t, &i.n_profiles) < 0) {
890
891 pa_context_fail(o->context, PA_ERR_PROTOCOL);
892 card_info_free(&i);
893 goto finish;
894 }
895
896 if (i.n_profiles > 0) {
897 i.profiles = pa_xnew0(pa_card_profile_info, i.n_profiles+1);
898
899 for (j = 0; j < i.n_profiles; j++) {
900
901 if (pa_tagstruct_gets(t, &i.profiles[j].name) < 0 ||
902 pa_tagstruct_gets(t, &i.profiles[j].description) < 0 ||
903 pa_tagstruct_getu32(t, &i.profiles[j].n_sinks) < 0 ||
904 pa_tagstruct_getu32(t, &i.profiles[j].n_sources) < 0 ||
905 pa_tagstruct_getu32(t, &i.profiles[j].priority) < 0) {
906
907 pa_context_fail(o->context, PA_ERR_PROTOCOL);
908 card_info_free(&i);
909 goto finish;
910 }
911 }
912
913 /* Terminate with an extra NULL entry, just to make sure */
914 i.profiles[j].name = NULL;
915 i.profiles[j].description = NULL;
916 }
917
918 i.proplist = pa_proplist_new();
919
920 if (pa_tagstruct_gets(t, &ap) < 0 ||
921 pa_tagstruct_get_proplist(t, i.proplist) < 0) {
922
923 pa_context_fail(o->context, PA_ERR_PROTOCOL);
924 card_info_free(&i);
925 goto finish;
926 }
927
928 if (ap) {
929 for (j = 0; j < i.n_profiles; j++)
930 if (pa_streq(i.profiles[j].name, ap)) {
931 i.active_profile = &i.profiles[j];
932 break;
933 }
934 }
935
936 if (o->context->version >= 26) {
937 if (fill_card_port_info(o->context, t, &i) < 0) {
938 pa_context_fail(o->context, PA_ERR_PROTOCOL);
939 card_info_free(&i);
940 goto finish;
941 }
942 }
943
944 if (o->callback) {
945 pa_card_info_cb_t cb = (pa_card_info_cb_t) o->callback;
946 cb(o->context, &i, 0, o->userdata);
947 }
948
949 card_info_free(&i);
950 }
951 }
952
953 if (o->callback) {
954 pa_card_info_cb_t cb = (pa_card_info_cb_t) o->callback;
955 cb(o->context, NULL, eol, o->userdata);
956 }
957
958 finish:
959 pa_operation_done(o);
960 pa_operation_unref(o);
961 }
962
963 pa_operation* pa_context_get_card_info_by_index(pa_context *c, uint32_t idx, pa_card_info_cb_t cb, void *userdata) {
964 pa_tagstruct *t;
965 pa_operation *o;
966 uint32_t tag;
967
968 pa_assert(c);
969 pa_assert(PA_REFCNT_VALUE(c) >= 1);
970 pa_assert(cb);
971
972 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
973 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
974 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
975 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 15, PA_ERR_NOTSUPPORTED);
976
977 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
978
979 t = pa_tagstruct_command(c, PA_COMMAND_GET_CARD_INFO, &tag);
980 pa_tagstruct_putu32(t, idx);
981 pa_tagstruct_puts(t, NULL);
982 pa_pstream_send_tagstruct(c->pstream, t);
983 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);
984
985 return o;
986 }
987
988 pa_operation* pa_context_get_card_info_by_name(pa_context *c, const char*name, pa_card_info_cb_t cb, void *userdata) {
989 pa_tagstruct *t;
990 pa_operation *o;
991 uint32_t tag;
992
993 pa_assert(c);
994 pa_assert(PA_REFCNT_VALUE(c) >= 1);
995 pa_assert(cb);
996
997 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
998 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
999 PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
1000 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 15, PA_ERR_NOTSUPPORTED);
1001
1002 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1003
1004 t = pa_tagstruct_command(c, PA_COMMAND_GET_CARD_INFO, &tag);
1005 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1006 pa_tagstruct_puts(t, name);
1007 pa_pstream_send_tagstruct(c->pstream, t);
1008 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);
1009
1010 return o;
1011 }
1012
1013 pa_operation* pa_context_get_card_info_list(pa_context *c, pa_card_info_cb_t cb, void *userdata) {
1014 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 15, PA_ERR_NOTSUPPORTED);
1015
1016 return pa_context_send_simple_command(c, PA_COMMAND_GET_CARD_INFO_LIST, context_get_card_info_callback, (pa_operation_cb_t) cb, userdata);
1017 }
1018
1019 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) {
1020 pa_operation *o;
1021 pa_tagstruct *t;
1022 uint32_t tag;
1023
1024 pa_assert(c);
1025 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1026
1027 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1028 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1029 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1030 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 15, PA_ERR_NOTSUPPORTED);
1031
1032 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1033
1034 t = pa_tagstruct_command(c, PA_COMMAND_SET_CARD_PROFILE, &tag);
1035 pa_tagstruct_putu32(t, idx);
1036 pa_tagstruct_puts(t, NULL);
1037 pa_tagstruct_puts(t, profile);
1038 pa_pstream_send_tagstruct(c->pstream, t);
1039 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);
1040
1041 return o;
1042 }
1043
1044 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) {
1045 pa_operation *o;
1046 pa_tagstruct *t;
1047 uint32_t tag;
1048
1049 pa_assert(c);
1050 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1051
1052 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1053 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1054 PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
1055 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 15, PA_ERR_NOTSUPPORTED);
1056
1057 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1058
1059 t = pa_tagstruct_command(c, PA_COMMAND_SET_CARD_PROFILE, &tag);
1060 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1061 pa_tagstruct_puts(t, name);
1062 pa_tagstruct_puts(t, profile);
1063 pa_pstream_send_tagstruct(c->pstream, t);
1064 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);
1065
1066 return o;
1067 }
1068
1069 /*** Module info ***/
1070
1071 static void context_get_module_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1072 pa_operation *o = userdata;
1073 int eol = 1;
1074
1075 pa_assert(pd);
1076 pa_assert(o);
1077 pa_assert(PA_REFCNT_VALUE(o) >= 1);
1078
1079 if (!o->context)
1080 goto finish;
1081
1082 if (command != PA_COMMAND_REPLY) {
1083 if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
1084 goto finish;
1085
1086 eol = -1;
1087 } else {
1088
1089 while (!pa_tagstruct_eof(t)) {
1090 pa_module_info i;
1091 pa_bool_t auto_unload = FALSE;
1092
1093 pa_zero(i);
1094 i.proplist = pa_proplist_new();
1095
1096 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
1097 pa_tagstruct_gets(t, &i.name) < 0 ||
1098 pa_tagstruct_gets(t, &i.argument) < 0 ||
1099 pa_tagstruct_getu32(t, &i.n_used) < 0 ||
1100 (o->context->version < 15 && pa_tagstruct_get_boolean(t, &auto_unload) < 0) ||
1101 (o->context->version >= 15 && pa_tagstruct_get_proplist(t, i.proplist) < 0)) {
1102 pa_context_fail(o->context, PA_ERR_PROTOCOL);
1103 goto finish;
1104 }
1105
1106 i.auto_unload = (int) auto_unload;
1107
1108 if (o->callback) {
1109 pa_module_info_cb_t cb = (pa_module_info_cb_t) o->callback;
1110 cb(o->context, &i, 0, o->userdata);
1111 }
1112
1113 pa_proplist_free(i.proplist);
1114 }
1115 }
1116
1117 if (o->callback) {
1118 pa_module_info_cb_t cb = (pa_module_info_cb_t) o->callback;
1119 cb(o->context, NULL, eol, o->userdata);
1120 }
1121
1122 finish:
1123 pa_operation_done(o);
1124 pa_operation_unref(o);
1125 }
1126
1127 pa_operation* pa_context_get_module_info(pa_context *c, uint32_t idx, pa_module_info_cb_t cb, void *userdata) {
1128 pa_tagstruct *t;
1129 pa_operation *o;
1130 uint32_t tag;
1131
1132 pa_assert(c);
1133 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1134 pa_assert(cb);
1135
1136 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1137 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1138 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1139
1140 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1141
1142 t = pa_tagstruct_command(c, PA_COMMAND_GET_MODULE_INFO, &tag);
1143 pa_tagstruct_putu32(t, idx);
1144 pa_pstream_send_tagstruct(c->pstream, t);
1145 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);
1146
1147 return o;
1148 }
1149
1150 pa_operation* pa_context_get_module_info_list(pa_context *c, pa_module_info_cb_t cb, void *userdata) {
1151 return pa_context_send_simple_command(c, PA_COMMAND_GET_MODULE_INFO_LIST, context_get_module_info_callback, (pa_operation_cb_t) cb, userdata);
1152 }
1153
1154 /*** Sink input info ***/
1155
1156 static void context_get_sink_input_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1157 pa_operation *o = userdata;
1158 int eol = 1;
1159
1160 pa_assert(pd);
1161 pa_assert(o);
1162 pa_assert(PA_REFCNT_VALUE(o) >= 1);
1163
1164 if (!o->context)
1165 goto finish;
1166
1167 if (command != PA_COMMAND_REPLY) {
1168 if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
1169 goto finish;
1170
1171 eol = -1;
1172 } else {
1173
1174 while (!pa_tagstruct_eof(t)) {
1175 pa_sink_input_info i;
1176 pa_bool_t mute = FALSE, corked = FALSE, has_volume = FALSE, volume_writable = TRUE;
1177
1178 pa_zero(i);
1179 i.proplist = pa_proplist_new();
1180 i.format = pa_format_info_new();
1181
1182 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
1183 pa_tagstruct_gets(t, &i.name) < 0 ||
1184 pa_tagstruct_getu32(t, &i.owner_module) < 0 ||
1185 pa_tagstruct_getu32(t, &i.client) < 0 ||
1186 pa_tagstruct_getu32(t, &i.sink) < 0 ||
1187 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
1188 pa_tagstruct_get_channel_map(t, &i.channel_map) < 0 ||
1189 pa_tagstruct_get_cvolume(t, &i.volume) < 0 ||
1190 pa_tagstruct_get_usec(t, &i.buffer_usec) < 0 ||
1191 pa_tagstruct_get_usec(t, &i.sink_usec) < 0 ||
1192 pa_tagstruct_gets(t, &i.resample_method) < 0 ||
1193 pa_tagstruct_gets(t, &i.driver) < 0 ||
1194 (o->context->version >= 11 && pa_tagstruct_get_boolean(t, &mute) < 0) ||
1195 (o->context->version >= 13 && pa_tagstruct_get_proplist(t, i.proplist) < 0) ||
1196 (o->context->version >= 19 && pa_tagstruct_get_boolean(t, &corked) < 0) ||
1197 (o->context->version >= 20 && (pa_tagstruct_get_boolean(t, &has_volume) < 0 ||
1198 pa_tagstruct_get_boolean(t, &volume_writable) < 0)) ||
1199 (o->context->version >= 21 && pa_tagstruct_get_format_info(t, i.format) < 0)) {
1200
1201 pa_context_fail(o->context, PA_ERR_PROTOCOL);
1202 pa_proplist_free(i.proplist);
1203 pa_format_info_free(i.format);
1204 goto finish;
1205 }
1206
1207 i.mute = (int) mute;
1208 i.corked = (int) corked;
1209 i.has_volume = (int) has_volume;
1210 i.volume_writable = (int) volume_writable;
1211
1212 if (o->callback) {
1213 pa_sink_input_info_cb_t cb = (pa_sink_input_info_cb_t) o->callback;
1214 cb(o->context, &i, 0, o->userdata);
1215 }
1216
1217 pa_proplist_free(i.proplist);
1218 pa_format_info_free(i.format);
1219 }
1220 }
1221
1222 if (o->callback) {
1223 pa_sink_input_info_cb_t cb = (pa_sink_input_info_cb_t) o->callback;
1224 cb(o->context, NULL, eol, o->userdata);
1225 }
1226
1227 finish:
1228 pa_operation_done(o);
1229 pa_operation_unref(o);
1230 }
1231
1232 pa_operation* pa_context_get_sink_input_info(pa_context *c, uint32_t idx, pa_sink_input_info_cb_t cb, void *userdata) {
1233 pa_tagstruct *t;
1234 pa_operation *o;
1235 uint32_t tag;
1236
1237 pa_assert(c);
1238 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1239 pa_assert(cb);
1240
1241 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1242 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1243 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1244
1245 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1246
1247 t = pa_tagstruct_command(c, PA_COMMAND_GET_SINK_INPUT_INFO, &tag);
1248 pa_tagstruct_putu32(t, idx);
1249 pa_pstream_send_tagstruct(c->pstream, t);
1250 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);
1251
1252 return o;
1253 }
1254
1255 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) {
1256 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);
1257 }
1258
1259 /*** Source output info ***/
1260
1261 static void context_get_source_output_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1262 pa_operation *o = userdata;
1263 int eol = 1;
1264
1265 pa_assert(pd);
1266 pa_assert(o);
1267 pa_assert(PA_REFCNT_VALUE(o) >= 1);
1268
1269 if (!o->context)
1270 goto finish;
1271
1272 if (command != PA_COMMAND_REPLY) {
1273 if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
1274 goto finish;
1275
1276 eol = -1;
1277 } else {
1278
1279 while (!pa_tagstruct_eof(t)) {
1280 pa_source_output_info i;
1281 pa_bool_t mute = FALSE, corked = FALSE, has_volume = FALSE, volume_writable = TRUE;
1282
1283 pa_zero(i);
1284 i.proplist = pa_proplist_new();
1285 i.format = pa_format_info_new();
1286
1287 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
1288 pa_tagstruct_gets(t, &i.name) < 0 ||
1289 pa_tagstruct_getu32(t, &i.owner_module) < 0 ||
1290 pa_tagstruct_getu32(t, &i.client) < 0 ||
1291 pa_tagstruct_getu32(t, &i.source) < 0 ||
1292 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
1293 pa_tagstruct_get_channel_map(t, &i.channel_map) < 0 ||
1294 pa_tagstruct_get_usec(t, &i.buffer_usec) < 0 ||
1295 pa_tagstruct_get_usec(t, &i.source_usec) < 0 ||
1296 pa_tagstruct_gets(t, &i.resample_method) < 0 ||
1297 pa_tagstruct_gets(t, &i.driver) < 0 ||
1298 (o->context->version >= 13 && pa_tagstruct_get_proplist(t, i.proplist) < 0) ||
1299 (o->context->version >= 19 && pa_tagstruct_get_boolean(t, &corked) < 0) ||
1300 (o->context->version >= 22 && (pa_tagstruct_get_cvolume(t, &i.volume) < 0 ||
1301 pa_tagstruct_get_boolean(t, &mute) < 0 ||
1302 pa_tagstruct_get_boolean(t, &has_volume) < 0 ||
1303 pa_tagstruct_get_boolean(t, &volume_writable) < 0 ||
1304 pa_tagstruct_get_format_info(t, i.format) < 0))) {
1305
1306 pa_context_fail(o->context, PA_ERR_PROTOCOL);
1307 pa_proplist_free(i.proplist);
1308 pa_format_info_free(i.format);
1309 goto finish;
1310 }
1311
1312 i.mute = (int) mute;
1313 i.corked = (int) corked;
1314 i.has_volume = (int) has_volume;
1315 i.volume_writable = (int) volume_writable;
1316
1317 if (o->callback) {
1318 pa_source_output_info_cb_t cb = (pa_source_output_info_cb_t) o->callback;
1319 cb(o->context, &i, 0, o->userdata);
1320 }
1321
1322 pa_proplist_free(i.proplist);
1323 pa_format_info_free(i.format);
1324 }
1325 }
1326
1327 if (o->callback) {
1328 pa_source_output_info_cb_t cb = (pa_source_output_info_cb_t) o->callback;
1329 cb(o->context, NULL, eol, o->userdata);
1330 }
1331
1332 finish:
1333 pa_operation_done(o);
1334 pa_operation_unref(o);
1335 }
1336
1337 pa_operation* pa_context_get_source_output_info(pa_context *c, uint32_t idx, pa_source_output_info_cb_t cb, void *userdata) {
1338 pa_tagstruct *t;
1339 pa_operation *o;
1340 uint32_t tag;
1341
1342 pa_assert(c);
1343 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1344 pa_assert(cb);
1345
1346 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1347 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1348 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1349
1350 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1351
1352 t = pa_tagstruct_command(c, PA_COMMAND_GET_SOURCE_OUTPUT_INFO, &tag);
1353 pa_tagstruct_putu32(t, idx);
1354 pa_pstream_send_tagstruct(c->pstream, t);
1355 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);
1356
1357 return o;
1358 }
1359
1360 pa_operation* pa_context_get_source_output_info_list(pa_context *c, pa_source_output_info_cb_t cb, void *userdata) {
1361 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);
1362 }
1363
1364 /*** Volume manipulation ***/
1365
1366 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) {
1367 pa_operation *o;
1368 pa_tagstruct *t;
1369 uint32_t tag;
1370
1371 pa_assert(c);
1372 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1373 pa_assert(volume);
1374
1375 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1376 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1377 PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID);
1378
1379 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1380
1381 t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_VOLUME, &tag);
1382 pa_tagstruct_putu32(t, idx);
1383 pa_tagstruct_puts(t, NULL);
1384 pa_tagstruct_put_cvolume(t, volume);
1385 pa_pstream_send_tagstruct(c->pstream, t);
1386 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);
1387
1388 return o;
1389 }
1390
1391 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) {
1392 pa_operation *o;
1393 pa_tagstruct *t;
1394 uint32_t tag;
1395
1396 pa_assert(c);
1397 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1398 pa_assert(name);
1399 pa_assert(volume);
1400
1401 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1402 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1403 PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID);
1404 PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
1405
1406 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1407
1408 t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_VOLUME, &tag);
1409 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1410 pa_tagstruct_puts(t, name);
1411 pa_tagstruct_put_cvolume(t, volume);
1412 pa_pstream_send_tagstruct(c->pstream, t);
1413 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);
1414
1415 return o;
1416 }
1417
1418 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) {
1419 pa_operation *o;
1420 pa_tagstruct *t;
1421 uint32_t tag;
1422
1423 pa_assert(c);
1424 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1425
1426 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1427 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1428
1429 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1430
1431 t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_MUTE, &tag);
1432 pa_tagstruct_putu32(t, idx);
1433 pa_tagstruct_puts(t, NULL);
1434 pa_tagstruct_put_boolean(t, mute);
1435 pa_pstream_send_tagstruct(c->pstream, t);
1436 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);
1437
1438 return o;
1439 }
1440
1441 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) {
1442 pa_operation *o;
1443 pa_tagstruct *t;
1444 uint32_t tag;
1445
1446 pa_assert(c);
1447 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1448 pa_assert(name);
1449
1450 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1451 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1452 PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
1453
1454 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1455
1456 t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_MUTE, &tag);
1457 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1458 pa_tagstruct_puts(t, name);
1459 pa_tagstruct_put_boolean(t, mute);
1460 pa_pstream_send_tagstruct(c->pstream, t);
1461 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);
1462
1463 return o;
1464 }
1465
1466 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) {
1467 pa_operation *o;
1468 pa_tagstruct *t;
1469 uint32_t tag;
1470
1471 pa_assert(c);
1472 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1473 pa_assert(volume);
1474
1475 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1476 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1477 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1478 PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID);
1479
1480 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1481
1482 t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_INPUT_VOLUME, &tag);
1483 pa_tagstruct_putu32(t, idx);
1484 pa_tagstruct_put_cvolume(t, volume);
1485 pa_pstream_send_tagstruct(c->pstream, t);
1486 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);
1487
1488 return o;
1489 }
1490
1491 pa_operation* pa_context_set_sink_input_mute(pa_context *c, uint32_t idx, int mute, pa_context_success_cb_t cb, void *userdata) {
1492 pa_operation *o;
1493 pa_tagstruct *t;
1494 uint32_t tag;
1495
1496 pa_assert(c);
1497 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1498
1499 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1500 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1501 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1502 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED);
1503
1504 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1505
1506 t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_INPUT_MUTE, &tag);
1507 pa_tagstruct_putu32(t, idx);
1508 pa_tagstruct_put_boolean(t, mute);
1509 pa_pstream_send_tagstruct(c->pstream, t);
1510 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);
1511
1512 return o;
1513 }
1514
1515 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) {
1516 pa_operation *o;
1517 pa_tagstruct *t;
1518 uint32_t tag;
1519
1520 pa_assert(c);
1521 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1522 pa_assert(volume);
1523
1524 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1525 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1526 PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID);
1527
1528 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1529
1530 t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_VOLUME, &tag);
1531 pa_tagstruct_putu32(t, idx);
1532 pa_tagstruct_puts(t, NULL);
1533 pa_tagstruct_put_cvolume(t, volume);
1534 pa_pstream_send_tagstruct(c->pstream, t);
1535 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);
1536
1537 return o;
1538 }
1539
1540 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) {
1541 pa_operation *o;
1542 pa_tagstruct *t;
1543 uint32_t tag;
1544
1545 pa_assert(c);
1546 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1547 pa_assert(name);
1548 pa_assert(volume);
1549
1550 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1551 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1552 PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID);
1553 PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
1554
1555 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1556
1557 t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_VOLUME, &tag);
1558 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1559 pa_tagstruct_puts(t, name);
1560 pa_tagstruct_put_cvolume(t, volume);
1561 pa_pstream_send_tagstruct(c->pstream, t);
1562 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);
1563
1564 return o;
1565 }
1566
1567 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) {
1568 pa_operation *o;
1569 pa_tagstruct *t;
1570 uint32_t tag;
1571
1572 pa_assert(c);
1573 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1574
1575 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1576 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1577
1578 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1579
1580 t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_MUTE, &tag);
1581 pa_tagstruct_putu32(t, idx);
1582 pa_tagstruct_puts(t, NULL);
1583 pa_tagstruct_put_boolean(t, mute);
1584 pa_pstream_send_tagstruct(c->pstream, t);
1585 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);
1586
1587 return o;
1588 }
1589
1590 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) {
1591 pa_operation *o;
1592 pa_tagstruct *t;
1593 uint32_t tag;
1594
1595 pa_assert(c);
1596 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1597 pa_assert(name);
1598
1599 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1600 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1601 PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
1602
1603 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1604
1605 t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_MUTE, &tag);
1606 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1607 pa_tagstruct_puts(t, name);
1608 pa_tagstruct_put_boolean(t, mute);
1609 pa_pstream_send_tagstruct(c->pstream, t);
1610 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);
1611
1612 return o;
1613 }
1614
1615 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) {
1616 pa_operation *o;
1617 pa_tagstruct *t;
1618 uint32_t tag;
1619
1620 pa_assert(c);
1621 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1622 pa_assert(volume);
1623
1624 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1625 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1626 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1627 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 22, PA_ERR_NOTSUPPORTED);
1628 PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID);
1629
1630 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1631
1632 t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_OUTPUT_VOLUME, &tag);
1633 pa_tagstruct_putu32(t, idx);
1634 pa_tagstruct_put_cvolume(t, volume);
1635 pa_pstream_send_tagstruct(c->pstream, t);
1636 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);
1637
1638 return o;
1639 }
1640
1641 pa_operation* pa_context_set_source_output_mute(pa_context *c, uint32_t idx, int mute, pa_context_success_cb_t cb, void *userdata) {
1642 pa_operation *o;
1643 pa_tagstruct *t;
1644 uint32_t tag;
1645
1646 pa_assert(c);
1647 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1648
1649 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1650 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1651 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1652 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 22, PA_ERR_NOTSUPPORTED);
1653
1654 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1655
1656 t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_OUTPUT_MUTE, &tag);
1657 pa_tagstruct_putu32(t, idx);
1658 pa_tagstruct_put_boolean(t, mute);
1659 pa_pstream_send_tagstruct(c->pstream, t);
1660 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);
1661
1662 return o;
1663 }
1664
1665 /** Sample Cache **/
1666
1667 static void context_get_sample_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1668 pa_operation *o = userdata;
1669 int eol = 1;
1670
1671 pa_assert(pd);
1672 pa_assert(o);
1673 pa_assert(PA_REFCNT_VALUE(o) >= 1);
1674
1675 if (!o->context)
1676 goto finish;
1677
1678 if (command != PA_COMMAND_REPLY) {
1679 if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
1680 goto finish;
1681
1682 eol = -1;
1683 } else {
1684
1685 while (!pa_tagstruct_eof(t)) {
1686 pa_sample_info i;
1687 pa_bool_t lazy = FALSE;
1688
1689 pa_zero(i);
1690 i.proplist = pa_proplist_new();
1691
1692 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
1693 pa_tagstruct_gets(t, &i.name) < 0 ||
1694 pa_tagstruct_get_cvolume(t, &i.volume) < 0 ||
1695 pa_tagstruct_get_usec(t, &i.duration) < 0 ||
1696 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
1697 pa_tagstruct_get_channel_map(t, &i.channel_map) < 0 ||
1698 pa_tagstruct_getu32(t, &i.bytes) < 0 ||
1699 pa_tagstruct_get_boolean(t, &lazy) < 0 ||
1700 pa_tagstruct_gets(t, &i.filename) < 0 ||
1701 (o->context->version >= 13 && pa_tagstruct_get_proplist(t, i.proplist) < 0)) {
1702
1703 pa_context_fail(o->context, PA_ERR_PROTOCOL);
1704 goto finish;
1705 }
1706
1707 i.lazy = (int) lazy;
1708
1709 if (o->callback) {
1710 pa_sample_info_cb_t cb = (pa_sample_info_cb_t) o->callback;
1711 cb(o->context, &i, 0, o->userdata);
1712 }
1713
1714 pa_proplist_free(i.proplist);
1715 }
1716 }
1717
1718 if (o->callback) {
1719 pa_sample_info_cb_t cb = (pa_sample_info_cb_t) o->callback;
1720 cb(o->context, NULL, eol, o->userdata);
1721 }
1722
1723 finish:
1724 pa_operation_done(o);
1725 pa_operation_unref(o);
1726 }
1727
1728 pa_operation* pa_context_get_sample_info_by_name(pa_context *c, const char *name, pa_sample_info_cb_t cb, void *userdata) {
1729 pa_tagstruct *t;
1730 pa_operation *o;
1731 uint32_t tag;
1732
1733 pa_assert(c);
1734 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1735 pa_assert(cb);
1736
1737 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1738 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1739 PA_CHECK_VALIDITY_RETURN_NULL(c, name && *name, PA_ERR_INVALID);
1740
1741 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1742
1743 t = pa_tagstruct_command(c, PA_COMMAND_GET_SAMPLE_INFO, &tag);
1744 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1745 pa_tagstruct_puts(t, name);
1746 pa_pstream_send_tagstruct(c->pstream, t);
1747 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);
1748
1749 return o;
1750 }
1751
1752 pa_operation* pa_context_get_sample_info_by_index(pa_context *c, uint32_t idx, pa_sample_info_cb_t cb, void *userdata) {
1753 pa_tagstruct *t;
1754 pa_operation *o;
1755 uint32_t tag;
1756
1757 pa_assert(c);
1758 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1759 pa_assert(cb);
1760
1761 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1762 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1763 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1764
1765 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1766
1767 t = pa_tagstruct_command(c, PA_COMMAND_GET_SAMPLE_INFO, &tag);
1768 pa_tagstruct_putu32(t, idx);
1769 pa_tagstruct_puts(t, NULL);
1770 pa_pstream_send_tagstruct(c->pstream, t);
1771 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);
1772
1773 return o;
1774 }
1775
1776 pa_operation* pa_context_get_sample_info_list(pa_context *c, pa_sample_info_cb_t cb, void *userdata) {
1777 return pa_context_send_simple_command(c, PA_COMMAND_GET_SAMPLE_INFO_LIST, context_get_sample_info_callback, (pa_operation_cb_t) cb, userdata);
1778 }
1779
1780 static pa_operation* command_kill(pa_context *c, uint32_t command, uint32_t idx, pa_context_success_cb_t cb, void *userdata) {
1781 pa_operation *o;
1782 pa_tagstruct *t;
1783 uint32_t tag;
1784
1785 pa_assert(c);
1786 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1787
1788 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1789 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1790 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1791
1792 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1793
1794 t = pa_tagstruct_command(c, command, &tag);
1795 pa_tagstruct_putu32(t, idx);
1796 pa_pstream_send_tagstruct(c->pstream, t);
1797 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);
1798
1799 return o;
1800 }
1801
1802 pa_operation* pa_context_kill_client(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata) {
1803 return command_kill(c, PA_COMMAND_KILL_CLIENT, idx, cb, userdata);
1804 }
1805
1806 pa_operation* pa_context_kill_sink_input(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata) {
1807 return command_kill(c, PA_COMMAND_KILL_SINK_INPUT, idx, cb, userdata);
1808 }
1809
1810 pa_operation* pa_context_kill_source_output(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata) {
1811 return command_kill(c, PA_COMMAND_KILL_SOURCE_OUTPUT, idx, cb, userdata);
1812 }
1813
1814 static void context_index_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1815 pa_operation *o = userdata;
1816 uint32_t idx;
1817
1818 pa_assert(pd);
1819 pa_assert(o);
1820 pa_assert(PA_REFCNT_VALUE(o) >= 1);
1821
1822 if (!o->context)
1823 goto finish;
1824
1825 if (command != PA_COMMAND_REPLY) {
1826 if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
1827 goto finish;
1828
1829 idx = PA_INVALID_INDEX;
1830 } else if (pa_tagstruct_getu32(t, &idx) ||
1831 !pa_tagstruct_eof(t)) {
1832 pa_context_fail(o->context, PA_ERR_PROTOCOL);
1833 goto finish;
1834 }
1835
1836 if (o->callback) {
1837 pa_context_index_cb_t cb = (pa_context_index_cb_t) o->callback;
1838 cb(o->context, idx, o->userdata);
1839 }
1840
1841
1842 finish:
1843 pa_operation_done(o);
1844 pa_operation_unref(o);
1845 }
1846
1847 pa_operation* pa_context_load_module(pa_context *c, const char*name, const char *argument, pa_context_index_cb_t cb, void *userdata) {
1848 pa_operation *o;
1849 pa_tagstruct *t;
1850 uint32_t tag;
1851
1852 pa_assert(c);
1853 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1854
1855 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1856 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1857 PA_CHECK_VALIDITY_RETURN_NULL(c, name && *name, PA_ERR_INVALID);
1858
1859 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1860
1861 t = pa_tagstruct_command(c, PA_COMMAND_LOAD_MODULE, &tag);
1862 pa_tagstruct_puts(t, name);
1863 pa_tagstruct_puts(t, argument);
1864 pa_pstream_send_tagstruct(c->pstream, t);
1865 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_index_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1866
1867 return o;
1868 }
1869
1870 pa_operation* pa_context_unload_module(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata) {
1871 return command_kill(c, PA_COMMAND_UNLOAD_MODULE, idx, cb, userdata);
1872 }
1873
1874 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) {
1875 pa_operation *o;
1876 pa_tagstruct *t;
1877 uint32_t tag;
1878
1879 pa_assert(c);
1880 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1881
1882 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1883 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1884 PA_CHECK_VALIDITY_RETURN_NULL(c, card_name && *card_name, PA_ERR_INVALID);
1885 PA_CHECK_VALIDITY_RETURN_NULL(c, port_name && *port_name, PA_ERR_INVALID);
1886 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 27, PA_ERR_NOTSUPPORTED);
1887
1888 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1889
1890 t = pa_tagstruct_command(c, PA_COMMAND_SET_PORT_LATENCY_OFFSET, &tag);
1891 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1892 pa_tagstruct_puts(t, card_name);
1893 pa_tagstruct_puts(t, port_name);
1894 pa_tagstruct_puts64(t, offset);
1895 pa_pstream_send_tagstruct(c->pstream, t);
1896 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);
1897
1898 return o;
1899 }
1900
1901 /*** Autoload stuff ***/
1902
1903 PA_WARN_REFERENCE(pa_context_get_autoload_info_by_name, "Module auto-loading no longer supported.");
1904
1905 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) {
1906
1907 pa_assert(c);
1908 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1909
1910 PA_FAIL_RETURN_NULL(c, PA_ERR_OBSOLETE);
1911 }
1912
1913 PA_WARN_REFERENCE(pa_context_get_autoload_info_by_index, "Module auto-loading no longer supported.");
1914
1915 pa_operation* pa_context_get_autoload_info_by_index(pa_context *c, uint32_t idx, pa_autoload_info_cb_t cb, void *userdata) {
1916 pa_assert(c);
1917 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1918
1919 PA_FAIL_RETURN_NULL(c, PA_ERR_OBSOLETE);
1920 }
1921
1922 PA_WARN_REFERENCE(pa_context_get_autoload_info_list, "Module auto-loading no longer supported.");
1923
1924 pa_operation* pa_context_get_autoload_info_list(pa_context *c, pa_autoload_info_cb_t cb, void *userdata) {
1925 pa_assert(c);
1926 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1927
1928 PA_FAIL_RETURN_NULL(c, PA_ERR_OBSOLETE);
1929 }
1930
1931 PA_WARN_REFERENCE(pa_context_add_autoload, "Module auto-loading no longer supported.");
1932
1933 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) {
1934 pa_assert(c);
1935 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1936
1937 PA_FAIL_RETURN_NULL(c, PA_ERR_OBSOLETE);
1938 }
1939
1940 PA_WARN_REFERENCE(pa_context_remove_autoload_by_name, "Module auto-loading no longer supported.");
1941
1942 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) {
1943 pa_assert(c);
1944 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1945
1946 PA_FAIL_RETURN_NULL(c, PA_ERR_OBSOLETE);
1947 }
1948
1949 PA_WARN_REFERENCE(pa_context_remove_autoload_by_index, "Module auto-loading no longer supported.");
1950
1951 pa_operation* pa_context_remove_autoload_by_index(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void* userdata) {
1952 pa_assert(c);
1953 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1954
1955 PA_FAIL_RETURN_NULL(c, PA_ERR_OBSOLETE);
1956 }
1957
1958 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) {
1959 pa_operation *o;
1960 pa_tagstruct *t;
1961 uint32_t tag;
1962
1963 pa_assert(c);
1964 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1965
1966 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1967 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1968 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 10, PA_ERR_NOTSUPPORTED);
1969 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1970 PA_CHECK_VALIDITY_RETURN_NULL(c, sink_name && *sink_name, PA_ERR_INVALID);
1971
1972 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1973
1974 t = pa_tagstruct_command(c, PA_COMMAND_MOVE_SINK_INPUT, &tag);
1975 pa_tagstruct_putu32(t, idx);
1976 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1977 pa_tagstruct_puts(t, sink_name);
1978 pa_pstream_send_tagstruct(c->pstream, t);
1979 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);
1980
1981 return o;
1982 }
1983
1984 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) {
1985 pa_operation *o;
1986 pa_tagstruct *t;
1987 uint32_t tag;
1988
1989 pa_assert(c);
1990 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1991
1992 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1993 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1994 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 10, PA_ERR_NOTSUPPORTED);
1995 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1996 PA_CHECK_VALIDITY_RETURN_NULL(c, sink_idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1997
1998 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1999
2000 t = pa_tagstruct_command(c, PA_COMMAND_MOVE_SINK_INPUT, &tag);
2001 pa_tagstruct_putu32(t, idx);
2002 pa_tagstruct_putu32(t, sink_idx);
2003 pa_tagstruct_puts(t, NULL);
2004 pa_pstream_send_tagstruct(c->pstream, t);
2005 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);
2006
2007 return o;
2008 }
2009
2010 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) {
2011 pa_operation *o;
2012 pa_tagstruct *t;
2013 uint32_t tag;
2014
2015 pa_assert(c);
2016 pa_assert(PA_REFCNT_VALUE(c) >= 1);
2017
2018 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
2019 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
2020 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 10, PA_ERR_NOTSUPPORTED);
2021 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
2022 PA_CHECK_VALIDITY_RETURN_NULL(c, source_name && *source_name, PA_ERR_INVALID);
2023
2024 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
2025
2026 t = pa_tagstruct_command(c, PA_COMMAND_MOVE_SOURCE_OUTPUT, &tag);
2027 pa_tagstruct_putu32(t, idx);
2028 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
2029 pa_tagstruct_puts(t, source_name);
2030 pa_pstream_send_tagstruct(c->pstream, t);
2031 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);
2032
2033 return o;
2034 }
2035
2036 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) {
2037 pa_operation *o;
2038 pa_tagstruct *t;
2039 uint32_t tag;
2040
2041 pa_assert(c);
2042 pa_assert(PA_REFCNT_VALUE(c) >= 1);
2043
2044 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
2045 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
2046 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 10, PA_ERR_NOTSUPPORTED);
2047 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
2048 PA_CHECK_VALIDITY_RETURN_NULL(c, source_idx != PA_INVALID_INDEX, PA_ERR_INVALID);
2049
2050 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
2051
2052 t = pa_tagstruct_command(c, PA_COMMAND_MOVE_SOURCE_OUTPUT, &tag);
2053 pa_tagstruct_putu32(t, idx);
2054 pa_tagstruct_putu32(t, source_idx);
2055 pa_tagstruct_puts(t, NULL);
2056 pa_pstream_send_tagstruct(c->pstream, t);
2057 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);
2058
2059 return o;
2060 }
2061
2062 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) {
2063 pa_operation *o;
2064 pa_tagstruct *t;
2065 uint32_t tag;
2066
2067 pa_assert(c);
2068 pa_assert(PA_REFCNT_VALUE(c) >= 1);
2069
2070 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
2071 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
2072 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED);
2073 PA_CHECK_VALIDITY_RETURN_NULL(c, !sink_name || *sink_name, PA_ERR_INVALID);
2074
2075 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
2076
2077 t = pa_tagstruct_command(c, PA_COMMAND_SUSPEND_SINK, &tag);
2078 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
2079 pa_tagstruct_puts(t, sink_name);
2080 pa_tagstruct_put_boolean(t, suspend);
2081 pa_pstream_send_tagstruct(c->pstream, t);
2082 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);
2083
2084 return o;
2085 }
2086
2087 pa_operation* pa_context_suspend_sink_by_index(pa_context *c, uint32_t idx, int suspend, pa_context_success_cb_t cb, void* userdata) {
2088 pa_operation *o;
2089 pa_tagstruct *t;
2090 uint32_t tag;
2091
2092 pa_assert(c);
2093 pa_assert(PA_REFCNT_VALUE(c) >= 1);
2094
2095 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
2096 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
2097 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED);
2098
2099 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
2100
2101 t = pa_tagstruct_command(c, PA_COMMAND_SUSPEND_SINK, &tag);
2102 pa_tagstruct_putu32(t, idx);
2103 pa_tagstruct_puts(t, idx == PA_INVALID_INDEX ? "" : NULL);
2104 pa_tagstruct_put_boolean(t, suspend);
2105 pa_pstream_send_tagstruct(c->pstream, t);
2106 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);
2107
2108 return o;
2109 }
2110
2111 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) {
2112 pa_operation *o;
2113 pa_tagstruct *t;
2114 uint32_t tag;
2115
2116 pa_assert(c);
2117 pa_assert(PA_REFCNT_VALUE(c) >= 1);
2118
2119 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
2120 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
2121 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED);
2122 PA_CHECK_VALIDITY_RETURN_NULL(c, !source_name || *source_name, PA_ERR_INVALID);
2123
2124 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
2125
2126 t = pa_tagstruct_command(c, PA_COMMAND_SUSPEND_SOURCE, &tag);
2127 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
2128 pa_tagstruct_puts(t, source_name);
2129 pa_tagstruct_put_boolean(t, suspend);
2130 pa_pstream_send_tagstruct(c->pstream, t);
2131 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);
2132
2133 return o;
2134 }
2135
2136 pa_operation* pa_context_suspend_source_by_index(pa_context *c, uint32_t idx, int suspend, pa_context_success_cb_t cb, void* userdata) {
2137 pa_operation *o;
2138 pa_tagstruct *t;
2139 uint32_t tag;
2140
2141 pa_assert(c);
2142 pa_assert(PA_REFCNT_VALUE(c) >= 1);
2143
2144 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
2145 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
2146 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED);
2147
2148 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
2149
2150 t = pa_tagstruct_command(c, PA_COMMAND_SUSPEND_SOURCE, &tag);
2151 pa_tagstruct_putu32(t, idx);
2152 pa_tagstruct_puts(t, idx == PA_INVALID_INDEX ? "" : NULL);
2153 pa_tagstruct_put_boolean(t, suspend);
2154 pa_pstream_send_tagstruct(c->pstream, t);
2155 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);
2156
2157 return o;
2158 }