pa_hook_slot *source_new_slot;
};
-static pa_device_port* find_best_port(pa_hashmap *ports) {
- void *state;
- pa_device_port* port, *result = NULL;
-
- PA_HASHMAP_FOREACH(port, ports, state) {
- if (result == NULL ||
- result->available == PA_AVAILABLE_NO ||
- (port->available != PA_AVAILABLE_NO && port->priority > result->priority)) {
- result = port;
- }
- }
-
- return result;
-}
-
static bool profile_good_for_output(pa_card_profile *profile) {
pa_sink *sink;
uint32_t idx;
return true;
}
-static pa_bool_t try_to_switch_profile(pa_device_port *port) {
+static int try_to_switch_profile(pa_device_port *port) {
pa_card_profile *best_profile = NULL, *profile;
void *state;
pa_log_debug("Finding best profile");
PA_HASHMAP_FOREACH(profile, port->profiles, state) {
- pa_direction_t direction = port->is_output ? PA_DIRECTION_OUTPUT : PA_DIRECTION_INPUT;
- bool good;
+ bool good = false;
if (best_profile && best_profile->priority >= profile->priority)
continue;
/* We make a best effort to keep other direction unchanged */
- switch (direction) {
+ switch (port->direction) {
case PA_DIRECTION_OUTPUT:
good = profile_good_for_output(profile);
break;
if (!best_profile) {
pa_log_debug("No suitable profile found");
- return FALSE;
+ return -1;
}
- if (pa_card_set_profile(port->card, best_profile->name, FALSE) != 0) {
+ if (pa_card_set_profile(port->card, best_profile, false) != 0) {
pa_log_debug("Could not set profile %s", best_profile->name);
- return FALSE;
+ return -1;
}
- return TRUE;
+ return 0;
}
-static void find_sink_and_source(pa_card *card, pa_device_port *port, pa_sink **si, pa_source **so)
-{
+static void find_sink_and_source(pa_card *card, pa_device_port *port, pa_sink **si, pa_source **so) {
pa_sink *sink = NULL;
pa_source *source = NULL;
uint32_t state;
- if (port->is_output)
- PA_IDXSET_FOREACH(sink, card->sinks, state)
- if (port == pa_hashmap_get(sink->ports, port->name))
- break;
+ switch (port->direction) {
+ case PA_DIRECTION_OUTPUT:
+ PA_IDXSET_FOREACH(sink, card->sinks, state)
+ if (port == pa_hashmap_get(sink->ports, port->name))
+ break;
+ break;
- if (port->is_input)
- PA_IDXSET_FOREACH(source, card->sources, state)
- if (port == pa_hashmap_get(source->ports, port->name))
- break;
+ case PA_DIRECTION_INPUT:
+ PA_IDXSET_FOREACH(source, card->sources, state)
+ if (port == pa_hashmap_get(source->ports, port->name))
+ break;
+ break;
+ }
*si = sink;
*so = source;
}
static pa_hook_result_t port_available_hook_callback(pa_core *c, pa_device_port *port, void* userdata) {
- uint32_t state;
pa_card* card;
pa_sink *sink;
pa_source *source;
- pa_bool_t is_active_profile, is_active_port;
+ bool is_active_profile, is_active_port;
if (port->available == PA_AVAILABLE_UNKNOWN)
return PA_HOOK_OK;
- pa_log_debug("finding port %s", port->name);
-
- PA_IDXSET_FOREACH(card, c->cards, state)
- if (port == pa_hashmap_get(card->ports, port->name))
- break;
+ card = port->card;
if (!card) {
- pa_log_warn("Did not find port %s in array of cards", port->name);
+ pa_log_warn("Port %s does not have a card", port->name);
return PA_HOOK_OK;
}
+ if (pa_idxset_size(card->sinks) == 0 && pa_idxset_size(card->sources) == 0)
+ /* This card is not initialized yet. We'll handle it in
+ sink_new / source_new callbacks later. */
+ return PA_HOOK_OK;
+
find_sink_and_source(card, port, &sink, &source);
is_active_profile = card->active_profile == pa_hashmap_get(port->profiles, card->active_profile->name);
return PA_HOOK_OK;
if (!is_active_profile) {
- if (!try_to_switch_profile(port))
+ if (try_to_switch_profile(port) < 0)
return PA_HOOK_OK;
pa_assert(card->active_profile == pa_hashmap_get(port->profiles, card->active_profile->name));
}
if (source)
- pa_source_set_port(source, port->name, FALSE);
+ pa_source_set_port(source, port->name, false);
if (sink)
- pa_sink_set_port(sink, port->name, FALSE);
+ pa_sink_set_port(sink, port->name, false);
}
if (port->available == PA_AVAILABLE_NO) {
if (sink) {
- pa_device_port *p2 = find_best_port(sink->ports);
+ pa_device_port *p2 = pa_device_port_find_best(sink->ports);
if (p2 && p2->available != PA_AVAILABLE_NO)
- pa_sink_set_port(sink, p2->name, FALSE);
+ pa_sink_set_port(sink, p2->name, false);
else {
/* Maybe try to switch to another profile? */
}
}
if (source) {
- pa_device_port *p2 = find_best_port(source->ports);
+ pa_device_port *p2 = pa_device_port_find_best(source->ports);
if (p2 && p2->available != PA_AVAILABLE_NO)
- pa_source_set_port(source, p2->name, FALSE);
+ pa_source_set_port(source, p2->name, false);
else {
/* Maybe try to switch to another profile? */
}
if (p->available != PA_AVAILABLE_NO)
return NULL;
- pa_assert_se(p = find_best_port(ports));
+ pa_assert_se(p = pa_device_port_find_best(ports));
return p;
}
return PA_HOOK_OK;
}
-
int pa__init(pa_module*m) {
struct userdata *u;