乐趣区

关于linux-kernel:Multitouch-Protocol

Multi-touch Protocol

kernel/Documentation/input/multi-touch-protocol.rst

:Copyright: |copy| 2009-2010 Henrik Rydberg mailto:rydberg@euromail.se

Introduction

为了充分利用新的多点触控和多用户设施的全副性能,须要一种形式来上报多个触点(即与设施外表间接接触的对象)具体数据的办法。此文档形容了容许内核驱动程序报告任意数量的触点的详细信息的多点触控 (MT) 协定。

依据硬件的能力,此协定被分为了两种类型。对于解决匿名触点的设施(type A),此协定形容了如何将所有触点的原始数据发送给接收者。对于可能跟踪可辨认触点的设施(type B),此协定形容了如何通过 event slot 来发送单个触点的更新信息。

留神: type A 多点触控协定曾经过期,所有的内核驱动程序都转用 type B 协定。

Protcol Usage

触点的详细信息被作为独自的 ABS_MT 事件数据包程序发送,并且只有 ABS_MT 事件被辨认为触点数据包的一部分。因为以后的单点触控 (ST) 应用程序疏忽了这些事件,因而能够在现有驱动程序中的 ST 协定之上实现 MT 协定。

type A 设施的驱动程序通过在每个数据包的结尾调用 input_mt_sync() 来分隔触点数据包。这样会产生一个 SYN_MT_REPORT 事件来批示接管方接管以后触点的数据并筹备好接管下一个触点的数据。

type B 设施通过在每个数据包的结尾调用 input_mt_slot(),并以 slot 作为参数来分隔触点数据包。这样会产生一个ABS_MT_SLOT 事件来批示接管方筹备更新给定的 slot 的信息。

所有的驱动程序都通过调用 input_sync() 函数来标记多点触控数据传输的完结。这批示接受者对上一次 EV_SYN/SYN_REPORT 事件当前的事件进行解决,并筹备好接管新的事件或者数据包。

无状态 type A 以及有状态 type B 的次要区别在于应用可辨认的触点来缩小发送到用户空间的数据。slot 协定须要应用ABS_MT_TRACKING_ID, 它由硬件提供或者通过原始数据计算得出。

对于 type A 类设施,驱动程序应该生成以后触屏上全副匿名触点的任意枚举。数据包在事件流中呈现的程序并不重要,事件过滤以及手指跟踪被留到了用户空间。

对于 type B 设施,驱动程序应该将每个可辨认的触点和一个 slot 关联,并用 slot 来更新触点的变动。通过批改触点关联的 slot 的 ABS_MT_TRACKING_ID 来创立,替换或者销毁触点。非负的 ID 被认为是无效的触点,- 1 示意未被应用的 slot。以前没有呈现的 ID 被认为是新的,不再呈现的 ID 被认为是曾经移出了的。因为只有扭转了的货色会被发送,因而每个触点的残缺状态必须驻留在接收端。收到 MT 事件后,只需更新以后 slot 的相干的属性。

一些设施辨认和 (或) 跟踪的触点数量超过了它们能够向驱动程序报告的数量。此类设施的驱动程序应将一个 B 型 slot 与硬件报告的每个触点相关联。每当与 slot 关联的触点产生更改时,驱动程序应通过更改其 ABS_MT_TRACKING_ID 使该 slot 有效。如果硬件信号表明它正在跟踪的触点数量比以后报告的多,则驱动程序应应用 BTN_TOOL_*TAP 事件来告诉用户空间过后硬件正在跟踪的触点的数量。驱动程序应
通过显式的发送相应的 BTN_TOOL_*TAP 事件并在调用 input_mt_report_pointer_emulation() 时将 use_count 设置为 false 来执行此操作。驱动程序应该只颁布硬件能够报告的尽可能多的 slot。通过观察最大反对的 BTN_TOOL_*TAP 事件大于在 ABS_MT_SLOT 轴的 absinfo 中报告的 B 类 slot 的总数,用户空间能检测到驱动程序能够报告比插槽更多的总触点数。

ABS_MT_SLOT轴的最小值必须为 0。

Protocol Example A:

以下是 type 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

挪动其中一个触点后的序列看起来完全相同; 所有以后触点的原始数据在每次应用 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_TOUCHABS_PRESSURE,则能够省略最初一个 SYN_MT_REPORT 事件。否则,最初一个 SYN_REPORT 将 input core 疏忽,导致没有零接触事件达到用户空间。

Protocol Example B:

以下是 type 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

以下是在 x 轴方向挪动触点 45 当前的序列:

   ABS_MT_SLOT 0
   ABS_MT_POSITION_X x[0]
   SYN_REPORT

以下是在开释 slot0 对应的触点之后的序列:

   ABS_MT_TRACKING_ID -1
   SYN_REPORT

因为被批改的 slot 曾经是 0,所以 ABS_MT_SLOT 会被疏忽。这个音讯解除了 slot0 与触点 45 的关联,以此来销毁触点 45 并开释 slot0 给其余的触点应用。

最初,以下是开释第二个触点之后的序列:

   ABS_MT_SLOT 1
   ABS_MT_TRACKING_ID -1
   SYN_REPORT

Event Usage:

一系列 ABS_MT 事件所须要的属性被定义。事件被分为几类,容许局部实现。最小集由 ABS_MT_POSITION_XABS_MT_POSITION_Y 组成,容许跟踪多个触点。如果设施反对,ABS_MT_TOUCH_MAJORABS_MT_WIDTH_MAJOR 可别离用于提供触点面积尺寸和接触工具尺寸。

TOUCHWIDTH 参数具备几何解释;设想通过窗户看着某人轻轻地将手指靠在玻璃上。你会看到两个区域,一个由理论触碰在玻璃上的手指局部组成的外部区域,一个由手指周边造成的内部区域。接触区域的核心 (a) 为ABS_MT_POSITION_X/Y,接触手指的核心 (b) 为ABS_MT_TOOL_X/Y。接触的尺寸为 ABS_MT_TOUCH_MAJOR,手指的尺寸为ABS_MT_WIDTH_MAJOR。当初设想某人更加使劲地按压在玻璃上,触摸面积将会减少,总体上ABS_MT_TOUCH_MAJOR / ABS_MT_WIDTH_MAJOR 的比率与触点压力相干,该比率会小于 1。对于基于压力的设施,应用 ABS_MT_PRESSURE 提供触点区域的压力。可能悬停接触的设施能够应用 ABS_MT_DISTANCE 来批示接触点与外表之间的间隔。

  Linux MT                               Win8
     __________                     _______________________
    /          \                   |                       |
   /            \                  |                       |
  /     ____     \                 |                       |
 /     /    \     \                |                       |
 \     \  a  \     \               |       a               |
  \     \____/      \              |                       |
   \                 \             |                       |
    \        b        \            |           b           |
     \                 \           |                       |
      \                 \          |                       |
       \                 \         |                       |
        \                /         |                       |
         \              /          |                       |
          \            /           |                       |
           \__________/            |_______________________|

除了 MAJOR 参数外,还能够通过增加 MINOR 参数来形容触摸区域和手指区域的椭圆形状,以使 MAJORMINOR是椭圆的长轴和短轴。触摸椭圆的方向能够用 ORIENTATION 参数形容,而手指椭圆的方向则由矢量 (a-b) 给出。

对于 A 型设施,能够通过 ABS_MT_BLOB_ID 进一步指定触摸形态。

ABS_MT_TOOL_TYPE能够用于辨别接触工具是手指、笔或者其余工具。最初,ABS_MT_TRACKING_ID事件能够用于跟踪一段时间内已辨认的触点

Event Semantics:

ABS_MT_TOUCH_MAJOR

触点主轴长度。该长度须要以外表单位给出。如果外表的分辨率是 X 的 Y 倍,则 ABS_MT_TOUCH_MAJOR 的最大可能值为sqrt(X ^ 2 + Y ^ 2),即对角线。

ABS_MT_TOUCH_MINOR

触点的短轴长度,单位为外表单位。如果触点是元,该事件能够被疏忽。

ABS_MT_WIDTH_MAJOR

接触工具的长轴长度,单位为外表单位。这要被了解为工具本身的尺寸。触点和接触工具的方向假设是一样的。

ABS_MT_WIDTH_MINOR

接触工具的长轴短度,单位为外表单位。如果为圆形疏忽。

以上四个值可用于导出触点的其余信息。比率 ABS_MT_TOUCH_MAJOR / BS_MT_WIDTH_MAJOR 近似于压力的概念。手的手指和手掌都有不同的特色宽度。

ABS_MT_PRESSURE

接触区域上的压力(以任意单位示意)。对于基于压力的设施或任何具备空间信号强度散布的设施,能够代替 TOUCHWIDTH应用。

ABS_MT_DISTANCE

接触点和曲面之间的间隔(以曲面为单位)。零距离意味着触点正在接触外表。负数示意触点悬停在外表上方。

ABS_MT_ORIENTATION

