触摸屏的输入事件
输入设备与输入事件
linux系统中将所有的输入设备统统交给 input Core(输入子系统)来管理和维护
即在Linux系统中任意的一个输入设备,都会被系统转换为输入事件
输入事件是 输入子系统 捕捉到输入设备状态发生变化后,向linux上报的一种输入结果
在上层应用开发中,输入事件由结构体 struct input_event来描述在头文件“linux/input.h"中定义
结构体原型如下(也就是说用户每触发一次输入事件,在应用程序中都能获取一个下列结构体的数据)
struct input_event {
struct timeval time;//记录了输入事件触发的时间
__u16 type;//记录了输入事件的类型
__u16 code;//记录了输入事件的编码
__s32 value;//记录了输入事件的值
};
```c
struct timeval {
__kernel_time_t tv_sec; /* seconds */记录秒钟
__kernel_suseconds_t tv_usec; /* microseconds */记录微秒
};
type:输入事件类型
Linux系统为了方便管理设备,在应用层是将所有的输入设备的事件,都交给struct input_event来描述,为了区分不同的输入设备,该结构体提供了type 成员变量,不同的输入设备type有不同的值,具体哪个值对应哪种设备请参考头文件"input-event-codes.h"
1.EV_SYN :同步事件,用户通过输入设备进行一次操作可以并不止产生一次输入事件
比如:手指触碰到触摸屏,其实已经触发了三次输入事件
手指触摸到触摸屏 ==》按键事件(把触摸屏当成一个触摸按键)
触摸点的x轴事件 ==》用来上报触摸点的x轴坐标
触摸点的y轴事件==》用来上报触摸点的y轴坐标
EV_SYN会在输入设备的一次输入动作的所有事件都上报后,会自动生成一次同步事件,用来告诉Linux本次动作结束
2.EV_KEY:按键事件
3.EV_ABS:绝对坐标事件
每种事件都有自己不同的事件编码,因为同一个输入动作可能产生不同的输入信息
比如:手指在触摸屏上滑动,x,y的坐标都会变化
每个事件都在头文件中提供了不同的事件编码 code
1.EV_KEY事件中BTN_TOUCH是触摸按键的事件编码
2.EV_ABS下的:
ABS_X 触摸点x轴的事件编码
ABS_Y 触摸点y轴的事件编码
code必须在type的前提下才能理解
value是表示该输入事件的值,不同输入事件中不同的事件编码值的含义不同,需要结合type和code来理解
比如:
type=EV_KEY code=BTN_TOUCH value=1 ==>手指在触摸屏上按下
type=EV_KEY code=BTN_TOUCH value=0 ==>手指在触摸屏上离开
type=EV_ABS code=ABS_X value=133
type=EV_ABS code=ABS_Y value=256 ==》表示手指目前处于(133.256)
获取输入事件
在Linux中获取事件非常简单,只需要三步:
1.打开输入事件文件 ==》触摸屏是"dev/input/event0"
2.从该文件中读取输入事件,存入到 struct input_event结构体便
3.从结构体中解析输入事件
end :关闭文件
/*************************************************
*头文件
*************************************************/
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/input.h>
int get_input_event(void)
{
int event_fd = 0;
ssize_t rsize = 0;
struct input_event ev;//用来保存从输入设备中获取到的的输入事件
event_fd =open("/dev/input/event0",O_RDWR);
if (-1 == event_fd)
{
perror("open event0 error");
}
while(1)
{
rsize = read(event_fd,&ev,sizeof(ev));
if (rsize == sizeof(ev))//读到了输入事件
{
printf("type:0x%2x\ncode:0x%2x\tvalue%d\n",ev.type,ev.code,ev.value);
}
}
}
int main(int argc, char const *argv[])
{
get_input_event();
return 0;
}
type:
0x03 EV_ABS 触摸屏事件
0x00 ABS_X
0X01 ABS_Y
0X01 EV_KEY 按键事件
0X14A BTN_TOUCH 触摸按键事件
0x00 EV_SYN 同步事件,表示本动作结束
上面截图的信息就表示了:
手指在 (570,479)处 按下,并立即松开了
任务:
0X01 ABS_Y
0X01 EV_KEY 按键事件
0X14A BTN_TOUCH 触摸按键事件
0x00 EV_SYN 同步事件,表示本动作结束
上面截图的信息就表示了:
手指在 (570,479)处 按下,并立即松开了
案例:获取触屏信息
/*************************************************
*头文件
*************************************************/
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/input.h>
int get_input_evnet(void)
{
int event_fd = 0;
ssize_t rsize = 0;
int start_x,start_y;
int end_x,end_y;
int x,y;
struct input_event ev; //保存 从输入设备中获取到的 输入事件
event_fd = open("/dev/input/event0",O_RDWR);
if(-1 == event_fd)
{
perror("open event0 error");
return -1;
}
while(1)
{
rsize = read(event_fd,&ev,sizeof(ev));
if(rsize == sizeof(ev)) //读到了 输入事件
{
printf("type:0x%2x\tcode:0x%2x\tvalue:%d\n",ev.type,ev.code,ev.value);
if(ev.type == EV_ABS && ev.code == ABS_X)
{
x = ev.value;
}
else if(ev.type == EV_ABS && ev.code == ABS_Y)
{
y = ev.value;
}
else if(ev.type == EV_KEY && ev.code == BTN_TOUCH)
{
if(ev.value == 1)
{
start_x = x;
start_y = y;
}
else if(ev.value == 0)
{
end_x = x;
end_y = y;
printf("本次触摸屏操作是在(%d,%d)处按下,在(%d,%d)处松开\n",start_x,start_y,end_x,end_y);
}
}
}
}
close(event_fd);
}
int main(void)
{
get_input_evnet();
}