From: Takashi Sakamoto Date: Wed, 1 Apr 2020 09:13:28 +0000 (+0900) Subject: seq: add global method to get the list of subscriptions between ports X-Git-Tag: v0.1.0~251 X-Git-Url: https://git.alsa-project.org/?a=commitdiff_plain;h=3a052aa28768d6eeb720260ff91f5cf82ab7b57f;p=alsa-gobject.git seq: add global method to get the list of subscriptions between ports Signed-off-by: Takashi Sakamoto --- diff --git a/src/seq/alsaseq.map b/src/seq/alsaseq.map index 230c640..dbddb71 100644 --- a/src/seq/alsaseq.map +++ b/src/seq/alsaseq.map @@ -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"; diff --git a/src/seq/privates.h b/src/seq/privates.h index 2ec43a4..78e957c 100644 --- a/src/seq/privates.h +++ b/src/seq/privates.h @@ -12,6 +12,7 @@ #include "port-info.h" #include "client-pool.h" #include "event.h" +#include "subscribe-data.h" #include @@ -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 diff --git a/src/seq/query.c b/src/seq/query.c index 39f5789..957d954 100644 --- a/src/seq/query.c +++ b/src/seq/query.c @@ -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; + } +} diff --git a/src/seq/query.h b/src/seq/query.h index e2bb567..0871542 100644 --- a/src/seq/query.h +++ b/src/seq/query.h @@ -9,6 +9,7 @@ #include #include #include +#include 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 diff --git a/src/seq/subscribe-data.c b/src/seq/subscribe-data.c index 2b8746a..07d6ba6 100644 --- a/src/seq/subscribe-data.c +++ b/src/seq/subscribe-data.c @@ -1,7 +1,5 @@ // SPDX-License-Identifier: LGPL-3.0-or-later -#include "subscribe-data.h" - -#include +#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; +}