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