uinput
文章目录
- 🔧 使用场景举例
- 📂 uinput 的工作机制
- 📌 核心数据结构:`struct input_event`
- ✅ 示例流程代码
- 🔍 注意事项
- 📊 uinput 与 input 子系统的关系
- 🧠 总结一句话
uinput
(User Input Subsystem)是 Linux 内核提供的一个字符设备接口,它允许用户空间程序创建虚拟输入设备,并向内核上报各种输入事件(键盘、鼠标、触摸、游戏手柄等),从而模拟真实的输入设备行为。
换句话说,uinput
让用户空间也能**“伪装”出一个输入设备**,对系统来说,它和真正的物理键盘/鼠标没有区别。
🔧 使用场景举例
- 虚拟键盘/鼠标:例如模拟自动输入操作
- 触摸屏模拟:测试 UI 时模拟触控行为
- 游戏控制器仿真
- 输入录制与重放工具
- 远程桌面控制(输入事件重定向)
- 手势识别程序:识别后转为标准输入事件
📂 uinput 的工作机制
- 用户态打开
/dev/uinput
- 设置设备信息(如名称、支持的事件类型)
- 发送
UI_DEV_CREATE
ioctl 创建设备 - 通过
write()
写入 input_event 结构体,发送事件 - 发送
UI_DEV_DESTROY
ioctl 注销设备
📌 核心数据结构:struct input_event
struct input_event {struct timeval time;__u16 type; // 事件类型,比如 EV_KEY、EV_REL、EV_ABS 等__u16 code; // 键值,如 KEY_A、REL_X 等__s32 value; // 键值的状态:按下(1)、释放(0)、保持(2)
};
✅ 示例流程代码
下面是一个模拟按下和释放 “A” 键的 uinput 简例:
#include <linux/uinput.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/ioctl.h>int main() {int fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);// 设置支持的事件类型ioctl(fd, UI_SET_EVBIT, EV_KEY);ioctl(fd, UI_SET_KEYBIT, KEY_A); // 支持键盘A键struct uinput_user_dev uidev = {};snprintf(uidev.name, UINPUT_MAX_NAME_SIZE, "virtual-keyboard");uidev.id.bustype = BUS_USB;uidev.id.vendor = 0x1234;uidev.id.product = 0xfedc;uidev.id.version = 1;write(fd, &uidev, sizeof(uidev));ioctl(fd, UI_DEV_CREATE); // 创建虚拟设备sleep(1); // 等待设备被系统识别// 模拟按下A键struct input_event ev = {};ev.type = EV_KEY;ev.code = KEY_A;ev.value = 1; // 按下write(fd, &ev, sizeof(ev));// 同步事件ev.type = EV_SYN;ev.code = SYN_REPORT;ev.value = 0;write(fd, &ev, sizeof(ev));// 模拟释放A键ev.type = EV_KEY;ev.code = KEY_A;ev.value = 0; // 释放write(fd, &ev, sizeof(ev));// 再次同步ev.type = EV_SYN;ev.code = SYN_REPORT;ev.value = 0;write(fd, &ev, sizeof(ev));sleep(1);ioctl(fd, UI_DEV_DESTROY); // 销毁设备close(fd);return 0;
}
🔍 注意事项
- uinput模块必须加载:
modprobe uinput
- 确保
/dev/uinput
存在并有权限访问:
ls -l /dev/uinput
-
需要 root 权限 或使用
udev
设置非 root 访问权限 -
SYN_REPORT 必不可少:通知内核“这一批输入事件”已完成
📊 uinput 与 input 子系统的关系
模块 | 作用 |
---|---|
input_dev | 真实或虚拟输入设备结构体 |
evdev | 把 input_dev 转换成 /dev/input/eventX 供用户读取 |
uinput | 用户空间模拟 input_dev 的工具 |
用户态程序 | 写入 uinput ,驱动事件注入系统 |
🧠 总结一句话
uinput
是 Linux 提供的一种机制,让你在用户态就能模拟一个输入设备,并“骗过”操作系统和上层应用。
在自动化测试、输入仿真、手势识别、远程控制等场景中,uinput
是一个非常强大的工具。