From: Takashi Sakamoto Date: Wed, 27 Nov 2019 07:08:52 +0000 (+0900) Subject: hwdep: add global method to get information of hwdep device X-Git-Tag: v0.1.0~198 X-Git-Url: https://git.alsa-project.org/?a=commitdiff_plain;h=53d99ede24864fb9b45ef4e98f1ee92c83e670dd;p=alsa-gobject.git hwdep: add global method to get information of hwdep device Signed-off-by: Takashi Sakamoto --- diff --git a/src/hwdep/alsahwdep.map b/src/hwdep/alsahwdep.map index 58b4aac..979c109 100644 --- a/src/hwdep/alsahwdep.map +++ b/src/hwdep/alsahwdep.map @@ -5,6 +5,7 @@ ALSA_GOBJECT_0_0_0 { "alsahwdep_get_device_id_list"; "alsahwdep_get_hwdep_sysname"; "alsahwdep_get_hwdep_devnode"; + "alsahwdep_get_device_info"; "alsahwdep_device_info_get_type"; local: diff --git a/src/hwdep/device-info.c b/src/hwdep/device-info.c index 409c0e5..44ff77e 100644 --- a/src/hwdep/device-info.c +++ b/src/hwdep/device-info.c @@ -1,7 +1,5 @@ // SPDX-License-Identifier: LGPL-3.0-or-later -#include "device-info.h" - -#include +#include "privates.h" struct _ALSAHwdepDeviceInfoPrivate { struct snd_hwdep_info info; @@ -27,19 +25,19 @@ static void hwdep_device_info_get_property(GObject *obj, guint id, GValue *val, switch (id) { case HWDEP_DEVICE_INFO_PROP_DEVICE_ID: - priv->info.device = g_value_get_uint(val); + g_value_set_uint(val, priv->info.device); break; case HWDEP_DEVICE_INFO_PROP_CARD_ID: - priv->info.card = g_value_get_int(val); + g_value_set_int(val, priv->info.card); break; case HWDEP_DEVICE_INFO_PROP_ID: - strncpy((char *)priv->info.id, g_value_get_string(val), sizeof(priv->info.id)); + g_value_set_static_string(val, (char *)priv->info.id); break; case HWDEP_DEVICE_INFO_PROP_NAME: - strncpy((char *)priv->info.name, g_value_get_string(val), sizeof(priv->info.name)); + g_value_set_static_string(val, (char *)priv->info.name); break; case HWDEP_DEVICE_INFO_PROP_IFACE: - priv->info.iface = (int)g_value_get_enum(val); + g_value_set_enum(val, (ALSAHwdepIfaceType)priv->info.iface); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, id, spec); @@ -96,3 +94,12 @@ static void alsahwdep_device_info_init(ALSAHwdepDeviceInfo *self) { return; } + +void hwdep_device_info_refer_private(ALSAHwdepDeviceInfo *self, + struct snd_hwdep_info **info) +{ + ALSAHwdepDeviceInfoPrivate *priv = + alsahwdep_device_info_get_instance_private(self); + + *info = &priv->info; +} diff --git a/src/hwdep/privates.h b/src/hwdep/privates.h index 621edc3..5e881bb 100644 --- a/src/hwdep/privates.h +++ b/src/hwdep/privates.h @@ -2,6 +2,10 @@ #ifndef __ALSA_GOBJECT_ALSAHWDEP_PRIVATES__H__ #define __ALSA_GOBJECT_ALSAHWDEP_PRIVATES__H__ +#include "device-info.h" + +#include + G_BEGIN_DECLS GQuark alsahwdep_error_quark(void); @@ -10,6 +14,9 @@ GQuark alsahwdep_error_quark(void); g_set_error(err, alsahwdep_error_quark(), errno, \ __FILE__ ":%d: %s", __LINE__, strerror(errno)) +void hwdep_device_info_refer_private(ALSAHwdepDeviceInfo *self, + struct snd_hwdep_info **info); + G_END_DECLS #endif diff --git a/src/hwdep/query.c b/src/hwdep/query.c index eaf9c13..5f92f0f 100644 --- a/src/hwdep/query.c +++ b/src/hwdep/query.c @@ -18,6 +18,7 @@ G_DEFINE_QUARK("alsahwdep-error", alsahwdep_error) // 'C' is required apart from emulation of Open Sound System. #define PREFIX_SYSNAME_TEMPLATE "hwC%u" #define HWDEP_SYSNAME_TEMPLATE "hwC%uD%u" +#define CTL_SYSNAME_TEMPLATE "controlC%u" static void prepare_udev_enum(struct udev_enumerate **enumerator, GError **error) { @@ -300,3 +301,80 @@ void alsahwdep_get_hwdep_devnode(guint card_id, guint device_id, udev_device_unref(dev); udev_unref(ctx); } + +static void hwdep_perform_ctl_ioctl(guint card_id, long request, void *data, + GError **error) +{ + unsigned int length; + char *sysname; + struct udev *ctx; + struct udev_device *dev; + const char *devnode; + int fd; + + length = strlen(CTL_SYSNAME_TEMPLATE) + calculate_digits(card_id) + 1; + sysname = g_try_malloc0(length); + if (sysname == NULL) { + generate_error(error, ENOMEM); + return; + } + snprintf(sysname, length, CTL_SYSNAME_TEMPLATE, card_id); + + ctx = udev_new(); + if (ctx == NULL) { + generate_error(error, errno); + goto err_sysname; + } + + dev = udev_device_new_from_subsystem_sysname(ctx, "sound", sysname); + if (dev == NULL) { + generate_error(error, errno); + goto err_ctx; + } + + devnode = udev_device_get_devnode(dev); + if (devnode == NULL) { + generate_error(error, ENODEV); + goto err_device; + } + + fd = open(devnode, O_RDONLY | O_NONBLOCK); + if (fd < 0) { + generate_error(error, errno); + goto err_device; + } + + if (ioctl(fd, request, data) < 0) + generate_error(error, errno); +err_device: + udev_device_unref(dev); +err_ctx: + udev_unref(ctx); +err_sysname: + g_free(sysname); +} + +/** + * alsahwdep_get_device_info: + * @card_id: The numberical value for sound card to query. + * @device_id: The numerical value of hwdep device to query. + * @device_info: (out): The information of the device. + * @error: A #GError. + */ +void alsahwdep_get_device_info(guint card_id, guint device_id, + ALSAHwdepDeviceInfo **device_info, + GError **error) +{ + struct snd_hwdep_info *info; + + g_return_if_fail(device_info != NULL); + + *device_info = g_object_new(ALSAHWDEP_TYPE_DEVICE_INFO, NULL); + hwdep_device_info_refer_private(*device_info, &info); + + info->device = device_id; + info->card = card_id; + hwdep_perform_ctl_ioctl(card_id, SNDRV_CTL_IOCTL_HWDEP_INFO, info, error); + if (*error != NULL) + g_object_unref(*device_info); +} diff --git a/src/hwdep/query.h b/src/hwdep/query.h index ed005ef..58369d4 100644 --- a/src/hwdep/query.h +++ b/src/hwdep/query.h @@ -5,6 +5,8 @@ #include #include +#include + G_BEGIN_DECLS void alsahwdep_get_device_id_list(guint card_id, guint **entries, @@ -16,6 +18,10 @@ void alsahwdep_get_hwdep_sysname(guint card_id, guint device_id, void alsahwdep_get_hwdep_devnode(guint card_id, guint device_id, char **devnode, GError **error); +void alsahwdep_get_device_info(guint card_id, guint device_id, + ALSAHwdepDeviceInfo **device_info, + GError **error); + G_END_DECLS #endif