From 8d59cdb5b15fe0f5dad19e23924d5ae90674ddb5 Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Sun, 9 Feb 2020 12:20:53 +0900 Subject: [PATCH] timer: user_instance: emit 'handle-event' signal Signed-off-by: Takashi Sakamoto --- src/timer/event-data-tick.c | 10 ++++ src/timer/event-data-timestamp.c | 10 ++++ src/timer/instance-params.c | 6 ++- src/timer/privates.h | 9 ++++ src/timer/user-instance.c | 78 ++++++++++++++++++++++++++++++++ src/timer/user-instance.h | 2 + 6 files changed, 113 insertions(+), 2 deletions(-) diff --git a/src/timer/event-data-tick.c b/src/timer/event-data-tick.c index f5ba1e9..1337a08 100644 --- a/src/timer/event-data-tick.c +++ b/src/timer/event-data-tick.c @@ -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; +} diff --git a/src/timer/event-data-timestamp.c b/src/timer/event-data-timestamp.c index 51e7eb2..69d6725 100644 --- a/src/timer/event-data-timestamp.c +++ b/src/timer/event-data-timestamp.c @@ -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; +} diff --git a/src/timer/instance-params.c b/src/timer/instance-params.c index 8e31491..0a15302 100644 --- a/src/timer/instance-params.c +++ b/src/timer/instance-params.c @@ -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, diff --git a/src/timer/privates.h b/src/timer/privates.h index 87d3dcc..3e174af 100644 --- a/src/timer/privates.h +++ b/src/timer/privates.h @@ -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 @@ -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 diff --git a/src/timer/user-instance.c b/src/timer/user-instance.c index 6ec4ce5..4f12948 100644 --- a/src/timer/user-instance.c +++ b/src/timer/user-instance.c @@ -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); } diff --git a/src/timer/user-instance.h b/src/timer/user-instance.h index 1448575..5d83933 100644 --- a/src/timer/user-instance.h +++ b/src/timer/user-instance.h @@ -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, -- 2.47.3