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