热门内容

公众号"MAKE1"

获取行业最新资讯

请扫码添加

专业客服企业微信

多点触控协议(MTP)详细解析

简介

多点触控协议(MTP)

多点触控协议(MTP)的简介与内容

Multi-touch (MT) Protocol

------------------------- Copyright (C)2009-2010 Henrik Rydberg

Introduction

------------

In order to utilize the full power of thenew multi-touch and multi-user devices, a way to report detailed data frommultiple contacts, i.e., objects in direct contact with the device surface, isneeded. This document describes themulti-touch (MT) protocol which allows kernel drivers to report details for anarbitrary number of contacts.

为了使用功能强大的多点触控设备,一种方案是上报多触点的详细数据。本文档所描述的多点触控协议(MTP)可以让内核驱动向用户层上报任意多个触点的数据信息。

The protocol is divided into two types,depending on the capabilities of the hardware. For devices handling anonymouscontacts (type A), the protocol describes how to send the raw data for allcontacts to the receiver. For devices capable of tracking identifiable contacts(type B), the protocol describes how to send updates for individual contacts viaevent slots.

根据硬件功能,此协议分为两种类型。A类型:对于处理未标识的触点的设备,此类协议描述如何将所有触点的原始数据上报给上层;B类型:对于能跟踪可标识的触点的设备,此类协议描述如何将单个触点的更新信息通过事件槽上报给上层。

Protocol Usage

--------------

Contact details are sent sequentially asseparate packets of ABS_MT events. Only the ABS_MT events are recognized as partof a contact packet. Since these events are ignored by current single-touch(ST) applications, the MT protocol can be implemented on top of the ST protocolin an existing driver.

触点的详细数据作为单独的ABS_MT事件包按顺序发送,只有ABS_MT事件作为触控数据包时才能被识别。由于这些事件会被单触点应用所忽略,MTP是在STP上实现的。

Drivers for type A devices separate contactpackets by calling input_mt_sync() at the end of each packet. This generates aSYN_MT_REPORT event, which instructs the receiver to accept the data for thecurrent contact and prepare to receive another.

A类设备的驱动:它会在每个包的最后调用一次input_mt_sync()函数分离接收到的触点数据包,并且会产生一个SYN_MT_REPORT event ,该事件会告诉接收方接收当前触点数据,并准备接受其他的。

Drivers for type B devices separate contactpackets by calling input_mt_slot(), with a slot as argument, at the beginningof each packet. This generates an ABS_MT_SLOT event, which instructs thereceiver to prepare for updates of the given slot.

B类设备的驱动:在每个包的开头调用input_mt_slot()函数并携带一个槽作为参数,此时会

产生一个ABS_MT_SLOT event,该事件会告诉接收方准备更新给定的槽。

All drivers mark the end of a multi-touchtransfer by calling the usual input_sync() function. This instructs thereceiver to act upon events accumulated since last EV_SYN/SYN_REPORT andprepare to receive a new set of events/packets.

所有类型的驱动都会调用input_sync()函数来标记多点触摸传输的结束,并会告知接收方开始从最后一次EV_SYN/SYN_REPORT起作事件累计。

The main difference between the statelesstype A protocol and the stateful type B slot protocol lies in the usage ofidentifiable contacts to reduce the amount of data sent to userspace. The slotprotocol requires the use of the ABS_MT_TRACKING_ID, either provided by thehardware or computed from the raw data [5].

A类协议和B类协议的主要区别是B类协议使用ID来标识触点,减少了上报到用户空间的数据量。B类协议需要使用ABS_MT_TRACKING_ID,由硬件提供或者通过原始数据计算得来。

For type A devices, the kernel drivershould generate an arbitrary enumeration of the full set of anonymous contactscurrently on the surface. The order in which the packets appear in the eventstream is not important. Event filteringand finger tracking is left to user space [3].

对于A类设备,内核驱动需要对当前的所有触点进行任意枚举。数据包在事件流里出现的顺序并不是很重要。事件过滤和触点跟踪都由用户空间来处理。

For type B devices, the kernel drivershould associate a slot with each identified contact, and use that slot topropagate changes for the contact. Creation, replacement and destruction ofcontacts is achieved by modifying the ABS_MT_TRACKING_ID of the associatedslot. A non-negative tracking id isinterpreted as a contact, and the value -1 denotes an unused slot. A tracking id not previously present isconsidered new, and a tracking id no longer present is considered removed. Since only changes are propagated, the fullstate of each initiated contact has to reside in the receiving end. Upon receiving an MT event, one simplyupdates the appropriate attribute of the current slot.

