]> code.delx.au - pulseaudio/blob - polyp/polyplib-introspect.c
move sample cache to namereg
[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_eof(t)) {
50 pa_context_fail(o->context, PA_ERROR_PROTOCOL);
51 goto finish;
52 }
53
54 if (o->callback) {
55 void (*cb)(struct pa_context *s, const struct pa_stat_info*i, void *userdata) = o->callback;
56 cb(o->context, p, o->userdata);
57 }
58
59 finish:
60 pa_operation_done(o);
61 pa_operation_unref(o);
62 }
63
64 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) {
65 return pa_context_send_simple_command(c, PA_COMMAND_STAT, context_stat_callback, cb, userdata);
66 }
67
68 /*** Server Info ***/
69
70 static void context_get_server_info_callback(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata) {
71 struct pa_operation *o = userdata;
72 struct pa_server_info i, *p = &i;
73 assert(pd && o && o->context && o->ref >= 1);
74
75 if (command != PA_COMMAND_REPLY) {
76 if (pa_context_handle_error(o->context, command, t) < 0)
77 goto finish;
78
79 p = NULL;
80 } else if (pa_tagstruct_gets(t, &i.server_name) < 0 ||
81 pa_tagstruct_gets(t, &i.server_version) < 0 ||
82 pa_tagstruct_gets(t, &i.user_name) < 0 ||
83 pa_tagstruct_gets(t, &i.host_name) < 0 ||
84 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
85 !pa_tagstruct_eof(t)) {
86 pa_context_fail(o->context, PA_ERROR_PROTOCOL);
87 goto finish;
88 }
89
90 if (o->callback) {
91 void (*cb)(struct pa_context *s, const struct pa_server_info*i, void *userdata) = o->callback;
92 cb(o->context, p, o->userdata);
93 }
94
95 finish:
96 pa_operation_done(o);
97 pa_operation_unref(o);
98 }
99
100 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) {
101 return pa_context_send_simple_command(c, PA_COMMAND_GET_SERVER_INFO, context_get_server_info_callback, cb, userdata);
102 }
103
104 /*** Sink Info ***/
105
106 static void context_get_sink_info_callback(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata) {
107 struct pa_operation *o = userdata;
108 int eof = 1;
109 assert(pd && o && o->context && o->ref >= 1);
110
111 if (command != PA_COMMAND_REPLY) {
112 if (pa_context_handle_error(o->context, command, t) < 0)
113 goto finish;
114
115 eof = -1;
116 } else {
117
118 while (!pa_tagstruct_eof(t)) {
119 struct pa_sink_info i;
120
121 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
122 pa_tagstruct_gets(t, &i.name) < 0 ||
123 pa_tagstruct_gets(t, &i.description) < 0 ||
124 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
125 pa_tagstruct_getu32(t, &i.owner_module) < 0 ||
126 pa_tagstruct_getu32(t, &i.volume) < 0 ||
127 pa_tagstruct_getu32(t, &i.monitor_source) < 0 ||
128 pa_tagstruct_gets(t, &i.monitor_source_name) < 0 ||
129 pa_tagstruct_getu32(t, &i.latency) < 0) {
130 pa_context_fail(o->context, PA_ERROR_PROTOCOL);
131 goto finish;
132 }
133
134 if (o->callback) {
135 void (*cb)(struct pa_context *s, const struct pa_sink_info*i, int eof, void *userdata) = o->callback;
136 cb(o->context, &i, 0, o->userdata);
137 }
138 }
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, NULL, eof, o->userdata);
144 }
145
146 finish:
147 pa_operation_done(o);
148 pa_operation_unref(o);
149 }
150
151 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) {
152 return pa_context_send_simple_command(c, PA_COMMAND_GET_SINK_INFO_LIST, context_get_sink_info_callback, cb, userdata);
153 }
154
155 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) {
156 struct pa_tagstruct *t;
157 struct pa_operation *o;
158 uint32_t tag;
159 assert(c && cb);
160
161 o = pa_operation_new(c, NULL);
162 o->callback = cb;
163 o->userdata = userdata;
164
165 t = pa_tagstruct_new(NULL, 0);
166 pa_tagstruct_putu32(t, PA_COMMAND_GET_SINK_INFO);
167 pa_tagstruct_putu32(t, tag = c->ctag++);
168 pa_tagstruct_putu32(t, index);
169 pa_tagstruct_puts(t, "");
170 pa_pstream_send_tagstruct(c->pstream, t);
171 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_sink_info_callback, o);
172
173 return pa_operation_ref(o);
174 }
175
176 /*** Source info ***/
177
178 static void context_get_source_info_callback(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata) {
179 struct pa_operation *o = userdata;
180 int eof = 1;
181 assert(pd && o && o->context && o->ref >= 1);
182
183 if (command != PA_COMMAND_REPLY) {
184 if (pa_context_handle_error(o->context, command, t) < 0)
185 goto finish;
186
187 eof = -1;
188 } else {
189
190 while (!pa_tagstruct_eof(t)) {
191 struct pa_source_info i;
192
193 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
194 pa_tagstruct_gets(t, &i.name) < 0 ||
195 pa_tagstruct_gets(t, &i.description) < 0 ||
196 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
197 pa_tagstruct_getu32(t, &i.owner_module) < 0 ||
198 pa_tagstruct_getu32(t, &i.monitor_of_sink) < 0 ||
199 pa_tagstruct_gets(t, &i.monitor_of_sink_name) < 0) {
200 pa_context_fail(o->context, PA_ERROR_PROTOCOL);
201 goto finish;
202 }
203
204 if (o->callback) {
205 void (*cb)(struct pa_context *s, const struct pa_source_info*i, int eof, void *userdata) = o->callback;
206 cb(o->context, &i, 0, o->userdata);
207 }
208 }
209 }
210
211 if (o->callback) {
212 void (*cb)(struct pa_context *s, const struct pa_source_info*i, int eof, void *userdata) = o->callback;
213 cb(o->context, NULL, eof, o->userdata);
214 }
215
216 finish:
217 pa_operation_done(o);
218 pa_operation_unref(o);
219 }
220
221 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) {
222 return pa_context_send_simple_command(c, PA_COMMAND_GET_SOURCE_INFO_LIST, context_get_source_info_callback, cb, userdata);
223 }
224
225 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) {
226 struct pa_tagstruct *t;
227 struct pa_operation *o;
228 uint32_t tag;
229 assert(c && cb);
230
231 o = pa_operation_new(c, NULL);
232 o->callback = cb;
233 o->userdata = userdata;
234
235 t = pa_tagstruct_new(NULL, 0);
236 pa_tagstruct_putu32(t, PA_COMMAND_GET_SOURCE_INFO);
237 pa_tagstruct_putu32(t, tag = c->ctag++);
238 pa_tagstruct_putu32(t, index);
239 pa_tagstruct_puts(t, "");
240 pa_pstream_send_tagstruct(c->pstream, t);
241 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_source_info_callback, o);
242
243 return pa_operation_ref(o);
244 }
245
246 /*** Client info ***/
247
248 static void context_get_client_info_callback(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata) {
249 struct pa_operation *o = userdata;
250 int eof = 1;
251 assert(pd && o && o->context && o->ref >= 1);
252
253 if (command != PA_COMMAND_REPLY) {
254 if (pa_context_handle_error(o->context, command, t) < 0)
255 goto finish;
256
257 eof = -1;
258 } else {
259
260 while (!pa_tagstruct_eof(t)) {
261 struct pa_client_info i;
262
263 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
264 pa_tagstruct_gets(t, &i.name) < 0 ||
265 pa_tagstruct_gets(t, &i.protocol_name) < 0 ||
266 pa_tagstruct_getu32(t, &i.owner_module) < 0) {
267 pa_context_fail(o->context, PA_ERROR_PROTOCOL);
268 goto finish;
269 }
270
271 if (o->callback) {
272 void (*cb)(struct pa_context *s, const struct pa_client_info*i, int eof, void *userdata) = o->callback;
273 cb(o->context, &i, 0, o->userdata);
274 }
275 }
276 }
277
278 if (o->callback) {
279 void (*cb)(struct pa_context *s, const struct pa_client_info*i, int eof, void *userdata) = o->callback;
280 cb(o->context, NULL, eof, o->userdata);
281 }
282
283 finish:
284 pa_operation_done(o);
285 pa_operation_unref(o);
286 }
287
288 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) {
289 struct pa_tagstruct *t;
290 struct pa_operation *o;
291 uint32_t tag;
292 assert(c && cb);
293
294 o = pa_operation_new(c, NULL);
295 o->callback = cb;
296 o->userdata = userdata;
297
298 t = pa_tagstruct_new(NULL, 0);
299 pa_tagstruct_putu32(t, PA_COMMAND_GET_CLIENT_INFO);
300 pa_tagstruct_putu32(t, tag = c->ctag++);
301 pa_tagstruct_putu32(t, index);
302 pa_pstream_send_tagstruct(c->pstream, t);
303 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_client_info_callback, o);
304
305 return pa_operation_ref(o);
306 }
307
308 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) {
309 return pa_context_send_simple_command(c, PA_COMMAND_GET_CLIENT_INFO_LIST, context_get_client_info_callback, cb, userdata);
310 }
311
312 /*** Module info ***/
313
314 static void context_get_module_info_callback(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata) {
315 struct pa_operation *o = userdata;
316 int eof = 1;
317 assert(pd && o && o->context && o->ref >= 1);
318
319 if (command != PA_COMMAND_REPLY) {
320 if (pa_context_handle_error(o->context, command, t) < 0)
321 goto finish;
322
323 eof = -1;
324 } else {
325
326 while (!pa_tagstruct_eof(t)) {
327 struct pa_module_info i;
328
329 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
330 pa_tagstruct_gets(t, &i.name) < 0 ||
331 pa_tagstruct_gets(t, &i.argument) < 0 ||
332 pa_tagstruct_getu32(t, &i.n_used) < 0 ||
333 pa_tagstruct_getu32(t, &i.auto_unload) < 0) {
334 pa_context_fail(o->context, PA_ERROR_PROTOCOL);
335 goto finish;
336 }
337
338 if (o->callback) {
339 void (*cb)(struct pa_context *s, const struct pa_module_info*i, int eof, void *userdata) = o->callback;
340 cb(o->context, &i, 0, o->userdata);
341 }
342 }
343 }
344
345 if (o->callback) {
346 void (*cb)(struct pa_context *s, const struct pa_module_info*i, int eof, void *userdata) = o->callback;
347 cb(o->context, NULL, eof, o->userdata);
348 }
349
350 finish:
351 pa_operation_done(o);
352 pa_operation_unref(o);
353 }
354
355 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) {
356 struct pa_tagstruct *t;
357 struct pa_operation *o;
358 uint32_t tag;
359 assert(c && cb);
360
361 o = pa_operation_new(c, NULL);
362 o->callback = cb;
363 o->userdata = userdata;
364
365 t = pa_tagstruct_new(NULL, 0);
366 pa_tagstruct_putu32(t, PA_COMMAND_GET_MODULE_INFO);
367 pa_tagstruct_putu32(t, tag = c->ctag++);
368 pa_tagstruct_putu32(t, index);
369 pa_pstream_send_tagstruct(c->pstream, t);
370 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_module_info_callback, o);
371
372 return pa_operation_ref(o);
373 }
374
375 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) {
376 return pa_context_send_simple_command(c, PA_COMMAND_GET_MODULE_INFO_LIST, context_get_module_info_callback, cb, userdata);
377 }
378
379 /*** Sink input info ***/
380
381 static void context_get_sink_input_info_callback(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata) {
382 struct pa_operation *o = userdata;
383 int eof = 1;
384 assert(pd && o && o->context && o->ref >= 1);
385
386 if (command != PA_COMMAND_REPLY) {
387 if (pa_context_handle_error(o->context, command, t) < 0)
388 goto finish;
389
390 eof = -1;
391 } else {
392
393 while (!pa_tagstruct_eof(t)) {
394 struct pa_sink_input_info i;
395
396 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
397 pa_tagstruct_gets(t, &i.name) < 0 ||
398 pa_tagstruct_getu32(t, &i.owner_module) < 0 ||
399 pa_tagstruct_getu32(t, &i.client) < 0 ||
400 pa_tagstruct_getu32(t, &i.sink) < 0 ||
401 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
402 pa_tagstruct_getu32(t, &i.volume) < 0 ||
403 pa_tagstruct_getu32(t, &i.latency) < 0) {
404 pa_context_fail(o->context, PA_ERROR_PROTOCOL);
405 goto finish;
406 }
407
408 if (o->callback) {
409 void (*cb)(struct pa_context *s, const struct pa_sink_input_info*i, int eof, void *userdata) = o->callback;
410 cb(o->context, &i, 0, o->userdata);
411 }
412 }
413 }
414
415 if (o->callback) {
416 void (*cb)(struct pa_context *s, const struct pa_sink_input_info*i, int eof, void *userdata) = o->callback;
417 cb(o->context, NULL, eof, o->userdata);
418 }
419
420 finish:
421 pa_operation_done(o);
422 pa_operation_unref(o);
423 }
424
425 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) {
426 struct pa_tagstruct *t;
427 struct pa_operation *o;
428 uint32_t tag;
429 assert(c && cb);
430
431 o = pa_operation_new(c, NULL);
432 o->callback = cb;
433 o->userdata = userdata;
434
435 t = pa_tagstruct_new(NULL, 0);
436 pa_tagstruct_putu32(t, PA_COMMAND_GET_SINK_INPUT_INFO);
437 pa_tagstruct_putu32(t, tag = c->ctag++);
438 pa_tagstruct_putu32(t, index);
439 pa_pstream_send_tagstruct(c->pstream, t);
440 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_sink_input_info_callback, o);
441
442 return pa_operation_ref(o);
443 }
444
445 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) {
446 return pa_context_send_simple_command(c, PA_COMMAND_GET_SINK_INPUT_INFO_LIST, context_get_sink_input_info_callback, cb, userdata);
447 }
448
449 /*** Source output info ***/
450
451 static void context_get_source_output_info_callback(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata) {
452 struct pa_operation *o = userdata;
453 int eof = 1;
454 assert(pd && o && o->context && o->ref >= 1);
455
456 if (command != PA_COMMAND_REPLY) {
457 if (pa_context_handle_error(o->context, command, t) < 0)
458 goto finish;
459
460 eof = -1;
461 } else {
462
463 while (!pa_tagstruct_eof(t)) {
464 struct pa_source_output_info i;
465
466 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
467 pa_tagstruct_gets(t, &i.name) < 0 ||
468 pa_tagstruct_getu32(t, &i.owner_module) < 0 ||
469 pa_tagstruct_getu32(t, &i.client) < 0 ||
470 pa_tagstruct_getu32(t, &i.source) < 0 ||
471 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0) {
472 pa_context_fail(o->context, PA_ERROR_PROTOCOL);
473 goto finish;
474 }
475
476 if (o->callback) {
477 void (*cb)(struct pa_context *s, const struct pa_source_output_info*i, int eof, void *userdata) = o->callback;
478 cb(o->context, &i, 0, o->userdata);
479 }
480 }
481 }
482
483 if (o->callback) {
484 void (*cb)(struct pa_context *s, const struct pa_source_output_info*i, int eof, void *userdata) = o->callback;
485 cb(o->context, NULL, eof, o->userdata);
486 }
487
488 finish:
489 pa_operation_done(o);
490 pa_operation_unref(o);
491 }
492
493 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) {
494 struct pa_tagstruct *t;
495 struct pa_operation *o;
496 uint32_t tag;
497 assert(c && cb);
498
499 o = pa_operation_new(c, NULL);
500 o->callback = cb;
501 o->userdata = userdata;
502
503 t = pa_tagstruct_new(NULL, 0);
504 pa_tagstruct_putu32(t, PA_COMMAND_GET_SOURCE_OUTPUT_INFO);
505 pa_tagstruct_putu32(t, tag = c->ctag++);
506 pa_tagstruct_putu32(t, index);
507 pa_pstream_send_tagstruct(c->pstream, t);
508 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_source_output_info_callback, o);
509
510 return pa_operation_ref(o);
511 }
512
513 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) {
514 return pa_context_send_simple_command(c, PA_COMMAND_GET_SOURCE_OUTPUT_INFO_LIST, context_get_source_output_info_callback, cb, userdata);
515 }
516
517 /*** Volume manipulation ***/
518
519 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) {
520 struct pa_operation *o;
521 struct pa_tagstruct *t;
522 uint32_t tag;
523 assert(c && index != PA_INVALID_INDEX);
524
525 o = pa_operation_new(c, NULL);
526 o->callback = cb;
527 o->userdata = userdata;
528
529 t = pa_tagstruct_new(NULL, 0);
530 pa_tagstruct_putu32(t, PA_COMMAND_SET_SINK_VOLUME);
531 pa_tagstruct_putu32(t, tag = c->ctag++);
532 pa_tagstruct_putu32(t, index);
533 pa_tagstruct_puts(t, "");
534 pa_tagstruct_putu32(t, volume);
535 pa_pstream_send_tagstruct(c->pstream, t);
536 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, o);
537
538 return pa_operation_ref(o);
539 }
540
541 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) {
542 struct pa_operation *o;
543 struct pa_tagstruct *t;
544 uint32_t tag;
545 assert(c && name);
546
547 o = pa_operation_new(c, NULL);
548 o->callback = cb;
549 o->userdata = userdata;
550
551 t = pa_tagstruct_new(NULL, 0);
552 pa_tagstruct_putu32(t, PA_COMMAND_SET_SINK_VOLUME);
553 pa_tagstruct_putu32(t, tag = c->ctag++);
554 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
555 pa_tagstruct_puts(t, name);
556 pa_tagstruct_putu32(t, volume);
557 pa_pstream_send_tagstruct(c->pstream, t);
558 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, o);
559
560 return pa_operation_ref(o);
561 }
562
563 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) {
564 struct pa_operation *o;
565 struct pa_tagstruct *t;
566 uint32_t tag;
567 assert(c && index != PA_INVALID_INDEX);
568
569 o = pa_operation_new(c, NULL);
570 o->callback = cb;
571 o->userdata = userdata;
572
573 t = pa_tagstruct_new(NULL, 0);
574 pa_tagstruct_putu32(t, PA_COMMAND_SET_SINK_INPUT_VOLUME);
575 pa_tagstruct_putu32(t, tag = c->ctag++);
576 pa_tagstruct_putu32(t, index);
577 pa_tagstruct_putu32(t, volume);
578 pa_pstream_send_tagstruct(c->pstream, t);
579 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, o);
580
581 return pa_operation_ref(o);
582 }
583
584 /** Sample Cache **/
585
586 static void context_get_sample_info_callback(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata) {
587 struct pa_operation *o = userdata;
588 int eof = 1;
589 assert(pd && o && o->context && o->ref >= 1);
590
591 if (command != PA_COMMAND_REPLY) {
592 if (pa_context_handle_error(o->context, command, t) < 0)
593 goto finish;
594
595 eof = -1;
596 } else {
597
598 while (!pa_tagstruct_eof(t)) {
599 struct pa_sample_info i;
600
601 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
602 pa_tagstruct_gets(t, &i.name) < 0 ||
603 pa_tagstruct_getu32(t, &i.volume) < 0 ||
604 pa_tagstruct_getu32(t, &i.duration) < 0 ||
605 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0) {
606 pa_context_fail(o->context, PA_ERROR_PROTOCOL);
607 goto finish;
608 }
609
610 if (o->callback) {
611 void (*cb)(struct pa_context *s, const struct pa_sample_info*i, int eof, void *userdata) = o->callback;
612 cb(o->context, &i, 0, o->userdata);
613 }
614 }
615 }
616
617 if (o->callback) {
618 void (*cb)(struct pa_context *s, const struct pa_sample_info*i, int eof, void *userdata) = o->callback;
619 cb(o->context, NULL, eof, o->userdata);
620 }
621
622 finish:
623 pa_operation_done(o);
624 pa_operation_unref(o);
625 }
626
627 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) {
628 struct pa_tagstruct *t;
629 struct pa_operation *o;
630 uint32_t tag;
631 assert(c && cb && name);
632
633 o = pa_operation_new(c, NULL);
634 o->callback = cb;
635 o->userdata = userdata;
636
637 t = pa_tagstruct_new(NULL, 0);
638 pa_tagstruct_putu32(t, PA_COMMAND_GET_SAMPLE_INFO);
639 pa_tagstruct_putu32(t, tag = c->ctag++);
640 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
641 pa_tagstruct_puts(t, name);
642 pa_pstream_send_tagstruct(c->pstream, t);
643 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_sample_info_callback, o);
644
645 return pa_operation_ref(o);
646 }
647
648 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) {
649 struct pa_tagstruct *t;
650 struct pa_operation *o;
651 uint32_t tag;
652 assert(c && cb);
653
654 o = pa_operation_new(c, NULL);
655 o->callback = cb;
656 o->userdata = userdata;
657
658 t = pa_tagstruct_new(NULL, 0);
659 pa_tagstruct_putu32(t, PA_COMMAND_GET_SAMPLE_INFO);
660 pa_tagstruct_putu32(t, tag = c->ctag++);
661 pa_tagstruct_putu32(t, index);
662 pa_tagstruct_puts(t, "");
663 pa_pstream_send_tagstruct(c->pstream, t);
664 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_sample_info_callback, o);
665
666 return pa_operation_ref(o);
667 }
668
669 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) {
670 return pa_context_send_simple_command(c, PA_COMMAND_GET_SAMPLE_INFO_LIST, context_get_sample_info_callback, cb, userdata);
671 }