Linux Multi-Touch

http://blog.sina.com.cn/s/blog_5375a6c60100ngpz.html

多點觸摸(Multi-touch,MT)協議


  Copyright (C) 2009 Henrik Rydberg <rydberg[AT]euromail[DOT]se>  

  翻譯  劉吉東 <[email protected]>

 
特別聲明:本文爲本人在閱讀Linux相關文檔時隨手翻譯,因質量原因未提交到社區,歡迎任何人在進行校對之後貢獻給社區。
任何引用皆無需註明譯者,任何引用皆須註明原作。
 
介紹
爲了充分利用新多點觸摸設備的全部威力,Linux需要一個向用戶空間報告詳細指尖數據的途徑。
本文章描述了多點觸摸協議(MT),該協議允許內核驅動報告任意手指數量的詳細數據。

使用
匿名手指細節是作爲ABS事件的分開的數據包順序發出的。只有ABS_MT事件被識別爲手指數據的一部分。
數據包的結束通過調用input_mt_sync()被標記,它產生了一個SYN_MT_REPORT事件。
這指引接收者接受當前手指數據並準備接受其它的。多點觸摸傳輸的結束是通過調用常用的input_sync()函數來標記的。
這指引接收者根據從最後一個EV_SYN/SYN_REPORT累積的事件進行動作,並準備接收一組新的事件/數據包。
一組帶着想得到的屬性的ABS_MT事件被定義了。事件被分爲目錄,以允許部分實現。
最小集包括ABS_MT_POSITION_X和ABS_MT_POSITION_Y,這能保證多個手指被跟蹤。
如果設置支持,ABS_MT_TOUCH_MAJOR和ABS_MT_WIDTH_MAJOR可以被用來分別提供接觸區域的尺寸和靠近的手指(APPROACHING FINGER)。
TOUCH和WIDTH參數擁有幾何解釋;想象視線穿過窗戶看到有人輕輕的把手指按在玻璃上。
你將看到兩個區域,一個內部區域是手指實際觸摸玻璃的部分,一個外部區域由手指的外邊界組成。
內部區域的直徑是ABS_MT_TOUCH_MAJOR,外部區域的直徑是ABS_MT_WIDTH_MAJOR。
現在想象那個人增加手指按在玻璃上的力量,內部區域將增加,同時顯然,
ABS_MT_TOUCH_MAJOR/ABS_MT_WIDTH_MAJOR,永遠小於1,並且和壓力有關。對於基於壓力的設備,ABS_MT_PRESSURE可以用於提供相應區域的壓力。
除了MAJOR參數,手指的橢圓形狀可以通過增加MINOR參數描述,因此MAJOR和MINOR是橢圓形的主要和次要軸。最後,橢圓形的方向可以通過ORIENTATION參數描述。
ABS_MT_TOOL_TYPE可以被用來指定觸摸工具是否是手指或者筆或其它設備。具有更細粒度信息的設備可以指定一般形狀爲blobs,
例如,作爲一個矩形序列通過ABS_MT_BLOB_ID組織在一起。最後,對於少數設備已經能夠支持ABS_MT_TRACKING_ID事件,可以用於通過硬件報告手指跟蹤信息。[5].
 
這裏是兩個手指觸摸可能產生的最小的事件序列:
   ABS_MT_POSITION_X
   ABS_MT_POSITION_Y
   SYN_MT_REPORT
   ABS_MT_POSITION_X
   ABS_MT_POSITION_Y
   SYN_MT_REPORT
   SYN_REPORT

這裏是拿開一個手指之後產生的事件序列:
   ABS_MT_POSITION_X
   ABS_MT_POSITION_Y
   SYN_MT_REPORT
   SYN_REPORT
這是把另一個手指拿開產生的事件序列:
   SYN_MT_REPORT
   SYN_REPORT
如果驅動除了ABS_MT事件之外,還報告了一個BTN_TOUCH或者ABS_PRESSURE,最後一個SYN_MT_REPORT事件會被忽略。
否則,最後的SYN_REPORT將會被輸入核心丟棄,導致無手指事件無法到達用戶空間。
 
事件語法
“接觸”一詞用於描述直接接觸表面的工具,手指、筆或者橡皮,都可以歸類爲接觸。
ABS_MT_TOUCH_MAJOR

