From 1b1ab6b6241792508b095020587e1ab3d0e9d862 Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Mon, 18 Nov 2019 13:22:44 +0900 Subject: [PATCH] ctl: card: add an API to get information of element --- src/ctl/alsactl.map | 1 + src/ctl/card.c | 88 +++++++++++++++++++++++++++++++++++++++++++++ src/ctl/card.h | 4 +++ tests/alsactl-card | 1 + 4 files changed, 94 insertions(+) diff --git a/src/ctl/alsactl.map b/src/ctl/alsactl.map index 55c2377..cb85df7 100644 --- a/src/ctl/alsactl.map +++ b/src/ctl/alsactl.map @@ -17,6 +17,7 @@ ALSA_GOBJECT_0_0_0 { "alsactl_card_get_info"; "alsactl_card_get_elem_id_list"; "alsactl_card_lock_elem"; + "alsactl_card_get_elem_info"; "alsactl_card_info_get_type"; diff --git a/src/ctl/card.c b/src/ctl/card.c index 4d9e08b..061ab54 100644 --- a/src/ctl/card.c +++ b/src/ctl/card.c @@ -1,6 +1,12 @@ // SPDX-License-Identifier: LGPL-3.0-or-later #include "card.h" #include "query.h" +#include "elem-info-bool.h" +#include "elem-info-int.h" +#include "elem-info-enum.h" +#include "elem-info-bytes.h" +#include "elem-info-iec60958.h" +#include "elem-info-int64.h" #include "privates.h" #include @@ -251,3 +257,85 @@ void alsactl_card_lock_elem(ALSACtlCard *self, const ALSACtlElemId *elem_id, if (ret < 0) generate_error(error, errno); } + +/** + * alsactl_card_get_elem_info: + * @self: A #ALSACtlCard. + * @elem_id: A #ALSACtlElemId. + * @elem_info: (out): A %ALSACtlElemInfo. + * @error: A #GError. + * + * Get information of element corresponding to given id. + */ +void alsactl_card_get_elem_info(ALSACtlCard *self, const ALSACtlElemId *elem_id, + ALSACtlElemInfo **elem_info, GError **error) +{ + ALSACtlCardPrivate *priv; + struct snd_ctl_elem_info *info_ptr, info = {0}; + + g_return_if_fail(ALSACTL_IS_CARD(self)); + g_return_if_fail(elem_id != NULL); + priv = alsactl_card_get_instance_private(self); + + info.id = *elem_id; + if (ioctl(priv->fd, SNDRV_CTL_IOCTL_ELEM_INFO, &info)) { + generate_error(error, errno); + return; + } + + if (info.type != SNDRV_CTL_ELEM_TYPE_ENUMERATED) { + switch (info.type) { + case SNDRV_CTL_ELEM_TYPE_BOOLEAN: + *elem_info = g_object_new(ALSACTL_TYPE_ELEM_INFO_BOOL, NULL); + break; + case SNDRV_CTL_ELEM_TYPE_INTEGER: + *elem_info = g_object_new(ALSACTL_TYPE_ELEM_INFO_INT, NULL); + break; + case SNDRV_CTL_ELEM_TYPE_BYTES: + *elem_info = g_object_new(ALSACTL_TYPE_ELEM_INFO_BYTES, NULL); + break; + case SNDRV_CTL_ELEM_TYPE_IEC958: + *elem_info = g_object_new(ALSACTL_TYPE_ELEM_INFO_IEC60958, NULL); + break; + case SNDRV_CTL_ELEM_TYPE_INTEGER64: + *elem_info = g_object_new(ALSACTL_TYPE_ELEM_INFO_INT64, NULL); + break; + default: + generate_error(error, ENXIO); + return; + } + } else { + gchar **labels; + int i; + + labels = g_malloc0_n(info.value.enumerated.items + 1, sizeof(*labels)); + if (labels == NULL) { + generate_error(error, ENOMEM); + return; + } + + for (i = 0; i < info.value.enumerated.items; ++i) { + info.value.enumerated.item = i; + if (ioctl(priv->fd, SNDRV_CTL_IOCTL_ELEM_INFO, &info)) { + generate_error(error, errno); + g_strfreev(labels); + return; + } + + labels[i] = strdup(info.value.enumerated.name); + if (labels[i] == NULL) { + generate_error(error, ENOMEM); + g_strfreev(labels); + return; + } + } + labels[info.value.enumerated.items] = NULL; + + *elem_info = g_object_new(ALSACTL_TYPE_ELEM_INFO_ENUM, "labels", labels, + NULL); + g_strfreev(labels); + } + + ctl_elem_info_refer_private(ALSACTL_ELEM_INFO(*elem_info), &info_ptr); + *info_ptr = info; +} diff --git a/src/ctl/card.h b/src/ctl/card.h index 526c917..8dacecb 100644 --- a/src/ctl/card.h +++ b/src/ctl/card.h @@ -7,6 +7,7 @@ #include #include +#include G_BEGIN_DECLS @@ -61,6 +62,9 @@ void alsactl_card_get_elem_id_list(ALSACtlCard *self, GList **entries, void alsactl_card_lock_elem(ALSACtlCard *self, const ALSACtlElemId *elem_id, gboolean lock, GError **error); +void alsactl_card_get_elem_info(ALSACtlCard *self, const ALSACtlElemId *elem_id, + ALSACtlElemInfo **elem_info, GError **error); + G_END_DECLS #endif diff --git a/tests/alsactl-card b/tests/alsactl-card index 2b550e7..12ca1c9 100644 --- a/tests/alsactl-card +++ b/tests/alsactl-card @@ -19,6 +19,7 @@ methods = ( 'get_info', 'get_elem_id_list', 'lock_elem', + 'get_elem_info', ) signals = () -- 2.47.3