Add copyright notices to all relevant files. (based on svn log)
[profile/ivi/pulseaudio.git] / src / pulse / introspect.c
1 /* $Id$ */
2
3 /***
4   This file is part of PulseAudio.
5
6   Copyright 2004-2006 Lennart Poettering
7   Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
8
9   PulseAudio is free software; you can redistribute it and/or modify
10   it under the terms of the GNU Lesser General Public License as published
11   by the Free Software Foundation; either version 2 of the License,
12   or (at your option) any later version.
13
14   PulseAudio is distributed in the hope that it will be useful, but
15   WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17   General Public License for more details.
18
19   You should have received a copy of the GNU Lesser General Public License
20   along with PulseAudio; if not, write to the Free Software
21   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22   USA.
23 ***/
24
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28
29 #include <assert.h>
30
31 #include <pulse/context.h>
32
33 #include <pulsecore/gccmacro.h>
34 #include <pulsecore/pstream-util.h>
35
36 #include "internal.h"
37
38 #include "introspect.h"
39
40 /*** Statistics ***/
41
42 static void context_stat_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
43     pa_operation *o = userdata;
44     pa_stat_info i, *p = &i;
45
46     assert(pd);
47     assert(o);
48     assert(o->ref >= 1);
49
50     if (!o->context)
51         goto finish;
52
53     if (command != PA_COMMAND_REPLY) {
54         if (pa_context_handle_error(o->context, command, t) < 0)
55             goto finish;
56
57         p = NULL;
58     } else if (pa_tagstruct_getu32(t, &i.memblock_total) < 0 ||
59                pa_tagstruct_getu32(t, &i.memblock_total_size) < 0 ||
60                pa_tagstruct_getu32(t, &i.memblock_allocated) < 0 ||
61                pa_tagstruct_getu32(t, &i.memblock_allocated_size) < 0 ||
62                pa_tagstruct_getu32(t, &i.scache_size) < 0 ||
63                !pa_tagstruct_eof(t)) {
64         pa_context_fail(o->context, PA_ERR_PROTOCOL);
65         goto finish;
66     }
67
68     if (o->callback) {
69         pa_stat_info_cb_t cb = (pa_stat_info_cb_t) o->callback;
70         cb(o->context, p, o->userdata);
71     }
72
73 finish:
74     pa_operation_done(o);
75     pa_operation_unref(o);
76 }
77
78 pa_operation* pa_context_stat(pa_context *c, pa_stat_info_cb_t cb, void *userdata) {
79     return pa_context_send_simple_command(c, PA_COMMAND_STAT, context_stat_callback, (pa_operation_cb_t) cb, userdata);
80 }
81
82 /*** Server Info ***/
83
84 static void context_get_server_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
85     pa_operation *o = userdata;
86     pa_server_info i, *p = &i;
87
88     assert(pd);
89     assert(o);
90     assert(o->ref >= 1);
91
92     if (!o->context)
93         goto finish;
94
95     if (command != PA_COMMAND_REPLY) {
96         if (pa_context_handle_error(o->context, command, t) < 0)
97             goto finish;
98
99         p = NULL;
100     } else if (pa_tagstruct_gets(t, &i.server_name) < 0 ||
101                pa_tagstruct_gets(t, &i.server_version) < 0 ||
102                pa_tagstruct_gets(t, &i.user_name) < 0 ||
103                pa_tagstruct_gets(t, &i.host_name) < 0 ||
104                pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
105                pa_tagstruct_gets(t, &i.default_sink_name) < 0 ||
106                pa_tagstruct_gets(t, &i.default_source_name) < 0 ||
107                pa_tagstruct_getu32(t, &i.cookie) < 0 ||
108                !pa_tagstruct_eof(t)) {
109
110         pa_context_fail(o->context, PA_ERR_PROTOCOL);
111         goto finish;
112     }
113
114     if (o->callback) {
115         pa_server_info_cb_t cb = (pa_server_info_cb_t) o->callback;
116         cb(o->context, p, o->userdata);
117     }
118
119 finish:
120     pa_operation_done(o);
121     pa_operation_unref(o);
122 }
123
124 pa_operation* pa_context_get_server_info(pa_context *c, pa_server_info_cb_t cb, void *userdata) {
125     return pa_context_send_simple_command(c, PA_COMMAND_GET_SERVER_INFO, context_get_server_info_callback, (pa_operation_cb_t) cb, userdata);
126 }
127
128 /*** Sink Info ***/
129
130 static void context_get_sink_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
131     pa_operation *o = userdata;
132     int eol = 1;
133
134     assert(pd);
135     assert(o);
136     assert(o->ref >= 1);
137
138     if (!o->context)
139         goto finish;
140
141     if (command != PA_COMMAND_REPLY) {
142         if (pa_context_handle_error(o->context, command, t) < 0)
143             goto finish;
144
145         eol = -1;
146     } else {
147         uint32_t flags;
148
149         while (!pa_tagstruct_eof(t)) {
150             pa_sink_info i;
151
152             if (pa_tagstruct_getu32(t, &i.index) < 0 ||
153                 pa_tagstruct_gets(t, &i.name) < 0 ||
154                 pa_tagstruct_gets(t, &i.description) < 0 ||
155                 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
156                 pa_tagstruct_get_channel_map(t, &i.channel_map) < 0 ||
157                 pa_tagstruct_getu32(t, &i.owner_module) < 0 ||
158                 pa_tagstruct_get_cvolume(t, &i.volume) < 0 ||
159                 pa_tagstruct_get_boolean(t, &i.mute) < 0 ||
160                 pa_tagstruct_getu32(t, &i.monitor_source) < 0 ||
161                 pa_tagstruct_gets(t, &i.monitor_source_name) < 0 ||
162                 pa_tagstruct_get_usec(t, &i.latency) < 0 ||
163                 pa_tagstruct_gets(t, &i.driver) < 0 ||
164                 pa_tagstruct_getu32(t, &flags) < 0) {
165
166                 pa_context_fail(o->context, PA_ERR_PROTOCOL);
167                 goto finish;
168             }
169
170             i.flags = (pa_sink_flags_t) flags;
171
172             if (o->callback) {
173                 pa_sink_info_cb_t cb = (pa_sink_info_cb_t) o->callback;
174                 cb(o->context, &i, 0, o->userdata);
175             }
176         }
177     }
178
179     if (o->callback) {
180         pa_sink_info_cb_t cb = (pa_sink_info_cb_t) o->callback;
181         cb(o->context, NULL, eol, o->userdata);
182     }
183
184 finish:
185     pa_operation_done(o);
186     pa_operation_unref(o);
187 }
188
189 pa_operation* pa_context_get_sink_info_list(pa_context *c, pa_sink_info_cb_t cb, void *userdata) {
190     return pa_context_send_simple_command(c, PA_COMMAND_GET_SINK_INFO_LIST, context_get_sink_info_callback, (pa_operation_cb_t) cb, userdata);
191 }
192
193 pa_operation* pa_context_get_sink_info_by_index(pa_context *c, uint32_t idx, pa_sink_info_cb_t cb, void *userdata) {
194     pa_tagstruct *t;
195     pa_operation *o;
196     uint32_t tag;
197
198     assert(c);
199     assert(c->ref >= 1);
200     assert(cb);
201
202     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
203
204     o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
205
206     t = pa_tagstruct_command(c, PA_COMMAND_GET_SINK_INFO, &tag);
207     pa_tagstruct_putu32(t, idx);
208     pa_tagstruct_puts(t, NULL);
209     pa_pstream_send_tagstruct(c->pstream, t);
210     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);
211
212     return o;
213 }
214
215 pa_operation* pa_context_get_sink_info_by_name(pa_context *c, const char *name, pa_sink_info_cb_t cb, void *userdata) {
216     pa_tagstruct *t;
217     pa_operation *o;
218     uint32_t tag;
219
220     assert(c);
221     assert(c->ref >= 1);
222     assert(cb);
223
224     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
225     PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
226
227     o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
228
229     t = pa_tagstruct_command(c, PA_COMMAND_GET_SINK_INFO, &tag);
230     pa_tagstruct_putu32(t, PA_INVALID_INDEX);
231     pa_tagstruct_puts(t, name);
232     pa_pstream_send_tagstruct(c->pstream, t);
233     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);
234
235     return o;
236 }
237
238 /*** Source info ***/
239
240 static void context_get_source_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
241     pa_operation *o = userdata;
242     int eol = 1;
243
244     assert(pd);
245     assert(o);
246     assert(o->ref >= 1);
247
248     if (!o->context)
249         goto finish;
250
251     if (command != PA_COMMAND_REPLY) {
252         if (pa_context_handle_error(o->context, command, t) < 0)
253             goto finish;
254
255         eol = -1;
256     } else {
257
258         while (!pa_tagstruct_eof(t)) {
259             pa_source_info i;
260             uint32_t flags;
261
262             if (pa_tagstruct_getu32(t, &i.index) < 0 ||
263                 pa_tagstruct_gets(t, &i.name) < 0 ||
264                 pa_tagstruct_gets(t, &i.description) < 0 ||
265                 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
266                 pa_tagstruct_get_channel_map(t, &i.channel_map) < 0 ||
267                 pa_tagstruct_getu32(t, &i.owner_module) < 0 ||
268                 pa_tagstruct_get_cvolume(t, &i.volume) < 0 ||
269                 pa_tagstruct_get_boolean(t, &i.mute) < 0 ||
270                 pa_tagstruct_getu32(t, &i.monitor_of_sink) < 0 ||
271                 pa_tagstruct_gets(t, &i.monitor_of_sink_name) < 0 ||
272                 pa_tagstruct_get_usec(t, &i.latency) < 0 ||
273                 pa_tagstruct_gets(t, &i.driver) < 0 ||
274                 pa_tagstruct_getu32(t, &flags) < 0) {
275
276                 pa_context_fail(o->context, PA_ERR_PROTOCOL);
277                 goto finish;
278             }
279
280             i.flags = (pa_source_flags_t) flags;
281
282             if (o->callback) {
283                 pa_source_info_cb_t cb = (pa_source_info_cb_t) o->callback;
284                 cb(o->context, &i, 0, o->userdata);
285             }
286         }
287     }
288
289     if (o->callback) {
290         pa_source_info_cb_t cb = (pa_source_info_cb_t) o->callback;
291         cb(o->context, NULL, eol, o->userdata);
292     }
293
294 finish:
295     pa_operation_done(o);
296     pa_operation_unref(o);
297 }
298
299 pa_operation* pa_context_get_source_info_list(pa_context *c, pa_source_info_cb_t cb, void *userdata) {
300     return pa_context_send_simple_command(c, PA_COMMAND_GET_SOURCE_INFO_LIST, context_get_source_info_callback, (pa_operation_cb_t) cb, userdata);
301 }
302
303 pa_operation* pa_context_get_source_info_by_index(pa_context *c, uint32_t idx, pa_source_info_cb_t cb, void *userdata) {
304     pa_tagstruct *t;
305     pa_operation *o;
306     uint32_t tag;
307
308     assert(c);
309     assert(c->ref >= 1);
310     assert(cb);
311
312     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
313
314     o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
315
316     t = pa_tagstruct_command(c, PA_COMMAND_GET_SOURCE_INFO, &tag);
317     pa_tagstruct_putu32(t, idx);
318     pa_tagstruct_puts(t, NULL);
319     pa_pstream_send_tagstruct(c->pstream, t);
320     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);
321
322     return o;
323 }
324
325 pa_operation* pa_context_get_source_info_by_name(pa_context *c, const char *name, pa_source_info_cb_t cb, void *userdata) {
326     pa_tagstruct *t;
327     pa_operation *o;
328     uint32_t tag;
329
330     assert(c);
331     assert(c->ref >= 1);
332     assert(cb);
333
334     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
335     PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
336
337     o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
338
339     t = pa_tagstruct_command(c, PA_COMMAND_GET_SOURCE_INFO, &tag);
340     pa_tagstruct_putu32(t, PA_INVALID_INDEX);
341     pa_tagstruct_puts(t, name);
342     pa_pstream_send_tagstruct(c->pstream, t);
343     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);
344
345     return o;
346 }
347
348 /*** Client info ***/
349
350 static void context_get_client_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
351     pa_operation *o = userdata;
352     int eol = 1;
353
354     assert(pd);
355     assert(o);
356     assert(o->ref >= 1);
357
358     if (!o->context)
359         goto finish;
360
361     if (command != PA_COMMAND_REPLY) {
362         if (pa_context_handle_error(o->context, command, t) < 0)
363             goto finish;
364
365         eol = -1;
366     } else {
367
368         while (!pa_tagstruct_eof(t)) {
369             pa_client_info i;
370
371             if (pa_tagstruct_getu32(t, &i.index) < 0 ||
372                 pa_tagstruct_gets(t, &i.name) < 0 ||
373                 pa_tagstruct_getu32(t, &i.owner_module) < 0 ||
374                 pa_tagstruct_gets(t, &i.driver) < 0 ) {
375                 pa_context_fail(o->context, PA_ERR_PROTOCOL);
376                 goto finish;
377             }
378
379             if (o->callback) {
380                 pa_client_info_cb_t cb = (pa_client_info_cb_t) o->callback;
381                 cb(o->context, &i, 0, o->userdata);
382             }
383         }
384     }
385
386     if (o->callback) {
387         pa_client_info_cb_t cb = (pa_client_info_cb_t) o->callback;
388         cb(o->context, NULL, eol, o->userdata);
389     }
390
391 finish:
392     pa_operation_done(o);
393     pa_operation_unref(o);
394 }
395
396 pa_operation* pa_context_get_client_info(pa_context *c, uint32_t idx, pa_client_info_cb_t cb, void *userdata) {
397     pa_tagstruct *t;
398     pa_operation *o;
399     uint32_t tag;
400
401     assert(c);
402     assert(c->ref >= 1);
403     assert(cb);
404
405     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
406     PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
407
408     o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
409
410     t = pa_tagstruct_command(c, PA_COMMAND_GET_CLIENT_INFO, &tag);
411     pa_tagstruct_putu32(t, idx);
412     pa_pstream_send_tagstruct(c->pstream, t);
413     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);
414
415     return o;
416 }
417
418 pa_operation* pa_context_get_client_info_list(pa_context *c, pa_client_info_cb_t cb, void *userdata) {
419     return pa_context_send_simple_command(c, PA_COMMAND_GET_CLIENT_INFO_LIST, context_get_client_info_callback, (pa_operation_cb_t) cb, userdata);
420 }
421
422 /*** Module info ***/
423
424 static void context_get_module_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
425     pa_operation *o = userdata;
426     int eol = 1;
427
428     assert(pd);
429     assert(o);
430     assert(o->ref >= 1);
431
432     if (!o->context)
433         goto finish;
434
435     if (command != PA_COMMAND_REPLY) {
436         if (pa_context_handle_error(o->context, command, t) < 0)
437             goto finish;
438
439         eol = -1;
440     } else {
441
442         while (!pa_tagstruct_eof(t)) {
443             pa_module_info i;
444
445             if (pa_tagstruct_getu32(t, &i.index) < 0 ||
446                 pa_tagstruct_gets(t, &i.name) < 0 ||
447                 pa_tagstruct_gets(t, &i.argument) < 0 ||
448                 pa_tagstruct_getu32(t, &i.n_used) < 0 ||
449                 pa_tagstruct_get_boolean(t, &i.auto_unload) < 0) {
450                 pa_context_fail(o->context, PA_ERR_PROTOCOL);
451                 goto finish;
452             }
453
454             if (o->callback) {
455                 pa_module_info_cb_t cb = (pa_module_info_cb_t) o->callback;
456                 cb(o->context, &i, 0, o->userdata);
457             }
458         }
459     }
460
461     if (o->callback) {
462         pa_module_info_cb_t cb = (pa_module_info_cb_t) o->callback;
463         cb(o->context, NULL, eol, o->userdata);
464     }
465
466 finish:
467     pa_operation_done(o);
468     pa_operation_unref(o);
469 }
470
471 pa_operation* pa_context_get_module_info(pa_context *c, uint32_t idx, pa_module_info_cb_t cb, void *userdata) {
472     pa_tagstruct *t;
473     pa_operation *o;
474     uint32_t tag;
475
476     assert(c);
477     assert(c->ref >= 1);
478     assert(cb);
479
480     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
481     PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
482
483     o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
484
485     t = pa_tagstruct_command(c, PA_COMMAND_GET_MODULE_INFO, &tag);
486     pa_tagstruct_putu32(t, idx);
487     pa_pstream_send_tagstruct(c->pstream, t);
488     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);
489
490     return o;
491 }
492
493 pa_operation* pa_context_get_module_info_list(pa_context *c, pa_module_info_cb_t cb, void *userdata) {
494     return pa_context_send_simple_command(c, PA_COMMAND_GET_MODULE_INFO_LIST, context_get_module_info_callback, (pa_operation_cb_t) cb, userdata);
495 }
496
497 /*** Sink input info ***/
498
499 static void context_get_sink_input_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
500     pa_operation *o = userdata;
501     int eol = 1;
502
503     assert(pd);
504     assert(o);
505     assert(o->ref >= 1);
506
507     if (!o->context)
508         goto finish;
509
510     if (command != PA_COMMAND_REPLY) {
511         if (pa_context_handle_error(o->context, command, t) < 0)
512             goto finish;
513
514         eol = -1;
515     } else {
516
517         while (!pa_tagstruct_eof(t)) {
518             pa_sink_input_info i;
519
520             if (pa_tagstruct_getu32(t, &i.index) < 0 ||
521                 pa_tagstruct_gets(t, &i.name) < 0 ||
522                 pa_tagstruct_getu32(t, &i.owner_module) < 0 ||
523                 pa_tagstruct_getu32(t, &i.client) < 0 ||
524                 pa_tagstruct_getu32(t, &i.sink) < 0 ||
525                 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
526                 pa_tagstruct_get_channel_map(t, &i.channel_map) < 0 ||
527                 pa_tagstruct_get_cvolume(t, &i.volume) < 0 ||
528                 pa_tagstruct_get_usec(t, &i.buffer_usec) < 0 ||
529                 pa_tagstruct_get_usec(t, &i.sink_usec) < 0 ||
530                 pa_tagstruct_gets(t, &i.resample_method) < 0 ||
531                 pa_tagstruct_gets(t, &i.driver) < 0) {
532
533                 pa_context_fail(o->context, PA_ERR_PROTOCOL);
534                 goto finish;
535             }
536
537             if (o->callback) {
538                 pa_sink_input_info_cb_t cb = (pa_sink_input_info_cb_t) o->callback;
539                 cb(o->context, &i, 0, o->userdata);
540             }
541         }
542     }
543
544     if (o->callback) {
545         pa_sink_input_info_cb_t cb = (pa_sink_input_info_cb_t) o->callback;
546         cb(o->context, NULL, eol, o->userdata);
547     }
548
549 finish:
550     pa_operation_done(o);
551     pa_operation_unref(o);
552 }
553
554 pa_operation* pa_context_get_sink_input_info(pa_context *c, uint32_t idx, pa_sink_input_info_cb_t cb, void *userdata) {
555     pa_tagstruct *t;
556     pa_operation *o;
557     uint32_t tag;
558
559     assert(c);
560     assert(c->ref >= 1);
561     assert(cb);
562
563     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
564     PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
565
566     o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
567
568     t = pa_tagstruct_command(c, PA_COMMAND_GET_SINK_INPUT_INFO, &tag);
569     pa_tagstruct_putu32(t, idx);
570     pa_pstream_send_tagstruct(c->pstream, t);
571     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);
572
573     return o;
574 }
575
576 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) {
577     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);
578 }
579
580 /*** Source output info ***/
581
582 static void context_get_source_output_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
583     pa_operation *o = userdata;
584     int eol = 1;
585
586     assert(pd);
587     assert(o);
588     assert(o->ref >= 1);
589
590     if (!o->context)
591         goto finish;
592
593     if (command != PA_COMMAND_REPLY) {
594         if (pa_context_handle_error(o->context, command, t) < 0)
595             goto finish;
596
597         eol = -1;
598     } else {
599
600         while (!pa_tagstruct_eof(t)) {
601             pa_source_output_info i;
602
603             if (pa_tagstruct_getu32(t, &i.index) < 0 ||
604                 pa_tagstruct_gets(t, &i.name) < 0 ||
605                 pa_tagstruct_getu32(t, &i.owner_module) < 0 ||
606                 pa_tagstruct_getu32(t, &i.client) < 0 ||
607                 pa_tagstruct_getu32(t, &i.source) < 0 ||
608                 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
609                 pa_tagstruct_get_channel_map(t, &i.channel_map) < 0 ||
610                 pa_tagstruct_get_usec(t, &i.buffer_usec) < 0 ||
611                 pa_tagstruct_get_usec(t, &i.source_usec) < 0 ||
612                 pa_tagstruct_gets(t, &i.resample_method) < 0 ||
613                 pa_tagstruct_gets(t, &i.driver) < 0) {
614
615                 pa_context_fail(o->context, PA_ERR_PROTOCOL);
616                 goto finish;
617             }
618
619             if (o->callback) {
620                 pa_source_output_info_cb_t cb = (pa_source_output_info_cb_t) o->callback;
621                 cb(o->context, &i, 0, o->userdata);
622             }
623         }
624     }
625
626     if (o->callback) {
627         pa_source_output_info_cb_t cb = (pa_source_output_info_cb_t) o->callback;
628         cb(o->context, NULL, eol, o->userdata);
629     }
630
631 finish:
632     pa_operation_done(o);
633     pa_operation_unref(o);
634 }
635
636 pa_operation* pa_context_get_source_output_info(pa_context *c, uint32_t idx, pa_source_output_info_cb_t cb, void *userdata) {
637     pa_tagstruct *t;
638     pa_operation *o;
639     uint32_t tag;
640
641     assert(c);
642     assert(c->ref >= 1);
643     assert(cb);
644
645     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
646     PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
647
648     o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
649
650     t = pa_tagstruct_command(c, PA_COMMAND_GET_SOURCE_OUTPUT_INFO, &tag);
651     pa_tagstruct_putu32(t, idx);
652     pa_pstream_send_tagstruct(c->pstream, t);
653     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);
654
655     return o;
656 }
657
658 pa_operation* pa_context_get_source_output_info_list(pa_context *c,  pa_source_output_info_cb_t cb, void *userdata) {
659     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);
660 }
661
662 /*** Volume manipulation ***/
663
664 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) {
665     pa_operation *o;
666     pa_tagstruct *t;
667     uint32_t tag;
668
669     assert(c);
670     assert(c->ref >= 1);
671     assert(volume);
672
673     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
674     PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID);
675
676     o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
677
678     t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_VOLUME, &tag);
679     pa_tagstruct_putu32(t, idx);
680     pa_tagstruct_puts(t, NULL);
681     pa_tagstruct_put_cvolume(t, volume);
682     pa_pstream_send_tagstruct(c->pstream, t);
683     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);
684
685     return o;
686 }
687
688 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) {
689     pa_operation *o;
690     pa_tagstruct *t;
691     uint32_t tag;
692
693     assert(c);
694     assert(c->ref >= 1);
695     assert(name);
696     assert(volume);
697
698     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
699     PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID);
700     PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
701
702     o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
703
704     t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_VOLUME, &tag);
705     pa_tagstruct_putu32(t, PA_INVALID_INDEX);
706     pa_tagstruct_puts(t, name);
707     pa_tagstruct_put_cvolume(t, volume);
708     pa_pstream_send_tagstruct(c->pstream, t);
709     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);
710
711     return o;
712 }
713
714 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) {
715     pa_operation *o;
716     pa_tagstruct *t;
717     uint32_t tag;
718
719     assert(c);
720     assert(c->ref >= 1);
721
722     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
723
724     o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
725
726     t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_MUTE, &tag);
727     pa_tagstruct_putu32(t, idx);
728     pa_tagstruct_puts(t, NULL);
729     pa_tagstruct_put_boolean(t, mute);
730     pa_pstream_send_tagstruct(c->pstream, t);
731     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);
732
733     return o;
734 }
735
736 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) {
737     pa_operation *o;
738     pa_tagstruct *t;
739     uint32_t tag;
740
741     assert(c);
742     assert(c->ref >= 1);
743     assert(name);
744
745     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
746     PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
747
748     o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
749
750     t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_MUTE, &tag);
751     pa_tagstruct_putu32(t, PA_INVALID_INDEX);
752     pa_tagstruct_puts(t, name);
753     pa_tagstruct_put_boolean(t, mute);
754     pa_pstream_send_tagstruct(c->pstream, t);
755     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);
756
757     return o;
758 }
759
760 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) {
761     pa_operation *o;
762     pa_tagstruct *t;
763     uint32_t tag;
764
765     assert(c);
766     assert(c->ref >= 1);
767     assert(volume);
768
769     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
770     PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
771     PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID);
772
773     o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
774
775     t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_INPUT_VOLUME, &tag);
776     pa_tagstruct_putu32(t, idx);
777     pa_tagstruct_put_cvolume(t, volume);
778     pa_pstream_send_tagstruct(c->pstream, t);
779     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);
780
781     return o;
782 }
783
784 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) {
785     pa_operation *o;
786     pa_tagstruct *t;
787     uint32_t tag;
788
789     assert(c);
790     assert(c->ref >= 1);
791     assert(volume);
792
793     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
794     PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID);
795
796     o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
797
798     t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_VOLUME, &tag);
799     pa_tagstruct_putu32(t, idx);
800     pa_tagstruct_puts(t, NULL);
801     pa_tagstruct_put_cvolume(t, volume);
802     pa_pstream_send_tagstruct(c->pstream, t);
803     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);
804
805     return o;
806 }
807
808 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) {
809     pa_operation *o;
810     pa_tagstruct *t;
811     uint32_t tag;
812
813     assert(c);
814     assert(c->ref >= 1);
815     assert(name);
816     assert(volume);
817
818     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
819     PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID);
820     PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
821
822     o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
823
824     t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_VOLUME, &tag);
825     pa_tagstruct_putu32(t, PA_INVALID_INDEX);
826     pa_tagstruct_puts(t, name);
827     pa_tagstruct_put_cvolume(t, volume);
828     pa_pstream_send_tagstruct(c->pstream, t);
829     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);
830
831     return o;
832 }
833
834 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) {
835     pa_operation *o;
836     pa_tagstruct *t;
837     uint32_t tag;
838
839     assert(c);
840     assert(c->ref >= 1);
841
842     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
843
844     o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
845
846     t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_MUTE, &tag);
847     pa_tagstruct_putu32(t, idx);
848     pa_tagstruct_puts(t, NULL);
849     pa_tagstruct_put_boolean(t, mute);
850     pa_pstream_send_tagstruct(c->pstream, t);
851     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);
852
853     return o;
854 }
855
856 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) {
857     pa_operation *o;
858     pa_tagstruct *t;
859     uint32_t tag;
860
861     assert(c);
862     assert(c->ref >= 1);
863     assert(name);
864
865     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
866     PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
867
868     o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
869
870     t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_MUTE, &tag);
871     pa_tagstruct_putu32(t, PA_INVALID_INDEX);
872     pa_tagstruct_puts(t, name);
873     pa_tagstruct_put_boolean(t, mute);
874     pa_pstream_send_tagstruct(c->pstream, t);
875     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);
876
877     return o;
878 }
879
880 /** Sample Cache **/
881
882 static void context_get_sample_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
883     pa_operation *o = userdata;
884     int eol = 1;
885
886     assert(pd);
887     assert(o);
888     assert(o->ref >= 1);
889
890     if (!o->context)
891         goto finish;
892
893     if (command != PA_COMMAND_REPLY) {
894         if (pa_context_handle_error(o->context, command, t) < 0)
895             goto finish;
896
897         eol = -1;
898     } else {
899
900         while (!pa_tagstruct_eof(t)) {
901             pa_sample_info i;
902
903             if (pa_tagstruct_getu32(t, &i.index) < 0 ||
904                 pa_tagstruct_gets(t, &i.name) < 0 ||
905                 pa_tagstruct_get_cvolume(t, &i.volume) < 0 ||
906                 pa_tagstruct_get_usec(t, &i.duration) < 0 ||
907                 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
908                 pa_tagstruct_get_channel_map(t, &i.channel_map) < 0 ||
909                 pa_tagstruct_getu32(t, &i.bytes) < 0 ||
910                 pa_tagstruct_get_boolean(t, &i.lazy) < 0 ||
911                 pa_tagstruct_gets(t, &i.filename) < 0) {
912
913                 pa_context_fail(o->context, PA_ERR_PROTOCOL);
914                 goto finish;
915             }
916
917             if (o->callback) {
918                 pa_sample_info_cb_t cb = (pa_sample_info_cb_t) o->callback;
919                 cb(o->context, &i, 0, o->userdata);
920             }
921         }
922     }
923
924     if (o->callback) {
925         pa_sample_info_cb_t cb = (pa_sample_info_cb_t) o->callback;
926         cb(o->context, NULL, eol, o->userdata);
927     }
928
929 finish:
930     pa_operation_done(o);
931     pa_operation_unref(o);
932 }
933
934 pa_operation* pa_context_get_sample_info_by_name(pa_context *c, const char *name, pa_sample_info_cb_t cb, void *userdata) {
935     pa_tagstruct *t;
936     pa_operation *o;
937     uint32_t tag;
938
939     assert(c);
940     assert(c->ref >= 1);
941     assert(cb);
942
943     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
944     PA_CHECK_VALIDITY_RETURN_NULL(c, name && *name, PA_ERR_INVALID);
945
946     o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
947
948     t = pa_tagstruct_command(c, PA_COMMAND_GET_SAMPLE_INFO, &tag);
949     pa_tagstruct_putu32(t, PA_INVALID_INDEX);
950     pa_tagstruct_puts(t, name);
951     pa_pstream_send_tagstruct(c->pstream, t);
952     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);
953
954     return o;
955 }
956
957 pa_operation* pa_context_get_sample_info_by_index(pa_context *c, uint32_t idx, pa_sample_info_cb_t cb, void *userdata) {
958     pa_tagstruct *t;
959     pa_operation *o;
960     uint32_t tag;
961
962     assert(c);
963     assert(c->ref >= 1);
964     assert(cb);
965
966     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
967     PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
968
969     o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
970
971     t = pa_tagstruct_command(c, PA_COMMAND_GET_SAMPLE_INFO, &tag);
972     pa_tagstruct_putu32(t, idx);
973     pa_tagstruct_puts(t, NULL);
974     pa_pstream_send_tagstruct(c->pstream, t);
975     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);
976
977     return o;
978 }
979
980 pa_operation* pa_context_get_sample_info_list(pa_context *c, pa_sample_info_cb_t cb, void *userdata) {
981     return pa_context_send_simple_command(c, PA_COMMAND_GET_SAMPLE_INFO_LIST, context_get_sample_info_callback, (pa_operation_cb_t) cb, userdata);
982 }
983
984 static pa_operation* command_kill(pa_context *c, uint32_t command, uint32_t idx, pa_context_success_cb_t cb, void *userdata) {
985     pa_operation *o;
986     pa_tagstruct *t;
987     uint32_t tag;
988
989     assert(c);
990     assert(c->ref >= 1);
991
992     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
993     PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
994
995     o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
996
997     t = pa_tagstruct_command(c, command, &tag);
998     pa_tagstruct_putu32(t, idx);
999     pa_pstream_send_tagstruct(c->pstream, t);
1000     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);
1001
1002     return o;
1003 }
1004
1005 pa_operation* pa_context_kill_client(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata) {
1006     return command_kill(c, PA_COMMAND_KILL_CLIENT, idx, cb, userdata);
1007 }
1008
1009 pa_operation* pa_context_kill_sink_input(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata) {
1010     return command_kill(c, PA_COMMAND_KILL_SINK_INPUT, idx, cb, userdata);
1011 }
1012
1013 pa_operation* pa_context_kill_source_output(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata) {
1014     return command_kill(c, PA_COMMAND_KILL_SOURCE_OUTPUT, idx, cb, userdata);
1015 }
1016
1017 static void context_index_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
1018     pa_operation *o = userdata;
1019     uint32_t idx;
1020
1021     assert(pd);
1022     assert(o);
1023     assert(o->ref >= 1);
1024
1025     if (!o->context)
1026         goto finish;
1027
1028     if (command != PA_COMMAND_REPLY) {
1029         if (pa_context_handle_error(o->context, command, t) < 0)
1030             goto finish;
1031
1032         idx = PA_INVALID_INDEX;
1033     } else if (pa_tagstruct_getu32(t, &idx) ||
1034                !pa_tagstruct_eof(t)) {
1035         pa_context_fail(o->context, PA_ERR_PROTOCOL);
1036         goto finish;
1037     }
1038
1039     if (o->callback) {
1040         pa_context_index_cb_t cb = (pa_context_index_cb_t) o->callback;
1041         cb(o->context, idx, o->userdata);
1042     }
1043
1044
1045 finish:
1046     pa_operation_done(o);
1047     pa_operation_unref(o);
1048 }
1049
1050 pa_operation* pa_context_load_module(pa_context *c, const char*name, const char *argument, pa_context_index_cb_t cb, void *userdata) {
1051     pa_operation *o;
1052     pa_tagstruct *t;
1053     uint32_t tag;
1054
1055     assert(c);
1056     assert(c->ref >= 1);
1057
1058     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1059     PA_CHECK_VALIDITY_RETURN_NULL(c, name && *name, PA_ERR_INVALID);
1060
1061     o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1062
1063     t = pa_tagstruct_command(c, PA_COMMAND_LOAD_MODULE, &tag);
1064     pa_tagstruct_puts(t, name);
1065     pa_tagstruct_puts(t, argument);
1066     pa_pstream_send_tagstruct(c->pstream, t);
1067     pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_index_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1068
1069     return o;
1070 }
1071
1072 pa_operation* pa_context_unload_module(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata) {
1073     return command_kill(c, PA_COMMAND_UNLOAD_MODULE, idx, cb, userdata);
1074 }
1075
1076 /*** Autoload stuff ***/
1077
1078 static void context_get_autoload_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
1079     pa_operation *o = userdata;
1080     int eol = 1;
1081
1082     assert(pd);
1083     assert(o);
1084     assert(o->ref >= 1);
1085
1086     if (!o->context)
1087         goto finish;
1088
1089     if (command != PA_COMMAND_REPLY) {
1090         if (pa_context_handle_error(o->context, command, t) < 0)
1091             goto finish;
1092
1093         eol = -1;
1094     } else {
1095
1096         while (!pa_tagstruct_eof(t)) {
1097             pa_autoload_info i;
1098
1099             if (pa_tagstruct_getu32(t, &i.index) < 0 ||
1100                 pa_tagstruct_gets(t, &i.name) < 0 ||
1101                 pa_tagstruct_getu32(t, &i.type) < 0 ||
1102                 pa_tagstruct_gets(t, &i.module) < 0 ||
1103                 pa_tagstruct_gets(t, &i.argument) < 0) {
1104                 pa_context_fail(o->context, PA_ERR_PROTOCOL);
1105                 goto finish;
1106             }
1107
1108             if (o->callback) {
1109                 pa_autoload_info_cb_t cb = (pa_autoload_info_cb_t) o->callback;
1110                 cb(o->context, &i, 0, o->userdata);
1111             }
1112         }
1113     }
1114
1115     if (o->callback) {
1116         pa_autoload_info_cb_t cb = (pa_autoload_info_cb_t) o->callback;
1117         cb(o->context, NULL, eol, o->userdata);
1118     }
1119
1120 finish:
1121     pa_operation_done(o);
1122     pa_operation_unref(o);
1123 }
1124
1125 pa_operation* pa_context_get_autoload_info_by_name(pa_context *c, const char *name, pa_autoload_type_t type, pa_autoload_info_cb_t cb, void *userdata) {
1126     pa_tagstruct *t;
1127     pa_operation *o;
1128     uint32_t tag;
1129
1130     assert(c);
1131     assert(c->ref >= 1);
1132     assert(cb);
1133
1134     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1135     PA_CHECK_VALIDITY_RETURN_NULL(c, name && *name, PA_ERR_INVALID);
1136     PA_CHECK_VALIDITY_RETURN_NULL(c, type == PA_AUTOLOAD_SINK || type == PA_AUTOLOAD_SOURCE, PA_ERR_INVALID);
1137
1138     o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1139
1140     t = pa_tagstruct_command(c, PA_COMMAND_GET_AUTOLOAD_INFO, &tag);
1141     pa_tagstruct_puts(t, name);
1142     pa_tagstruct_putu32(t, type);
1143     pa_pstream_send_tagstruct(c->pstream, t);
1144     pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_autoload_info_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1145
1146     return o;
1147 }
1148
1149 pa_operation* pa_context_get_autoload_info_by_index(pa_context *c, uint32_t idx, pa_autoload_info_cb_t cb, void *userdata) {
1150     pa_tagstruct *t;
1151     pa_operation *o;
1152     uint32_t tag;
1153
1154     assert(c);
1155     assert(c->ref >= 1);
1156     assert(cb);
1157
1158     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1159     PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1160
1161     o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1162
1163     t = pa_tagstruct_command(c, PA_COMMAND_GET_AUTOLOAD_INFO, &tag);
1164     pa_tagstruct_putu32(t, idx);
1165     pa_pstream_send_tagstruct(c->pstream, t);
1166     pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_autoload_info_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1167
1168     return o;
1169 }
1170
1171 pa_operation* pa_context_get_autoload_info_list(pa_context *c, pa_autoload_info_cb_t cb, void *userdata) {
1172     return pa_context_send_simple_command(c, PA_COMMAND_GET_AUTOLOAD_INFO_LIST, context_get_autoload_info_callback, (pa_operation_cb_t) cb, userdata);
1173 }
1174
1175 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) {
1176     pa_operation *o;
1177     pa_tagstruct *t;
1178     uint32_t tag;
1179
1180     assert(c);
1181     assert(c->ref >= 1);
1182
1183     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1184     PA_CHECK_VALIDITY_RETURN_NULL(c, name && *name, PA_ERR_INVALID);
1185     PA_CHECK_VALIDITY_RETURN_NULL(c, type == PA_AUTOLOAD_SINK || type == PA_AUTOLOAD_SOURCE, PA_ERR_INVALID);
1186     PA_CHECK_VALIDITY_RETURN_NULL(c, module && *module, PA_ERR_INVALID);
1187
1188     o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1189
1190     t = pa_tagstruct_command(c, PA_COMMAND_ADD_AUTOLOAD, &tag);
1191     pa_tagstruct_puts(t, name);
1192     pa_tagstruct_putu32(t, type);
1193     pa_tagstruct_puts(t, module);
1194     pa_tagstruct_puts(t, argument);
1195     pa_pstream_send_tagstruct(c->pstream, t);
1196     pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_index_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1197
1198     return o;
1199 }
1200
1201 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) {
1202     pa_operation *o;
1203     pa_tagstruct *t;
1204     uint32_t tag;
1205
1206     assert(c);
1207     assert(c->ref >= 1);
1208
1209     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1210     PA_CHECK_VALIDITY_RETURN_NULL(c, name && *name, PA_ERR_INVALID);
1211     PA_CHECK_VALIDITY_RETURN_NULL(c, type == PA_AUTOLOAD_SINK || type == PA_AUTOLOAD_SOURCE, PA_ERR_INVALID);
1212
1213     o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1214
1215     t = pa_tagstruct_command(c, PA_COMMAND_REMOVE_AUTOLOAD, &tag);
1216     pa_tagstruct_puts(t, name);
1217     pa_tagstruct_putu32(t, type);
1218     pa_pstream_send_tagstruct(c->pstream, t);
1219     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);
1220
1221     return o;
1222 }
1223
1224 pa_operation* pa_context_remove_autoload_by_index(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void* userdata) {
1225     pa_operation *o;
1226     pa_tagstruct *t;
1227     uint32_t tag;
1228
1229     assert(c);
1230     assert(c->ref >= 1);
1231
1232     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1233     PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1234
1235     o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1236
1237     t = pa_tagstruct_command(c, PA_COMMAND_REMOVE_AUTOLOAD, &tag);
1238     pa_tagstruct_putu32(t, idx);
1239     pa_pstream_send_tagstruct(c->pstream, t);
1240     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);
1241
1242     return o;
1243 }
1244
1245 pa_operation* pa_context_move_sink_input_by_name(pa_context *c, uint32_t idx, char *sink_name, pa_context_success_cb_t cb, void* userdata) {
1246     pa_operation *o;
1247     pa_tagstruct *t;
1248     uint32_t tag;
1249
1250     assert(c);
1251     assert(c->ref >= 1);
1252
1253     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1254     PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 10, PA_ERR_NOTSUPPORTED);
1255     PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1256     PA_CHECK_VALIDITY_RETURN_NULL(c, sink_name && *sink_name, PA_ERR_INVALID);
1257
1258     o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1259
1260     t = pa_tagstruct_command(c, PA_COMMAND_MOVE_SINK_INPUT, &tag);
1261     pa_tagstruct_putu32(t, idx);
1262     pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1263     pa_tagstruct_puts(t, sink_name);
1264     pa_pstream_send_tagstruct(c->pstream, t);
1265     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);
1266
1267     return o;
1268 }
1269
1270 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) {
1271     pa_operation *o;
1272     pa_tagstruct *t;
1273     uint32_t tag;
1274
1275     assert(c);
1276     assert(c->ref >= 1);
1277
1278     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1279     PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 10, PA_ERR_NOTSUPPORTED);
1280     PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1281     PA_CHECK_VALIDITY_RETURN_NULL(c, sink_idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1282
1283     o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1284
1285     t = pa_tagstruct_command(c, PA_COMMAND_MOVE_SINK_INPUT, &tag);
1286     pa_tagstruct_putu32(t, idx);
1287     pa_tagstruct_putu32(t, sink_idx);
1288     pa_tagstruct_puts(t, NULL);
1289     pa_pstream_send_tagstruct(c->pstream, t);
1290     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);
1291
1292     return o;
1293 }
1294
1295 pa_operation* pa_context_move_source_output_by_name(pa_context *c, uint32_t idx, char *source_name, pa_context_success_cb_t cb, void* userdata) {
1296     pa_operation *o;
1297     pa_tagstruct *t;
1298     uint32_t tag;
1299
1300     assert(c);
1301     assert(c->ref >= 1);
1302
1303     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1304     PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 10, PA_ERR_NOTSUPPORTED);
1305     PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1306     PA_CHECK_VALIDITY_RETURN_NULL(c, source_name && *source_name, PA_ERR_INVALID);
1307
1308     o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1309
1310     t = pa_tagstruct_command(c, PA_COMMAND_MOVE_SOURCE_OUTPUT, &tag);
1311     pa_tagstruct_putu32(t, idx);
1312     pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1313     pa_tagstruct_puts(t, source_name);
1314     pa_pstream_send_tagstruct(c->pstream, t);
1315     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);
1316
1317     return o;
1318 }
1319
1320 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) {
1321     pa_operation *o;
1322     pa_tagstruct *t;
1323     uint32_t tag;
1324
1325     assert(c);
1326     assert(c->ref >= 1);
1327
1328     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1329     PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 10, PA_ERR_NOTSUPPORTED);
1330     PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1331     PA_CHECK_VALIDITY_RETURN_NULL(c, source_idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1332
1333     o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1334
1335     t = pa_tagstruct_command(c, PA_COMMAND_MOVE_SOURCE_OUTPUT, &tag);
1336     pa_tagstruct_putu32(t, idx);
1337     pa_tagstruct_putu32(t, source_idx);
1338     pa_tagstruct_puts(t, NULL);
1339     pa_pstream_send_tagstruct(c->pstream, t);
1340     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);
1341
1342     return o;
1343 }