触摸屏的使用

本文详细介绍了Linux系统中触摸屏的实现机制,包括如何通过文件系统操作触摸屏,以及输入事件的结构、类型和编码。重点讲解了EV_KEY,EV_REL,EV_ABS等事件类型和它们在处理键盘、鼠标和触摸屏输入时的作用。
摘要由CSDN通过智能技术生成

触摸屏的使用
        在Linux中,触摸屏是什么?
                是文件,操作触摸屏其实就是操作文件(对于上层应用来说),可以使用操作文件的接口(open/read/close)去操作触摸屏
        文件名(gec6818):
"/dev/input/event0"

                   (gec210):"/dev/event0"

在linux系统把所有的输入都封装为一个"输入事件"的结构体,都归属于linux输入子系统管理,linux输入子系统管理所有的输入设备,当输入设备发生输入信息的时候,会把输入信息包装为一个"输入事件"的结构体,再把结构体放到对应的文件中去

APP   <--------->  OS(linux)  <---------->  驱动   <------------>   Hardware

键盘

鼠标

触摸屏

手柄

.....

都是输入设备,都归结到输入子系统

对于APP,所有的设备都是以文件的方式去操作的

APP可以获取"输入事件"

输入设备发生的输入都会包装成为一个"输入事件(描述事件的数据)(struct input_event)",把输入事件保存到对应的文件(键盘,鼠标,触摸屏)中

任何设备发生的输入,都会包装成对应的事件保存到发生输入的"设备文件"中

用户如果需要获取输入信息,只需要打开对应的设备文件,读取结构体的内容即可:

(触摸屏和显示屏是两个独立的设备) 内屏:显示屏       外屏:触摸屏
        操作的大概步骤: 
                1. 打开文件
                2. 读取对应输入事件(结构体)
                3. 解析结构体
                4. 关闭文件

输入事件是如何封装的?
        在Linux中,使用了一个结构体来描述输入事件(
struct input_event)

        定义在内核的头文件中(<linux/input.h>
        vim  /usr/include/linux/input.h

键盘事件

/*
 *  The event structure itself
 */

struct input_event {
    struct timeval time;    // 时间,记录了事件发生的时间
    __u16 type;             // unsigned  short  事件的类型
    __u16 code;             // 事件的编码,根据事件的类型解析
    __s32 value;            // 事件的值,根据type的不同,有不同的含义
};

 __u16 type; // unsigned  short 事件的类型
             // 判断是什么设备发生的这个事件。这些数据应该写入哪一个设备文件

Linux把所有的输入都进行了分类,不同的类型使用不同的“宏”表示
    常见的:
         #define EV_KEY      0x01    // 按键事件(键盘事件)
         #define EV_REL      0x02    // 相对坐标事件(鼠标移动)
         #define EV_ABS      0x03    // 绝对坐标事件(触摸屏点的位置)
         ......

__u16 code;   // 事件的编码,根据事件的类型解析
    随着type的不同,code有不同的解释
        如:
            if (type == EV_KEY)
            code表示键盘的键值,国际标准化组织,给每一个按键都分配了一个值
            #define KEY_A            30
            #define KEY_S            31
            #define KEY_D            32
            #define KEY_F            33
            #define KEY_G            34
            #define KEY_H            35
            #define KEY_J            36
            #define KEY_K            37
            #define KEY_L            38
            ......
            
            有时候也会把触摸屏整体当做一个按键
            #define BTN_TOUCH  0x14a
            (判断手指是否离开屏幕)
            ...
            
        value表示具体的操作(按键的状态):
            value == 0  松开    
            value == 1  按下
            ...
 
在虚拟机中, /dev/input/event1 表示键盘

当按键发生按键事件的时候,Linux输入子系统会把这个事件包装为结构体
写入到对应的文件中去,我们只需要读取事件结构体就可以了
鼠标事件                                                                                                                                   
if (type == EV_REL)   此时code表示为相对(相对上一次)坐标事件
    鼠标移动的时候,新的位置会相对于之前的位置有一个变化(轨迹)
    鼠标移动一次,至少产生两个事件,坐标分为x和y
    读取鼠标的移动,至少需要两个事件辅助
    每一次的事件都和上一次的有关系

    如:
        x轴相对原来的位置偏移了多少
        y轴相对原来的位置偏移了多少

    code表示相对坐标轴向
        #define REL_X            0x00
        #define REL_Y            0x01
        ...

    当ev.type == EV_REL && ev.code == REL_X
        此事件结构体中的value表示x轴相对于原来的位置偏移了多少
    当ev.type==EV_REL && ev.code==REL_Y
        此事件结构体中的value表示y轴相对于原来的位置偏移了多少    

    value表示具体的偏移量(可正可负)
  触摸屏事件                                                                                                              
if (type == EV_ABS)   此时code表示为绝对(绝对的)坐标事件
触摸屏点击屏幕的时候,这次的位置和上次的位置没有关系,只需要说明当前位置的绝对坐标即可

整个屏幕所有的像素点其实是一个二维坐标系,只要能够描述点的位置即可
每一次发生的输入和上次没有关系

    code表示绝对坐标轴向
        #define ABS_X            0x00
        #define ABS_Y            0x01
        ...
        #define  ABS_PRESSURE   0x18
        // 压力值(判断手指是否离开屏幕)
        
        当ev.type == EV_ABS && ev.code == ABS_X 
            此事件结构体中的value表示x轴的值是多少
        当ev.type == EV_ABS && ev.code == ABS_Y
            此事件结构体中的value表示y轴的值是多少
        当ev.type == EV_ABS && ev.code == ABS_PRESSURE 
            ---->这个事件去掉了,驱动里面没有了,不可再用
            此事件结构体中的value表示压力值 

        value表示具体的坐标(>=0)

触摸屏的分辨率可能和显示屏的分辨率不一样,没有一一对应
            触摸屏:1024*600     x*y
            显示屏:800*480       x0*y0
            需要做一个等比例的缩放:
            x/1024 = x0/800   ===>x0 = 1.0 * x / 1024 * 800     注意:乘以1.0
            y/600 = x0/480     ===>y0 = 1.0 * y / 600 * 480       注意:乘以1.0

手指没有离开触摸屏,一直都在产生输入事件,多个struct input_event可以确定一个点

获取触摸屏上一个点的坐标

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>

int main(int argc, char *argv[]) 
{
    // 打开文件
    int fd = open("/dev/input/event0", O_RDONLY);
    if (-1 == fd)
    {
        perror("open failed");
        return -1;
    }

    struct input_event ev; // 保存读取到的输入事件
    int x, y;
    while (1) 
    {
        // 读取输入事件
        int r = read(fd, &ev, sizeof(ev));
        if (r != sizeof(ev)) {
            continue;
        }
        // 解析输入事件
        if (ev.type == EV_ABS && ev.code == ABS_X) {
            x = ev.value * 1.0 / 1024 * 800;
        }
        if (ev.type == EV_ABS && ev.code == ABS_Y) {
            y = ev.value * 1.0 / 600 * 480;
        }
        // 手指离开屏幕的时候,退出循环
        if (ev.type == EV_KEY && ev.code == BTN_TOUCH && ev.value == 0) {
            break;
        }
        // 手指离开屏幕的时候,退出循环,这个事件去掉了,不可再用
        // if (ev.type == EV_ABS && ev.code == ABS_PRESSURE && ev.value == 0) {
        //     break;
        // }
    }

    printf("x = %d,y = %d\n", x, y);

    // 关闭文件
    close(fd);

    return 0;
}

获取手指滑动的方向:

   

  • 20
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值