From 9d535a87381c83af7a8c48154afaaada8606bc97 Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Wed, 1 Apr 2020 18:13:28 +0900 Subject: [PATCH] seq: user_client: add an API to schedule event Signed-off-by: Takashi Sakamoto --- src/seq/alsaseq.map | 1 + src/seq/user-client.c | 59 +++++++++++++++++++++++++++++++++++++++ src/seq/user-client.h | 4 +++ tests/alsaseq-user-client | 1 + 4 files changed, 65 insertions(+) diff --git a/src/seq/alsaseq.map b/src/seq/alsaseq.map index 5589432..9b0f883 100644 --- a/src/seq/alsaseq.map +++ b/src/seq/alsaseq.map @@ -42,6 +42,7 @@ ALSA_GOBJECT_0_0_0 { "alsaseq_user_client_delete_port"; "alsaseq_user_client_set_pool"; "alsaseq_user_client_get_pool"; + "alsaseq_user_client_schedule_event"; "alsaseq_addr_get_type"; "alsaseq_addr_new"; diff --git a/src/seq/user-client.c b/src/seq/user-client.c index fb3fd50..3836438 100644 --- a/src/seq/user-client.c +++ b/src/seq/user-client.c @@ -312,3 +312,62 @@ void alsaseq_user_client_get_pool(ALSASeqUserClient *self, if (ioctl(priv->fd, SNDRV_SEQ_IOCTL_GET_CLIENT_POOL, pool) < 0) generate_error(error, errno); } + +/** + * alsaseq_user_client_schedule_event: + * @self: A #ALSASeqUserClient. + * @event: An instance of #ALSASeqEvent to schedule. + * @error: A #GError. + * + * Deliver the event immediately, or schedule it into memory pool of the client. + */ +void alsaseq_user_client_schedule_event(ALSASeqUserClient *self, + ALSASeqEvent *event, GError **error) +{ + ALSASeqUserClientPrivate *priv; + struct snd_seq_event *ev; + ssize_t len; + guint8 *ptr; + + g_return_if_fail(ALSASEQ_IS_USER_CLIENT(self)); + g_return_if_fail(ALSASEQ_IS_EVENT(event)); + priv = alsaseq_user_client_get_instance_private(self); + seq_event_refer_private(event, &ev); + + switch (ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) { + case SNDRV_SEQ_EVENT_LENGTH_FIXED: + ptr = NULL; + len = sizeof(*ev); + break; + case SNDRV_SEQ_EVENT_LENGTH_VARIABLE: + if (ev->data.ext.len == 0 || ev->data.ext.ptr == NULL) { + generate_error(error, EINVAL); + return; + } + + len = sizeof(*ev) + ev->data.ext.len; + ptr = g_malloc0(len); + if (ptr == NULL) { + generate_error(error, ENOMEM); + return; + } + + memcpy(ptr, ev, sizeof(*ev)); + memcpy(ptr + sizeof(*ev), ev->data.ext.ptr, ev->data.ext.len); + + ev = (struct snd_seq_event *)ptr; + break; + case SNDRV_SEQ_EVENT_LENGTH_VARUSR: + // Unsupported since it handles raw pointer which is difficult to + // be exposed by interfaces capable for g-i. + default: + break; + } + + len = write(priv->fd, ev, len); + if (len < 0) + generate_error(error, errno); + + if (ptr != NULL) + g_free(ptr); +} diff --git a/src/seq/user-client.h b/src/seq/user-client.h index fa98f35..8db8f8d 100644 --- a/src/seq/user-client.h +++ b/src/seq/user-client.h @@ -8,6 +8,7 @@ #include #include #include +#include G_BEGIN_DECLS @@ -81,6 +82,9 @@ void alsaseq_user_client_get_pool(ALSASeqUserClient *self, ALSASeqClientPool *const *client_pool, GError **error); +void alsaseq_user_client_schedule_event(ALSASeqUserClient *self, + ALSASeqEvent *event, GError **error); + G_END_DECLS #endif diff --git a/tests/alsaseq-user-client b/tests/alsaseq-user-client index 90960ef..f2c3b67 100644 --- a/tests/alsaseq-user-client +++ b/tests/alsaseq-user-client @@ -23,6 +23,7 @@ methods = ( 'delete_port', 'set_pool', 'get_pool', + 'schedule_event', ) signals = () -- 2.47.3