Linux Input Subsystem
最近在写一个能够显示键盘输入的应用,需要实时获取键盘输入;在 SDL的 API 中有用于获取键盘输入的函数
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
{
if (event->type == SDL_EVENT_KEY_DOWN) {
SDL_Log("key: %s", SDL_GetKeyName(event->key.key));
}
}
通过 SDL_KeyboardEvent结构体能获取所有的按键输入,但当窗口焦点丢失时,无论是否置顶窗口,都无法
继续获取输入。
input 子系统
Input subsystem is a collection of drivers that is designed to support all input devices under Linux. Most of the drivers reside in drivers/input, although quite a few live in drivers/hid and drivers/platform.
The core of the input subsystem is the input module, which must be loaded before any other of the input modules - it serves as a way of communication between two groups of modules:
在/dev/input目录下有一系列输入接口文件,读取后可获得设备输入信息。但一个文件只能获取一个设备的输入,如果有外接键盘
需要读取多个文件。
事件结构体的定义为
struct input_event {
struct timeval time;
unsigned short type;
unsigned short code;
int value;
};
time为时间戳,type为事件类型,code表示输入的按键编码,在 include/uapi/linux/input-event-codes.h中定义,value是事件携带的值
因为我们只需要获取按键按下的事件 所以用if (in_event.type != EV_KEY || in_event.value != 1)过滤事件。
最终得到
#include <fcntl.h>
#include <linux/input.h>
#include <unistd.h>
int quit = 0;
int read_input(const char *name)
{
struct input_event in_event;
int fd = open(name, O_RDONLY);
if (fd == -1) {
printf("Failed to open %s\n", name);
return -1;
}
while (!quit && read(fd, &in_event, sizeof(in_event)) == sizeof(in_event)) {
if (in_event.type != EV_KEY || in_event.value != 1) continue;
SDL_Log("time: %ld key: %hu\n", in_event.time.tv_sec, in_event.code);
}
return 0;
}
如果需获取按键名称,可以按照定义创建映射表