]> git.alsa-project.org Git - alsa-gobject.git/commitdiff
timer: user_instance: emit 'handle-event' signal
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>
Sun, 9 Feb 2020 03:20:53 +0000 (12:20 +0900)
committer坂本 貴史 <o-takashi@sakamocchi.jp>
Tue, 11 Feb 2020 04:28:18 +0000 (13:28 +0900)
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
src/timer/event-data-tick.c
src/timer/event-data-timestamp.c
src/timer/instance-params.c
src/timer/privates.h
src/timer/user-instance.c
src/timer/user-instance.h

index f5ba1e96fc8b02ff45f09573008d3c8c017b126c..1337a087fb0d9405a3b582f361c4dd61e4704093 100644 (file)
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: LGPL-3.0-or-later
 #include "event-data-tick.h"
+#include "privates.h"
 
 struct _ALSATimerEventDataTickPrivate {
     struct snd_timer_read event;
@@ -59,3 +60,12 @@ static void alsatimer_event_data_tick_init(ALSATimerEventDataTick *self)
 {
     return;
 }
+
+void timer_event_data_tick_set_data(ALSATimerEventDataTick *self,
+                                    struct snd_timer_read *data)
+{
+    ALSATimerEventDataTickPrivate *priv =
+                        alsatimer_event_data_tick_get_instance_private(self);
+
+    priv->event = *data;
+}
index 51e7eb2309683296e8a9d825db0c7ca649b5998c..69d6725742a904aba1dadc1b5b20da493f4938de 100644 (file)
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: LGPL-3.0-or-later
 #include "event-data-timestamp.h"
+#include "privates.h"
 
 struct _ALSATimerEventDataTimestampPrivate {
     struct snd_timer_tread event;
@@ -81,3 +82,12 @@ void alsatimer_event_data_timestamp_get_timestamp(ALSATimerEventDataTimestamp *s
     *tv_sec = priv->event.tstamp.tv_sec;
     *tv_nsec = priv->event.tstamp.tv_nsec;
 }
+
+void timer_event_data_timestamp_set_data(ALSATimerEventDataTimestamp *self,
+                                         struct snd_timer_tread *data)
+{
+    ALSATimerEventDataTimestampPrivate *priv =
+                    alsatimer_event_data_timestamp_get_instance_private(self);
+
+    priv->event = *data;
+}
index 8e31491163d280e747d012a6be0d1acd4e9860dd..0a15302fadebb3955c374a629e83363737f58d88 100644 (file)
@@ -122,7 +122,8 @@ ALSATimerInstanceParams *alsatimer_instance_params_new()
  * @entry_count: The number of elements in the above array.
  * @error: A #GError at failure.
  *
- * Set the list of ALSATimerEventType to filter events.
+ * Set the list of ALSATimerEventType to filter events. This parameter is only
+ * effective for target instance with ALSATimerEventDataType.TIMESTAMP.
  */
 void alsatimer_instance_params_set_event_filter(ALSATimerInstanceParams *self,
                                             const ALSATimerEventType *entries,
@@ -166,7 +167,8 @@ void alsatimer_instance_params_set_event_filter(ALSATimerInstanceParams *self,
  * @entry_count: The number of elements in the above array.
  * @error: A #GError at failure.
  *
- * Get the list of ALSATimerEventType to filter events.
+ * Get the list of ALSATimerEventType to filter events. This parameter is only
+ * effective for target instance with ALSATimerEventDataType.TIMESTAMP.
  */
 void alsatimer_instance_params_get_event_filter(ALSATimerInstanceParams *self,
                                             ALSATimerEventType **entries,
index 87d3dcc749dfca2627d464b62ef9a23edb2a9996..3e174affdd1e13d1edc07c3f61019a80e4c1f6d0 100644 (file)
@@ -8,6 +8,9 @@
 #include "instance-info.h"
 #include "instance-params.h"
 #include "instance-status.h"
+#include "event-data.h"
+#include "event-data-tick.h"
+#include "event-data-timestamp.h"
 
 #include <sound/asound.h>
 
@@ -37,6 +40,12 @@ void timer_instance_params_refer_private(ALSATimerInstanceParams *self,
 void timer_instance_status_refer_private(ALSATimerInstanceStatus *self,
                                          struct snd_timer_status **status);
 
+void timer_event_data_tick_set_data(ALSATimerEventDataTick *self,
+                                    struct snd_timer_read *data);
+
+void timer_event_data_timestamp_set_data(ALSATimerEventDataTimestamp *self,
+                                         struct snd_timer_tread *data);
+
 G_END_DECLS
 
 #endif
index 6ec4ce5ecaf95db6f0bd4713910d06bc52bae386..4f129488c7b9d989b7a6fc2db001dc965f1ab4cd 100644 (file)
@@ -12,6 +12,7 @@
 
 struct _ALSATimerUserInstancePrivate {
     int fd;
+    ALSATimerEventDataType event_data_type;
 };
 G_DEFINE_TYPE_WITH_PRIVATE(ALSATimerUserInstance, alsatimer_user_instance, G_TYPE_OBJECT)
 
@@ -21,6 +22,7 @@ typedef struct {
     gpointer tag;
     void *buf;
     unsigned int buf_len;
+    ALSATimerEventData *event_data;
 } TimerUserInstanceSource;
 
 enum timer_user_instance_sig_type {
@@ -107,21 +109,31 @@ ALSATimerUserInstance *alsatimer_user_instance_new()
  * alsatimer_user_instance_attach:
  * @self: A #ALSATimerUserInstance.
  * @device_id: A #ALSATimerDeviceId to which the instance is attached.
+ * @event_data_type: The type of event data, one of ALSATimerEventDataType.
  * @error: A #GError.
  *
  * Attach the instance to the timer device.
  */
 void alsatimer_user_instance_attach(ALSATimerUserInstance *self,
                                     ALSATimerDeviceId *device_id,
+                                    ALSATimerEventDataType event_data_type,
                                     GError **error)
 {
     ALSATimerUserInstancePrivate *priv;
+    int tread;
     struct snd_timer_select sel = {0};
 
     g_return_if_fail(ALSATIMER_IS_USER_INSTANCE(self));
     g_return_if_fail(device_id != NULL);
     priv = alsatimer_user_instance_get_instance_private(self);
 
+    tread = (int)event_data_type;
+    if (ioctl(priv->fd, SNDRV_TIMER_IOCTL_TREAD, &tread) < 0) {
+        generate_error(error, errno);
+        return;
+    }
+    priv->event_data_type = event_data_type;
+
     sel.id = *device_id;
     if (ioctl(priv->fd, SNDRV_TIMER_IOCTL_SELECT, &sel) < 0)
         generate_error(error, errno);
@@ -133,6 +145,7 @@ void alsatimer_user_instance_attach(ALSATimerUserInstance *self,
  * @slave_class: The class identifier of master instance, one of
  *               #ALSATimerSlaveClass.
  * @slave_id: The numerical identifier of master instance.
+ * @event_data_type: The type of event data, one of ALSATimerEventDataType.
  * @error: A #GError.
  *
  * Attach the instance to timer device as an slave to another instance indicated
@@ -145,14 +158,23 @@ void alsatimer_user_instance_attach(ALSATimerUserInstance *self,
 void alsatimer_user_instance_attach_as_slave(ALSATimerUserInstance *self,
                                         ALSATimerSlaveClass slave_class,
                                         int slave_id,
+                                        ALSATimerEventDataType event_data_type,
                                         GError **error)
 {
     ALSATimerUserInstancePrivate *priv;
+    int tread;
     struct snd_timer_select sel = {0};
 
     g_return_if_fail(ALSATIMER_IS_USER_INSTANCE(self));
     priv = alsatimer_user_instance_get_instance_private(self);
 
+    tread = (int)event_data_type;
+    if (ioctl(priv->fd, SNDRV_TIMER_IOCTL_TREAD, &tread) < 0) {
+        generate_error(error, errno);
+        return;
+    }
+    priv->event_data_type = event_data_type;
+
     sel.id.dev_class = SNDRV_TIMER_CLASS_SLAVE;
     sel.id.dev_sclass = slave_class;
     sel.id.device = slave_id;
@@ -238,6 +260,40 @@ void alsatimer_user_instance_get_status(ALSATimerUserInstance *self,
     }
 }
 
+static void handle_tick_events(TimerUserInstanceSource *src, int len)
+{
+    struct snd_timer_read *ev = src->buf;
+
+    while (len >= sizeof(*ev)) {
+        ALSATimerEventDataTick *data = ALSATIMER_EVENT_DATA_TICK(src->event_data);
+
+        timer_event_data_tick_set_data(data, ev);
+        g_signal_emit(src->self,
+                timer_user_instance_sigs[TIMER_USER_INSTANCE_SIG_HANDLE_EVENT],
+                0, src->event_data);
+
+        len -= sizeof(*ev);
+        ++ev;
+    }
+}
+
+static void handle_timestamp_events(TimerUserInstanceSource *src, int len)
+{
+    struct snd_timer_tread *ev = src->buf;
+
+    while (len >= sizeof(*ev)) {
+        ALSATimerEventDataTimestamp *data = ALSATIMER_EVENT_DATA_TIMESTAMP(src->event_data);
+
+        timer_event_data_timestamp_set_data(data, ev);
+        g_signal_emit(src->self,
+                timer_user_instance_sigs[TIMER_USER_INSTANCE_SIG_HANDLE_EVENT],
+                0, src->event_data);
+
+        len -= sizeof(*ev);
+        ++ev;
+    }
+}
+
 static gboolean timer_user_instance_prepare_src(GSource *src, gint *timeout)
 {
     *timeout = 500;
@@ -282,6 +338,11 @@ static gboolean timer_user_instance_dispatch_src(GSource *gsrc, GSourceFunc cb,
         return G_SOURCE_REMOVE;
     }
 
+    if (priv->event_data_type == ALSATIMER_EVENT_DATA_TYPE_TICK)
+        handle_tick_events(src, len);
+    else
+        handle_timestamp_events(src, len);
+
     // Just be sure to continue to process this source.
     return G_SOURCE_CONTINUE;
 }
@@ -291,6 +352,7 @@ static void timer_user_instance_finalize_src(GSource *gsrc)
     TimerUserInstanceSource *src = (TimerUserInstanceSource *)gsrc;
 
     g_free(src->buf);
+    g_object_unref(src->event_data);
     g_object_unref(src->self);
 }
 
@@ -313,6 +375,7 @@ void alsatimer_user_instance_create_source(ALSATimerUserInstance *self,
             .finalize       = timer_user_instance_finalize_src,
     };
     ALSATimerUserInstancePrivate *priv;
+    GType event_data_class;
     TimerUserInstanceSource *src;
     long page_size = sysconf(_SC_PAGESIZE);
     void *buf;
@@ -325,6 +388,18 @@ void alsatimer_user_instance_create_source(ALSATimerUserInstance *self,
         return;
     }
 
+    switch (priv->event_data_type) {
+    case ALSATIMER_EVENT_DATA_TYPE_TICK:
+        event_data_class = ALSATIMER_TYPE_EVENT_DATA_TICK;
+        break;
+    case ALSATIMER_EVENT_DATA_TYPE_TIMESTAMP:
+        event_data_class = ALSATIMER_TYPE_EVENT_DATA_TIMESTAMP;
+        break;
+    default:
+        generate_error(error, EINVAL);
+        return;
+    }
+
     buf = g_try_malloc0(page_size);
     if (buf == NULL) {
         generate_error(error, ENOMEM);
@@ -342,4 +417,7 @@ void alsatimer_user_instance_create_source(ALSATimerUserInstance *self,
     src->tag = g_source_add_unix_fd(*gsrc, priv->fd, G_IO_IN);
     src->buf = buf;
     src->buf_len = page_size;
+
+    src->event_data = g_object_new(event_data_class,
+                                  "type", priv->event_data_type, NULL);
 }
index 1448575107ae9499412291e9cd2309ef02fb1f47..5d83933624f607165388edb193eaed848a792876 100644 (file)
@@ -67,11 +67,13 @@ void alsatimer_user_instance_open(ALSATimerUserInstance *self, GError **error);
 
 void alsatimer_user_instance_attach(ALSATimerUserInstance *self,
                                     ALSATimerDeviceId *device_id,
+                                    ALSATimerEventDataType event_data_type,
                                     GError **error);
 
 void alsatimer_user_instance_attach_as_slave(ALSATimerUserInstance *self,
                                         ALSATimerSlaveClass slave_class,
                                         int slave_id,
+                                        ALSATimerEventDataType event_data_type,
                                         GError **error);
 
 void alsatimer_user_instance_get_info(ALSATimerUserInstance *self,