priv->buf = buf;
priv->length = length;
}
+
+void seq_event_cntr_get_buf(ALSASeqEventCntr *self, gsize count,
+ const guint8 **buf, gsize *length)
+{
+ ALSASeqEventCntrPrivate *priv =
+ alsaseq_event_cntr_get_instance_private(self);
+ struct event_iterator iter;
+
+ event_iterator_init(&iter, priv->buf, priv->length, priv->allocated);
+ if (event_iterator_find(&iter, count - 1) != NULL) {
+ *buf = priv->buf;
+ *length = iter.offset;
+ } else {
+ *buf = NULL;
+ *length = 0;
+ }
+}
/**
* alsaseq_user_client_schedule_event:
* @self: A #ALSASeqUserClient.
- * @event: An instance of #ALSASeqEvent to schedule.
+ * @ev_cntr: An instance of #ALSASeqEventCntr pointing to events.
+ * @count: The number of events in the ev_cntr to write.
* @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)
+ ALSASeqEventCntr *ev_cntr,
+ gsize count, GError **error)
{
ALSASeqUserClientPrivate *priv;
- struct snd_seq_event *ev;
+ gsize total;
+ const guint8 *buf;
+ gsize length;
ssize_t len;
- guint8 *ptr;
g_return_if_fail(ALSASEQ_IS_USER_CLIENT(self));
- g_return_if_fail(ALSASEQ_IS_EVENT(event));
+ g_return_if_fail(ALSASEQ_IS_EVENT_CNTR(ev_cntr));
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;
+ alsaseq_event_cntr_count_events(ev_cntr, &total);
+ if (count > total) {
+ generate_error(error, ENOBUFS);
+ return;
}
- len = write(priv->fd, ev, len);
+ seq_event_cntr_get_buf(ev_cntr, count, &buf, &length);
+ if (buf == NULL || length == 0) {
+ generate_error(error, ENODATA);
+ return;
+ }
+
+ len = write(priv->fd, buf, length);
if (len < 0)
generate_error(error, errno);
-
- if (ptr != NULL)
- g_free(ptr);
}
static gboolean seq_user_client_check_src(GSource *gsrc)