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