免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2592 | 回复: 0
打印 上一主题 下一主题

Android 多点触摸接口 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-09-15 15:08 |只看该作者 |倒序浏览
Android 多点触摸接口




   使用说明
       单点触摸信息是以ABS承载并按一定顺序发送,如BTN_TOUCH、ABS_X、ABS_Y、SYNC。而多点触摸信息则是以ABS_MT承 载并按一定顺序发送,如ABS_MT_POSITION_X、ABS_MT_POSITION_Y,然后通过调用input_mt_sync()产生一个 SYN_MT_REPORT event来标记一个点的结束,告诉接收方接收当前手指的信息并准备接收其它手指的触控信息。最后调用 input_sync()函数上报触摸信息开始动作并告诉接收方开始接收下一系列多点触摸信息。

       协议定义了一系列ABS_MT事件,这些事件被分为几大类,充许只应用其中的一部份,多点触摸最小的事件集中应包括 ABS_MT_TOUCH_MAJOR、ABS_MT_POSITION_X和 ABS_MT_POSITION_Y,以此来实现多点触摸。如果设备支持ABS_MT_WIDTH_MAJOR这个事件,那么此事件可以提供手指触摸接触 面积大小。触摸方向等信息可以由ABS_MT_TOUCH_MINOR, ABS_MT_WIDTH_MINOR and ABS_MT_ORIENTATION提供。ABS_MT_TOOL_TYPE提供触摸设备的类别,如手或是笔或是其它。最后有些设备可能会支持 ABS_MT_TRACKING_ID,用来支持硬件跟踪多点信息,即该点属于哪一条线等。

       下面是两点触摸支持的最小事件集序列:

java代码:

  1. 01.ABS_MT_TOUCH_MAJOR

  2. 02.ABS_MT_POSITION_X

  3. 03.ABS_MT_POSITION_Y

  4. 04.SYN_MT_REPORT //上报第一个点

  5. 05.ABS_MT_TOUCH_MAJOR

  6. 06.ABS_MT_POSITION_X

  7. 07.ABS_MT_POSITION_Y

  8. 08.SYN_MT_REPORT //上报第二个点

  9. 09.SYN_REPORT //开始动作
复制代码
复制代码        Event 原语
        “接触”一词用来描述一个物体直接碰到另一个物体的表面。
         ABS_MT_TOUCH_MAJOR描述了主接触面的长轴,它和X,Y同一个单位,如果一个面的分辨率为X*Y,则 ABS_MT_TOUCH_MAJOR的最大值为sqrt(X^2+Y^2),ABS_MT_TOUCH_MINOR描述了接触面的短轴,如果接触面是圆形,它可以不用。ABS_MT_WIDTH_MAJOR描述了接触工具的长轴,ABS_MT_WIDTH_MINOR描述了接触工具的短轴。

java代码:
01.ABS_MT_TOUCH_MAJOR := max(X, Y)

02.ABS_MT_TOUCH_MINOR := min(X, Y)

03.ABS_MT_ORIENTATION := bool(X > Y)
复制代码  以上四个参数可以用来生成额外的触摸信息,如ABS_MT_TOUCH_MAJOR/ABS_MT_WIDTH_MAJOR的比率可以用来描述压力。
       ABS_MT_ORIENTATION
       ABS_MT_POSITION_X接触面的中心点X坐标
       ABS_MT_POSITION_Y接触面的中心点Y坐标
       ABS_MT_TOOL_TYPE描述接触工具类型,很多内核驱动无法区分此参数如手指及笔,如果是这样,该参数可以不用,协议目前支持MT_TOOL_FINGER和MT_TOOL_PEN两种类型。
       ABS_MT_BLOB_ID形状集ID,集合几个点以描述一个形状,很多驱动没有形状属性,此参数可以不用。
       ABS_MT_TRACKING_ID描述了从接触开始到释放的整个过程的集合,如果设备不支持,此参数可是不用。

       触摸轨迹
       仅有少数设备可以明触的标识真实的 trackingID,多数情况下 trackingID只能来标识一次触摸动作的过程。

       手势
       多点触摸指定的应用是创建手势动作, TOUCH和 WIDTH参数经常用来区别手指的压力和手指间的距离,另外 MINOR类的参数可以用来区别设备的接触面的大小(点接触还是面接触),ORIENTATION可以产生旋转事件。

       在Linux内核支持的基础上,Android在其2.0源码中加入多点触摸功能。由此触摸屏在Android的frameworks被完全分为2种实现途径:单点触摸屏的单点方式,多点触摸屏的单点和多点方式。

       在Linux的input.h中,多点触摸功能依赖于以下几个主要的软件位:

