原子学习笔记6——使用tslib库

一、tslib介绍

tslib 是专门为触摸屏设备所开发的 Linux 应用层函数库,并且是开源。
tslib 为触摸屏驱动和应用层之间的适配层,它把应用程序中读取触摸屏 struct input_event 类型数据(这是输入设备上报给应用层的原始数据)并进行解析的操作过程进行了封装,向使用者提供了封装好的 API 接口。

二、tslib 移植

首先进入到 tslib 的 git 仓库下载源码tslib下载地址
下载 1.16 版本的 tslib,往下翻找到 1.16 版本的下载链接:
在这里插入图片描述
点击红框字样进入下载页面:
在这里插入图片描述
下载 tar.gz 格式的压缩包文件,点击文字即可下载。

三、编译 tslib 源码

解压tslib-1.16.tar.gz 源码包
在这里插入图片描述
解压之后会生成 tslib-1.16 目录,tslib包目录下创建一个 tools 目录,然后在 tools 目录下创建 tslib 目录,等会编译 tslib 库的时候将安装目录指定到这里,如下所示:
在这里插入图片描述
进入到 tslib-1.16 目录,准备进行编译 tslib 源码:
在这里插入图片描述
首先在配置工程之前,先对交叉编译工具的环境进行设置

source /opt/fsl-imx-x11/4.1.15-2.1.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabi

执行下面这条命令对 tslib 源码工程进行配置:

./configure --host=arm-poky-linux-gnueabi --prefix=/home/jack/linux/tslib/tools/tslib/

–host 选项用于指定交叉编译得到的库文件是运行在哪个平台,通常将–host 设置为交叉编译器名称的前缀,譬如 arm-pokylinux-gnueabi-gcc 前缀就是 arm-poky-linux-gnueabi;–prefix 选项则用于指定库文件的安装路径,后面写自己设置的路径
在这里插入图片描述
接着执行

make
make install

在这里插入图片描述

至此交叉编译完成,可以在安装目录下看到生成的文件夹。
移植的最后一步就是把 tslib 安装目录下的库文件、etc 下的配置文件以及编译得到的测试工具拷贝到开发板 Linux 系统目录下,由于开发板出厂系统中已经移植了 tslib 库,所以我们这里就不用拷贝了。如果是自己做的根文件系统并没有移植 tslib,那么就需要把这些库、可执行文件以及配置文件拷贝到根文件系统中,大致步骤如下:

  • 将安装目录 bin/目录下的所有可执行文件拷贝到开发板/usr/bin 目录下;
  • 将安装目录 etc/目录下的配置文件 ts.conf 拷贝到开发板/etc 目录下;
  • 将安装目录 lib/目录下的所有库文件拷贝到开发板/usr/lib 目录下。

四、基于tslib写单点触摸屏应用程序

使用 tslib 提供的 API 接口来编写触摸屏应用程序,使用 tslib 库函数需要在我们的应用程序中包含 tslib 的头文件 tslib.h。

#include <stdio.h>
#include <stdlib.h>
#include <tslib.h> //包含 tslib.h 头文件
int main(int argc, char *argv[])
{
    struct tsdev *ts = NULL;
    struct ts_sample samp;
    int pressure = 0;//用于保存上一次的按压力,初始为 0,表示松开
    // /* 打开并配置触摸屏设备 
    ts = ts_setup(NULL, 0);
    if (NULL == ts) {
        fprintf(stderr, "ts_setup error");
        exit(EXIT_FAILURE);
    }
    // /* 读数据 
    for ( ; ; ) {
        if (0 > ts_read(ts, &samp, 1)) {
            fprintf(stderr, "ts_read error");
            ts_close(ts);
            exit(EXIT_FAILURE);
        }
        if (samp.pressure) {//按压力>0
            if (pressure) //若上一次的按压力>0
                printf("移动(%d, %d)\n", samp.x, samp.y);
            else
                printf("按下(%d, %d)\n", samp.x, samp.y);
        }
        else
            printf("松开\n");//打印坐标
        pressure = samp.pressure;
    }
    ts_close(ts);
    exit(EXIT_SUCCESS);
}

