天天看點

Linux MT 協定

本文内提到的内容來至于 Kernel Documentation

協定被分為了兩種類型的裝置:

  • 所有裝置都處理匿名接觸點(A類), 協定描述如何發送 raw 資料來自所有接觸點給接收者
  • 處理帶Tracking ID 的接觸點(B類),協定描述如何通過事件slot發送更新每個獨立接觸點

協定使用

接觸點描述的每個包都通過 ABS_MT_* 事件來進行發送單條資訊。

在Type A 裝置驅動中每個獨立接觸點之後都會使用 input_mt_sync() 來發送 SYN_MT_REPORT 事件。

而在Type B 裝置驅動中每個獨立接觸點之前都會使用 input_mt_slot() 函數來發送 ABS_MT_SLOT 事件,用來表示準備開始更新某給定的slot 事件。同時要求使用 ABS_MT_TRACKING_ID 來描述slot協定。

所有類型的驅動都會通過 input_sync() 函數來結束單次操作的 EV_SYN/SYN_REPORT事件來進行同步。表示目前事件已經結束,可以使用之前更新的資料。

無狀态的Type A 協定與含狀态的Type B slot協定主要差別在于使用接觸點Id 來減少大量資料發送給到使用者空間中。

對于A類裝置來說,核心驅動随意疊代所有接觸點,資料包在事件流中的位置并不重要。事件過濾及事件tracking都被遺留給了使用者空間來處理。而 B 類裝置,核心用 slot 來關聯每個接觸點,通過 slot 來傳遞接觸點的變化。接觸點的建立,更新及銷毀都通過修改關聯的slot的 ABS_MT_TRACKING_ID 來完成(非負數表示诠釋一個接觸點,-1 表示為一個無用的接觸點)。當出現一個之前沒有出現過tracking id 時,表示為一個新的點。某個tracking id 不再次出現時,表示已經移除。

如果tracking的接觸點多餘目前上報的硬體信号時,驅動應該使用 BTN_TOOL_TAP 事件來告知使用者空間目前tracking的接觸點總數量。驅動應該通過發送相應的 BTN_TOOL_TAP 事件以及在調用 input_mt_report_pointer_emulation() 函數時設定 use_count 為 false 。

ABS_MT_SLOT 最小值為 0。

協定樣例

A 類協定

A 類裝置擷取兩點的事件如下:

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
           

當其中某點發送移動,進行更新時,這時所有呈現的接觸點的 raw 資料通過發送 SYN_REPORT 來同步資料。

比如:

ABS_MT_POSITION_X x[1]
   ABS_MT_POSITION_Y y[1]
   SYN_MT_REPORT
   SYN_REPORT
           

接下來通過如下方式來将更新及同步資料

SYN_MT_REPORT
   SYN_REPORT
           

如果驅動除 ABS_MT 事件外額外上報一個 BTN_TOUCH 或 ABS_PRESSURE 事件。最後一個 SYN_MT_REPORT 事件可能會省略。

B 類協定

如下是兩個接觸點的 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
           

如下是在當第一個 slot 在 x 軸上移動之後,上報的日志:

ABS_MT_SLOT 0
   ABS_MT_POSITION_X x[0]
   SYN_REPORT
           

如下是當slot 關聯的 slot 擡起(release)之後,上報如下事件:

ABS_MT_TRACKING_ID -1
   SYN_REPORT
           

如果第二點擡起之後,則上報如下事件:

ABS_MT_SLOT 1
   ABS_MT_TRACKING_ID -1
   SYN_REPORT
           

即當變化的接觸點所關聯的 slot 與上次同步資料的 slot 不一緻時,必須先發送 ABS_MT_SLOT 來标記目前要修改的 slot 資料。(類似于 patch 将單個 slot 資料進行緩存,然後通過修改變更的資料來同步目前接觸點的資料)。

繼續閱讀