Hubbry Logo
EvdevEvdevMain
Open search
Evdev
Community hub
Evdev
logo
8 pages, 0 posts
0 subscribers
Be the first to start a discussion here.
Be the first to start a discussion here.
Contribute something
Evdev
Evdev
from Wikipedia
Evdev and libevdev form a prominent part of the Linux API.

evdev (short for 'event device') is a generic input event interface in the Linux kernel and FreeBSD.[1] It generalizes raw input events from device drivers and makes them available through character devices in the /dev/input/ directory.

The user-space library for the kernel component evdev is called libevdev. Libevdev abstracts the evdev ioctls through type-safe interfaces and provides functions to change the appearance of the device. Libevdev shares similarities with the read system call.[2]

It sits below the process that handles input events, in between the kernel and that process.

kernel → libevdev → xf86-input-evdev → X server → X client

For Weston/Wayland compositor, the stack would look like this:

kernel → libevdev → libinputWayland compositor → Wayland client

Since version 1.16 the xorg-xserver obtained support for libinput:

kernel → libevdev → libinput → xf86-input-libinput → X server → X client

evdev is primarily used by display servers like X.org (via xf86-input-evdev driver and libevdev) and Weston, as well as by games and console emulators making use of USB and Bluetooth controllers.

See also

[edit]

References

[edit]
[edit]
Revisions and contributorsEdit on WikipediaRead on Wikipedia
from Grokipedia
Evdev, short for "event device," is a generic input event interface within the kernel's input subsystem that enables userspace applications to receive standardized raw input events from hardware devices such as keyboards, mice, touchpads, and joysticks. It serves as the primary mechanism for passing events generated by device drivers directly to programs, including timestamps and hardware-independent event codes, via character devices typically exposed as /dev/input/eventX. Developed by Vojtech Pavlik in the late and sponsored by SuSE, evdev was introduced to provide a unified, architecture-agnostic way to handle input across diverse devices, replacing fragmented legacy interfaces such as /dev/psaux for PS/2 mice and direct console access for keyboards. The interface supports both blocking and non-blocking reads, as well as operations like select(), allowing efficient event consumption without polling. Events are structured using the struct input_event, which includes a timestamp (struct timeval), event type (unsigned short), event code (unsigned short), and value (int). Key event types defined in evdev include EV_KEY for keyboard and presses/releases (with values indicating press, release, or repeat), EV_REL for relative movements like pointers, EV_ABS for absolute positions such as touch coordinates, and EV_SYN for synchronizing event packets. Additional types cover miscellaneous (EV_MSC), switches (EV_SW), LEDs (EV_LED), commands (EV_SND), autorepeat settings (EV_REP), force feedback (EV_FF), and power events (EV_PWR). This comprehensive framework ensures compatibility with a wide range of input hardware, forming the foundation for tools like Xorg input drivers and libraries such as libevdev or python-evdev.

Overview

Definition and Purpose

Evdev, short for "event device," is a generic input event interface implemented in the and that generalizes raw input events from various device drivers into a standardized format. It serves as a core component of the input subsystem, enabling the kernel to capture and process events from hardware such as keyboards, mice, and touchscreens before relaying them to userspace applications. The primary purpose of evdev is to deliver kernel-generated input events—such as keystrokes, movements, and touch inputs—directly to userspace programs, each accompanied by a precise for . This design provides a hardware-independent application programming interface () that abstracts away device-specific details, allowing applications to interact with input hardware uniformly without needing to handle low-level driver protocols. In both and , evdev operates through character devices, facilitating efficient event streaming while supporting ioctl-based queries for device capabilities. Evdev offers several key benefits, including consistent event codes that remain uniform across different architectures, ensuring portability for software developed on one platform to function reliably on others. It promotes a clear separation between input devices and consuming applications, reducing complexity in userspace code and enabling support for diverse device types like joysticks and touchscreens without custom integrations. Introduced as part of the input subsystem in the early to supersede older, device-specific interfaces, evdev enhances overall efficiency and maintainability by centralizing event handling in the kernel. In , its implementation, added around 2016, mirrors this Linux-centric approach for ioctl-level compatibility, further broadening its utility in environments.

History

