Для демона (т.е. фон) процесс действительно ли возможно искать нажатия клавиш с клавиатуры USB?

Freebsd:

/usr/sbin/daemon -f <command> <command args>
13
09.10.2013, 23:52
2 ответа

Устройства, скорее всего, вкладывают файл /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:

Хорошо. Я подробно останавливаюсь на этом основанном на предположении ответе /dev/input/eventN используется.

Один путь мог быть:

  1. В цикле запуска все event файлы, найденные в /dev/input/. Использовать ioctl() запрашивать биты события:

    ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), &evbit);
    

    затем проверьте если EV_KEY- бит установлен.

  2. Набор ЭКВИВАЛЕНТНОСТИ затем проверяет на ключи:

    ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), &keybit);
    

    Например, если цифровые клавиши интересны, то проверьте если биты на KEY_0 - KEY9 и KEY_KP0 кому: KEY_KP9.

  3. Ключи ЭКВИВАЛЕНТНОСТИ, найденные затем, начинают контролировать файл события в потоке.

  4. Назад к 1.

Таким образом, необходимо добраться для контроля всех устройств, которые соответствуют требуемым критериям. Можно не только проверить на EV_KEY как, например, кнопка питания будет иметь этот набор битов, но это, очевидно, не будет иметь KEY_A и т.д. набор.

Видели ложные положительные стороны для экзотических ключей, но для нормальных ключей это должно быть достаточным. Нет никакого прямого вреда в контроле, например, файле события для кнопки питания или разъема, но Вы они не испустят рассматриваемые события (иначе. плохой код).

Больше подробно ниже.


РЕДАКТИРОВАНИЕ 1:

В отношении "Объясняют что последний оператор …". Осмотр в stackoverflow приземляется здесь …, но:

Быстрый и грязный образец в 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. Например, если Вы хотите проверить, какие свойства LED доступны, скажите:

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 затем Caps Lock, освещен и т.д.

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

Некоторые связанные документы:

  1. Documentation/input/input.txt, особенно отметьте раздел 5.
  2. Documentation/input/event-codes.txt, описание различных событий и т.д. Обращает внимание к тому, что упоминается под, например. EV_SYN о нас SYN_DROPPED
  3. Documentation/input ... читайте на остальных, если Вы хотите.
24
27.01.2020, 19:52

Можно сделать это легко путем ссылки /dev/input/by-id/usb-manufacturername_*serialnumber*. Они появляются как символьные ссылки, которые можно разыменовать использование readlink -e определить связанное блочное устройство. Эти ссылки однако создаются udev который не мог бы присутствовать в Вашей встроенной среде.

Или.. Посмотрите на dmesg после подключения USB-устройства. Это должно дать Вам /dev узел.

2
27.01.2020, 19:52
  • 1
    Записи в /dev/disk/by-id/ по моему скромному мнению, создаются udev - вопрос состоит в том, доступно ли это в этом partcular случае (встроенная платформа). –  peterph 10.10.2013, 00:26
  • 2
    @peterph: Вы корректны. Если не использование udev первое предложение не будет работать. –  Jeight 10.10.2013, 00:30
  • 3
    @Gilles: Я вижу, что Вы отредактировали ответ, и измените путь к входному, а не диску. В этом случае я полагаю, что это был бы input/by-path и не disk/by-id. Я подозреваю, что любой работал бы. –  Jeight 10.10.2013, 01:40
  • 4
    Нет, 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. –  Gilles 'SO- stop being evil' 10.10.2013, 01:44
  • 5
    @Jeight справки: После того как я нахожу узел правильного устройства, Вы знаете, как я могу нажатия ключа доступа? –  KyleL 10.10.2013, 02:37

Теги

Похожие вопросы