当前位置: 首页 > news >正文

Linux学习笔记--uinput

 uinput 是 Linux 内核的一个模块,允许用户空间程序创建虚拟输入设备。这些虚拟设备的行为与真实硬件设备完全相同。

1. 头文件引入

#include <linux/uinput.h>  // uinput 相关定义和 ioctl 命令

2. 事件发送函数

void emit(int fd, int type, int code, int val)
{struct input_event ie;ie.type = type;ie.code = code;ie.value = val;ie.time.tv_sec = 0;ie.time.tv_usec = 0;write(fd, &ie, sizeof(ie));
}
  • 封装了输入事件的构造和发送

  • input_event 结构与内核中的定义一致

  • 时间戳被忽略(设为0)

1. 打开 uinput 设备

int fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
  • 打开 uinput 字符设备

  • O_WRONLY: 只写模式(用于发送事件)

  • O_NONBLOCK: 非阻塞模式

2. 配置设备属性

ioctl(fd, UI_SET_PROPBIT, INPUT_PROP_DIRECT);

设置设备为直接输入设备(触摸屏类设备)。

3. 配置设备能力

按键事件支持:
ioctl(fd, UI_SET_EVBIT, EV_KEY);        // 启用按键事件类型
ioctl(fd, UI_SET_KEYBIT, BTN_TOUCH);    // 启用触摸按键
绝对坐标事件支持:
ioctl(fd, UI_SET_EVBIT, EV_ABS);        // 启用绝对坐标事件类型
ioctl(fd, UI_SET_ABSBIT, ABS_X);        // 启用 X 坐标轴
ioctl(fd, UI_SET_ABSBIT, ABS_Y);        // 启用 Y 坐标轴

4. 设备信息设置

memset(&usetup, 0, sizeof(usetup));
usetup.id.bustype = BUS_USB;
usetup.id.vendor = 0x1234;   /* 示例厂商 ID */
usetup.id.product = 0x5678;  /* 示例产品 ID */
strcpy(usetup.name, "Example device");

5. 创建设备

ioctl(fd, UI_DEV_SETUP, &usetup);  // 应用设备设置
ioctl(fd, UI_DEV_CREATE);          // 创建设备节点

执行 UI_DEV_CREATE 后,内核会在 /dev/input/ 目录下创建新的输入设备节点。

事件模拟流程

1. 等待校准程序

printf("Will sleep 60s, in this time you should run ts_calibreate\n");
sleep(60);

给用户时间运行触摸屏校准程序。

2. 五点校准模拟

程序模拟了标准的五点触摸校准:

左上角点:
emit(fd, EV_KEY, BTN_TOUCH, 1);   // 触摸开始
emit(fd, EV_ABS, ABS_X, 100);     // X 坐标
emit(fd, EV_ABS, ABS_Y, 100);     // Y 坐标
emit(fd, EV_SYN, SYN_REPORT, 0);  // 同步事件
emit(fd, EV_KEY, BTN_TOUCH, 0);   // 触摸结束
emit(fd, EV_SYN, SYN_REPORT, 0);  // 同步事件
sleep(5);
事件序列说明:
  1. BTN_TOUCH=1: 触摸按下

  2. ABS_XABS_Y: 坐标位置

  3. SYN_REPORT: 同步,表示一组事件完成

  4. BTN_TOUCH=0: 触摸释放

  5. 再次 SYN_REPORT: 同步

五个校准点:
  • 左上角: (100, 100)

  • 右上角: (1000, 100)

  • 右下角: (1000, 1000)

  • 左下角: (100, 1000)

  • 中心点: (550, 550)

3. 对角线绘制测试

emit(fd, EV_KEY, BTN_TOUCH, 1);   // 触摸开始
emit(fd, EV_ABS, ABS_X, 200);
emit(fd, EV_ABS, ABS_Y, 200);
emit(fd, EV_SYN, SYN_REPORT, 0);
sleep(5);i = 200;
while (i < 1000)
{emit(fd, EV_ABS, ABS_X, i);emit(fd, EV_ABS, ABS_Y, i);emit(fd, EV_SYN, SYN_REPORT, 0);i += 10;sleep(5);
}emit(fd, EV_KEY, BTN_TOUCH, 0);   // 触摸结束
emit(fd, EV_SYN, SYN_REPORT, 0);

模拟从 (200,200) 到 (1000,1000) 的对角线绘制。

4. 清理资源

ioctl(fd, UI_DEV_DESTROY);  // 销毁虚拟设备
close(fd);                  // 关闭文件描述符

技术细节

uinput ioctl 命令详解:


命令	           作用	          参数
UI_SET_EVBIT	启用事件类型	 EV_KEY, EV_ABS 等
UI_SET_KEYBIT	启用具体按键	 BTN_TOUCH, KEY_A 等
UI_SET_ABSBIT	启用坐标轴	 ABS_X, ABS_Y 等
UI_SET_PROPBIT	设置设备属性	 INPUT_PROP_DIRECT 等
UI_DEV_SETUP	配置设备信息	 uinput_setup 结构体
UI_DEV_CREATE	创建设备	    无
UI_DEV_DESTROY	销毁设备	    无

输入事件流协议:

正确的输入事件序列:

EV_KEY, BTN_TOUCH, 1    // 触摸开始
EV_ABS, ABS_X, x_value  // X 坐标
EV_ABS, ABS_Y, y_value  // Y 坐标
EV_SYN, SYN_REPORT, 0   // 同步(上报事件)
...                     // 可能的多点触控数据
EV_KEY, BTN_TOUCH, 0    // 触摸结束
EV_SYN, SYN_REPORT, 0   // 同步

运行要求

1. 内核支持

# 检查 uinput 模块
lsmod | grep uinput# 加载模块
sudo modprobe uinput

2. 设备权限

# 检查设备权限
ls -l /dev/uinput# 可能需要 root 权限或设置 udev 规则
sudo chmod 666 /dev/uinput

3. 编译运行

gcc -o virtual_touch virtual_touch.c
sudo ./virtual_touch

http://www.dtcms.com/a/470910.html

相关文章:

  • 重庆网站建设哪里比较好呢自建网站和第三方平台
  • Linux1011 shell:sed2
  • 网站正在升级建设中源码美食网站联系我们怎么做
  • 武汉公交站点数据,shp+xlsx格式
  • 后端(JavaWeb)学习笔记(CLASS 2):SpringBootWeb入门
  • 湖北立方建设工程有限公司网站页面优化诊断
  • mysql表的操作——mysql表的约束
  • 城关区建设局网站吉林从业自助app下载
  • 网站域名类型wordpress获取权限
  • VxLAN解析
  • 口碑好网站建设公司哪家好网站是做排行榜
  • 张掖网站建设网页设计心得体会400字
  • 【优选算法必刷100题】第011~012题(滑动窗口):最大连续1的个数 III,将 x 减到 0 的最小操作数
  • seochinaz查询seo排名优化公司哪家好
  • 一场跨越技术栈的诡异异常侦破记
  • 基于之前说麦克斯韦方程的挠场和涡旋场和特斯拉的非赫兹波
  • 铁路项目建设 网站wordpress站点
  • i.mx8上Qt应用星期显示异常
  • 08_Matplotlib数据可视化
  • 怎么上传自己做的网站wordpress注册跳转
  • 荆州做网站建设学校网站多钱
  • RDKit | 深入探讨用于捕获立体化学特征的分子指纹
  • Windows Server 2019域域控制器如何设置编辑WMI筛选器
  • Hive SQL:where 与 having(城市分组,年龄筛选)
  • C# 枚举(Enum)
  • 松江网站建设哪家好手机网站开发计划
  • 模板网站如何做seo网站维护html模板
  • PostgreSql 判断字符串是否为null 或 空字符串
  • 我做外贸要开国际网站吗个人网站cms
  • VR全景园区完整实现方案