The development of evdev, the generic input event interface for the , was primarily led by Vojtech Pavlik as part of the Linux input drivers version 1.0, with initial work beginning in 1999 and finalized in 2001. Sponsored by SuSE, Pavlik's efforts addressed the need for a flexible and unified system to handle the increasing variety of input devices, such as keyboards, mice, joysticks, and emerging USB peripherals, which prior fragmented drivers struggled to support efficiently. Evdev was formally introduced in Linux kernel version 2.4.0, released on January 4, 2001, marking a significant unification of input handling within the new input subsystem architecture. This integration allowed device drivers to generate standardized events passed directly to userspace applications via character devices under /dev/input/event*, reducing redundancy and improving portability across hardware. As the Linux kernel evolved, evdev became a core component of the input subsystem, with enhancements in the 2.6 series (starting from 2003) expanding its capabilities to include support for protocols—introduced in kernel 2.6.30 in 2009 to handle absolute multi-finger coordinates—and force feedback (EV_FF events) for haptic devices, enabling effects like in joysticks and gamepads from kernel 2.6.11 onward. Key milestones in evdev's adoption include its integration into the and X.org display stacks around 2006, when the xf86-input-evdev was first developed to leverage kernel events for hotplugging and multi-device support in graphical environments. FreeBSD began implementing evdev kernel support in 2014 as part of the , with the changes accepted and committed in 2016 to provide compatibility with input handling. By 2025, evdev remains a standard feature in modern kernels, such as the 6.x series, with ongoing to accommodate new device protocols like advanced touch gestures and inputs.

Kernel Implementation

Event Structure

The evdev interface defines input events using the struct input_event data structure, which encapsulates the details of hardware-generated input changes for transmission to userspace. This structure is specified in the Linux kernel's user API header include/uapi/linux/input.h. The structure includes a timestamp field using struct timeval to record the event's occurrence in seconds and microseconds, ensuring precise temporal ordering of events. Following the timestamp, a 16-bit unsigned integer (__u16) denotes the event type, categorizing the input such as key actions or axis movements. An adjacent __u16 field specifies the event code, identifying the exact input element involved, like a particular key or coordinate axis. The final field is a 32-bit signed integer (__s32) for the event value, which conveys the change's magnitude—for instance, 1 indicating a key press, 0 for release, or a signed delta for positional shifts. Due to field alignments and padding for ABI stability across architectures, the structure occupies 24 bytes on 64-bit systems. Events are not emitted in isolation but grouped into logical packets representing atomic hardware reports, delimited by synchronization events of type EV_SYN with code SYN_REPORT. This grouping ensures that related changes, such as a key press and its synchronization, are processed as a cohesive unit, separating distinct hardware interactions in time or context. For example, a keyboard 'A' key press might produce an event packet with timestamp set to the current time, type EV_KEY, code KEY_A, and value 1, immediately followed by a SYN_REPORT event (type EV_SYN, code SYN_REPORT, value 0). Individual events report only state transitions or deltas rather than full device snapshots, promoting efficiency by avoiding redundant data. The kernel maintains the complete device state internally through bitmasks and arrays, which userspace can query via ioctls such as EVIOCGKEY to retrieve the current global key or button states without replaying the event history.

Event Types and Codes

In the evdev interface, events are categorized by types defined in the kernel's input subsystem, each representing a logical grouping of input data such as key presses, axis movements, or device states. These types are encoded in the type field of the input event structure, with associated codes specifying the exact event within the type. The kernel documentation outlines 12 primary event types, which allow hardware drivers to report diverse inputs from devices like keyboards, mice, touchscreens, and joysticks in a standardized manner. The EV_KEY type handles state changes for keys and buttons, using codes such as KEY_A (30) for the 'A' key on a keyboard or BTN_LEFT (272) for the primary . Values for EV_KEY events indicate 0 for release, 1 for press, and 2 for autorepeat. The EV_REL type reports relative displacements, common in pointing devices, with codes like REL_X (0x00) for horizontal movement or REL_WHEEL (0x08) for detents; values represent the signed delta in device units. Similarly, EV_ABS captures absolute positions or states, such as ABS_X (0x00) for X-axis coordinates on a or ABS_MT_POSITION_X (0x35) for multitouch finger positions on a , where values denote the exact position within the device's range. EV_MSC serves for miscellaneous events not covered by other types, including codes like MSC_TIMESTAMP for high-resolution timing in microseconds. EV_SW manages binary switches, such as SW_LID (0) for a laptop lid status, with values of 0 or 1 indicating off or on. EV_LED controls output to device LEDs, using codes like LED_NUML for the indicator, where values enable (1) or disable (0) the light. EV_SND triggers sound emissions from the device, with codes such as SND_CLICK for a click sound and values specifying volume or other parameters. EV_REP configures autorepeat behavior for keyboards, including REP_DELAY (0) for initial delay and REP_PERIOD (1) for repeat interval, with values in milliseconds. EV_FF supports force feedback effects in devices like gamepads, using codes to upload or play effects such as FF_CONSTANT (0x00) for constant force. EV_PWR reports power management events, such as those from power buttons and switches. EV_FF_STATUS reports the status of force feedback effects, with the value set to FF_STATUS_STOPPED (0) when the effect stops or FF_STATUS_PLAYING (1) when it starts playing. Synchronization is handled by the EV_SYN type, which delimits groups of simultaneous events; key codes include SYN_REPORT (0) to mark the end of a logical event packet and SYN_MT_REPORT (2) to separate slot reports. Additionally, devices can expose properties via EVIOCGPROP ioctls, such as INPUT_PROP_DIRECT (0x01) for touchscreens that map coordinates directly to the display without pointer emulation. These types and codes ensure consistent interpretation across input hardware, enabling drivers to generate events that userspace applications can process reliably.

