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