C语言 除了 /dev/input/eventx 之外,是否有更高级别的(字符?)访问 Linux 键盘的方式?



我正在尝试编写一个需要从类似键盘的(HID(设备获取输入的Linux守护进程 - 它不是控制台键盘,而是第二个设备(如果它有任何区别,它实际上是一个一维条形码扫描仪(。守护程序将处理它接收的数据(来自字母数字条形码的"击键"(。

我知道守护程序可以使用 ioctl(EVIOCGRAB( 从/dev/input/eventx 获取该设备,然后读取 (( 事件(来自 的结构input_event(,这是有效的,但它对于我的需求来说太低了。我不需要知道每个向上和向下键事件,我宁愿不必解码/处理同时键,即我不想知道KEY_DOWN+KEY_RTSHIFT、KEY_DOWN+KEY_A、KEY_UP+KEY_RTSHIFT、KEY_UP+KEY_A,我只想收到"A"。

使用输入事件需要编写一大堆额外的代码,只是为了从中获取"A" - 这似乎是浪费时间和精力,因为几乎可以肯定存在现有的键盘处理程序(或类似的东西(会比我一起破解代码做得更好 - 我只是找不到它们!

有没有办法将现有的(键盘?(软件层放到/dev/input/eventx 上,然后守护程序可以从中专门读取简单的 ascii 流?

对于此设备,/proc/bus/input/devices 报告 ...

H: Handlers=sysrq kbd leds event9

。这可能表明某些东西已经在上面放了一个"kbd"层,但是如何访问它呢?

如果我不 EVIOCGRAB,那么当我扫描条形码时,我会看到有关"/dev/tty1 上登录失败"的系统日志,因此键盘输入显然正在尝试登录到某处的终端/外壳:-/(这台机器上也没有X,桌面等。

我不知道这样的库或守护进程。

但是,编写一个守护程序来做到这一点并不像您想象的那么难。 根据我的观点/经验,如果您不需要实现自动重复(即,仅在类似键盘的设备发送自动重复按键时才执行自动重复(,则守护程序非常简单。

特别是,主循环只是一个阻塞读取,然后是零个或多个阻塞写入,中间有一个数组查找。

您可以使用命名管道(在这种情况下,在打开设备之前打开管道,因为只有在另一个进程打开命名管道或 FIFO 进行读取后,打开才会成功(,也可以使用套接字;Unix 域套接字,或者 TCP 或 UDP 套接字(在环回接口上(。我可能会使用命名管道,/var/run/barcode-scanner.

我会使用一个单独的配置文件进行输入映射,并且我会支持预处理器宏名称(KEY_(从/usr/include/linux/input-event-codes.h,使用辅助程序awk脚本解析为数组。键映射文件可能存在于/etc/barcode-scanner/keymap中,并且包含类似于

KEY_1 = 1
KEY_NUMERIC_1 = 1
KEY_E = e
shift KEY_E = E
ctrl KEY_E = 5
altgr KEY_E = €
KEY_UP = 33[A

等等。定义文件中未列出的事件将被忽略或选择性地记录。

您可以使用数组,因为最多有 768 个(包括 0 到 KEY_MAX;尽管 0 是 KEY_RESERVED(不同的键盘事件;作为一个二维数组,您可能需要 16 个数组,以便在按下每个键时支持ShiftCtrl、Alt 和AltGr(或右alt键(的所有集成。 在内部,您只需要处理KEY_LEFTSHIFTKEY_RIGHTSHIFTKEY_CAPSLOCK(管理班次状态(;KEY_LEFTALT(管理 alt 状态(;KEY_RIGHTALT(管理 altgr 状态(;以及KEY_LEFTCTRLKEY_RIGHTCTRL(用于管理 Ctrl 状态(。如果使用位掩码来指示当前状态,则可以将其用作查找数组外部维度的索引。 这真的非常简单。

请注意,每个数组元素都是一个字符串,当按下该状态的键时会发出该字符串(ev.value == 1用于按键,ev.value == 2用于自动重复(。除了上述特殊键外,您根本不需要处理键释放。

嗯。我想知道是否有其他人需要这样的守护进程? 如果源代码在 GitHub,你会使用 GPL3 许可的吗?

libevdev 库并不是你所要求的。但它被广泛使用(例如,由Xorg服务器evdev和libinput驱动程序(。

作为主页上的状态:

libevdev 本质上是/dev/input/eventX 设备上类固醇的 read(2(。

它为您管理ioctl调用,处理事件队列等。

您没有要求的另一个功能,但它确实很有帮助:它可以一次处理来自多个设备的事件。它允许您侦听位于/dev/input 中的多个设备,并在单个线程中处理相同的事件类型。

最新更新