]> code.delx.au - pulseaudio/blob - src/pulse/introspect.c
334ffd96672217ee6e4987badfc6930e47d40352
[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 bool 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 bool 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 bool 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 bool 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 bool 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 bool 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 finish:
1842 pa_operation_done(o);
1843 pa_operation_unref(o);
1844 }
1845
1846 pa_operation* pa_context_load_module(pa_context *c, const char*name, const char *argument, pa_context_index_cb_t cb, void *userdata) {
1847 pa_operation *o;
1848 pa_tagstruct *t;
1849 uint32_t tag;
1850
1851 pa_assert(c);
1852 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1853
1854 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1855 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1856 PA_CHECK_VALIDITY_RETURN_NULL(c, name && *name, PA_ERR_INVALID);
1857
1858 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1859
1860 t = pa_tagstruct_command(c, PA_COMMAND_LOAD_MODULE, &tag);
1861 pa_tagstruct_puts(t, name);
1862 pa_tagstruct_puts(t, argument);
1863 pa_pstream_send_tagstruct(c->pstream, t);
1864 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_index_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1865
1866 return o;
1867 }
1868
1869 pa_operation* pa_context_unload_module(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata) {
1870 return command_kill(c, PA_COMMAND_UNLOAD_MODULE, idx, cb, userdata);
1871 }
1872
1873 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) {
1874 pa_operation *o;
1875 pa_tagstruct *t;
1876 uint32_t tag;
1877
1878 pa_assert(c);
1879 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1880
1881 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1882 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1883 PA_CHECK_VALIDITY_RETURN_NULL(c, card_name && *card_name, PA_ERR_INVALID);
1884 PA_CHECK_VALIDITY_RETURN_NULL(c, port_name && *port_name, PA_ERR_INVALID);
1885 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 27, PA_ERR_NOTSUPPORTED);
1886
1887 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1888
1889 t = pa_tagstruct_command(c, PA_COMMAND_SET_PORT_LATENCY_OFFSET, &tag);
1890 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1891 pa_tagstruct_puts(t, card_name);
1892 pa_tagstruct_puts(t, port_name);
1893 pa_tagstruct_puts64(t, offset);
1894 pa_pstream_send_tagstruct(c->pstream, t);
1895 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);
1896
1897 return o;
1898 }
1899
1900 /*** Autoload stuff ***/
1901
1902 PA_WARN_REFERENCE(pa_context_get_autoload_info_by_name, "Module auto-loading no longer supported.");
1903
1904 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) {
1905
1906 pa_assert(c);
1907 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1908
1909 PA_FAIL_RETURN_NULL(c, PA_ERR_OBSOLETE);
1910 }
1911
1912 PA_WARN_REFERENCE(pa_context_get_autoload_info_by_index, "Module auto-loading no longer supported.");
1913
1914 pa_operation* pa_context_get_autoload_info_by_index(pa_context *c, uint32_t idx, pa_autoload_info_cb_t cb, void *userdata) {
1915 pa_assert(c);
1916 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1917
1918 PA_FAIL_RETURN_NULL(c, PA_ERR_OBSOLETE);
1919 }
1920
1921 PA_WARN_REFERENCE(pa_context_get_autoload_info_list, "Module auto-loading no longer supported.");
1922
1923 pa_operation* pa_context_get_autoload_info_list(pa_context *c, pa_autoload_info_cb_t cb, void *userdata) {
1924 pa_assert(c);
1925 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1926
1927 PA_FAIL_RETURN_NULL(c, PA_ERR_OBSOLETE);
1928 }
1929
1930 PA_WARN_REFERENCE(pa_context_add_autoload, "Module auto-loading no longer supported.");
1931
1932 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) {
1933 pa_assert(c);
1934 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1935
1936 PA_FAIL_RETURN_NULL(c, PA_ERR_OBSOLETE);
1937 }
1938
1939 PA_WARN_REFERENCE(pa_context_remove_autoload_by_name, "Module auto-loading no longer supported.");
1940
1941 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) {
1942 pa_assert(c);
1943 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1944
1945 PA_FAIL_RETURN_NULL(c, PA_ERR_OBSOLETE);
1946 }
1947
1948 PA_WARN_REFERENCE(pa_context_remove_autoload_by_index, "Module auto-loading no longer supported.");
1949
1950 pa_operation* pa_context_remove_autoload_by_index(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void* userdata) {
1951 pa_assert(c);
1952 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1953
1954 PA_FAIL_RETURN_NULL(c, PA_ERR_OBSOLETE);
1955 }
1956
1957 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) {
1958 pa_operation *o;
1959 pa_tagstruct *t;
1960 uint32_t tag;
1961
1962 pa_assert(c);
1963 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1964
1965 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1966 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1967 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 10, PA_ERR_NOTSUPPORTED);
1968 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1969 PA_CHECK_VALIDITY_RETURN_NULL(c, sink_name && *sink_name, PA_ERR_INVALID);
1970
1971 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1972
1973 t = pa_tagstruct_command(c, PA_COMMAND_MOVE_SINK_INPUT, &tag);
1974 pa_tagstruct_putu32(t, idx);
1975 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1976 pa_tagstruct_puts(t, sink_name);
1977 pa_pstream_send_tagstruct(c->pstream, t);
1978 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);
1979
1980 return o;
1981 }
1982
1983 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) {
1984 pa_operation *o;
1985 pa_tagstruct *t;
1986 uint32_t tag;
1987
1988 pa_assert(c);
1989 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1990
1991 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1992 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1993 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 10, PA_ERR_NOTSUPPORTED);
1994 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1995 PA_CHECK_VALIDITY_RETURN_NULL(c, sink_idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1996
1997 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1998
1999 t = pa_tagstruct_command(c, PA_COMMAND_MOVE_SINK_INPUT, &tag);
2000 pa_tagstruct_putu32(t, idx);
2001 pa_tagstruct_putu32(t, sink_idx);
2002 pa_tagstruct_puts(t, NULL);
2003 pa_pstream_send_tagstruct(c->pstream, t);
2004 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);
2005
2006 return o;
2007 }
2008
2009 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) {
2010 pa_operation *o;
2011 pa_tagstruct *t;
2012 uint32_t tag;
2013
2014 pa_assert(c);
2015 pa_assert(PA_REFCNT_VALUE(c) >= 1);
2016
2017 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
2018 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
2019 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 10, PA_ERR_NOTSUPPORTED);
2020 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
2021 PA_CHECK_VALIDITY_RETURN_NULL(c, source_name && *source_name, PA_ERR_INVALID);
2022
2023 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
2024
2025 t = pa_tagstruct_command(c, PA_COMMAND_MOVE_SOURCE_OUTPUT, &tag);
2026 pa_tagstruct_putu32(t, idx);
2027 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
2028 pa_tagstruct_puts(t, source_name);
2029 pa_pstream_send_tagstruct(c->pstream, t);
2030 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);
2031
2032 return o;
2033 }
2034
2035 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) {
2036 pa_operation *o;
2037 pa_tagstruct *t;
2038 uint32_t tag;
2039
2040 pa_assert(c);
2041 pa_assert(PA_REFCNT_VALUE(c) >= 1);
2042
2043 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
2044 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
2045 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 10, PA_ERR_NOTSUPPORTED);
2046 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
2047 PA_CHECK_VALIDITY_RETURN_NULL(c, source_idx != PA_INVALID_INDEX, PA_ERR_INVALID);
2048
2049 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
2050
2051 t = pa_tagstruct_command(c, PA_COMMAND_MOVE_SOURCE_OUTPUT, &tag);
2052 pa_tagstruct_putu32(t, idx);
2053 pa_tagstruct_putu32(t, source_idx);
2054 pa_tagstruct_puts(t, NULL);
2055 pa_pstream_send_tagstruct(c->pstream, t);
2056 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);
2057
2058 return o;
2059 }
2060
2061 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) {
2062 pa_operation *o;
2063 pa_tagstruct *t;
2064 uint32_t tag;
2065
2066 pa_assert(c);
2067 pa_assert(PA_REFCNT_VALUE(c) >= 1);
2068
2069 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
2070 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
2071 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED);
2072 PA_CHECK_VALIDITY_RETURN_NULL(c, !sink_name || *sink_name, PA_ERR_INVALID);
2073
2074 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
2075
2076 t = pa_tagstruct_command(c, PA_COMMAND_SUSPEND_SINK, &tag);
2077 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
2078 pa_tagstruct_puts(t, sink_name);
2079 pa_tagstruct_put_boolean(t, suspend);
2080 pa_pstream_send_tagstruct(c->pstream, t);
2081 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);
2082
2083 return o;
2084 }
2085
2086 pa_operation* pa_context_suspend_sink_by_index(pa_context *c, uint32_t idx, int suspend, pa_context_success_cb_t cb, void* userdata) {
2087 pa_operation *o;
2088 pa_tagstruct *t;
2089 uint32_t tag;
2090
2091 pa_assert(c);
2092 pa_assert(PA_REFCNT_VALUE(c) >= 1);
2093
2094 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
2095 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
2096 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED);
2097
2098 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
2099
2100 t = pa_tagstruct_command(c, PA_COMMAND_SUSPEND_SINK, &tag);
2101 pa_tagstruct_putu32(t, idx);
2102 pa_tagstruct_puts(t, idx == PA_INVALID_INDEX ? "" : NULL);
2103 pa_tagstruct_put_boolean(t, suspend);
2104 pa_pstream_send_tagstruct(c->pstream, t);
2105 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);
2106
2107 return o;
2108 }
2109
2110 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) {
2111 pa_operation *o;
2112 pa_tagstruct *t;
2113 uint32_t tag;
2114
2115 pa_assert(c);
2116 pa_assert(PA_REFCNT_VALUE(c) >= 1);
2117
2118 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
2119 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
2120 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED);
2121 PA_CHECK_VALIDITY_RETURN_NULL(c, !source_name || *source_name, PA_ERR_INVALID);
2122
2123 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
2124
2125 t = pa_tagstruct_command(c, PA_COMMAND_SUSPEND_SOURCE, &tag);
2126 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
2127 pa_tagstruct_puts(t, source_name);
2128 pa_tagstruct_put_boolean(t, suspend);
2129 pa_pstream_send_tagstruct(c->pstream, t);
2130 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);
2131
2132 return o;
2133 }
2134
2135 pa_operation* pa_context_suspend_source_by_index(pa_context *c, uint32_t idx, int suspend, pa_context_success_cb_t cb, void* userdata) {
2136 pa_operation *o;
2137 pa_tagstruct *t;
2138 uint32_t tag;
2139
2140 pa_assert(c);
2141 pa_assert(PA_REFCNT_VALUE(c) >= 1);
2142
2143 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
2144 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
2145 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED);
2146
2147 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
2148
2149 t = pa_tagstruct_command(c, PA_COMMAND_SUSPEND_SOURCE, &tag);
2150 pa_tagstruct_putu32(t, idx);
2151 pa_tagstruct_puts(t, idx == PA_INVALID_INDEX ? "" : NULL);
2152 pa_tagstruct_put_boolean(t, suspend);
2153 pa_pstream_send_tagstruct(c->pstream, t);
2154 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);
2155
2156 return o;
2157 }