Открыть сервисСервис

EV_KEY

EV_KEY — это тип события (event type) в подсистеме ввода ядра Linux, используемый для передачи информации о нажатиях и отпусканиях клавиш, кнопок и других дискретных переключателей. Относится к семейству событий, генерируемых драйверами устройств ввода (например, клавиатур, мышей, джойстиков, сенсорных панелей) и обрабатываемых через интерфейс /dev/input/event*. Код события EV_KEY является одним из базовых в системе ввода Linux наряду с EV_REL (относительные движения), EV_ABS (абсолютные координаты) и EV_SYN (синхронизация).

История и контекст

Подсистема ввода в Linux была разработана в конце 1990-х — начале 2000-х годов для унификации работы с разнообразными устройствами ввода. До её появления каждый драйвер имел собственный интерфейс, что усложняло разработку приложений. В 2001 году была представлена архитектура Input Core, которая ввела единый протокол событий. Тип EV_KEY был определён как часть этого протокола для обработки дискретных сигналов — нажатий, которые могут быть только в двух состояниях (нажато/отпущено) или, в некоторых случаях, с автоповтором.

Стандартизация кодов клавиш (key codes) в Linux была закреплена в заголовочном файле <linux/input-event-codes.h>, который содержит константы для всех поддерживаемых клавиш, кнопок и переключателей. Этот файл обновляется по мере добавления новых устройств.

Технические характеристики

Структура события

Каждое событие ввода в Linux представляет собой структуру struct input_event, определённую в <linux/input.h>:

``c struct input_event { struct timeval time; // Время события __u16 type; // Тип события (например, EV_KEY) __u16 code; // Код клавиши (например, KEY_A) __s32 value; // Значение (0 — отпущено, 1 — нажато, 2 — автоповтор) }; ``

Для EV_KEY поле type всегда равно константе EV_KEY (значение 0x01). Поле code содержит идентификатор конкретной клавиши, а value — её состояние.

Значения поля value

  • 0 — клавиша отпущена.
  • 1 — клавиша нажата.
  • 2 — автоповтор (генерируется, если клавиша удерживается дольше заданного времени и система поддерживает автоповтор).

Автоповтор (repeat) — это функция, при которой драйвер или ядро генерирует дополнительные события EV_KEY со значением 2, имитируя повторное нажатие. Это поведение настраивается через параметры ввода, например, через setleds или inputrepeat.

Коды клавиш (key codes)

Коды клавиш в Linux охватывают широкий спектр устройств: от стандартных клавиш клавиатуры (KEY_A, KEY_ENTER) до кнопок мыши (BTN_LEFT, BTN_RIGHT), кнопок джойстиков (BTN_JOYSTICK), мультимедийных клавиш (KEY_VOLUMEUP) и даже кнопок на пультах дистанционного управления (KEY_POWER). Всего определено более 600 кодов, включая зарезервированные для будущих устройств.

Примеры распространённых кодов:

  • KEY_A (0x1E) — клавиша A.
  • KEY_ENTER (0x1C) — клавиша Enter.
  • BTN_LEFT (0x110) — левая кнопка мыши.
  • KEY_SPACE (0x39) — пробел.
  • KEY_ESC (0x01) — Escape.

Применение

EV_KEY используется в драйверах всех устройств ввода, которые генерируют дискретные сигналы. Основные области применения:

  • Клавиатуры — передача нажатий и отпусканий клавиш. Каждое нажатие генерирует два события: нажатие (value=1) и отпускание (value=0). При удержании — автоповторы.
  • Мыши — кнопки мыши (левая, правая, средняя, боковые) передаются как EV_KEY с кодами BTN_LEFT, BTN_RIGHT, BTN_MIDDLE и т.д.
  • Джойстики и геймпады — кнопки на геймпадах (например, кнопки A, B, X, Y на контроллере Xbox) передаются через EV_KEY. Аналоговые стики обычно используют EV_ABS.
  • Сенсорные панели — нажатие на тачпад (tap) может генерировать EV_KEY с кодом BTN_TOUCH.
  • Мультимедийные пульты — кнопки громкости, воспроизведения, переключения треков.
  • Специализированные устройства — например, кнопки на руле, педали, кнопки на джойстиках для авиасимуляторов.

Взаимодействие с пользовательским пространством

Приложения могут читать события EV_KEY из файлов устройств /dev/input/event* (например, /dev/input/event0). Для этого используется системный вызов read(), который возвращает структуру input_event. Программы, такие как evtest (утилита для отладки ввода), позволяют в реальном времени просматривать события EV_KEY.

Также существует библиотека libinput, которая абстрагирует работу с устройствами ввода и предоставляет высокоуровневый API для обработки нажатий. Она широко используется в графических окружениях (GNOME, KDE) и оконных менеджерах (Wayland, X11).

Примеры использования

Пример 1: Чтение событий клавиатуры через evtest

``bash sudo evtest /dev/input/event0 ``

После запуска при нажатии клавиши A будет выведено:

`` Event: time 1234567890.123456, type 1 (EV_KEY), code 30 (KEY_A), value 1 Event: time 1234567890.123456, type 0 (EV_SYN), code 0 (SYN_REPORT), value 0 Event: time 1234567890.234567, type 1 (EV_KEY), code 30 (KEY_A), value 0 Event: time 1234567890.234567, type 0 (EV_SYN), code 0 (SYN_REPORT), value 0 ``

Первое событие — нажатие (value=1), второе — синхронизация (EV_SYN), третье — отпускание (value=0).

Пример 2: Программная обработка на C

```c

include <linux/input.h>

include <fcntl.h>

include <stdio.h>

include <unistd.h>

int main() { int fd = open("/dev/input/event0", O_RDONLY); struct input_event ev; while (read(fd, &ev, sizeof(ev)) > 0) { if (ev.type == EV_KEY) { printf("Key %d %s\n", ev.code, ev.value ? "pressed" : "released"); } } close(fd); return 0; } ```

Ограничения и особенности

  • EV_KEY не поддерживает аналоговые значения — только дискретные состояния (0, 1, 2). Для аналоговых сигналов (например, нажатие с разной силой) используется EV_ABS.
  • Автоповтор (value=2) может быть отключён на уровне ядра или приложения. В некоторых драйверах автоповтор не реализован.
  • Коды клавиш могут различаться в зависимости от раскладки клавиатуры (например, KEY_A соответствует физической клавише A, но при переключении раскладки на русскую та же клавиша может передавать другой символ). EV_KEY передаёт физический код, а не символ.
  • В многопользовательских системах доступ к устройствам ввода может быть ограничен правами (требуется группа input или root-права).

Связанные типы событий

  • EV_SYN (0x00) — синхронизация, используется для разделения групп событий.
  • EV_REL (0x02) — относительные движения (например, мышь).
  • EV_ABS (0x03) — абсолютные координаты (например, сенсорный экран).
  • EV_MSC (0x04) — прочие события (например, скан-коды клавиш).
  • EV_LED (0x11) — управление светодиодами (Caps Lock, Num Lock).

Источники

  • Linux kernel source tree, файл include/uapi/linux/input-event-codes.h
  • Документация Linux: Documentation/input/input.rst
  • Man-страница: input(4), evtest(1)
  • Книга: «Linux Device Drivers» (3rd edition), глава 16 — Input Drivers
  • Сайт: kernel.org — описание подсистемы ввода
Заметили ошибку или не согласны с информацией в статье? Напишите нам support@bfometr.ru