一,uinput介绍
uinput机制有2个很大的优点:
1) 不用自己写驱动(比如弄个红外遥控器、车载线控,不需要读芯片手册),直接在用户空间实现。
2) 创建/dev/input/eventX节点,根据不同设备特定事件数据格式,在用户态下向/dev/input/eventX写入事件数据,即可模拟键盘、鼠标等的事件输入。uinput操作步骤流程:
1) 打开uinput device
2) 设置uinput device
3) 写入设备信息,如busid, 名字等
4) 创建Input device
5) 向input device发送Event坐标数据。
二,多点触摸协议
虚拟输入设备,通过uinput可以构建对应的设备节点出来,最终都是需要通过写入对应的触控数据,触控数据一般分成type-A和type-B,模拟写入触控数据的时候,选择其中一种就可以了。
1,多点触摸协议Type-A
对于type A设备,内核驱动应该根据设备表面上全部有效触控进行列举并生成事件。每个触控点数据包在这次事件流中的顺序并不重要。事件过滤和手指跟踪的工作留给用户空间来实现。多点触摸时, 多点坐标之间需要进行区分,设备类型A比较大特征就是通过ABS_MT_SYNC进行隔离,所以在上报事件的时候无需id和slot。需要上报的事件中需要包含:
BTN_TOUCH
MT_TOOL_FINGER
ABS_MT_POSITION_X
ABS_MT_POSITION_Y
ABS_MT_PRESSURE
ABS_MT_TOUCH_MAJOR
SYN_MT_REPORT
SYN_REPORT
Type-A三个点按下并移动例子:
EV_KEY, BTN_TOUCH, 1 //应用理解为按下
EV_ABS, MT_TOOL_FINGER, 1
EV_ABS, ABS_MT_POSITION_X, x1
EV_ABS, ABS_MT_POSITION_Y, y1
EV_ABS, ABS_MT_PRESSURE, 50
EV_ABS, ABS_MT_TOUCH_MAJOR, 5
EV_SYN, SYN_MT_REPORT, 0
EV_KEY, BTN_TOUCH, 1
EV_ABS, MT_TOOL_FINGER, 1
EV_ABS, ABS_MT_POSITION_X, x2
EV_ABS, ABS_MT_POSITION_Y, y2
EV_ABS, ABS_MT_PRESSURE, 50
EV_ABS, ABS_MT_TOUCH_MAJOR, 5
EV_SYN, SYN_MT_REPORT, 0
EV_KEY, BTN_TOUCH, 1
EV_ABS, MT_TOOL_FINGER, 1
EV_ABS, ABS_MT_POSITION_X, x3
EV_ABS, ABS_MT_POSITION_Y, y3
EV_ABS, ABS_MT_PRESSURE, 50
EV_ABS, ABS_MT_TOUCH_MAJOR, 5
EV_SYN, SYN_MT_REPORT, 0
EV_SYN, SYN_REPORT, 0 //表示本次上报三个点结束
//###############################################################接下来移动
EV_KEY, BTN_TOUCH, 1 //应用理解为按下
EV_ABS, MT_TOOL_FINGER, 1
EV_ABS, ABS_MT_POSITION_X, x1+10
EV_ABS, ABS_MT_POSITION_Y, y1+10
EV_ABS, ABS_MT_PRESSURE, 50
EV_ABS, ABS_MT_TOUCH_MAJOR, 5
EV_SYN, SYN_MT_REPORT, 0
EV_KEY, BTN_TOUCH, 1
EV_ABS, MT_TOOL_FINGER, 1
EV_ABS, ABS_MT_POSITION_X, x2+10
EV_ABS, ABS_MT_POSITION_Y, y2+10
EV_ABS, ABS_MT_PRESSURE, 50
EV_ABS, ABS_MT_TOUCH_MAJOR, 5
EV_SYN, SYN_MT_REPORT, 0
EV_KEY, BTN_TOUCH, 1
EV_ABS, MT_TOOL_FINGER, 1
EV_ABS, ABS_MT_POSITION_X, x3+10
EV_ABS, ABS_MT_POSITION_Y, y3+10
EV_ABS, ABS_MT_PRESSURE, 50
EV_ABS, ABS_MT_TOUCH_MAJOR, 5
EV_SYN, SYN_MT_REPORT, 0
EV_SYN, SYN_REPORT, 0 //表示本次上报三个点结束
//########可以移动多次, 最后抬起来
EV_KEY, BTN_TOUCH, 0
EV_ABS, MT_TOOL_FINGER, 0
EV_SYN, SYN_REPORT, 0
2,多点触摸协议Type-B
对于type B设备,内核驱动应该把每一个识别出的触控点和一个slot相关联,并使用该slot来传播触摸状态的改变。通过修改关联slot的 ABS_MT_TRACKING_ID来达到对触摸点的创建,替换和销毁。一个非负数的跟踪id被解释为有效的触摸,-1则代表一个不再使用的slot。 一个之前没有出现过的跟踪id被认为是一个新的接触点,当一个跟踪id不再出现时则认为该接触点已经被移除。每当接收到一个MT事件,只需对当前slot的相关属性进行一次简单的更新即可。
Type-B需要上报的事件中需要包含
BTN_TOUCH
MT_TOOL_FINGER
ABS_MT_SLOT
ABS_MT_TRACKING_ID
ABS_MT_POSITION_X
ABS_MT_POSITION_Y
ABS_MT_PRESSURE
ABS_MT_TOUCH_MAJOR
//无SYN_MT_REPORT
SYN_REPORT
Type-A三个点按下并移动例子:
EV_ABS, ABS_MT_SLOT, 0 // slot=0 第0个点
EV_ABS, ABS_MT_TRACKING_ID, 20 //可以是一个累计数字
EV_KEY, BTN_TOUCH, 1 //应用层理解为按下
EV_ABS, MT_TOOL_FINGER, 1
EV_ABS, ABS_MT_POSITION_X, x1
EV_ABS, ABS_MT_POSITION_Y, y1
EV_ABS, ABS_MT_PRESSURE, 50
EV_ABS, ABS_MT_TOUCH_MAJOR, 5
EV_ABS, ABS_MT_SLOT, 1 // slot=1 第1个点
EV_ABS, ABS_MT_TRACKING_ID, 20 //可以是一个累计数字
EV_KEY, BTN_TOUCH, 1
EV_ABS, MT_TOOL_FINGER, 1
EV_ABS, ABS_MT_POSITION_X, x2
EV_ABS, ABS_MT_POSITION_Y, y2
EV_ABS, ABS_MT_PRESSURE, 50
EV_ABS, ABS_MT_TOUCH_MAJOR, 5
EV_ABS, ABS_MT_SLOT, 2 // slot=2 第2个点
EV_ABS, ABS_MT_TRACKING_ID, 21 //可以是一个累计数字
EV_KEY, BTN_TOUCH, 1
EV_ABS, MT_TOOL_FINGER, 1
EV_ABS, ABS_MT_POSITION_X, x3
EV_ABS, ABS_MT_POSITION_Y, y3
EV_ABS, ABS_MT_PRESSURE, 50
EV_ABS, ABS_MT_TOUCH_MAJOR, 5
EV_SYN, SYN_REPORT, 0 //表示本次上报三个点结束
//###############################################################接下来移动
EV_ABS, ABS_MT_SLOT, 0 // slot=0 第0个点
EV_ABS, ABS_MT_TRACKING_ID, 20 //可以是一个累计数字
EV_KEY, BTN_TOUCH, 1 //应用层理解为按下
EV_ABS, MT_TOOL_FINGER, 1
EV_ABS, ABS_MT_POSITION_X, x1+20
EV_ABS, ABS_MT_POSITION_Y, y1+20
EV_ABS, ABS_MT_PRESSURE, 50
EV_ABS, ABS_MT_TOUCH_MAJOR, 5
EV_ABS, ABS_MT_SLOT, 1 // slot=1 第1个点
EV_ABS, ABS_MT_TRACKING_ID, 20 //可以是一个累计数字
EV_KEY, BTN_TOUCH, 1
EV_ABS, MT_TOOL_FINGER, 1
EV_ABS, ABS_MT_POSITION_X, x2+20
EV_ABS, ABS_MT_POSITION_Y, y2+20
EV_ABS, ABS_MT_PRESSURE, 50
EV_ABS, ABS_MT_TOUCH_MAJOR, 5
EV_ABS, ABS_MT_SLOT, 2 // slot=2 第2个点
EV_ABS, ABS_MT_TRACKING_ID, 21 //可以是一个累计数字
EV_KEY, BTN_TOUCH, 1
EV_ABS, MT_TOOL_FINGER, 1
EV_ABS, ABS_MT_POSITION_X, x3+20
EV_ABS, ABS_MT_POSITION_Y, y3+20
EV_ABS, ABS_MT_PRESSURE, 50
EV_ABS, ABS_MT_TOUCH_MAJOR, 5
EV_SYN, SYN_REPORT, 0 //表示本次上报三个点结束
//########可以移动多次, 最后抬起来
EV_ABS, ABS_MT_SLOT, 0 //需要被抬起的第0点
EV_ABS, ABS_MT_TRACKING_ID, -1 //必须设置为-1
EV_ABS, ABS_MT_SLOT, 1 //需要被抬起的第1点
EV_ABS, ABS_MT_TRACKING_ID, -1 //必须设置为-1
EV_ABS, ABS_MT_SLOT, 2 //需要被抬起的第2点
EV_ABS, ABS_MT_TRACKING_ID, -1 //必须设置为-1
EV_SYN, SYN_REPORT, 0
多点触摸调试getevent工具
getevent命令:
generic_arm64:/data # getevent -v32 /dev/input/event0
events:
KEY (0001): 0066 006b 0072 0073 0074 008e 009e 00d4
00d9 00e5 00e6 00e7 0244 0245 0246 0247
0248
ABS (0003): 0000 : value 0, min 0, max 32767, fuzz 0, flat 0, resolution 0
0001 : value 0, min 0, max 32767, fuzz 0, flat 0, resolution 0
0002 : value 0, min 0, max 1, fuzz 0, flat 0, resolution 0
002f : value 0, min 0, max 9, fuzz 0, flat 0, resolution 0
0030 : value 0, min 0, max 2147483647, fuzz 0, flat 0, resolution 0
0035 : value 0, min 0, max 32767, fuzz 0, flat 0, resolution 0
0036 : value 0, min 0, max 32767, fuzz 0, flat 0, resolution 0
0039 : value 0, min 0, max 10, fuzz 0, flat 0, resolution 0
003a : value 0, min 0, max 256, fuzz 0, flat 0, resolution 0
SW (0005): 0002 0004
getevent -l /dev/input/event0: 以文本形式输出事件类型和名称,比 -t 更清楚直观
getevent -l /dev/input/event0
EV_ABS ABS_MT_SLOT 00000000
EV_ABS ABS_MT_TRACKING_ID 000029c9
EV_KEY BTN_TOUCH DOWN
EV_KEY BTN_TOOL_FINGER DOWN
EV_ABS ABS_MT_POSITION_X 00000140
EV_ABS ABS_MT_POSITION_Y 00000329
EV_ABS ABS_MT_TOUCH_MAJOR 00000003
EV_ABS ABS_MT_TOUCH_MINOR 00000002
EV_SYN SYN_REPORT 00000000
EV_ABS ABS_MT_SLOT 00000001
EV_ABS ABS_MT_TRACKING_ID 000029ca
EV_ABS ABS_MT_POSITION_X 00000252
EV_ABS ABS_MT_POSITION_Y 0000025f
EV_ABS ABS_MT_TOUCH_MINOR 00000003
EV_SYN SYN_REPORT 00000000
getevent -tlr /dev/input/event0: 参数可以组合使用,一次性查看需要的触摸屏信息
generic_arm64:/data # getevent -tlr /dev/input/event0
[ 629.854478] EV_ABS ABS_MT_TRACKING_ID 00000000
[ 629.854478] EV_ABS ABS_MT_TOUCH_MAJOR 0000000c
[ 629.854478] EV_ABS ABS_MT_PRESSURE 00000081
[ 629.854478] EV_ABS ABS_MT_POSITION_X 000030b5
[ 629.854478] EV_ABS ABS_MT_POSITION_Y 0000647f
[ 629.854478] EV_SYN SYN_REPORT 00000000
[ 629.902909] EV_ABS ABS_MT_POSITION_Y 000063cc
[ 629.902909] EV_SYN SYN_REPORT 00000000 rate 20
[ 629.910887] EV_ABS ABS_MT_POSITION_X 000030e3
[ 629.910887] EV_ABS ABS_MT_POSITION_Y 000062cc
[ 629.910887] EV_SYN SYN_REPORT 00000000 rate 125
[ 629.918829] EV_ABS ABS_MT_POSITION_X 0000316b
[ 629.918829] EV_ABS ABS_MT_POSITION_Y 00006218
[ 629.918829] EV_SYN SYN_REPORT 00000000 rate 125
[ 629.929179] EV_ABS ABS_MT_POSITION_X 00003221
[ 629.929179] EV_ABS ABS_MT_POSITION_Y 000060cc
[ 629.929179] EV_SYN SYN_REPORT 00000000 rate 96
[ 629.934846] EV_ABS ABS_MT_POSITION_X 000032d7
[ 629.934846] EV_ABS ABS_MT_POSITION_Y 00005f98
[ 629.934846] EV_SYN SYN_REPORT 00000000 rate 176
[ 629.941290] EV_ABS ABS_MT_POSITION_X 00003360
[ 629.941290] EV_ABS ABS_MT_POSITION_Y 00005e32
[ 629.941290] EV_SYN SYN_REPORT 00000000 rate 155
[ 629.948866] EV_ABS ABS_MT_POSITION_X 000033bb
[ 629.948866] EV_ABS ABS_MT_POSITION_Y 00005d18
[ 629.948866] EV_SYN SYN_REPORT 00000000 rate 131