]> git.alsa-project.org Git - alsa-gobject.git/commitdiff
seq: add global method to get the list of subscriptions between ports
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>
Wed, 1 Apr 2020 09:13:28 +0000 (18:13 +0900)
committer坂本 貴史 <o-takashi@sakamocchi.jp>
Fri, 3 Apr 2020 13:06:25 +0000 (22:06 +0900)
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
src/seq/alsaseq.map
src/seq/privates.h
src/seq/query.c
src/seq/query.h
src/seq/subscribe-data.c

index 230c640ec68ec7fc328b66ae8ae3e44e04aed744..dbddb71c5ba7c8c5b471b69c0841d43c3ba5999d 100644 (file)
@@ -24,6 +24,7 @@ ALSA_GOBJECT_0_0_0 {
     "alsaseq_get_port_id_list";
     "alsaseq_get_port_info";
     "alsaseq_get_client_pool";
+    "alsaseq_get_subscription_list";
 
     "alsaseq_system_info_get_type";
 
index 2ec43a40c9319d6cf1d7a182254d057744fe3d62..78e957cb89ff6645e87b86b622a85de929a6f4b7 100644 (file)
@@ -12,6 +12,7 @@
 #include "port-info.h"
 #include "client-pool.h"
 #include "event.h"
+#include "subscribe-data.h"
 
 #include <sound/asequencer.h>
 
@@ -37,6 +38,9 @@ void seq_client_pool_refer_private(ALSASeqClientPool *self,
 
 void seq_event_refer_private(ALSASeqEvent *self, struct snd_seq_event **ev);
 
+void seq_subscribe_data_refer_private(ALSASeqSubscribeData *self,
+                                      struct snd_seq_port_subscribe **data);
+
 G_END_DECLS
 
 #endif
index 39f57899631264ea7c363afcaf1a0581696bc64c..957d954eb4e7a50e85ddae975d51a5ac41e05993 100644 (file)
@@ -429,3 +429,89 @@ void alsaseq_get_client_pool(gint client_id, ALSASeqClientPool **client_pool,
 
     close(fd);
 }
+
+static void fill_data_with_result(struct snd_seq_port_subscribe *data,
+                                  struct snd_seq_query_subs *query)
+{
+    if (query->type == SNDRV_SEQ_QUERY_SUBS_READ) {
+        data->sender = query->root;
+        data->dest = query->addr;
+    } else {
+        data->sender = query->addr;
+        data->dest = query->root;
+    }
+    data->queue = query->queue;
+    data->flags = query->flags;
+}
+
+/**
+ * alsaseq_get_subscription_list:
+ * @addr: A #ALSASeqAddr to query.
+ * @query_type: The type of query, one of #ALSASeqQuerySubscribeType.
+ * @entries: (element-type ALSASeq.SubscribeData)(out): The array with element
+ *           for subscription data.
+ * @error: A #GError.
+ *
+ * Get the list of subscription for given address and query type.
+ */
+void alsaseq_get_subscription_list(const ALSASeqAddr *addr,
+                                   ALSASeqQuerySubscribeType query_type,
+                                   GList **entries, GError **error)
+{
+    char *devnode;
+    int fd;
+    struct snd_seq_query_subs query = {0};
+    unsigned int count;
+    unsigned int index;
+
+    alsaseq_get_seq_devnode(&devnode, error);
+    if (*error != NULL)
+        return;
+
+    fd = open(devnode, O_RDONLY);
+    g_free(devnode);
+    if (fd < 0) {
+        generate_error(error, errno);
+        return;
+    }
+
+    g_object_get((gpointer)addr, "client-id", &query.root.client,
+                 "port-id", &query.root.port, NULL);
+    query.type = query_type;
+    if (ioctl(fd, SNDRV_SEQ_IOCTL_QUERY_SUBS, &query) < 0) {
+        if (errno != ENOENT)
+            generate_error(error, errno);
+        close(fd);
+        return;
+    }
+    count = query.num_subs;
+
+    index = 0;
+    while (index < count) {
+        ALSASeqSubscribeData *subs_data =
+                                g_object_new(ALSASEQ_TYPE_SUBSCRIBE_DATA, NULL);
+        struct snd_seq_port_subscribe *data;
+
+        seq_subscribe_data_refer_private(subs_data, &data);
+        fill_data_with_result(data, &query);
+
+        *entries = g_list_append(*entries, (gpointer)subs_data);
+        ++index;
+
+        ++query.index;
+        if (ioctl(fd, SNDRV_SEQ_IOCTL_QUERY_SUBS, &query) < 0) {
+            if (errno != ENOENT)
+                generate_error(error, errno);
+            break;
+        }
+    }
+
+    close(fd);
+
+    if (index != count)
+        generate_error(error, ENXIO);
+    if (*error != NULL) {
+        g_list_free_full(*entries, g_object_unref);
+        return;
+    }
+}
index e2bb56743266c275a5c5df3e689c714b230c5ec4..0871542a1292c4976383ca65de3152de03b84a1a 100644 (file)
@@ -9,6 +9,7 @@
 #include <seq/client-info.h>
 #include <seq/port-info.h>
 #include <seq/client-pool.h>
+#include <seq/subscribe-data.h>
 
 G_BEGIN_DECLS
 
@@ -33,6 +34,10 @@ void alsaseq_get_port_info(guint client_id, guint port_id,
 void alsaseq_get_client_pool(gint client_id, ALSASeqClientPool **client_pool,
                              GError **error);
 
+void alsaseq_get_subscription_list(const ALSASeqAddr *addr,
+                                   ALSASeqQuerySubscribeType query_type,
+                                   GList **entries, GError **error);
+
 G_END_DECLS
 
 #endif
index 2b8746ab6f9a795bd23b327ab171d5e7c780b909..07d6ba6624085936bdfbaab809d5fe149f8951a2 100644 (file)
@@ -1,7 +1,5 @@
 // SPDX-License-Identifier: LGPL-3.0-or-later
-#include "subscribe-data.h"
-
-#include <sound/asequencer.h>
+#include "privates.h"
 
 struct _ALSASeqSubscribeDataPrivate {
     struct snd_seq_port_subscribe data;
@@ -132,3 +130,12 @@ ALSASeqSubscribeData *alsaseq_subscribe_data_new()
 {
     return g_object_new(ALSASEQ_TYPE_SUBSCRIBE_DATA, NULL);
 }
+
+void seq_subscribe_data_refer_private(ALSASeqSubscribeData *self,
+                                      struct snd_seq_port_subscribe **data)
+{
+    ALSASeqSubscribeDataPrivate *priv =
+                            alsaseq_subscribe_data_get_instance_private(self);
+
+    *data = &priv->data;
+}