Specifications
CHAPTER 5. IMPLEMENTATION 50
gap by reporting all input events of keyboards—whether there is a translation available for a
key’s scancode or not. The source code of the module is found in the directory modules. The
prefix libial evdev is common for all files belonging to the module.
The event interface module can be enabled or disabled. This is the only configuration
option provided by the module. The following source code shows a shortened version of the
module’s relevant data structures:
ModuleOption mod_options[] = {
{"disable", "false", "disable=(true|false)"},
{NULL}
};
ModuleData mod_data = {
.name = "Event Interface Input Abstraction Layer Module",
.token = "evdev",
.options = mod_options,
.load = mod_load,
.unload = mod_unload
};
At initialization time the module first checks its configuration option. If the option disable
is set to true, it returns FALSE to signal the daemon that the initialization was not successful.
Otherwise, the module tries to initialize the event interfaces. For this purpose, the module
scans the directory /dev/input/ for available input event interfaces—each one representing
one input device. Furthermore, each applicable input device is observed for input events.
Once an input event occurs, the module translates the concrete input event to a corresponding
abstract input event. The abstract input events are reported by utilizing the library’s function
event send().
The module’s loading function is invoked by the daemon. The module’s option disable is
verified by a string comparison using strcmp(3). If the module is not disabled, it proceeds.
The verification of each available interface is divided into several steps. First, the module tries
to get a file descriptor for all possible event interfaces. This is done by a loop which iterates
all event interfaces from /dev/input/event0 to /dev/input/event31. If the module has
successfully acquired a file descriptor, it performs a check to determine whether the protocol
of the event interface matches the protocol known to the module. This is done using the
event interface’s ioctl(2) request EV VERSION. If this check is being accomplished without
an error, the module further creates a GIOChannel and associates a corresponding watch with
the daemon’s event loop. The callback function evdev callback() is common for all watches.
Each watch is added with the two conditions G IO IN and G IO ERR.
At this point the module’s initialization is complete. As soon as an input event occurs, the
condition G IO IN is fulfilled and the callback function evdev callback() is invoked by the
event loop. The function is called with one argument: the file descriptor of the event interface
on which the event occurred. Once called, the callback function has several responsibilities:
– Read data from the file descriptor
– Check whether it was a keypress
– Check whether the key is blacklisted