我正在尝试编写自己的“键盘驱动程序”(实际上没有编写内核模块),
通过在我认为是用户空间中最低抽象级别的地方捕获键盘:/dev/input/event*
。
如果您更改 ioctl(fd, EVIOCGRAB, UNGRAB)
的第一次出现,则以下代码执行抓取
到 ioctl(fd, EVIOCGRAB, GRAB)
。
// gcc main.c -o main
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <linux/input.h>
#include <fcntl.h>
#include <errno.h>
#define EXIT_KEY KEY_ESC
#define UNGRAB 0
#define GRAB 1
const char* kbd_device = "/dev/input/event4";
// ------------------------------------------------------------------------------------------------
int main(void){
int fd = open(kbd_device, O_RDONLY);
if(fd == -1){
printf("Cannot open %s. %s.\n", kbd_device, strerror(errno));
return -1;
}
if(ioctl(fd, EVIOCGRAB, UNGRAB))
printf("Couldn't grab %s. %s.\n", kbd_device, strerror(errno));
else
printf("Grabbed %s!\n", kbd_device);
while(1){
struct input_event event;
read(fd, &event, sizeof(event));
if (event.type == EV_KEY && event.value >= 0 && event.value <= 2){
printf("%d %3d\n", event.value, event.code);
if(event.code == EXIT_KEY){
ioctl(fd, EVIOCGRAB, UNGRAB);
close(fd);
return 0;
}
}
}
}
问题
- 如果我运行
gcc main.c -o main && sudo ./main
,一切都会按预期运行。 - 如果先编译然后然后我运行
sudo ./main
,但是,终端会不停地向下滚动,就像按住 RETURN 键一样。
为什么会发生?
注意事项
- 我正在运行 Ubuntu 14.04
- 在我的平台上,
/dev/input/event4
恰好是键盘
动机
我正在尝试编写一个键盘“驱动程序”,它既可以在 X 上运行,也可以在 X 上运行,但不能在 X 上运行(例如 TTY)。
我知道 X11 的键盘库/扩展是 XKB。我认为 TTY 的键盘库是 linux/divers/tty/vt/keyboard.c
( source ),
它使用的初始键盘映射位于 linux/drivers/tty/vt/defkeymap.map
( source ) 中,可以使用 loadkeys
对其进行修改(来源 here )。如果我错了,请纠正我。
最佳答案
当你输入时
gcc main.c -o main && sudo ./main ↵
GCC 需要一些时间,所以 ↵ key 在 ./main
运行时已经释放。
当你输入时
sudo ./main ↵
当您按下 ↵ 时,终端会立即向 shell 发送一个换行符,并开始执行 ./main
。然后 ↵ released 事件会被你的程序看到,但不会被你的终端看到,因为你的程序已经捕获了输入设备。因此,对于终端来说,它看起来像 ↵ 被卡住了,所以它继续产生换行符。
关于c - 为什么 `ioctl(fd, EVIOCGRAB, 1)` 有时会导致 key 垃圾邮件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41995349/