mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2026-05-21 03:48:11 +02:00
There is some case that multiple ucm devices share an amixer Jack
like "Headphones", "Headset" and "Mic2" share the "Headphone Mic Jack",
When the Jack state is changed, the module-switch-on-port-available
will process them in the order they are in the jack->ucm_devices, and
the last device will decide the final setting.
But usually users put priority for those devices and expect the
final setting is based on the highest priority device if there is no
other policies like manual selection. So here do some change to store
the ucm_devices according to their priority (from low to high).
For example, we have ucm devices definition like below (ucm2):
SectionDevice."Mic2" {
Comment "Headphones Stereo Microphone"
...
Value {
CapturePriority 200
...
}
SectionDevice."Headset" {
Comment "Headset Mono Microphone"
...
Value {
CapturePriority 300
...
}
}
Without this patch, the final setting is based on Mic2, after applying
this patch, the final setting is based on the Headset (with higher
priority than Mic2).
Signed-off-by: Hui Wang <hui.wang@canonical.com>
165 lines
3.6 KiB
C
165 lines
3.6 KiB
C
/***
|
|
This file is part of PulseAudio.
|
|
|
|
Copyright 2004-2008 Lennart Poettering
|
|
|
|
PulseAudio is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU Lesser General Public License as
|
|
published by the Free Software Foundation; either version 2.1 of the
|
|
License, or (at your option) any later version.
|
|
|
|
PulseAudio is distributed in the hope that it will be useful, but
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
|
|
***/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <pulse/xmalloc.h>
|
|
#include <pulsecore/macro.h>
|
|
|
|
#include "dynarray.h"
|
|
|
|
struct pa_dynarray {
|
|
void **data;
|
|
unsigned n_allocated, n_entries;
|
|
pa_free_cb_t free_cb;
|
|
};
|
|
|
|
pa_dynarray* pa_dynarray_new(pa_free_cb_t free_cb) {
|
|
pa_dynarray *array;
|
|
|
|
array = pa_xnew0(pa_dynarray, 1);
|
|
array->free_cb = free_cb;
|
|
|
|
return array;
|
|
}
|
|
|
|
void pa_dynarray_free(pa_dynarray *array) {
|
|
unsigned i;
|
|
pa_assert(array);
|
|
|
|
if (array->free_cb)
|
|
for (i = 0; i < array->n_entries; i++)
|
|
array->free_cb(array->data[i]);
|
|
|
|
pa_xfree(array->data);
|
|
pa_xfree(array);
|
|
}
|
|
|
|
void pa_dynarray_append(pa_dynarray *array, void *p) {
|
|
pa_assert(array);
|
|
pa_assert(p);
|
|
|
|
if (array->n_entries == array->n_allocated) {
|
|
unsigned n = PA_MAX(array->n_allocated * 2, 25U);
|
|
|
|
array->data = pa_xrealloc(array->data, sizeof(void *) * n);
|
|
array->n_allocated = n;
|
|
}
|
|
|
|
array->data[array->n_entries++] = p;
|
|
}
|
|
|
|
void *pa_dynarray_get(pa_dynarray *array, unsigned i) {
|
|
pa_assert(array);
|
|
|
|
if (i >= array->n_entries)
|
|
return NULL;
|
|
|
|
return array->data[i];
|
|
}
|
|
|
|
void *pa_dynarray_last(pa_dynarray *array) {
|
|
pa_assert(array);
|
|
|
|
if (array->n_entries == 0)
|
|
return NULL;
|
|
|
|
return array->data[array->n_entries - 1];
|
|
}
|
|
|
|
int pa_dynarray_remove_by_index(pa_dynarray *array, unsigned i) {
|
|
void *entry;
|
|
|
|
pa_assert(array);
|
|
|
|
if (i >= array->n_entries)
|
|
return -PA_ERR_NOENTITY;
|
|
|
|
entry = array->data[i];
|
|
array->data[i] = array->data[array->n_entries - 1];
|
|
array->n_entries--;
|
|
|
|
if (array->free_cb)
|
|
array->free_cb(entry);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int pa_dynarray_remove_by_data(pa_dynarray *array, void *p) {
|
|
unsigned i;
|
|
|
|
pa_assert(array);
|
|
pa_assert(p);
|
|
|
|
/* Iterate backwards, with the assumption that recently appended entries
|
|
* are likely to be removed first. */
|
|
i = array->n_entries;
|
|
while (i > 0) {
|
|
i--;
|
|
if (array->data[i] == p) {
|
|
pa_dynarray_remove_by_index(array, i);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return -PA_ERR_NOENTITY;
|
|
}
|
|
|
|
void *pa_dynarray_steal_last(pa_dynarray *array) {
|
|
pa_assert(array);
|
|
|
|
if (array->n_entries > 0)
|
|
return array->data[--array->n_entries];
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
unsigned pa_dynarray_size(pa_dynarray *array) {
|
|
pa_assert(array);
|
|
|
|
return array->n_entries;
|
|
}
|
|
|
|
int pa_dynarray_insert_by_index(pa_dynarray *array, void *p, unsigned i) {
|
|
void *entry;
|
|
unsigned j;
|
|
|
|
pa_assert(array);
|
|
|
|
if (i > array->n_entries)
|
|
return -PA_ERR_NOENTITY;
|
|
|
|
if (i == array->n_entries)
|
|
pa_dynarray_append(array, p);
|
|
else {
|
|
entry = pa_dynarray_last(array);
|
|
pa_dynarray_append(array, entry);
|
|
j = array->n_entries - 2;
|
|
for (;j > i; j--)
|
|
array->data[j] = array->data[j-1];
|
|
array->data[i] = p;
|
|
}
|
|
|
|
return 0;
|
|
}
|