对于有触摸设备的电脑或者手机,通过cat /proc/bus/input/devices应该就能够看到触摸设备的相关信息。比如
~ # cat /proc/bus/input/devices
I: Bus=0013 Vendor=0x0012 Product=0x1200 Version=0101
N: Name="TouchScreen"
P: Phys=
S: Sysfs=/devices/virtual/input/input0
U: Uniq=
H: Handlers=event0
B: EV=b
B: KEY=0
B: ABS=1000003
上面的信息有触摸屏vid,pid,版本等,以及ABS表示触摸屏的绝对坐标掩码,掩码上面表示16进制,所以
0x1000003=0001 0000 0000 0000 0000 0000 0011,其中为1的比特的位置就表示触摸屏会报告这一类型的事件,前面bit0和bit1以及bit24为1,那么看linux/input.h文件就表示事件code码有ABS_X=0x00 , ABS_Y=0x01, ABS_PRESSURE=0x18,这三个分别表示触摸屏报告触摸的x坐标,y坐标,以及按下和松开。
但是不同的触摸屏的x,y坐标的范围不一定,所以需要通过input_absinfo结构体去记录得到触摸屏的绝对值信息。
struct input_absinfo {
__s32 value;//这个轴最后一次报告的坐标值
__s32 minimum;//这个轴的坐标最小值
__s32 maximum;//这个轴的坐标最大值
__s32 fuzz;
__s32 flat;
__s32 resolution;
};
得到触摸屏的绝对值信息的代码如下:
#include
#include
#include
#include
#include
#include
int main()
{
struct input_absinfo absI;
int ret;
int fd=-1;
fd = open("/dev/input/event0",O_RDONLY);
if(fd<0){
perror("/dev/input/event0");
return -1;
}
//得到X轴的abs信息
ioctl(fd,EVIOCGABS(ABS_X),&absI);
printf("x abs lastest value=%d\n",absI.value);
printf("x abs min=%d\n",absI.minimum);
printf("x abs max=%d\n",absI.maximum);
//得到y轴的abs信息
ioctl(fd,EVIOCGABS(ABS_Y),&absI);
printf("y abs lastest value=%d\n",absI.value);
printf("y abs min=%d\n",absI.minimum);
printf("y abs max=%d\n",absI.maximum);
//得到按压轴的abs信息
ioctl(fd,EVIOCGABS(ABS_PRESSURE),&absI);
printf("pressure abs lastest value=%d\n",absI.value);
printf("pressure abs min=%d\n",absI.minimum);
printf("pressure abs max=%d\n",absI.maximum);
close(fd);
return 0;
}
结果如下,可以看到x,y方向的触摸值范围都是0~1023,触摸屏按下松开的取值分别是1,0
x abs lastest value=315
x abs min=0
x abs max=1023
y abs lastest value=257
y abs min=0
y abs max=1023
pressure abs lastest value=0
pressure abs min=0
pressure abs max=1
接着通过linux/input.h里面提供的函数得到触摸屏的事件报告。
#include
#include
#include
#include
#include
#include
int main( void )
{
int fd;
fd_set rds;
int ret;
struct input_event event;
struct timeval time;
fd = open( "/dev/input/event0", O_RDONLY );
if ( fd < 0 )
{
perror( "/dev/input/event0" );
return(-1);
}
while ( 1 )
{
FD_ZERO( &rds );
FD_SET( fd, &rds );
/*调用select检查是否能够从/dev/input/event0设备读取数据*/
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) );
time = event.time;
printf( "timeS=%d,timeUS=%d,type=%d,code=%d,value=%d\n", time.tv_sec, time.tv_usec, event.type, event.code, event.value );
}
}
/*关闭设备文件句柄*/
close( fd );
return(0);
}
触摸一下触摸屏,得到下面的事件报告,timeS和timeUS是发生报告的事件,对于PC的话一般是从1970到现在的时间,对于我的开发板的话是系统启动开始到报告的时间。
type的话是事件类型,为3就是EV_ABS=0x03,为0就是EV_SYN=0x00(用来作为事件的分隔)
code的话根据事件类型而定,如果是EV_ABS的话,那么code就从ABS_XXX中去找,type为EV_ABS,code为0就是ABS_X,code为1就是ABS_Y,code为24就是ABS_PRESSURE,这些都可以在linux/input.h里面找到,然后value就是在type和code的前提下的值,比如type为EV_ABS,code为ABS_X,那么value就代表触摸点的x轴绝对值。
timeS=3143,timeUS=415046,type=3,code=0,value=325 触摸x轴值
timeS=3143,timeUS=415082,type=3,code=1,value=599 触摸y轴值
timeS=3143,timeUS=415092,type=3,code=24,value=1 按下
timeS=3143,timeUS=415098,type=0,code=0,value=0 同步
timeS=3143,timeUS=430129,type=3,code=0,value=323 触摸x轴值
timeS=3143,timeUS=430169,type=3,code=1,value=592 触摸y轴值
timeS=3143,timeUS=430183,type=0,code=0,value=0 同步
timeS=3143,timeUS=445130,type=3,code=24,value=0 松开