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]请看手指跟踪一节。

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