mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-31 22:25:38 -04:00
acp: add support for hiding profiles and ports
api.acp.hidden-ports and api.acp.hidden-profiles can be used to pass a json array of ports and profiles to hide. They will not show and will not be selectable.
This commit is contained in:
parent
85a9e30908
commit
a532c2abdb
3 changed files with 52 additions and 2 deletions
|
|
@ -7,6 +7,7 @@
|
||||||
#include "alsa-ucm.h"
|
#include "alsa-ucm.h"
|
||||||
|
|
||||||
#include <spa/utils/string.h>
|
#include <spa/utils/string.h>
|
||||||
|
#include <spa/utils/json.h>
|
||||||
|
|
||||||
int _acp_log_level = 1;
|
int _acp_log_level = 1;
|
||||||
acp_log_func _acp_log_func;
|
acp_log_func _acp_log_func;
|
||||||
|
|
@ -449,6 +450,24 @@ static int add_pro_profile(pa_card *impl, uint32_t index)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool contains_string(const char *arr, const char *str)
|
||||||
|
{
|
||||||
|
struct spa_json it[2];
|
||||||
|
char v[256];
|
||||||
|
|
||||||
|
if (arr == NULL || str == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
spa_json_init(&it[0], arr, strlen(arr));
|
||||||
|
if (spa_json_enter_array(&it[0], &it[1]) <= 0)
|
||||||
|
spa_json_init(&it[1], arr, strlen(arr));
|
||||||
|
|
||||||
|
while (spa_json_get_string(&it[1], v, sizeof(v)) > 0) {
|
||||||
|
if (spa_streq(v, str))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static void add_profiles(pa_card *impl)
|
static void add_profiles(pa_card *impl)
|
||||||
{
|
{
|
||||||
|
|
@ -459,6 +478,7 @@ static void add_profiles(pa_card *impl)
|
||||||
pa_alsa_device *dev;
|
pa_alsa_device *dev;
|
||||||
int n_profiles, n_ports, n_devices;
|
int n_profiles, n_ports, n_devices;
|
||||||
uint32_t idx;
|
uint32_t idx;
|
||||||
|
const char *arr;
|
||||||
|
|
||||||
n_devices = 0;
|
n_devices = 0;
|
||||||
pa_dynarray_init(&impl->out.devices, device_free);
|
pa_dynarray_init(&impl->out.devices, device_free);
|
||||||
|
|
@ -561,7 +581,10 @@ static void add_profiles(pa_card *impl)
|
||||||
dev->device.ports = dev->port_array.array.data;
|
dev->device.ports = dev->port_array.array.data;
|
||||||
dev->device.n_ports = pa_dynarray_size(&dev->port_array);
|
dev->device.n_ports = pa_dynarray_size(&dev->port_array);
|
||||||
}
|
}
|
||||||
|
arr = pa_proplist_gets(impl->proplist, "api.acp.hidden-ports");
|
||||||
PA_HASHMAP_FOREACH(dp, impl->ports, state) {
|
PA_HASHMAP_FOREACH(dp, impl->ports, state) {
|
||||||
|
if (contains_string(arr, dp->name))
|
||||||
|
dp->port.flags |= ACP_PORT_HIDDEN;
|
||||||
dp->port.devices = dp->devices.array.data;
|
dp->port.devices = dp->devices.array.data;
|
||||||
dp->port.n_devices = pa_dynarray_size(&dp->devices);
|
dp->port.n_devices = pa_dynarray_size(&dp->devices);
|
||||||
}
|
}
|
||||||
|
|
@ -570,7 +593,10 @@ static void add_profiles(pa_card *impl)
|
||||||
|
|
||||||
n_profiles = 0;
|
n_profiles = 0;
|
||||||
pa_dynarray_init(&impl->out.profiles, NULL);
|
pa_dynarray_init(&impl->out.profiles, NULL);
|
||||||
|
arr = pa_proplist_gets(impl->proplist, "api.acp.hidden-profiles");
|
||||||
PA_HASHMAP_FOREACH(cp, impl->profiles, state) {
|
PA_HASHMAP_FOREACH(cp, impl->profiles, state) {
|
||||||
|
if (contains_string(arr, cp->name))
|
||||||
|
cp->flags |= ACP_PROFILE_HIDDEN;
|
||||||
cp->index = n_profiles++;
|
cp->index = n_profiles++;
|
||||||
pa_dynarray_append(&impl->out.profiles, cp);
|
pa_dynarray_append(&impl->out.profiles, cp);
|
||||||
}
|
}
|
||||||
|
|
@ -1021,6 +1047,9 @@ uint32_t acp_card_find_best_profile_index(struct acp_card *card, const char *nam
|
||||||
for (i = 0; i < card->n_profiles; i++) {
|
for (i = 0; i < card->n_profiles; i++) {
|
||||||
struct acp_card_profile *p = profiles[i];
|
struct acp_card_profile *p = profiles[i];
|
||||||
|
|
||||||
|
if (SPA_FLAG_IS_SET(p->flags, ACP_PROFILE_HIDDEN))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (name) {
|
if (name) {
|
||||||
if (spa_streq(name, p->name))
|
if (spa_streq(name, p->name))
|
||||||
best = i;
|
best = i;
|
||||||
|
|
@ -1440,9 +1469,11 @@ int acp_card_set_profile(struct acp_card *card, uint32_t new_index, uint32_t fla
|
||||||
if (new_index >= card->n_profiles)
|
if (new_index >= card->n_profiles)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
op = old_index != ACP_INVALID_INDEX ? (pa_alsa_profile*)profiles[old_index] : NULL;
|
|
||||||
np = (pa_alsa_profile*)profiles[new_index];
|
np = (pa_alsa_profile*)profiles[new_index];
|
||||||
|
if (SPA_FLAG_IS_SET(np->profile.flags, ACP_PROFILE_HIDDEN))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
op = old_index != ACP_INVALID_INDEX ? (pa_alsa_profile*)profiles[old_index] : NULL;
|
||||||
if (op == np)
|
if (op == np)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
@ -1830,6 +1861,9 @@ uint32_t acp_device_find_best_port_index(struct acp_device *dev, const char *nam
|
||||||
for (i = 0; i < dev->n_ports; i++) {
|
for (i = 0; i < dev->n_ports; i++) {
|
||||||
struct acp_port *p = ports[i];
|
struct acp_port *p = ports[i];
|
||||||
|
|
||||||
|
if (SPA_FLAG_IS_SET(p->flags, ACP_PORT_HIDDEN))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (name) {
|
if (name) {
|
||||||
if (spa_streq(name, p->name))
|
if (spa_streq(name, p->name))
|
||||||
best = i;
|
best = i;
|
||||||
|
|
@ -1869,6 +1903,8 @@ int acp_device_set_port(struct acp_device *dev, uint32_t port_index, uint32_t fl
|
||||||
p = (pa_device_port*)impl->card.ports[port_index];
|
p = (pa_device_port*)impl->card.ports[port_index];
|
||||||
if (!pa_hashmap_get(d->ports, p->name))
|
if (!pa_hashmap_get(d->ports, p->name))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
if (SPA_FLAG_IS_SET(p->port.flags, ACP_PORT_HIDDEN))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
p->port.flags = ACP_PORT_ACTIVE | flags;
|
p->port.flags = ACP_PORT_ACTIVE | flags;
|
||||||
if (p == old)
|
if (p == old)
|
||||||
|
|
|
||||||
|
|
@ -167,6 +167,7 @@ struct acp_port {
|
||||||
uint32_t index; /**< unique index for this port */
|
uint32_t index; /**< unique index for this port */
|
||||||
#define ACP_PORT_ACTIVE (1<<0)
|
#define ACP_PORT_ACTIVE (1<<0)
|
||||||
#define ACP_PORT_SAVE (1<<1) /* if the port needs saving */
|
#define ACP_PORT_SAVE (1<<1) /* if the port needs saving */
|
||||||
|
#define ACP_PORT_HIDDEN (1<<2)
|
||||||
uint32_t flags; /**< extra port flags */
|
uint32_t flags; /**< extra port flags */
|
||||||
|
|
||||||
const char *name; /**< Name of this port */
|
const char *name; /**< Name of this port */
|
||||||
|
|
@ -190,6 +191,7 @@ struct acp_device {
|
||||||
#define ACP_DEVICE_HW_MUTE (1<<2)
|
#define ACP_DEVICE_HW_MUTE (1<<2)
|
||||||
#define ACP_DEVICE_UCM_DEVICE (1<<3)
|
#define ACP_DEVICE_UCM_DEVICE (1<<3)
|
||||||
#define ACP_DEVICE_IEC958 (1<<4)
|
#define ACP_DEVICE_IEC958 (1<<4)
|
||||||
|
#define ACP_DEVICE_HIDDEN (1<<5)
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
|
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
@ -218,6 +220,7 @@ struct acp_card_profile {
|
||||||
#define ACP_PROFILE_OFF (1<<1) /* the Off profile */
|
#define ACP_PROFILE_OFF (1<<1) /* the Off profile */
|
||||||
#define ACP_PROFILE_SAVE (1<<2) /* if the profile needs saving */
|
#define ACP_PROFILE_SAVE (1<<2) /* if the profile needs saving */
|
||||||
#define ACP_PROFILE_PRO (1<<3) /* the Pro profile */
|
#define ACP_PROFILE_PRO (1<<3) /* the Pro profile */
|
||||||
|
#define ACP_PROFILE_HIDDEN (1<<4) /* don't show the profile */
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
|
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
|
||||||
|
|
@ -516,14 +516,17 @@ static int impl_enum_params(void *object, int seq,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
pr = card->profiles[result.index];
|
pr = card->profiles[result.index];
|
||||||
|
if (SPA_FLAG_IS_SET(pr->flags, ACP_PROFILE_HIDDEN))
|
||||||
|
goto next;
|
||||||
param = build_profile(&b.b, id, pr, false);
|
param = build_profile(&b.b, id, pr, false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SPA_PARAM_Profile:
|
case SPA_PARAM_Profile:
|
||||||
if (result.index > 0 || card->active_profile_index >= card->n_profiles)
|
if (result.index > 0 || card->active_profile_index >= card->n_profiles)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
pr = card->profiles[card->active_profile_index];
|
pr = card->profiles[card->active_profile_index];
|
||||||
|
if (SPA_FLAG_IS_SET(pr->flags, ACP_PROFILE_HIDDEN))
|
||||||
|
goto next;
|
||||||
param = build_profile(&b.b, id, pr, true);
|
param = build_profile(&b.b, id, pr, true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -532,6 +535,8 @@ static int impl_enum_params(void *object, int seq,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
p = card->ports[result.index];
|
p = card->ports[result.index];
|
||||||
|
if (SPA_FLAG_IS_SET(p->flags, ACP_PORT_HIDDEN))
|
||||||
|
goto next;
|
||||||
param = build_route(&b.b, id, p, NULL, SPA_ID_INVALID);
|
param = build_route(&b.b, id, p, NULL, SPA_ID_INVALID);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -541,6 +546,8 @@ static int impl_enum_params(void *object, int seq,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
dev = card->devices[result.index];
|
dev = card->devices[result.index];
|
||||||
|
if (SPA_FLAG_IS_SET(dev->flags, ACP_DEVICE_HIDDEN))
|
||||||
|
goto next;
|
||||||
if (SPA_FLAG_IS_SET(dev->flags, ACP_DEVICE_ACTIVE) &&
|
if (SPA_FLAG_IS_SET(dev->flags, ACP_DEVICE_ACTIVE) &&
|
||||||
(p = find_port_for_device(card, dev)) != NULL)
|
(p = find_port_for_device(card, dev)) != NULL)
|
||||||
break;
|
break;
|
||||||
|
|
@ -548,6 +555,8 @@ static int impl_enum_params(void *object, int seq,
|
||||||
result.index++;
|
result.index++;
|
||||||
}
|
}
|
||||||
result.next = result.index + 1;
|
result.next = result.index + 1;
|
||||||
|
if (SPA_FLAG_IS_SET(p->flags, ACP_PORT_HIDDEN))
|
||||||
|
goto next;
|
||||||
param = build_route(&b.b, id, p, dev, card->active_profile_index);
|
param = build_route(&b.b, id, p, dev, card->active_profile_index);
|
||||||
if (param == NULL)
|
if (param == NULL)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
@ -754,6 +763,8 @@ static int impl_set_param(void *object,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
dev = this->card->devices[device];
|
dev = this->card->devices[device];
|
||||||
|
if (SPA_FLAG_IS_SET(dev->flags, ACP_DEVICE_HIDDEN))
|
||||||
|
return -EINVAL;
|
||||||
acp_device_set_port(dev, idx, save ? ACP_PORT_SAVE : 0);
|
acp_device_set_port(dev, idx, save ? ACP_PORT_SAVE : 0);
|
||||||
if (props)
|
if (props)
|
||||||
apply_device_props(this, dev, props);
|
apply_device_props(this, dev, props);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue