Устройства, скорее всего, получают файл с /dev/input/
именем, eventN
где N - это различные устройства, такие как мышь, клавиатура, разъем, кнопки питания и т. Д.
ls -l /dev/input/by-{path,id}/
должен дать вам подсказку.
Также посмотрите на:
cat /proc/bus/input/devices
Где Sysfs
значение путь под /sys
.
Вы можете проверить, например,
cat /dev/input/event2 # if 2 is kbd.
Для реализации используйте ioctl и проверьте устройства + монитор.
РЕДАКТИРОВАТЬ 2:
OK. Я расширяю этот ответ, основываясь на предположении, /dev/input/eventN
которое используется.
Одним из способов может быть:
При запуске цикла все event
файлы, найденные в /dev/input/
. Используйте ioctl()
для запроса битов события:
ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), &evbit);
затем проверьте, установлен ли EV_KEY
-bit.
IFF установлен, затем проверьте ключи:
ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), &keybit);
Например, если цифровые клавиши интересны, то проверьте, есть ли биты для KEY_0
- KEY9
и KEY_KP0
к KEY_KP9
.
Найдены ключи IFF, затем запускается файл событий мониторинга в потоке.
Вернуться к 1.
Таким образом, вы должны отслеживать все устройства, которые соответствуют требуемым критериям. Вы не можете только проверить, EV_KEY
например, для кнопки питания будет установлен этот бит, но, очевидно, он не будет установлен KEY_A
и т.д.
Видели ложные срабатывания для экзотических ключей, но для обычных ключей этого должно хватить. Нет прямого вреда в мониторинге, например, файла событий для кнопки питания или разъема, но вы не будете генерировать события, о которых идет речь (иначе плохой код).
Подробнее ниже.
РЕДАКТИРОВАТЬ 1:
В отношении «Объясните это последнее утверждение…» . Перебираемся в стекаповорот земли здесь ... но:
Быстрый и грязный пример на C. Вам нужно будет реализовать различный код, чтобы проверить, действительно ли вы получили правильное устройство, перевести тип события, код и значение. Как правило, нажатие клавиши, нажатие клавиши, повторение клавиши, код клавиши и т. Д.
Не было времени (и здесь слишком много), чтобы добавить остальное.
Проверьте linux/input.h
, как программы dumpkeys
, код ядра и т. Д. Для отображения кодов. Напримерdumpkeys -l
Так или иначе:
Запустите как например:
# ./testprog /dev/input/event2
Код:
#include <stdio.h>
#include <string.h> /* strerror() */
#include <errno.h> /* errno */
#include <fcntl.h> /* open() */
#include <unistd.h> /* close() */
#include <sys/ioctl.h> /* ioctl() */
#include <linux/input.h> /* EVIOCGVERSION ++ */
#define EV_BUF_SIZE 16
int main(int argc, char *argv[])
{
int fd, sz;
unsigned i;
/* A few examples of information to gather */
unsigned version;
unsigned short id[4]; /* or use struct input_id */
char name[256] = "N/A";
struct input_event ev[EV_BUF_SIZE]; /* Read up to N events ata time */
if (argc < 2) {
fprintf(stderr,
"Usage: %s /dev/input/eventN\n"
"Where X = input device number\n",
argv[0]
);
return EINVAL;
}
if ((fd = open(argv[1], O_RDONLY)) < 0) {
fprintf(stderr,
"ERR %d:\n"
"Unable to open `%s'\n"
"%s\n",
errno, argv[1], strerror(errno)
);
}
/* Error check here as well. */
ioctl(fd, EVIOCGVERSION, &version);
ioctl(fd, EVIOCGID, id);
ioctl(fd, EVIOCGNAME(sizeof(name)), name);
fprintf(stderr,
"Name : %s\n"
"Version : %d.%d.%d\n"
"ID : Bus=%04x Vendor=%04x Product=%04x Version=%04x\n"
"----------\n"
,
name,
version >> 16,
(version >> 8) & 0xff,
version & 0xff,
id[ID_BUS],
id[ID_VENDOR],
id[ID_PRODUCT],
id[ID_VERSION]
);
/* Loop. Read event file and parse result. */
for (;;) {
sz = read(fd, ev, sizeof(struct input_event) * EV_BUF_SIZE);
if (sz < (int) sizeof(struct input_event)) {
fprintf(stderr,
"ERR %d:\n"
"Reading of `%s' failed\n"
"%s\n",
errno, argv[1], strerror(errno)
);
goto fine;
}
/* Implement code to translate type, code and value */
for (i = 0; i < sz / sizeof(struct input_event); ++i) {
fprintf(stderr,
"%ld.%06ld: "
"type=%02x "
"code=%02x "
"value=%02x\n",
ev[i].time.tv_sec,
ev[i].time.tv_usec,
ev[i].type,
ev[i].code,
ev[i].value
);
}
}
fine:
close(fd);
return errno;
}
РЕДАКТИРОВАТЬ 2 (продолжение):
Обратите внимание, что если вы посмотрите, у /proc/bus/input/devices
вас есть буква в начале каждой строки. Здесь B
означает бит-карту. Вот например:
B: PROP=0
B: EV=120013
B: KEY=20000 200 20 0 0 0 0 500f 2100002 3803078 f900d401 feffffdf ffefffff ffffffff fffffffe
B: MSC=10
B: LED=7
Каждый из этих битов соответствует свойству устройства. Что с помощью битовой карты означает, что 1 указывает на наличие свойства, как определено в linux/input.h
. :
B: PROP=0 => 0000 0000
B: EV=120013 => 0001 0010 0000 0000 0001 0011 (Event types sup. in this device.)
| | | ||
| | | |+-- EV_SYN (0x00)
| | | +--- EV_KEY (0x01)
| | +------- EV_MSC (0x04)
| +----------------------- EV_LED (0x11)
+--------------------------- EV_REP (0x14)
B: KEY=20... => OK, I'm not writing out this one as it is a bit huge.
B: MSC=10 => 0001 0000
|
+------- MSC_SCAN
B: LED=7 => 0000 0111 , indicates what LED's are present
|||
||+-- LED_NUML
|+--- LED_CAPSL
+---- LED_SCROLL
Взгляните на /drivers/input/input.{h,c}
дерево исходных текстов ядра. Там много хорошего кода. (Например, свойства устройств создаются этой функцией .)
Каждая из этих карт свойств может быть достигнута ioctl
. Например, если вы хотите проверить, какие свойства светодиодов доступны, скажите:
ioctl(fd, EVIOCGBIT(EV_LED, sizeof(ledbit)), &ledbit);
Посмотрите на определение struct input_dev
в input.h
том, ledbit
как определяются.
Чтобы проверить состояние светодиодов, скажите:
ioctl(fd, EVIOCGLED(sizeof(ledbit)), &ledbit);
Если бит 1 in ledbit
равен 1, тогда num-lock светятся. Если бит 2 равен 1, загорается заглушка и т. Д.
input.h
имеет различные определения.
Примечания, когда дело доходит до мониторинга событий:
Псевдокод для мониторинга может быть чем-то в направлении:
WHILE TRUE
READ input_event
IF event->type == EV_SYN THEN
IF event->code == SYN_DROPPED THEN
Discard all events including next EV_SYN
ELSE
This marks EOF current event.
FI
ELSE IF event->type == EV_KEY THEN
SWITCH ev->value
CASE 0: Key Release (act accordingly)
CASE 1: Key Press (act accordingly)
CASE 2: Key Autorepeat (act accordingly)
END SWITCH
FI
END WHILE
Некоторые связанные документы:
Documentation/input/input.txt
особенно примечание раздел 5.
Documentation/input/event-codes.txt
, описание различных событий и т. д. Обратите внимание на то, что упоминается, например, EV_SYN
оSYN_DROPPED
Documentation/input
... прочитайте об остальном, если хотите.
/dev/disk/by-id/
imho созданыudev
- вопрос в том, доступно ли это в данном случае (встроенная платформа).by-id
это правильно. Например моя клавиатура USB доступна как/dev/input/by-id/usb-_USB_Keyboard-event-kbd
и/dev/input/by-path/pci-0000:00:1d.2-usb-0:2:1.0-event-kbd
.