Events Programming Guide

EFL is event-driven. This means that execution usually takes place within an internal EFL Main Loop. The application receives notifications through function callbacks. These can apply to virtually any event which occurs on a computer.

Events play a central role in EFL. In this guide, you'll learn more about the required methods to handle them.

You can also find usage examples in the EFL examples repository: reference/c/core/src/core_event.c

Prerequisites

Listening to Events from Objects

All Eo objects can emit events. You can discover more about this in the Events sections of their respective API Reference documentation.

To register a callback method to be called when an object emits a given event use efl_event_callback_add():

efl_event_callback_add(object, event, callback, data);

Substitute object for any Eo * or derived object and event for the identifier of the event (such as EFL_LOOP_EVENT_POLL_HIGH or EFL_LOOP_TIMER_EVENT_TIMER_TICK). Set callback to the method to be called when the event occurs and data to any data you want to pass to your callback (if you have no need of this use NULL).

The method signature for the callback is:

void callback(void *data, const Efl_Event *event);

In the above example data is the last parameter you used when registering the callback with efl_event_callback_add(). event contains information about the event itself:

Attribute Type Content
event->object Eo * The Object that emitted the event
event->info void * Used by some events to provide additional information. Must be cast to the appropriate type (see below).
event->desc->name const char * Name of the event

The API Reference documentation for each event tells you how to use event->info. See EFL_EVENT_POINTER_DOWN for more examples.

To stop receiving notifications for a particular event (unregister a callback) use efl_event_callback_del():

efl_event_callback_del(object, event, callback, data);

The parameters here have the same meaning as for efl_event_callback_add(). Note that in order to unregister the callback you have to provide the same parameters you used to register it. This is because you can register different callbacks to the same event or even the same callback with different data.

NOTE: Registering and unregistering callbacks is an resource-intensive process. If you perform these operations continuously on several callbacks at the same time do so in a batch as this is more efficient. You can use efl_event_callback_array_add() and efl_event_callback_array_del() to accomplish this. Remember however that you can't unregister an individual callback which has been registered in a batch. They must all be unregistered together.

Below is an example code snippet based on reference/c/core/src/core_event.c:

static void
callback(void *data, const Efl_Event *event)
{
   Efl_Loop *polled = data;
   printf("  Polled %s from %s\n", efl_name_get(polled), efl_name_get(event->object));
}
 
void
setup()
{
   [...]
   efl_add(EFL_LOOP_TIMER_CLASS, mainloop,
           efl_name_set(efl_added, "timer2"),
           efl_loop_timer_interval_set(efl_added, .1),
           efl_event_callback_add(efl_added, EFL_LOOP_TIMER_EVENT_TIMER_TICK, callback, mainloop));
   [...]
}

Here a new timer object is created and added to mainloop. The configuration of this timer takes place entirely inside the efl_add() call, as explained in the Introduction to Eo tutorial.

Note how the polled object is passed as the data parameter to efl_event_callback_add() and recovered from the callback. The object that emitted the event (the timer) is also recovered from the callback through the event parameter.

Pausing and Resuming Event Notifications

All event emissions from a given object can be paused (frozen) using efl_event_freeze() and resumed with efl_event_thaw():

   efl_event_freeze(object);
   efl_event_thaw(object);

While an object is frozen only high-priority events (marked as hot) will be emitted. Hot events cannot be stopped.

Remember that ALL events emitting from a object are stopped if its frozen, except for hot events. If you need to stop individual events you can unregister their callback temporarily and then re-register later.

Defining Custom Events

You can define any number of custom events and emit them from any Eo object. You can then register callbacks to be activated by these events.

First create a Efl_Event_Description variable. Next, initialize it with EFL_EVENT_DESCRIPTION() and make it available everywhere you want to use this new event:

   Efl_Event_Description CUSTOM_EVENT = EFL_EVENT_DESCRIPTION("custom-event");

Register to this event as you would normally do for EFL events with efl_event_callback_add():

   efl_event_callback_add(object, &CUSTOM_EVENT, callback, data);

data works as usual and can be recovered from the callback through the data parameter.

Now emit the event using efl_event_callback_call():

   efl_event_callback_call(object, &CUSTOM_EVENT, event_info);

event_info will be passed to the callback through the event->info parameter. Its meaning is completely up to you as the event creator.

Further Reading

reference/c/core/src/core_event.c
EFL examples repository
Efl.Object API Reference
Detailed documentation for the EFL object, which implements the events mechanism
Introduction to Eo
Tutorial on instantiating and configuring Eo objects