Userspace Access

Device Files and Permissions

Evdev devices appear in the user-space filesystem as character special files under the /dev/input/ directory, typically named /dev/input/eventX, where X is a sequential non-negative beginning at 0. These files provide direct access to raw input events generated by hardware devices such as keyboards, mice, and touchscreens. The input core automatically creates these nodes upon registration of an when the evdev handler is active in the kernel. The device files use major number 13, with minor numbers starting at 64 for the first device (/dev/input/event0 as minor 64) and incrementing sequentially. The initial 32 devices occupy the static legacy range of minors 64 through 95, while additional devices beyond this limit receive dynamically allocated minors beginning at 256 to accommodate larger systems. The input subsystem supports up to 1024 character devices under major 13, allowing for more than 256 evdev devices shared with other input handlers. For instance, the command ls -l /dev/input/event0 on a kernel-default system commonly displays crw-r--r-- 1 root root 13,64 /dev/input/event0, indicating character device type, read access for all users, write access only for root, and ownership by root. By default in the kernel, these files have 644 permissions, owned by :, allowing read access to all users but write access only to ; however, this permits any user to access sensitive input like keystrokes, posing a . Most distributions address this by configuring rules to set permissions to 660 with ownership :input, restricting read and write access to and members of the input group (GID varies by distribution, e.g., 29 on Debian-based systems). A typical rule for this purpose, placed in /etc/udev/rules.d/, is KERNEL=="event*", SUBSYSTEM=="input", MODE="0660", GROUP="input", which sets group read/write permissions for the input group. To enable non- applications, such as input daemons or graphical environments, to read and write events, users must belong to the input group and relogin. This setup balances with functionality, as unrestricted access could allow . Device identification is facilitated through ioctls on the open file descriptor: EVIOCGNAME retrieves a string with the device's human-readable name (up to 256 characters), while EVIOCGID fetches a structure containing the bus type, vendor ID, product ID, and version. These queries help userspace applications match event sources to specific hardware without relying on filename indices alone. Additionally, while evdev provides general event access, joystick devices may expose parallel files like /dev/input/jsX via the separate joydev handler for specialized protocols.

Reading and Handling Events

Userspace programs access evdev devices by opening the corresponding device files under /dev/input/eventX, where X is a non-negative integer identifying the device. The open() system call can be used in either blocking or non-blocking mode; in blocking mode, read() waits until events are available, while non-blocking mode returns immediately if no events are pending, typically setting the O_NONBLOCK flag. The read() call retrieves an array of struct input_event structures, each 24 bytes in size, representing individual events generated by the device. To efficiently monitor multiple devices or integrate with event-driven applications, userspace can employ polling mechanisms such as select() or poll() on the file descriptors obtained from open(). These functions allow the program to wait for input readiness without busy-waiting, returning when data is available for reading on the specified descriptors. For higher performance in scenarios with many file descriptors, epoll() may also be used, though it is not specific to evdev. Several ioctls provide metadata about the device and its capabilities. The EVIOCGVERSION retrieves the version of the evdev interface supported by the kernel. To query supported event types, EVIOCGBIT(EV_MAX, nbytes) returns a bitmask indicating which event types the device can generate. Similarly, EVIOCGKEY(len) fetches the current state of all key events as a of the specified length. Other ioctls like EVIOCGBIT(type, nbytes) allow querying specific event codes within a type. Handling events typically involves a loop that reads from the file descriptor and parses the returned struct input_event arrays. Each structure contains a timestamp, event type, event code, and value; events are processed sequentially until a SYN_REPORT event (type EV_SYN, code SYN_REPORT) is encountered, which delimits the end of a logical event packet representing simultaneous changes. Other EV_SYN events, such as SYN_DROPPED, indicate that events were lost due to buffer overrun and should be ignored until the next SYN_REPORT, after which the current device state must be queried via ioctls to resynchronize. The following pseudocode illustrates a basic event reading loop in C:

