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