链接点击打开链接

关于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. vue2.0+ 从插件开发到npm发布

    vue: V2.5.11 此篇尽量详细,清楚的讲解vue插件的开发到npm的发布,想想将你自己做的东西展示给广大"网民",心里还是有点小激动的...-^_^ 先上一下插件效果图-- ...

  2. VMware在宿主上没有VMnet0、VMnet8,解决方法

    一开始,坐着上机实验,一直搞不通为什么虚拟机上的客户机可以ping通自己的ip也可以ping通自己本身的ip,但是主机ping不通虚拟机的客户机,也ping不通虚拟机的网关. 尝试了各种问题,也追出了 ...

  3. ubuntu部署mipsel64交叉编译环境

    最近找到个不错的交叉工具链,据传能够编译mipsel64的程序,决定试试. 首先当然是安装环境: apt install -y gcc libncursesada3-dev 下载,解压,进入 三部曲: ...

  4. 【python标准库模块五】Xml模块学习

    Xml模块 xml本身是一种格式规范,是一种包含了数据以及数据说明的文本格式规范.在json没有兴起之前各行各业进行数据交换的时候用的就是这个.目前在金融行业也在广泛在运用. 举个简单的例子,xml是 ...

  5. JavaScript Window Navigator

    window.navigator 对象包含有关访问者浏览器的信息. Window Navigator window.navigator 对象在编写时可不使用 window 这个前缀. 实例 <d ...

  6. 一些有用的Java参考资料

    Better Java,一些好的Java实践 Google Java Style Guide 30个Java编程技巧 JDK8新增语法特性简介,对Java8中新增的函数接口.Lambda表达式.方法引 ...

  7. ListView常见的优化方式简述

    ListView的优化 对于ListView来说,应该算是布局中几种最常用的组件之一了,使用也十分方便,下面个大家介绍一下两种常见的优化方式. 1.条目复用优化 其实listview的工作原理就是,l ...

  8. ZooKeeper之(二)数据模型

    ZooKeeper 会维护一个具有层次关系的数据结构,它非常类似于一个标准的文件系统: 树形结构的每个节点都被称作为Znode. Zonde通过路径引用,如同Unix中的文件路径.路径必须是绝对的,因 ...

  9. Android源码浅析(五)——关于定制系统,如何给你的Android应用系统签名

    Android源码浅析(五)--关于定制系统,如何给你的Android应用系统签名 今天来点简单的我相信很多定制系统的同学都会有一些特定功能的需求,比如 修改系统时间 静默安装 执行某shell命令 ...

  10. Java异常封装(自己定义错误码和描述,附源码)

    真正工作了才发现,Java里面的异常在真正工作中使用还是十分普遍的.什么时候该抛出什么异常,这个是必须知道的. 当然真正工作里面主动抛出的异常都是经过分装过的,自己可以定义错误码和异常描述. 下面小宝 ...