4 This file is part of polypaudio.
6 polypaudio is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published
8 by the Free Software Foundation; either version 2 of the License,
9 or (at your option) any later version.
11 polypaudio is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with polypaudio; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
30 #include <sys/types.h>
31 #include <sys/socket.h>
35 #include "native-common.h"
36 #include "pdispatch.h"
39 #include "socket-client.h"
40 #include "pstream-util.h"
45 #define DEFAULT_MAXLENGTH 204800
46 #define DEFAULT_TLENGTH 10240
47 #define DEFAULT_PREBUF 4096
48 #define DEFAULT_MINREQ 1024
49 #define DEFAULT_FRAGSIZE 1024
51 #define DEFAULT_TIMEOUT (5*60)
52 #define DEFAULT_SERVER "/tmp/polypaudio/native"
53 #define DEFAULT_PORT "4713"
57 struct pa_mainloop_api
* mainloop
;
58 struct pa_socket_client
*client
;
59 struct pa_pstream
*pstream
;
60 struct pa_pdispatch
*pdispatch
;
61 struct pa_dynarray
*record_streams
, *playback_streams
;
62 struct pa_stream
*first_stream
;
74 void (*connect_complete_callback
)(struct pa_context
*c
, int success
, void *userdata
);
75 void *connect_complete_userdata
;
77 void (*drain_complete_callback
)(struct pa_context
*c
, void *userdata
);
78 void *drain_complete_userdata
;
80 void (*die_callback
)(struct pa_context
*c
, void *userdata
);
83 void (*stat_callback
)(struct pa_context
*c
, uint32_t count
, uint32_t total
, void *userdata
);
86 void (*play_sample_callback
)(struct pa_context
*c
, int success
, void *userdata
);
87 void *play_sample_userdata
;
89 void (*remove_sample_callback
)(struct pa_context
*c
, int success
, void *userdata
);
90 void *remove_sample_userdata
;
92 void (*get_server_info_callback
)(struct pa_context
*c
, const struct pa_server_info
* i
, void *userdata
);
93 void *get_server_info_userdata
;
95 void (*get_sink_info_callback
)(struct pa_context
*c
, const struct pa_sink_info
* i
, int is_last
, void *userdata
);
96 void *get_sink_info_userdata
;
98 void (*get_source_info_callback
)(struct pa_context
*c
, const struct pa_source_info
* i
, int is_last
, void *userdata
);
99 void *get_source_info_userdata
;
101 void (*subscribe_callback
)(struct pa_context
*c
, enum pa_subscription_event_type t
, uint32_t index
, void *userdata
);
102 void *subscribe_userdata
;
103 enum pa_subscription_mask subscribe_mask
;
105 void (*get_client_info_callback
)(struct pa_context
*c
, const struct pa_client_info
* i
, int is_last
, void *userdata
);
106 void *get_client_info_userdata
;
108 void (*get_module_info_callback
)(struct pa_context
*c
, const struct pa_module_info
* i
, int is_last
, void *userdata
);
109 void *get_module_info_userdata
;
111 uint8_t auth_cookie
[PA_NATIVE_COOKIE_LENGTH
];
115 struct pa_context
*context
;
116 struct pa_stream
*next
, *previous
;
119 struct pa_buffer_attr buffer_attr
;
120 struct pa_sample_spec sample_spec
;
123 uint32_t device_index
;
124 enum pa_stream_direction direction
;
126 enum { STREAM_CREATING
, STREAM_READY
, STREAM_DEAD
} state
;
127 uint32_t requested_bytes
;
129 void (*read_callback
)(struct pa_stream
*p
, const void*data
, size_t length
, void *userdata
);
132 void (*write_callback
)(struct pa_stream
*p
, size_t length
, void *userdata
);
133 void *write_userdata
;
135 void (*create_complete_callback
)(struct pa_stream
*s
, int success
, void *userdata
);
136 void *create_complete_userdata
;
138 void (*drain_complete_callback
)(struct pa_stream
*s
, void *userdata
);
139 void *drain_complete_userdata
;
141 void (*die_callback
)(struct pa_stream
*c
, void *userdata
);
144 void (*get_latency_callback
)(struct pa_stream
*c
, uint32_t latency
, void *userdata
);
145 void *get_latency_userdata
;
147 void (*finish_sample_callback
)(struct pa_stream
*c
, int success
, void *userdata
);
148 void *finish_sample_userdata
;
151 static void command_request(struct pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, struct pa_tagstruct
*t
, void *userdata
);
152 static void command_playback_stream_killed(struct pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, struct pa_tagstruct
*t
, void *userdata
);
153 static void command_subscribe_event(struct pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, struct pa_tagstruct
*t
, void *userdata
);
155 static const struct pa_pdispatch_command command_table
[PA_COMMAND_MAX
] = {
156 [PA_COMMAND_ERROR
] = { NULL
},
157 [PA_COMMAND_REPLY
] = { NULL
},
158 [PA_COMMAND_CREATE_PLAYBACK_STREAM
] = { NULL
},
159 [PA_COMMAND_DELETE_PLAYBACK_STREAM
] = { NULL
},
160 [PA_COMMAND_CREATE_RECORD_STREAM
] = { NULL
},
161 [PA_COMMAND_DELETE_RECORD_STREAM
] = { NULL
},
162 [PA_COMMAND_EXIT
] = { NULL
},
163 [PA_COMMAND_REQUEST
] = { command_request
},
164 [PA_COMMAND_PLAYBACK_STREAM_KILLED
] = { command_playback_stream_killed
},
165 [PA_COMMAND_RECORD_STREAM_KILLED
] = { command_playback_stream_killed
},
166 [PA_COMMAND_SUBSCRIBE_EVENT
] = { command_subscribe_event
},
169 struct pa_context
*pa_context_new(struct pa_mainloop_api
*mainloop
, const char *name
) {
170 struct pa_context
*c
;
171 assert(mainloop
&& name
);
173 c
= pa_xmalloc(sizeof(struct pa_context
));
174 c
->name
= pa_xstrdup(name
);
175 c
->mainloop
= mainloop
;
179 c
->playback_streams
= pa_dynarray_new();
180 assert(c
->playback_streams
);
181 c
->record_streams
= pa_dynarray_new();
182 assert(c
->record_streams
);
183 c
->first_stream
= NULL
;
184 c
->error
= PA_ERROR_OK
;
185 c
->state
= CONTEXT_UNCONNECTED
;
188 c
->connect_complete_callback
= NULL
;
189 c
->connect_complete_userdata
= NULL
;
191 c
->drain_complete_callback
= NULL
;
192 c
->drain_complete_userdata
= NULL
;
194 c
->die_callback
= NULL
;
195 c
->die_userdata
= NULL
;
197 c
->stat_callback
= NULL
;
198 c
->stat_userdata
= NULL
;
200 c
->play_sample_callback
= NULL
;
201 c
->play_sample_userdata
= NULL
;
203 c
->remove_sample_callback
= NULL
;
204 c
->remove_sample_userdata
= NULL
;
206 c
->get_server_info_callback
= NULL
;
207 c
->get_server_info_userdata
= NULL
;
209 c
->get_sink_info_callback
= NULL
;
210 c
->get_sink_info_userdata
= NULL
;
212 c
->get_source_info_callback
= NULL
;
213 c
->get_source_info_userdata
= NULL
;
215 c
->subscribe_callback
= NULL
;
216 c
->subscribe_userdata
= NULL
;
218 c
->get_client_info_callback
= NULL
;
219 c
->get_client_info_userdata
= NULL
;
221 c
->get_module_info_callback
= NULL
;
222 c
->get_module_info_userdata
= NULL
;
224 pa_check_for_sigpipe();
228 void pa_context_free(struct pa_context
*c
) {
231 while (c
->first_stream
)
232 pa_stream_free(c
->first_stream
);
235 pa_socket_client_free(c
->client
);
237 pa_pdispatch_free(c
->pdispatch
);
239 pa_pstream_free(c
->pstream
);
240 if (c
->record_streams
)
241 pa_dynarray_free(c
->record_streams
, NULL
, NULL
);
242 if (c
->playback_streams
)
243 pa_dynarray_free(c
->playback_streams
, NULL
, NULL
);
249 static void stream_dead(struct pa_stream
*s
) {
252 if (s
->state
== STREAM_DEAD
)
255 if (s
->state
== STREAM_READY
) {
256 s
->state
= STREAM_DEAD
;
258 s
->die_callback(s
, s
->die_userdata
);
260 s
->state
= STREAM_DEAD
;
263 static void context_dead(struct pa_context
*c
) {
267 if (c
->state
== CONTEXT_DEAD
)
271 pa_pdispatch_free(c
->pdispatch
);
275 pa_pstream_free(c
->pstream
);
279 pa_socket_client_free(c
->client
);
282 for (s
= c
->first_stream
; s
; s
= s
->next
)
285 if (c
->state
== CONTEXT_READY
) {
286 c
->state
= CONTEXT_DEAD
;
288 c
->die_callback(c
, c
->die_userdata
);
290 c
->state
= CONTEXT_DEAD
;
293 static void pstream_die_callback(struct pa_pstream
*p
, void *userdata
) {
294 struct pa_context
*c
= userdata
;
296 c
->error
= PA_ERROR_CONNECTIONTERMINATED
;
300 static void pstream_packet_callback(struct pa_pstream
*p
, struct pa_packet
*packet
, void *userdata
) {
301 struct pa_context
*c
= userdata
;
302 assert(p
&& packet
&& c
);
304 if (pa_pdispatch_run(c
->pdispatch
, packet
, c
) < 0) {
305 fprintf(stderr
, "polyp.c: invalid packet.\n");
306 c
->error
= PA_ERROR_PROTOCOL
;
311 static void pstream_memblock_callback(struct pa_pstream
*p
, uint32_t channel
, int32_t delta
, const struct pa_memchunk
*chunk
, void *userdata
) {
312 struct pa_context
*c
= userdata
;
314 assert(p
&& chunk
&& c
&& chunk
->memblock
&& chunk
->memblock
->data
);
316 if (!(s
= pa_dynarray_get(c
->record_streams
, channel
)))
319 if (s
->read_callback
)
320 s
->read_callback(s
, chunk
->memblock
->data
+ chunk
->index
, chunk
->length
, s
->read_userdata
);
323 static int handle_error(struct pa_context
*c
, uint32_t command
, struct pa_tagstruct
*t
) {
326 if (command
== PA_COMMAND_ERROR
) {
327 if (pa_tagstruct_getu32(t
, &c
->error
) < 0) {
328 c
->error
= PA_ERROR_PROTOCOL
;
335 c
->error
= (command
== PA_COMMAND_TIMEOUT
) ? PA_ERROR_TIMEOUT
: PA_ERROR_INTERNAL
;
339 static void setup_complete_callback(struct pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, struct pa_tagstruct
*t
, void *userdata
) {
340 struct pa_context
*c
= userdata
;
341 assert(pd
&& c
&& (c
->state
== CONTEXT_AUTHORIZING
|| c
->state
== CONTEXT_SETTING_NAME
));
343 if (command
!= PA_COMMAND_REPLY
) {
344 handle_error(c
, command
, t
);
347 if (c
->connect_complete_callback
)
348 c
->connect_complete_callback(c
, 0, c
->connect_complete_userdata
);
353 if (c
->state
== CONTEXT_AUTHORIZING
) {
354 struct pa_tagstruct
*t
;
355 c
->state
= CONTEXT_SETTING_NAME
;
356 t
= pa_tagstruct_new(NULL
, 0);
358 pa_tagstruct_putu32(t
, PA_COMMAND_SET_NAME
);
359 pa_tagstruct_putu32(t
, tag
= c
->ctag
++);
360 pa_tagstruct_puts(t
, c
->name
);
361 pa_pstream_send_tagstruct(c
->pstream
, t
);
362 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, setup_complete_callback
, c
);
364 assert(c
->state
== CONTEXT_SETTING_NAME
);
366 c
->state
= CONTEXT_READY
;
368 if (c
->connect_complete_callback
)
369 c
->connect_complete_callback(c
, 1, c
->connect_complete_userdata
);
375 static void on_connection(struct pa_socket_client
*client
, struct pa_iochannel
*io
, void *userdata
) {
376 struct pa_context
*c
= userdata
;
377 struct pa_tagstruct
*t
;
379 assert(client
&& c
&& c
->state
== CONTEXT_CONNECTING
);
381 pa_socket_client_free(client
);
385 c
->error
= PA_ERROR_CONNECTIONREFUSED
;
388 if (c
->connect_complete_callback
)
389 c
->connect_complete_callback(c
, 0, c
->connect_complete_userdata
);
394 c
->pstream
= pa_pstream_new(c
->mainloop
, io
);
396 pa_pstream_set_die_callback(c
->pstream
, pstream_die_callback
, c
);
397 pa_pstream_set_recieve_packet_callback(c
->pstream
, pstream_packet_callback
, c
);
398 pa_pstream_set_recieve_memblock_callback(c
->pstream
, pstream_memblock_callback
, c
);
400 c
->pdispatch
= pa_pdispatch_new(c
->mainloop
, command_table
, PA_COMMAND_MAX
);
401 assert(c
->pdispatch
);
403 t
= pa_tagstruct_new(NULL
, 0);
405 pa_tagstruct_putu32(t
, PA_COMMAND_AUTH
);
406 pa_tagstruct_putu32(t
, tag
= c
->ctag
++);
407 pa_tagstruct_put_arbitrary(t
, c
->auth_cookie
, sizeof(c
->auth_cookie
));
408 pa_pstream_send_tagstruct(c
->pstream
, t
);
409 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, setup_complete_callback
, c
);
410 c
->state
= CONTEXT_AUTHORIZING
;
413 static struct sockaddr
*resolve_server(const char *server
, size_t *len
) {
415 struct addrinfo hints
, *result
= NULL
;
417 assert(server
&& len
);
419 if ((port
= strrchr(server
, ':')))
424 memset(&hints
, 0, sizeof(hints
));
425 hints
.ai_family
= PF_UNSPEC
;
426 hints
.ai_socktype
= SOCK_STREAM
;
427 hints
.ai_protocol
= 0;
429 if (getaddrinfo(server
, port
, &hints
, &result
) != 0)
433 sa
= pa_xmalloc(*len
= result
->ai_addrlen
);
434 memcpy(sa
, result
->ai_addr
, *len
);
436 freeaddrinfo(result
);
441 int pa_context_connect(struct pa_context
*c
, const char *server
, void (*complete
) (struct pa_context
*c
, int success
, void *userdata
), void *userdata
) {
442 assert(c
&& c
->state
== CONTEXT_UNCONNECTED
);
444 if (pa_authkey_load_from_home(PA_NATIVE_COOKIE_FILE
, c
->auth_cookie
, sizeof(c
->auth_cookie
)) < 0) {
445 c
->error
= PA_ERROR_AUTHKEY
;
450 if (!(server
= getenv("POLYP_SERVER")))
451 server
= DEFAULT_SERVER
;
455 if (*server
== '/') {
456 if (!(c
->client
= pa_socket_client_new_unix(c
->mainloop
, server
))) {
457 c
->error
= PA_ERROR_CONNECTIONREFUSED
;
464 if (!(sa
= resolve_server(server
, &sa_len
))) {
465 c
->error
= PA_ERROR_INVALIDSERVER
;
469 c
->client
= pa_socket_client_new_sockaddr(c
->mainloop
, sa
, sa_len
);
473 c
->error
= PA_ERROR_CONNECTIONREFUSED
;
478 c
->connect_complete_callback
= complete
;
479 c
->connect_complete_userdata
= userdata
;
481 pa_socket_client_set_callback(c
->client
, on_connection
, c
);
482 c
->state
= CONTEXT_CONNECTING
;
487 int pa_context_is_dead(struct pa_context
*c
) {
489 return c
->state
== CONTEXT_DEAD
;
492 int pa_context_is_ready(struct pa_context
*c
) {
494 return c
->state
== CONTEXT_READY
;
497 int pa_context_errno(struct pa_context
*c
) {
502 void pa_context_set_die_callback(struct pa_context
*c
, void (*cb
)(struct pa_context
*c
, void *userdata
), void *userdata
) {
504 c
->die_callback
= cb
;
505 c
->die_userdata
= userdata
;
508 static void command_playback_stream_killed(struct pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, struct pa_tagstruct
*t
, void *userdata
) {
509 struct pa_context
*c
= userdata
;
512 assert(pd
&& (command
== PA_COMMAND_PLAYBACK_STREAM_KILLED
|| command
== PA_COMMAND_RECORD_STREAM_KILLED
) && t
&& c
);
514 if (pa_tagstruct_getu32(t
, &channel
) < 0 ||
515 !pa_tagstruct_eof(t
)) {
516 c
->error
= PA_ERROR_PROTOCOL
;
521 if (!(s
= pa_dynarray_get(command
== PA_COMMAND_PLAYBACK_STREAM_KILLED
? c
->playback_streams
: c
->record_streams
, channel
)))
524 c
->error
= PA_ERROR_KILLED
;
528 static void command_request(struct pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, struct pa_tagstruct
*t
, void *userdata
) {
530 struct pa_context
*c
= userdata
;
531 uint32_t bytes
, channel
;
532 assert(pd
&& command
== PA_COMMAND_REQUEST
&& t
&& c
);
534 if (pa_tagstruct_getu32(t
, &channel
) < 0 ||
535 pa_tagstruct_getu32(t
, &bytes
) < 0 ||
536 !pa_tagstruct_eof(t
)) {
537 c
->error
= PA_ERROR_PROTOCOL
;
542 if (!(s
= pa_dynarray_get(c
->playback_streams
, channel
)))
545 if (s
->state
!= STREAM_READY
)
548 s
->requested_bytes
+= bytes
;
550 if (s
->requested_bytes
&& s
->write_callback
)
551 s
->write_callback(s
, s
->requested_bytes
, s
->write_userdata
);
554 static void create_stream_callback(struct pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, struct pa_tagstruct
*t
, void *userdata
) {
555 struct pa_stream
*s
= userdata
;
556 assert(pd
&& s
&& s
->state
== STREAM_CREATING
);
558 if (command
!= PA_COMMAND_REPLY
) {
559 if (handle_error(s
->context
, command
, t
) < 0) {
560 context_dead(s
->context
);
565 if (s
->create_complete_callback
)
566 s
->create_complete_callback(s
, 0, s
->create_complete_userdata
);
571 if (pa_tagstruct_getu32(t
, &s
->channel
) < 0 ||
572 ((s
->direction
!= PA_STREAM_UPLOAD
) && pa_tagstruct_getu32(t
, &s
->device_index
) < 0) ||
573 !pa_tagstruct_eof(t
)) {
574 s
->context
->error
= PA_ERROR_PROTOCOL
;
575 context_dead(s
->context
);
579 s
->channel_valid
= 1;
580 pa_dynarray_put((s
->direction
== PA_STREAM_RECORD
) ? s
->context
->record_streams
: s
->context
->playback_streams
, s
->channel
, s
);
582 s
->state
= STREAM_READY
;
583 if (s
->create_complete_callback
)
584 s
->create_complete_callback(s
, 1, s
->create_complete_userdata
);
587 static void create_stream(struct pa_stream
*s
, const char *dev
) {
588 struct pa_tagstruct
*t
;
592 s
->state
= STREAM_CREATING
;
594 t
= pa_tagstruct_new(NULL
, 0);
597 pa_tagstruct_putu32(t
, s
->direction
== PA_STREAM_PLAYBACK
? PA_COMMAND_CREATE_PLAYBACK_STREAM
: PA_COMMAND_CREATE_RECORD_STREAM
);
598 pa_tagstruct_putu32(t
, tag
= s
->context
->ctag
++);
599 pa_tagstruct_puts(t
, s
->name
);
600 pa_tagstruct_put_sample_spec(t
, &s
->sample_spec
);
601 pa_tagstruct_putu32(t
, (uint32_t) -1);
602 pa_tagstruct_puts(t
, dev
? dev
: "");
603 pa_tagstruct_putu32(t
, s
->buffer_attr
.maxlength
);
604 if (s
->direction
== PA_STREAM_PLAYBACK
) {
605 pa_tagstruct_putu32(t
, s
->buffer_attr
.tlength
);
606 pa_tagstruct_putu32(t
, s
->buffer_attr
.prebuf
);
607 pa_tagstruct_putu32(t
, s
->buffer_attr
.minreq
);
609 pa_tagstruct_putu32(t
, s
->buffer_attr
.fragsize
);
611 pa_pstream_send_tagstruct(s
->context
->pstream
, t
);
612 pa_pdispatch_register_reply(s
->context
->pdispatch
, tag
, DEFAULT_TIMEOUT
, create_stream_callback
, s
);
615 static struct pa_stream
*internal_stream_new(struct pa_context
*c
) {
618 s
= pa_xmalloc(sizeof(struct pa_stream
));
621 s
->read_callback
= NULL
;
622 s
->read_userdata
= NULL
;
623 s
->write_callback
= NULL
;
624 s
->write_userdata
= NULL
;
625 s
->die_callback
= NULL
;
626 s
->die_userdata
= NULL
;
627 s
->create_complete_callback
= NULL
;
628 s
->create_complete_userdata
= NULL
;
629 s
->get_latency_callback
= NULL
;
630 s
->get_latency_userdata
= NULL
;
631 s
->finish_sample_callback
= NULL
;
632 s
->finish_sample_userdata
= NULL
;
635 s
->state
= STREAM_CREATING
;
636 s
->requested_bytes
= 0;
638 s
->channel_valid
= 0;
639 s
->device_index
= (uint32_t) -1;
641 memset(&s
->buffer_attr
, 0, sizeof(s
->buffer_attr
));
643 s
->next
= c
->first_stream
;
645 s
->next
->previous
= s
;
652 struct pa_stream
* pa_stream_new(
653 struct pa_context
*c
,
654 enum pa_stream_direction dir
,
657 const struct pa_sample_spec
*ss
,
658 const struct pa_buffer_attr
*attr
,
659 void (*complete
) (struct pa_stream
*s
, int success
, void *userdata
),
664 assert(c
&& name
&& ss
&& c
->state
== CONTEXT_READY
&& (dir
== PA_STREAM_PLAYBACK
|| dir
== PA_STREAM_RECORD
));
666 s
= internal_stream_new(c
);
669 s
->create_complete_callback
= complete
;
670 s
->create_complete_userdata
= userdata
;
671 s
->name
= pa_xstrdup(name
);
672 s
->state
= STREAM_CREATING
;
674 s
->sample_spec
= *ss
;
676 s
->buffer_attr
= *attr
;
678 s
->buffer_attr
.maxlength
= DEFAULT_MAXLENGTH
;
679 s
->buffer_attr
.tlength
= DEFAULT_TLENGTH
;
680 s
->buffer_attr
.prebuf
= DEFAULT_PREBUF
;
681 s
->buffer_attr
.minreq
= DEFAULT_MINREQ
;
682 s
->buffer_attr
.fragsize
= DEFAULT_FRAGSIZE
;
685 create_stream(s
, dev
);
690 void pa_stream_free(struct pa_stream
*s
) {
691 assert(s
&& s
->context
);
693 if (s
->context
->pdispatch
)
694 pa_pdispatch_unregister_reply(s
->context
->pdispatch
, s
);
698 if (s
->channel_valid
&& s
->context
->state
== CONTEXT_READY
) {
699 struct pa_tagstruct
*t
= pa_tagstruct_new(NULL
, 0);
702 pa_tagstruct_putu32(t
, s
->direction
== PA_STREAM_PLAYBACK
? PA_COMMAND_DELETE_PLAYBACK_STREAM
:
703 (s
->direction
== PA_STREAM_RECORD
? PA_COMMAND_DELETE_RECORD_STREAM
: PA_COMMAND_DELETE_UPLOAD_STREAM
));
704 pa_tagstruct_putu32(t
, s
->context
->ctag
++);
705 pa_tagstruct_putu32(t
, s
->channel
);
706 pa_pstream_send_tagstruct(s
->context
->pstream
, t
);
709 if (s
->channel_valid
)
710 pa_dynarray_put((s
->direction
== PA_STREAM_PLAYBACK
) ? s
->context
->playback_streams
: s
->context
->record_streams
, s
->channel
, NULL
);
713 s
->next
->previous
= s
->previous
;
715 s
->previous
->next
= s
->next
;
717 s
->context
->first_stream
= s
->next
;
722 void pa_stream_set_write_callback(struct pa_stream
*s
, void (*cb
)(struct pa_stream
*p
, size_t length
, void *userdata
), void *userdata
) {
723 s
->write_callback
= cb
;
724 s
->write_userdata
= userdata
;
727 void pa_stream_write(struct pa_stream
*s
, const void *data
, size_t length
) {
728 struct pa_memchunk chunk
;
729 assert(s
&& s
->context
&& data
&& length
&& s
->state
== STREAM_READY
);
731 chunk
.memblock
= pa_memblock_new(length
);
732 assert(chunk
.memblock
&& chunk
.memblock
->data
);
733 memcpy(chunk
.memblock
->data
, data
, length
);
735 chunk
.length
= length
;
737 pa_pstream_send_memblock(s
->context
->pstream
, s
->channel
, 0, &chunk
);
738 pa_memblock_unref(chunk
.memblock
);
740 /*fprintf(stderr, "Sent %u bytes\n", length);*/
742 if (length
< s
->requested_bytes
)
743 s
->requested_bytes
-= length
;
745 s
->requested_bytes
= 0;
748 size_t pa_stream_writable_size(struct pa_stream
*s
) {
749 assert(s
&& s
->state
== STREAM_READY
);
750 return s
->requested_bytes
;
753 void pa_stream_set_read_callback(struct pa_stream
*s
, void (*cb
)(struct pa_stream
*p
, const void*data
, size_t length
, void *userdata
), void *userdata
) {
755 s
->read_callback
= cb
;
756 s
->read_userdata
= userdata
;
759 int pa_stream_is_dead(struct pa_stream
*s
) {
760 return s
->state
== STREAM_DEAD
;
763 int pa_stream_is_ready(struct pa_stream
*s
) {
764 return s
->state
== STREAM_READY
;
767 void pa_stream_set_die_callback(struct pa_stream
*s
, void (*cb
)(struct pa_stream
*s
, void *userdata
), void *userdata
) {
769 s
->die_callback
= cb
;
770 s
->die_userdata
= userdata
;
773 int pa_context_is_pending(struct pa_context
*c
) {
776 if (c
->state
!= CONTEXT_READY
)
779 return pa_pstream_is_pending(c
->pstream
) || pa_pdispatch_is_pending(c
->pdispatch
);
782 struct pa_context
* pa_stream_get_context(struct pa_stream
*p
) {
787 static void set_dispatch_callbacks(struct pa_context
*c
);
789 static void pdispatch_drain_callback(struct pa_pdispatch
*pd
, void *userdata
) {
790 set_dispatch_callbacks(userdata
);
793 static void pstream_drain_callback(struct pa_pstream
*s
, void *userdata
) {
794 set_dispatch_callbacks(userdata
);
797 static void set_dispatch_callbacks(struct pa_context
*c
) {
798 assert(c
&& c
->state
== CONTEXT_READY
);
800 pa_pstream_set_drain_callback(c
->pstream
, NULL
, NULL
);
801 pa_pdispatch_set_drain_callback(c
->pdispatch
, NULL
, NULL
);
803 if (pa_pdispatch_is_pending(c
->pdispatch
)) {
804 pa_pdispatch_set_drain_callback(c
->pdispatch
, pdispatch_drain_callback
, c
);
808 if (pa_pstream_is_pending(c
->pstream
)) {
809 pa_pstream_set_drain_callback(c
->pstream
, pstream_drain_callback
, c
);
813 assert(c
->drain_complete_callback
);
814 c
->drain_complete_callback(c
, c
->drain_complete_userdata
);
817 int pa_context_drain(
818 struct pa_context
*c
,
819 void (*complete
) (struct pa_context
*c
, void *userdata
),
822 assert(c
&& c
->state
== CONTEXT_READY
);
824 if (complete
== NULL
) {
825 c
->drain_complete_callback
= NULL
;
826 pa_pstream_set_drain_callback(c
->pstream
, NULL
, NULL
);
827 pa_pdispatch_set_drain_callback(c
->pdispatch
, NULL
, NULL
);
831 if (!pa_context_is_pending(c
))
834 c
->drain_complete_callback
= complete
;
835 c
->drain_complete_userdata
= userdata
;
837 set_dispatch_callbacks(c
);
842 static void stream_drain_callback(struct pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, struct pa_tagstruct
*t
, void *userdata
) {
843 struct pa_stream
*s
= userdata
;
846 if (command
!= PA_COMMAND_REPLY
) {
847 if (handle_error(s
->context
, command
, t
) < 0) {
848 context_dead(s
->context
);
856 if (s
->state
!= STREAM_READY
)
859 if (!pa_tagstruct_eof(t
)) {
860 s
->context
->error
= PA_ERROR_PROTOCOL
;
861 context_dead(s
->context
);
865 if (s
->drain_complete_callback
) {
866 void (*temp
) (struct pa_stream
*s
, void *userdata
) = s
->drain_complete_callback
;
867 s
->drain_complete_callback
= NULL
;
868 temp(s
, s
->drain_complete_userdata
);
873 void pa_stream_drain(struct pa_stream
*s
, void (*complete
) (struct pa_stream
*s
, void *userdata
), void *userdata
) {
874 struct pa_tagstruct
*t
;
876 assert(s
&& s
->state
== STREAM_READY
);
879 s
->drain_complete_callback
= NULL
;
883 s
->drain_complete_callback
= complete
;
884 s
->drain_complete_userdata
= userdata
;
886 t
= pa_tagstruct_new(NULL
, 0);
889 pa_tagstruct_putu32(t
, PA_COMMAND_DRAIN_PLAYBACK_STREAM
);
890 pa_tagstruct_putu32(t
, tag
= s
->context
->ctag
++);
891 pa_tagstruct_putu32(t
, s
->channel
);
892 pa_pstream_send_tagstruct(s
->context
->pstream
, t
);
893 pa_pdispatch_register_reply(s
->context
->pdispatch
, tag
, DEFAULT_TIMEOUT
, stream_drain_callback
, s
);
896 void pa_context_exit(struct pa_context
*c
) {
897 struct pa_tagstruct
*t
;
898 t
= pa_tagstruct_new(NULL
, 0);
900 pa_tagstruct_putu32(t
, PA_COMMAND_EXIT
);
901 pa_tagstruct_putu32(t
, c
->ctag
++);
902 pa_pstream_send_tagstruct(c
->pstream
, t
);
905 static void context_stat_callback(struct pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, struct pa_tagstruct
*t
, void *userdata
) {
906 struct pa_context
*c
= userdata
;
907 uint32_t total
, count
;
910 if (command
!= PA_COMMAND_REPLY
) {
911 if (handle_error(c
, command
, t
) < 0) {
916 if (c
->stat_callback
)
917 c
->stat_callback(c
, (uint32_t) -1, (uint32_t) -1, c
->stat_userdata
);
921 if (pa_tagstruct_getu32(t
, &count
) < 0 ||
922 pa_tagstruct_getu32(t
, &total
) < 0 ||
923 !pa_tagstruct_eof(t
)) {
924 c
->error
= PA_ERROR_PROTOCOL
;
929 if (c
->stat_callback
)
930 c
->stat_callback(c
, count
, total
, c
->stat_userdata
);
933 void pa_context_stat(struct pa_context
*c
, void (*cb
)(struct pa_context
*c
, uint32_t count
, uint32_t total
, void *userdata
), void *userdata
) {
935 struct pa_tagstruct
*t
;
937 c
->stat_callback
= cb
;
938 c
->stat_userdata
= userdata
;
943 t
= pa_tagstruct_new(NULL
, 0);
945 pa_tagstruct_putu32(t
, PA_COMMAND_STAT
);
946 pa_tagstruct_putu32(t
, tag
= c
->ctag
++);
947 pa_pstream_send_tagstruct(c
->pstream
, t
);
948 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, context_stat_callback
, c
);
951 static void stream_get_latency_callback(struct pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, struct pa_tagstruct
*t
, void *userdata
) {
952 struct pa_stream
*s
= userdata
;
956 if (command
!= PA_COMMAND_REPLY
) {
957 if (handle_error(s
->context
, command
, t
) < 0) {
958 context_dead(s
->context
);
962 if (s
->get_latency_callback
)
963 s
->get_latency_callback(s
, (uint32_t) -1, s
->get_latency_userdata
);
967 if (pa_tagstruct_getu32(t
, &latency
) < 0 ||
968 !pa_tagstruct_eof(t
)) {
969 s
->context
->error
= PA_ERROR_PROTOCOL
;
970 context_dead(s
->context
);
974 if (s
->get_latency_callback
)
975 s
->get_latency_callback(s
, latency
, s
->get_latency_userdata
);
978 void pa_stream_get_latency(struct pa_stream
*p
, void (*cb
)(struct pa_stream
*p
, uint32_t latency
, void *userdata
), void *userdata
) {
980 struct pa_tagstruct
*t
;
982 p
->get_latency_callback
= cb
;
983 p
->get_latency_userdata
= userdata
;
988 t
= pa_tagstruct_new(NULL
, 0);
990 pa_tagstruct_putu32(t
, PA_COMMAND_GET_PLAYBACK_LATENCY
);
991 pa_tagstruct_putu32(t
, tag
= p
->context
->ctag
++);
992 pa_tagstruct_putu32(t
, p
->channel
);
993 pa_pstream_send_tagstruct(p
->context
->pstream
, t
);
994 pa_pdispatch_register_reply(p
->context
->pdispatch
, tag
, DEFAULT_TIMEOUT
, stream_get_latency_callback
, p
);
997 struct pa_stream
* pa_context_upload_sample(struct pa_context
*c
, const char *name
, const struct pa_sample_spec
*ss
, size_t length
, void (*cb
) (struct pa_stream
*s
, int success
, void *userdata
), void *userdata
) {
999 struct pa_tagstruct
*t
;
1002 s
= internal_stream_new(c
);
1005 s
->create_complete_callback
= cb
;
1006 s
->create_complete_userdata
= userdata
;
1007 s
->name
= pa_xstrdup(name
);
1008 s
->state
= STREAM_CREATING
;
1009 s
->direction
= PA_STREAM_UPLOAD
;
1010 s
->sample_spec
= *ss
;
1012 t
= pa_tagstruct_new(NULL
, 0);
1014 pa_tagstruct_putu32(t
, PA_COMMAND_CREATE_UPLOAD_STREAM
);
1015 pa_tagstruct_putu32(t
, tag
= c
->ctag
++);
1016 pa_tagstruct_puts(t
, name
);
1017 pa_tagstruct_put_sample_spec(t
, ss
);
1018 pa_tagstruct_putu32(t
, length
);
1019 pa_pstream_send_tagstruct(c
->pstream
, t
);
1020 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, create_stream_callback
, s
);
1025 static void stream_finish_sample_callback(struct pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, struct pa_tagstruct
*t
, void *userdata
) {
1026 struct pa_stream
*s
= userdata
;
1029 if (command
!= PA_COMMAND_REPLY
) {
1030 if (handle_error(s
->context
, command
, t
) < 0) {
1031 context_dead(s
->context
);
1035 if (s
->finish_sample_callback
)
1036 s
->finish_sample_callback(s
, 0, s
->finish_sample_userdata
);
1040 if (!pa_tagstruct_eof(t
)) {
1041 s
->context
->error
= PA_ERROR_PROTOCOL
;
1042 context_dead(s
->context
);
1046 if (s
->finish_sample_callback
)
1047 s
->finish_sample_callback(s
, 1, s
->finish_sample_userdata
);
1050 void pa_stream_finish_sample(struct pa_stream
*p
, void (*cb
)(struct pa_stream
*s
, int success
, void *userdata
), void *userdata
) {
1051 struct pa_tagstruct
*t
;
1055 p
->finish_sample_callback
= cb
;
1056 p
->finish_sample_userdata
= userdata
;
1058 t
= pa_tagstruct_new(NULL
, 0);
1060 pa_tagstruct_putu32(t
, PA_COMMAND_FINISH_UPLOAD_STREAM
);
1061 pa_tagstruct_putu32(t
, tag
= p
->context
->ctag
++);
1062 pa_tagstruct_putu32(t
, p
->channel
);
1063 pa_pstream_send_tagstruct(p
->context
->pstream
, t
);
1064 pa_pdispatch_register_reply(p
->context
->pdispatch
, tag
, DEFAULT_TIMEOUT
, stream_finish_sample_callback
, p
);
1067 static void context_play_sample_callback(struct pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, struct pa_tagstruct
*t
, void *userdata
) {
1068 struct pa_context
*c
= userdata
;
1071 if (command
!= PA_COMMAND_REPLY
) {
1072 if (handle_error(c
, command
, t
) < 0) {
1077 if (c
->play_sample_callback
)
1078 c
->play_sample_callback(c
, 0, c
->play_sample_userdata
);
1082 if (!pa_tagstruct_eof(t
)) {
1083 c
->error
= PA_ERROR_PROTOCOL
;
1088 if (c
->play_sample_callback
)
1089 c
->play_sample_callback(c
, 1, c
->play_sample_userdata
);
1092 void pa_context_play_sample(struct pa_context
*c
, const char *name
, const char *dev
, uint32_t volume
, void (*cb
)(struct pa_context
*c
, int success
, void *userdata
), void *userdata
) {
1093 struct pa_tagstruct
*t
;
1095 assert(c
&& name
&& *name
&& (!dev
|| *dev
));
1097 c
->play_sample_callback
= cb
;
1098 c
->play_sample_userdata
= userdata
;
1103 t
= pa_tagstruct_new(NULL
, 0);
1105 pa_tagstruct_putu32(t
, PA_COMMAND_PLAY_SAMPLE
);
1106 pa_tagstruct_putu32(t
, tag
= c
->ctag
++);
1107 pa_tagstruct_putu32(t
, (uint32_t) -1);
1108 pa_tagstruct_puts(t
, dev
? dev
: "");
1109 pa_tagstruct_putu32(t
, volume
);
1110 pa_tagstruct_puts(t
, name
);
1111 pa_pstream_send_tagstruct(c
->pstream
, t
);
1112 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, context_play_sample_callback
, c
);
1115 static void context_remove_sample_callback(struct pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, struct pa_tagstruct
*t
, void *userdata
) {
1116 struct pa_context
*c
= userdata
;
1119 if (command
!= PA_COMMAND_REPLY
) {
1120 if (handle_error(c
, command
, t
) < 0) {
1125 if (c
->remove_sample_callback
)
1126 c
->remove_sample_callback(c
, 0, c
->remove_sample_userdata
);
1130 if (!pa_tagstruct_eof(t
)) {
1131 c
->error
= PA_ERROR_PROTOCOL
;
1136 if (c
->remove_sample_callback
)
1137 c
->remove_sample_callback(c
, 1, c
->remove_sample_userdata
);
1140 void pa_context_remove_sample(struct pa_context
*c
, const char *name
, void (*cb
)(struct pa_context
*c
, int success
, void *userdata
), void *userdata
) {
1141 struct pa_tagstruct
*t
;
1145 c
->remove_sample_callback
= cb
;
1146 c
->remove_sample_userdata
= userdata
;
1151 t
= pa_tagstruct_new(NULL
, 0);
1153 pa_tagstruct_putu32(t
, PA_COMMAND_REMOVE_SAMPLE
);
1154 pa_tagstruct_putu32(t
, tag
= c
->ctag
++);
1155 pa_tagstruct_puts(t
, name
);
1156 pa_pstream_send_tagstruct(c
->pstream
, t
);
1157 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, context_remove_sample_callback
, c
);
1160 static void context_get_server_info_callback(struct pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, struct pa_tagstruct
*t
, void *userdata
) {
1161 struct pa_context
*c
= userdata
;
1162 struct pa_server_info i
;
1165 if (command
!= PA_COMMAND_REPLY
) {
1166 if (handle_error(c
, command
, t
) < 0) {
1171 if (c
->get_server_info_callback
)
1172 c
->get_server_info_callback(c
, NULL
, c
->get_server_info_userdata
);
1176 if (pa_tagstruct_gets(t
, &i
.server_name
) < 0 ||
1177 pa_tagstruct_gets(t
, &i
.server_version
) < 0 ||
1178 pa_tagstruct_gets(t
, &i
.user_name
) < 0 ||
1179 pa_tagstruct_gets(t
, &i
.host_name
) < 0 ||
1180 pa_tagstruct_get_sample_spec(t
, &i
.sample_spec
) < 0 ||
1181 !pa_tagstruct_eof(t
)) {
1182 c
->error
= PA_ERROR_PROTOCOL
;
1187 if (c
->get_server_info_callback
)
1188 c
->get_server_info_callback(c
, &i
, c
->get_server_info_userdata
);
1191 void pa_context_get_server_info(struct pa_context
*c
, void (*cb
)(struct pa_context
*c
, const struct pa_server_info
*i
, void *userdata
), void *userdata
) {
1192 struct pa_tagstruct
*t
;
1196 c
->get_server_info_callback
= cb
;
1197 c
->get_server_info_userdata
= userdata
;
1202 t
= pa_tagstruct_new(NULL
, 0);
1204 pa_tagstruct_putu32(t
, PA_COMMAND_GET_SERVER_INFO
);
1205 pa_tagstruct_putu32(t
, tag
= c
->ctag
++);
1206 pa_pstream_send_tagstruct(c
->pstream
, t
);
1207 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, context_get_server_info_callback
, c
);
1210 static void context_get_sink_info_callback(struct pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, struct pa_tagstruct
*t
, void *userdata
) {
1211 struct pa_context
*c
= userdata
;
1214 if (command
!= PA_COMMAND_REPLY
) {
1215 if (handle_error(c
, command
, t
) < 0) {
1220 if (c
->get_sink_info_callback
)
1221 c
->get_sink_info_callback(c
, NULL
, 0, c
->get_sink_info_userdata
);
1225 while (!pa_tagstruct_eof(t
)) {
1226 struct pa_sink_info i
;
1228 if (pa_tagstruct_getu32(t
, &i
.index
) < 0 ||
1229 pa_tagstruct_gets(t
, &i
.name
) < 0 ||
1230 pa_tagstruct_gets(t
, &i
.description
) < 0 ||
1231 pa_tagstruct_get_sample_spec(t
, &i
.sample_spec
) < 0 ||
1232 pa_tagstruct_getu32(t
, &i
.owner_module
) < 0 ||
1233 pa_tagstruct_getu32(t
, &i
.volume
) < 0 ||
1234 pa_tagstruct_getu32(t
, &i
.monitor_source
) < 0 ||
1235 pa_tagstruct_gets(t
, &i
.monitor_source_name
) < 0 ||
1236 pa_tagstruct_getu32(t
, &i
.latency
) < 0) {
1237 c
->error
= PA_ERROR_PROTOCOL
;
1242 if (c
->get_sink_info_callback
)
1243 c
->get_sink_info_callback(c
, &i
, 0, c
->get_sink_info_userdata
);
1246 if (c
->get_sink_info_callback
)
1247 c
->get_sink_info_callback(c
, NULL
, 1, c
->get_sink_info_userdata
);
1250 void pa_context_get_sink_info_list(struct pa_context
*c
, void (*cb
)(struct pa_context
*c
, const struct pa_sink_info
*i
, int is_last
, void *userdata
), void *userdata
) {
1251 struct pa_tagstruct
*t
;
1255 c
->get_sink_info_callback
= cb
;
1256 c
->get_sink_info_userdata
= userdata
;
1261 t
= pa_tagstruct_new(NULL
, 0);
1263 pa_tagstruct_putu32(t
, PA_COMMAND_GET_SINK_INFO_LIST
);
1264 pa_tagstruct_putu32(t
, tag
= c
->ctag
++);
1265 pa_pstream_send_tagstruct(c
->pstream
, t
);
1266 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, context_get_sink_info_callback
, c
);
1269 static void context_get_source_info_callback(struct pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, struct pa_tagstruct
*t
, void *userdata
) {
1270 struct pa_context
*c
= userdata
;
1273 if (command
!= PA_COMMAND_REPLY
) {
1274 if (handle_error(c
, command
, t
) < 0) {
1279 if (c
->get_source_info_callback
)
1280 c
->get_source_info_callback(c
, NULL
, 0, c
->get_source_info_userdata
);
1284 while (!pa_tagstruct_eof(t
)) {
1285 struct pa_source_info i
;
1287 if (pa_tagstruct_getu32(t
, &i
.index
) < 0 ||
1288 pa_tagstruct_gets(t
, &i
.name
) < 0 ||
1289 pa_tagstruct_gets(t
, &i
.description
) < 0 ||
1290 pa_tagstruct_get_sample_spec(t
, &i
.sample_spec
) < 0 ||
1291 pa_tagstruct_getu32(t
, &i
.owner_module
) < 0 ||
1292 pa_tagstruct_getu32(t
, &i
.monitor_of_sink
) < 0 ||
1293 pa_tagstruct_gets(t
, &i
.monitor_of_sink_name
) < 0) {
1294 c
->error
= PA_ERROR_PROTOCOL
;
1299 if (c
->get_source_info_callback
)
1300 c
->get_source_info_callback(c
, &i
, 0, c
->get_source_info_userdata
);
1303 if (c
->get_source_info_callback
)
1304 c
->get_source_info_callback(c
, NULL
, 1, c
->get_source_info_userdata
);
1307 void pa_context_get_source_info_list(struct pa_context
*c
, void (*cb
)(struct pa_context
*c
, const struct pa_source_info
*i
, int is_last
, void *userdata
), void *userdata
) {
1308 struct pa_tagstruct
*t
;
1312 c
->get_source_info_callback
= cb
;
1313 c
->get_source_info_userdata
= userdata
;
1318 t
= pa_tagstruct_new(NULL
, 0);
1320 pa_tagstruct_putu32(t
, PA_COMMAND_GET_SOURCE_INFO_LIST
);
1321 pa_tagstruct_putu32(t
, tag
= c
->ctag
++);
1322 pa_pstream_send_tagstruct(c
->pstream
, t
);
1323 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, context_get_source_info_callback
, c
);
1326 void pa_context_subscribe(struct pa_context
*c
, enum pa_subscription_mask m
, void (*cb
)(struct pa_context
*c
, enum pa_subscription_event_type t
, uint32_t index
, void *userdata
), void *userdata
) {
1327 struct pa_tagstruct
*t
;
1330 c
->subscribe_callback
= cb
;
1331 c
->subscribe_userdata
= userdata
;
1332 c
->subscribe_mask
= m
;
1334 t
= pa_tagstruct_new(NULL
, 0);
1336 pa_tagstruct_putu32(t
, PA_COMMAND_SUBSCRIBE
);
1337 pa_tagstruct_putu32(t
, c
->ctag
++);
1338 pa_tagstruct_putu32(t
, cb
? m
: 0);
1339 pa_pstream_send_tagstruct(c
->pstream
, t
);
1342 static void command_subscribe_event(struct pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, struct pa_tagstruct
*t
, void *userdata
) {
1343 struct pa_context
*c
= userdata
;
1344 enum pa_subscription_event_type e
;
1346 assert(pd
&& command
== PA_COMMAND_SUBSCRIBE_EVENT
&& t
&& c
);
1348 if (pa_tagstruct_getu32(t
, &e
) < 0 ||
1349 pa_tagstruct_getu32(t
, &index
) < 0 ||
1350 !pa_tagstruct_eof(t
)) {
1351 c
->error
= PA_ERROR_PROTOCOL
;
1356 if (pa_subscription_match_flags(c
->subscribe_mask
, e
) && c
->subscribe_callback
)
1357 c
->subscribe_callback(c
, e
, index
, c
->subscribe_userdata
);
1360 void pa_context_get_sink_info_by_index(struct pa_context
*c
, uint32_t index
, void (*cb
)(struct pa_context
*c
, const struct pa_sink_info
*i
, int is_last
, void *userdata
), void *userdata
) {
1361 struct pa_tagstruct
*t
;
1365 c
->get_sink_info_callback
= cb
;
1366 c
->get_sink_info_userdata
= userdata
;
1371 t
= pa_tagstruct_new(NULL
, 0);
1373 pa_tagstruct_putu32(t
, PA_COMMAND_GET_SINK_INFO
);
1374 pa_tagstruct_putu32(t
, tag
= c
->ctag
++);
1375 pa_tagstruct_putu32(t
, index
);
1376 pa_tagstruct_puts(t
, "");
1377 pa_pstream_send_tagstruct(c
->pstream
, t
);
1378 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, context_get_sink_info_callback
, c
);
1381 void pa_context_get_source_info_by_index(struct pa_context
*c
, uint32_t index
, void (*cb
)(struct pa_context
*c
, const struct pa_source_info
*i
, int is_last
, void *userdata
), void *userdata
) {
1382 struct pa_tagstruct
*t
;
1386 c
->get_source_info_callback
= cb
;
1387 c
->get_source_info_userdata
= userdata
;
1392 t
= pa_tagstruct_new(NULL
, 0);
1394 pa_tagstruct_putu32(t
, PA_COMMAND_GET_SOURCE_INFO
);
1395 pa_tagstruct_putu32(t
, tag
= c
->ctag
++);
1396 pa_tagstruct_putu32(t
, index
);
1397 pa_tagstruct_puts(t
, "");
1398 pa_pstream_send_tagstruct(c
->pstream
, t
);
1399 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, context_get_source_info_callback
, c
);
1402 static void context_get_client_info_callback(struct pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, struct pa_tagstruct
*t
, void *userdata
) {
1403 struct pa_context
*c
= userdata
;
1406 if (command
!= PA_COMMAND_REPLY
) {
1407 if (handle_error(c
, command
, t
) < 0) {
1412 if (c
->get_client_info_callback
)
1413 c
->get_client_info_callback(c
, NULL
, 0, c
->get_client_info_userdata
);
1417 while (!pa_tagstruct_eof(t
)) {
1418 struct pa_client_info i
;
1420 if (pa_tagstruct_getu32(t
, &i
.index
) < 0 ||
1421 pa_tagstruct_gets(t
, &i
.name
) < 0 ||
1422 pa_tagstruct_gets(t
, &i
.protocol_name
) < 0 ||
1423 pa_tagstruct_getu32(t
, &i
.owner_module
) < 0) {
1424 c
->error
= PA_ERROR_PROTOCOL
;
1429 if (c
->get_client_info_callback
)
1430 c
->get_client_info_callback(c
, &i
, 0, c
->get_client_info_userdata
);
1433 if (c
->get_client_info_callback
)
1434 c
->get_client_info_callback(c
, NULL
, 1, c
->get_client_info_userdata
);
1438 void pa_context_get_client_info(struct pa_context
*c
, uint32_t index
, void (*cb
)(struct pa_context
*c
, const struct pa_client_info
*i
, int is_last
, void *userdata
), void *userdata
) {
1439 struct pa_tagstruct
*t
;
1443 c
->get_client_info_callback
= cb
;
1444 c
->get_client_info_userdata
= userdata
;
1449 t
= pa_tagstruct_new(NULL
, 0);
1451 pa_tagstruct_putu32(t
, PA_COMMAND_GET_CLIENT_INFO
);
1452 pa_tagstruct_putu32(t
, tag
= c
->ctag
++);
1453 pa_tagstruct_putu32(t
, index
);
1454 pa_pstream_send_tagstruct(c
->pstream
, t
);
1455 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, context_get_client_info_callback
, c
);
1458 void pa_context_get_client_info_list(struct pa_context
*c
, void (*cb
)(struct pa_context
*c
, const struct pa_client_info
*i
, int is_last
, void *userdata
), void *userdata
) {
1459 struct pa_tagstruct
*t
;
1463 c
->get_client_info_callback
= cb
;
1464 c
->get_client_info_userdata
= userdata
;
1469 t
= pa_tagstruct_new(NULL
, 0);
1471 pa_tagstruct_putu32(t
, PA_COMMAND_GET_CLIENT_INFO_LIST
);
1472 pa_tagstruct_putu32(t
, tag
= c
->ctag
++);
1473 pa_pstream_send_tagstruct(c
->pstream
, t
);
1474 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, context_get_client_info_callback
, c
);
1477 static void context_get_module_info_callback(struct pa_pdispatch
*pd
, uint32_t command
, uint32_t tag
, struct pa_tagstruct
*t
, void *userdata
) {
1478 struct pa_context
*c
= userdata
;
1481 if (command
!= PA_COMMAND_REPLY
) {
1482 if (handle_error(c
, command
, t
) < 0) {
1487 if (c
->get_module_info_callback
)
1488 c
->get_module_info_callback(c
, NULL
, 0, c
->get_module_info_userdata
);
1492 while (!pa_tagstruct_eof(t
)) {
1493 struct pa_module_info i
;
1495 if (pa_tagstruct_getu32(t
, &i
.index
) < 0 ||
1496 pa_tagstruct_gets(t
, &i
.name
) < 0 ||
1497 pa_tagstruct_gets(t
, &i
.argument
) < 0 ||
1498 pa_tagstruct_getu32(t
, &i
.n_used
) < 0 ||
1499 pa_tagstruct_getu32(t
, &i
.auto_unload
) < 0) {
1500 c
->error
= PA_ERROR_PROTOCOL
;
1505 if (c
->get_module_info_callback
)
1506 c
->get_module_info_callback(c
, &i
, 0, c
->get_module_info_userdata
);
1509 if (c
->get_module_info_callback
)
1510 c
->get_module_info_callback(c
, NULL
, 1, c
->get_module_info_userdata
);
1513 void pa_context_get_module_info(struct pa_context
*c
, uint32_t index
, void (*cb
)(struct pa_context
*c
, const struct pa_module_info
*i
, int is_last
, void *userdata
), void *userdata
) {
1514 struct pa_tagstruct
*t
;
1518 c
->get_module_info_callback
= cb
;
1519 c
->get_module_info_userdata
= userdata
;
1524 t
= pa_tagstruct_new(NULL
, 0);
1526 pa_tagstruct_putu32(t
, PA_COMMAND_GET_MODULE_INFO
);
1527 pa_tagstruct_putu32(t
, tag
= c
->ctag
++);
1528 pa_tagstruct_putu32(t
, index
);
1529 pa_pstream_send_tagstruct(c
->pstream
, t
);
1530 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, context_get_module_info_callback
, c
);
1533 void pa_context_get_module_info_list(struct pa_context
*c
, void (*cb
)(struct pa_context
*c
, const struct pa_module_info
*i
, int is_last
, void *userdata
), void *userdata
) {
1534 struct pa_tagstruct
*t
;
1538 c
->get_module_info_callback
= cb
;
1539 c
->get_module_info_userdata
= userdata
;
1544 t
= pa_tagstruct_new(NULL
, 0);
1546 pa_tagstruct_putu32(t
, PA_COMMAND_GET_MODULE_INFO_LIST
);
1547 pa_tagstruct_putu32(t
, tag
= c
->ctag
++);
1548 pa_pstream_send_tagstruct(c
->pstream
, t
);
1549 pa_pdispatch_register_reply(c
->pdispatch
, tag
, DEFAULT_TIMEOUT
, context_get_module_info_callback
, c
);