Linux MT 協(xié)議

本文內(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ù))。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容