java代码:

  1. 01.#define SYN_REPORT0

  2. 02.#define SYN_CONFIG1

  3. 03.#define SYN_MT_REPORT2

  4. 04.

  5. 05.#define ABS_MT_TOUCH_MAJOR0x30/* Major axis of touching ellipse */

  6. 06.#define ABS_MT_TOUCH_MINOR0x31/* Minor axis (omit if circular) */

  7. 07.#define ABS_MT_WIDTH_MAJOR0x32/* Major axis of approaching ellipse */

  8. 08.#define ABS_MT_WIDTH_MINOR0x33/* Minor axis (omit if circular) */

  9. 09.#define ABS_MT_ORIENTATION0x34/* Ellipse orientation */

  10. 10.#define ABS_MT_POSITION_X0x35/* Center X ellipse position */

  11. 11.#define ABS_MT_POSITION_Y0x36/* Center Y ellipse position */

  12. 12.#define ABS_MT_TOOL_TYPE0x37/* Type of touching device */

  13. 13.#define ABS_MT_BLOB_ID0x38/* Group a set of packets as a blob */
复制代码
复制代码     在Android中对应的软件位定义在RawInputEvent.java中:

java代码:

  1. 01.public class RawInputEvent {

  2. 02.public static final int CLASS_TOUCHSCREEN_MT = 0x00000010;

  3. 03.

  4. 04.public static final int ABS_MT_TOUCH_MAJOR = 0x30;

  5. 05.public static final int ABS_MT_TOUCH_MINOR = 0x31;

  6. 06.public static final int ABS_MT_WIDTH_MAJOR = 0x32;

  7. 07.public static final int ABS_MT_WIDTH_MINOR = 0x33;

  8. 08.public static final int ABS_MT_ORIENTATION = 0x34;

  9. 09.public static final int ABS_MT_POSITION_X = 0x35;

  10. 10.public static final int ABS_MT_POSITION_Y = 0x36;

  11. 11.public static final int ABS_MT_TOOL_TYPE = 0x37;

  12. 12.public static final int ABS_MT_BLOB_ID = 0x38;

  13. 13.

  14. 14.public static final int SYN_REPORT = 0;

  15. 15.public static final int SYN_CONFIG = 1;

  16. 16.public static final int SYN_MT_REPORT = 2;
复制代码
复制代码     在Android中,多点触摸的实现方法在具体的代码实现中和单点是完全区分开的。在Android代码的EventHub.cpp中,单点屏和多点屏由如下代码段来判定:

java代码:

  1. 01.int EventHub::open_device(const char *deviceName){

  2. 02.

  3. 03.if (test_bit(ABS_MT_TOUCH_MAJOR, abs_bitmask)&& test_bit(ABS_MT_POSITION_X, abs_bitmask)

  4. 04.&& test_bit(ABS_MT_POSITION_Y, abs_bitmask)) {

  5. 05.device->classes |= CLASS_TOUCHSCREEN | CLASS_TOUCHSCREEN_MT;

  6. 06.//LOGI("It is a multi-touch screen!");

  7. 07.}

  8. 08.

  9. 09.//single-touch?

  10. 10.

  11. 11.else if (test_bit(BTN_TOUCH, key_bitmask)

  12. 12.&& test_bit(ABS_X, abs_bitmask)

  13. 13.&& test_bit(ABS_Y, abs_bitmask)) {

  14. 14.device->classes |= CLASS_TOUCHSCREEN;

  15. 15.

  16. 16.//LOGI("It is a single-touch screen!");

  17. 17.}

  18. 18.}
复制代码
复制代码   我们知道,在触摸屏驱动中,通常在probe函数中会调用input_set_abs_params给设备的input_dev结构体初始化,这些input_dev的参数会在Android的EventHub.cpp中被读取。如上可知,如果我们的触摸屏想被当成多点屏被处理,只需要在驱动中给input_dev额外增加以下几个参数即可:

java代码:

  1. 01.input_set_abs_params(mcs_data.input, ABS_MT_POSITION_X, pdata->abs_x_min, pdata->abs_x_max, 0, 0);

  2. 02.

  3. 03.input_set_abs_params(mcs_data.input, ABS_MT_POSITION_Y, pdata->abs_y_min, pdata->abs_y_max, 0, 0);

  4. 04.

  5. 05.input_set_abs_params(mcs_data.input, ABS_MT_TOUCH_MAJOR, 0, 15, 0, 0);

  6. 06.

  7. 07.//相当于单点屏的ABX_PRESSURE

  8. 08.

  9. 09.input_set_abs_params(mcs_data.input, ABS_MT_WIDTH_MAJOR, 0, 15, 0, 0);

  10. 10.

  11. 11.//相当于单点屏的ABS_TOOL_WIDTH
复制代码
复制代码     由于多点触摸技术需要采集到多个点,然后再一起处理这些点,所以在软件实现中需要保证每一波点的准确性和完整性。因此,Linux内核提供了input_mt_sync(struct input_dev * input)函数。在每波的每个点上报后需要紧跟一句input_mt_sync(), 当这波所有点上报后再使用input_sync()进行同步。例如一波要上报3个点:

java代码:

  1. 01./* 上报点1*/

  2. 02.input_mt_sync(input);

  3. 03.

  4. 04./* 上报点2*/

  5. 05.input_mt_sync(input);

  6. 06.

  7. 07./* 上报点3*/

  8. 08.input_mt_sync(input);

  9. 09.input_sync(input);
复制代码
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP