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 39static 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 72finish: 73 pa_operation_done(o); 74 pa_operation_unref(o); 75} 76 77pa_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 83static 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 125finish: 126 pa_operation_done(o); 127 pa_operation_unref(o); 128} 129 130pa_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 136static 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 289finish: 290 pa_operation_done(o); 291 pa_operation_unref(o); 292 return; 293 294fail: 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 313pa_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 317pa_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 340pa_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 364pa_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 389pa_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 416static 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 568finish: 569 pa_operation_done(o); 570 pa_operation_unref(o); 571 return; 572 573fail: 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 592pa_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 596pa_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 619pa_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 643pa_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 668pa_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 695static 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 744finish: 745 pa_operation_done(o); 746 pa_operation_unref(o); 747} 748 749pa_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 772pa_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 778static 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 812static 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 892static 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 927static 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 1002finish: 1003 pa_operation_done(o); 1004 pa_operation_unref(o); 1005 return; 1006 1007fail: 1008 pa_context_fail(o->context, PA_ERR_PROTOCOL); 1009 card_info_free(&i); 1010 goto finish; 1011} 1012 1013pa_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 1038pa_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 1063pa_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 1069pa_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 1094pa_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 1121static 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 1172finish: 1173 pa_operation_done(o); 1174 pa_operation_unref(o); 1175} 1176 1177pa_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 1200pa_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 1206static 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 1277finish: 1278 pa_operation_done(o); 1279 pa_operation_unref(o); 1280} 1281 1282pa_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 1305pa_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 1311static 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 1382finish: 1383 pa_operation_done(o); 1384 pa_operation_unref(o); 1385} 1386 1387pa_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 1410pa_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 1416pa_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 1441pa_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 1468pa_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 1491pa_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 1516pa_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 1541pa_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 1565pa_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 1590pa_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 1617pa_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 1640pa_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 1665pa_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 1691pa_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 1717static 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 1773finish: 1774 pa_operation_done(o); 1775 pa_operation_unref(o); 1776} 1777 1778pa_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 1802pa_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 1826pa_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 1830static 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 1852pa_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 1856pa_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 1860pa_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 1864static 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 1891finish: 1892 pa_operation_done(o); 1893 pa_operation_unref(o); 1894} 1895 1896pa_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 1919pa_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 1923pa_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 1952PA_WARN_REFERENCE(pa_context_get_autoload_info_by_name, "Module auto-loading no longer supported."); 1953 1954pa_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 1962PA_WARN_REFERENCE(pa_context_get_autoload_info_by_index, "Module auto-loading no longer supported."); 1963 1964pa_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 1971PA_WARN_REFERENCE(pa_context_get_autoload_info_list, "Module auto-loading no longer supported."); 1972 1973pa_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 1980PA_WARN_REFERENCE(pa_context_add_autoload, "Module auto-loading no longer supported."); 1981 1982pa_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 1989PA_WARN_REFERENCE(pa_context_remove_autoload_by_name, "Module auto-loading no longer supported."); 1990 1991pa_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 1998PA_WARN_REFERENCE(pa_context_remove_autoload_by_index, "Module auto-loading no longer supported."); 1999 2000pa_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 2007pa_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 2033pa_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 2059pa_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 2085pa_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 2111pa_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 2136pa_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 2160pa_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 2185pa_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 2211static 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 2250finish: 2251 pa_operation_done(o); 2252 pa_operation_unref(o); 2253} 2254 2255pa_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