1 /***
2 This file is part of PulseAudio.
3
4 Copyright 2004-2006 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
6
7 PulseAudio is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published
9 by the Free Software Foundation; either version 2.1 of the License,
10 or (at your option) any later version.
11
12 PulseAudio is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
19 ***/
20
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24
25 #include <pulse/context.h>
26 #include <pulse/direction.h>
27 #include <pulse/xmalloc.h>
28 #include <pulse/fork-detect.h>
29
30 #include <pulsecore/macro.h>
31 #include <pulsecore/core-util.h>
32 #include <pulsecore/pstream-util.h>
33
34 #include "internal.h"
35 #include "introspect.h"
36
37 /*** Statistics ***/
38
context_stat_callback(pa_pdispatch * pd,uint32_t command,uint32_t tag,pa_tagstruct * t,void * userdata)39 static void context_stat_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
40 pa_operation *o = userdata;
41 pa_stat_info i, *p = &i;
42
43 pa_assert(pd);
44 pa_assert(o);
45 pa_assert(PA_REFCNT_VALUE(o) >= 1);
46
47 pa_zero(i);
48
49 if (!o->context)
50 goto finish;
51
52 if (command != PA_COMMAND_REPLY) {
53 if (pa_context_handle_error(o->context, command, t, false) < 0)
54 goto finish;
55
56 p = NULL;
57 } else if (pa_tagstruct_getu32(t, &i.memblock_total) < 0 ||
58 pa_tagstruct_getu32(t, &i.memblock_total_size) < 0 ||
59 pa_tagstruct_getu32(t, &i.memblock_allocated) < 0 ||
60 pa_tagstruct_getu32(t, &i.memblock_allocated_size) < 0 ||
61 pa_tagstruct_getu32(t, &i.scache_size) < 0 ||
62 !pa_tagstruct_eof(t)) {
63 pa_context_fail(o->context, PA_ERR_PROTOCOL);
64 goto finish;
65 }
66
67 if (o->callback) {
68 pa_stat_info_cb_t cb = (pa_stat_info_cb_t) o->callback;
69 cb(o->context, p, o->userdata);
70 }
71
72 finish:
73 pa_operation_done(o);
74 pa_operation_unref(o);
75 }
76
pa_context_stat(pa_context * c,pa_stat_info_cb_t cb,void * userdata)77 pa_operation* pa_context_stat(pa_context *c, pa_stat_info_cb_t cb, void *userdata) {
78 return pa_context_send_simple_command(c, PA_COMMAND_STAT, context_stat_callback, (pa_operation_cb_t) cb, userdata);
79 }
80
81 /*** Server Info ***/
82
context_get_server_info_callback(pa_pdispatch * pd,uint32_t command,uint32_t tag,pa_tagstruct * t,void * userdata)83 static void context_get_server_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
84 pa_operation *o = userdata;
85 pa_server_info i, *p = &i;
86
87 pa_assert(pd);
88 pa_assert(o);
89 pa_assert(PA_REFCNT_VALUE(o) >= 1);
90
91 pa_zero(i);
92
93 if (!o->context)
94 goto finish;
95
96 if (command != PA_COMMAND_REPLY) {
97 if (pa_context_handle_error(o->context, command, t, false) < 0)
98 goto finish;
99
100 p = NULL;
101 } else if (pa_tagstruct_gets(t, &i.server_name) < 0 ||
102 pa_tagstruct_gets(t, &i.server_version) < 0 ||
103 pa_tagstruct_gets(t, &i.user_name) < 0 ||
104 pa_tagstruct_gets(t, &i.host_name) < 0 ||
105 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
106 pa_tagstruct_gets(t, &i.default_sink_name) < 0 ||
107 pa_tagstruct_gets(t, &i.default_source_name) < 0 ||
108 pa_tagstruct_getu32(t, &i.cookie) < 0 ||
109 (o->context->version >= 15 &&
110 pa_tagstruct_get_channel_map(t, &i.channel_map) < 0) ||
111 !pa_tagstruct_eof(t)) {
112
113 pa_context_fail(o->context, PA_ERR_PROTOCOL);
114 goto finish;
115 }
116
117 if (p && o->context->version < 15)
118 pa_channel_map_init_extend(&i.channel_map, i.sample_spec.channels, PA_CHANNEL_MAP_DEFAULT);
119
120 if (o->callback) {
121 pa_server_info_cb_t cb = (pa_server_info_cb_t) o->callback;
122 cb(o->context, p, o->userdata);
123 }
124
125 finish:
126 pa_operation_done(o);
127 pa_operation_unref(o);
128 }
129
pa_context_get_server_info(pa_context * c,pa_server_info_cb_t cb,void * userdata)130 pa_operation* pa_context_get_server_info(pa_context *c, pa_server_info_cb_t cb, void *userdata) {
131 return pa_context_send_simple_command(c, PA_COMMAND_GET_SERVER_INFO, context_get_server_info_callback, (pa_operation_cb_t) cb, userdata);
132 }
133
134 /*** Sink Info ***/
135
context_get_sink_info_callback(pa_pdispatch * pd,uint32_t command,uint32_t tag,pa_tagstruct * t,void * userdata)136 static void context_get_sink_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
137 pa_operation *o = userdata;
138 int eol = 1;
139 pa_sink_info i;
140 uint32_t j;
141
142 pa_assert(pd);
143 pa_assert(o);
144 pa_assert(PA_REFCNT_VALUE(o) >= 1);
145
146 /* For safety in case someone use fail: outside the while loop below */
147 pa_zero(i);
148
149 if (!o->context)
150 goto finish;
151
152 if (command != PA_COMMAND_REPLY) {
153 if (pa_context_handle_error(o->context, command, t, false) < 0)
154 goto finish;
155
156 eol = -1;
157 } else {
158
159 while (!pa_tagstruct_eof(t)) {
160 bool mute;
161 uint32_t flags;
162 uint32_t state;
163 const char *ap = NULL;
164
165 pa_zero(i);
166 i.proplist = pa_proplist_new();
167 i.base_volume = PA_VOLUME_NORM;
168 i.n_volume_steps = PA_VOLUME_NORM+1;
169 mute = false;
170 state = PA_SINK_INVALID_STATE;
171 i.card = PA_INVALID_INDEX;
172
173 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
174 pa_tagstruct_gets(t, &i.name) < 0 ||
175 pa_tagstruct_gets(t, &i.description) < 0 ||
176 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
177 pa_tagstruct_get_channel_map(t, &i.channel_map) < 0 ||
178 pa_tagstruct_getu32(t, &i.owner_module) < 0 ||
179 pa_tagstruct_get_cvolume(t, &i.volume) < 0 ||
180 pa_tagstruct_get_boolean(t, &mute) < 0 ||
181 pa_tagstruct_getu32(t, &i.monitor_source) < 0 ||
182 pa_tagstruct_gets(t, &i.monitor_source_name) < 0 ||
183 pa_tagstruct_get_usec(t, &i.latency) < 0 ||
184 pa_tagstruct_gets(t, &i.driver) < 0 ||
185 pa_tagstruct_getu32(t, &flags) < 0 ||
186 (o->context->version >= 13 &&
187 (pa_tagstruct_get_proplist(t, i.proplist) < 0 ||
188 pa_tagstruct_get_usec(t, &i.configured_latency) < 0)) ||
189 (o->context->version >= 15 &&
190 (pa_tagstruct_get_volume(t, &i.base_volume) < 0 ||
191 pa_tagstruct_getu32(t, &state) < 0 ||
192 pa_tagstruct_getu32(t, &i.n_volume_steps) < 0 ||
193 pa_tagstruct_getu32(t, &i.card) < 0)) ||
194 (o->context->version >= 16 &&
195 (pa_tagstruct_getu32(t, &i.n_ports)))) {
196
197 goto fail;
198 }
199
200 if (o->context->version >= 16) {
201 if (i.n_ports > 0) {
202 i.ports = pa_xnew(pa_sink_port_info*, i.n_ports+1);
203 i.ports[0] = pa_xnew(pa_sink_port_info, i.n_ports);
204
205 for (j = 0; j < i.n_ports; j++) {
206 i.ports[j] = &i.ports[0][j];
207
208 if (pa_tagstruct_gets(t, &i.ports[j]->name) < 0 ||
209 pa_tagstruct_gets(t, &i.ports[j]->description) < 0 ||
210 pa_tagstruct_getu32(t, &i.ports[j]->priority) < 0) {
211
212 goto fail;
213 }
214
215 i.ports[j]->available = PA_PORT_AVAILABLE_UNKNOWN;
216 if (o->context->version >= 24) {
217 uint32_t av;
218 if (pa_tagstruct_getu32(t, &av) < 0 || av > PA_PORT_AVAILABLE_YES)
219 goto fail;
220 i.ports[j]->available = av;
221 }
222 i.ports[j]->availability_group = NULL;
223 i.ports[j]->type = PA_DEVICE_PORT_TYPE_UNKNOWN;
224 if (o->context->version >= 34) {
225 if (pa_tagstruct_gets(t, &i.ports[j]->availability_group) < 0 ||
226 pa_tagstruct_getu32(t, &i.ports[j]->type) < 0)
227 goto fail;
228 }
229 }
230
231 i.ports[j] = NULL;
232 }
233
234 if (pa_tagstruct_gets(t, &ap) < 0)
235 goto fail;
236
237 if (ap) {
238 for (j = 0; j < i.n_ports; j++)
239 if (pa_streq(i.ports[j]->name, ap)) {
240 i.active_port = i.ports[j];
241 break;
242 }
243 }
244 }
245
246 if (o->context->version >= 21) {
247 uint8_t n_formats;
248 if (pa_tagstruct_getu8(t, &n_formats) < 0 || n_formats < 1)
249 goto fail;
250
251 i.formats = pa_xnew0(pa_format_info*, n_formats);
252
253 for (j = 0; j < n_formats; j++) {
254 i.n_formats++;
255 i.formats[j] = pa_format_info_new();
256
257 if (pa_tagstruct_get_format_info(t, i.formats[j]) < 0)
258 goto fail;
259 }
260 }
261
262 i.mute = (int) mute;
263 i.flags = (pa_sink_flags_t) flags;
264 i.state = (pa_sink_state_t) state;
265
266 if (o->callback) {
267 pa_sink_info_cb_t cb = (pa_sink_info_cb_t) o->callback;
268 cb(o->context, &i, 0, o->userdata);
269 }
270
271 if (i.formats) {
272 for (j = 0; j < i.n_formats; j++)
273 pa_format_info_free(i.formats[j]);
274 pa_xfree(i.formats);
275 }
276 if (i.ports) {
277 pa_xfree(i.ports[0]);
278 pa_xfree(i.ports);
279 }
280 pa_proplist_free(i.proplist);
281 }
282 }
283
284 if (o->callback) {
285 pa_sink_info_cb_t cb = (pa_sink_info_cb_t) o->callback;
286 cb(o->context, NULL, eol, o->userdata);
287 }
288
289 finish:
290 pa_operation_done(o);
291 pa_operation_unref(o);
292 return;
293
294 fail:
295 pa_assert(i.proplist);
296
297 pa_context_fail(o->context, PA_ERR_PROTOCOL);
298
299 if (i.formats) {
300 for (j = 0; j < i.n_formats; j++)
301 pa_format_info_free(i.formats[j]);
302 pa_xfree(i.formats);
303 }
304 if (i.ports) {
305 pa_xfree(i.ports[0]);
306 pa_xfree(i.ports);
307 }
308 pa_proplist_free(i.proplist);
309
310 goto finish;
311 }
312
pa_context_get_sink_info_list(pa_context * c,pa_sink_info_cb_t cb,void * userdata)313 pa_operation* pa_context_get_sink_info_list(pa_context *c, pa_sink_info_cb_t cb, void *userdata) {
314 return pa_context_send_simple_command(c, PA_COMMAND_GET_SINK_INFO_LIST, context_get_sink_info_callback, (pa_operation_cb_t) cb, userdata);
315 }
316
pa_context_get_sink_info_by_index(pa_context * c,uint32_t idx,pa_sink_info_cb_t cb,void * userdata)317 pa_operation* pa_context_get_sink_info_by_index(pa_context *c, uint32_t idx, pa_sink_info_cb_t cb, void *userdata) {
318 pa_tagstruct *t;
319 pa_operation *o;
320 uint32_t tag;
321
322 pa_assert(c);
323 pa_assert(PA_REFCNT_VALUE(c) >= 1);
324 pa_assert(cb);
325
326 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
327 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
328
329 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
330
331 t = pa_tagstruct_command(c, PA_COMMAND_GET_SINK_INFO, &tag);
332 pa_tagstruct_putu32(t, idx);
333 pa_tagstruct_puts(t, NULL);
334 pa_pstream_send_tagstruct(c->pstream, t);
335 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_sink_info_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
336
337 return o;
338 }
339
pa_context_get_sink_info_by_name(pa_context * c,const char * name,pa_sink_info_cb_t cb,void * userdata)340 pa_operation* pa_context_get_sink_info_by_name(pa_context *c, const char *name, pa_sink_info_cb_t cb, void *userdata) {
341 pa_tagstruct *t;
342 pa_operation *o;
343 uint32_t tag;
344
345 pa_assert(c);
346 pa_assert(PA_REFCNT_VALUE(c) >= 1);
347 pa_assert(cb);
348
349 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
350 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
351 PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
352
353 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
354
355 t = pa_tagstruct_command(c, PA_COMMAND_GET_SINK_INFO, &tag);
356 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
357 pa_tagstruct_puts(t, name);
358 pa_pstream_send_tagstruct(c->pstream, t);
359 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_sink_info_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
360
361 return o;
362 }
363
pa_context_set_sink_port_by_index(pa_context * c,uint32_t idx,const char * port,pa_context_success_cb_t cb,void * userdata)364 pa_operation* pa_context_set_sink_port_by_index(pa_context *c, uint32_t idx, const char*port, pa_context_success_cb_t cb, void *userdata) {
365 pa_operation *o;
366 pa_tagstruct *t;
367 uint32_t tag;
368
369 pa_assert(c);
370 pa_assert(PA_REFCNT_VALUE(c) >= 1);
371
372 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
373 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
374 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
375 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 16, PA_ERR_NOTSUPPORTED);
376
377 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
378
379 t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_PORT, &tag);
380 pa_tagstruct_putu32(t, idx);
381 pa_tagstruct_puts(t, NULL);
382 pa_tagstruct_puts(t, port);
383 pa_pstream_send_tagstruct(c->pstream, t);
384 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
385
386 return o;
387 }
388
pa_context_set_sink_port_by_name(pa_context * c,const char * name,const char * port,pa_context_success_cb_t cb,void * userdata)389 pa_operation* pa_context_set_sink_port_by_name(pa_context *c, const char *name, const char*port, pa_context_success_cb_t cb, void *userdata) {
390 pa_operation *o;
391 pa_tagstruct *t;
392 uint32_t tag;
393
394 pa_assert(c);
395 pa_assert(PA_REFCNT_VALUE(c) >= 1);
396
397 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
398 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
399 PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
400 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 16, PA_ERR_NOTSUPPORTED);
401
402 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
403
404 t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_PORT, &tag);
405 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
406 pa_tagstruct_puts(t, name);
407 pa_tagstruct_puts(t, port);
408 pa_pstream_send_tagstruct(c->pstream, t);
409 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
410
411 return o;
412 }
413
414 /*** Source info ***/
415
context_get_source_info_callback(pa_pdispatch * pd,uint32_t command,uint32_t tag,pa_tagstruct * t,void * userdata)416 static void context_get_source_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
417 pa_operation *o = userdata;
418 int eol = 1;
419 pa_source_info i;
420 uint32_t j;
421
422 pa_assert(pd);
423 pa_assert(o);
424 pa_assert(PA_REFCNT_VALUE(o) >= 1);
425
426 /* For safety in case someone use fail: outside the while loop below */
427 pa_zero(i);
428
429 if (!o->context)
430 goto finish;
431
432 if (command != PA_COMMAND_REPLY) {
433 if (pa_context_handle_error(o->context, command, t, false) < 0)
434 goto finish;
435
436 eol = -1;
437 } else {
438
439 while (!pa_tagstruct_eof(t)) {
440 bool mute;
441 uint32_t flags;
442 uint32_t state;
443 const char *ap;
444
445 pa_zero(i);
446 i.proplist = pa_proplist_new();
447 i.base_volume = PA_VOLUME_NORM;
448 i.n_volume_steps = PA_VOLUME_NORM+1;
449 mute = false;
450 state = PA_SOURCE_INVALID_STATE;
451 i.card = PA_INVALID_INDEX;
452
453 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
454 pa_tagstruct_gets(t, &i.name) < 0 ||
455 pa_tagstruct_gets(t, &i.description) < 0 ||
456 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
457 pa_tagstruct_get_channel_map(t, &i.channel_map) < 0 ||
458 pa_tagstruct_getu32(t, &i.owner_module) < 0 ||
459 pa_tagstruct_get_cvolume(t, &i.volume) < 0 ||
460 pa_tagstruct_get_boolean(t, &mute) < 0 ||
461 pa_tagstruct_getu32(t, &i.monitor_of_sink) < 0 ||
462 pa_tagstruct_gets(t, &i.monitor_of_sink_name) < 0 ||
463 pa_tagstruct_get_usec(t, &i.latency) < 0 ||
464 pa_tagstruct_gets(t, &i.driver) < 0 ||
465 pa_tagstruct_getu32(t, &flags) < 0 ||
466 (o->context->version >= 13 &&
467 (pa_tagstruct_get_proplist(t, i.proplist) < 0 ||
468 pa_tagstruct_get_usec(t, &i.configured_latency) < 0)) ||
469 (o->context->version >= 15 &&
470 (pa_tagstruct_get_volume(t, &i.base_volume) < 0 ||
471 pa_tagstruct_getu32(t, &state) < 0 ||
472 pa_tagstruct_getu32(t, &i.n_volume_steps) < 0 ||
473 pa_tagstruct_getu32(t, &i.card) < 0)) ||
474 (o->context->version >= 16 &&
475 (pa_tagstruct_getu32(t, &i.n_ports)))) {
476
477 goto fail;
478 }
479
480 if (o->context->version >= 16) {
481 if (i.n_ports > 0) {
482 i.ports = pa_xnew(pa_source_port_info*, i.n_ports+1);
483 i.ports[0] = pa_xnew(pa_source_port_info, i.n_ports);
484
485 for (j = 0; j < i.n_ports; j++) {
486 i.ports[j] = &i.ports[0][j];
487
488 if (pa_tagstruct_gets(t, &i.ports[j]->name) < 0 ||
489 pa_tagstruct_gets(t, &i.ports[j]->description) < 0 ||
490 pa_tagstruct_getu32(t, &i.ports[j]->priority) < 0) {
491
492 goto fail;
493 }
494
495 i.ports[j]->available = PA_PORT_AVAILABLE_UNKNOWN;
496 if (o->context->version >= 24) {
497 uint32_t av;
498 if (pa_tagstruct_getu32(t, &av) < 0 || av > PA_PORT_AVAILABLE_YES)
499 goto fail;
500 i.ports[j]->available = av;
501 }
502 i.ports[j]->availability_group = NULL;
503 i.ports[j]->type = PA_DEVICE_PORT_TYPE_UNKNOWN;
504 if (o->context->version >= 34) {
505 if (pa_tagstruct_gets(t, &i.ports[j]->availability_group) < 0 ||
506 pa_tagstruct_getu32(t, &i.ports[j]->type))
507 goto fail;
508 }
509 }
510
511 i.ports[j] = NULL;
512 }
513 if (pa_tagstruct_gets(t, &ap) < 0)
514 goto fail;
515
516 if (ap) {
517 for (j = 0; j < i.n_ports; j++)
518 if (pa_streq(i.ports[j]->name, ap)) {
519 i.active_port = i.ports[j];
520 break;
521 }
522 }
523 }
524
525 if (o->context->version >= 22) {
526 uint8_t n_formats;
527 if (pa_tagstruct_getu8(t, &n_formats) < 0 || n_formats < 1)
528 goto fail;
529
530 i.formats = pa_xnew0(pa_format_info*, n_formats);
531
532 for (j = 0; j < n_formats; j++) {
533 i.n_formats++;
534 i.formats[j] = pa_format_info_new();
535
536 if (pa_tagstruct_get_format_info(t, i.formats[j]) < 0)
537 goto fail;
538 }
539 }
540
541 i.mute = (int) mute;
542 i.flags = (pa_source_flags_t) flags;
543 i.state = (pa_source_state_t) state;
544
545 if (o->callback) {
546 pa_source_info_cb_t cb = (pa_source_info_cb_t) o->callback;
547 cb(o->context, &i, 0, o->userdata);
548 }
549
550 if (i.formats) {
551 for (j = 0; j < i.n_formats; j++)
552 pa_format_info_free(i.formats[j]);
553 pa_xfree(i.formats);
554 }
555 if (i.ports) {
556 pa_xfree(i.ports[0]);
557 pa_xfree(i.ports);
558 }
559 pa_proplist_free(i.proplist);
560 }
561 }
562
563 if (o->callback) {
564 pa_source_info_cb_t cb = (pa_source_info_cb_t) o->callback;
565 cb(o->context, NULL, eol, o->userdata);
566 }
567
568 finish:
569 pa_operation_done(o);
570 pa_operation_unref(o);
571 return;
572
573 fail:
574 pa_assert(i.proplist);
575
576 pa_context_fail(o->context, PA_ERR_PROTOCOL);
577
578 if (i.formats) {
579 for (j = 0; j < i.n_formats; j++)
580 pa_format_info_free(i.formats[j]);
581 pa_xfree(i.formats);
582 }
583 if (i.ports) {
584 pa_xfree(i.ports[0]);
585 pa_xfree(i.ports);
586 }
587 pa_proplist_free(i.proplist);
588
589 goto finish;
590 }
591
pa_context_get_source_info_list(pa_context * c,pa_source_info_cb_t cb,void * userdata)592 pa_operation* pa_context_get_source_info_list(pa_context *c, pa_source_info_cb_t cb, void *userdata) {
593 return pa_context_send_simple_command(c, PA_COMMAND_GET_SOURCE_INFO_LIST, context_get_source_info_callback, (pa_operation_cb_t) cb, userdata);
594 }
595
pa_context_get_source_info_by_index(pa_context * c,uint32_t idx,pa_source_info_cb_t cb,void * userdata)596 pa_operation* pa_context_get_source_info_by_index(pa_context *c, uint32_t idx, pa_source_info_cb_t cb, void *userdata) {
597 pa_tagstruct *t;
598 pa_operation *o;
599 uint32_t tag;
600
601 pa_assert(c);
602 pa_assert(PA_REFCNT_VALUE(c) >= 1);
603 pa_assert(cb);
604
605 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
606 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
607
608 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
609
610 t = pa_tagstruct_command(c, PA_COMMAND_GET_SOURCE_INFO, &tag);
611 pa_tagstruct_putu32(t, idx);
612 pa_tagstruct_puts(t, NULL);
613 pa_pstream_send_tagstruct(c->pstream, t);
614 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_source_info_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
615
616 return o;
617 }
618
pa_context_get_source_info_by_name(pa_context * c,const char * name,pa_source_info_cb_t cb,void * userdata)619 pa_operation* pa_context_get_source_info_by_name(pa_context *c, const char *name, pa_source_info_cb_t cb, void *userdata) {
620 pa_tagstruct *t;
621 pa_operation *o;
622 uint32_t tag;
623
624 pa_assert(c);
625 pa_assert(PA_REFCNT_VALUE(c) >= 1);
626 pa_assert(cb);
627
628 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
629 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
630 PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
631
632 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
633
634 t = pa_tagstruct_command(c, PA_COMMAND_GET_SOURCE_INFO, &tag);
635 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
636 pa_tagstruct_puts(t, name);
637 pa_pstream_send_tagstruct(c->pstream, t);
638 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_source_info_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
639
640 return o;
641 }
642
pa_context_set_source_port_by_index(pa_context * c,uint32_t idx,const char * port,pa_context_success_cb_t cb,void * userdata)643 pa_operation* pa_context_set_source_port_by_index(pa_context *c, uint32_t idx, const char*port, pa_context_success_cb_t cb, void *userdata) {
644 pa_operation *o;
645 pa_tagstruct *t;
646 uint32_t tag;
647
648 pa_assert(c);
649 pa_assert(PA_REFCNT_VALUE(c) >= 1);
650
651 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
652 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
653 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
654 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 16, PA_ERR_NOTSUPPORTED);
655
656 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
657
658 t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_PORT, &tag);
659 pa_tagstruct_putu32(t, idx);
660 pa_tagstruct_puts(t, NULL);
661 pa_tagstruct_puts(t, port);
662 pa_pstream_send_tagstruct(c->pstream, t);
663 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
664
665 return o;
666 }
667
pa_context_set_source_port_by_name(pa_context * c,const char * name,const char * port,pa_context_success_cb_t cb,void * userdata)668 pa_operation* pa_context_set_source_port_by_name(pa_context *c, const char *name, const char*port, pa_context_success_cb_t cb, void *userdata) {
669 pa_operation *o;
670 pa_tagstruct *t;
671 uint32_t tag;
672
673 pa_assert(c);
674 pa_assert(PA_REFCNT_VALUE(c) >= 1);
675
676 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
677 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
678 PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
679 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 16, PA_ERR_NOTSUPPORTED);
680
681 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
682
683 t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_PORT, &tag);
684 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
685 pa_tagstruct_puts(t, name);
686 pa_tagstruct_puts(t, port);
687 pa_pstream_send_tagstruct(c->pstream, t);
688 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
689
690 return o;
691 }
692
693 /*** Client info ***/
694
context_get_client_info_callback(pa_pdispatch * pd,uint32_t command,uint32_t tag,pa_tagstruct * t,void * userdata)695 static void context_get_client_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
696 pa_operation *o = userdata;
697 int eol = 1;
698
699 pa_assert(pd);
700 pa_assert(o);
701 pa_assert(PA_REFCNT_VALUE(o) >= 1);
702
703 if (!o->context)
704 goto finish;
705
706 if (command != PA_COMMAND_REPLY) {
707 if (pa_context_handle_error(o->context, command, t, false) < 0)
708 goto finish;
709
710 eol = -1;
711 } else {
712
713 while (!pa_tagstruct_eof(t)) {
714 pa_client_info i;
715
716 pa_zero(i);
717 i.proplist = pa_proplist_new();
718
719 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
720 pa_tagstruct_gets(t, &i.name) < 0 ||
721 pa_tagstruct_getu32(t, &i.owner_module) < 0 ||
722 pa_tagstruct_gets(t, &i.driver) < 0 ||
723 (o->context->version >= 13 && pa_tagstruct_get_proplist(t, i.proplist) < 0)) {
724
725 pa_context_fail(o->context, PA_ERR_PROTOCOL);
726 pa_proplist_free(i.proplist);
727 goto finish;
728 }
729
730 if (o->callback) {
731 pa_client_info_cb_t cb = (pa_client_info_cb_t) o->callback;
732 cb(o->context, &i, 0, o->userdata);
733 }
734
735 pa_proplist_free(i.proplist);
736 }
737 }
738
739 if (o->callback) {
740 pa_client_info_cb_t cb = (pa_client_info_cb_t) o->callback;
741 cb(o->context, NULL, eol, o->userdata);
742 }
743
744 finish:
745 pa_operation_done(o);
746 pa_operation_unref(o);
747 }
748
pa_context_get_client_info(pa_context * c,uint32_t idx,pa_client_info_cb_t cb,void * userdata)749 pa_operation* pa_context_get_client_info(pa_context *c, uint32_t idx, pa_client_info_cb_t cb, void *userdata) {
750 pa_tagstruct *t;
751 pa_operation *o;
752 uint32_t tag;
753
754 pa_assert(c);
755 pa_assert(PA_REFCNT_VALUE(c) >= 1);
756 pa_assert(cb);
757
758 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
759 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
760 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
761
762 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
763
764 t = pa_tagstruct_command(c, PA_COMMAND_GET_CLIENT_INFO, &tag);
765 pa_tagstruct_putu32(t, idx);
766 pa_pstream_send_tagstruct(c->pstream, t);
767 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_client_info_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
768
769 return o;
770 }
771
pa_context_get_client_info_list(pa_context * c,pa_client_info_cb_t cb,void * userdata)772 pa_operation* pa_context_get_client_info_list(pa_context *c, pa_client_info_cb_t cb, void *userdata) {
773 return pa_context_send_simple_command(c, PA_COMMAND_GET_CLIENT_INFO_LIST, context_get_client_info_callback, (pa_operation_cb_t) cb, userdata);
774 }
775
776 /*** Card info ***/
777
card_info_free(pa_card_info * i)778 static void card_info_free(pa_card_info* i) {
779 if (i->proplist)
780 pa_proplist_free(i->proplist);
781
782 pa_xfree(i->profiles);
783
784 if (i->n_profiles) {
785 uint32_t j;
786
787 for (j = 0; j < i->n_profiles; j++)
788 pa_xfree(i->profiles2[j]);
789
790 pa_xfree(i->profiles2);
791 }
792
793 if (i->ports) {
794 uint32_t j;
795
796 for (j = 0; j < i->n_ports; j++) {
797 if (i->ports[j]) {
798 if (i->ports[j]->profiles)
799 pa_xfree(i->ports[j]->profiles);
800 if (i->ports[j]->profiles2)
801 pa_xfree(i->ports[j]->profiles2);
802 if (i->ports[j]->proplist)
803 pa_proplist_free(i->ports[j]->proplist);
804 }
805 }
806
807 pa_xfree(i->ports[0]);
808 pa_xfree(i->ports);
809 }
810 }
811
fill_card_port_info(pa_context * context,pa_tagstruct * t,pa_card_info * i)812 static int fill_card_port_info(pa_context *context, pa_tagstruct* t, pa_card_info* i) {
813 uint32_t j, k, l;
814
815 if (pa_tagstruct_getu32(t, &i->n_ports) < 0)
816 return -PA_ERR_PROTOCOL;
817
818 if (i->n_ports == 0) {
819 i->ports = NULL;
820 return 0;
821 }
822
823 i->ports = pa_xnew0(pa_card_port_info*, i->n_ports+1);
824 i->ports[0] = pa_xnew0(pa_card_port_info, i->n_ports);
825
826 for (j = 0; j < i->n_ports; j++) {
827 uint8_t direction;
828 uint32_t available;
829 pa_card_port_info* port = i->ports[j] = &i->ports[0][j];
830
831 port->proplist = pa_proplist_new();
832
833 if (pa_tagstruct_gets(t, &port->name) < 0 ||
834 pa_tagstruct_gets(t, &port->description) < 0 ||
835 pa_tagstruct_getu32(t, &port->priority) < 0 ||
836 pa_tagstruct_getu32(t, &available) < 0 ||
837 pa_tagstruct_getu8(t, &direction) < 0 ||
838 !pa_direction_valid(direction) ||
839 pa_tagstruct_get_proplist(t, port->proplist) < 0 ||
840 pa_tagstruct_getu32(t, &port->n_profiles) < 0) {
841
842 return -PA_ERR_PROTOCOL;
843 }
844
845 if (available > PA_PORT_AVAILABLE_YES ) {
846 return -PA_ERR_PROTOCOL;
847 }
848
849 port->direction = direction;
850 port->available = available;
851
852 if (port->n_profiles > 0) {
853 port->profiles = pa_xnew0(pa_card_profile_info*, i->n_profiles+1);
854 port->profiles2 = pa_xnew0(pa_card_profile_info2*, i->n_profiles+1);
855
856 for (k = 0; k < port->n_profiles; k++) {
857 const char* profilename;
858
859 if (pa_tagstruct_gets(t, &profilename) < 0)
860 return -PA_ERR_PROTOCOL;
861
862 for (l = 0; l < i->n_profiles; l++) {
863 if (pa_streq(i->profiles[l].name, profilename)) {
864 port->profiles[k] = &i->profiles[l];
865 port->profiles2[k] = i->profiles2[l];
866 break;
867 }
868 }
869
870 if (l >= i->n_profiles)
871 return -PA_ERR_PROTOCOL;
872 }
873 }
874 if (context->version >= 27) {
875 if (pa_tagstruct_gets64(t, &port->latency_offset) < 0)
876 return -PA_ERR_PROTOCOL;
877 } else
878 port->latency_offset = 0;
879
880 port->type = PA_DEVICE_PORT_TYPE_UNKNOWN;
881 if (context->version >= 34) {
882 if (pa_tagstruct_gets(t, &port->availability_group) < 0 ||
883 pa_tagstruct_getu32(t, &port->type) < 0)
884 return -PA_ERR_PROTOCOL;
885 } else
886 port->availability_group = NULL;
887 }
888
889 return 0;
890 }
891
fill_card_profile_info(pa_context * context,pa_tagstruct * t,pa_card_info * i)892 static int fill_card_profile_info(pa_context *context, pa_tagstruct* t, pa_card_info* i) {
893 uint32_t j;
894
895 i->profiles = pa_xnew0(pa_card_profile_info, i->n_profiles+1);
896 i->profiles2 = pa_xnew0(pa_card_profile_info2*, i->n_profiles+1);
897
898 for (j = 0; j < i->n_profiles; j++) {
899 if (pa_tagstruct_gets(t, &i->profiles[j].name) < 0 ||
900 pa_tagstruct_gets(t, &i->profiles[j].description) < 0 ||
901 pa_tagstruct_getu32(t, &i->profiles[j].n_sinks) < 0 ||
902 pa_tagstruct_getu32(t, &i->profiles[j].n_sources) < 0 ||
903 pa_tagstruct_getu32(t, &i->profiles[j].priority) < 0)
904 return -PA_ERR_PROTOCOL;
905
906 i->profiles2[j] = pa_xnew0(pa_card_profile_info2, 1);
907 i->profiles2[j]->name = i->profiles[j].name;
908 i->profiles2[j]->description = i->profiles[j].description;
909 i->profiles2[j]->n_sinks = i->profiles[j].n_sinks;
910 i->profiles2[j]->n_sources = i->profiles[j].n_sources;
911 i->profiles2[j]->priority = i->profiles[j].priority;
912 i->profiles2[j]->available = 1;
913
914 if (context->version >= 29) {
915 uint32_t av;
916
917 if (pa_tagstruct_getu32(t, &av) < 0)
918 return -PA_ERR_PROTOCOL;
919
920 i->profiles2[j]->available = av;
921 }
922 }
923
924 return 0;
925 }
926
context_get_card_info_callback(pa_pdispatch * pd,uint32_t command,uint32_t tag,pa_tagstruct * t,void * userdata)927 static void context_get_card_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
928 pa_operation *o = userdata;
929 int eol = 1;
930 pa_card_info i;
931
932 pa_assert(pd);
933 pa_assert(o);
934 pa_assert(PA_REFCNT_VALUE(o) >= 1);
935
936 if (!o->context)
937 goto finish;
938
939 if (command != PA_COMMAND_REPLY) {
940 if (pa_context_handle_error(o->context, command, t, false) < 0)
941 goto finish;
942
943 eol = -1;
944 } else {
945
946 while (!pa_tagstruct_eof(t)) {
947 uint32_t j;
948 const char*ap;
949
950 pa_zero(i);
951
952 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
953 pa_tagstruct_gets(t, &i.name) < 0 ||
954 pa_tagstruct_getu32(t, &i.owner_module) < 0 ||
955 pa_tagstruct_gets(t, &i.driver) < 0 ||
956 pa_tagstruct_getu32(t, &i.n_profiles) < 0)
957 goto fail;
958
959 if (i.n_profiles > 0) {
960 if (fill_card_profile_info(o->context, t, &i) < 0)
961 goto fail;
962 }
963
964 i.proplist = pa_proplist_new();
965
966 if (pa_tagstruct_gets(t, &ap) < 0 ||
967 pa_tagstruct_get_proplist(t, i.proplist) < 0) {
968
969 pa_context_fail(o->context, PA_ERR_PROTOCOL);
970 card_info_free(&i);
971 goto finish;
972 }
973
974 if (ap) {
975 for (j = 0; j < i.n_profiles; j++)
976 if (pa_streq(i.profiles[j].name, ap)) {
977 i.active_profile = &i.profiles[j];
978 i.active_profile2 = i.profiles2[j];
979 break;
980 }
981 }
982
983 if (o->context->version >= 26) {
984 if (fill_card_port_info(o->context, t, &i) < 0)
985 goto fail;
986 }
987
988 if (o->callback) {
989 pa_card_info_cb_t cb = (pa_card_info_cb_t) o->callback;
990 cb(o->context, &i, 0, o->userdata);
991 }
992
993 card_info_free(&i);
994 }
995 }
996
997 if (o->callback) {
998 pa_card_info_cb_t cb = (pa_card_info_cb_t) o->callback;
999 cb(o->context, NULL, eol, o->userdata);
1000 }
1001
1002 finish:
1003 pa_operation_done(o);
1004 pa_operation_unref(o);
1005 return;
1006
1007 fail:
1008 pa_context_fail(o->context, PA_ERR_PROTOCOL);
1009 card_info_free(&i);
1010 goto finish;
1011 }
1012
pa_context_get_card_info_by_index(pa_context * c,uint32_t idx,pa_card_info_cb_t cb,void * userdata)1013 pa_operation* pa_context_get_card_info_by_index(pa_context *c, uint32_t idx, pa_card_info_cb_t cb, void *userdata) {
1014 pa_tagstruct *t;
1015 pa_operation *o;
1016 uint32_t tag;
1017
1018 pa_assert(c);
1019 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1020 pa_assert(cb);
1021
1022 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1023 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1024 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1025 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 15, PA_ERR_NOTSUPPORTED);
1026
1027 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1028
1029 t = pa_tagstruct_command(c, PA_COMMAND_GET_CARD_INFO, &tag);
1030 pa_tagstruct_putu32(t, idx);
1031 pa_tagstruct_puts(t, NULL);
1032 pa_pstream_send_tagstruct(c->pstream, t);
1033 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_card_info_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1034
1035 return o;
1036 }
1037
pa_context_get_card_info_by_name(pa_context * c,const char * name,pa_card_info_cb_t cb,void * userdata)1038 pa_operation* pa_context_get_card_info_by_name(pa_context *c, const char*name, pa_card_info_cb_t cb, void *userdata) {
1039 pa_tagstruct *t;
1040 pa_operation *o;
1041 uint32_t tag;
1042
1043 pa_assert(c);
1044 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1045 pa_assert(cb);
1046
1047 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1048 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1049 PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
1050 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 15, PA_ERR_NOTSUPPORTED);
1051
1052 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1053
1054 t = pa_tagstruct_command(c, PA_COMMAND_GET_CARD_INFO, &tag);
1055 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1056 pa_tagstruct_puts(t, name);
1057 pa_pstream_send_tagstruct(c->pstream, t);
1058 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_card_info_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1059
1060 return o;
1061 }
1062
pa_context_get_card_info_list(pa_context * c,pa_card_info_cb_t cb,void * userdata)1063 pa_operation* pa_context_get_card_info_list(pa_context *c, pa_card_info_cb_t cb, void *userdata) {
1064 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 15, PA_ERR_NOTSUPPORTED);
1065
1066 return pa_context_send_simple_command(c, PA_COMMAND_GET_CARD_INFO_LIST, context_get_card_info_callback, (pa_operation_cb_t) cb, userdata);
1067 }
1068
pa_context_set_card_profile_by_index(pa_context * c,uint32_t idx,const char * profile,pa_context_success_cb_t cb,void * userdata)1069 pa_operation* pa_context_set_card_profile_by_index(pa_context *c, uint32_t idx, const char*profile, pa_context_success_cb_t cb, void *userdata) {
1070 pa_operation *o;
1071 pa_tagstruct *t;
1072 uint32_t tag;
1073
1074 pa_assert(c);
1075 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1076
1077 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1078 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1079 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1080 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 15, PA_ERR_NOTSUPPORTED);
1081
1082 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1083
1084 t = pa_tagstruct_command(c, PA_COMMAND_SET_CARD_PROFILE, &tag);
1085 pa_tagstruct_putu32(t, idx);
1086 pa_tagstruct_puts(t, NULL);
1087 pa_tagstruct_puts(t, profile);
1088 pa_pstream_send_tagstruct(c->pstream, t);
1089 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1090
1091 return o;
1092 }
1093
pa_context_set_card_profile_by_name(pa_context * c,const char * name,const char * profile,pa_context_success_cb_t cb,void * userdata)1094 pa_operation* pa_context_set_card_profile_by_name(pa_context *c, const char *name, const char*profile, pa_context_success_cb_t cb, void *userdata) {
1095 pa_operation *o;
1096 pa_tagstruct *t;
1097 uint32_t tag;
1098
1099 pa_assert(c);
1100 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1101
1102 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1103 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1104 PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
1105 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 15, PA_ERR_NOTSUPPORTED);
1106
1107 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1108
1109 t = pa_tagstruct_command(c, PA_COMMAND_SET_CARD_PROFILE, &tag);
1110 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1111 pa_tagstruct_puts(t, name);
1112 pa_tagstruct_puts(t, profile);
1113 pa_pstream_send_tagstruct(c->pstream, t);
1114 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1115
1116 return o;
1117 }
1118
1119 /*** Module info ***/
1120
context_get_module_info_callback(pa_pdispatch * pd,uint32_t command,uint32_t tag,pa_tagstruct * t,void * userdata)1121 static void context_get_module_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1122 pa_operation *o = userdata;
1123 int eol = 1;
1124
1125 pa_assert(pd);
1126 pa_assert(o);
1127 pa_assert(PA_REFCNT_VALUE(o) >= 1);
1128
1129 if (!o->context)
1130 goto finish;
1131
1132 if (command != PA_COMMAND_REPLY) {
1133 if (pa_context_handle_error(o->context, command, t, false) < 0)
1134 goto finish;
1135
1136 eol = -1;
1137 } else {
1138
1139 while (!pa_tagstruct_eof(t)) {
1140 pa_module_info i;
1141 bool auto_unload = false;
1142
1143 pa_zero(i);
1144 i.proplist = pa_proplist_new();
1145
1146 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
1147 pa_tagstruct_gets(t, &i.name) < 0 ||
1148 pa_tagstruct_gets(t, &i.argument) < 0 ||
1149 pa_tagstruct_getu32(t, &i.n_used) < 0 ||
1150 (o->context->version < 15 && pa_tagstruct_get_boolean(t, &auto_unload) < 0) ||
1151 (o->context->version >= 15 && pa_tagstruct_get_proplist(t, i.proplist) < 0)) {
1152 pa_context_fail(o->context, PA_ERR_PROTOCOL);
1153 goto finish;
1154 }
1155
1156 i.auto_unload = (int) auto_unload;
1157
1158 if (o->callback) {
1159 pa_module_info_cb_t cb = (pa_module_info_cb_t) o->callback;
1160 cb(o->context, &i, 0, o->userdata);
1161 }
1162
1163 pa_proplist_free(i.proplist);
1164 }
1165 }
1166
1167 if (o->callback) {
1168 pa_module_info_cb_t cb = (pa_module_info_cb_t) o->callback;
1169 cb(o->context, NULL, eol, o->userdata);
1170 }
1171
1172 finish:
1173 pa_operation_done(o);
1174 pa_operation_unref(o);
1175 }
1176
pa_context_get_module_info(pa_context * c,uint32_t idx,pa_module_info_cb_t cb,void * userdata)1177 pa_operation* pa_context_get_module_info(pa_context *c, uint32_t idx, pa_module_info_cb_t cb, void *userdata) {
1178 pa_tagstruct *t;
1179 pa_operation *o;
1180 uint32_t tag;
1181
1182 pa_assert(c);
1183 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1184 pa_assert(cb);
1185
1186 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1187 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1188 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1189
1190 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1191
1192 t = pa_tagstruct_command(c, PA_COMMAND_GET_MODULE_INFO, &tag);
1193 pa_tagstruct_putu32(t, idx);
1194 pa_pstream_send_tagstruct(c->pstream, t);
1195 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_module_info_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1196
1197 return o;
1198 }
1199
pa_context_get_module_info_list(pa_context * c,pa_module_info_cb_t cb,void * userdata)1200 pa_operation* pa_context_get_module_info_list(pa_context *c, pa_module_info_cb_t cb, void *userdata) {
1201 return pa_context_send_simple_command(c, PA_COMMAND_GET_MODULE_INFO_LIST, context_get_module_info_callback, (pa_operation_cb_t) cb, userdata);
1202 }
1203
1204 /*** Sink input info ***/
1205
context_get_sink_input_info_callback(pa_pdispatch * pd,uint32_t command,uint32_t tag,pa_tagstruct * t,void * userdata)1206 static void context_get_sink_input_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1207 pa_operation *o = userdata;
1208 int eol = 1;
1209
1210 pa_assert(pd);
1211 pa_assert(o);
1212 pa_assert(PA_REFCNT_VALUE(o) >= 1);
1213
1214 if (!o->context)
1215 goto finish;
1216
1217 if (command != PA_COMMAND_REPLY) {
1218 if (pa_context_handle_error(o->context, command, t, false) < 0)
1219 goto finish;
1220
1221 eol = -1;
1222 } else {
1223
1224 while (!pa_tagstruct_eof(t)) {
1225 pa_sink_input_info i;
1226 bool mute = false, corked = false, has_volume = false, volume_writable = true;
1227
1228 pa_zero(i);
1229 i.proplist = pa_proplist_new();
1230 i.format = pa_format_info_new();
1231
1232 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
1233 pa_tagstruct_gets(t, &i.name) < 0 ||
1234 pa_tagstruct_getu32(t, &i.owner_module) < 0 ||
1235 pa_tagstruct_getu32(t, &i.client) < 0 ||
1236 pa_tagstruct_getu32(t, &i.sink) < 0 ||
1237 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
1238 pa_tagstruct_get_channel_map(t, &i.channel_map) < 0 ||
1239 pa_tagstruct_get_cvolume(t, &i.volume) < 0 ||
1240 pa_tagstruct_get_usec(t, &i.buffer_usec) < 0 ||
1241 pa_tagstruct_get_usec(t, &i.sink_usec) < 0 ||
1242 pa_tagstruct_gets(t, &i.resample_method) < 0 ||
1243 pa_tagstruct_gets(t, &i.driver) < 0 ||
1244 (o->context->version >= 11 && pa_tagstruct_get_boolean(t, &mute) < 0) ||
1245 (o->context->version >= 13 && pa_tagstruct_get_proplist(t, i.proplist) < 0) ||
1246 (o->context->version >= 19 && pa_tagstruct_get_boolean(t, &corked) < 0) ||
1247 (o->context->version >= 20 && (pa_tagstruct_get_boolean(t, &has_volume) < 0 ||
1248 pa_tagstruct_get_boolean(t, &volume_writable) < 0)) ||
1249 (o->context->version >= 21 && pa_tagstruct_get_format_info(t, i.format) < 0)) {
1250
1251 pa_context_fail(o->context, PA_ERR_PROTOCOL);
1252 pa_proplist_free(i.proplist);
1253 pa_format_info_free(i.format);
1254 goto finish;
1255 }
1256
1257 i.mute = (int) mute;
1258 i.corked = (int) corked;
1259 i.has_volume = (int) has_volume;
1260 i.volume_writable = (int) volume_writable;
1261
1262 if (o->callback) {
1263 pa_sink_input_info_cb_t cb = (pa_sink_input_info_cb_t) o->callback;
1264 cb(o->context, &i, 0, o->userdata);
1265 }
1266
1267 pa_proplist_free(i.proplist);
1268 pa_format_info_free(i.format);
1269 }
1270 }
1271
1272 if (o->callback) {
1273 pa_sink_input_info_cb_t cb = (pa_sink_input_info_cb_t) o->callback;
1274 cb(o->context, NULL, eol, o->userdata);
1275 }
1276
1277 finish:
1278 pa_operation_done(o);
1279 pa_operation_unref(o);
1280 }
1281
pa_context_get_sink_input_info(pa_context * c,uint32_t idx,pa_sink_input_info_cb_t cb,void * userdata)1282 pa_operation* pa_context_get_sink_input_info(pa_context *c, uint32_t idx, pa_sink_input_info_cb_t cb, void *userdata) {
1283 pa_tagstruct *t;
1284 pa_operation *o;
1285 uint32_t tag;
1286
1287 pa_assert(c);
1288 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1289 pa_assert(cb);
1290
1291 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1292 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1293 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1294
1295 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1296
1297 t = pa_tagstruct_command(c, PA_COMMAND_GET_SINK_INPUT_INFO, &tag);
1298 pa_tagstruct_putu32(t, idx);
1299 pa_pstream_send_tagstruct(c->pstream, t);
1300 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_sink_input_info_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1301
1302 return o;
1303 }
1304
pa_context_get_sink_input_info_list(pa_context * c,void (* cb)(pa_context * c,const pa_sink_input_info * i,int is_last,void * userdata),void * userdata)1305 pa_operation* pa_context_get_sink_input_info_list(pa_context *c, void (*cb)(pa_context *c, const pa_sink_input_info*i, int is_last, void *userdata), void *userdata) {
1306 return pa_context_send_simple_command(c, PA_COMMAND_GET_SINK_INPUT_INFO_LIST, context_get_sink_input_info_callback, (pa_operation_cb_t) cb, userdata);
1307 }
1308
1309 /*** Source output info ***/
1310
context_get_source_output_info_callback(pa_pdispatch * pd,uint32_t command,uint32_t tag,pa_tagstruct * t,void * userdata)1311 static void context_get_source_output_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1312 pa_operation *o = userdata;
1313 int eol = 1;
1314
1315 pa_assert(pd);
1316 pa_assert(o);
1317 pa_assert(PA_REFCNT_VALUE(o) >= 1);
1318
1319 if (!o->context)
1320 goto finish;
1321
1322 if (command != PA_COMMAND_REPLY) {
1323 if (pa_context_handle_error(o->context, command, t, false) < 0)
1324 goto finish;
1325
1326 eol = -1;
1327 } else {
1328
1329 while (!pa_tagstruct_eof(t)) {
1330 pa_source_output_info i;
1331 bool mute = false, corked = false, has_volume = false, volume_writable = true;
1332
1333 pa_zero(i);
1334 i.proplist = pa_proplist_new();
1335 i.format = pa_format_info_new();
1336
1337 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
1338 pa_tagstruct_gets(t, &i.name) < 0 ||
1339 pa_tagstruct_getu32(t, &i.owner_module) < 0 ||
1340 pa_tagstruct_getu32(t, &i.client) < 0 ||
1341 pa_tagstruct_getu32(t, &i.source) < 0 ||
1342 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
1343 pa_tagstruct_get_channel_map(t, &i.channel_map) < 0 ||
1344 pa_tagstruct_get_usec(t, &i.buffer_usec) < 0 ||
1345 pa_tagstruct_get_usec(t, &i.source_usec) < 0 ||
1346 pa_tagstruct_gets(t, &i.resample_method) < 0 ||
1347 pa_tagstruct_gets(t, &i.driver) < 0 ||
1348 (o->context->version >= 13 && pa_tagstruct_get_proplist(t, i.proplist) < 0) ||
1349 (o->context->version >= 19 && pa_tagstruct_get_boolean(t, &corked) < 0) ||
1350 (o->context->version >= 22 && (pa_tagstruct_get_cvolume(t, &i.volume) < 0 ||
1351 pa_tagstruct_get_boolean(t, &mute) < 0 ||
1352 pa_tagstruct_get_boolean(t, &has_volume) < 0 ||
1353 pa_tagstruct_get_boolean(t, &volume_writable) < 0 ||
1354 pa_tagstruct_get_format_info(t, i.format) < 0))) {
1355
1356 pa_context_fail(o->context, PA_ERR_PROTOCOL);
1357 pa_proplist_free(i.proplist);
1358 pa_format_info_free(i.format);
1359 goto finish;
1360 }
1361
1362 i.mute = (int) mute;
1363 i.corked = (int) corked;
1364 i.has_volume = (int) has_volume;
1365 i.volume_writable = (int) volume_writable;
1366
1367 if (o->callback) {
1368 pa_source_output_info_cb_t cb = (pa_source_output_info_cb_t) o->callback;
1369 cb(o->context, &i, 0, o->userdata);
1370 }
1371
1372 pa_proplist_free(i.proplist);
1373 pa_format_info_free(i.format);
1374 }
1375 }
1376
1377 if (o->callback) {
1378 pa_source_output_info_cb_t cb = (pa_source_output_info_cb_t) o->callback;
1379 cb(o->context, NULL, eol, o->userdata);
1380 }
1381
1382 finish:
1383 pa_operation_done(o);
1384 pa_operation_unref(o);
1385 }
1386
pa_context_get_source_output_info(pa_context * c,uint32_t idx,pa_source_output_info_cb_t cb,void * userdata)1387 pa_operation* pa_context_get_source_output_info(pa_context *c, uint32_t idx, pa_source_output_info_cb_t cb, void *userdata) {
1388 pa_tagstruct *t;
1389 pa_operation *o;
1390 uint32_t tag;
1391
1392 pa_assert(c);
1393 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1394 pa_assert(cb);
1395
1396 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1397 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1398 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1399
1400 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1401
1402 t = pa_tagstruct_command(c, PA_COMMAND_GET_SOURCE_OUTPUT_INFO, &tag);
1403 pa_tagstruct_putu32(t, idx);
1404 pa_pstream_send_tagstruct(c->pstream, t);
1405 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_source_output_info_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1406
1407 return o;
1408 }
1409
pa_context_get_source_output_info_list(pa_context * c,pa_source_output_info_cb_t cb,void * userdata)1410 pa_operation* pa_context_get_source_output_info_list(pa_context *c, pa_source_output_info_cb_t cb, void *userdata) {
1411 return pa_context_send_simple_command(c, PA_COMMAND_GET_SOURCE_OUTPUT_INFO_LIST, context_get_source_output_info_callback, (pa_operation_cb_t) cb, userdata);
1412 }
1413
1414 /*** Volume manipulation ***/
1415
pa_context_set_sink_volume_by_index(pa_context * c,uint32_t idx,const pa_cvolume * volume,pa_context_success_cb_t cb,void * userdata)1416 pa_operation* pa_context_set_sink_volume_by_index(pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata) {
1417 pa_operation *o;
1418 pa_tagstruct *t;
1419 uint32_t tag;
1420
1421 pa_assert(c);
1422 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1423 pa_assert(volume);
1424
1425 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1426 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1427 PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID);
1428
1429 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1430
1431 t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_VOLUME, &tag);
1432 pa_tagstruct_putu32(t, idx);
1433 pa_tagstruct_puts(t, NULL);
1434 pa_tagstruct_put_cvolume(t, volume);
1435 pa_pstream_send_tagstruct(c->pstream, t);
1436 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1437
1438 return o;
1439 }
1440
pa_context_set_sink_volume_by_name(pa_context * c,const char * name,const pa_cvolume * volume,pa_context_success_cb_t cb,void * userdata)1441 pa_operation* pa_context_set_sink_volume_by_name(pa_context *c, const char *name, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata) {
1442 pa_operation *o;
1443 pa_tagstruct *t;
1444 uint32_t tag;
1445
1446 pa_assert(c);
1447 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1448 pa_assert(name);
1449 pa_assert(volume);
1450
1451 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1452 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1453 PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID);
1454 PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
1455
1456 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1457
1458 t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_VOLUME, &tag);
1459 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1460 pa_tagstruct_puts(t, name);
1461 pa_tagstruct_put_cvolume(t, volume);
1462 pa_pstream_send_tagstruct(c->pstream, t);
1463 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1464
1465 return o;
1466 }
1467
pa_context_set_sink_mute_by_index(pa_context * c,uint32_t idx,int mute,pa_context_success_cb_t cb,void * userdata)1468 pa_operation* pa_context_set_sink_mute_by_index(pa_context *c, uint32_t idx, int mute, pa_context_success_cb_t cb, void *userdata) {
1469 pa_operation *o;
1470 pa_tagstruct *t;
1471 uint32_t tag;
1472
1473 pa_assert(c);
1474 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1475
1476 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1477 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1478
1479 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1480
1481 t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_MUTE, &tag);
1482 pa_tagstruct_putu32(t, idx);
1483 pa_tagstruct_puts(t, NULL);
1484 pa_tagstruct_put_boolean(t, mute);
1485 pa_pstream_send_tagstruct(c->pstream, t);
1486 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1487
1488 return o;
1489 }
1490
pa_context_set_sink_mute_by_name(pa_context * c,const char * name,int mute,pa_context_success_cb_t cb,void * userdata)1491 pa_operation* pa_context_set_sink_mute_by_name(pa_context *c, const char *name, int mute, pa_context_success_cb_t cb, void *userdata) {
1492 pa_operation *o;
1493 pa_tagstruct *t;
1494 uint32_t tag;
1495
1496 pa_assert(c);
1497 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1498 pa_assert(name);
1499
1500 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1501 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1502 PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
1503
1504 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1505
1506 t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_MUTE, &tag);
1507 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1508 pa_tagstruct_puts(t, name);
1509 pa_tagstruct_put_boolean(t, mute);
1510 pa_pstream_send_tagstruct(c->pstream, t);
1511 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1512
1513 return o;
1514 }
1515
pa_context_set_sink_input_volume(pa_context * c,uint32_t idx,const pa_cvolume * volume,pa_context_success_cb_t cb,void * userdata)1516 pa_operation* pa_context_set_sink_input_volume(pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata) {
1517 pa_operation *o;
1518 pa_tagstruct *t;
1519 uint32_t tag;
1520
1521 pa_assert(c);
1522 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1523 pa_assert(volume);
1524
1525 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1526 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1527 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1528 PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID);
1529
1530 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1531
1532 t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_INPUT_VOLUME, &tag);
1533 pa_tagstruct_putu32(t, idx);
1534 pa_tagstruct_put_cvolume(t, volume);
1535 pa_pstream_send_tagstruct(c->pstream, t);
1536 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1537
1538 return o;
1539 }
1540
pa_context_set_sink_input_mute(pa_context * c,uint32_t idx,int mute,pa_context_success_cb_t cb,void * userdata)1541 pa_operation* pa_context_set_sink_input_mute(pa_context *c, uint32_t idx, int mute, pa_context_success_cb_t cb, void *userdata) {
1542 pa_operation *o;
1543 pa_tagstruct *t;
1544 uint32_t tag;
1545
1546 pa_assert(c);
1547 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1548
1549 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1550 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1551 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1552 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED);
1553
1554 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1555
1556 t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_INPUT_MUTE, &tag);
1557 pa_tagstruct_putu32(t, idx);
1558 pa_tagstruct_put_boolean(t, mute);
1559 pa_pstream_send_tagstruct(c->pstream, t);
1560 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1561
1562 return o;
1563 }
1564
pa_context_set_source_volume_by_index(pa_context * c,uint32_t idx,const pa_cvolume * volume,pa_context_success_cb_t cb,void * userdata)1565 pa_operation* pa_context_set_source_volume_by_index(pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata) {
1566 pa_operation *o;
1567 pa_tagstruct *t;
1568 uint32_t tag;
1569
1570 pa_assert(c);
1571 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1572 pa_assert(volume);
1573
1574 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1575 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1576 PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID);
1577
1578 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1579
1580 t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_VOLUME, &tag);
1581 pa_tagstruct_putu32(t, idx);
1582 pa_tagstruct_puts(t, NULL);
1583 pa_tagstruct_put_cvolume(t, volume);
1584 pa_pstream_send_tagstruct(c->pstream, t);
1585 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1586
1587 return o;
1588 }
1589
pa_context_set_source_volume_by_name(pa_context * c,const char * name,const pa_cvolume * volume,pa_context_success_cb_t cb,void * userdata)1590 pa_operation* pa_context_set_source_volume_by_name(pa_context *c, const char *name, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata) {
1591 pa_operation *o;
1592 pa_tagstruct *t;
1593 uint32_t tag;
1594
1595 pa_assert(c);
1596 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1597 pa_assert(name);
1598 pa_assert(volume);
1599
1600 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1601 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1602 PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID);
1603 PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
1604
1605 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1606
1607 t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_VOLUME, &tag);
1608 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1609 pa_tagstruct_puts(t, name);
1610 pa_tagstruct_put_cvolume(t, volume);
1611 pa_pstream_send_tagstruct(c->pstream, t);
1612 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1613
1614 return o;
1615 }
1616
pa_context_set_source_mute_by_index(pa_context * c,uint32_t idx,int mute,pa_context_success_cb_t cb,void * userdata)1617 pa_operation* pa_context_set_source_mute_by_index(pa_context *c, uint32_t idx, int mute, pa_context_success_cb_t cb, void *userdata) {
1618 pa_operation *o;
1619 pa_tagstruct *t;
1620 uint32_t tag;
1621
1622 pa_assert(c);
1623 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1624
1625 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1626 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1627
1628 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1629
1630 t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_MUTE, &tag);
1631 pa_tagstruct_putu32(t, idx);
1632 pa_tagstruct_puts(t, NULL);
1633 pa_tagstruct_put_boolean(t, mute);
1634 pa_pstream_send_tagstruct(c->pstream, t);
1635 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1636
1637 return o;
1638 }
1639
pa_context_set_source_mute_by_name(pa_context * c,const char * name,int mute,pa_context_success_cb_t cb,void * userdata)1640 pa_operation* pa_context_set_source_mute_by_name(pa_context *c, const char *name, int mute, pa_context_success_cb_t cb, void *userdata) {
1641 pa_operation *o;
1642 pa_tagstruct *t;
1643 uint32_t tag;
1644
1645 pa_assert(c);
1646 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1647 pa_assert(name);
1648
1649 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1650 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1651 PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
1652
1653 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1654
1655 t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_MUTE, &tag);
1656 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1657 pa_tagstruct_puts(t, name);
1658 pa_tagstruct_put_boolean(t, mute);
1659 pa_pstream_send_tagstruct(c->pstream, t);
1660 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1661
1662 return o;
1663 }
1664
pa_context_set_source_output_volume(pa_context * c,uint32_t idx,const pa_cvolume * volume,pa_context_success_cb_t cb,void * userdata)1665 pa_operation* pa_context_set_source_output_volume(pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata) {
1666 pa_operation *o;
1667 pa_tagstruct *t;
1668 uint32_t tag;
1669
1670 pa_assert(c);
1671 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1672 pa_assert(volume);
1673
1674 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1675 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1676 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1677 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 22, PA_ERR_NOTSUPPORTED);
1678 PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID);
1679
1680 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1681
1682 t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_OUTPUT_VOLUME, &tag);
1683 pa_tagstruct_putu32(t, idx);
1684 pa_tagstruct_put_cvolume(t, volume);
1685 pa_pstream_send_tagstruct(c->pstream, t);
1686 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1687
1688 return o;
1689 }
1690
pa_context_set_source_output_mute(pa_context * c,uint32_t idx,int mute,pa_context_success_cb_t cb,void * userdata)1691 pa_operation* pa_context_set_source_output_mute(pa_context *c, uint32_t idx, int mute, pa_context_success_cb_t cb, void *userdata) {
1692 pa_operation *o;
1693 pa_tagstruct *t;
1694 uint32_t tag;
1695
1696 pa_assert(c);
1697 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1698
1699 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1700 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1701 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1702 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 22, PA_ERR_NOTSUPPORTED);
1703
1704 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1705
1706 t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_OUTPUT_MUTE, &tag);
1707 pa_tagstruct_putu32(t, idx);
1708 pa_tagstruct_put_boolean(t, mute);
1709 pa_pstream_send_tagstruct(c->pstream, t);
1710 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1711
1712 return o;
1713 }
1714
1715 /** Sample Cache **/
1716
context_get_sample_info_callback(pa_pdispatch * pd,uint32_t command,uint32_t tag,pa_tagstruct * t,void * userdata)1717 static void context_get_sample_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1718 pa_operation *o = userdata;
1719 int eol = 1;
1720
1721 pa_assert(pd);
1722 pa_assert(o);
1723 pa_assert(PA_REFCNT_VALUE(o) >= 1);
1724
1725 if (!o->context)
1726 goto finish;
1727
1728 if (command != PA_COMMAND_REPLY) {
1729 if (pa_context_handle_error(o->context, command, t, false) < 0)
1730 goto finish;
1731
1732 eol = -1;
1733 } else {
1734
1735 while (!pa_tagstruct_eof(t)) {
1736 pa_sample_info i;
1737 bool lazy = false;
1738
1739 pa_zero(i);
1740 i.proplist = pa_proplist_new();
1741
1742 if (pa_tagstruct_getu32(t, &i.index) < 0 ||
1743 pa_tagstruct_gets(t, &i.name) < 0 ||
1744 pa_tagstruct_get_cvolume(t, &i.volume) < 0 ||
1745 pa_tagstruct_get_usec(t, &i.duration) < 0 ||
1746 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 ||
1747 pa_tagstruct_get_channel_map(t, &i.channel_map) < 0 ||
1748 pa_tagstruct_getu32(t, &i.bytes) < 0 ||
1749 pa_tagstruct_get_boolean(t, &lazy) < 0 ||
1750 pa_tagstruct_gets(t, &i.filename) < 0 ||
1751 (o->context->version >= 13 && pa_tagstruct_get_proplist(t, i.proplist) < 0)) {
1752
1753 pa_context_fail(o->context, PA_ERR_PROTOCOL);
1754 goto finish;
1755 }
1756
1757 i.lazy = (int) lazy;
1758
1759 if (o->callback) {
1760 pa_sample_info_cb_t cb = (pa_sample_info_cb_t) o->callback;
1761 cb(o->context, &i, 0, o->userdata);
1762 }
1763
1764 pa_proplist_free(i.proplist);
1765 }
1766 }
1767
1768 if (o->callback) {
1769 pa_sample_info_cb_t cb = (pa_sample_info_cb_t) o->callback;
1770 cb(o->context, NULL, eol, o->userdata);
1771 }
1772
1773 finish:
1774 pa_operation_done(o);
1775 pa_operation_unref(o);
1776 }
1777
pa_context_get_sample_info_by_name(pa_context * c,const char * name,pa_sample_info_cb_t cb,void * userdata)1778 pa_operation* pa_context_get_sample_info_by_name(pa_context *c, const char *name, pa_sample_info_cb_t cb, void *userdata) {
1779 pa_tagstruct *t;
1780 pa_operation *o;
1781 uint32_t tag;
1782
1783 pa_assert(c);
1784 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1785 pa_assert(cb);
1786
1787 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1788 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1789 PA_CHECK_VALIDITY_RETURN_NULL(c, name && *name, PA_ERR_INVALID);
1790
1791 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1792
1793 t = pa_tagstruct_command(c, PA_COMMAND_GET_SAMPLE_INFO, &tag);
1794 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1795 pa_tagstruct_puts(t, name);
1796 pa_pstream_send_tagstruct(c->pstream, t);
1797 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_sample_info_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1798
1799 return o;
1800 }
1801
pa_context_get_sample_info_by_index(pa_context * c,uint32_t idx,pa_sample_info_cb_t cb,void * userdata)1802 pa_operation* pa_context_get_sample_info_by_index(pa_context *c, uint32_t idx, pa_sample_info_cb_t cb, void *userdata) {
1803 pa_tagstruct *t;
1804 pa_operation *o;
1805 uint32_t tag;
1806
1807 pa_assert(c);
1808 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1809 pa_assert(cb);
1810
1811 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1812 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1813 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1814
1815 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1816
1817 t = pa_tagstruct_command(c, PA_COMMAND_GET_SAMPLE_INFO, &tag);
1818 pa_tagstruct_putu32(t, idx);
1819 pa_tagstruct_puts(t, NULL);
1820 pa_pstream_send_tagstruct(c->pstream, t);
1821 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_sample_info_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1822
1823 return o;
1824 }
1825
pa_context_get_sample_info_list(pa_context * c,pa_sample_info_cb_t cb,void * userdata)1826 pa_operation* pa_context_get_sample_info_list(pa_context *c, pa_sample_info_cb_t cb, void *userdata) {
1827 return pa_context_send_simple_command(c, PA_COMMAND_GET_SAMPLE_INFO_LIST, context_get_sample_info_callback, (pa_operation_cb_t) cb, userdata);
1828 }
1829
command_kill(pa_context * c,uint32_t command,uint32_t idx,pa_context_success_cb_t cb,void * userdata)1830 static pa_operation* command_kill(pa_context *c, uint32_t command, uint32_t idx, pa_context_success_cb_t cb, void *userdata) {
1831 pa_operation *o;
1832 pa_tagstruct *t;
1833 uint32_t tag;
1834
1835 pa_assert(c);
1836 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1837
1838 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1839 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1840 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
1841
1842 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1843
1844 t = pa_tagstruct_command(c, command, &tag);
1845 pa_tagstruct_putu32(t, idx);
1846 pa_pstream_send_tagstruct(c->pstream, t);
1847 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1848
1849 return o;
1850 }
1851
pa_context_kill_client(pa_context * c,uint32_t idx,pa_context_success_cb_t cb,void * userdata)1852 pa_operation* pa_context_kill_client(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata) {
1853 return command_kill(c, PA_COMMAND_KILL_CLIENT, idx, cb, userdata);
1854 }
1855
pa_context_kill_sink_input(pa_context * c,uint32_t idx,pa_context_success_cb_t cb,void * userdata)1856 pa_operation* pa_context_kill_sink_input(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata) {
1857 return command_kill(c, PA_COMMAND_KILL_SINK_INPUT, idx, cb, userdata);
1858 }
1859
pa_context_kill_source_output(pa_context * c,uint32_t idx,pa_context_success_cb_t cb,void * userdata)1860 pa_operation* pa_context_kill_source_output(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata) {
1861 return command_kill(c, PA_COMMAND_KILL_SOURCE_OUTPUT, idx, cb, userdata);
1862 }
1863
context_index_callback(pa_pdispatch * pd,uint32_t command,uint32_t tag,pa_tagstruct * t,void * userdata)1864 static void context_index_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
1865 pa_operation *o = userdata;
1866 uint32_t idx;
1867
1868 pa_assert(pd);
1869 pa_assert(o);
1870 pa_assert(PA_REFCNT_VALUE(o) >= 1);
1871
1872 if (!o->context)
1873 goto finish;
1874
1875 if (command != PA_COMMAND_REPLY) {
1876 if (pa_context_handle_error(o->context, command, t, false) < 0)
1877 goto finish;
1878
1879 idx = PA_INVALID_INDEX;
1880 } else if (pa_tagstruct_getu32(t, &idx) ||
1881 !pa_tagstruct_eof(t)) {
1882 pa_context_fail(o->context, PA_ERR_PROTOCOL);
1883 goto finish;
1884 }
1885
1886 if (o->callback) {
1887 pa_context_index_cb_t cb = (pa_context_index_cb_t) o->callback;
1888 cb(o->context, idx, o->userdata);
1889 }
1890
1891 finish:
1892 pa_operation_done(o);
1893 pa_operation_unref(o);
1894 }
1895
pa_context_load_module(pa_context * c,const char * name,const char * argument,pa_context_index_cb_t cb,void * userdata)1896 pa_operation* pa_context_load_module(pa_context *c, const char*name, const char *argument, pa_context_index_cb_t cb, void *userdata) {
1897 pa_operation *o;
1898 pa_tagstruct *t;
1899 uint32_t tag;
1900
1901 pa_assert(c);
1902 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1903
1904 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1905 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1906 PA_CHECK_VALIDITY_RETURN_NULL(c, name && *name, PA_ERR_INVALID);
1907
1908 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1909
1910 t = pa_tagstruct_command(c, PA_COMMAND_LOAD_MODULE, &tag);
1911 pa_tagstruct_puts(t, name);
1912 pa_tagstruct_puts(t, argument);
1913 pa_pstream_send_tagstruct(c->pstream, t);
1914 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_index_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1915
1916 return o;
1917 }
1918
pa_context_unload_module(pa_context * c,uint32_t idx,pa_context_success_cb_t cb,void * userdata)1919 pa_operation* pa_context_unload_module(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata) {
1920 return command_kill(c, PA_COMMAND_UNLOAD_MODULE, idx, cb, userdata);
1921 }
1922
pa_context_set_port_latency_offset(pa_context * c,const char * card_name,const char * port_name,int64_t offset,pa_context_success_cb_t cb,void * userdata)1923 pa_operation* pa_context_set_port_latency_offset(pa_context *c, const char *card_name, const char *port_name, int64_t offset, pa_context_success_cb_t cb, void *userdata) {
1924 pa_operation *o;
1925 pa_tagstruct *t;
1926 uint32_t tag;
1927
1928 pa_assert(c);
1929 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1930
1931 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
1932 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
1933 PA_CHECK_VALIDITY_RETURN_NULL(c, card_name && *card_name, PA_ERR_INVALID);
1934 PA_CHECK_VALIDITY_RETURN_NULL(c, port_name && *port_name, PA_ERR_INVALID);
1935 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 27, PA_ERR_NOTSUPPORTED);
1936
1937 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
1938
1939 t = pa_tagstruct_command(c, PA_COMMAND_SET_PORT_LATENCY_OFFSET, &tag);
1940 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
1941 pa_tagstruct_puts(t, card_name);
1942 pa_tagstruct_puts(t, port_name);
1943 pa_tagstruct_puts64(t, offset);
1944 pa_pstream_send_tagstruct(c->pstream, t);
1945 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
1946
1947 return o;
1948 }
1949
1950 /*** Autoload stuff ***/
1951
1952 PA_WARN_REFERENCE(pa_context_get_autoload_info_by_name, "Module auto-loading no longer supported.");
1953
pa_context_get_autoload_info_by_name(pa_context * c,const char * name,pa_autoload_type_t type,pa_autoload_info_cb_t cb,void * userdata)1954 pa_operation* pa_context_get_autoload_info_by_name(pa_context *c, const char *name, pa_autoload_type_t type, pa_autoload_info_cb_t cb, void *userdata) {
1955
1956 pa_assert(c);
1957 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1958
1959 PA_FAIL_RETURN_NULL(c, PA_ERR_OBSOLETE);
1960 }
1961
1962 PA_WARN_REFERENCE(pa_context_get_autoload_info_by_index, "Module auto-loading no longer supported.");
1963
pa_context_get_autoload_info_by_index(pa_context * c,uint32_t idx,pa_autoload_info_cb_t cb,void * userdata)1964 pa_operation* pa_context_get_autoload_info_by_index(pa_context *c, uint32_t idx, pa_autoload_info_cb_t cb, void *userdata) {
1965 pa_assert(c);
1966 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1967
1968 PA_FAIL_RETURN_NULL(c, PA_ERR_OBSOLETE);
1969 }
1970
1971 PA_WARN_REFERENCE(pa_context_get_autoload_info_list, "Module auto-loading no longer supported.");
1972
pa_context_get_autoload_info_list(pa_context * c,pa_autoload_info_cb_t cb,void * userdata)1973 pa_operation* pa_context_get_autoload_info_list(pa_context *c, pa_autoload_info_cb_t cb, void *userdata) {
1974 pa_assert(c);
1975 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1976
1977 PA_FAIL_RETURN_NULL(c, PA_ERR_OBSOLETE);
1978 }
1979
1980 PA_WARN_REFERENCE(pa_context_add_autoload, "Module auto-loading no longer supported.");
1981
pa_context_add_autoload(pa_context * c,const char * name,pa_autoload_type_t type,const char * module,const char * argument,pa_context_index_cb_t cb,void * userdata)1982 pa_operation* pa_context_add_autoload(pa_context *c, const char *name, pa_autoload_type_t type, const char *module, const char*argument, pa_context_index_cb_t cb, void* userdata) {
1983 pa_assert(c);
1984 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1985
1986 PA_FAIL_RETURN_NULL(c, PA_ERR_OBSOLETE);
1987 }
1988
1989 PA_WARN_REFERENCE(pa_context_remove_autoload_by_name, "Module auto-loading no longer supported.");
1990
pa_context_remove_autoload_by_name(pa_context * c,const char * name,pa_autoload_type_t type,pa_context_success_cb_t cb,void * userdata)1991 pa_operation* pa_context_remove_autoload_by_name(pa_context *c, const char *name, pa_autoload_type_t type, pa_context_success_cb_t cb, void* userdata) {
1992 pa_assert(c);
1993 pa_assert(PA_REFCNT_VALUE(c) >= 1);
1994
1995 PA_FAIL_RETURN_NULL(c, PA_ERR_OBSOLETE);
1996 }
1997
1998 PA_WARN_REFERENCE(pa_context_remove_autoload_by_index, "Module auto-loading no longer supported.");
1999
pa_context_remove_autoload_by_index(pa_context * c,uint32_t idx,pa_context_success_cb_t cb,void * userdata)2000 pa_operation* pa_context_remove_autoload_by_index(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void* userdata) {
2001 pa_assert(c);
2002 pa_assert(PA_REFCNT_VALUE(c) >= 1);
2003
2004 PA_FAIL_RETURN_NULL(c, PA_ERR_OBSOLETE);
2005 }
2006
pa_context_move_sink_input_by_name(pa_context * c,uint32_t idx,const char * sink_name,pa_context_success_cb_t cb,void * userdata)2007 pa_operation* pa_context_move_sink_input_by_name(pa_context *c, uint32_t idx, const char *sink_name, pa_context_success_cb_t cb, void* userdata) {
2008 pa_operation *o;
2009 pa_tagstruct *t;
2010 uint32_t tag;
2011
2012 pa_assert(c);
2013 pa_assert(PA_REFCNT_VALUE(c) >= 1);
2014
2015 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
2016 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
2017 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 10, PA_ERR_NOTSUPPORTED);
2018 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
2019 PA_CHECK_VALIDITY_RETURN_NULL(c, sink_name && *sink_name, PA_ERR_INVALID);
2020
2021 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
2022
2023 t = pa_tagstruct_command(c, PA_COMMAND_MOVE_SINK_INPUT, &tag);
2024 pa_tagstruct_putu32(t, idx);
2025 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
2026 pa_tagstruct_puts(t, sink_name);
2027 pa_pstream_send_tagstruct(c->pstream, t);
2028 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
2029
2030 return o;
2031 }
2032
pa_context_move_sink_input_by_index(pa_context * c,uint32_t idx,uint32_t sink_idx,pa_context_success_cb_t cb,void * userdata)2033 pa_operation* pa_context_move_sink_input_by_index(pa_context *c, uint32_t idx, uint32_t sink_idx, pa_context_success_cb_t cb, void* userdata) {
2034 pa_operation *o;
2035 pa_tagstruct *t;
2036 uint32_t tag;
2037
2038 pa_assert(c);
2039 pa_assert(PA_REFCNT_VALUE(c) >= 1);
2040
2041 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
2042 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
2043 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 10, PA_ERR_NOTSUPPORTED);
2044 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
2045 PA_CHECK_VALIDITY_RETURN_NULL(c, sink_idx != PA_INVALID_INDEX, PA_ERR_INVALID);
2046
2047 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
2048
2049 t = pa_tagstruct_command(c, PA_COMMAND_MOVE_SINK_INPUT, &tag);
2050 pa_tagstruct_putu32(t, idx);
2051 pa_tagstruct_putu32(t, sink_idx);
2052 pa_tagstruct_puts(t, NULL);
2053 pa_pstream_send_tagstruct(c->pstream, t);
2054 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
2055
2056 return o;
2057 }
2058
pa_context_move_source_output_by_name(pa_context * c,uint32_t idx,const char * source_name,pa_context_success_cb_t cb,void * userdata)2059 pa_operation* pa_context_move_source_output_by_name(pa_context *c, uint32_t idx, const char *source_name, pa_context_success_cb_t cb, void* userdata) {
2060 pa_operation *o;
2061 pa_tagstruct *t;
2062 uint32_t tag;
2063
2064 pa_assert(c);
2065 pa_assert(PA_REFCNT_VALUE(c) >= 1);
2066
2067 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
2068 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
2069 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 10, PA_ERR_NOTSUPPORTED);
2070 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
2071 PA_CHECK_VALIDITY_RETURN_NULL(c, source_name && *source_name, PA_ERR_INVALID);
2072
2073 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
2074
2075 t = pa_tagstruct_command(c, PA_COMMAND_MOVE_SOURCE_OUTPUT, &tag);
2076 pa_tagstruct_putu32(t, idx);
2077 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
2078 pa_tagstruct_puts(t, source_name);
2079 pa_pstream_send_tagstruct(c->pstream, t);
2080 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
2081
2082 return o;
2083 }
2084
pa_context_move_source_output_by_index(pa_context * c,uint32_t idx,uint32_t source_idx,pa_context_success_cb_t cb,void * userdata)2085 pa_operation* pa_context_move_source_output_by_index(pa_context *c, uint32_t idx, uint32_t source_idx, pa_context_success_cb_t cb, void* userdata) {
2086 pa_operation *o;
2087 pa_tagstruct *t;
2088 uint32_t tag;
2089
2090 pa_assert(c);
2091 pa_assert(PA_REFCNT_VALUE(c) >= 1);
2092
2093 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
2094 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
2095 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 10, PA_ERR_NOTSUPPORTED);
2096 PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
2097 PA_CHECK_VALIDITY_RETURN_NULL(c, source_idx != PA_INVALID_INDEX, PA_ERR_INVALID);
2098
2099 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
2100
2101 t = pa_tagstruct_command(c, PA_COMMAND_MOVE_SOURCE_OUTPUT, &tag);
2102 pa_tagstruct_putu32(t, idx);
2103 pa_tagstruct_putu32(t, source_idx);
2104 pa_tagstruct_puts(t, NULL);
2105 pa_pstream_send_tagstruct(c->pstream, t);
2106 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
2107
2108 return o;
2109 }
2110
pa_context_suspend_sink_by_name(pa_context * c,const char * sink_name,int suspend,pa_context_success_cb_t cb,void * userdata)2111 pa_operation* pa_context_suspend_sink_by_name(pa_context *c, const char *sink_name, int suspend, pa_context_success_cb_t cb, void* userdata) {
2112 pa_operation *o;
2113 pa_tagstruct *t;
2114 uint32_t tag;
2115
2116 pa_assert(c);
2117 pa_assert(PA_REFCNT_VALUE(c) >= 1);
2118
2119 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
2120 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
2121 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED);
2122 PA_CHECK_VALIDITY_RETURN_NULL(c, !sink_name || *sink_name, PA_ERR_INVALID);
2123
2124 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
2125
2126 t = pa_tagstruct_command(c, PA_COMMAND_SUSPEND_SINK, &tag);
2127 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
2128 pa_tagstruct_puts(t, sink_name);
2129 pa_tagstruct_put_boolean(t, suspend);
2130 pa_pstream_send_tagstruct(c->pstream, t);
2131 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
2132
2133 return o;
2134 }
2135
pa_context_suspend_sink_by_index(pa_context * c,uint32_t idx,int suspend,pa_context_success_cb_t cb,void * userdata)2136 pa_operation* pa_context_suspend_sink_by_index(pa_context *c, uint32_t idx, int suspend, pa_context_success_cb_t cb, void* userdata) {
2137 pa_operation *o;
2138 pa_tagstruct *t;
2139 uint32_t tag;
2140
2141 pa_assert(c);
2142 pa_assert(PA_REFCNT_VALUE(c) >= 1);
2143
2144 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
2145 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
2146 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED);
2147
2148 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
2149
2150 t = pa_tagstruct_command(c, PA_COMMAND_SUSPEND_SINK, &tag);
2151 pa_tagstruct_putu32(t, idx);
2152 pa_tagstruct_puts(t, idx == PA_INVALID_INDEX ? "" : NULL);
2153 pa_tagstruct_put_boolean(t, suspend);
2154 pa_pstream_send_tagstruct(c->pstream, t);
2155 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
2156
2157 return o;
2158 }
2159
pa_context_suspend_source_by_name(pa_context * c,const char * source_name,int suspend,pa_context_success_cb_t cb,void * userdata)2160 pa_operation* pa_context_suspend_source_by_name(pa_context *c, const char *source_name, int suspend, pa_context_success_cb_t cb, void* userdata) {
2161 pa_operation *o;
2162 pa_tagstruct *t;
2163 uint32_t tag;
2164
2165 pa_assert(c);
2166 pa_assert(PA_REFCNT_VALUE(c) >= 1);
2167
2168 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
2169 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
2170 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED);
2171 PA_CHECK_VALIDITY_RETURN_NULL(c, !source_name || *source_name, PA_ERR_INVALID);
2172
2173 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
2174
2175 t = pa_tagstruct_command(c, PA_COMMAND_SUSPEND_SOURCE, &tag);
2176 pa_tagstruct_putu32(t, PA_INVALID_INDEX);
2177 pa_tagstruct_puts(t, source_name);
2178 pa_tagstruct_put_boolean(t, suspend);
2179 pa_pstream_send_tagstruct(c->pstream, t);
2180 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
2181
2182 return o;
2183 }
2184
pa_context_suspend_source_by_index(pa_context * c,uint32_t idx,int suspend,pa_context_success_cb_t cb,void * userdata)2185 pa_operation* pa_context_suspend_source_by_index(pa_context *c, uint32_t idx, int suspend, pa_context_success_cb_t cb, void* userdata) {
2186 pa_operation *o;
2187 pa_tagstruct *t;
2188 uint32_t tag;
2189
2190 pa_assert(c);
2191 pa_assert(PA_REFCNT_VALUE(c) >= 1);
2192
2193 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
2194 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
2195 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED);
2196
2197 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
2198
2199 t = pa_tagstruct_command(c, PA_COMMAND_SUSPEND_SOURCE, &tag);
2200 pa_tagstruct_putu32(t, idx);
2201 pa_tagstruct_puts(t, idx == PA_INVALID_INDEX ? "" : NULL);
2202 pa_tagstruct_put_boolean(t, suspend);
2203 pa_pstream_send_tagstruct(c->pstream, t);
2204 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
2205
2206 return o;
2207 }
2208
2209 /** Object response string processing **/
2210
context_string_callback(pa_pdispatch * pd,uint32_t command,uint32_t tag,pa_tagstruct * t,void * userdata)2211 static void context_string_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
2212 pa_operation *o = userdata;
2213 const char *response;
2214 int success = 1;
2215
2216 pa_assert(pd);
2217 pa_assert(o);
2218 pa_assert(PA_REFCNT_VALUE(o) >= 1);
2219
2220 if (!o->context)
2221 goto finish;
2222
2223 if (command != PA_COMMAND_REPLY) {
2224 if (pa_context_handle_error(o->context, command, t, false) < 0)
2225 goto finish;
2226
2227 success = 0;
2228 response = "";
2229 } else if (pa_tagstruct_gets(t, &response) < 0 ||
2230 !pa_tagstruct_eof(t)) {
2231 pa_context_fail(o->context, PA_ERR_PROTOCOL);
2232 goto finish;
2233 }
2234
2235 if (!response)
2236 response = "";
2237
2238 if (o->callback) {
2239 char *response_copy;
2240 pa_context_string_cb_t cb;
2241
2242 response_copy = pa_xstrdup(response);
2243
2244 cb = (pa_context_string_cb_t) o->callback;
2245 cb(o->context, success, response_copy, o->userdata);
2246
2247 pa_xfree(response_copy);
2248 }
2249
2250 finish:
2251 pa_operation_done(o);
2252 pa_operation_unref(o);
2253 }
2254
pa_context_send_message_to_object(pa_context * c,const char * object_path,const char * message,const char * message_parameters,pa_context_string_cb_t cb,void * userdata)2255 pa_operation* pa_context_send_message_to_object(pa_context *c, const char *object_path, const char *message, const char *message_parameters, pa_context_string_cb_t cb, void *userdata) {
2256 pa_operation *o;
2257 pa_tagstruct *t;
2258 uint32_t tag;
2259
2260 pa_assert(c);
2261 pa_assert(PA_REFCNT_VALUE(c) >= 1);
2262
2263 PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
2264 PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
2265 PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 35, PA_ERR_NOTSUPPORTED);
2266
2267 o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
2268
2269 t = pa_tagstruct_command(c, PA_COMMAND_SEND_OBJECT_MESSAGE, &tag);
2270
2271 pa_tagstruct_puts(t, object_path);
2272 pa_tagstruct_puts(t, message);
2273 pa_tagstruct_puts(t, message_parameters);
2274
2275 pa_pstream_send_tagstruct(c->pstream, t);
2276 pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_string_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
2277
2278 return o;
2279 }
2280