ydotool开发指南:理解uinput框架与虚拟设备创建原理

张开发
2026/5/8 10:30:11 15 分钟阅读

分享文章

ydotool开发指南:理解uinput框架与虚拟设备创建原理
ydotool开发指南理解uinput框架与虚拟设备创建原理【免费下载链接】ydotoolGeneric command-line automation tool项目地址: https://gitcode.com/gh_mirrors/yd/ydotool一、什么是uinput框架uinput是Linux内核提供的一个强大框架允许用户空间程序创建和模拟输入设备。通过uinput开发者可以编写程序来模拟键盘、鼠标、触摸屏幕等输入设备的行为这为自动化测试、远程控制和辅助技术等场景提供了可能。在ydotool项目中uinput框架被广泛应用于创建虚拟输入设备从而实现各种输入操作的模拟。二、虚拟设备创建的基本流程创建虚拟输入设备通常需要以下几个关键步骤2.1 打开uinput设备首先需要打开/dev/uinput设备文件这是与uinput框架交互的入口点。在ydotool的实现中可以在Daemon/ydotoold.c文件中找到相关代码int fd_ui open(/dev/uinput, O_WRONLY); if (fd_ui 0) { perror(failed to open uinput device); exit(1); }2.2 配置设备功能接下来需要配置虚拟设备支持的输入事件类型。这包括键盘按键(EV_KEY)、相对坐标(EV_REL)和绝对坐标(EV_ABS)等。在ydotool中这一过程由uinput_setup函数处理static void uinput_setup(int fd, enum ydotool_uinput_setup_options setup_opt) { if (setup_opt ENABLE_KEY) { if (ioctl(fd, UI_SET_EVBIT, EV_KEY)) { fprintf(stderr, UI_SET_EVBIT %s failed\n, EV_KEY); } // 设置支持的按键列表 // ... } if (setup_opt ENABLE_REL) { if (ioctl(fd, UI_SET_EVBIT, EV_REL)) { fprintf(stderr, UI_SET_EVBIT %s failed\n, EV_REL); } // 设置支持的相对坐标轴 // ... } if (setup_opt ENABLE_ABS) { if (ioctl(fd, UI_SET_EVBIT, EV_ABS)) { fprintf(stderr, UI_SET_EVBIT %s failed\n, EV_ABS); } // 设置支持的绝对坐标轴 // ... } // ... }2.3 设置设备信息然后需要设置虚拟设备的基本信息如名称、总线类型、厂商ID和产品ID等static const struct uinput_setup usetup { .name ydotoold virtual device, .id { .bustype BUS_VIRTUAL, .vendor 0x2333, .product 0x6666, .version 1 } }; if (ioctl(fd, UI_DEV_SETUP, usetup)) { perror(UI_DEV_SETUP ioctl failed); exit(2); }2.4 创建设备最后通过UI_DEV_CREATEioctl命令完成虚拟设备的创建if (ioctl(fd, UI_DEV_CREATE)) { perror(UI_DEV_CREATE ioctl failed); exit(2); }三、ydotool中的uinput应用ydotool项目充分利用uinput框架实现了多种输入模拟功能。以下是一些关键应用场景3.1 键盘事件模拟在Client/tool_type.c中通过uinput_emit函数模拟键盘按键事件uinput_emit(EV_KEY, KEY_LEFTSHIFT, 1, 1); // 按下Shift键 uinput_emit(EV_KEY, kc, 1, 1); // 按下字符键 uinput_emit(EV_KEY, kc, 0, 1); // 释放字符键 uinput_emit(EV_KEY, KEY_LEFTSHIFT, 0, 1); // 释放Shift键3.2 鼠标事件模拟在Client/tool_click.c中模拟鼠标点击事件uinput_emit(EV_KEY, keycode, 1, 1); // 按下鼠标键 uinput_emit(EV_KEY, keycode, 0, 1); // 释放鼠标键在Client/tool_mousemove.c中模拟鼠标移动uinput_emit(EV_REL, REL_X, pos[0], 0); // X轴相对移动 uinput_emit(EV_REL, REL_Y, pos[1], 1); // Y轴相对移动四、uinput事件发送机制在ydotool中uinput_emit函数是发送输入事件的核心函数定义在Client/ydotool.c中void uinput_emit(uint16_t type, uint16_t code, int32_t val, bool syn_report) { struct input_event ev { .type type, .code code, .value val, }; gettimeofday(ev.time, NULL); write(sock, ev, sizeof(ev)); if (syn_report) { struct input_event ev_syn { .type EV_SYN, .code SYN_REPORT, .value 0, }; gettimeofday(ev_syn.time, NULL); write(sock, ev_syn, sizeof(ev_syn)); } }这个函数负责构造输入事件结构并通过socket发送到ydotoold守护进程。每个事件都包含类型、代码和值三个要素最后通过发送EV_SYN类型的同步事件来通知内核处理已发送的事件。五、编译和使用ydotool要编译ydotool项目首先需要克隆仓库git clone https://gitcode.com/gh_mirrors/yd/ydotool cd ydotool然后使用CMake进行构建mkdir build cd build cmake .. make编译完成后可以使用以下命令启动ydotoold守护进程sudo ./ydotoold之后就可以使用ydotool客户端工具来模拟各种输入操作了。六、总结uinput框架为Linux系统提供了强大的虚拟输入设备支持而ydotool项目则充分利用这一框架实现了灵活的命令行输入自动化工具。通过理解uinput的工作原理和ydotool的实现方式开发者可以更好地掌握虚拟输入设备的创建和使用方法为自动化测试、远程控制等场景开发出更加强大的工具。无论是模拟键盘输入、鼠标操作还是触摸屏幕事件uinput都提供了统一的接口使得这些操作的实现变得简单而高效。ydotool作为一个优秀的开源项目为我们展示了如何充分利用uinput框架来构建实用的工具。【免费下载链接】ydotoolGeneric command-line automation tool项目地址: https://gitcode.com/gh_mirrors/yd/ydotool创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

更多文章