一,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