Linux輸入事件編碼

此文章爲個人翻譯英文文檔的產物,僅當做個人筆記使用,不喜勿噴!!
對於翻譯內容有強迫症的讀者請勿閱讀此文檔!!
閱讀過程中如有不恰當之處歡迎交流指正~~
如需轉載,請註明出處!

Linux中的輸入協議採用一系列的類型和編碼向用戶空間表示輸入設備的值。

單一的硬件事件可以產生多個輸入事件,每個輸入事件包含新的單個數據項值。使用一個特殊的事件類型EV_SYNC將輸入事件分成不同的數據包,數據包中輸入數據的改變在時間上是在同一時刻出現的。在下文中,術語“事件”是指單個輸入事件,包括類型,編碼和值。

輸入協議是一種狀態性的協議,只有在事件編碼的值改變之後才需要發送事件。儘管如此,狀態是保存在Linux輸入子系統中的,驅動程序沒有必要去保存狀態,並且,即使驅動發送沒有改變的值也是沒有關係的。用戶空間通過使用定義在linux/input.h中的EVIOCG來得到當前狀態的事件編碼。設備支持的事件上報也由sysfs在class/input/event/device/capabilities /中提供,而設備的屬性在class/input/event*/device/properties中提供。

1. 事件類型

事件類型是邏輯輸入構造下的代碼分組。 每種類型都有一組用於生成事件的適用代碼。 有關每種類型的有效代碼的詳細信息,請參見“代碼”部分。

  • EV_SYN : 分割事件的標記。事件可能按照事件或者空間進行分割,例如多點觸協議。
  • EV_KEY : 用於描述鍵盤、按鍵或其他類似按鍵設備的狀態變化。
  • EV_REL : 用於描述相對座標值變化,例如向左移動鼠標5個單位。
  • EV_ABS : 用於描述絕對座標值變化,例如描述觸摸屏上的觸摸座標。
  • EV_MSC : 用於描述不適合其他事件類型的雜項輸入數據。
  • EV_SW : 用於描述二進制狀態輸入開關。
  • EV_LED : 用於開關設備上的LED。
  • EV_SND : 用於輸出聲音到設備。
  • EV_REP : 用於自動重複設備。
  • EV_FF : 用於給輸入設備發送一個力反饋命令。
  • EV_PWR : 用於電源按鍵和開關輸入的特殊類型。
  • EV_FF_STATUS :用於接受力反饋設備狀態。

2. 事件編碼

事件編碼定義了準確的事件類型。

2.1 EV_SYNC

EV_SYNC事件值沒有被定義。它們只有在evdev事件流中被髮送時才被定義。

2.1.1 SYN_REPORT

用於同步和分割事件到不同的數據包,數據包中輸入數據的改變在時間上是在同一時刻出現的。例如,鼠標的一個動作可能產生REL_X和REL_Y兩個值的變化,在這個之後需要發送SYN_REPORT。下一個動作可能發送更多的REL_X和REL_Y,需要發送另一個SYN_REPORT。

2.1.2 SYN_CONFIG

TBD

2.1.3 SYN_MT_REPORT

用於同步和分割觸摸事件。參看multi-touch-protocol.txt文檔獲得更多信息。

2.1.4 SYN_DROPPED

用於指示evdev客戶端的事件隊列中的緩衝區溢出。客戶端應忽略直到下一個SYN_REPORT事件的所有事件,並查詢設備(使用EVIOCG * ioctls)以獲取其當前狀態。

2.2 EV_KEY

EV_KEY事件採用KEY_<name>或者BTN_<name>的格式。例如,KEY_A用於表示鍵盤上的‘A’按鍵。當一個按鍵被按下時,將會發送一個包含按鍵的編碼的事件,其值爲1。當按鍵被釋放時,一個事件被髮送,其值爲0。一些硬件在重複按下按鍵時發送的事件值爲2。總的來說,KEY_<name>用於鍵盤按鍵,BTN_<name>用於其他類型短暫切換事件。

一些EV_KEY編碼具有特殊含義:

2.2.1 BTN_TOOL_<name>

這些編碼與輸入觸控板、平板電腦和觸摸屏結合使用。這些設備可能和手指、筆或者其他工具一起使用。當一個事件發生並且工具被使用,相應的BTN_TOOL_<name>編碼需要被設置爲值1。當工具不再與輸入設備相互作用時,BTN_TOOL_<name>編碼需要被重置爲0。觸控板、平板電腦和觸摸屏在事件產生時應該使用至少一個BTN_TOOL_<name>編碼。

2.2.2 BTN_TOUCH

