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