c

#include <linux/input.h> #include <sys/ioctl.h> #include <unistd.h> #include <fcntl.h> int fd = open("/dev/input/event0", O_RDONLY | O_NONBLOCK); struct input_event ev[64]; ssize_t n; while ((n = read(fd, ev, sizeof(ev))) > 0) { int num = n / sizeof(struct input_event); for (int i = 0; i < num; i++) { if (ev[i].type == EV_SYN && ev[i].code == SYN_REPORT) { // Process the packet of events up to this point break; } // Handle ev[i].type, ev[i].code, ev[i].value } } close(fd);

#include <linux/input.h> #include <sys/ioctl.h> #include <unistd.h> #include <fcntl.h> int fd = open("/dev/input/event0", O_RDONLY | O_NONBLOCK); struct input_event ev[64]; ssize_t n; while ((n = read(fd, ev, sizeof(ev))) > 0) { int num = n / sizeof(struct input_event); for (int i = 0; i < num; i++) { if (ev[i].type == EV_SYN && ev[i].code == SYN_REPORT) { // Process the packet of events up to this point break; } // Handle ev[i].type, ev[i].code, ev[i].value } } close(fd);

This example reads up to 64 events at a time, computes the actual number received, and processes them until a SYN_REPORT is found, marking the packet boundary. In practice, the loop should check for EV_SYN events appropriately and handle parsing based on the event type and code. Error handling is essential for robust applications. In non-blocking mode, read() returns -1 with errno set to EAGAIN when no events are available. For buffer overruns signaled by SYN_DROPPED, the application must use ioctls like EVIOCGKEY or EVIOCGABS to retrieve the current device state and continue from there. Interrupts from signals may cause EINTR, requiring the read to be retried. Timestamps in struct input_event use struct timeval and default to wall-clock time (CLOCK_REALTIME). In kernels since version 3.17, the EVIOCSCLOCKID ioctl allows setting the timestamp source to the monotonic clock (CLOCK_MONOTONIC) for more reliable, non-adjustable timing suitable for input processing. This is particularly useful in environments where system time adjustments could otherwise skew event ordering. While direct access via system calls offers low-level control, many applications prefer wrapper libraries like libevdev for simplified event handling, capability querying, and state tracking, though such libraries are covered in detail elsewhere.

Integration in Display Systems

X11 Stack

In the X11 display server ecosystem, evdev integrates as the foundational kernel interface for input events, which are processed through dedicated X.org input drivers to deliver user interactions to applications. Traditionally, the flow follows the kernel's evdev devices—exposed as /dev/input/event* files—directly to the xf86-input-evdev driver, which interfaces with the X server core to translate raw events into pointer, keyboard, and other input actions for X client applications. This driver serves as a generic handler for all Linux evdev-compatible devices, encompassing keyboards, mice, touchpads, tablets, and joysticks, by reading events from the kernel and applying device-specific transformations before passing them to the server. The xf86-input-evdev driver plays a central role in this integration by providing unified support for diverse input hardware, replacing older specialized drivers such as xf86-input-kbd and xf86-input-mouse to streamline handling under a single framework. It incorporates features like axis calibration for touchscreens and tablets—configurable via the "Evdev Axis Calibration" property with four values defining minimum and maximum coordinates for X and Y axes. These capabilities ensure precise input mapping without requiring per-device kernel modifications, while the driver leverages the X server's input extension (XI) for multi-device coordination. Configuration of evdev devices in the X11 stack typically occurs through xorg.conf or drop-in files in /etc/X11/xorg.conf.d/, using InputClass sections that match devices by attributes like vendor or product ID and specify Driver "evdev". For instance, an InputClass block can enable options such as button mapping or third-button emulation for trackpoints, though automatic detection via udev rules is preferred for hotplug support, allowing dynamic addition of devices without manual restarts. This hotplug mechanism, integrated since early evdev adoption, relies on udev to monitor kernel events and notify the X server, enabling seamless handling of USB insertions or wireless pairings. Since the release of X.org Server 1.16 in 2014, the input stack has evolved toward a layered approach, where kernel evdev events pass through the libevdev library for abstraction, then to the libinput library for advanced processing like gesture recognition and smoothing, before reaching the xf86-input-libinput wrapper driver and finally the X server. This shift, adopted as the default in distributions like Fedora 22 in 2015, unifies input handling across X11 and Wayland while retaining evdev compatibility, with xf86-input-libinput acting as a minimal passthrough that exposes libinput's features via X properties and configuration snippets like 40-libinput.conf. The xf86-input-evdev remains available for legacy or specialized setups requiring direct low-level control, but libinput's stack is now standard for its enhanced multitouch and calibration support.