BTN_TOUCH用於觸摸接觸。當一個輸入工具確定處於有意義的物理接觸範圍內時,此屬性的值必須設置爲1。有意義的物理接觸可以是任何接觸或者是接觸條件被定義的接觸。例如,觸摸板可以在壓力上升到某個確定值的時候將這個屬性值設置爲1。BTN_TOUCH可以與BTN_TOOL_ 編碼結合使用。例如,當平板電腦筆在平板電腦表面上方徘徊但沒有觸摸到表面時,可以設置BTN_TOOL_PEN爲1,BTN_TOUCH爲0。
注意:對於舊版本的mousedev仿真驅動程序的某些功能,BTN_TOUCH必須是同步幀中發出的第一個evdev編碼。
注意:過去,具有BTN_TOOL_FINGER和BTN_TOUCH的觸摸設備在用戶空間被認爲是觸摸板,而類似設備沒有BTN_TOOL_FINGER被認爲是觸摸屏。爲了後續兼容當前的用戶空間,建議遵循這一特徵。未來,這一特徵將會不再被支持,定義在linux/input.h中的EVIOCGPROP設備屬性將會用來傳遞設備類型。

2.2.3 BTN_TOOL_FINGER, BTN_TOOL_DOUBLETAP, BTN_TOOL_TRIPLETAP, BTN_TOOL_QUADTAP

這幾個編碼對應一個、兩個、三個和四個手指與觸摸板或觸摸屏相互作用。例如,如果用戶使用兩個手指在觸摸板上移動從而滾動屏幕上的內容,BTN_TOOL_DOUBLETAP在這個動作期間應該被設置爲值1。注意,所有BTN_TOOL_<name>編碼和BTN_TOUCH編碼在目的上是互不相干的,手指觸摸觸摸板產生的事件應該從每個組中產生一個編碼。在任何同步幀中,最多隻有一個BTN_TOOL_<name>編碼的值被設置爲1。
注意:過去,一些驅動發送在相同的同步幀中通過值1來發送多個手指數量的編碼,這種用法是不被贊同的。
注意:在多點觸控驅動中,input_mt_report_finger_count()函數被用於發送這些編碼。請參看multi-touch-protocol.txt獲取詳細信息。

2.3 EV_REL

EV_REL事件描述某個屬性的相對變化。例如,鼠標可能向左移動確定的單位數,但是,它的絕對空間位置是不可知的。如果絕對爲位置可知,應該使用EV_ABS編碼來代替EV_REL編碼。

一些EV_REL編碼具有特殊的含義:

2.3.1 REL_WHEEL,REL_HWHEEL

這些編碼分別用於豎直和水平滾輪。

2.4 EV_ABS

EV_ABS事件描述某一屬性的絕對位變化。例如,觸摸板能夠發送觸摸位置的座標值。

一些EV_ABS編碼具有特殊含義:

2.4.1 ABS_DISTANCE

用於描述工具到交互表面的距離。僅在工具懸停時(即緊靠設備且BTN_TOUCH代碼的值爲0時)才發出此事件。如果輸入設備可以在三維空間中不受限制地使用,考慮使用ABS_Z替代。

當工具進入到可檢測的鄰近區域時BTN_TOOL_<name>應該被置1,當工具離開可檢測區域時BTN_TOOL_<name>應該被置0。BTN_TOOL_<name>標記了當前被硬件檢測到的工具類型,並且它與ABS_DISTANCE和/或BTN_TOUCH是相互獨立的。

2.4.2 AB_MT_<name>

用於描述多點觸輸入事件。請參看multi-touch-protocol.txt獲取更多信息。

2.5 EV_SW

EV_SW用於描述狀態二進制開關。例如,SW_LID編碼用於表示筆記本計算機的機蓋是否關閉。

當綁定到設備或者從掛起中恢復後,驅動程序必須上報當前開關狀態。這樣可以確保設備、內核和用戶空間狀態同步。

當恢復時,如果開關狀態和掛起時相同,輸入子系統將會過濾出開關狀態信息。驅動程序在任何時候都不需要保存開關的狀態。

2.6 EV_MSC

EV_MSC事件用於輸入和輸出那些不能被分類到其他種類下的事件。

一些EV_MSC編碼具有特殊含義:

2.6.1 MSC_TIMESTAMP

用於報告自上次重置之後的微秒數。這個事件應該被編碼爲uint32值,該值可以繞回而不會產生特殊後果。假定兩個連續事件之間的時間差在合理的時間範圍(小時)內是可靠的。
一個復位到0的情況可能發生,在這種情況下自從上次事件後的時間是不可知的。如果設備不提供這個信息,驅動程序一定不要提供這個信息到用戶空間。

2.7 EV_LED

EV_LED事件通過輸入和輸出來設置和查詢設備上的各種LED狀態。

2.8 EV_REP

EV_REP事件用來描述自動重複事件。

2.9 EV_SND

EV_SND事件用來發送聲音指令到簡單的聲音輸出設備。

2.10 EV_FF

EV_FF事件用來初始化具有力反饋能力的設備,同時讓這樣的設備產生反饋。

2.11 EV_PWR

EV_PWR事件是一種特殊類型的事件,用來作爲電源管理。它的用法定義的不是太好。待以後處理。

3. 設備屬性

通常情況下,用戶空間是基於設備發送的數據(例如:事件類型)來創建一個輸入設備的。有些情況下兩個設備發送相同的事件類型,則可以以設備屬性的方式提供其他信息。

3.1 INPUT_PROP_DIRECT + INPUT_PROP_POINTER