接触椭圆的方向。该值应形容围绕触摸核心顺时针旋转的四分之一圈。有符号的值范畴是任意的,但对于与曲面的 Y 轴(北)对齐的椭圆,应返回零;当将椭圆向左旋转时,应返回负值;当将椭圆向右旋转时,则应返回正值。当在正方向上与 X 轴对齐时,应返回最大范畴;当与 X 轴在负方向上对齐时,应返回 -max 范畴。

默认状况下,触摸椭圆是对称的。对于具备真正 360 度方位角的设施,报告的方位角必须超出最大范畴,以示意超过四分之一圈。对于倒置的手指,应返回最大 * 2 的范畴。

如果接触区域是圆形或者在内核驱动中没有无效信息,方向能够被疏忽。如果设施能够辨别两个轴,但不能(惟一地)辨别两个轴,则能够进行局部定向。在这种状况下,ABS_MT_ORIENTATION的取值范畴为[0, 1]

ABS_MT_POSITION_X

接触椭圆核心外表 X 坐标。

ABS_MT_POSITION_Y

接触椭圆核心外表 Y 坐标。

ABS_MT_TOOL_X

接触工具的核心外表 X 坐标。如果设施不能辨别想要的触点和工具自身,则能够疏忽。

ABS_MT_TOOL_Y

接触工具的核心外表 Y 坐标。如果设施不能辨别想要的触点和工具自身,则能够疏忽。

以上四个地位值可用于将触摸地位与工具地位离开。如果两个地位都存在,则主工具轴指向接触点,否则,工具轴与触摸轴对其。

ABS_MT_TOOL_TYPE

接触工具类型。很多内核驱动不能分辨不同的工具类型,例如手指或笔。在这种状况下,该事件应该被疏忽。协定以后次要反对 MT_TOOL_FINGERMT_TOOL_PENMT_TOOL_PALM.

对于类型 B 设施,该事件由输出内核解决;驱动程序应该改用 input_mt_report_slot_state()。一个触点的ABS_MT_TOOL_TYPE 在始终触摸设施时可能产生扭转,因为当工具首次呈现时固件不可能确定正在应用哪个工具。

ABS_MT_BLOB_ID

BLOB_ID将几个数据包组合在一起,造成一个任意形态的触点。点序列造成定义接触形态的多边形。这是用于类型 A 设施的低级别匿名分组,不应与高级TrackingID 混同。大部分的类型 A 设施没有这个 blob 性能,所以驱动能够平安地疏忽这个事件。

ABS_MT_TRACKING_ID

TRACKING_ID辨认一个触点并贯通它的生命周期。TRACKING_ID的值范畴应足够大,以确保在长时间内能惟一标识触点。对于类型 B 的设施,此事件由输出内核解决;驱动程序应该改用input_mt_report_slot_state()

Event Computation

不同硬件的多样性不可避免地导致某些设施比其余设施更适宜 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 轴(0) 和手指沿着 X 轴(1)。

对于 Win8 设施具备 T 和 C 坐标,地位映射为:

   ABS_MT_POSITION_X := T_X
   ABS_MT_POSITION_Y := T_Y
   ABS_MT_TOOL_X := C_X
   ABS_MT_TOOL_Y := C_Y

可怜的是,没有足够的信息去确定是触摸椭圆还是工具椭圆,因而必须采纳近似值。一种与晚期用法兼容的简略计划是:

   ABS_MT_TOUCH_MAJOR := min(X, Y)
   ABS_MT_TOUCH_MINOR := <not used>
   ABS_MT_ORIENTATION := <not used>
   ABS_MT_WIDTH_MAJOR := min(X, Y) + distance(T, C)
   ABS_MT_WIDTH_MINOR := min(X, Y)

原理:咱们没有对于触摸椭圆的方向的信息,因而能够应用内接圆来近似它。工具椭圆应与向量 (T-C) 对齐,因而直径必须随间隔 (T,C) 增大。最初,假如接触直径等于工具厚度,咱们得出下面的公式。

Finger Tracking

手指跟踪的过程,即为外表上的每个已启动接触调配惟一的trackingID,是欧几里得两局部匹配问题。在每个事件同步中,理论触点集与来自先前同步的触点集匹配。残缺的实现能够在上面找到。

Gestures

在创立手势事件的特定利用中,TOUCHWIDTH 参数可用于例如预计手指压力或辨别食指和拇指。通过增加 MINOR 参数,您还能够辨别手指是扫入手指还是手指,并且通过ORIENTATION,能够检测手指的扭曲。

留神

为了与已存在的利用放弃兼容,手指数据包中报告的数据不得被辨认为单点触摸事件。

对于类型A设施,所有手指数据都绕过输出过滤,因为雷同类型的后续事件援用了不同的手指。

退出移动版