Пристрої, швидше за все, отримують файл з /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 і перевіряйте пристрої + монітор.
EDIT 2:
ДОБРЕ. Я розширюю цю відповідь на основі використовуваного припущення /dev/input/eventN
.
Одним із способів може бути:
При запуску циклу всі event
файли, знайдені в /dev/input/
. Використовувати ioctl()
для запиту бітів події:
ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), &evbit);
потім перевірте, чи встановлено EV_KEY
-біт.
IFF встановити, то перевірити наявність ключів:
ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), &keybit);
Наприклад, якщо цифрові клавіші цікаві, перевірте, чи біти для KEY_0
- KEY9
і KEY_KP0
до KEY_KP9
.
Знайдені ключі IFF, тоді запускайте моніторинг файлу події в потоці.
Назад до 1.
Таким чином, ви повинні контролювати всі пристрої, які відповідають бажаним критеріям. Ви не можете перевірити лише те, що EV_KEY
, наприклад, кнопка живлення встановить цей біт, але це, очевидно, не буде встановлено KEY_A
тощо.
Побачили помилкові позитиви екзотичних ключів, але для звичайних ключів цього має бути достатньо. Немає прямої шкоди під час моніторингу, наприклад, файл події для кнопки живлення або гнізда, але ви не будете випромінювати події, про які йдеться (ака. Поганий код).
Більш докладно нижче.
EDIT 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;
}
EDIT 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 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/
них створюються шляхомudev
- питання полягає в тому, чи доступно це в цьому частковому випадку (вбудована платформа).