INPUT_PROP_DIRECT屬性表示設備座標系應該直接被映射爲屏幕座標系(不考慮瑣碎的變換,例如縮放,翻轉和旋轉)。Non-direct輸入設備需要特殊的變換,例如觸摸板的絕對向相對的變換。典型的direct輸入設備有:觸摸屏、繪畫平板;non-direct輸入設備有:觸摸板、鼠標。

INPUT_PROP_POINTER屬性表示設備沒有在屏幕上移動,因此需要使用屏幕指針來追蹤用戶的移動。典型的pointer設備有:觸摸屏板、筆記本電腦、鼠標;non-pointer設備有:觸摸屏。

如果INPUT_PROP_POINTER活着INPUT_PROP_DIRECT均沒有被設置,則認爲屬性是未定義的 ,設備類型應通過發送的事件類型這傳統的方式進行推斷。

3.2 INPUT_PROP_BUTTONPAD

對於表面下方有按鍵的觸摸板,按下觸摸板後會產生一個按鍵單擊,這種情況下這個屬性需要被設置。這屬性通常存在於2009年以來的筆記本和macbook的觸摸板中。

起初,buttonpad屬性被編碼在bcm5974驅動版本字段中,名稱爲集成按鍵。爲了確保向前兼容,在用戶空間中這兩種方式都需要進行檢驗。

3.3INPUT_PROP_SEMI_MT

一些在2008到2011年期間的觸摸板可以檢測當前有多個觸摸而不知道每個觸摸點的位置,只有觸摸數量和矩形是已知的。對於這樣的觸摸板,semi-mt屬性需要被設置。

根據設備的不同,矩形可能會包含所有觸摸(例如邊界框)或其中的一部分,例如最近的兩次觸摸。多樣性使矩形的使用受到限制,但是通常可以從中提取一些手勢。

如果INPUT_PROP_SEMI_MT沒有被設置,則該設備被假定爲真正的MT設備。

3.4 INPUT_PROP_TOPBUTTONPAD

一些筆記本(特別是聯想40系列)提供觸控板設備,但是沒有物理按鍵與觸控板設備相關聯。取而代之的是,觸摸板的頂部區域被標記爲顯示與觸控板一起使用的左,中,右按鈕的視覺/觸覺區域。

如果INPUT_PROP_TOPBUTTONPAD被設置,用戶空間需要相應的模擬按鍵。這個屬性不會影響內核的行爲。內核不會爲這樣的設備提供按鍵模擬,而是會想其他INPUT_PROB_BUTTONPAD設備一樣對待它們。

3.5 INPUT_PROP_ACCELEROMETER

這種設備的指向性座標軸(絕對與/或相對x、y、z)表示加速度數據。一些可以報告旋轉座標軸(絕對與/或相對rx、ry、rz)的設備還上報陀螺儀數據。
所有其他軸保留其含義。 設備不得在同一事件節點上混合常規方向軸和加速度計軸。

4. 指南

以下指南確保正確的單指觸摸和多指功能。對於多指觸摸功能,請參看multi-touch-protocol.txt文檔獲取更多信息。

4.1 鼠標

當鼠標移動時必須上報REL_{X,Y}。BTN_LEFT用於上報主按鍵按下。BTN_{MIDDLE,RIGHT,4,5,etc.}用於上報設備的更多按鍵。如果滾輪事件有效,使用REL_WHEEL和REL_HWHEEL進行上報。

4.2 觸摸屏

觸摸位置通過ABS_{X,Y}上報。當屏幕上的有觸摸時,使用BTN_TOUCH上報。
觸摸接觸時,不能夠使用BTN_{MOUSE,LEFT,MIDDLE,RIGHT}進行上報,如果可能應該採用BTN_TOOL_<name>上報。

對於新的硬件,應該設置INPUT_PROP_DIRECT。

4.3 觸控板

以往的觸控板只提供相對位置信息,因此需要像上面的鼠標一樣來上報事件。

可以提供絕對位置的觸控板需要上報ABS_{X,Y}來上報觸摸位置。當觸控板上有觸摸時,使用BTN_TOUCH進行上報。如果支持多個手指,BTN_TOOL_<name>用於上報觸摸在觸控板上的手指數量。

對於新的硬件,需要設置INPUT_PROP_POINTER。

4.4 寫字板

當筆尖或者其他工具接觸到寫字板時,BTN_TOOL_<name>事件需要進行上報。ABS_{X,Y}用於上報工具的具體位置。當工具與寫字板接觸時,使用BTN_TOUCH上報。
BTN_{STYLUS,STYLUS2}用於上報工具自身的按鍵。除了BTN_{MOUSE,LEFT}外,其他按鍵均可以用於寫字板上的按鍵上報。對於滅有標記的按鍵,BTN_{0,1,2,etc.}是很好的通用編碼。不要使用有特定含義的按鍵,例如BTN_FORWARD,除非設備上的按鍵標籤就是這個含義。

對於新的硬件,需要設置INPUT_PROP_DIRECT和INPUT_PROP_POINTER。

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