linux触摸屏(一)编写触摸屏应用

linux触摸屏(一)编写触摸屏应用

linux触摸屏

linux触摸屏(一)编写触摸屏应用

linux触摸屏(二)使用tslib

触摸屏驱动一般是采用input子系统驱动框架实现的,所以应用层接口要遵循input框架的接口,在介绍触摸屏应用编写前,先来学习input应用编程

一、使用hexdump读取input设备

在Linux下查看ls /dev/input,可以看到现在有的输入设备

比如我的结果是

# ls /dev/input/
event0  event1  event2  mice    mouse0  mouse1

这些都是通过input子系统实现的输入设备驱动,遵循input子系统规范

其中event2为我的触摸屏设备节点,通过下面命令读取(hexdump读取的数是以16进制打印)

# hexdump /dev/input/event2

当我点击触摸屏然后松开,发现控制台打印了许多消息

0247 0000 00d3 000e 0003 0000 02c4 0000
0247 0000 00db 000e 0003 0001 0181 0000
0247 0000 00de 000e 0001 014a 0001 0000
0247 0000 00e0 000e 0003 0018 0001 0000
0247 0000 00e2 000e 0000 0000 0000 0000
0248 0000 c838 0002 0001 014a 0000 0000
0248 0000 c876 0002 0003 0018 0000 0000
0248 0000 c89f 0002 0000 0000 0000 0000

其中每一行都表示一个input事件,如果单纯这样子看是分析不出所以然的,我们需要先介绍input事件,然后再来分析

二、input事件分析

input事件结构体的定义如下,在Linux内核的include\linux\input.h文件中

struct timeval {
    __kernel_time_t     tv_sec;     /* seconds,32bit */
    __kernel_suseconds_t    tv_usec;    /* microseconds,32bit */
};
​
struct input_event {
    struct timeval time; //时间
    __u16 type; //事件类型
    __u16 code; //事件键值
    __s32 value; //值
};

可以看到,每一个input事件都有一个时间,包含32位的秒,32位的微妙

此外还有16位的type(事件类型),16位的code(事件键值),32位的value(值)

好,现在又有疑惑,type、code、value具体是什么?

type

type是指事件类型,在include\linux\input.h文件中定义了一系列的事件类型

#define EV_SYN          0x00 //同步事件,用于分隔事件
#define EV_KEY          0x01 //按键事件,例如按键、鼠标按键、触摸屏按键
#define EV_REL          0x02 //相对位置事件,常见于鼠标坐标
#define EV_ABS          0x03 //绝对位置事件,常见于触摸屏坐标
...

一个设备可以有多种类型的事件,例如鼠标点击按键时会上报按键事件,移动时会上报相对位置事件

code

code指事件的键值,在事件类型中的子事件,每一个事件类型都有其对应的一系列键值

例如按键事件,那么你这个按键表示按键1还是按键2还是鼠标左键

例如绝对位置事件,那么你上报的这个事件是指X轴还是Y轴

include\linux\input.h文件中定义了一系列的事件键值

  • 按键事件的键值

    #define KEY_1           2
    #define KEY_2           3
    #define KEY_3           4
    ...
    #define KEY_A           30
    #define KEY_S           31
    #define KEY_D           32
    ...

  • 相对位置事件的键值

    #define REL_X           0x00 //x轴
    #define REL_Y           0x01 //y轴
    #define REL_Z           0x02 //z轴
    #define REL_RX          0x03
    #define REL_RY          0x04
    #define REL_RZ          0x05
    #define REL_HWHEEL      0x06
    #define REL_DIAL        0x07
    #define REL_WHEEL       0x08
    #define REL_MISC        0x09

  • 绝对位置事件

    #define ABS_X           0x00
    #define ABS_Y           0x01
    #define ABS_Z           0x02
    ...
    #define ABS_PRESSURE        0x18
    ...

还有其他的事件类型这里就不详述了

value

value是code(键值)对应的值,其解释随code类型的变化而变化

例如在按键事件中,如果code表示按键1,那么value等于1表示按键1按下,等于0等于按键1未按下

在绝对位置事件中,如果code表示X轴坐标,那么value就表示触摸点在X轴坐标的位置

到这里应该就对input事件的理解很清除了,有了这些理解,下面我们来解析一下上面使用hexdump读取到的数据

由于前64位表示的是事件,所以这里就不解析了

    s        |us       |type|code|value
1: 0247 0000 00d3 000e 0003 0000 02c4 0000 //EV_ABS、ABS_X、708
2: 0247 0000 00db 000e 0003 0001 0181 0000 //EV_ABS、ABS_Y、385
3: 0247 0000 00de 000e 0001 014a 0001 0000 //EV_KEY、BTN_TOUCH、1
4: 0247 0000 00e0 000e 0003 0018 0001 0000 //EV_ABS、ABS_PRESSURE、1
5: 0247 0000 00e2 000e 0000 0000 0000 0000 //EV_SYN
6: 0248 0000 c838 0002 0001 014a 0000 0000 //EV_KEY、BTN_TOUCH、0
7: 0248 0000 c876 0002 0003 0018 0000 0000 //EV_ABS、ABS_PRESSURE、0
8: 0248 0000 c89f 0002 0000 0000 0000 0000 //EV_SYN

1:绝对位置事件,X轴708处

2:绝对位置事件,Y轴385处

3:按键事件,触摸屏按键,1表示按下

4:绝对位置事件,绝对位置按压,压力为1(有些触摸屏是有压力检测的,这款触摸屏没有所以直接上报了1)

5:同步事件,用于分隔

6:按键事件,触摸屏按键,0表示松开

7:绝对位置事件,绝对位置按压,压力为0,表松开

8:同步事件

三、触摸屏应用编程

搞清除input事件后,编写一个应用其实非常简单,以触摸屏为例子,我们可以直接读取struct input_event对象,然后根据typecodekey来解析

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <linux/input.h>
​
int main(int argc, char* argv[])
{
    if(argc != 2)
    {
        printf("Usage: %s <input dev>\n", argv[0]);
        return -1;
    }
​
    int fd = open(argv[1], O_RDONLY);
    if(fd < 0)
    {
        printf("failed to open %s\n", argv[1]);
        return -1;
    }
​
    struct input_event event;
    int x = 0, y = 0;
    while(1)
    {        
        memset(&event, 0, sizeof(event));
        read(fd, &event, sizeof(event));
        if(event.type == EV_SYN)
            continue;
​
        if(event.type == EV_ABS)
        {
            if(event.code == ABS_X)
                x = event.value;
            else if(event.code == ABS_Y)
                y = event.value;
        }
        else if(event.type == EV_KEY)
        {
            if(event.value == 1)
            {
                printf("touch press (%d,%d)\n", x, y);
            }
            else if(event.value == 0)
            {
                printf("touch release (%d,%d)\n", x, y);
                x = 0;
                y = 0;
            }
        }
        else
            continue;
    }
​
    close(fd);
return 0;

}

转载自:

https://blog.csdn.net/weixin_42462202/article/details/84963795

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
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 ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值