本文內(nèi)提到的內(nèi)容來至于 Kernel Documentation。
協(xié)議被分為了兩種類型的設(shè)備:
- 所有設(shè)備都處理匿名接觸點(A類), 協(xié)議描述如何發(fā)送 raw 數(shù)據(jù)來自所有接觸點給接收者
- 處理帶Tracking ID 的接觸點(B類),協(xié)議描述如何通過事件slot發(fā)送更新每個獨立接觸點
協(xié)議使用
接觸點描述的每個包都通過 ABS_MT_* 事件來進行發(fā)送單條信息。
在Type A 設(shè)備驅(qū)動中每個獨立接觸點之后都會使用 input_mt_sync() 來發(fā)送 SYN_MT_REPORT 事件。
而在Type B 設(shè)備驅(qū)動中每個獨立接觸點之前都會使用 input_mt_slot() 函數(shù)來發(fā)送 ABS_MT_SLOT 事件,用來表示準備開始更新某給定的slot 事件。同時要求使用 ABS_MT_TRACKING_ID 來描述slot協(xié)議。
所有類型的驅(qū)動都會通過 input_sync() 函數(shù)來結(jié)束單次操作的 EV_SYN/SYN_REPORT事件來進行同步。表示當(dāng)前事件已經(jīng)結(jié)束,可以使用之前更新的數(shù)據(jù)。
無狀態(tài)的Type A 協(xié)議與含狀態(tài)的Type B slot協(xié)議主要區(qū)別在于使用接觸點Id 來減少大量數(shù)據(jù)發(fā)送給到用戶空間中。
對于A類設(shè)備來說,內(nèi)核驅(qū)動隨意迭代所有接觸點,數(shù)據(jù)包在事件流中的位置并不重要。事件過濾及事件tracking都被遺留給了用戶空間來處理。而 B 類設(shè)備,內(nèi)核用 slot 來關(guān)聯(lián)每個接觸點,通過 slot 來傳遞接觸點的變化。接觸點的創(chuàng)建,更新及銷毀都通過修改關(guān)聯(lián)的slot的 ABS_MT_TRACKING_ID 來完成(非負數(shù)表示詮釋一個接觸點,-1 表示為一個無用的接觸點)。當(dāng)出現(xiàn)一個之前沒有出現(xiàn)過tracking id 時,表示為一個新的點。某個tracking id 不再次出現(xiàn)時,表示已經(jīng)移除。
如果tracking的接觸點多余當(dāng)前上報的硬件信號時,驅(qū)動應(yīng)該使用 BTN_TOOL_TAP 事件來告知用戶空間當(dāng)前tracking的接觸點總數(shù)量。驅(qū)動應(yīng)該通過發(fā)送相應(yīng)的 BTN_TOOL_TAP 事件以及在調(diào)用 input_mt_report_pointer_emulation() 函數(shù)時設(shè)置 use_count 為 false 。
ABS_MT_SLOT 最小值為 0。
協(xié)議樣例
A 類協(xié)議
A 類設(shè)備獲取兩點的事件如下:
ABS_MT_POSITION_X x[0]
ABS_MT_POSITION_Y y[0]
SYN_MT_REPORT
ABS_MT_POSITION_X x[1]
ABS_MT_POSITION_Y y[1]
SYN_MT_REPORT
SYN_REPORT
當(dāng)其中某點發(fā)送移動,進行更新時,這時所有呈現(xiàn)的接觸點的 raw 數(shù)據(jù)通過發(fā)送 SYN_REPORT 來同步數(shù)據(jù)。
比如:
ABS_MT_POSITION_X x[1]
ABS_MT_POSITION_Y y[1]
SYN_MT_REPORT
SYN_REPORT
接下來通過如下方式來將更新及同步數(shù)據(jù)
SYN_MT_REPORT
SYN_REPORT
如果驅(qū)動除 ABS_MT 事件外額外上報一個 BTN_TOUCH 或 ABS_PRESSURE 事件。最后一個 SYN_MT_REPORT 事件可能會省略。
B 類協(xié)議
如下是兩個接觸點的 B 類事件:
ABS_MT_SLOT 0
ABS_MT_TRACKING_ID 45
ABS_MT_POSITION_X x[0]
ABS_MT_POSITION_Y y[0]
ABS_MT_SLOT 1
ABS_MT_TRACKING_ID 46
ABS_MT_POSITION_X x[1]
ABS_MT_POSITION_Y y[1]
SYN_REPORT
如下是在當(dāng)?shù)谝粋€ slot 在 x 軸上移動之后,上報的日志:
ABS_MT_SLOT 0
ABS_MT_POSITION_X x[0]
SYN_REPORT
如下是當(dāng)slot 關(guān)聯(lián)的 slot 抬起(release)之后,上報如下事件:
ABS_MT_TRACKING_ID -1
SYN_REPORT
如果第二點抬起之后,則上報如下事件:
ABS_MT_SLOT 1
ABS_MT_TRACKING_ID -1
SYN_REPORT
即當(dāng)變化的接觸點所關(guān)聯(lián)的 slot 與上次同步數(shù)據(jù)的 slot 不一致時,必須先發(fā)送 ABS_MT_SLOT 來標記當(dāng)前要修改的 slot 數(shù)據(jù)。(類似于 patch 將單個 slot 數(shù)據(jù)進行緩存,然后通過修改變更的數(shù)據(jù)來同步當(dāng)前接觸點的數(shù)據(jù))。