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