Файл устройства /dev/input/event
Файл устройства /dev/input/event — это специальный файл (символьное устройство) в операционной системе Linux, предоставляющий интерфейс для чтения событий от устройств ввода (клавиатур, мышей, тачпадов, джойстиков, сенсорных экранов и других). Данные файлы являются частью подсистемы ввода ядра Linux (input subsystem) и служат основным каналом для передачи информации о действиях пользователя от физического оборудования к прикладному программному обеспечению.
Назначение и принцип работы
В Linux каждое устройство ввода, поддерживаемое ядром, получает свой собственный файл устройства в каталоге /dev/input/. Имена файлов имеют вид event0, event1, event2 и так далее. Номер устройства присваивается ядром автоматически при обнаружении оборудования или загрузке драйвера. При этом файл event не является «файлом» в традиционном смысле — он не хранит данные, а представляет собой интерфейс для взаимодействия с драйвером устройства в пространстве пользователя.
Когда пользователь совершает действие (нажимает клавишу, двигает мышь, касается экрана), драйвер устройства генерирует структуру данных, называемую input_event. Эта структура содержит информацию о типе события, коде (идентификаторе конкретной клавиши, оси или кнопки) и значении (например, нажата или отпущена клавиша, новое положение оси). Ядро помещает эти события в буфер, откуда их может прочитать любая программа, открывшая соответствующий файл /dev/input/eventN.
Структура input_event
Событие, передаваемое через файл устройства, описывается структурой struct input_event, определённой в заголовочном файле <linux/input.h>. Она имеет фиксированный размер (обычно 24 байта на 64-битных системах) и включает следующие поля:
struct timeval time— временная метка события (секунды и микросекунды с точностью до микросекунд). Позволяет точно определить момент возникновения события.__u16 type— тип события (например,EV_KEY— клавиша/кнопка,EV_REL— относительное перемещение,EV_ABS— абсолютное перемещение,EV_SYN— синхронизация).__u16 code— код события (например, дляEV_KEY— код клавиши, такой какKEY_AилиBTN_LEFT; дляEV_REL— код оси, такой какREL_XилиREL_Y).__s32 value— значение события (дляEV_KEY: 0 — отпущена, 1 — нажата, 2 — повторное нажатие; дляEV_REL: смещение; дляEV_ABS: абсолютная координата).
События группируются в пакеты. После передачи всех данных, относящихся к одному физическому действию (например, перемещение мыши), ядро отправляет событие синхронизации с типом EV_SYN и кодом SYN_REPORT. Это сигнализирует программе, что набор событий завершён и может быть обработан.
Идентификация устройств
Для определения, какое физическое устройство соответствует конкретному файлу /dev/input/eventN, используются несколько методов:
- Символические ссылки в
/dev/input/by-path/— ссылки на файлыeventN, созданные на основе физического пути подключения (например, шины USB, порта PS/2). Имя ссылки содержит идентификатор контроллера и порта. - Символические ссылки в
/dev/input/by-id/— ссылки, основанные на идентификаторе производителя и модели устройства. Позволяют найти устройство по его уникальному USB-идентификатору. - Информация из файловой системы
/sys/class/input/— в этой виртуальной файловой системе для каждого устройства ввода имеется подкаталог с именемeventN, содержащий файлыname(название устройства),phys(физический путь),uniq(уникальный идентификатор) и другие. - Утилита
evtest— программа для просмотра событий от устройств ввода. Позволяет вывести список доступных устройств с их названиями и протестировать чтение событий в реальном времени.
Применение
Файлы /dev/input/event используются в различных областях:
- Системы ввода в графических окружениях — X11 и Wayland считывают события из этих файлов для обработки ввода от клавиатур, мышей и тачпадов.
- Игровые приложения — джойстики, геймпады и рули передают свои состояния через события
EV_ABS,EV_KEYиEV_ABS(для аналоговых осей). Игры и игровые движки (например, SDL) читают эти файлы напрямую или через библиотеки. - Специализированное программное обеспечение — программы для автоматизации, макросов, удалённого управления, а также системы киосков и терминалов могут напрямую обрабатывать события ввода, минуя стандартные протоколы оконных систем.
- Эмуляция ввода — запись и воспроизведение событий (например, с помощью утилиты
evemuили путём записи в файл/dev/input/eventN). Это используется для тестирования, автоматизации и создания демонстраций. - Встраиваемые системы — на устройствах с ограниченными ресурсами (например, на базе OpenWrt или Buildroot) прямой доступ к событиям ввода позволяет реализовать интерфейс без использования графического сервера.
Права доступа и безопасность
По умолчанию файлы /dev/input/eventN принадлежат группе input и имеют права crw-rw---- (чтение и запись для владельца и группы, никаких прав для остальных). Для чтения событий пользователь должен быть членом группы input или иметь права суперпользователя. Запись в файлы устройств (для эмуляции ввода) обычно требует прав root.
С точки зрения безопасности, чтение событий ввода может представлять угрозу, так как позволяет перехватывать нажатия клавиш (включая пароли) и движения мыши. Поэтому в многопользовательских системах доступ к этим файлам ограничивается. В современных графических окружениях (например, в Wayland) прямой доступ к устройствам ввода для обычных приложений блокируется, и события передаются через защищённые протоколы.
Взаимодействие с другими подсистемами
Файлы /dev/input/event являются частью более широкой архитектуры ввода в Linux. Ядро предоставляет также:
/dev/input/mice— объединённый поток событий от всех мышей (устаревший интерфейс)./dev/input/js0,/dev/input/js1— интерфейс для джойстиков (устаревший, заменён наevent)./dev/input/eventN— основной современный интерфейс для всех устройств ввода.
Прикладные библиотеки, такие как libinput (используется в GNOME, KDE и Wayland), SDL и SFML, работают поверх файлов /dev/input/event, абстрагируя детали формата событий и предоставляя более высокоуровневый API.
Примеры использования
Чтение событий с помощью утилиты evtest
`` sudo evtest /dev/input/event0 ``
После запуска программа выводит информацию об устройстве и начинает отображать входящие события в реальном времени.
Чтение событий на языке C
Программа открывает файл устройства, читает структуры input_event в цикле и выводит их поля. Примерный код:
```c
include <stdio.h>
include <fcntl.h>
include <unistd.h>
include <linux/input.h>
int main() { int fd = open("/dev/input/event0", O_RDONLY); if (fd < 0) { perror("open"); return 1; } struct input_event ev; while (read(fd, &ev, sizeof(ev)) > 0) { printf("Type: %d, Code: %d, Value: %d\n", ev.type, ev.code, ev.value); } close(fd); return 0; } ```
Ограничения
- Файлы
/dev/input/eventне поддерживают произвольный доступ (seek) — данные можно только читать последовательно. - Буфер событий в ядре имеет ограниченный размер (обычно 64 КБ). Если программа не успевает читать события, буфер переполняется, и новые события теряются.
- Некоторые устройства ввода (например, сенсорные экраны с мультитач) могут генерировать сложные последовательности событий, требующие специальной обработки (например, отслеживание идентификаторов касаний через событие
EV_ABSс кодомABS_MT_SLOT).
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →