链接点击打开链接

关于Linux多点触摸协议大家可以参考kernel中的文档:https://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt,而这里根据实际的例子来理解多点触摸协议。

多点触摸协议有两种,A协议和B协议。

首先来看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

如果第一个触点离开(抬起),这里的意思是说还有一个触点,需要继续上报这个触点。

        ABS_MT_POSITION_X x[1]
        ABS_MT_POSITION_Y y[1]
        SYN_MT_REPORT
        SYN_REPORT

如果两个触点都离开了,那么只需要报告一个同步事件就可以了。

        SYN_MT_REPORT
        SYN_REPORT

而代码示例如下:

[cpp] view plain copy
  1. for (i = 0; i < count; i++) {
  2. input_report_abs(input_dev, ABS_MT_POSITION_X, finger[i].x);
  3. input_report_abs(input_dev, ABS_MT_POSITION_Y, finger[i].x);
  4. input_mt_sync(input_dev);
  5. }
  6. if (!count)
  7. input_mt_sync(input_dev);
  8. input_sync(input_dev);

其中count值表示触点个数,如果是2个,那么这里值就为2,如果所有触点都离开了,那么count值就为0。

上面可以说是最简单,也是最基本的A协议报点了。除了报点以外,我们也来关注一下input device注册时需要setting的一些东西。

[cpp] view plain copy
  1. input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, MAX_X, 0, 0);
  2. input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, MAX_Y, 0, 0);
  3. __set_bit(EV_SYN, input_dev->evbit);
  4. __set_bit(EV_ABS, input_dev->evbit);
  5. __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);

可能你会看到有的代码会多下面这两句:

[cpp] view plain copy
  1. __set_bit(ABS_MT_POSITION_X, input_dev->absbit);
  2. __set_bit(ABS_MT_POSITION_X, input_dev->absbit);

其实这两句(包括上面的__set_bit(EV_ABS, input_dev->evbit);)是可有可无的,因为在input_set_abs_params函数中会做相应的设置。

而这句__set_bit(INPUT_PROP_DIRECT, input_dev->propbit);也是必须要有的,否则在Android中会出现一个白色小圆环,感觉像是缺少idc文件一样。最后通过getevent -p命令看一下触摸屏的setting。

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

对于B协议就稍微显得有点复杂。B协议需要硬件支持,和A协议主要区别在哪里呢?B协议可以使用一个ID来标识触点,可以减少上报到用户空间的数据量,这个ID(ABS_MT_TRACKING_ID)可以有硬件提供或者从原始数据计算而得。那>么下面我们就来看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

如果触点45只是在x方向做了移动,那么应该怎么报告这个事件呢?

        ABS_MT_SLOT 0
        ABS_MT_POSITION_X x[0]
        SYN_REPORT

可以看到减少了很多数据的上报,这就是同A协议最大的区别。

如果同slot 0相关的触点离开(抬起),只需要做下面的操作。
        ABS_MT_TRACKING_ID -1
        SYN_REPORT

这里为什么没有发送ABS_MT_SLOT 0事件呢,因为之前slot已经被置成了0,再次发送ABS_MT_SLOT 0是会被忽略掉的。

如果第二个触点被抬起,发送下面的事件序列。

        ABS_MT_SLOT 1
        ABS_MT_TRACKING_ID -1
        SYN_REPORT

其他event
ABS_MT_POSITION_X和ABS_MT_POSITION_Y是多点触摸协议的最小事件集,是最基本的事件,也是必须的事件。除此之外呢,还包括下面的一些时间集(需要设置支持):
ABS_MT_TOUCH_MAJOR
ABS_MT_TOUCH_MINOR
ABS_MT_TOUCH*用来表示接触点区域大小(即手指与玻璃接触区域大小),通常接触区域是一个椭圆形状,那么MAJOR就表示椭圆的长轴,而MINOR就表示椭圆的短轴。如果接触区域是圆形的话,那么可以忽略MINOR,而MAJOR就表示圆形的直径大小。

ABS_MT_WIDTH_MAJOR
ABS_MT_WIDTH_MINOR
上面的TOUCH表示接触区域的大小,而WIDTH则表示为接触工具的大小(例如手指,触控笔等)。

ABS_MT_PRESSURE
而PRESSURE表示压力值,这个压力值可以通过上面的4个参数计算而得,例如:ABS_MT_TOUCH_MAJOR/ABS_MT_WIDTH_MAJOR,可以看到接触面积越大,压力值也就越大。当然这个压力值也可以直接由设备提供。

ABS_MT_DISTANCE
触点与接触面的距离,0表示触点在接触面的表面(已经实实在在的接触到了),而正数表示在接触面的上方。

ABS_MT_ORIENTATION
触点的方向。

ABS_MT_TOOL_X
ABS_MT_TOOL_Y
ABS_MT_TOOL_TYPE

关于上报虚拟按键值
通常触摸屏下方都有3个虚拟按键,而这3个按键同其它实体按键(例如:power按键、音量按键)又有所不同,它是触摸屏提供的一组虚拟按键,我们通过触摸屏会得到这一组按键的坐标值,可以通过这个坐标值上报相应的按键值来实
现按键功能,那么怎么来上报这个按键值呢。首先需要对input设备做一些setting:

[cpp] view plain copy
  1. __set_bit(KEY_MENU, input_dev->keybit);
  2. __set_bit(KEY_HOMEPAGE, input_dev->keybit);
  3. __set_bit(KEY_BACK, input_dev->keybit);
  4. __set_bit(EV_KEY, input_dev->evbit);
  5. __set_bit(EV_SYN, input_dev->evbit);

OK,这些键值呢在kernel中是定义在uapi/linux/input.h中的,而通常我们的driver只需要包含linux/input.h就可以了,这个文件中include了的uapi/linux/input.h。

好的,再来看怎么上报键值。
按键按下:

[cpp] view plain copy
  1. input_report_key(input_dev, key_value, 1);
  2. input_sync(input_dev);

按键抬起:

[cpp] view plain copy
  1. input_report_key(input_dev, key_value, 0);
  2. input_sync(input_dev);

如果是按键一直被按下,重复上报按键被按下那部分就可以了。

有的地方可能会看到直接使用input_event函数,例如:

[cpp] view plain copy
  1. input_event(input_dev, EV_KEY, key_value, 1);

大家也可以去看看input_report_key函数,它其实是对input_event函数做了封装,不管是input_report_abs也好,还是input_sync,最终都是调用的input_event函数,所以真正上报event的函数其实是input_event函数。

最后一点在setting时除了__set_bit之外,可能还会看到另外一个函数input_set_capability,这个函数实现在drivers/input/input.c中,而它最终还是调用了__set_bit函数,所以最后效果都是一样的。

Linux/Android多点触摸协议的更多相关文章

  1. Linux & Android 多点触摸协议

    Linux & Android 多点触摸协议 Android4.0多点触摸入门 1 KERNEL 对于触摸屏的驱动我们简单的划分为两个主要的部分,一个是注册,另一个是上报. 1.1 注册 单点 ...

  2. Linux/Android多点触摸协议【转】

    本文转载自: 链接点击打开链接 关于Linux多点触摸协议大家可以参考kernel中的文档:https://www.kernel.org/doc/Documentation/input/multi-t ...

  3. Linux Android 多点触摸协议 原文出自【比特网】,转载请保留原文链接:http://soft.chinabyte.com/os/71/12306571.shtml

    为了使用功能强大的多点触控设备,就需要一种方案去上报用户层所需的详细的手指触摸数据.这个文档所描述的多点触控协议可以让内核驱动程序向用户层上报任意多指的数据信息. 使用说明 单点触摸信息是以ABS承载 ...

  4. Linux与Android 多点触摸协议【转】

    本文转载自:http://blog.csdn.net/xubin341719/article/details/7833277 一.Linux与Android 多点触摸协议 为了使用功能强大的多点触控设 ...

  5. Android 中多点触摸协议

    http://blog.csdn.net/zuosifengli/article/details/7398661 Android 中多点触摸协议: 参考: http://www.kernel.org/ ...

  6. 内核中的多点触摸协议文档 Multi【转】

    转自:http://www.arm9home.net/read.php?tid=24754 前段时间改写了一个GT801的内核驱动,仔细阅读 MT Event 上报的时候,发现这个驱动是针对 Andr ...

  7. CTP多点触摸协议【转】

    转自:http://blog.chinaunix.net/uid-26403844-id-5063920.html linux kernel 2.6.30开始对多点触摸支持,最近高通要求所有CTP器件 ...

  8. Android多点触摸放大缩小图片

    1.Activity package com.fit.touchimage; import android.app.Activity; import android.graphics.Bitmap; ...

  9. 搞定android多点触摸模拟

    原理在android 创建多点触摸虚拟设备,然后往设备写模拟数据可以

随机推荐

  1. Java面试16|设计模式

    1.单例模式: 确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 单例模式有以下几个要素: 私有的构造方法 指向自己实例的私有静态引用 以自己实例为返回值的静态的公有的方法 单例模式根 ...

  2. 第一次作业:基于Linux操作系统深入源码进程模型分析

    1.Linux操作系统的简易介绍 Linux系统一般有4个主要部分:内核.shell.文件系统和应用程序.内核.shell和文件系统一起形成了基本的操作系统结构,它们使得用户可以运行程序.管理文件并使 ...

  3. jQuery 学习笔记一

  4. mybatis映射器配置细则

    前面三篇博客我们已经多次涉及到映射器的使用了,增删查基本上都用过一遍了,但是之前我们只是介绍了基本用法,实际上mybatis中映射器可以配置的地方还是非常多,今天我们就先来看看映射器还有哪些需要配置的 ...

  5. Bootstrap3 排版-标题

    HTML 中的所有标题标签,<h1> 到 <h6> 均可使用.另外,还提供了 .h1 到 .h6 类,为的是给内联(inline)属性的文本赋予标题的样式. h1. Boots ...

  6. python语言学习

    前段时间要做视频直播需要编写自动模块,就考虑使用python脚本语言,python的好多语法都是很独特的,比如数据类型不需要预定义,缩进的方式等,另外功能也很强大,豆瓣就是用python写的.我写的部 ...

  7. Dynamics CRM2016 Web API之Create related entities in one operation

    本篇继续来介绍两个web api的接口,一个是"Create related entities in one operation"即在一步操作中完成主实体的创建加关联实体的创建,一 ...

  8. cassandra 监控方案评估

    摘要 最开始做cassandra monitor 方案的选型时,主要是从cassandra 本身入手,后来发现cassandra运行在JVM上,所有的metrics都是通过JMX 暴露出来.所以又可以 ...

  9. zk日常运维管理

    清理数据目录 dataDir目录指定了ZK的数据目录,用于存储ZK的快照文件(snapshot).另外,默认情况下,ZK的事务日志也会存储在这个目录中.在完成若干次事务日志之后(在ZK中,凡是对数据有 ...

  10. springmvc的介绍和第一个例子

    SpringMVC是Spring 框架自带的一部分. SpringMVC底层基于:Servlet Struts2底层基于:filter struts1底层基于:Servlet spring 各模块 我 ...