]> code.delx.au - pulseaudio/blob - src/polyp/introspect.c
404cead5e85adacbd294d1eaf35f075259fb1ef2
[pulseaudio] / src / polyp / introspect.c
1 /* $Id$ */
2
3 /***
4 This file is part of polypaudio.
5
6 polypaudio is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published
8 by the Free Software Foundation; either version 2 of the License,
9 or (at your option) any later version.
10
11 polypaudio is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with polypaudio; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 USA.
20 ***/
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <assert.h>
27
28 #include <polyp/context.h>
29
30 #include <polypcore/gccmacro.h>
31 #include <polypcore/pstream-util.h>
32
33 #include "internal.h"
34
35 #include "introspect.h"
36
37 /*** Statistics ***/
38
39 static void context_stat_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
40 pa_operation *o = userdata;
41 pa_stat_info i, *p = &i;
42 assert(pd && o && o->context && o->ref >= 1);
43
44 if (command != PA_COMMAND_REPLY) {
45 if (pa_context_handle_error(o->context, command, t) < 0)
46 goto finish;
47
48 p = NULL;
49 } else if (pa_tagstruct_getu32(t, &i.memblock_total) < 0 ||
50 pa_tagstruct_getu32(t, &i.memblock_total_size) < 0 ||
51 pa_tagstruct_getu32(t, &i.memblock_allocated) < 0 ||
52 pa_tagstruct_getu32(t, &i.memblock_allocated_size) < 0 ||
53 pa_tagstruct_getu32(t, &i.scache_size) < 0 ||
54 !pa_tagstruct_eof(t)) {
55 pa_context_fail(o->context, PA_ERR_PROTOCOL);
56 goto finish;
57 }
58
59 if (o->callback) {
60 void (*cb)(pa_context *s, const pa_stat_info*_i, void *_userdata) = (void (*)(pa_context *s, const pa_stat_info*_i, void *_userdata)) o->callback;
61 cb(o->context, p, o->userdata);
62 }
63
64 finish:
65 pa_operation_done(o);
66 pa_operation_unref(o);
67 }
68
69 pa_operation* pa_context_stat(pa_context *c, void (*cb)(pa_context *c, const pa_stat_info*i, void *userdata), void *userdata) {
70 return pa_context_send_simple_command(c, PA_COMMAND_STAT, context_stat_callback, (pa_operation_callback_t) cb, userdata);
71 }
72
73 /*** Server Info ***/
74
75 static void context_get_server_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
76 pa_operation *o = userdata;
77 pa_server_info i, *p = &i;
78 assert(pd && o && o->context && o->ref >= 1);
79
80 if (command != PA_COMMAND_REPLY) {
81 if (pa_context_handle_error(o->context, command, t) < 0)
82 goto finish;
83
84 p = NULL;
85 } else if (pa_tagstruct_gets(t, &i.server_name) < 0 ||
86 pa_tagstruct_gets(t, &i.server_version) < 0 ||
87 pa_tagstruct_gets(t, &i.user_name) < 0 ||
88 pa_tagstruct_gets(t, &i.host_name) < 0 ||
89 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
90 pa_tagstruct_gets(t, &i.default_sink_name) < 0 ||
91 pa_tagstruct_gets(t, &i.default_source_name) < 0 ||
92 pa_tagstruct_getu32(t, &i.cookie) < 0 ||
93 !pa_tagstruct_eof(t)) {
94
95 pa_context_fail(o->context, PA_ERR_PROTOCOL);
96 goto finish;
97 }
98
99 if (o->callback) {
100 void (*cb)(pa_context *s, const pa_server_info*_i, void *_userdata) = (void (*)(pa_context *s, const pa_server_info*_i, void *_userdata)) o->callback;
101 cb(o->context, p, o->userdata);
102 }
103
104 finish:
105 pa_operation_done(o);
106 pa_operation_unref(o);
107 }
108
109 pa_operation* pa_context_get_server_info(pa_context *c, void (*cb)(pa_context *c, const pa_server_info*i, void *userdata), void *userdata) {
110 return pa_context_send_simple_command(c, PA_COMMAND_GET_SERVER_INFO, context_get_server_info_callback, (pa_operation_callback_t) cb, userdata);
111 }
112
113 /*** Sink Info ***/
114
115 static void context_get_sink_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
116 pa_operation *o = userdata;
117 int eof = 1;
118 assert(pd && o && o->context && o->ref >= 1);
119
120 if (command != PA_COMMAND_REPLY) {
121 if (pa_context_handle_error(o->context, command, t) < 0)
122 goto finish;
123
124 eof = -1;
125 } else {
126
127 while (!pa_tagstruct_eof(t)) {
128 pa_sink_info i;
129
130 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
131 pa_tagstruct_gets(t, &i.name) < 0 ||
132 pa_tagstruct_gets(t, &i.description) < 0 ||
133 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
134 pa_tagstruct_get_channel_map(t, &i.channel_map) < 0 ||
135 pa_tagstruct_getu32(t, &i.owner_module) < 0 ||
136 pa_tagstruct_get_cvolume(t, &i.volume) < 0 ||
137 pa_tagstruct_getu32(t, &i.monitor_source) < 0 ||
138 pa_tagstruct_gets(t, &i.monitor_source_name) < 0 ||
139 pa_tagstruct_get_usec(t, &i.latency) < 0 ||
140 pa_tagstruct_gets(t, &i.driver) < 0) {
141
142 pa_context_fail(o->context, PA_ERR_PROTOCOL);
143 goto finish;
144 }
145
146 if (o->callback) {
147 void (*cb)(pa_context *s, const pa_sink_info*_i, int _eof, void *_userdata) = (void (*)(pa_context *s, const pa_sink_info*_i, int _eof, void *_userdata)) o->callback;
148 cb(o->context, &i, 0, o->userdata);
149 }
150 }
151 }
152
153 if (o->callback) {
154 void (*cb)(pa_context *s, const pa_sink_info*_i, int _eof, void *_userdata) = (void (*)(pa_context *s, const pa_sink_info*_i, int _eof, void *_userdata)) o->callback;
155 cb(o->context, NULL, eof, o->userdata);
156 }
157
158 finish:
159 pa_operation_done(o);
160 pa_operation_unref(o);
161 }
162
163 pa_operation* pa_context_get_sink_info_list(pa_context *c, void (*cb)(pa_context *c, const pa_sink_info *i, int is_last, void *userdata), void *userdata) {
164 return pa_context_send_simple_command(c, PA_COMMAND_GET_SINK_INFO_LIST, context_get_sink_info_callback, (pa_operation_callback_t) cb, userdata);
165 }
166
167 pa_operation* pa_context_get_sink_info_by_index(pa_context *c, uint32_t idx, void (*cb)(pa_context *c, const pa_sink_info *i, int is_last, void *userdata), void *userdata) {
168 pa_tagstruct *t;
169 pa_operation *o;
170 uint32_t tag;
171 assert(c && cb);
172
173 o = pa_operation_new(c, NULL);
174 o->callback = (pa_operation_callback_t) cb;
175 o->userdata = userdata;
176
177 t = pa_tagstruct_new(NULL, 0);
178 pa_tagstruct_putu32(t, PA_COMMAND_GET_SINK_INFO);
179 pa_tagstruct_putu32(t, tag = c->ctag++);
180 pa_tagstruct_putu32(t, idx);
181 pa_tagstruct_puts(t, NULL);
182 pa_pstream_send_tagstruct(c->pstream, t);
183 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_sink_info_callback, o);
184
185 return pa_operation_ref(o);
186 }
187
188 pa_operation* pa_context_get_sink_info_by_name(pa_context *c, const char *name, void (*cb)(pa_context *c, const pa_sink_info *i, int is_last, void *userdata), void *userdata) {
189 pa_tagstruct *t;
190 pa_operation *o;
191 uint32_t tag;
192 assert(c && cb);
193
194 o = pa_operation_new(c, NULL);
195 o->callback = (pa_operation_callback_t) cb;
196 o->userdata = userdata;
197
198 t = pa_tagstruct_new(NULL, 0);
199 pa_tagstruct_putu32(t, PA_COMMAND_GET_SINK_INFO);
200 pa_tagstruct_putu32(t, tag = c->ctag++);
201 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
202 pa_tagstruct_puts(t, name);
203 pa_pstream_send_tagstruct(c->pstream, t);
204 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_sink_info_callback, o);
205
206 return pa_operation_ref(o);
207 }
208
209 /*** Source info ***/
210
211 static void context_get_source_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
212 pa_operation *o = userdata;
213 int eof = 1;
214 assert(pd && o && o->context && o->ref >= 1);
215
216 if (command != PA_COMMAND_REPLY) {
217 if (pa_context_handle_error(o->context, command, t) < 0)
218 goto finish;
219
220 eof = -1;
221 } else {
222
223 while (!pa_tagstruct_eof(t)) {
224 pa_source_info i;
225
226 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
227 pa_tagstruct_gets(t, &i.name) < 0 ||
228 pa_tagstruct_gets(t, &i.description) < 0 ||
229 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
230 pa_tagstruct_get_channel_map(t, &i.channel_map) < 0 ||
231 pa_tagstruct_getu32(t, &i.owner_module) < 0 ||
232 pa_tagstruct_getu32(t, &i.monitor_of_sink) < 0 ||
233 pa_tagstruct_gets(t, &i.monitor_of_sink_name) < 0 ||
234 pa_tagstruct_get_usec(t, &i.latency) < 0 ||
235 pa_tagstruct_gets(t, &i.driver) < 0) {
236
237 pa_context_fail(o->context, PA_ERR_PROTOCOL);
238 goto finish;
239 }
240
241 if (o->callback) {
242 void (*cb)(pa_context *s, const pa_source_info*_i, int _eof, void *_userdata) = (void (*)(pa_context *s, const pa_source_info*_i, int _eof, void *_userdata)) o->callback;
243 cb(o->context, &i, 0, o->userdata);
244 }
245 }
246 }
247
248 if (o->callback) {
249 void (*cb)(pa_context *s, const pa_source_info*_i, int _eof, void *_userdata) = (void (*)(pa_context *s, const pa_source_info*_i, int _eof, void *_userdata)) o->callback;
250 cb(o->context, NULL, eof, o->userdata);
251 }
252
253 finish:
254 pa_operation_done(o);
255 pa_operation_unref(o);
256 }
257
258 pa_operation* pa_context_get_source_info_list(pa_context *c, void (*cb)(pa_context *c, const pa_source_info *i, int is_last, void *userdata), void *userdata) {
259 return pa_context_send_simple_command(c, PA_COMMAND_GET_SOURCE_INFO_LIST, context_get_source_info_callback, (pa_operation_callback_t) cb, userdata);
260 }
261
262 pa_operation* pa_context_get_source_info_by_index(pa_context *c, uint32_t idx, void (*cb)(pa_context *c, const pa_source_info *i, int is_last, void *userdata), void *userdata) {
263 pa_tagstruct *t;
264 pa_operation *o;
265 uint32_t tag;
266 assert(c && cb);
267
268 o = pa_operation_new(c, NULL);
269 o->callback = (pa_operation_callback_t) cb;
270 o->userdata = userdata;
271
272 t = pa_tagstruct_new(NULL, 0);
273 pa_tagstruct_putu32(t, PA_COMMAND_GET_SOURCE_INFO);
274 pa_tagstruct_putu32(t, tag = c->ctag++);
275 pa_tagstruct_putu32(t, idx);
276 pa_tagstruct_puts(t, NULL);
277 pa_pstream_send_tagstruct(c->pstream, t);
278 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_source_info_callback, o);
279
280 return pa_operation_ref(o);
281 }
282
283 pa_operation* pa_context_get_source_info_by_name(pa_context *c, const char *name, void (*cb)(pa_context *c, const pa_source_info *i, int is_last, void *userdata), void *userdata) {
284 pa_tagstruct *t;
285 pa_operation *o;
286 uint32_t tag;
287 assert(c && cb);
288
289 o = pa_operation_new(c, NULL);
290 o->callback = (pa_operation_callback_t) cb;
291 o->userdata = userdata;
292
293 t = pa_tagstruct_new(NULL, 0);
294 pa_tagstruct_putu32(t, PA_COMMAND_GET_SOURCE_INFO);
295 pa_tagstruct_putu32(t, tag = c->ctag++);
296 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
297 pa_tagstruct_puts(t, name);
298 pa_pstream_send_tagstruct(c->pstream, t);
299 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_source_info_callback, o);
300
301 return pa_operation_ref(o);
302 }
303
304 /*** Client info ***/
305
306 static void context_get_client_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
307 pa_operation *o = userdata;
308 int eof = 1;
309 assert(pd && o && o->context && o->ref >= 1);
310
311 if (command != PA_COMMAND_REPLY) {
312 if (pa_context_handle_error(o->context, command, t) < 0)
313 goto finish;
314
315 eof = -1;
316 } else {
317
318 while (!pa_tagstruct_eof(t)) {
319 pa_client_info i;
320
321 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
322 pa_tagstruct_gets(t, &i.name) < 0 ||
323 pa_tagstruct_getu32(t, &i.owner_module) < 0 ||
324 pa_tagstruct_gets(t, &i.driver) < 0 ) {
325 pa_context_fail(o->context, PA_ERR_PROTOCOL);
326 goto finish;
327 }
328
329 if (o->callback) {
330 void (*cb)(pa_context *s, const pa_client_info*_i, int _eof, void *_userdata) = (void (*)(pa_context *s, const pa_client_info*_i, int _eof, void *_userdata)) o->callback;
331 cb(o->context, &i, 0, o->userdata);
332 }
333 }
334 }
335
336 if (o->callback) {
337 void (*cb)(pa_context *s, const pa_client_info*_i, int _eof, void *_userdata) = (void (*)(pa_context *s, const pa_client_info*_i, int _eof, void *_userdata)) o->callback;
338 cb(o->context, NULL, eof, o->userdata);
339 }
340
341 finish:
342 pa_operation_done(o);
343 pa_operation_unref(o);
344 }
345
346 pa_operation* pa_context_get_client_info(pa_context *c, uint32_t idx, void (*cb)(pa_context *c, const pa_client_info*i, int is_last, void *userdata), void *userdata) {
347 pa_tagstruct *t;
348 pa_operation *o;
349 uint32_t tag;
350 assert(c && cb);
351
352 o = pa_operation_new(c, NULL);
353 o->callback = (pa_operation_callback_t) cb;
354 o->userdata = userdata;
355
356 t = pa_tagstruct_new(NULL, 0);
357 pa_tagstruct_putu32(t, PA_COMMAND_GET_CLIENT_INFO);
358 pa_tagstruct_putu32(t, tag = c->ctag++);
359 pa_tagstruct_putu32(t, idx);
360 pa_pstream_send_tagstruct(c->pstream, t);
361 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_client_info_callback, o);
362
363 return pa_operation_ref(o);
364 }
365
366 pa_operation* pa_context_get_client_info_list(pa_context *c, void (*cb)(pa_context *c, const pa_client_info*i, int is_last, void *userdata), void *userdata) {
367 return pa_context_send_simple_command(c, PA_COMMAND_GET_CLIENT_INFO_LIST, context_get_client_info_callback, (pa_operation_callback_t) cb, userdata);
368 }
369
370 /*** Module info ***/
371
372 static void context_get_module_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
373 pa_operation *o = userdata;
374 int eof = 1;
375 assert(pd && o && o->context && o->ref >= 1);
376
377 if (command != PA_COMMAND_REPLY) {
378 if (pa_context_handle_error(o->context, command, t) < 0)
379 goto finish;
380
381 eof = -1;
382 } else {
383
384 while (!pa_tagstruct_eof(t)) {
385 pa_module_info i;
386
387 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
388 pa_tagstruct_gets(t, &i.name) < 0 ||
389 pa_tagstruct_gets(t, &i.argument) < 0 ||
390 pa_tagstruct_getu32(t, &i.n_used) < 0 ||
391 pa_tagstruct_get_boolean(t, &i.auto_unload) < 0) {
392 pa_context_fail(o->context, PA_ERR_PROTOCOL);
393 goto finish;
394 }
395
396 if (o->callback) {
397 void (*cb)(pa_context *s, const pa_module_info*_i, int _eof, void *_userdata) = (void (*)(pa_context *s, const pa_module_info*_i, int _eof, void *_userdata)) o->callback;
398 cb(o->context, &i, 0, o->userdata);
399 }
400 }
401 }
402
403 if (o->callback) {
404 void (*cb)(pa_context *s, const pa_module_info*_i, int _eof, void *_userdata) = (void (*)(pa_context *s, const pa_module_info*_i, int _eof, void *_userdata)) o->callback;
405 cb(o->context, NULL, eof, o->userdata);
406 }
407
408 finish:
409 pa_operation_done(o);
410 pa_operation_unref(o);
411 }
412
413 pa_operation* pa_context_get_module_info(pa_context *c, uint32_t idx, void (*cb)(pa_context *c, const pa_module_info*i, int is_last, void *userdata), void *userdata) {
414 pa_tagstruct *t;
415 pa_operation *o;
416 uint32_t tag;
417 assert(c && cb);
418
419 o = pa_operation_new(c, NULL);
420 o->callback = (pa_operation_callback_t) cb;
421 o->userdata = userdata;
422
423 t = pa_tagstruct_new(NULL, 0);
424 pa_tagstruct_putu32(t, PA_COMMAND_GET_MODULE_INFO);
425 pa_tagstruct_putu32(t, tag = c->ctag++);
426 pa_tagstruct_putu32(t, idx);
427 pa_pstream_send_tagstruct(c->pstream, t);
428 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_module_info_callback, o);
429
430 return pa_operation_ref(o);
431 }
432
433 pa_operation* pa_context_get_module_info_list(pa_context *c, void (*cb)(pa_context *c, const pa_module_info*i, int is_last, void *userdata), void *userdata) {
434 return pa_context_send_simple_command(c, PA_COMMAND_GET_MODULE_INFO_LIST, context_get_module_info_callback, (pa_operation_callback_t) cb, userdata);
435 }
436
437 /*** Sink input info ***/
438
439 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) {
440 pa_operation *o = userdata;
441 int eof = 1;
442 assert(pd && o && o->context && o->ref >= 1);
443
444 if (command != PA_COMMAND_REPLY) {
445 if (pa_context_handle_error(o->context, command, t) < 0)
446 goto finish;
447
448 eof = -1;
449 } else {
450
451 while (!pa_tagstruct_eof(t)) {
452 pa_sink_input_info i;
453
454 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
455 pa_tagstruct_gets(t, &i.name) < 0 ||
456 pa_tagstruct_getu32(t, &i.owner_module) < 0 ||
457 pa_tagstruct_getu32(t, &i.client) < 0 ||
458 pa_tagstruct_getu32(t, &i.sink) < 0 ||
459 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
460 pa_tagstruct_get_channel_map(t, &i.channel_map) < 0 ||
461 pa_tagstruct_get_cvolume(t, &i.volume) < 0 ||
462 pa_tagstruct_get_usec(t, &i.buffer_usec) < 0 ||
463 pa_tagstruct_get_usec(t, &i.sink_usec) < 0 ||
464 pa_tagstruct_gets(t, &i.resample_method) < 0 ||
465 pa_tagstruct_gets(t, &i.driver) < 0) {
466
467 pa_context_fail(o->context, PA_ERR_PROTOCOL);
468 goto finish;
469 }
470
471 if (o->callback) {
472 void (*cb)(pa_context *s, const pa_sink_input_info*_i, int _eof, void *_userdata) = (void (*)(pa_context *s, const pa_sink_input_info*_i, int _eof, void *_userdata)) o->callback;
473 cb(o->context, &i, 0, o->userdata);
474 }
475 }
476 }
477
478 if (o->callback) {
479 void (*cb)(pa_context *s, const pa_sink_input_info*_i, int _eof, void *_userdata) = (void (*)(pa_context *s, const pa_sink_input_info*_i, int _eof, void *_userdata)) o->callback;
480 cb(o->context, NULL, eof, o->userdata);
481 }
482
483 finish:
484 pa_operation_done(o);
485 pa_operation_unref(o);
486 }
487
488 pa_operation* pa_context_get_sink_input_info(pa_context *c, uint32_t idx, void (*cb)(pa_context *c, const pa_sink_input_info*i, int is_last, void *userdata), void *userdata) {
489 pa_tagstruct *t;
490 pa_operation *o;
491 uint32_t tag;
492 assert(c && cb);
493
494 o = pa_operation_new(c, NULL);
495 o->callback = (pa_operation_callback_t) cb;
496 o->userdata = userdata;
497
498 t = pa_tagstruct_new(NULL, 0);
499 pa_tagstruct_putu32(t, PA_COMMAND_GET_SINK_INPUT_INFO);
500 pa_tagstruct_putu32(t, tag = c->ctag++);
501 pa_tagstruct_putu32(t, idx);
502 pa_pstream_send_tagstruct(c->pstream, t);
503 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_sink_input_info_callback, o);
504
505 return pa_operation_ref(o);
506 }
507
508 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) {
509 return pa_context_send_simple_command(c, PA_COMMAND_GET_SINK_INPUT_INFO_LIST, context_get_sink_input_info_callback, (pa_operation_callback_t) cb, userdata);
510 }
511
512 /*** Source output info ***/
513
514 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) {
515 pa_operation *o = userdata;
516 int eof = 1;
517 assert(pd && o && o->context && o->ref >= 1);
518
519 if (command != PA_COMMAND_REPLY) {
520 if (pa_context_handle_error(o->context, command, t) < 0)
521 goto finish;
522
523 eof = -1;
524 } else {
525
526 while (!pa_tagstruct_eof(t)) {
527 pa_source_output_info i;
528
529 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
530 pa_tagstruct_gets(t, &i.name) < 0 ||
531 pa_tagstruct_getu32(t, &i.owner_module) < 0 ||
532 pa_tagstruct_getu32(t, &i.client) < 0 ||
533 pa_tagstruct_getu32(t, &i.source) < 0 ||
534 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
535 pa_tagstruct_get_channel_map(t, &i.channel_map) < 0 ||
536 pa_tagstruct_get_usec(t, &i.buffer_usec) < 0 ||
537 pa_tagstruct_get_usec(t, &i.source_usec) < 0 ||
538 pa_tagstruct_gets(t, &i.resample_method) < 0 ||
539 pa_tagstruct_gets(t, &i.driver) < 0) {
540
541 pa_context_fail(o->context, PA_ERR_PROTOCOL);
542 goto finish;
543 }
544
545 if (o->callback) {
546 void (*cb)(pa_context *s, const pa_source_output_info*_i, int _eof, void *_userdata) = (void (*)(pa_context *s, const pa_source_output_info*_i, int _eof, void *_userdata)) o->callback;
547 cb(o->context, &i, 0, o->userdata);
548 }
549 }
550 }
551
552 if (o->callback) {
553 void (*cb)(pa_context *s, const pa_source_output_info*_i, int _eof, void *_userdata) = (void (*)(pa_context *s, const pa_source_output_info*_i, int _eof, void *_userdata))o->callback;
554 cb(o->context, NULL, eof, o->userdata);
555 }
556
557 finish:
558 pa_operation_done(o);
559 pa_operation_unref(o);
560 }
561
562 pa_operation* pa_context_get_source_output_info(pa_context *c, uint32_t idx, void (*cb)(pa_context *c, const pa_source_output_info*i, int is_last, void *userdata), void *userdata) {
563 pa_tagstruct *t;
564 pa_operation *o;
565 uint32_t tag;
566 assert(c && cb);
567
568 o = pa_operation_new(c, NULL);
569 o->callback = (pa_operation_callback_t) cb;
570 o->userdata = userdata;
571
572 t = pa_tagstruct_new(NULL, 0);
573 pa_tagstruct_putu32(t, PA_COMMAND_GET_SOURCE_OUTPUT_INFO);
574 pa_tagstruct_putu32(t, tag = c->ctag++);
575 pa_tagstruct_putu32(t, idx);
576 pa_pstream_send_tagstruct(c->pstream, t);
577 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_source_output_info_callback, o);
578
579 return pa_operation_ref(o);
580 }
581
582 pa_operation* pa_context_get_source_output_info_list(pa_context *c, void (*cb)(pa_context *c, const pa_source_output_info*i, int is_last, void *userdata), void *userdata) {
583 return pa_context_send_simple_command(c, PA_COMMAND_GET_SOURCE_OUTPUT_INFO_LIST, context_get_source_output_info_callback, (pa_operation_callback_t) cb, userdata);
584 }
585
586 /*** Volume manipulation ***/
587
588 pa_operation* pa_context_set_sink_volume_by_index(pa_context *c, uint32_t idx, const pa_cvolume *volume, void (*cb)(pa_context *c, int success, void *userdata), void *userdata) {
589 pa_operation *o;
590 pa_tagstruct *t;
591 uint32_t tag;
592 assert(c && idx != PA_INVALID_INDEX);
593
594 o = pa_operation_new(c, NULL);
595 o->callback = (pa_operation_callback_t) cb;
596 o->userdata = userdata;
597
598 t = pa_tagstruct_new(NULL, 0);
599 pa_tagstruct_putu32(t, PA_COMMAND_SET_SINK_VOLUME);
600 pa_tagstruct_putu32(t, tag = c->ctag++);
601 pa_tagstruct_putu32(t, idx);
602 pa_tagstruct_puts(t, NULL);
603 pa_tagstruct_put_cvolume(t, volume);
604 pa_pstream_send_tagstruct(c->pstream, t);
605 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, o);
606
607 return pa_operation_ref(o);
608 }
609
610 pa_operation* pa_context_set_sink_volume_by_name(pa_context *c, const char *name, const pa_cvolume *volume, void (*cb)(pa_context *c, int success, void *userdata), void *userdata) {
611 pa_operation *o;
612 pa_tagstruct *t;
613 uint32_t tag;
614 assert(c && name);
615
616 o = pa_operation_new(c, NULL);
617 o->callback = (pa_operation_callback_t) cb;
618 o->userdata = userdata;
619
620 t = pa_tagstruct_new(NULL, 0);
621 pa_tagstruct_putu32(t, PA_COMMAND_SET_SINK_VOLUME);
622 pa_tagstruct_putu32(t, tag = c->ctag++);
623 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
624 pa_tagstruct_puts(t, name);
625 pa_tagstruct_put_cvolume(t, volume);
626 pa_pstream_send_tagstruct(c->pstream, t);
627 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, o);
628
629 return pa_operation_ref(o);
630 }
631
632 pa_operation* pa_context_set_sink_input_volume(pa_context *c, uint32_t idx, const pa_cvolume *volume, void (*cb)(pa_context *c, int success, void *userdata), void *userdata) {
633 pa_operation *o;
634 pa_tagstruct *t;
635 uint32_t tag;
636 assert(c && idx != PA_INVALID_INDEX);
637
638 o = pa_operation_new(c, NULL);
639 o->callback = (pa_operation_callback_t) cb;
640 o->userdata = userdata;
641
642 t = pa_tagstruct_new(NULL, 0);
643 pa_tagstruct_putu32(t, PA_COMMAND_SET_SINK_INPUT_VOLUME);
644 pa_tagstruct_putu32(t, tag = c->ctag++);
645 pa_tagstruct_putu32(t, idx);
646 pa_tagstruct_put_cvolume(t, volume);
647 pa_pstream_send_tagstruct(c->pstream, t);
648 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, o);
649
650 return pa_operation_ref(o);
651 }
652
653 /** Sample Cache **/
654
655 static void context_get_sample_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
656 pa_operation *o = userdata;
657 int eof = 1;
658 assert(pd && o && o->context && o->ref >= 1);
659
660 if (command != PA_COMMAND_REPLY) {
661 if (pa_context_handle_error(o->context, command, t) < 0)
662 goto finish;
663
664 eof = -1;
665 } else {
666
667 while (!pa_tagstruct_eof(t)) {
668 pa_sample_info i;
669
670 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
671 pa_tagstruct_gets(t, &i.name) < 0 ||
672 pa_tagstruct_get_cvolume(t, &i.volume) < 0 ||
673 pa_tagstruct_get_usec(t, &i.duration) < 0 ||
674 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
675 pa_tagstruct_get_channel_map(t, &i.channel_map) < 0 ||
676 pa_tagstruct_getu32(t, &i.bytes) < 0 ||
677 pa_tagstruct_get_boolean(t, &i.lazy) < 0 ||
678 pa_tagstruct_gets(t, &i.filename) < 0) {
679
680 pa_context_fail(o->context, PA_ERR_PROTOCOL);
681 goto finish;
682 }
683
684 if (o->callback) {
685 void (*cb)(pa_context *s, const pa_sample_info*_i, int _eof, void *_userdata) = (void (*)(pa_context *s, const pa_sample_info*_i, int _eof, void *_userdata)) o->callback;
686 cb(o->context, &i, 0, o->userdata);
687 }
688 }
689 }
690
691 if (o->callback) {
692 void (*cb)(pa_context *s, const pa_sample_info*_i, int _eof, void *_userdata) = (void (*)(pa_context *s, const pa_sample_info*_i, int _eof, void *_userdata)) o->callback;
693 cb(o->context, NULL, eof, o->userdata);
694 }
695
696 finish:
697 pa_operation_done(o);
698 pa_operation_unref(o);
699 }
700
701 pa_operation* pa_context_get_sample_info_by_name(pa_context *c, const char *name, void (*cb)(pa_context *c, const pa_sample_info *i, int is_last, void *userdata), void *userdata) {
702 pa_tagstruct *t;
703 pa_operation *o;
704 uint32_t tag;
705 assert(c && cb && name);
706
707 o = pa_operation_new(c, NULL);
708 o->callback = (pa_operation_callback_t) cb;
709 o->userdata = userdata;
710
711 t = pa_tagstruct_new(NULL, 0);
712 pa_tagstruct_putu32(t, PA_COMMAND_GET_SAMPLE_INFO);
713 pa_tagstruct_putu32(t, tag = c->ctag++);
714 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
715 pa_tagstruct_puts(t, name);
716 pa_pstream_send_tagstruct(c->pstream, t);
717 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_sample_info_callback, o);
718
719 return pa_operation_ref(o);
720 }
721
722 pa_operation* pa_context_get_sample_info_by_index(pa_context *c, uint32_t idx, void (*cb)(pa_context *c, const pa_sample_info *i, int is_last, void *userdata), void *userdata) {
723 pa_tagstruct *t;
724 pa_operation *o;
725 uint32_t tag;
726 assert(c && cb);
727
728 o = pa_operation_new(c, NULL);
729 o->callback = (pa_operation_callback_t) cb;
730 o->userdata = userdata;
731
732 t = pa_tagstruct_new(NULL, 0);
733 pa_tagstruct_putu32(t, PA_COMMAND_GET_SAMPLE_INFO);
734 pa_tagstruct_putu32(t, tag = c->ctag++);
735 pa_tagstruct_putu32(t, idx);
736 pa_tagstruct_puts(t, NULL);
737 pa_pstream_send_tagstruct(c->pstream, t);
738 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_sample_info_callback, o);
739
740 return pa_operation_ref(o);
741 }
742
743 pa_operation* pa_context_get_sample_info_list(pa_context *c, void (*cb)(pa_context *c, const pa_sample_info *i, int is_last, void *userdata), void *userdata) {
744 return pa_context_send_simple_command(c, PA_COMMAND_GET_SAMPLE_INFO_LIST, context_get_sample_info_callback, (pa_operation_callback_t) cb, userdata);
745 }
746
747 static pa_operation* command_kill(pa_context *c, uint32_t command, uint32_t idx, void (*cb)(pa_context *c, int success, void *userdata), void *userdata) {
748 pa_operation *o;
749 pa_tagstruct *t;
750 uint32_t tag;
751 assert(c && idx != PA_INVALID_INDEX);
752
753 o = pa_operation_new(c, NULL);
754 o->callback = (pa_operation_callback_t) cb;
755 o->userdata = userdata;
756
757 t = pa_tagstruct_new(NULL, 0);
758 pa_tagstruct_putu32(t, command);
759 pa_tagstruct_putu32(t, tag = c->ctag++);
760 pa_tagstruct_putu32(t, idx);
761 pa_pstream_send_tagstruct(c->pstream, t);
762 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, o);
763
764 return pa_operation_ref(o);
765 }
766
767 pa_operation* pa_context_kill_client(pa_context *c, uint32_t idx, void (*cb)(pa_context *c, int success, void *userdata), void *userdata) {
768 return command_kill(c, PA_COMMAND_KILL_CLIENT, idx, cb, userdata);
769 }
770
771 pa_operation* pa_context_kill_sink_input(pa_context *c, uint32_t idx, void (*cb)(pa_context *c, int success, void *userdata), void *userdata) {
772 return command_kill(c, PA_COMMAND_KILL_SINK_INPUT, idx, cb, userdata);
773 }
774
775 pa_operation* pa_context_kill_source_output(pa_context *c, uint32_t idx, void (*cb)(pa_context *c, int success, void *userdata), void *userdata) {
776 return command_kill(c, PA_COMMAND_KILL_SOURCE_OUTPUT, idx, cb, userdata);
777 }
778
779 static void load_module_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
780 pa_operation *o = userdata;
781 uint32_t idx = -1;
782 assert(pd && o && o->context && o->ref >= 1);
783
784 if (command != PA_COMMAND_REPLY) {
785 if (pa_context_handle_error(o->context, command, t) < 0)
786 goto finish;
787
788 } else if (pa_tagstruct_getu32(t, &idx) < 0 ||
789 !pa_tagstruct_eof(t)) {
790 pa_context_fail(o->context, PA_ERR_PROTOCOL);
791 goto finish;
792 }
793
794 if (o->callback) {
795 void (*cb)(pa_context *c, uint32_t _idx, void *_userdata) = (void (*)(pa_context *c, uint32_t _idx, void *_userdata)) o->callback;
796 cb(o->context, idx, o->userdata);
797 }
798
799 finish:
800 pa_operation_done(o);
801 pa_operation_unref(o);
802 }
803
804 pa_operation* pa_context_load_module(pa_context *c, const char*name, const char *argument, void (*cb)(pa_context *c, uint32_t idx, void *userdata), void *userdata) {
805 pa_operation *o;
806 pa_tagstruct *t;
807 uint32_t tag;
808 assert(c && name && argument);
809
810 o = pa_operation_new(c, NULL);
811 o->callback = (pa_operation_callback_t) cb;
812 o->userdata = userdata;
813
814 t = pa_tagstruct_new(NULL, 0);
815 pa_tagstruct_putu32(t, PA_COMMAND_LOAD_MODULE);
816 pa_tagstruct_putu32(t, tag = c->ctag++);
817 pa_tagstruct_puts(t, name);
818 pa_tagstruct_puts(t, argument);
819 pa_pstream_send_tagstruct(c->pstream, t);
820 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, load_module_callback, o);
821
822 return pa_operation_ref(o);
823 }
824
825 pa_operation* pa_context_unload_module(pa_context *c, uint32_t idx, void (*cb)(pa_context *c, int success, void *userdata), void *userdata) {
826 return command_kill(c, PA_COMMAND_UNLOAD_MODULE, idx, cb, userdata);
827 }
828
829 /*** Autoload stuff ***/
830
831 static void context_get_autoload_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
832 pa_operation *o = userdata;
833 int eof = 1;
834 assert(pd && o && o->context && o->ref >= 1);
835
836 if (command != PA_COMMAND_REPLY) {
837 if (pa_context_handle_error(o->context, command, t) < 0)
838 goto finish;
839
840 eof = -1;
841 } else {
842
843 while (!pa_tagstruct_eof(t)) {
844 pa_autoload_info i;
845
846 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
847 pa_tagstruct_gets(t, &i.name) < 0 ||
848 pa_tagstruct_getu32(t, &i.type) < 0 ||
849 pa_tagstruct_gets(t, &i.module) < 0 ||
850 pa_tagstruct_gets(t, &i.argument) < 0) {
851 pa_context_fail(o->context, PA_ERR_PROTOCOL);
852 goto finish;
853 }
854
855 if (o->callback) {
856 void (*cb)(pa_context *s, const pa_autoload_info*_i, int _eof, void *_userdata) = (void (*)(pa_context *s, const pa_autoload_info*_i, int _eof, void *_userdata)) o->callback;
857 cb(o->context, &i, 0, o->userdata);
858 }
859 }
860 }
861
862 if (o->callback) {
863 void (*cb)(pa_context *s, const pa_autoload_info*_i, int _eof, void *_userdata) = (void (*)(pa_context *s, const pa_autoload_info*_i, int _eof, void *_userdata)) o->callback;
864 cb(o->context, NULL, eof, o->userdata);
865 }
866
867 finish:
868 pa_operation_done(o);
869 pa_operation_unref(o);
870 }
871
872 pa_operation* pa_context_get_autoload_info_by_name(pa_context *c, const char *name, pa_autoload_type_t type, void (*cb)(pa_context *c, const pa_autoload_info *i, int is_last, void *userdata), void *userdata) {
873 pa_tagstruct *t;
874 pa_operation *o;
875 uint32_t tag;
876 assert(c && cb && name);
877
878 o = pa_operation_new(c, NULL);
879 o->callback = (pa_operation_callback_t) cb;
880 o->userdata = userdata;
881
882 t = pa_tagstruct_new(NULL, 0);
883 pa_tagstruct_putu32(t, PA_COMMAND_GET_AUTOLOAD_INFO);
884 pa_tagstruct_putu32(t, tag = c->ctag++);
885 pa_tagstruct_puts(t, name);
886 pa_tagstruct_putu32(t, type);
887 pa_pstream_send_tagstruct(c->pstream, t);
888 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_autoload_info_callback, o);
889
890 return pa_operation_ref(o);
891 }
892
893 pa_operation* pa_context_get_autoload_info_by_index(pa_context *c, uint32_t idx, void (*cb)(pa_context *c, const pa_autoload_info *i, int is_last, void *userdata), void *userdata) {
894 pa_tagstruct *t;
895 pa_operation *o;
896 uint32_t tag;
897 assert(c && cb && idx != PA_INVALID_INDEX);
898
899 o = pa_operation_new(c, NULL);
900 o->callback = (pa_operation_callback_t) cb;
901 o->userdata = userdata;
902
903 t = pa_tagstruct_new(NULL, 0);
904 pa_tagstruct_putu32(t, PA_COMMAND_GET_AUTOLOAD_INFO);
905 pa_tagstruct_putu32(t, tag = c->ctag++);
906 pa_tagstruct_putu32(t, idx);
907 pa_pstream_send_tagstruct(c->pstream, t);
908 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_autoload_info_callback, o);
909
910 return pa_operation_ref(o);
911 }
912
913 pa_operation* pa_context_get_autoload_info_list(pa_context *c, void (*cb)(pa_context *c, const pa_autoload_info *i, int is_last, void *userdata), void *userdata) {
914 return pa_context_send_simple_command(c, PA_COMMAND_GET_AUTOLOAD_INFO_LIST, context_get_autoload_info_callback, (pa_operation_callback_t) cb, userdata);
915 }
916
917 static void context_add_autoload_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
918 pa_operation *o = userdata;
919 uint32_t idx;
920 assert(pd && o && o->context && o->ref >= 1);
921
922 if (command != PA_COMMAND_REPLY) {
923 if (pa_context_handle_error(o->context, command, t) < 0)
924 goto finish;
925
926 idx = PA_INVALID_INDEX;
927 } else if (pa_tagstruct_getu32(t, &idx) ||
928 !pa_tagstruct_eof(t)) {
929 pa_context_fail(o->context, PA_ERR_PROTOCOL);
930 goto finish;
931 }
932
933 if (o->callback) {
934 void (*cb)(pa_context *s, uint32_t _idx, void *_userdata) = (void (*)(pa_context *s, uint32_t _idx, void *_userdata)) o->callback;
935 cb(o->context, idx, o->userdata);
936 }
937
938
939 finish:
940 pa_operation_done(o);
941 pa_operation_unref(o);
942 }
943
944 pa_operation* pa_context_add_autoload(pa_context *c, const char *name, pa_autoload_type_t type, const char *module, const char*argument, void (*cb)(pa_context *c, int success, void *userdata), void* userdata) {
945 pa_operation *o;
946 pa_tagstruct *t;
947 uint32_t tag;
948 assert(c && name && module && argument);
949
950 o = pa_operation_new(c, NULL);
951 o->callback = (pa_operation_callback_t) cb;
952 o->userdata = userdata;
953
954 t = pa_tagstruct_new(NULL, 0);
955 pa_tagstruct_putu32(t, PA_COMMAND_ADD_AUTOLOAD);
956 pa_tagstruct_putu32(t, tag = c->ctag++);
957 pa_tagstruct_puts(t, name);
958 pa_tagstruct_putu32(t, type);
959 pa_tagstruct_puts(t, module);
960 pa_tagstruct_puts(t, argument);
961 pa_pstream_send_tagstruct(c->pstream, t);
962 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_add_autoload_callback, o);
963
964 return pa_operation_ref(o);
965 }
966
967 pa_operation* pa_context_remove_autoload_by_name(pa_context *c, const char *name, pa_autoload_type_t type, void (*cb)(pa_context *c, int success, void *userdata), void* userdata) {
968 pa_operation *o;
969 pa_tagstruct *t;
970 uint32_t tag;
971 assert(c && name);
972
973 o = pa_operation_new(c, NULL);
974 o->callback = (pa_operation_callback_t) cb;
975 o->userdata = userdata;
976
977 t = pa_tagstruct_new(NULL, 0);
978 pa_tagstruct_putu32(t, PA_COMMAND_REMOVE_AUTOLOAD);
979 pa_tagstruct_putu32(t, tag = c->ctag++);
980 pa_tagstruct_puts(t, name);
981 pa_tagstruct_putu32(t, type);
982 pa_pstream_send_tagstruct(c->pstream, t);
983 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, o);
984
985 return pa_operation_ref(o);
986 }
987
988 pa_operation* pa_context_remove_autoload_by_index(pa_context *c, uint32_t idx, void (*cb)(pa_context *c, int success, void *userdata), void* userdata) {
989 pa_operation *o;
990 pa_tagstruct *t;
991 uint32_t tag;
992 assert(c && idx != PA_INVALID_INDEX);
993
994 o = pa_operation_new(c, NULL);
995 o->callback = (pa_operation_callback_t) cb;
996 o->userdata = userdata;
997
998 t = pa_tagstruct_new(NULL, 0);
999 pa_tagstruct_putu32(t, PA_COMMAND_REMOVE_AUTOLOAD);
1000 pa_tagstruct_putu32(t, tag = c->ctag++);
1001 pa_tagstruct_putu32(t, idx);
1002 pa_pstream_send_tagstruct(c->pstream, t);
1003 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, o);
1004
1005 return pa_operation_ref(o);
1006 }