]> git.alsa-project.org Git - alsa-gobject.git/commitdiff
ctl: elem_info: become concrete class instead of abstract class
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>
Fri, 12 Jun 2020 04:19:45 +0000 (13:19 +0900)
committer坂本 貴史 <o-takashi@sakamocchi.jp>
Fri, 12 Jun 2020 06:45:37 +0000 (15:45 +0900)
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
src/ctl/alsactl.map
src/ctl/card.c
src/ctl/elem-info.c
src/ctl/elem-info.h
tests/alsactl-elem-info

index 63bde1d20b22bd21102f9695602d788dc3ecc871..e82c35fb03e19407425f6ad544b2a79631e60d35 100644 (file)
@@ -43,6 +43,7 @@ ALSA_GOBJECT_0_0_0 {
     "alsactl_elem_id_equal";
 
     "alsactl_elem_info_get_type";
+    "alsactl_elem_info_new";
     "alsactl_elem_info_get_int_data";
     "alsactl_elem_info_set_int_data";
     "alsactl_elem_info_get_int64_data";
index 7100fc470fcfce1c79db66e29ae3bbd472ea8b6e..353faaa426b02b1af54bc79be488abbdeae67898 100644 (file)
@@ -1,12 +1,6 @@
 // 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 <sys/types.h>
@@ -384,44 +378,36 @@ 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};
+    struct snd_ctl_elem_info *info;
 
     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)) {
+    *elem_info = g_object_new(ALSACTL_TYPE_ELEM_INFO, NULL);
+    ctl_elem_info_refer_private(*elem_info, &info);
+
+    info->id = *elem_id;
+    if (ioctl(priv->fd, SNDRV_CTL_IOCTL_ELEM_INFO, info)) {
         generate_error(error, errno);
         return;
     }
 
-    switch (info.type) {
+    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;
     case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
     {
         gchar **labels;
 
-        parse_enum_names(priv, &info, &labels, error);
+        parse_enum_names(priv, info, &labels, error);
         if (*error != NULL)
             return;
 
-        *elem_info = g_object_new(ALSACTL_TYPE_ELEM_INFO_ENUM, "labels", labels,
-                                  NULL);
         alsactl_elem_info_set_enum_data(*elem_info, (const gchar **)labels,
                                         error);
         g_strfreev(labels);
@@ -436,9 +422,6 @@ void alsactl_card_get_elem_info(ALSACtlCard *self, const ALSACtlElemId *elem_id,
         generate_error(error, ENXIO);
         return;
     }
-
-    ctl_elem_info_refer_private(ALSACTL_ELEM_INFO(*elem_info), &info_ptr);
-    *info_ptr = info;
 }
 
 /**
@@ -636,20 +619,36 @@ static void add_or_replace_elems(int fd, const ALSACtlElemId *elem_id,
 
     ctl_elem_info_refer_private(elem_info, &info);
 
-    info->id = *elem_id;
-
-    if (info->type == SNDRV_CTL_ELEM_TYPE_ENUMERATED) {
+    switch (info->type) {
+    case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
+    case SNDRV_CTL_ELEM_TYPE_INTEGER:
+    case SNDRV_CTL_ELEM_TYPE_BYTES:
+    case SNDRV_CTL_ELEM_TYPE_IEC958:
+    case SNDRV_CTL_ELEM_TYPE_INTEGER64:
+        break;
+    case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
+    {
         const gchar **labels;
         int err;
 
-        g_object_get(elem_info, "labels", &labels, NULL);
+        alsactl_elem_info_get_enum_data(elem_info, &labels, error);
+        if (*error != NULL)
+            return;
+
         err = prepare_enum_names(info, labels);
-        g_strfreev((gchar **)labels);
         if (err < 0) {
             generate_error(error, -err);
             return;
         }
+
+        break;
     }
+    default:
+        generate_error(error, ENXIO);
+        return;
+    }
+
+    info->id = *elem_id;
 
     if (!replace)
         request = SNDRV_CTL_IOCTL_ELEM_ADD;
index 91ff78e1669f4f34277b2f81dd770a966602da42..914cd642174370c275efeb89bfc972413a778e9f 100644 (file)
@@ -6,10 +6,10 @@
 /**
  * SECTION: elem-info
  * @Title: ALSACtlElemInfo
- * @Short_description: An abstract object to represent the common information
+ * @Short_description: An GObject-derived object to represent the information
  *                     of any type of element
  *
- * A #ALSACtlElemInfo is an abstract object to represent the common information
+ * A #ALSACtlElemInfo is an GObject-derived object to represent the information
  * of any type of element.
  *
  * The object wraps 'struct snd_ctl_elem_info' in UAPI of Linux sound subsystem.
@@ -24,7 +24,7 @@ struct _ALSACtlElemInfoPrivate {
     } int_data;
     gchar **enum_data;
 };
-G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(ALSACtlElemInfo, alsactl_elem_info, G_TYPE_OBJECT)
+G_DEFINE_TYPE_WITH_PRIVATE(ALSACtlElemInfo, alsactl_elem_info, G_TYPE_OBJECT)
 
 enum ctl_elem_info_prop_type {
     CTL_ELEM_INFO_PROP_ELEM_ID = 1,
@@ -153,6 +153,33 @@ static void alsactl_elem_info_init(ALSACtlElemInfo *self)
     priv->enum_data = NULL;
 }
 
+/**
+ * alsactl_elem_info_new:
+ * @elem_type: The type of element, one of #ALSACtlElemType.
+ * @error: A #GError.
+ *
+ * Allocate and return the instance of #ALSACtlElemInfo.
+ *
+ * Returns: A #ALSACtlElemInfo.
+ */
+ALSACtlElemInfo *alsactl_elem_info_new(ALSACtlElemType elem_type, GError **error)
+{
+    switch (elem_type) {
+    case ALSACTL_ELEM_TYPE_BOOLEAN:
+    case ALSACTL_ELEM_TYPE_INTEGER:
+    case ALSACTL_ELEM_TYPE_ENUMERATED:
+    case ALSACTL_ELEM_TYPE_BYTES:
+    case ALSACTL_ELEM_TYPE_IEC60958:
+    case ALSACTL_ELEM_TYPE_INTEGER64:
+        break;
+    default:
+        generate_error(error, EINVAL);
+        return NULL;
+    }
+
+    return g_object_new(ALSACTL_TYPE_ELEM_INFO, "type", elem_type);
+}
+
 /**
  * alsactl_elem_info_get_int_data:
  * @self: A #ALSACtlElemInfo.
index 6891eec688913937e87cad5f47241d0a0f6ec4c8..9fd57edcf9d1139c3363cbf76fdaa96ffa10e19b 100644 (file)
@@ -49,6 +49,8 @@ struct _ALSACtlElemInfoClass {
 
 GType alsactl_elem_info_get_type() G_GNUC_CONST;
 
+ALSACtlElemInfo *alsactl_elem_info_new(ALSACtlElemType elem_type, GError **error);
+
 void alsactl_elem_info_get_int_data(ALSACtlElemInfo *self,
                                     const gint32 *data[3], GError **error);
 void alsactl_elem_info_set_int_data(ALSACtlElemInfo *self,
index a25d82988da1e35977116c99329e771b98548fab..98fe16bf6fc61d82c650d84603a4603cea013154 100644 (file)
@@ -18,6 +18,7 @@ props = (
     'value-count',
 )
 methods = (
+    'new',
     'get_int_data',
     'set_int_data',
     'get_int64_data',