对于B类设备,内核驱动需要将slot和每个已标识的触点关联,使用slot来传递触点的变化。触点的创建,替换和销毁都是通过修改相应slot的ABS_MT_TRACKING_ID来实现。非零的跟踪ID表示已使用触点,而-1表示未使用的slot。之前不存在的跟踪ID被认为是新的,再存在的跟踪ID被认为是已移除的。由于只有触点变化才会被传递,每个被标识的触点会驻留接收端,一旦接收到MT事件,就会更新当前slot的相应属性。

Some devices identify and/or track morecontacts than they can report to the driver. A driver for such a device should associate one type B slot with eachcontact that is reported by the hardware. Whenever the identity of the contact associated with a slot changes, thedriver should invalidate that slot by changing its ABS_MT_TRACKING_ID. If the hardware signals that it is trackingmore contacts than it is currently reporting, the driver should use aBTN_TOOL_*TAP event to inform userspace of the total number of contacts beingtracked by the hardware at that moment. The driver should do this by explicitly sending the correspondingBTN_TOOL_*TAP event and setting use_count to false when callinginput_mt_report_pointer_emulation(). The driver should only advertise as manyslots as the hardware can report. Userspace can detect that a driver can reportmore total contacts than slots by noting that the largest supportedBTN_TOOL_*TAP event is larger than the total number of type B slots reported inthe absinfo for the ABS_MT_SLOT axis.

一些设备标识和跟踪的触点比上报给驱动的触点要多。这种设备的驱动程序需要将一个B类型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总数,用户空间能检测出驱动程序可以报告比插槽更多的触点总数。

Protocol Example A

------------------

Here is what a minimal event sequence for atwo-contact touch would look like for a type A device:

对于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

The sequence after moving one of the contactslooks exactly the same; the raw data for all present contacts are sent betweenevery synchronization with SYN_REPORT.

移动其中的一个触点后的序列也是一样的,所有的触点数据包发送完后,会用SYN_REPORT用来同步处理。

Here is the sequence after lifting thefirst contact:

当第一个触点弹起后的序列:

ABS_MT_POSITION_X x[1]

ABS_MT_POSITION_Y y[1]

SYN_MT_REPORT

SYN_REPORT

And here is the sequence after lifting thesecond contact:

当第二个触点也弹起后的序列:

SYN_MT_REPORT

SYN_REPORT

If the driver reports one of BTN_TOUCH orABS_PRESSURE in addition to the ABS_MT events, the last SYN_MT_REPORT event maybe omitted. Otherwise, the last SYN_REPORT will be dropped by the input core,resulting in no zero-contact event reaching userland.

如果驱动上报BTN_TOUCH或ABS_PRESSURE事件,SYN_MT_REPORT事件可能会被忽略。否则最后的SYN_REPORT事件会被输入核心层丢弃,导致没有产生同步事件。

Protocol Example B

------------------

Here is what a minimal event sequence for atwo-contact touch would look like for a type B device:

下面是报告两个触点的最小事件序列:

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

Here is the sequence after moving contact45 in the x direction:

在X方向上移动触点45后的序列:

ABS_MT_SLOT 0

ABS_MT_POSITION_X x[0]

SYN_REPORT

Here is the sequence after lifting thecontact in slot 0:

与slot 0关联的触点弹起后的序列:

ABS_MT_TRACKING_ID -1

SYN_REPORT

The slot being modified is already 0, sothe ABS_MT_SLOT is omitted. The messageremoves the association of slot 0 with contact 45, thereby destroying contact45 and freeing slot 0 to be reused for another contact.

被修改过的slot已经为0了,所以ABS_MT_SLOT会被忽略。把触点45从slot 0上移除,因此销毁触点45和释放slot 0后,其他触点又可以重新使用。

Finally, here is the sequence after liftingthe second contact:

最后,第二个触点也弹起后的序列如下:

ABS_MT_SLOT 1

ABS_MT_TRACKING_ID-1

SYN_REPORT

Event Usage

-----------

A set of ABS_MT events with the desiredproperties is defined. The events are divided into categories, to allow forpartial implementation. The minimum setconsists of ABS_MT_POSITION_X and ABS_MT_POSITION_Y, which allows for multiplecontacts to be tracked. If the devicesupports it, the ABS_MT_TOUCH_MAJOR and ABS_MT_WIDTH_MAJOR may be used toprovide the size of the contact area and approaching contact, respectively.

