]> git.alsa-project.org Git - alsa-gobject.git/commitdiff
seq: remove-filter: rewrite as GObject-derived object
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>
Tue, 28 Jun 2022 21:45:49 +0000 (06:45 +0900)
committerTakashi Sakamoto <o-takashi@sakamocchi.jp>
Tue, 28 Jun 2022 21:45:49 +0000 (06:45 +0900)
In UAPI of ALSA Sequencer, 'struct snd_seq_remove_events' has reserved
member for future use. In the case, the convention of this project lets
us to use class instead of structure.

Additionally, current implementation of ALSASeq.RemoveFilter doesn't
support multiple condition to query events for removal. It's not
necessarily convenient.

This commit rewrites ALSASeq.RemoveFilter.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
src/seq/alsaseq.map
src/seq/privates.h
src/seq/remove-filter.c
src/seq/remove-filter.h
src/seq/user-client.c
tests/alsaseq-remove-filter

index 7de2c8a0cb616066d501354605f71c16341450d7..4ea8637e1ee330953f3b7889296bf81c27208706 100644 (file)
@@ -99,8 +99,6 @@ ALSA_GOBJECT_0_0_0 {
     "alsaseq_queue_tempo_new";
     "alsaseq_queue_tempo_get_skew";
     "alsaseq_queue_tempo_set_skew";
-
-    "alsaseq_remove_filter_get_type";
   local:
     *;
 };
