MTP-多点触摸协议信息获取

附:代码实例

多点触摸协议有两种,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

对于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 位于uapi/linux/input-event-codes.h
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


代码实例:

#include <stdio.h>  
#include <unistd.h>  
#include <sys/ioctl.h>  
#include <fcntl.h>  
#include <errno.h>  
#include <linux/input.h>  




struct Touch_info {
int ID;
char State;
int X;
int Y;
int W;
int H;
int Area;
};




int main( void )  
{  
    int fd;  
    fd_set rds;  
    int ret; 
int num =0; int flag;


int flag_a =1;
int flag_b =1;
int axis_x,axis_y;
    struct input_event  event; //触摸事件  


struct Touch_info Touch[3];


    fd = open( "/dev/input/event5", O_RDONLY );  
    if ( fd < 0 )  
    {  
        perror( "/dev/input/event5" );  
        return(-1);  
    }  
    while (1)  
    {  
        FD_ZERO( &rds );  
        FD_SET( fd, &rds );  
        /*调用select检查是否能够从/dev/input/event5设备读取数据*/  
        ret = select( fd + 1, &rds, NULL, NULL, NULL );  
        if ( ret < 0 )  
        {  
            perror( "select" );  
            return(-1);  
        }   
        else if ( FD_ISSET( fd, &rds ) )  
        {  
            ret = read( fd, &event, sizeof(struct input_event) );
if(ret < 0)
{
printf("read error");
return -1;
}
if (EV_KEY==event.type)                   
            {
if (event.code==BTN_TOUCH)
{
// printf("Touch[%d].State =  %d\n",num, event.value);
if(event.value)
{
flag =1;
}


}
}
if (EV_ABS==event.type)
{
if(event.code==ABS_MT_SLOT)
{
num = event.value;
}
switch(event.code)
{
case ABS_MT_POSITION_X :
Touch[num].X = event.value;
printf("Touch[%d].X =  %d\n",num, Touch[num].X);
break;
case ABS_MT_POSITION_Y :
Touch[num].Y = event.value;
printf("Touch[%d].Y =  %d\n",num, Touch[num].Y);
if(flag_a && flag_b)
{
printf("Touch[%d].H =  %d\n",num, 0);
printf("Touch[%d].W =  %d\n",num, 0);
}
break;
case ABS_MT_TRACKING_ID :
Touch[num].ID = event.value;
if(Touch[num].ID != -1)
{
printf("\n");
printf("TOUCH POINT COUNT: %d\n",num);
printf("Touch[%d].ID =  %d\n",num, Touch[num].ID);
if(flag)
{
printf("Touch[%d].State =  %s\n",num, "up");
}
}else{
printf("Touch[%d].ID =  %d\n",num, Touch[num].ID);
printf("Touch[%d].State =  %s\n",num, "DOWN");
}
break;
case ABS_MT_WIDTH_MAJOR :
Touch[num].H = event.value;
printf("Touch[%d].H =  %d\n",num, Touch[num].H);
flag_a = 0;
break;
case ABS_MT_WIDTH_MINOR :
Touch[num].W = event.value;
printf("Touch[%d].W =  %d\n",num, Touch[num].W);
flag_b = 0;
break;
#if 0
case ABS_MT_TOUCH_MAJOR :
axis_x = event.value/2;
break;
case ABS_MT_TOUCH_MINOR :
axis_y = event.value/2;
printf("Touch[%d].Area = %0.2f\n",num, 3.14*axis_x*axis_y);
#endif
}
}
}  
        }

    close( fd );  
    return(0);  
}  

猜你喜欢

转载自blog.csdn.net/weixin_42164528/article/details/80242040