日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux/Android多点触摸协议

發(fā)布時間:2025/4/16 linux 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux/Android多点触摸协议 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

鏈接點擊打開鏈接

關于Linux多點觸摸協(xié)議大家可以參考kernel中的文檔:https://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt,而這里根據(jù)實際的例子來理解多點觸摸協(xié)議。


多點觸摸協(xié)議有兩種,A協(xié)議和B協(xié)議。

首先來看A協(xié)議,協(xié)議上說了報點格式是這樣的,以兩點為例:
? ? ? ? ABS_MT_POSITION_X x[0]ABS_MT_POSITION_Y y[0]SYN_MT_REPORTABS_MT_POSITION_X x[1]ABS_MT_POSITION_Y y[1]SYN_MT_REPORTSYN_REPORT
如果第一個觸點離開(抬起),這里的意思是說還有一個觸點,需要繼續(xù)上報這個觸點。
? ? ? ? ABS_MT_POSITION_X x[1]ABS_MT_POSITION_Y y[1]SYN_MT_REPORTSYN_REPORT
如果兩個觸點都離開了,那么只需要報告一個同步事件就可以了。
? ? ? ? SYN_MT_REPORTSYN_REPORT
而代碼示例如下: [cpp]?view plaincopy
  • for?(i?=?0;?i?<?count;?i++)?{??
  • ????????input_report_abs(input_dev,?ABS_MT_POSITION_X,?finger[i].x);??
  • ????????input_report_abs(input_dev,?ABS_MT_POSITION_Y,?finger[i].x);??
  • ????????input_mt_sync(input_dev);??
  • }??
  • ??
  • if?(!count)??
  • ????????input_mt_sync(input_dev);??
  • ??
  • input_sync(input_dev);??
  • 其中count值表示觸點個數(shù),如果是2個,那么這里值就為2,如果所有觸點都離開了,那么count值就為0。

    上面可以說是最簡單,也是最基本的A協(xié)議報點了。除了報點以外,我們也來關注一下input device注冊時需要setting的一些東西。

    [cpp]?view plaincopy
  • input_set_abs_params(input_dev,?ABS_MT_POSITION_X,?0,?MAX_X,?0,?0);??
  • input_set_abs_params(input_dev,?ABS_MT_POSITION_Y,?0,?MAX_Y,?0,?0);??
  • ??
  • __set_bit(EV_SYN,?input_dev->evbit);??
  • __set_bit(EV_ABS,?input_dev->evbit);??
  • ??
  • __set_bit(INPUT_PROP_DIRECT,?input_dev->propbit);??
  • 可能你會看到有的代碼會多下面這兩句: [cpp]?view plaincopy
  • __set_bit(ABS_MT_POSITION_X,?input_dev->absbit);??
  • __set_bit(ABS_MT_POSITION_X,?input_dev->absbit);??
  • 其實這兩句(包括上面的__set_bit(EV_ABS, input_dev->evbit);)是可有可無的,因為在input_set_abs_params函數(shù)中會做相應的設置。

    而這句__set_bit(INPUT_PROP_DIRECT, input_dev->propbit);也是必須要有的,否則在Android中會出現(xiàn)一個白色小圓環(huán),感覺像是缺少idc文件一樣。最后通過getevent -p命令看一下觸摸屏的setting。

    add device 1: /dev/input/event1name: ? ? "ft6x36"events:ABS (0003): 0035 ?: value 0, min 0, max 540, fuzz 0, flat 0, resolution 00036 ?: value 0, min 0, max 960, fuzz 0, flat 0, resolution 0input props:INPUT_PROP_DIRECT


    對于B協(xié)議就稍微顯得有點復雜。B協(xié)議需要硬件支持,和A協(xié)議主要區(qū)別在哪里呢?B協(xié)議可以使用一個ID來標識觸點,可以減少上報到用戶空間的數(shù)據(jù)量,這個ID(ABS_MT_TRACKING_ID)可以有硬件提供或者從原始數(shù)據(jù)計算而得。那>么下面我們就來看B協(xié)議怎么上報數(shù)據(jù)的。

    ? ? ? ? ABS_MT_SLOT 0ABS_MT_TRACKING_ID 45ABS_MT_POSITION_X x[0]ABS_MT_POSITION_Y y[0]ABS_MT_SLOT 1ABS_MT_TRACKING_ID 46ABS_MT_POSITION_X x[1]ABS_MT_POSITION_Y y[1]SYN_REPORT

    如果觸點45只是在x方向做了移動,那么應該怎么報告這個事件呢?

    ? ? ? ? ABS_MT_SLOT 0ABS_MT_POSITION_X x[0]SYN_REPORT

    可以看到減少了很多數(shù)據(jù)的上報,這就是同A協(xié)議最大的區(qū)別。

    如果同slot 0相關的觸點離開(抬起),只需要做下面的操作。ABS_MT_TRACKING_ID -1SYN_REPORT

    這里為什么沒有發(fā)送ABS_MT_SLOT 0事件呢,因為之前slot已經(jīng)被置成了0,再次發(fā)送ABS_MT_SLOT 0是會被忽略掉的。

    如果第二個觸點被抬起,發(fā)送下面的事件序列。

    ? ? ? ? ABS_MT_SLOT 1ABS_MT_TRACKING_ID -1SYN_REPORT


    其他event
    ABS_MT_POSITION_X和ABS_MT_POSITION_Y是多點觸摸協(xié)議的最小事件集,是最基本的事件,也是必須的事件。除此之外呢,還包括下面的一些時間集(需要設置支持):
    ABS_MT_TOUCH_MAJOR
    ABS_MT_TOUCH_MINOR
    ABS_MT_TOUCH*用來表示接觸點區(qū)域大小(即手指與玻璃接觸區(qū)域大小),通常接觸區(qū)域是一個橢圓形狀,那么MAJOR就表示橢圓的長軸,而MINOR就表示橢圓的短軸。如果接觸區(qū)域是圓形的話,那么可以忽略MINOR,而MAJOR就表示圓形的直徑大小。

    ABS_MT_WIDTH_MAJOR
    ABS_MT_WIDTH_MINOR
    上面的TOUCH表示接觸區(qū)域的大小,而WIDTH則表示為接觸工具的大小(例如手指,觸控筆等)。

    ABS_MT_PRESSURE
    而PRESSURE表示壓力值,這個壓力值可以通過上面的4個參數(shù)計算而得,例如:ABS_MT_TOUCH_MAJOR/ABS_MT_WIDTH_MAJOR,可以看到接觸面積越大,壓力值也就越大。當然這個壓力值也可以直接由設備提供。

    ABS_MT_DISTANCE
    觸點與接觸面的距離,0表示觸點在接觸面的表面(已經(jīng)實實在在的接觸到了),而正數(shù)表示在接觸面的上方。

    ABS_MT_ORIENTATION
    觸點的方向。

    ABS_MT_TOOL_X
    ABS_MT_TOOL_Y
    ABS_MT_TOOL_TYPE


    關于上報虛擬按鍵值
    通常觸摸屏下方都有3個虛擬按鍵,而這3個按鍵同其它實體按鍵(例如:power按鍵、音量按鍵)又有所不同,它是觸摸屏提供的一組虛擬按鍵,我們通過觸摸屏會得到這一組按鍵的坐標值,可以通過這個坐標值上報相應的按鍵值來實
    現(xiàn)按鍵功能,那么怎么來上報這個按鍵值呢。首先需要對input設備做一些setting:

    [cpp]?view plaincopy
  • __set_bit(KEY_MENU,?input_dev->keybit);??
  • __set_bit(KEY_HOMEPAGE,?input_dev->keybit);??
  • __set_bit(KEY_BACK,?input_dev->keybit);??
  • ??
  • __set_bit(EV_KEY,?input_dev->evbit);??
  • __set_bit(EV_SYN,?input_dev->evbit);??
  • OK,這些鍵值呢在kernel中是定義在uapi/linux/input.h中的,而通常我們的driver只需要包含linux/input.h就可以了,這個文件中include了的uapi/linux/input.h。

    好的,再來看怎么上報鍵值。
    按鍵按下: [cpp]?view plaincopy
  • input_report_key(input_dev,?key_value,?1);??
  • input_sync(input_dev);??
  • 按鍵抬起: [cpp]?view plaincopy
  • input_report_key(input_dev,?key_value,?0);??
  • input_sync(input_dev);??
  • 如果是按鍵一直被按下,重復上報按鍵被按下那部分就可以了。

    有的地方可能會看到直接使用input_event函數(shù),例如: [cpp]?view plaincopy
  • input_event(input_dev,?EV_KEY,?key_value,?1);??
  • 大家也可以去看看input_report_key函數(shù),它其實是對input_event函數(shù)做了封裝,不管是input_report_abs也好,還是input_sync,最終都是調(diào)用的input_event函數(shù),所以真正上報event的函數(shù)其實是input_event函數(shù)。

    最后一點在setting時除了__set_bit之外,可能還會看到另外一個函數(shù)input_set_capability,這個函數(shù)實現(xiàn)在drivers/input/input.c中,而它最終還是調(diào)用了__set_bit函數(shù),所以最后效果都是一樣的。

    總結(jié)

    以上是生活随笔為你收集整理的Linux/Android多点触摸协议的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。