协议定义了一系列的ABS_MT事件,这些事件被分为几大类,允许只应用其中的一部分。最小的事件集由ABS_MT_POSITION_X 和ABS_MT_POSITION_Y组成,以此来实现多点触摸。如果设备支持ABS_MT_TOUCH_MAJOR和 ABS_MT_WIDTH_MAJOR可以分别提供触点大小和接触工具的大小。

The TOUCH and WIDTH parameters have ageometrical interpretation; imagine looking through a window at someone gentlyholding a finger against the glass. Youwill see two regions, one inner region consisting of the part of the fingeractually touching the glass, and one outer region formed by the perimeter ofthe finger. The diameter of the inner region is the ABS_MT_TOUCH_MAJOR, thediameter of the outer region is ABS_MT_WIDTH_MAJOR. Now imagine the personpressing the finger harder against the glass. The inner region will increase,and in general, the ratio ABS_MT_TOUCH_MAJOR / ABS_MT_WIDTH_MAJOR, which isalways smaller than unity, is related to the contact pressure. Forpressure-based devices, ABS_MT_PRESSURE may be used to provide the pressure onthe contact area instead. Devices capable of contact hovering can useABS_MT_DISTANCE to indicate the distance between the contact and the surface.

TOUCH和WIDTH参数。想象一下,一个人用手指按在玻璃上,通过玻璃你将看到两个区域,里面是手指与玻璃实际接触的区域,区域的直径用ABS_MT_TOUCH_MAJOR参数来描述;外面是手指本身大小的区域,区域的直径用ABS_MT_WIDTH_MAJOR参数来描述。手指与玻璃接触的面积要小于手指本身的大小,通过ABS_MT_TOUCH_MAJOR / ABS_MT_WIDTH_MAJOR的比值可以用来反映接触时的压力值。对于支持压力的设备,也可通过 ABS_MT_PRESSURE参数直接提供手指的压力。同样可以使用ABS_MT_DISTANCE参数提供接触点和表面的距离。

In addition to the MAJOR parameters, theoval shape of the contact can be described by adding the MINOR parameters, suchthat MAJOR and MINOR are the major and minor axis of an ellipse. Finally, theorientation of the oval shape can be describe with the ORIENTATION parameter.

另外MAJOR和MINOR参数用来描述椭圆的形状,触点的形状通常被认为是椭圆形。MAJOR和MINOR参数分别是这个椭圆的长轴和短轴,椭圆的方向可以被 ORIENTATION这个参数描述。

For type A devices, further specificationof the touch shape is possible via ABS_MT_BLOB_ID.

The ABS_MT_TOOL_TYPE may be used to specifywhether the touching tool is a finger or a pen or something else. Finally, theABS_MT_TRACKING_ID event may be used to track identified contacts over time[5].

对于A类设备,通过ABS_MT_BLOB_ID来进一步规范触点的形状,ABS_MT_TOOL_TYPE参数用来描述触摸工具的类型(手指,触控笔等)。ABS_MT_TRACKING_ID参数用来跟踪标识的触点。

In the type B protocol, ABS_MT_TOOL_TYPEand ABS_MT_TRACKING_ID are implicitly handled by input core; drivers shouldinstead call input_mt_report_slot_state().

对于B类型协议,ABS_MT_TOOL_TYPE and ABS_MT_TRACKING_ID都已被输入核心层隐式处理,驱动程序只需要调用input_mt_report_slot_state()。

Event Semantics

---------------

ABS_MT_TOUCH_MAJOR

The length of the major axis of thecontact. The length should be given in surface units. If the surface has an Xtimes Y resolution, the largest possible value of ABS_MT_TOUCH_MAJOR issqrt(X^2 + Y^2), the diagonal [4].

触点长轴长度

ABS_MT_TOUCH_MINOR

The length, in surface units, of the minoraxis of the contact. If the contact is circular, this event can be omitted [4].

触点短轴长度,如果触点是圆形,则忽略

ABS_MT_WIDTH_MAJOR

The length, in surface units, of the majoraxis of the approaching tool. This should be understood as the size of the toolitself. The orientation of the contact and the approaching tool are assumed tobe the same [4].

接触工具长轴长度

ABS_MT_WIDTH_MINOR

The length, in surface units, of the minoraxis of the approaching tool. Omit if circular [4].

接触工具短轴长度,接触工具切面是圆形,则忽略

The above four values can be used to deriveadditional information about the contact. The ratio ABS_MT_TOUCH_MAJOR /ABS_MT_WIDTH_MAJOR approximates the notion of pressure. The fingers of the handand the palm all have different characteristic widths [1].

