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