2 * module-murphy-ivi -- PulseAudio module for providing audio routing support
3 * Copyright (c) 2012, Intel Corporation.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU Lesser General Public License,
7 * version 2.1, as published by the Free Software Foundation.
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.
12 * See the GNU Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this program; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
20 #include <pulsecore/pulsecore-config.h>
22 #include <pulse/def.h>
23 #include <pulsecore/card.h>
32 struct pa_card_hooks {
35 pa_hook_slot *profchg;
38 struct pa_port_hooks {
42 struct pa_sink_hooks {
45 pa_hook_slot *portchg;
48 struct pa_source_hooks {
51 pa_hook_slot *portchg;
54 struct pa_sink_input_hooks {
65 pa_source_hooks source;
66 pa_sink_input_hooks sink_input;
70 static pa_hook_result_t card_put(void *, void *, void *);
71 static pa_hook_result_t card_unlink(void *, void *, void *);
72 static pa_hook_result_t card_profile_changed(void *, void *, void *);
74 static pa_hook_result_t port_available_changed(void *, void *, void *);
76 static pa_hook_result_t sink_put(void *, void *, void *);
77 static pa_hook_result_t sink_unlink(void *, void *, void *);
78 static pa_hook_result_t sink_port_changed(void *, void *, void *);
80 static pa_hook_result_t source_put(void *, void *, void *);
81 static pa_hook_result_t source_unlink(void *, void *, void *);
82 static pa_hook_result_t source_port_changed(void *, void *, void *);
84 static pa_hook_result_t sink_input_new(void *, void *, void *);
85 static pa_hook_result_t sink_input_put(void *, void *, void *);
86 static pa_hook_result_t sink_input_unlink(void *, void *, void *);
89 pa_tracker *pa_tracker_init(struct userdata *u)
97 pa_source_hooks *source;
98 pa_sink_input_hooks *sinp;
101 pa_assert_se((core = u->core));
102 pa_assert_se((hooks = core->hooks));
104 tracker = pa_xnew0(pa_tracker, 1);
105 card = &tracker->card;
106 port = &tracker->port;
107 sink = &tracker->sink;
108 source = &tracker->source;
109 sinp = &tracker->sink_input;
112 card->put = pa_hook_connect(
113 hooks + PA_CORE_HOOK_CARD_PUT,
114 PA_HOOK_LATE, card_put, u
116 card->unlink = pa_hook_connect(
117 hooks + PA_CORE_HOOK_CARD_UNLINK,
118 PA_HOOK_LATE, card_unlink, u
120 card->profchg = pa_hook_connect(
121 hooks + PA_CORE_HOOK_CARD_PROFILE_CHANGED,
122 PA_HOOK_LATE, card_profile_changed, u
125 port->avail = pa_hook_connect(
126 hooks + PA_CORE_HOOK_PORT_AVAILABLE_CHANGED,
127 PA_HOOK_LATE, port_available_changed, u
130 sink->put = pa_hook_connect(
131 hooks + PA_CORE_HOOK_SINK_PUT,
132 PA_HOOK_LATE, sink_put, u
134 sink->unlink = pa_hook_connect(
135 hooks + PA_CORE_HOOK_SINK_UNLINK,
136 PA_HOOK_LATE, sink_unlink, u
138 sink->portchg = pa_hook_connect(
139 hooks + PA_CORE_HOOK_SINK_PORT_CHANGED,
140 PA_HOOK_LATE, sink_port_changed, u
143 source->put = pa_hook_connect(
144 hooks + PA_CORE_HOOK_SOURCE_PUT,
145 PA_HOOK_LATE, source_put, u
147 source->unlink = pa_hook_connect(
148 hooks + PA_CORE_HOOK_SOURCE_UNLINK,
149 PA_HOOK_LATE, source_unlink, u
151 source->portchg = pa_hook_connect(
152 hooks + PA_CORE_HOOK_SOURCE_PORT_CHANGED,
153 PA_HOOK_LATE, source_port_changed, u
156 sinp->neew = pa_hook_connect(
157 hooks + PA_CORE_HOOK_SINK_INPUT_NEW,
158 PA_HOOK_EARLY, sink_input_new, u
160 sinp->put = pa_hook_connect(
161 hooks + PA_CORE_HOOK_SINK_INPUT_PUT,
162 PA_HOOK_LATE, sink_input_put, u
164 sinp->unlink = pa_hook_connect(
165 hooks + PA_CORE_HOOK_SINK_INPUT_UNLINK,
166 PA_HOOK_LATE, sink_input_unlink, u
172 void pa_tracker_done(struct userdata *u)
178 pa_source_hooks *source;
179 pa_sink_input_hooks *sinp;
181 if (u && (tracker = u->tracker)) {
183 card = &tracker->card;
184 pa_hook_slot_free(card->put);
185 pa_hook_slot_free(card->unlink);
186 pa_hook_slot_free(card->profchg);
188 port = &tracker->port;
189 pa_hook_slot_free(port->avail);
191 sink = &tracker->sink;
192 pa_hook_slot_free(sink->put);
193 pa_hook_slot_free(sink->unlink);
194 pa_hook_slot_free(sink->portchg);
196 source = &tracker->source;
197 pa_hook_slot_free(source->put);
198 pa_hook_slot_free(source->unlink);
199 pa_hook_slot_free(source->portchg);
201 sinp = &tracker->sink_input;
202 pa_hook_slot_free(sinp->neew);
203 pa_hook_slot_free(sinp->put);
204 pa_hook_slot_free(sinp->unlink);
212 void pa_tracker_synchronize(struct userdata *u)
222 pa_assert_se((core = u->core));
225 PA_IDXSET_FOREACH(card, core->cards, index) {
226 pa_discover_add_card(u, card);
229 PA_IDXSET_FOREACH(sink, core->sinks, index) {
230 pa_discover_add_sink(u, sink, FALSE);
233 PA_IDXSET_FOREACH(source, core->sources, index) {
234 pa_discover_add_source(u, source);
237 /* Hmm... we should first collect all sink-inputs, assign
238 priority to them, sort them, and call pa_discover_register_sink_input()
239 in reverse priority order. Until than we may experience sound leaks
240 unnecessary profile changes etc ... */
242 PA_IDXSET_FOREACH(sinp, core->sink_inputs, index) {
243 pa_discover_register_sink_input(u, sinp);
246 mir_router_make_routing(u);
250 static pa_hook_result_t card_put(void *hook_data,
254 pa_card *card = (pa_card *)call_data;
255 struct userdata *u = (struct userdata *)slot_data;
260 pa_discover_add_card(u, card);
265 static pa_hook_result_t card_unlink(void *hook_data,
269 pa_card *card = (pa_card *)call_data;
270 struct userdata *u = (struct userdata *)slot_data;
276 pa_discover_remove_card(u, card);
278 mir_router_print_rtgroups(u, buf, sizeof(buf));
279 pa_log_debug("%s", buf);
281 mir_router_make_routing(u);
287 static pa_hook_result_t card_profile_changed(void *hook_data,
291 pa_card *card = (pa_card *)call_data;
292 struct userdata *u = (struct userdata *)slot_data;
297 pa_discover_profile_changed(u, card);
303 static pa_hook_result_t port_available_changed(void *hook_data,
307 pa_device_port *port = (pa_device_port *)call_data;
308 struct userdata *u = (struct userdata *)slot_data;
313 pa_discover_port_available_changed(u, port);
320 static pa_hook_result_t sink_put(void *hook_data,
324 pa_sink *sink = (pa_sink *)call_data;
325 struct userdata *u = (struct userdata *)slot_data;
330 pa_discover_add_sink(u, sink, TRUE);
336 static pa_hook_result_t sink_unlink(void *hook_data,
340 pa_sink *sink = (pa_sink *)call_data;
341 struct userdata *u = (struct userdata *)slot_data;
346 pa_discover_remove_sink(u, sink);
352 static pa_hook_result_t sink_port_changed(void *hook_data,
356 pa_sink *sink = (pa_sink *)call_data;
357 struct userdata *u = (struct userdata *)slot_data;
367 static pa_hook_result_t source_put(void *hook_data,
371 pa_source *source = (pa_source *)call_data;
372 struct userdata *u = (struct userdata *)slot_data;
377 pa_discover_add_source(u, source);
383 static pa_hook_result_t source_unlink(void *hook_data,
387 pa_source *source = (pa_source *)call_data;
388 struct userdata *u = (struct userdata *)slot_data;
393 pa_discover_remove_source(u, source);
399 static pa_hook_result_t source_port_changed(void *hook_data,
403 pa_source *source = (pa_source *)call_data;
404 struct userdata *u = (struct userdata *)slot_data;
414 static pa_hook_result_t sink_input_new(void *hook_data,
418 pa_sink_input_new_data *data = (pa_sink_input_new_data *)call_data;
419 struct userdata *u = (struct userdata *)slot_data;
424 pa_discover_preroute_sink_input(u, data);
429 static pa_hook_result_t sink_input_put(void *hook_data,
433 pa_sink_input *sinp = (pa_sink_input *)call_data;
434 struct userdata *u = (struct userdata *)slot_data;
439 pa_discover_add_sink_input(u, sinp);
445 static pa_hook_result_t sink_input_unlink(void *hook_data,
449 struct pa_sink_input *sinp = (pa_sink_input *)call_data;
450 struct userdata *u = (struct userdata *)slot_data;
455 pa_discover_remove_sink_input(u, sinp);
464 * indent-tabs-mode: nil