linux读取触摸屏事件数据

7 篇文章 0 订阅

对于有触摸设备的电脑或者手机,通过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 <stdio.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
#include <linux/input.h>

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 <stdio.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
#include <linux/input.h>
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   松开

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 22
    点赞
  • 84
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
Linux系统中,触摸屏事件是指当触摸屏触摸或者发生其他状态改变时,系统会生成相应的事件。这些事件可以通过读取触摸屏设备文件来获取。触摸屏Linux系统中被当作一个文件,其设备文件名为/dev/input/event0。触摸屏事件的处理可以通过编写相关的代码来实现。 在处理触摸屏事件的代码中,可以使用struct input_event结构体来存储从设备文件中读取到的数据。通过读取设备文件的数据,并判断事件的类型和属性,可以确定是否发生了触摸屏的松手事件。 下面是一个示例代码,用于处理触摸屏事件: ``` int main(int argc, char *argv[]) { // 1. 打开触摸屏设备文件 int fd = open("/dev/input/event0", O_RDONLY); if (fd < 0) printf("open event0 error!\n"); struct input_event buf; while(1) { // 2. 将文件的数据读取到结构体中 read(fd, &buf, sizeof(buf)); // 3. 判断这些数据 // 如果以下三个条件都成立,说明发生了松手事件 if (buf.type == EV_KEY && buf.code == BTN_TOUCH && buf.value == 0) { // 4. 做出反应 printf("your hand leave lcd!\n"); } } // 5. 关闭文件。 close(fd); return 0; } ``` 以上代码示例中,打开了触摸屏设备文件并循环读取事件数据。通过判断读取到的数据的类型、代码和值,确定是否发生了松手事件,并进行相应的处理。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [第十八篇,Linux系统IO应用--触摸屏](https://blog.csdn.net/weixin_44651073/article/details/123137523)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值