@@ -161,14 +159,6 @@ ALSA_GOBJECT_0_3_0 {
     "alsaseq_event_data_queue_get_real_time_param";
     "alsaseq_event_data_queue_set_real_time_param";
 
-    "alsaseq_remove_filter_new_with_dest_addr";
-    "alsaseq_remove_filter_new_with_note_channel";
-    "alsaseq_remove_filter_new_with_event_type";
-    "alsaseq_remove_filter_new_with_note";
-    "alsaseq_remove_filter_new_with_tag";
-    "alsaseq_remove_filter_new_with_tick_time";
-    "alsaseq_remove_filter_new_with_real_time";
-
     "alsaseq_event_error_get_type";
     "alsaseq_event_error_quark";
 
@@ -224,4 +214,11 @@ ALSA_GOBJECT_0_3_0 {
 
     "alsaseq_event_cntr_get_type";
     "alsaseq_event_cntr_deserialize";
+
+    "alsaseq_remove_filter_get_type";
+    "alsaseq_remove_filter_new";
+    "alsaseq_remove_filter_set_tick_time";
+    "alsaseq_remove_filter_get_tick_time";
+    "alsaseq_remove_filter_set_real_time";
+    "alsaseq_remove_filter_get_real_time";
 } ALSA_GOBJECT_0_2_0;
index d49f0249f6bdbdf622fbc51ef66b9dd63f585e59..0b9abdf7bcb1fcc32e97ce11a5451f73187bc22c 100644 (file)
@@ -33,6 +33,9 @@ void seq_queue_tempo_refer_private(ALSASeqQueueTempo *self,
 void seq_queue_timer_alsa_refer_private(ALSASeqQueueTimerAlsa *self,
                                         struct snd_seq_queue_timer **timer);
 
+void seq_remove_filter_refer_private(ALSASeqRemoveFilter *self,
+                                     struct snd_seq_remove_events **data);
+
 void seq_event_cntr_serialize(ALSASeqEventCntr *self, const GList *events, gboolean aligned);
 void seq_event_copy_flattened(const ALSASeqEvent *self, guint8 *buf, gsize length);
 gsize seq_event_calculate_flattened_length(const ALSASeqEvent *self, gboolean aligned);
index c9f4861ae72fd530a770633afc50834de1cafd96..ffa5574ebde702e0e8d0cbae8133460f50d13c9d 100644 (file)
 
 /**
  * ALSASeqRemoveFilter:
- * A boxed object to express filter to remove scheduled event in queue.
+ * An object to express filter to remove scheduled event in queue.
  *
- * A [struct@RemoveFilter] is a boxed object to express filter to remove scheduled event in
- * queue. The call of [method@UserClient.remove_events] requires the instance of object. In the
- * object, data shares the same storage, thus it's not possible to use several purposes.
+ * A [class@RemoveFilter] is a GObject-derived object to express filter to remove scheduled event in
+ * queue. The call of [method@UserClient.remove_events] requires the instance of object.
  *
  * The object wraps `struct snd_seq_remove_events` in UAPI of Linux sound subsystem.
  */
-ALSASeqRemoveFilter *seq_remove_filter_copy(const ALSASeqRemoveFilter *self)
-{
-#ifdef g_memdup2
-    return g_memdup2(self, sizeof(*self));
-#else
-    // GLib v2.68 deprecated g_memdup() with concern about overflow by narrow conversion from size_t to
-    // unsigned int however it's safe in the local case.
-    gpointer ptr = g_malloc(sizeof(*self));
-    memcpy(ptr, self, sizeof(*self));
-    return ptr;
-#endif
-}
 
-G_DEFINE_BOXED_TYPE(ALSASeqRemoveFilter, alsaseq_remove_filter, seq_remove_filter_copy, g_free)
+typedef struct {
+    struct snd_seq_remove_events data;
+} ALSASeqRemoveFilterPrivate;
 
-/**
- * alsaseq_remove_filter_new_with_dest_addr:
- * @inout: The direction of queue; [flags@RemoveFilterFlag].INPUT or
- *         [flags@RemoveFilterFlag].OUTPUT.
- * @queue_id: The numeric ID of queue, excluding [enum@SpecificQueueId].DIRECT.
- * @dest: The address of destination.
- *
- * Allocate and return a memory object of [struct@RemoveFilter] to remove queued events towards the
- * destination.
- *
- * Returns: A [struct@RemoveFilter].
- */
-ALSASeqRemoveFilter *alsaseq_remove_filter_new_with_dest_addr(
-                                ALSASeqRemoveFilterFlag inout, guint8 queue_id,
-                                ALSASeqAddr *dest)
+G_DEFINE_TYPE_WITH_PRIVATE(ALSASeqRemoveFilter, alsaseq_remove_filter, G_TYPE_OBJECT)
+
+enum seq_remove_filter_prop_type {
+    SEQ_REMOVE_FILTER_PROP_FLAGS = 1,
+    SEQ_REMOVE_FILTER_PROP_QUEUE_ID,
+    SEQ_REMOVE_FILTER_PROP_DST,
+    SEQ_REMOVE_FILTER_PROP_CHANNEL,
+    SEQ_REMOVE_FILTER_PROP_EVENT_TYPE,
+    SEQ_REMOVE_FILTER_PROP_TAG,
+    SEQ_REMOVE_FILTER_PROP_COUNT,
+};
+static GParamSpec *seq_remove_filter_props[SEQ_REMOVE_FILTER_PROP_COUNT] = { NULL };
+
+static void seq_remove_filter_get_property(GObject *obj, guint id, GValue *val, GParamSpec *spec)
 {
-    struct snd_seq_remove_events filter;
+    ALSASeqRemoveFilter *self = ALSASEQ_REMOVE_FILTER(obj);
+    ALSASeqRemoveFilterPrivate *priv = alsaseq_remove_filter_get_instance_private(self);
+    const struct snd_seq_remove_events *data = &priv->data;
 
-    g_return_val_if_fail(!(inout & ~(SNDRV_SEQ_REMOVE_INPUT | SNDRV_SEQ_REMOVE_OUTPUT)), NULL);
+    switch (id) {
+    case SEQ_REMOVE_FILTER_PROP_FLAGS:
+        g_value_set_flags(val, (ALSASeqRemoveFilterFlag)data->remove_mode);
+        break;
+    case SEQ_REMOVE_FILTER_PROP_QUEUE_ID:
+        g_value_set_uchar(val, data->queue);
+        break;
+    case SEQ_REMOVE_FILTER_PROP_DST:
+        g_value_set_static_boxed(val, &data->dest);
+        break;
+    case SEQ_REMOVE_FILTER_PROP_CHANNEL:
+        g_value_set_uchar(val, data->channel);
+        break;
+    case SEQ_REMOVE_FILTER_PROP_EVENT_TYPE:
+        g_value_set_enum(val, data->type);
+        break;
+    case SEQ_REMOVE_FILTER_PROP_TAG:
+        g_value_set_schar(val, data->tag);
+        break;
+    default:
+        break;
+    }
+}
 
-    filter.remove_mode = inout | SNDRV_SEQ_REMOVE_DEST;
-    filter.queue = queue_id;
-    filter.dest = *dest;
+static void seq_remove_filter_set_property(GObject *obj, guint id, const GValue *val,
+                                           GParamSpec *spec)
+{
+    ALSASeqRemoveFilter *self = ALSASEQ_REMOVE_FILTER(obj);
+    ALSASeqRemoveFilterPrivate *priv = alsaseq_remove_filter_get_instance_private(self);
+    struct snd_seq_remove_events *data = &priv->data;
 
-    return g_boxed_copy(ALSASEQ_TYPE_REMOVE_FILTER, &filter);
+    switch (id) {
+    case SEQ_REMOVE_FILTER_PROP_FLAGS:
+        data->remove_mode = g_value_get_flags(val);
+        break;
+    case SEQ_REMOVE_FILTER_PROP_QUEUE_ID:
+        data->queue = g_value_get_uchar(val);
+        break;
+    case SEQ_REMOVE_FILTER_PROP_DST:
+    {
+        const ALSASeqAddr *src = g_value_get_boxed(val);
+        data->dest = *src;
+        break;
+    }
+    case SEQ_REMOVE_FILTER_PROP_CHANNEL:
+        data->channel = g_value_get_uchar(val);
+        break;
+    case SEQ_REMOVE_FILTER_PROP_EVENT_TYPE:
+        data->type = g_value_get_enum(val);
+        break;
+    case SEQ_REMOVE_FILTER_PROP_TAG:
+        data->tag = g_value_get_schar(val);
+        break;
+    default:
+        break;
+    }
 }
 
-/**
- * alsaseq_remove_filter_new_with_note_channel:
- * @inout: The direction of queue; [flags@RemoveFilterFlag].INPUT or
- *         [flags@RemoveFilterFlag].OUTPUT.
- * @queue_id: The numeric ID of queue, excluding [enum@SpecificQueueId].DIRECT.
- * @channel: The channel for note event.
- *
- * Allocate and return a memory object of [struct@RemoveFilter] to remove queued events with note
- * type towards the channel.
- *
- * Returns: A [struct@RemoveFilter].
- */
-ALSASeqRemoveFilter *alsaseq_remove_filter_new_with_note_channel(
-                                ALSASeqRemoveFilterFlag inout, guint8 queue_id,
-                                guint8 channel)
+static void alsaseq_remove_filter_class_init(ALSASeqRemoveFilterClass *klass)
 {
-    struct snd_seq_remove_events filter;
+    GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+
+    gobject_class->set_property = seq_remove_filter_set_property;
+    gobject_class->get_property = seq_remove_filter_get_property;
+
+    /**
+     * ALSASeqRemoveFilter:flags:
+     *
+     * The set of flags to filter events. They decide how to evaluate included data at call of
+     * [method@UserClient.remove_events].
+     *
+     * Since: 0.3.
+     */
+    seq_remove_filter_props[SEQ_REMOVE_FILTER_PROP_FLAGS] =
+        g_param_spec_flags("flags", "flags",
+                           "The set of flags to filter events",
+                           ALSASEQ_TYPE_REMOVE_FILTER_FLAG,
+                           0,
+                           G_PARAM_READWRITE);
+
+    /**
+     * ALSASeqRemoveFilter:queue-id:
+     *
+     * The numeric identifier of queue as filter condition. This is always evaluated at call of
+     * [method@UserClient.remove_events].
+     *
+     * Since: 0.3.
+     */
+    seq_remove_filter_props[SEQ_REMOVE_FILTER_PROP_QUEUE_ID] =
+        g_param_spec_uchar("queue-id", "queue-id",
+                           "The numeric identifier of queue as filter condition",
+                           0, G_MAXUINT8,
+                           0,
+                           G_PARAM_READWRITE);
 
-    g_return_val_if_fail(!(inout & ~(SNDRV_SEQ_REMOVE_INPUT | SNDRV_SEQ_REMOVE_OUTPUT)), NULL);
+    /**
+     * ALSASeqRemoveFilter:destination:
+     *
+     * The destionation of event as filter condition. This is evaluated with
+     * [flags@RemoveFilterFlag].DEST at call of [method@UserClient.remove_events].
+     *
+     * Since: 0.3.
+     */
+    seq_remove_filter_props[SEQ_REMOVE_FILTER_PROP_DST] =
+        g_param_spec_boxed("destination", "destination",
+                           "The destionation of event as filter condition",
+                           ALSASEQ_TYPE_ADDR,
+                           G_PARAM_READWRITE);
 
-    filter.remove_mode = inout | SNDRV_SEQ_REMOVE_DEST_CHANNEL;
-    filter.queue = queue_id;
-    filter.channel = channel;
+    /**
+     * ALSASeqRemoveFilter:channel:
+     *
+     * The channel of event as filter condition. This is evaluated with
+     * [flags@RemoveFilterFlag].DEST_CHANNEL at call of [method@UserClient.remove_events].
+     *
+     * Since: 0.3.
+     */
+    seq_remove_filter_props[SEQ_REMOVE_FILTER_PROP_CHANNEL] =
+        g_param_spec_uchar("channel", "channel",
+                           "The channel of event as filter condition",
+                           0, G_MAXUINT8,
+                           0,
+                           G_PARAM_READWRITE);
 
-    return g_boxed_copy(ALSASEQ_TYPE_REMOVE_FILTER, &filter);
+    /**
+     * ALSASeqRemoveFilter:event-type:
+     *
+     * The type of event as filter condition. This is evaluated with
+     * [flags@RemoveFilterFlag].EVENT_TYPE at call of [method@UserClient.remove_events].
+     *
+     * Since: 0.3.
+     */
+    seq_remove_filter_props[SEQ_REMOVE_FILTER_PROP_EVENT_TYPE] =
+        g_param_spec_enum("event-type", "event-type",
+                          "The type of event as filter condition",
+                          ALSASEQ_TYPE_EVENT_TYPE,
+                          ALSASEQ_EVENT_TYPE_NONE,
+                          G_PARAM_READWRITE);
+
+    /**
+     * ALSASeqRemoveFilter:tag:
+     *
+     * The tag of event as filter condition. This is evaluated with
+     * [flags@RemoveFilterFlag].TAG_MATCH at call of [method@UserClient.remove_events].
+     *
+     * Since: 0.3.
+     */
+    seq_remove_filter_props[SEQ_REMOVE_FILTER_PROP_TAG] =
+        g_param_spec_char("tag", "tag",
+                          "The tag of event as filter condition",
+                          G_MININT8, G_MAXINT8,
+                          0,
+                          G_PARAM_READWRITE);
+
+    g_object_class_install_properties(gobject_class,
+                                      SEQ_REMOVE_FILTER_PROP_COUNT,
+                                      seq_remove_filter_props);
+}
+
+static void alsaseq_remove_filter_init(ALSASeqRemoveFilter *self)
+{
 }
 
 /**
- * alsaseq_remove_filter_new_with_event_type:
- * @inout: The direction of queue; [flags@RemoveFilterFlag].INPUT or
- *         [flags@RemoveFilterFlag].OUTPUT.
- * @queue_id: The numeric ID of queue, excluding [enum@SpecificQueueId].DIRECT.
- * @ev_type: The type of event.
+ * alsaseq_remove_filter_new:
  *
- * Allocate and return a memory object of [struct@RemoveFilter] to remove queued events with the
- * type.
+ * Allocate and return an instance of [class@RemoveFilter].
  *
- * Returns: A [struct@RemoveFilter].
+ * Returns: An instance of [class@RemoveFilter].
  */
-ALSASeqRemoveFilter *alsaseq_remove_filter_new_with_event_type(
-                                ALSASeqRemoveFilterFlag inout, guint8 queue_id,
-                                ALSASeqEventType ev_type)
+ALSASeqRemoveFilter *alsaseq_remove_filter_new(void)
 {
-    struct snd_seq_remove_events filter;
-
-    g_return_val_if_fail(!(inout & ~(SNDRV_SEQ_REMOVE_INPUT | SNDRV_SEQ_REMOVE_OUTPUT)), NULL);
-
-    filter.remove_mode = inout | SNDRV_SEQ_REMOVE_EVENT_TYPE;
-    filter.queue = queue_id;
-    filter.type = ev_type;
-
-    return g_boxed_copy(ALSASEQ_TYPE_REMOVE_FILTER, &filter);
+    return g_object_new(ALSASEQ_TYPE_REMOVE_FILTER, NULL);
 }
 
 /**
- * alsaseq_remove_filter_new_with_note:
- * @inout: The direction of queue; [flags@RemoveFilterFlag].INPUT or [flags@RemoveFilterFlag].OUTPUT.
- * @queue_id: The numeric ID of queue, excluding [enum@SpecificQueueId].DIRECT.
- *
- * Allocate and return a memory object of [struct@RemoveFilter] to remove queued events for note,
- * excluding [enum@EventType:NOTEOFF].
+ * alsaseq_remove_filter_get_tick_time:
+ * @self: A [class@RemoveFilter].
+ * @tick_time: (out): The count of tick.
  *
- * Returns: A [struct@RemoveFilter].
+ * Refer to tick count in internal storage. The call works expectedly as long as
+ * [property@RemoveFilter:flags] contains [flags@RemoveFilterFlag].TICK. This is evaluated with
+ * [flags@RemoveFilterFlag].TIME_BEFORE and [flags@RemoveFilterFlag].TIME_AFTER at call of
+ * [method@UserClient.remove_events].
  */
-ALSASeqRemoveFilter *alsaseq_remove_filter_new_with_note(
-                                ALSASeqRemoveFilterFlag inout, guint8 queue_id)
+void alsaseq_remove_filter_get_tick_time(ALSASeqRemoveFilter *self, guint *tick_time)
 {
-    struct snd_seq_remove_events filter;
+    ALSASeqRemoveFilterPrivate *priv;
 
-    g_return_val_if_fail(!(inout & ~(SNDRV_SEQ_REMOVE_INPUT | SNDRV_SEQ_REMOVE_OUTPUT)), NULL);
+    g_return_if_fail(ALSASEQ_IS_REMOVE_FILTER(self));
+    g_return_if_fail(tick_time != NULL);
 
-    filter.remove_mode = inout | SNDRV_SEQ_REMOVE_IGNORE_OFF;
-    filter.queue = queue_id;
+    priv = alsaseq_remove_filter_get_instance_private(self);
+    g_return_if_fail((priv->data.remove_mode & SNDRV_SEQ_REMOVE_TIME_TICK) > 0);
 
-    return g_boxed_copy(ALSASEQ_TYPE_REMOVE_FILTER, &filter);
+    *tick_time = priv->data.time.tick;
 }
 
 /**
- * alsaseq_remove_filter_new_with_tag:
- * @inout: The direction of queue; [flags@RemoveFilterFlag].INPUT or
- *         [flags@RemoveFilterFlag].OUTPUT.
- * @queue_id: The numeric ID of queue, excluding [enum@SpecificQueueId].DIRECT.
- * @tag: The tag of event to remove.
+ * alsaseq_remove_filter_set_tick_time:
+ * @self: A [class@RemoveFilter].
+ * @tick_time: The count of tick.
  *
- * Allocate and return a memory object of [struct@RemoveFilter] to remove queued events with the
- * tag.
+ * Copy tick count into internal storage. The call works expectedly as long as
+ * [property@RemoveFilter:flags] contains [flags@RemoveFilterFlag].TICK. This is evaluated with
+ * [flags@RemoveFilterFlag].TIME_BEFORE and [flags@RemoveFilterFlag].TIME_AFTER at call of
+ * [method@UserClient.remove_events].
  *
- * Returns: A [struct@RemoveFilter].
  */
-ALSASeqRemoveFilter *alsaseq_remove_filter_new_with_tag(
-                                ALSASeqRemoveFilterFlag inout, guint8 queue_id,
-                                gint8 tag)
+void alsaseq_remove_filter_set_tick_time(ALSASeqRemoveFilter *self, guint tick_time)
 {
-    struct snd_seq_remove_events filter;
+    ALSASeqRemoveFilterPrivate *priv;
 
-    g_return_val_if_fail(!(inout & ~(SNDRV_SEQ_REMOVE_INPUT | SNDRV_SEQ_REMOVE_OUTPUT)), NULL);
+    g_return_if_fail(ALSASEQ_IS_REMOVE_FILTER(self));
 
-    filter.remove_mode = inout | SNDRV_SEQ_REMOVE_TAG_MATCH;
-    filter.queue = queue_id;
-    filter.tag = tag;
+    priv = alsaseq_remove_filter_get_instance_private(self);
+    g_return_if_fail((priv->data.remove_mode & SNDRV_SEQ_REMOVE_TIME_TICK) > 0);
 
-    return g_boxed_copy(ALSASEQ_TYPE_REMOVE_FILTER, &filter);
+    priv->data.time.tick = tick_time;
 }
 
 /**
- * alsaseq_remove_filter_new_with_tick_time:
- * @inout: The direction of queue; [flags@RemoveFilterFlag].INPUT or
- *         [flags@RemoveFilterFlag].OUTPUT.
- * @queue_id: The numeric ID of queue, excluding [enum@SpecificQueueId].DIRECT.
- * @tick_time: The count of tick.
- * @after: Remove events after the tick time if true, else remove events before the tick time.
+ * alsaseq_remove_filter_get_real_time:
+ * @self: A [class@RemoveFilter].
+ * @real_time: (array fixed-size=2) (out) (transfer none): The real time data of event.
  *
- * Allocate and return a memory object of [struct@RemoveFilter] to remove queued events
- * before/after the tick time.
- *
- * Returns: A [struct@RemoveFilter].
+ * Refer to doublet of real time in internal storage. The call works expectedly as long as
+ * [property@RemoveFilter:flags] doesn't contain [flags@RemoveFilterFlag].TICK. This is evaluated
+ * with [flags@RemoveFilterFlag].TIME_BEFORE and [flags@RemoveFilterFlag].TIME_AFTER at call of
+ * [method@UserClient.remove_events].
  */
-ALSASeqRemoveFilter *alsaseq_remove_filter_new_with_tick_time(
-                                ALSASeqRemoveFilterFlag inout, guint8 queue_id,
-                                gint32 tick_time, gboolean after)
+void alsaseq_remove_filter_get_real_time(ALSASeqRemoveFilter *self, const guint32 *real_time[2])
 {
-    struct snd_seq_remove_events filter;
+    ALSASeqRemoveFilterPrivate *priv;
 
-    g_return_val_if_fail(!(inout & ~(SNDRV_SEQ_REMOVE_INPUT | SNDRV_SEQ_REMOVE_OUTPUT)), NULL);
+    g_return_if_fail(ALSASEQ_IS_REMOVE_FILTER(self));
+    g_return_if_fail(real_time != NULL);
 
-    filter.remove_mode = inout | SNDRV_SEQ_REMOVE_TIME_TICK;
-    if (after)
-        filter.remove_mode |= SNDRV_SEQ_REMOVE_TIME_BEFORE;
-    else
-        filter.remove_mode |= SNDRV_SEQ_REMOVE_TIME_AFTER;
-    filter.queue = queue_id;
-    filter.time.tick = tick_time;
+    priv = alsaseq_remove_filter_get_instance_private(self);
+    g_return_if_fail((priv->data.remove_mode & SNDRV_SEQ_REMOVE_TIME_TICK) == 0);
 
-    return g_boxed_copy(ALSASEQ_TYPE_REMOVE_FILTER, &filter);
+    *real_time = (const guint32 *)&priv->data.time.time;
 }
 
 /**
- * alsaseq_remove_filter_new_with_real_time:
- * @inout: The direction of queue; [flags@RemoveFilterFlag].INPUT or
- *         [flags@RemoveFilterFlag].OUTPUT.
- * @queue_id: The numeric ID of queue, excluding [enum@SpecificQueueId].DIRECT.
- * @tv_sec: The second part of time.
- * @tv_nsec: The nanosecond part of time.
- * @after: Remove events after the real time if true, else remove events before the real time.
- *
- * Allocate and return a memory object of [struct@RemoveFilter] to remove queued events
- * before/after the real time.
+ * alsaseq_remove_filter_set_real_time:
+ * @self: A [class@RemoveFilter].
+ * @real_time: (array fixed-size=2): The real time data of event.
  *
- * Returns: A [struct@RemoveFilter].
+ * Copy doublet of real time into internal storage. The call works expectedly as long as
+ * [property@RemoveFilter:flags] doesn't contain [flags@RemoveFilterFlag].TICK. This is evaluated
+ * with [flags@RemoveFilterFlag].TIME_BEFORE and [flags@RemoveFilterFlag].TIME_AFTER at call of
+ * [method@UserClient.remove_events].
  */
-ALSASeqRemoveFilter *alsaseq_remove_filter_new_with_real_time(
-                                ALSASeqRemoveFilterFlag inout, guint8 queue_id,
-                                gint32 tv_sec, guint32 tv_nsec, gboolean after)
+void alsaseq_remove_filter_set_real_time(ALSASeqRemoveFilter *self, const guint32 real_time[2])
 {
-    struct snd_seq_remove_events filter;
+    ALSASeqRemoveFilterPrivate *priv;
 
-    g_return_val_if_fail(!(inout & ~(SNDRV_SEQ_REMOVE_INPUT | SNDRV_SEQ_REMOVE_OUTPUT)), NULL);
+    g_return_if_fail(ALSASEQ_IS_REMOVE_FILTER(self));
 
-    filter.remove_mode = inout;
-    if (after)
-        filter.remove_mode |= SNDRV_SEQ_REMOVE_TIME_AFTER;
-    else
-        filter.remove_mode |= SNDRV_SEQ_REMOVE_TIME_BEFORE;
-    filter.queue = queue_id;
-    filter.time.time.tv_sec = tv_sec;
-    filter.time.time.tv_nsec = tv_nsec;
+    priv = alsaseq_remove_filter_get_instance_private(self);
+    g_return_if_fail((priv->data.remove_mode & SNDRV_SEQ_REMOVE_TIME_TICK) == 0);
+
+    priv->data.time.time.tv_sec = real_time[0];
+    priv->data.time.time.tv_nsec = real_time[1];
+}
+
+void seq_remove_filter_refer_private(ALSASeqRemoveFilter *self,
+                                     struct snd_seq_remove_events **data)
+{
+    ALSASeqRemoveFilterPrivate *priv = alsaseq_remove_filter_get_instance_private(self);
 
-    return g_boxed_copy(ALSASEQ_TYPE_REMOVE_FILTER, &filter);
+    *data = &priv->data;
 }
index e096a87ea3f42db66fe9bfdffcbbc387e1c1f819..7aa74ff68a79ea88cb4b7681fd93dc0656a70783 100644 (file)
@@ -8,36 +8,19 @@ G_BEGIN_DECLS
 
 #define ALSASEQ_TYPE_REMOVE_FILTER     (alsaseq_remove_filter_get_type())
 
-typedef struct snd_seq_remove_events    ALSASeqRemoveFilter;
+G_DECLARE_DERIVABLE_TYPE(ALSASeqRemoveFilter, alsaseq_remove_filter, ALSASEQ, REMOVE_FILTER, GObject);
 
-GType alsaseq_remove_filter_get_type() G_GNUC_CONST;
+struct _ALSASeqRemoveFilterClass {
+    GObjectClass parent_class;
+};
 
-ALSASeqRemoveFilter *alsaseq_remove_filter_new_with_dest_addr(
-                                ALSASeqRemoveFilterFlag inout, guint8 queue_id,
-                                ALSASeqAddr *dest);
+ALSASeqRemoveFilter *alsaseq_remove_filter_new(void);
 
-ALSASeqRemoveFilter *alsaseq_remove_filter_new_with_note_channel(
-                                ALSASeqRemoveFilterFlag inout, guint8 queue_id,
-                                guint8 channel);
+void alsaseq_remove_filter_get_tick_time(ALSASeqRemoveFilter *self, guint *tick_time);
+void alsaseq_remove_filter_set_tick_time(ALSASeqRemoveFilter *self, guint tick_time);
 
-ALSASeqRemoveFilter *alsaseq_remove_filter_new_with_event_type(
-                                ALSASeqRemoveFilterFlag inout, guint8 queue_id,
-                                ALSASeqEventType ev_type);
-
-ALSASeqRemoveFilter *alsaseq_remove_filter_new_with_note(
-                                ALSASeqRemoveFilterFlag inout, guint8 queue_id);
-
-ALSASeqRemoveFilter *alsaseq_remove_filter_new_with_tag(
-                                ALSASeqRemoveFilterFlag inout, guint8 queue_id,
-                                gint8 tag);
-
-ALSASeqRemoveFilter *alsaseq_remove_filter_new_with_tick_time(
-                                ALSASeqRemoveFilterFlag inout, guint8 queue_id,
-                                gint32 tick_time, gboolean after);
-
-ALSASeqRemoveFilter *alsaseq_remove_filter_new_with_real_time(
-                                ALSASeqRemoveFilterFlag inout, guint8 queue_id,
-                                gint32 tv_sec, guint32 tv_nsec, gboolean after);
+void alsaseq_remove_filter_get_real_time(ALSASeqRemoveFilter *self, const guint32 *real_time[2]);
+void alsaseq_remove_filter_set_real_time(ALSASeqRemoveFilter *self, const guint32 real_time[2]);
 
 G_END_DECLS
 
index 3d28bb79b6031600c1cb6533a1115b7470c6d6a7..a2f9d98bd715705516b2db8fcc999d53f1b2df56 100644 (file)
@@ -1210,7 +1210,7 @@ gboolean alsaseq_user_client_get_queue_timer(ALSASeqUserClient *self, guint8 que
 /**
  * alsaseq_user_client_remove_events:
  * @self: A [class@UserClient].
- * @filter: A [struct@RemoveFilter].
+ * @filter: A [class@RemoveFilter].
  * @error: A [struct@GLib.Error]. Error is generated with domain of `ALSASeq.UserClientError`.
  *
  * Remove queued events according to the filter.
@@ -1224,6 +1224,7 @@ gboolean alsaseq_user_client_remove_events(ALSASeqUserClient *self, ALSASeqRemov
                                            GError **error)
 {
     ALSASeqUserClientPrivate *priv;
+    struct snd_seq_remove_events *data;
 
     g_return_val_if_fail(ALSASEQ_IS_USER_CLIENT(self), FALSE);
     priv = alsaseq_user_client_get_instance_private(self);
@@ -1231,7 +1232,9 @@ gboolean alsaseq_user_client_remove_events(ALSASeqUserClient *self, ALSASeqRemov
     g_return_val_if_fail(filter != NULL, FALSE);
     g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
 
-    if (ioctl(priv->fd, SNDRV_SEQ_IOCTL_REMOVE_EVENTS, filter) < 0) {
+    seq_remove_filter_refer_private(filter, &data);
+
+    if (ioctl(priv->fd, SNDRV_SEQ_IOCTL_REMOVE_EVENTS, data) < 0) {
         generate_syscall_error(error, errno, "ioctl(%s)", "REMOVE_EVENTS");
         return FALSE;
     }
index 18004d0d0ce03ee7a3f39092b9ac83578c524328..ce4f0364e0f85af9bd67219e7baf1f36b07b0c97 100644 (file)
@@ -3,22 +3,29 @@
 from sys import exit
 from errno import ENXIO
 
-from helper import test_struct
+from helper import test_object
 
 import gi
 gi.require_version('ALSASeq', '0.0')
 from gi.repository import ALSASeq
 
 target_type = ALSASeq.RemoveFilter
+props = (
+    'flags',
+    'queue-id',
+    'destination',
+    'channel',
+    'event-type',
+    'tag',
+)
 methods = (
-    'new_with_dest_addr',
-    'new_with_note_channel',
-    'new_with_event_type',
-    'new_with_note',
-    'new_with_tag',
-    'new_with_tick_time',
-    'new_with_real_time',
+    'get_tick_time',
+    'set_tick_time',
+    'get_real_time',
+    'set_real_time',
 )
+vmethods = ()
+signals = ()
 
-if not test_struct(target_type, methods):
+if not test_object(target_type, props, methods, vmethods, signals):
     exit(ENXIO)