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