Wayland Stack

In the Wayland display server protocol, evdev serves as the foundational interface for accessing hardware input events from the Linux kernel, forming the initial layer in the input processing stack. Raw events from kernel evdev devices, exposed via /dev/input/event* files, are typically processed through libevdev for parsing and then fed into libinput, which acts as the standard input library for Wayland compositors. This creates a direct pipeline: kernel evdev → libevdev → libinput → Wayland compositor (such as Weston or Mutter) → Wayland client. Libinput normalizes these events, applying device-specific configurations like pointer acceleration to smooth cursor movement based on velocity profiles, and handles touchpad-specific features including multi-finger tapping (mapped to button clicks) and gesture recognition for swipes or pinches. Wayland compositors integrate this stack to manage input delivery, with libinput being the de facto standard for general-purpose implementations, providing normalized events that abstract away low-level evdev details for easier compositor development. For instance, GNOME's Mutter and the reference compositor Weston rely on libinput to process evdev-sourced events for multitouch and gesture support, ensuring consistent behavior across devices. Some compositors, like Sway (an i3-compatible Wayland manager built on wlroots), also utilize libinput for input handling, though direct evdev access via libevdev is possible in specialized or minimal setups for custom event routing. This approach enables compositors to group devices into "seats" under the wl_seat interface, dispatching events precisely to relevant clients without unnecessary broadcasting. Compared to the X11 stack, Wayland's evdev integration offers enhanced security by eliminating global input grabs—compositors control access directly, preventing remote clients from intercepting events across sessions—and supports per-surface input routing, where events are delivered only to the focused surface rather than the entire server. Evdev has been integral to Wayland since its inception in 2012, providing essential hardware event access even in nested compositor scenarios, such as embedding one Wayland instance within another for isolated environments. As of 2025, major Linux distributions and desktop environments such as GNOME are transitioning to Wayland as the default display protocol, with X11 support being phased out in favor of Wayland while evdev continues to serve as the core kernel input interface for both.

libevdev Library

libevdev is a userspace C library designed to simplify interaction with Linux input devices through the evdev interface, abstracting the underlying kernel ioctls into a type-safe API that handles common tasks such as device initialization, capability discovery, and event processing. By encapsulating the complexities of raw evdev access, including ioctl calls for querying device properties and reading events, libevdev reduces the risk of errors like invalid struct handling or missed synchronization signals, making it suitable for applications requiring reliable input event handling. The library was initially released in 2013 and has been actively maintained by Peter Hutterer since its inception. Central to libevdev's functionality are key APIs for device management and event retrieval. The function libevdev_new_from_fd() initializes a device handle from an open file descriptor, enabling subsequent operations without direct ioctl exposure. Device information, such as the name or vendor details, can be retrieved via libevdev_get_name(), while capability checks use libevdev_has_event_type() and libevdev_has_event_code() to determine supported event types and codes without manual parsing. For event reading, libevdev_next_event() fetches the next event from the device, automatically handling synchronization issues like SYN_DROPPED events by applying state deltas to reconstruct missed inputs. Additional features include queries for device properties like repeat rates via libevdev_get_repeat() and support for signal-safe operations in most functions, ensuring compatibility with event-driven applications. libevdev avoids the need for direct parsing of the raw struct input_event, instead providing filtered and validated event streams that developers can process more safely. It has seen widespread adoption in input handling stacks, including the libinput library for multitouch and pointer devices, as well as X.Org's xf86-input-evdev driver, and various Wayland compositors. A typical usage pattern involves enumerating potential devices under /dev/input/event* using udev monitoring, opening a selected file descriptor, initializing with libevdev_new_from_fd(), querying supported events to filter irrelevant ones, and then entering a loop with libevdev_next_event() to process incoming data. For instance, a basic event reader might look like this:

