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