]> git.alsa-project.org Git - alsa-gobject.git/commitdiff
ctl: card: subscribe event when creating GSource
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>
Mon, 18 Nov 2019 04:22:44 +0000 (13:22 +0900)
committerTakashi Sakamoto <o-takashi@sakamocchi.jp>
Thu, 12 Dec 2019 05:29:12 +0000 (14:29 +0900)
src/ctl/card.c
tests/alsactl-card

index 0a6247dca09d3ec2fb8f32310f1aff99998d7a2a..419b0201b6d617d76381092193e709d9ac6010f8 100644 (file)
@@ -20,6 +20,7 @@
 struct _ALSACtlCardPrivate {
     int fd;
     char *devnode;
+    gint subscribers;
 };
 G_DEFINE_TYPE_WITH_PRIVATE(ALSACtlCard, alsactl_card, G_TYPE_OBJECT)
 
@@ -33,6 +34,7 @@ typedef struct {
 
 enum ctl_card_prop_type {
     CTL_CARD_PROP_DEVNODE = 1,
+    CTL_CARD_PROP_SUBSCRIBED,
     CTL_CARD_PROP_COUNT,
 };
 static GParamSpec *ctl_card_props[CTL_CARD_PROP_COUNT] = { NULL, };
@@ -47,6 +49,12 @@ static void ctl_card_get_property(GObject *obj, guint id, GValue *val,
     case CTL_CARD_PROP_DEVNODE:
         g_value_set_string(val, priv->devnode);
         break;
+    case CTL_CARD_PROP_SUBSCRIBED:
+    {
+        gboolean subscribed = g_atomic_int_get(&priv->subscribers) > 0;
+        g_value_set_boolean(val, subscribed);
+        break;
+    }
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, id, spec);
         break;
@@ -79,6 +87,12 @@ static void alsactl_card_class_init(ALSACtlCardClass *klass)
                             "",
                             G_PARAM_READABLE);
 
+    ctl_card_props[CTL_CARD_PROP_SUBSCRIBED] =
+        g_param_spec_boolean("subscribed", "subscribed",
+                             "Whether to be subscribed for event.",
+                             FALSE,
+                             G_PARAM_READABLE);
+
     g_object_class_install_properties(gobject_class, CTL_CARD_PROP_COUNT,
                                       ctl_card_props);
 }
@@ -703,6 +717,13 @@ static gboolean ctl_card_dispatch_src(GSource *gsrc, GSourceFunc cb,
 static void ctl_card_finalize_src(GSource *gsrc)
 {
     CtlCardSource *src = (CtlCardSource *)gsrc;
+    ALSACtlCardPrivate *priv = alsactl_card_get_instance_private(src->self);
+
+    // Unsubscribe events.
+    if (g_atomic_int_dec_and_test(&priv->subscribers)) {
+        int subscribe = 0;
+        ioctl(priv->fd, SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS, &subscribe);
+    }
 
     g_free(src->buf);
     g_object_unref(src->self);
@@ -756,4 +777,16 @@ void alsactl_card_create_source(ALSACtlCard *self, GSource **gsrc,
     src->tag = g_source_add_unix_fd(*gsrc, priv->fd, G_IO_IN);
     src->buf = buf;
     src->buf_len = page_size;
+
+    // Subscribe any event.
+    {
+        int subscribe = 1;
+
+        g_atomic_int_inc(&priv->subscribers);
+
+        if (ioctl(priv->fd, SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS, &subscribe)) {
+            generate_error(error, errno);
+            g_source_unref(*gsrc);
+        }
+    }
 }
index a43fa9b60cf780877e768a621c4a8474197d22cd..f348fc294d388384a6bf9c0bd5f59fdfe648ab9f 100644 (file)
@@ -12,6 +12,7 @@ from gi.repository import ALSACtl
 target = ALSACtl.Card()
 props = (
     'devnode',
+    'subscribed',
 )
 methods = (
     'new',