]> code.delx.au - pulseaudio/blob - polyp/polyplib-introspect.c
e650fb9fe3f70707e0291572dc59dde075345630
[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.buffer_usec) < 0 ||
404 pa_tagstruct_getu32(t, &i.sink_usec) < 0) {
405 pa_context_fail(o->context, PA_ERROR_PROTOCOL);
406 goto finish;
407 }
408
409 if (o->callback) {
410 void (*cb)(struct pa_context *s, const struct pa_sink_input_info*i, int eof, void *userdata) = o->callback;
411 cb(o->context, &i, 0, o->userdata);
412 }
413 }
414 }
415
416 if (o->callback) {
417 void (*cb)(struct pa_context *s, const struct pa_sink_input_info*i, int eof, void *userdata) = o->callback;
418 cb(o->context, NULL, eof, o->userdata);
419 }
420
421 finish:
422 pa_operation_done(o);
423 pa_operation_unref(o);
424 }
425
426 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) {
427 struct pa_tagstruct *t;
428 struct pa_operation *o;
429 uint32_t tag;
430 assert(c && cb);
431
432 o = pa_operation_new(c, NULL);
433 o->callback = cb;
434 o->userdata = userdata;
435
436 t = pa_tagstruct_new(NULL, 0);
437 pa_tagstruct_putu32(t, PA_COMMAND_GET_SINK_INPUT_INFO);
438 pa_tagstruct_putu32(t, tag = c->ctag++);
439 pa_tagstruct_putu32(t, index);
440 pa_pstream_send_tagstruct(c->pstream, t);
441 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_sink_input_info_callback, o);
442
443 return pa_operation_ref(o);
444 }
445
446 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) {
447 return pa_context_send_simple_command(c, PA_COMMAND_GET_SINK_INPUT_INFO_LIST, context_get_sink_input_info_callback, cb, userdata);
448 }
449
450 /*** Source output info ***/
451
452 static void context_get_source_output_info_callback(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata) {
453 struct pa_operation *o = userdata;
454 int eof = 1;
455 assert(pd && o && o->context && o->ref >= 1);
456
457 if (command != PA_COMMAND_REPLY) {
458 if (pa_context_handle_error(o->context, command, t) < 0)
459 goto finish;
460
461 eof = -1;
462 } else {
463
464 while (!pa_tagstruct_eof(t)) {
465 struct pa_source_output_info i;
466
467 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
468 pa_tagstruct_gets(t, &i.name) < 0 ||
469 pa_tagstruct_getu32(t, &i.owner_module) < 0 ||
470 pa_tagstruct_getu32(t, &i.client) < 0 ||
471 pa_tagstruct_getu32(t, &i.source) < 0 ||
472 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0) {
473 pa_context_fail(o->context, PA_ERROR_PROTOCOL);
474 goto finish;
475 }
476
477 if (o->callback) {
478 void (*cb)(struct pa_context *s, const struct pa_source_output_info*i, int eof, void *userdata) = o->callback;
479 cb(o->context, &i, 0, o->userdata);
480 }
481 }
482 }
483
484 if (o->callback) {
485 void (*cb)(struct pa_context *s, const struct pa_source_output_info*i, int eof, void *userdata) = o->callback;
486 cb(o->context, NULL, eof, o->userdata);
487 }
488
489 finish:
490 pa_operation_done(o);
491 pa_operation_unref(o);
492 }
493
494 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) {
495 struct pa_tagstruct *t;
496 struct pa_operation *o;
497 uint32_t tag;
498 assert(c && cb);
499
500 o = pa_operation_new(c, NULL);
501 o->callback = cb;
502 o->userdata = userdata;
503
504 t = pa_tagstruct_new(NULL, 0);
505 pa_tagstruct_putu32(t, PA_COMMAND_GET_SOURCE_OUTPUT_INFO);
506 pa_tagstruct_putu32(t, tag = c->ctag++);
507 pa_tagstruct_putu32(t, index);
508 pa_pstream_send_tagstruct(c->pstream, t);
509 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_source_output_info_callback, o);
510
511 return pa_operation_ref(o);
512 }
513
514 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) {
515 return pa_context_send_simple_command(c, PA_COMMAND_GET_SOURCE_OUTPUT_INFO_LIST, context_get_source_output_info_callback, cb, userdata);
516 }
517
518 /*** Volume manipulation ***/
519
520 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) {
521 struct pa_operation *o;
522 struct pa_tagstruct *t;
523 uint32_t tag;
524 assert(c && index != PA_INVALID_INDEX);
525
526 o = pa_operation_new(c, NULL);
527 o->callback = cb;
528 o->userdata = userdata;
529
530 t = pa_tagstruct_new(NULL, 0);
531 pa_tagstruct_putu32(t, PA_COMMAND_SET_SINK_VOLUME);
532 pa_tagstruct_putu32(t, tag = c->ctag++);
533 pa_tagstruct_putu32(t, index);
534 pa_tagstruct_puts(t, "");
535 pa_tagstruct_putu32(t, volume);
536 pa_pstream_send_tagstruct(c->pstream, t);
537 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, o);
538
539 return pa_operation_ref(o);
540 }
541
542 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) {
543 struct pa_operation *o;
544 struct pa_tagstruct *t;
545 uint32_t tag;
546 assert(c && name);
547
548 o = pa_operation_new(c, NULL);
549 o->callback = cb;
550 o->userdata = userdata;
551
552 t = pa_tagstruct_new(NULL, 0);
553 pa_tagstruct_putu32(t, PA_COMMAND_SET_SINK_VOLUME);
554 pa_tagstruct_putu32(t, tag = c->ctag++);
555 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
556 pa_tagstruct_puts(t, name);
557 pa_tagstruct_putu32(t, volume);
558 pa_pstream_send_tagstruct(c->pstream, t);
559 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, o);
560
561 return pa_operation_ref(o);
562 }
563
564 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) {
565 struct pa_operation *o;
566 struct pa_tagstruct *t;
567 uint32_t tag;
568 assert(c && index != PA_INVALID_INDEX);
569
570 o = pa_operation_new(c, NULL);
571 o->callback = cb;
572 o->userdata = userdata;
573
574 t = pa_tagstruct_new(NULL, 0);
575 pa_tagstruct_putu32(t, PA_COMMAND_SET_SINK_INPUT_VOLUME);
576 pa_tagstruct_putu32(t, tag = c->ctag++);
577 pa_tagstruct_putu32(t, index);
578 pa_tagstruct_putu32(t, volume);
579 pa_pstream_send_tagstruct(c->pstream, t);
580 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, o);
581
582 return pa_operation_ref(o);
583 }
584
585 /** Sample Cache **/
586
587 static void context_get_sample_info_callback(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata) {
588 struct pa_operation *o = userdata;
589 int eof = 1;
590 assert(pd && o && o->context && o->ref >= 1);
591
592 if (command != PA_COMMAND_REPLY) {
593 if (pa_context_handle_error(o->context, command, t) < 0)
594 goto finish;
595
596 eof = -1;
597 } else {
598
599 while (!pa_tagstruct_eof(t)) {
600 struct pa_sample_info i;
601
602 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
603 pa_tagstruct_gets(t, &i.name) < 0 ||
604 pa_tagstruct_getu32(t, &i.volume) < 0 ||
605 pa_tagstruct_getu32(t, &i.duration) < 0 ||
606 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0) {
607 pa_context_fail(o->context, PA_ERROR_PROTOCOL);
608 goto finish;
609 }
610
611 if (o->callback) {
612 void (*cb)(struct pa_context *s, const struct pa_sample_info*i, int eof, void *userdata) = o->callback;
613 cb(o->context, &i, 0, o->userdata);
614 }
615 }
616 }
617
618 if (o->callback) {
619 void (*cb)(struct pa_context *s, const struct pa_sample_info*i, int eof, void *userdata) = o->callback;
620 cb(o->context, NULL, eof, o->userdata);
621 }
622
623 finish:
624 pa_operation_done(o);
625 pa_operation_unref(o);
626 }
627
628 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) {
629 struct pa_tagstruct *t;
630 struct pa_operation *o;
631 uint32_t tag;
632 assert(c && cb && name);
633
634 o = pa_operation_new(c, NULL);
635 o->callback = cb;
636 o->userdata = userdata;
637
638 t = pa_tagstruct_new(NULL, 0);
639 pa_tagstruct_putu32(t, PA_COMMAND_GET_SAMPLE_INFO);
640 pa_tagstruct_putu32(t, tag = c->ctag++);
641 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
642 pa_tagstruct_puts(t, name);
643 pa_pstream_send_tagstruct(c->pstream, t);
644 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_sample_info_callback, o);
645
646 return pa_operation_ref(o);
647 }
648
649 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) {
650 struct pa_tagstruct *t;
651 struct pa_operation *o;
652 uint32_t tag;
653 assert(c && cb);
654
655 o = pa_operation_new(c, NULL);
656 o->callback = cb;
657 o->userdata = userdata;
658
659 t = pa_tagstruct_new(NULL, 0);
660 pa_tagstruct_putu32(t, PA_COMMAND_GET_SAMPLE_INFO);
661 pa_tagstruct_putu32(t, tag = c->ctag++);
662 pa_tagstruct_putu32(t, index);
663 pa_tagstruct_puts(t, "");
664 pa_pstream_send_tagstruct(c->pstream, t);
665 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_sample_info_callback, o);
666
667 return pa_operation_ref(o);
668 }
669
670 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) {
671 return pa_context_send_simple_command(c, PA_COMMAND_GET_SAMPLE_INFO_LIST, context_get_sample_info_callback, cb, userdata);
672 }