接觸主軸的長度,長度應該以表面的單位給出。如果表面有X倍Y分辨率,ABS_MT_TOUCH_MAJOR最大的可能值是sqrt(X^2+Y^2),即對角線。 [4].
ABS_MT_TOUCH_MINOR
接觸面短軸長度,單位是表面單位。如果接觸面是圓形的,此事件可以被忽略。 [4].
ABS_MT_WIDTH_MAJOR
接觸工具的長軸長度,單位是表面單位。這應該被理解爲工具自身的尺寸。接觸面的方向和相應工具假設是相同的。 [4].
ABS_MT_WIDTH_MINOR
接觸工具的短軸長度,單位是表面單位。如果是圓形,則忽略。[4].
以上四個值可以被用於派生關於接觸的附加信息。ABS_MT_TOUCH_MAJOR/ABS_MT_WIDTH_MAJOR接近壓力的概念。手指和手掌有不同的特性寬度。 [1].
ABS_MT_PRESSURE
壓力,可以是任意單位,在接觸區域。可能被用於相應的TOUCH和WIDTH,對於基於壓力的設備或者任何空間信號密度分佈設備。
ABS_MT_ORIENTATION
橢圓形的方向。這個值應該描述一個有符號的圍繞觸點中心的順時針方向的旋轉度。這個有符號值的範圍是任意的,但是對於手指沿着表面Y軸應該返回0,負值當手指轉向左邊,
正值當手指轉向右邊。當完全沿着X軸方向時,返回值的最大值。如果接觸物體是圓形的,或者內核驅動不提供這些信息,方向可以被忽略。如果設備可以區分兩個維度,但是不能
保證任意值,那麼可能是部分支持方向。這時,ABS_MT_ORIENTATION的值域應該是在[0,1] [4].
ABS_MT_POSITION_X
接觸橢圓中心的X表面座標。
ABS_MT_POSITION_Y
接觸橢圓中心的Y表面座標。
ABS_MT_TOOL_TYPE
接觸工具的類型。很多內核驅動不區分不同工具類型,例如手指和筆。在這種情況下,事件應該被忽略。協議當前支持MT_TOOL_FINGER和MT_TOOL_PEN。[2].
ABS_MT_BLOB_ID
BLOB_ID將多個數據包編成到一組任意形狀的接觸。這是一個低級的匿名組,並且不應該和高級跟蹤ID混淆。 [5]. 多數內核驅動沒有blob能力,可以安全的忽略此事件。
ABS_MT_TRACKING_ID
TRACKING_ID標識了一個初始的接觸,貫穿整個生命週期。[5].現在只有很少的設備支持,所以此事件通常被忽略。

事件計算
不同設備的多種多樣不可避免的導致一些設備比另外一些設備更適合MT協議。要簡化和統一映射,本章給出計算特定時間的一些辦法。
對於以矩形報告接觸的設備,無法獲得有符號的方向。假設X和Y是接觸矩形的邊唱,這裏是一個簡單的共識來獲得最可能的信息:
   ABS_MT_TOUCH_MAJOR := max(X, Y)
   ABS_MT_TOUCH_MINOR := min(X, Y)
   ABS_MT_ORIENTATION := bool(X > Y)
ABS_MT_ORIENTATION的範圍應該被設置爲[0,1],以區別沿着Y軸的手指還是沿着X軸的手指。(1).
 
手指跟蹤
內核驅動應該生成一個在當前表面的任意的匿名接觸的枚舉集合。數據包在事件流中的順序並不重要。
手指跟蹤的過程,例如指定一個唯一的跟蹤ID給每一個表面初始化接觸,被留給了用戶空間。跟適合的multi-touch X驅動。【3】在那些驅動中,trackingID保持相同和唯一,直
到接觸消失(當手指離開表面)。賦予一個匿名手指結合給一組特定的手指是一個歐幾里德雙向映射問題,在每一個事件更新,完全依賴於足夠的快速更新速率。
很少硬件支持trackingID。用戶空間可以使用這些原始的標識符來減少貸款和CPU使用。
 
手勢
對於特定的需要創建手勢事件的應用,TOUCH和WIDTH參數可以用來近似手指壓力或者區分索引手指和拇指。
通過附加的MINOR參數,也能區分橫掃手指和點狀手指,以及通過方向來檢查彎曲的手指。
 
注意
爲了和現有應用兼容,手指數據包報告的數據必須被識別爲單觸事件。另外,所有的手指數據必須旁路輸入過濾,因爲後續同類事件指的是不同手指。
第一個內核驅動支持MT協議的是bcm5974驅動,我們可以找到相關的例子。
 
[1]通過ABS_MT_APPROACH_X和ABS_MT_APPROACH_Y,接觸位置和技術工具位置可以被用來派生傾斜。

[2]列表當然可以被擴展

[3]多點觸摸的X驅動項目:http://bitmath.org/code/multitouch/

[4]請參考事件計算一節   

[5]請看手指跟蹤一節。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章