可以看出上述步骤:

  • 打开触摸屏设备:struct tsdev *ts_setup(const char *dev_name, int nonblock),参数 dev_name 指定触摸屏的设备节点,参数 nonblock 表示是否以非阻塞方式打开触摸屏设备。
  • 配置触摸屏设备:int ts_config(struct tsdev *ts),解析 ts.conf 文件中的配置信息,加载相应的插件。
  • 读取触摸屏数据:int ts_read(struct tsdev *ts, struct ts_sample *samp, int nr),ts_read 用于读取单点触摸数据
    代码中ts_setup函数的dev_name参数为null,函数内部会读取TSLIB_TSDEVICE 环境变量,获取该环境变量的内容以得知触摸屏的设备节点。
    在这里插入图片描述
    ts_read()函数的 samp 参数是一个 struct ts_sample *类型的指针,指向一个 struct ts_sample 对象,struct ts_sample 数据结构描述了触摸点的信息。
    编译应用程序:
${CC} -I /home/jack/linux/tslib/tools/tslib/include -L /home/jack/linux/tslib/tools/tslib/lib -lts -o ts_single_touch tslib_touch.c

-I 指定tslib库的头文件路径
-L 指定tslib库路径
-l 指定链接库,也就是 libts.so 库文件
在这里插入图片描述
结果如下:
在这里插入图片描述

五、基于tslib写多点触摸屏应用程序

使用 ts_read_mt()函数读取多点触摸数据

#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <linux/input.h>
#include <tslib.h>
int main(int argc, char *argv[])
{
    struct tsdev *ts = NULL;
    struct ts_sample_mt *mt_ptr = NULL;
    struct input_absinfo slot;
    int max_slots;
    unsigned int pressure[12] = {0}; //用于保存每一个触摸点上一次的按压力,初始为 0,表示松开
    int i;
    /* 打开并配置触摸屏设备 */
    ts = ts_setup(NULL, 0);
    if (NULL == ts) {
        fprintf(stderr, "ts_setup error");
        exit(EXIT_FAILURE);
    }
    /* 获取触摸屏支持的最大触摸点数 */
    if (0 > ioctl(ts_fd(ts), EVIOCGABS(ABS_MT_SLOT), &slot)) {
        perror("ioctl error");
        ts_close(ts);
        exit(EXIT_FAILURE);
    }
    max_slots = slot.maximum + 1 - slot.minimum;
    printf("max_slots: %d\n", max_slots);
    /* 内存分配 */
    mt_ptr = calloc(max_slots, sizeof(struct ts_sample_mt));
    /* 读数据 */
    for ( ; ; ) {
        if (0 > ts_read_mt(ts, &mt_ptr, max_slots, 1)) {
            perror("ts_read_mt error");
            ts_close(ts);
            free(mt_ptr);
            exit(EXIT_FAILURE);
        }
        for (i = 0; i < max_slots; i++) {
            if (mt_ptr[i].valid) {//有效表示有更新!
                if (mt_ptr[i].pressure) { //如果按压力>0
                    if (pressure[mt_ptr[i].slot])//如果上一次的按压力>0
                        printf("slot<%d>, 移动(%d, %d)\n", mt_ptr[i].slot, mt_ptr[i].x, mt_ptr[i].y);
                    else
                        printf("slot<%d>, 按下(%d, %d)\n", mt_ptr[i].slot, mt_ptr[i].x, mt_ptr[i].y);
                }
                else
                    printf("slot<%d>, 松开\n", mt_ptr[i].slot);
                pressure[mt_ptr[i].slot] = mt_ptr[i].pressure;
            }
        }
    }
    /* 关闭设备、释放内存、退出 */
    ts_close(ts);
    free(mt_ptr);
    exit(EXIT_SUCCESS);
}

结果如下:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值