summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/modules/module-device-manager.c81
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;