Linux Input Subsystem

Posted on Feb 6, 2026

最近在写一个能够显示键盘输入的应用,需要实时获取键盘输入;在 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;
}

如果需获取按键名称,可以按照定义创建映射表