#include <libevdev/libevdev.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> int fd = open("/dev/input/[event0](/page/Event_0)", O_RDONLY | O_NONBLOCK); struct libevdev *dev; if (libevdev_new_from_fd(fd, &dev) < 0) { // Handle error close(fd); return 1; } const char *name = libevdev_get_name(dev); // Retrieve device name if (name) { [printf](/page/Printf)("Device name: %s\n", name); } struct input_event ev; int rc; do { rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev); if (rc == LIBEVDEV_READ_STATUS_SUCCESS || rc == LIBEVDEV_READ_STATUS_SYNC) { // Handle event (e.g., print or process ev) [printf](/page/Printf)("Event: type=%d, code=%d, value=%d\n", ev.type, ev.[code](/page/Code), ev.value); } else if (rc == -EAGAIN) { // No events, continue or sleep usleep(1000); } else { // Handle error break; } } while (rc != -ENODEV); // Or other exit condition libevdev_free(dev); close(fd);

#include <libevdev/libevdev.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> int fd = open("/dev/input/[event0](/page/Event_0)", O_RDONLY | O_NONBLOCK); struct libevdev *dev; if (libevdev_new_from_fd(fd, &dev) < 0) { // Handle error close(fd); return 1; } const char *name = libevdev_get_name(dev); // Retrieve device name if (name) { [printf](/page/Printf)("Device name: %s\n", name); } struct input_event ev; int rc; do { rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev); if (rc == LIBEVDEV_READ_STATUS_SUCCESS || rc == LIBEVDEV_READ_STATUS_SYNC) { // Handle event (e.g., print or process ev) [printf](/page/Printf)("Event: type=%d, code=%d, value=%d\n", ev.type, ev.[code](/page/Code), ev.value); } else if (rc == -EAGAIN) { // No events, continue or sleep usleep(1000); } else { // Handle error break; } } while (rc != -ENODEV); // Or other exit condition libevdev_free(dev); close(fd);

This approach ensures robust event handling while abstracting kernel-level details.

uinput for Event Injection

uinput serves as the userspace interface to the input subsystem for creating virtual input devices and injecting synthetic events, complementing the evdev mechanism which primarily handles reading from physical devices. This kernel module allows processes to emulate hardware input devices, such as keyboards or mice, by writing to the special /dev/uinput or /dev/input/uinput. The injected events are then processed by the kernel as if they originated from real hardware, making uinput essential for applications requiring simulated input, including automated testing, macro recording, and virtual device creation. To set up a virtual device with uinput, a userspace process first opens the uinput device file in write-only non-blocking mode. It then uses ioctl calls to declare the device's capabilities: UI_SET_EVBIT to enable event types (e.g., EV_KEY for keys), and UI_SET_KEYBIT to specify supported codes (e.g., KEY_A for the 'A' key). Additional ioctls like UI_SET_ABSBIT can define absolute axes for devices such as touchpads. Once capabilities are set, UI_DEV_SETUP configures properties like the device name and UI_DEV_CREATE registers the virtual device, resulting in a corresponding /dev/input/eventX file that other processes can read as with physical evdev devices. Event injection occurs by writing struct input_event structures to the uinput via the write() system call. Each structure contains fields for type (e.g., EV_KEY), code (e.g., KEY_SPACE), value (e.g., 1 for press, 0 for release), and time for the event timestamp. A typical key press simulation involves writing an EV_KEY event followed by an EV_SYN synchronization event with code SYN_REPORT and value 0 to commit the change. For example, simulating a spacebar press requires two writes: one for the key down and one for the sync. To remove the device, the process issues UI_DEV_DESTROY ioctl and closes the . Unlike evdev, which provides read access to events from hardware input devices, uinput enables write access for generating synthetic events to simulate input, supporting use cases like software-based input for testing or creating virtual peripherals without physical hardware. Enabling uinput requires the CONFIG_INPUT_UINPUT kernel configuration option, typically built as a module named uinput.ko. Permissions for /dev/uinput are managed similarly to evdev files, often set to 0660 with ownership by root and the input group, allowing non-root access for users in that group via udev rules. It is commonly employed in userspace tools for input injection, such as ydotool for command-line automation on Wayland and X11 environments.

References

Add your contribution
Related Hubs
Contribute something
User Avatar
No comments yet.