]> git.alsa-project.org Git - alsa-gobject.git/commitdiff
seq: user_client: add an API to schedule event
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/user-client.c
src/seq/user-client.h
tests/alsaseq-user-client

index 5589432db2b5a1d9cf8d82aafbb0591be54210f4..9b0f883202d8cc77d173a1792bd44937da75f09b 100644 (file)
@@ -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";
index fb3fd509916b96cdd4d015b2d0c10140c898c123..383643833fb6c99b1447c8504d97e5f6f36c60ed 100644 (file)
@@ -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);
+}
index fa98f3575e4722604c23b6074237f0d9505a335e..8db8f8daf36110ec5dc25d2adb7534585200d37f 100644 (file)
@@ -8,6 +8,7 @@
 #include <seq/client-info.h>
 #include <seq/port-info.h>
 #include <seq/client-pool.h>
+#include <seq/event.h>
 
 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
index 90960efcdf4dace6fac990a17fc2571cc4d516b2..f2c3b6743704970ebb136d05bb18f7c618bd2924 100644 (file)
@@ -23,6 +23,7 @@ methods = (
     'delete_port',
     'set_pool',
     'get_pool',
+    'schedule_event',
 )
 signals = ()