可以利用上面的四个值去获取触点其它的信息,ABS_MT_TOUCH_MAJOR/ ABS_MT_WIDTH_MAJOR的比值可以用来反应接触时的压力值

ABS_MT_PRESSURE

The pressure, in arbitrary units, on thecontact area. May be used instead of TOUCH and WIDTH for pressure-based devicesor any device with a spatial signal intensity distribution.

压力,如果设备支持压力功能或者空间信号分布强度功能,可用此参数来替代上面四个参数

ABS_MT_DISTANCE

The distance, in surface units, between thecontact and the surface. Zero distance means the contact is touching thesurface. A positive number means the contact is hovering above the surface.

触点和表面的距离,0表示触点接触到触摸屏表面,正数意味着触点在表面上方

ABS_MT_ORIENTATION

The orientation of the ellipse. The valueshould describe a signed quarter of a revolution clockwise around the touchcenter. The signed value range is arbitrary, but zero should be returned for afinger aligned along the Y axis of the surface, a negative value when finger isturned to the left, and a positive value when finger turned to the right. Whencompletely aligned with the X axis, the range max should be returned. Orientation can be omitted if the touchingobject is circular, or if the information is not available in the kerneldriver. Partial orientation support is possible if the device can distinguishbetween the two axis, but not (uniquely) any values in between. In such cases,the range of ABS_MT_ORIENTATION should be [0, 1] [4].

触点的方向。此值的范围是任意的,0表示手指和Y轴对齐,负值表示手指向左移,正值表示手指向右移。当和X轴完全对齐时,返回最大值。如果接触面是圆形或在驱动中此值不可用,会被忽略。如果设备能区分XY轴,部分的方向是有可能支持的。在这种情况下,ABS_MT_ORIENTATION的范围应该是[0,1]。

ABS_MT_POSITION_X

The surface X coordinate of the center ofthe touching ellipse.

接触面中心的X坐标值

ABS_MT_POSITION_Y

The surface Y coordinate of the center ofthe touching ellipse.

接触面中心的Y坐标值

ABS_MT_TOOL_TYPE

The type of approaching tool. A lot ofkernel drivers cannot distinguish between different tool types, such as afinger or a pen. In such cases, the event should be omitted. The protocolcurrently supports MT_TOOL_FINGER and MT_TOOL_PEN [2]. For type B devices, thisevent is handled by input core; drivers should instead useinput_mt_report_slot_state().

触摸工具的类型,大多数的内核驱动都不能区分工具的类型,所以在这种情况下,应该被忽略。MTP当前只支持MT_TOOL_FINGER(手指) 和MT_TOOL_PEN(笔)。对于B类设备,驱动调用input_mt_report_slot_state()函数将这些事件都交由输入核心层来处理。

ABS_MT_BLOB_ID

The BLOB_ID groups several packets togetherinto one arbitrarily shaped contact. The sequence of points forms a polygonwhich defines the shape of the contact. This is a low-level anonymous groupingfor type A devices, and should not be confused with the high-level trackingID[5]. Most type A devices do not have blob capability, so drivers can safelyomit this event.

BLOB_ID是形状集ID,可以用来组合任意的触点形状,大多数的A类设备没有形状属性,所以驱动应该将此事件忽略。

ABS_MT_TRACKING_ID

The TRACKING_ID identifies an initiatedcontact throughout its life cycle [5]. The value range of the TRACKING_IDshould be large enough to ensure unique identification of a contact maintainedover an extended period of time. For type B devices, this event is handled byinput core; drivers should instead use input_mt_report_slot_state().

TRACKING_ID用来标识触点的整个生命周期。TRACKING_ID的范围必须足够大,以确保每个触点都有一个独一的标号。对于B类设备,驱动调用input_mt_report_slot_state()函数将这些事件都交由输入核心层来处理。

Event Computation

-----------------

The flora of different hardware unavoidablyleads to some devices fitting better to the MT protocol than others. Tosimplify and unify the mapping, this section gives recipes for how to computecertain events.

由于硬件上的差异,导致一些设备不能更好的使用MTP。为了简化和统一,本节给出来某些事件的计算方法。

For devices reporting contacts asrectangular shapes, signed orientation cannot be obtained. Assuming X and Y arethe lengths of the sides of the touching rectangle, here is a simple formulathat retains the most information possible:

一些设备将接触面作为一个矩形上报,假设X和Y是矩形接触面的边,可以通过下面一些公式获取一些信息:

