# Choose tstamp type of data for event and register event handler.
instance.choose_event_data_type(ALSATimer.EventDataType.TSTAMP)
-def handle_event(instance, event):
- data = event.get_tstamp_data()
- tstamp = data.get_tstamp([0, 0])
+def handle_tstamp_event(instance, event):
+ tstamp = event.get_tstamp([0, 0])
print('\nEvent at', tstamp)
- print(' ', data.get_event().value_nick)
- print(' ', data.get_val())
-instance.connect('handle-event', handle_event)
+ print(' ', event.get_event().value_nick)
+ print(' ', event.get_val())
+instance.connect('handle-tstamp-event', handle_tstamp_event)
# Decide ALSA timer device to which the instance is attached.
targets = (
} TimerUserInstanceSource;
enum timer_user_instance_sig_type {
- TIMER_USER_INSTANCE_SIG_HANDLE_EVENT = 0,
+ TIMER_USER_INSTANCE_SIG_HANDLE_TICK_EVENT = 0,
+ TIMER_USER_INSTANCE_SIG_HANDLE_TSTAMP_EVENT,
TIMER_USER_INSTANCE_SIG_HANDLE_DISCONNECTION,
TIMER_USER_INSTANCE_SIG_COUNT,
};
gobject_class->finalize = timer_user_instance_finalize;
/**
- * ALSATimerUserInstance::handle-event:
+ * ALSATimerUserInstance::handle-tick-event:
* @self: A [class@UserInstance].
- * @event: (transfer none): The instance of [struct@Event].
+ * @event: (transfer none): The instance of [struct@EventDataTick].
*
- * Emitted when event occurs.
+ * Emitted when tick event occurs.
*/
- timer_user_instance_sigs[TIMER_USER_INSTANCE_SIG_HANDLE_EVENT] =
- g_signal_new("handle-event",
+ timer_user_instance_sigs[TIMER_USER_INSTANCE_SIG_HANDLE_TICK_EVENT] =
+ g_signal_new("handle-tick-event",
G_OBJECT_CLASS_TYPE(klass),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET(ALSATimerUserInstanceClass, handle_event),
+ G_STRUCT_OFFSET(ALSATimerUserInstanceClass, handle_tick_event),
NULL, NULL,
g_cclosure_marshal_VOID__BOXED,
- G_TYPE_NONE, 1, ALSATIMER_TYPE_EVENT);
+ G_TYPE_NONE, 1, ALSATIMER_TYPE_EVENT_DATA_TICK);
+
+ /**
+ * ALSATimerUserInstance::handle-tstamp-event:
+ * @self: A [class@UserInstance].
+ * @event: (transfer none): The instance of [struct@EventDataTstamp].
+ *
+ * Emitted when timestamp event occurs.
+ */
+ timer_user_instance_sigs[TIMER_USER_INSTANCE_SIG_HANDLE_TSTAMP_EVENT] =
+ g_signal_new("handle-tstamp-event",
+ G_OBJECT_CLASS_TYPE(klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(ALSATimerUserInstanceClass, handle_tstamp_event),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE, 1, ALSATIMER_TYPE_EVENT_DATA_TSTAMP);
/**
* ALSATimerUserInstance::handle-disconnection:
return !!(condition & (G_IO_IN | G_IO_ERR));
}
+static void dispatch_tick_events(ALSATimerUserInstance *self, const guint8 *buf, gsize length)
+{
+ const struct snd_timer_read *ev;
+
+ while (length >= sizeof(*ev)) {
+ ev = (const struct snd_timer_read *)buf;
+
+ g_signal_emit(self, timer_user_instance_sigs[TIMER_USER_INSTANCE_SIG_HANDLE_TICK_EVENT],
+ 0, ev);
+
+ length -= sizeof(*ev);
+ buf += sizeof(*ev);
+ }
+}
+
+static void dispatch_tstamp_events(ALSATimerUserInstance *self, const guint8 *buf, gsize length)
+{
+ const struct snd_timer_tread *ev;
+
+ while (length >= sizeof(*ev)) {
+ const struct snd_timer_tread *ev = (const struct snd_timer_tread *)buf;
+
+ g_signal_emit(self, timer_user_instance_sigs[TIMER_USER_INSTANCE_SIG_HANDLE_TSTAMP_EVENT],
+ 0, ev);
+
+ length -= sizeof(*ev);
+ buf += sizeof(*ev);
+ }
+}
+
static gboolean timer_user_instance_dispatch_src(GSource *gsrc, GSourceFunc cb,
gpointer user_data)
{
ALSATimerUserInstance *self = src->self;
ALSATimerUserInstancePrivate *priv;
GIOCondition condition;
- size_t event_size;
- int len;
- guint8 *buf;
+ ssize_t len;
priv = alsatimer_user_instance_get_instance_private(self);
if (priv->fd < 0)
switch (priv->event_data_type) {
case ALSATIMER_EVENT_DATA_TYPE_TICK:
- event_size = sizeof(struct snd_timer_read);
+ dispatch_tick_events(self, src->buf, (size_t)len);
break;
case ALSATIMER_EVENT_DATA_TYPE_TSTAMP:
- event_size = sizeof(struct snd_timer_tread);
+ dispatch_tstamp_events(self, src->buf, (size_t)len);
break;
default:
- return G_SOURCE_CONTINUE;
- }
-
- buf = src->buf;
- while (len > 0) {
- ALSATimerEvent *ev = (ALSATimerEvent *)buf;
-
- g_signal_emit(src->self,
- timer_user_instance_sigs[TIMER_USER_INSTANCE_SIG_HANDLE_EVENT],
- 0, ev);
-
- buf += event_size;
- len -= event_size;
+ break;
}
// Just be sure to continue to process this source.
*
* Allocate [struct@GLib.Source] structure to handle events from ALSA timer character device. In
* each iteration of [struct@GLib.MainContext], the `read(2)` system call is executed to dispatch
- * timer event for [signal@UserInstance::handle-event] signal, according to the result of `poll(2)`
- * system call.
+ * timer event for either [signal@UserInstance::handle-tick-event] or
+ * [signal@UserInstance::handle-tstamp-event] signals, according to the result of `poll(2)` system
+ * call.
*
* Returns: %TRUE when the overall operation finishes successfully, else %FALSE.
*/
GObjectClass parent_class;
/**
- * ALSATimerUserInstanceClass::handle_event:
+ * ALSATimerUserInstanceClass::handle_tick_event:
* @self: A [class@UserInstance].
- * @event: (transfer none): An object derived from [struct@Event].
+ * @event: (transfer none): An object derived from [struct@EventDataTick].
*
- * Class closure for the [signal@UserInstance::handle-event] signal.
+ * Class closure for the [signal@UserInstance::handle-tick-event] signal.
*/
- void (*handle_event)(ALSATimerUserInstance *self,
- const ALSATimerEvent *event);
+ void (*handle_tick_event)(ALSATimerUserInstance *self, const ALSATimerEventDataTick *event);
+
+ /**
+ * ALSATimerUserInstanceClass::handle_tstamp_event:
+ * @self: A [class@UserInstance].
+ * @event: (transfer none): An object derived from [struct@EventDataTstamp].
+ *
+ * Class closure for the [signal@UserInstance::handle-tstamp-event] signal.
+ */
+ void (*handle_tstamp_event)(ALSATimerUserInstance *self, const ALSATimerEventDataTstamp *event);
/**
* ALSATimerUserInstanceClass::handle_disconnection: