diff options
-rw-r--r-- | src/modules/module-device-manager.c | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/src/modules/module-device-manager.c b/src/modules/module-device-manager.c index 38b4c025..f4d00b55 100644 --- a/src/modules/module-device-manager.c +++ b/src/modules/module-device-manager.c @@ -402,6 +402,87 @@ static char *get_name(const char *key, const char *prefix) { return t; } +static role_indexes_t *get_highest_priority_device_indexes(struct userdata *u, const char *prefix) { + role_indexes_t *indexes, highest_priority_available; + pa_datum key; + pa_bool_t done; + + pa_assert(u); + pa_assert(prefix); + + indexes = pa_xnew(role_indexes_t, 1); + for (uint32_t i = 0; i < NUM_ROLES; ++i) { + *indexes[i] = PA_INVALID_INDEX; + } + pa_zero(highest_priority_available); + + done = !pa_database_first(u->database, &key, NULL); + + /* Find all existing devices with the same prefix so we find the highest priority device for each role */ + while (!done) { + pa_datum next_key; + + done = !pa_database_next(u->database, &key, &next_key, NULL); + + if (key.size > strlen(prefix) && strncmp(key.data, prefix, strlen(prefix)) == 0) { + char *name; + struct entry *e; + + name = pa_xstrndup(key.data, key.size); + + if ((e = read_entry(u, name))) { + for (uint32_t i = 0; i < NUM_ROLES; ++i) { + if (highest_priority_available[i] && e->priority[i] < highest_priority_available[i]) { + /* We've found a device with a higher priority than that we've currently got, + so see if it is currently available or not and update our list */ + uint32_t idx; + pa_bool_t found = FALSE; + char *device_name = get_name(name, prefix); + + if (strcmp(prefix, "sink:") == 0) { + pa_sink *sink; + + PA_IDXSET_FOREACH(sink, u->core->sinks, idx) { + if (strcmp(sink->name, device_name) == 0) { + found = TRUE; + idx = sink->index; /* Is this needed? */ + break; + } + } + } else { + pa_source *source; + + PA_IDXSET_FOREACH(source, u->core->sources, idx) { + if (strcmp(source->name, device_name) == 0) { + found = TRUE; + idx = source->index; /* Is this needed? */ + break; + } + } + } + if (found) { + highest_priority_available[i] = e->priority[i]; + *indexes[i] = idx; + } + + pa_xfree(device_name); + } + } + + pa_xfree(e); + } + + pa_xfree(name); + } + + pa_datum_free(&key); + key = next_key; + } + + return indexes; +} + + static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_new_data *new_data, struct userdata *u) { char *name; struct entry *e; |