ABS_MT_TOUCH_MAJOR := max(X, Y)

ABS_MT_TOUCH_MINOR := min(X, Y)

ABS_MT_ORIENTATION := bool(X > Y)

The range of ABS_MT_ORIENTATION should beset to [0, 1], to indicate that the device can distinguish between a fingeralong the Y axis (0) and a finger along the X axis (1).

ABS_MT_ORIENTATION的取值范围为0至1,用来标识矩形接触面偏向Y轴(0)或X轴(1)的程度。

Finger Tracking

---------------

The process of finger tracking, i.e., toassign a unique trackingID to each initiated contact on the surface, is aEuclidian Bipartite Matching problem. Ateach event synchronization, the set of actual contacts is matched to the set ofcontacts from the previous synchronization. A full implementation can be foundin [3].

触点跟踪过程,比如为每个触点分配一个独一的跟踪ID号。每一个事件同步时,实际的触点集是和之前同步的触点集匹配的。

Gestures

--------

In the specific application of creating gestureevents, the TOUCH and WIDTH parameters can be used to, e.g., approximate fingerpressure or distinguish between index finger and thumb. With the addition ofthe MINOR parameters, one can also distinguish between a sweeping finger and apointing finger, and with ORIENTATION, one can detect twisting of fingers.

对于创建手势事件这类特殊的应用中,TOUCH和 WIDTH参数经常用来,例如区分拇指和食指或者手指大约的压力,另外 MINOR参数可以用来区别设备的接触面的大小(点接触还是面接触),ORIENTATION可以检测旋转方向。

Notes

-----

In order to staycompatible with existing applications, the data reported

in a finger packet mustnot be recognized as single-touch events.

为了和现有的应用兼容,在上报的触点数据包中的数据不能识别为单点触控事件。

For type A devices, allfinger data bypasses input filtering, since

subsequent events of thesame type refer to different fingers.

对于A类型的设备,由于随后相同类型的事件关联不同的触控,所有的数据会绕过输入过滤.

For example usage of thetype A protocol, see the bcm5974 driver. For

example usage of thetype B protocol, see the hid-egalax driver.

比如A类型协议的使用,可以参考内核中实现的bcm5974驱动。再如B类型协议的使用,可以参考hid-egalax驱动。

[1] With the extensionABS_MT_APPROACH_X and ABS_MT_APPROACH_Y, the

difference between thecontact position and the approaching tool position

could be used to derivetilt.

有了ABS_MT_APPROACH_X 和 ABS_MT_APPROACH_Y 的扩展,在触控位置和触控工具的位置的差异可以推导出倾斜度。

[2] The list can ofcourse be extended.

[3] The mtdev project:http://bitmath.org/code/mtdev/.

[4] See the section onevent computation.

[5] See the section onfinger tracking.

---------------------下面是另一篇全中文翻译-----------------------

Linux输入子系统:多点触控协议 -- multi-touch-protocol.txt

Multi-touch (MT) Protocol

-------------------------

Copyright(C) 2009-2010 Henrik Rydberg

简介

------------

为了发挥新近的多点触摸和多用户设备的强大功能,为多点触摸定义一种上报详细数据的方法(比如有多个物体直接接触到设备的表面),是非常有必要的。这篇文档描述了多点触摸协议(multi-touch,MT),是的内核驱动可以对多个随意数量的触控事件上报详细的数据信息。

基于硬件的能力,该协议被分为两种类型。对于只能处理匿名接触(type A)的设备,该协议描述了如何把所有的原始触摸数据发送给接收者。对于那些有能力跟踪并识别每个触摸点的设备(type B),该协议描述了如何把每个触摸点的单独更新通过事件slots发送给接受者。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Kernel版本:V3.7

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

协议的使用

--------------

详细的触控信息被按顺序地分割为多个ABS_MT事件数据包进行发送。只有ABS_MT事件信息被识别为触控数据包的一部分,因为这些事件在当前的单点触控(single-touch,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协议之间的主要区别是通过识别相同接触点来减低发送到用户空间的数据量。slot协议需要使用到ABS_MT_TRACKING_ID,它要不由硬件来提供,或者通过原始数据进行计算。

对于type A设备,内核驱动应该根据设备表面上全部有效触控进行列举并生成事件。每个触控点数据包在这次事件流中的顺序并不重要。事件过滤和手指跟踪的工作留给用户空间来实现。

对于type B设备,内核驱动应该把每一个识别出的触控和一个slot相关联,并使用该slot来传播触摸状态的改变。通过修改关联slot的ABS_MT_TRACKING_ID来达到对触摸点的创建,替换和销毁。一个非负数的跟踪id被解释为有效的触摸,-1则代表一个不再使用的slot。一个之前没有出现过的跟踪id被认为是一个新的接触点,当一个跟踪id不再出现时则认为该接触点已经被移除。因为只有变化的部分被传播,每个被启动的接触点的状态信息必须驻留在接收端。每当接收到一个MT事件,只需对当前slot的相关属性进行一次简单的更新即可。

有些设备可以识别和/或跟踪比它能报告给驱动更多的接触点,对于这种设备的驱动应该使得硬件上报的每一个接触点关联一个type B的slot。一旦识别到一个关联了slot的接触点发生了变化,驱动应该通过改变他的ABS_MT_TRACKING_ID使得该slot无效。如果硬件发出通知它跟踪到了比目前上报的还要多的接触点,驱动应该使用BTN_TOOL_*TAP事件知会用户空间此刻硬件跟踪的总的接触点数目已经改变。要完成此工作,驱动应该显式地发送BTN_TOOL_*TAP事件,并在调用input_mt_report_pointer_emulation()时把use_count参数设为false。驱动应该只通告硬件所能报告的slots数量。用户空间可以通过注意到最大支持的BTN_TOOL_*TAP事件大于在ABS_MT_SLOT轴的absinfo中报告的type B的slots总数,来检测驱动是否能报告比slots数还多的触控点。

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_TOUCH 或ABS_PRESSURE事件,最后一个SYN_MT_REPORT可以省略掉,否则,最后的SYN_REPORT会被input核心层扔掉,结果就是一个0触控点事件被传到用户空间中。

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

id 45的触控点在x方向移动后的事件序列如下:

ABS_MT_SLOT 0

ABS_MT_POSITION_X x[0]

SYN_REPORT

slot 0对应的接触点离开后,对应的事件序列如下:

ABS_MT_TRACKING_ID -1

SYN_REPORT

上一个被修改的slot也是0,所以ABS_MT_SLOT被省略掉。这一消息移除了接触点45相关联的slot 0,于是接触点45被销毁,slot 0被释放后可以被另一个接触点重用。

最后,第二个接触点离开后的时间序列如下:

ABS_MT_SLOT 1

ABS_MT_TRACKING_ID -1

SYN_REPORT

事件的使用

-----------

一组ABS_MT事件集合按需要的特性被定义。这些事件被分成几个组,以便允许只实现其中的一部分。最小的集合由ABS_MT_POSITION_X和ABS_MT_POSITION_Y组成,用于跟踪多点接触。如果设备支持,ABS_MT_TOUCH_MAJOR和ABS_MT_WIDTH_MAJOR可以用来提供接触面积和对应的接触工具。

TOUCH和WIDTH参数有一个几何解释。想象一下通过一个窗户观察一个人把一个手指按压在对面的玻璃上,你会看到两个区域,内圈的区域包含了手指实际和玻璃接触的部分,而外圈则是手指的外轮廓。接触区域(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参数,MAJOR和MINOR参数相当于椭圆的长轴和短轴。接触区域的椭圆的方向可以用ORIENTATION参数描述,而手指区域的椭圆方向可以通过向量运算(a-b)来获得。

对于type A设备,将来的规格可能会通过ABS_MT_BLOB_ID来描述接触的外形。

ABS_MT_TOOL_TYPE可以用来指出触控工具是手指还是笔或者其它物体。最后,ABS_MT_TRACKING_ID应该一直用来跟踪被识别的接触点。

在type B协议里,ABS_MT_TOOL_TYPE和ABS_MT_TRACKING_ID被隐藏在input核心层中进行处理,驱动程序应该改为调用input_mt_report_slot_state()。

事件的语义说明

---------------

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

工具轮廓区域短轴的表面单位长度,圆形的话可以被忽略。

上述4个值可以被用来推导出接触面的额外信息。ABS_MT_TOUCH_MAJOR / ABS_MT_WIDTH_MAJOR可以被用作接近的压力。手指和手掌有不用的特征宽度。

ABS_MT_PRESSURE

接触区域的压力值,可以是任意单位。基于压力的设备应该使用该事件而不是TOUCH和 WIDTH事件。也用于可以报告空间信号强度的设备。

ABS_MT_DISTANCE

接触物到接触表面之间的表面单位距离。距离为0表明已经接触到了表面。一个正值表示接触物悬浮在表面之上。

ABS_MT_ORIENTATION

接触椭圆区域的方向。该值描述了围绕触摸中心做1/4顺时针转动的有符号数。没有限定该数值的范围,但是在椭圆和表面的Y方向对齐时应该返回0值,椭圆往左转时应该返回负值,往右转时应该返回正值。当和X轴完全对齐时,应该返回最大值。

接触的椭圆默认为是对称点。对于可以360度转动的设备,需要报告超出最大范围来指出转动多于1/4圈。对于倒置的手指,应该上报最大范围的两倍。

如果接触面是一个圆形,或者方向信息在内核驱动中不可用,此时方向参数可以被忽略。如果设备可以识别出两个轴方向,有可能只支持部分不连续的方向,在这种情况下,ABS_MT_ORIENTATION的范围应该是[0,1]【4】。

ABS_MT_POSITION_X

接触中心的X坐标。

ABS_MT_POSITION_Y

接触中心的Y坐标

ABS_MT_TOOL_X

接触工具轮廓中心的X坐标。如果设备不能区分接触面和工具本身时,可以忽略该事件。

ABS_MT_TOOL_Y

接触工具轮廓中心的Y坐标。如果设备不能区分接触面和工具本身时,可以忽略该事件。

这4个位置值可以用于从触控工具位置中分离实际的接触位置。如果两种位置信息都存在,那么触控工具的长轴指向接触点,否则,工具和接触面的轴互相对其。

ABS_MT_TOOL_TYPE

接近工具的类型。很多内核驱动程序不能区分不同的触控工具,比如手指和笔。这种情况下,该事件可以被忽略。目前的协议支持MT_TOOL_FINGER 和MT_TOOL_PEN【2】两种类型。对于type B设备,该事件由input核心层处理,驱动应该改为使用input_mt_report_slot_state()来上报。

ABS_MT_BLOB_ID

BLOB_ID事件把几个数据包组合在一起来组成一个任意的接触形状。一些点组成的序列定义了一个多边形的外形。这是一个type A设备的底层匿名数据组合,不应该和上层的跟踪ID相混淆。多数type A设备没有blog这一能力,所以驱动可以放心地忽略该事件。

ABS_MT_TRACKING_ID

TRACKING_ID识别一个被启动的触控点的整个生命周期。TRACKING_ID的范围应该足够大,从而保证在足够长的时间内都可以维护一个唯一的值。对于type B设备,该事件由input核心层处理,驱动程序应该改为使用input_mt_report_slot_state()来上报该事件。

事件的计算

-----------------

一堆不同的硬件不可避免地导致一些设备比另一些更适合于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轴。

对于有T和C坐标的win8设备,位置信息的对应关系是:

ABS_MT_POSITION_X := T_X

ABS_MT_POSITION_Y := T_Y

ABS_MT_TOOL_X := C_X

ABS_MT_TOOL_X := C_Y

很不幸的是,没有足够的信息可以确定触摸椭圆和工具椭圆,所以只能求助于近似算法。一种兼容早期使用方式的简单的方案是:

ABS_MT_TOUCH_MAJOR := min(X, Y)

ABS_MT_TOUCH_MINOR :=

ABS_MT_ORIENTATION :=

ABS_MT_WIDTH_MAJOR := min(X, Y) + distance(T, C)

ABS_MT_WIDTH_MINOR := min(X, Y)

基本原理是:我们没有关于触摸椭圆的相关信息,所以改用它的内切圆形来近似它。触控工具的椭圆应该与向量(T - C)对齐,所以它的直径必须增加(T, C)之间的距离。最后,假设触摸区域的直径等于触控工具的厚度,我们可以得到上述公式。

手指跟踪

---------------

跟踪手指的处理过程,例如,为在表面上启动的每个触控点分配一个唯一的trackingID,是一个欧几里得偶匹配问题。在每一次的事件同步中,一组实际的触控点要和上一个同步的一组触控点进行匹配,完整的实现请参考。

手势

--------

在某些可以产生手势事件的特殊应用中,可以使用TOUCH和WIDTH参数,比如,近似手指的压力或者区分食指和拇指。利用额外的MINOR参数,可以区分整个手指压下还是只是手指的一个点压。利用ORIENTATION参数,我们可以检测手指的拧动。

注意事项

------------

为了和现有的应用兼容,一个手指数据包中报告的数据不能被识别为单点触控事件。

对于type A设备,所有的手指数据都要略过输入过滤算法,因为接下来的同一类型的事件指向的是不同的手指。

使用type A协议设备的例子,请参考bcm5974的驱动。对于type B协议的例子,请参考hid-egalax的驱动。

[1] Also, the difference (TOOL_X -POSITION_X) can be used to model tilt.

[2] The list can of course be extended.

[3] mtdev 项目: http://bitmath.org/code/mtdev/.

[4] 参看事件计算一节的内容。

[5] 参看手指跟踪一节的内容。

-----------------------------------------------------------下面是另一篇总结--------------------------------------------------------------------------

多点触摸协议

1、基于硬件的能力,该协议分为两种类型。

2、TYPE A:针对于只能处理匿名接触的设备,该协议描述了如何把所有的原始触摸数据发送给接受者。

在每个数据包的结尾用input_mt_sync()对多个触控包进行分割,这将会产生一个SYN_MT_REPORT事件,

它通知接收者接收当前的触控信息并准备接收下一个信息。

3、TYPE B:针对于那些有能力跟踪并识别每个触摸点的设备,该协议描述了如何把每个触摸点的单独跟新通过

事件slots发送给接收者。在每个数据包的开始,通过调用input_mt_slot()进行分割,同时带入一个参数:slot。

这回产生一个ABS_MT_SLOT事件,它通知接收者准备更新给定slot的信息。

4、对于type B设备,内河驱动应该把每一个识别出的触控点和一个slot相关联,并使用该slot的ABS_MT_TRAKING_ID

来达到对触摸点的创建,替换和销毁。一个非负数的track_id被解释为有效的触摸,-1则代表一个不再使用的slot。

5、一个之前没有出现过的track_id被认为是一个新的触摸点,当一个track_id不再出现时则认为该接触点已经被移除。

因为只要有变化的部分被上报,每个被启动的接触点的状态信息必须驻留在接收端。每当接收到一个MT事件,

只需对当前slot的相关属性进行一次简单的更新即可。

6、type B设备的最小的事件序列:

ABS_MT_SLOT 0

ABS_MT_TRACKING_ID 45

ABS_MT_POSITION_X x0

ABS_MT_PPOSITION_Y Y0

ABS_MT_SLOT 1

ABS_MT_TRACKING_ID 46

ABS_MT_POSITION_X x1

ABS_MT_POSITION_Y Y1

SYN_REPORT

 

id=45的触控点在x方向移动后的事件序列如下:

ABS_MT_SLOT 0

ABS_MT_POSITION_X x0

SYN_REPORT

slot 0对应的触摸点离开后,对应的事件序列如下:

ABS_MT_TRACKING_ID -1

SYN_REPORT

上一个被修改的slot也是0,所以ABS_MT_SLOT被省略掉。这一消息移除了触摸点45相关联的slot 0,于是接触点45被销毁,

slot 0 被释放后可以被另外一个接触点重用。

最后,第二个接触点离开后的时间序列如下:

ABS_MT_SLOT 1

ABS_MT_TRACKING_ID -1

SYN_REPORT

7、相同点:

两种类型的驱动通常都通过调用Input_sync()函数来标记一个多点触摸数据传送的结束,这通知接收者对

从上一个EV_SYN/SYN_REPORT以来的所有累加事件作出响应,并准备接收新的一组事件/数据包

8、不同点:

无状态的type A协议和有状态的type B slot协议之间的主要区别是通过识别相同触摸点来减少发送到用户空间

的数据量。slot协议需要使用到ABS_MT_TRACKING_ID,它可以由硬件来提供,或者通过原始数据进行计算得到。

附录:

static inline void input_mt_slot(struct input_dev *dev, int slot)

{

input_event(dev, EV_ABS, ABS_MT_SLOT, slot); // 此处 对于type B设备的驱动,在每个数据包的开始,通过调用input_mt_slot()进行分割,同时带入一个参数:slot。这会产生一个ABS_MT_SLOT事件,它通知接收者准备更新给定slot的信息。

}

void input_mt_report_slot_state(struct input_dev *dev,unsigned int tool_type, bool active)

{

struct input_mt_slot *mt;

int id;

if (!dev->mt || !active) {

input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1); //销毁触摸点

return;

}

mt = &dev->mt[dev->slot];

id = input_mt_get_value(mt, ABS_MT_TRACKING_ID);

if (id < 0 || input_mt_get_value(mt, ABS_MT_TOOL_TYPE) != tool_type)

id = input_mt_new_trkid(dev);

input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, id);//创建触摸点

input_event(dev, EV_ABS, ABS_MT_TOOL_TYPE, tool_type);

}

3
 条评论
相关内容推荐