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