tslib学习

写在前边

本文是B站up主韦东山的4_7-9.编写基于tslib的测试程序_哔哩哔哩_bilibili视频的笔记,其中有些部分博主也没有理解,希望各位辩证的看。

目录

基本知识

交叉编译、测试 tslib

示例程序


基本知识

tslib 是一个触摸屏的开源库,可以使用它来访问触摸屏设备,可以给输入设 备 添 加 各 种 “ filter ” ( 过 滤 器 , 就 是 各 种 处 理 ) , 地 址 是 :http://www.tslib.org/。

编译 tslib 后,可以得到 libts 库,还可以得到各种工具:较准工具、测试工具。

官网地址:C library for filtering touchscreen events

tslib 框架分析

tslib 的主要代码位置

tslib 1主要代码

plugins目录下的每个文件都是一个 module,每个模块都会被编译成动态库,每个 module 都提供 2 个函数:read、read_mt,前者用于读取单点触摸屏的数据,后者用于读取多点触摸屏的数据。

tests目录下是测试程序:参考 ts_test.c 和ts_test_mt.c,前者用于一般触摸屏(比如电阻屏、单点电容屏),后者用于多点触摸屏。

tslib 2tslib框架图

交叉编译、测试 tslib

首先先安装依赖库

sudo apt-get install autoconf automake libtool

然后需要根据自己板子的交叉编译工具链安装:

其中arm-linux-gnueabihf就是你的交叉编译工具链,你需要根据自己的工具链将这里进行替换。

./configure --host=arm-linux-gnueabihf --prefix=/

make

make install DESTDIR=$PWD/tmp

这里完成后会在当前文件夹下产生tslib的各种文件,接下来需要将某些文件加入到工具链的目录中,以便程序在编译时可以找到这些库函数。

这里需要做的是先知道这些工具链的目录在哪里:

echo 'main(){}'| arm-linux-gnueabihf-gcc -E -v -

同样的,arm-linux-gnueabihf是交叉编译工具链,将这里替换成自己的工具链。

tslib 3工具链目录

// 下边的这些命令我直接复制的百问的命令,所以这里边的工具链和我标出的不太一样,这里需按照自己的板子上的工具链进行替换。

cd tslib-1.21/tmp/

cp include/* /home/book/100ask_imx6ull-sdk/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/bin/../arm-linux-gnueabihf/libc/usr/include

cp -d lib/*so* /home/book/100ask_imx6ull-sdk/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/bin/../arm-linux-gnueabihf/libc/usr/lib/

这些完成之后,需要将库文件放到板子上运行(这里我提前挂载了网络文件系统):

cp /mnt/tslib-1.21/tmp/lib/*so* -d /lib

cp /mnt/tslib-1.21/tmp/bin/* /bin

cp /mnt/tslib-1.21/tmp/etc/ts.conf -d /etc

完成之后就可以在板子上运行tslib库了。

示例程序

下边是我做的一个画板程序,主要功能为可以在上边画线,点击上边颜色部分可以切换画线颜色。

tslib 4画板实物

#include <stdio.h>

#include <stdint.h>

#include <stdlib.h>

#include <string.h>

#include <signal.h>

#include <errno.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <unistd.h>

#include <getopt.h>

#include <linux/input.h>

#include <sys/ioctl.h>

#include <tslib.h>

#include <sys/mman.h>

#include <linux/fb.h>



// 可变参数结构体

static struct fb_var_screeninfo var; /* current var */

// 屏幕文件的句柄

static int fd_fb;

// 整个屏幕的像素个数

static int screen_size;

// 指向映射的区域指针

static unsigned char* fb_base;

// 一行有多少像素

static unsigned int line_width;

// 一个像素多少byte

static unsigned int pixel_width;

// 定义颜色

unsigned int color = 0;



// 描点函数(color格式:0x00RRGGBB)

void lcd_put_pixel(int x, int y, unsigned int color)

{

         unsigned char* pen_8 = fb_base + y * line_width + x * pixel_width;

         unsigned short* pen_16;

         unsigned int* pen_32;



         unsigned int red, green, blue;



         pen_16 = (unsigned short*)pen_8;

         pen_32 = (unsigned int*)pen_8;



         switch (var.bits_per_pixel) { /* bpp 像素深度 */

         case 8:

         {

                   *pen_8 = color;

                   break;

         }

         case 16:

         {

                   /* RGB565 */

                   red = (color >> 16) & 0xFF;

                   green = (color >> 8) & 0xFF;

                   blue = (color >> 0) & 0xFF;

                   color = ((red >> 3) << 11) | ((green >> 2) << 5) | (blue >> 3);

                   *pen_16 = color;

                   break;

         }

         case 32:

         {

                   /* RGB888 */

                   *pen_32 = color;

                   break;

         }

         default:

         {

                   printf("Can't support %d bpp\n", var.bits_per_pixel);

                   break;

         }

         }

}

// 画线函数(color格式:0x00RRGGBB)

// x1,y1,x2,y2: 线段的起点和终点坐标

// color: 线段的颜色

void lcd_draw_line(int x1, int y1, int x2, int y2, unsigned int color)

{

         // abs函数用于求绝对值

         int dx = abs(x2 - x1);

         int dy = abs(y2 - y1);

         int sx = (x1 < x2) ? 1 : -1;

         int sy = (y1 < y2) ? 1 : -1;

         int err = dx - dy;

         int e2;



         while (1) {

                   lcd_put_pixel(x1, y1, color);

                   if (x1 == x2 && y1 == y2)

                            break;

                   e2 = 2 * err;

                   if (e2 > -dy) {

                            err = err - dy;

                            x1 = x1 + sx;

                   }

                   if (e2 <  dx) {

                            err = err + dx;

                            y1 = y1 + sy;

                   }

                   /*printf("x1: %d, y1: %d\n", x1, y1);*/

         }

}

// 选择颜色函数

void select_color(int x)

{

         if (x < 100)

         {

                   color = 0xFF0000; // 红色

         }

         else if (x < 200)

         {

                   color = 0x000000; // 黑色

         }

         else if (x < 300)

         {

                   color = 0xCC5500; // 燃橙

         }

         else if (x < 400)

         {

                   color = 0x996B1F; // 卡其色

         }

         else if (x < 500)

         {

                   color = 0xFFFFF0; // 象牙色

         }

         else if (x < 600)

         {

                   color = 0xFFFF00; // 黄色

         }

         else if (x < 700)

         {

                   color = 0x99FF4D; // 嫩绿

         }

         else if (x < 800)

         {

                   color = 0xB0E0E6; // 婴儿粉蓝

         }

         else if (x < 900)

         {

                   color = 0x000080; // 藏青

         }

         else

         {

                   color = 0xEE82EE; // 亮紫

         }

}

// (实心)矩形函数(color格式:0x00RRGGBB)

// x1,y1,x2,y2: 矩形的左上角和右下角坐标

// color: 矩形的颜色

void lcd_draw_rect(int x1, int y1, int x2, int y2, unsigned int color)

{

         for (int i = y1; i < y2; i++)

         {

                   for (int j = x1; j < x2; j++)

                   {

                            lcd_put_pixel(j, i, color);

                   }

         }

        

        

}



int distance(struct ts_sample_mt* point1, struct ts_sample_mt* point2)

{



         int x = point1->x - point2->x;

         int y = point1->y - point2->y;



         return x * x + y * y;

}



int main(int argc, char** argv)

{

         struct tsdev* ts;

         int i;

         int ret;

         struct ts_sample_mt** samp_mt;

         int x = 0, y = 0;

         int max_slots;

         int point_pressed[20];

         struct input_absinfo slot;

         int touch_cnt = 0;

         static int first_click = 1; // 标志变量,初始为1表示第一次点击

         ts = ts_setup(NULL, 0);

         if (!ts)

         {

                   printf("ts_setup err\n");

                   return -1;

         }



         if (ioctl(ts_fd(ts), EVIOCGABS(ABS_MT_SLOT), &slot) < 0) {

                   perror("ioctl EVIOGABS");

                   ts_close(ts);

                   return errno;

         }



         max_slots = slot.maximum + 1 - slot.minimum;



         samp_mt = malloc(sizeof(struct ts_sample_mt*));

         if (!samp_mt) {

                   ts_close(ts);

                   return -ENOMEM;

         }

         samp_mt[0] = calloc(max_slots, sizeof(struct ts_sample_mt));

         if (!samp_mt[0]) {

                   free(samp_mt);

                   ts_close(ts);

                   return -ENOMEM;

         }





         for (i = 0; i < max_slots; i++)

                   samp_mt[0][i].valid = 0;





         // 打开文件,获得文件句柄

         int fd_fb = open("/dev/fb0", O_RDWR);

         // 获取设备参数

         ioctl(fd_fb, FBIOGET_VSCREENINFO, &var);

         // 内存映射

         line_width = var.xres * var.bits_per_pixel / 8; // 一行多少byte

         pixel_width = var.bits_per_pixel / 8;           // 一个像素多少byte

         screen_size = var.xres * var.yres * var.bits_per_pixel / 8; // 一屏多少byte

         fb_base = (unsigned char*)mmap(NULL, var.xres * var.yres * var.bits_per_pixel / 8, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);

         /* 清屏: 全部设为白色 */

         memset(fb_base, 0xFF, screen_size);

         x = 0;

         y = 0;

         lcd_draw_rect(0, 0, 100, 100, 0xFF0000); // 画一个矩形红色

         lcd_draw_rect(100, 0, 200, 100, 0x000000); // 画一个矩形黑色

         lcd_draw_rect(200, 0, 300, 100, 0xCC5500); // 画一个矩形燃橙

         lcd_draw_rect(300, 0, 400, 100, 0x996B1F); // 画一个矩形卡其色

         lcd_draw_rect(400, 0, 500, 100, 0xFFFFF0); // 画一个矩形象牙色

         lcd_draw_rect(500, 0, 600, 100, 0xFFFF00); // 画一个矩形黄色

         lcd_draw_rect(600, 0, 700, 100, 0x99FF4D); // 画一个矩形嫩绿

         lcd_draw_rect(700, 0, 800, 100, 0xB0E0E6); // 画一个矩形婴儿粉蓝

         lcd_draw_rect(800, 0, 900, 100, 0x000080); // 画一个矩形藏青

         lcd_draw_rect(900, 0, 1000, 100, 0xEE82EE); // 画一个矩形亮紫



         while (1)

         {

                   ret = ts_read_mt(ts, samp_mt, max_slots, 1);



                   if (ret < 0) {

                            printf("ts_read_mt err\n");

                            ts_close(ts);

                            return -1;

                   }

                   if (samp_mt[0][0].valid && samp_mt[0][0].tracking_id != -1)

                   {

                            // 如果是第一次点击,则记录坐标

                            if (first_click)

                            {

                                     x = samp_mt[0][0].x;

                                     y = samp_mt[0][0].y;

                                     first_click = 0;// 设置标志变量为0,表示不再是第一次点击

                            }

                            else

                            {

                                     // 画线区域

                                     if (samp_mt[0][0].y > 100)

                                     {

                                               lcd_draw_line(x, y, samp_mt[0][0].x, samp_mt[0][0].y, color);

                                               x = samp_mt[0][0].x;

                                               y = samp_mt[0][0].y;

                                     }

                                    

                            }

                   }

                   else

                            first_click = 1;

                   // 选择颜色区域

                   if (samp_mt[0][0].y < 100)

                   {

                            select_color(samp_mt[0][0].x);

                   }

         }



         return 0;

}

  • 15
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 要下载tslib-1.4.tar.gz文件,可以通过CSDN网站进行下载。以下是具体步骤: 1. 打开CSDN网站,并进入其下载页面。 2. 在搜索框中输入tslib-1.4.tar.gz进行搜索。 3. 在搜索结果中找到相关的下载链接,并点击进入。 4. 查看下载页面上的介绍和相关信息,确保下载的文件是正确版本。 5. 点击下载按钮,开始下载tslib-1.4.tar.gz文件。 6. 下载完成后,可以在下载文件的默认保存位置找到该文件。 7. 解压缩下载的tslib-1.4.tar.gz文件。可以使用解压软件,如WinRAR或7-Zip等工具进行解压。 8. 解压后,就可以使用tslib-1.4.tar.gz文件进行相关的操作,如安装、配置等。 需要注意的是,CSDN作为一个开放的技术社区,提供了众多开发者共享的资源,但要注意选择可信的下载链接和源,确保所下载的文件是没有被恶意篡改或携带病毒的。 ### 回答2: tslib-1.4.tar.gz是一个名为tslib的软件包文件,它可能包含了一些用于触摸屏驱动和应用程序开发的工具和库。CSDN是一个在线技术社区,它为开发者提供了许多技术相关的资源。 如果你想要下载tslib-1.4.tar.gz文件,你可以在CSDN的网站上搜索该文件的下载链接。首先,访问CSDN的官方网站,并输入“tslib-1.4.tar.gz下载”进行搜索。在搜索结果中,你可能会找到一些相关的帖子或文章,其中包含了这个文件的下载链接。 点击下载链接后,你将被重定向到一个下载页面,在该页面上你可以选择下载文件的保存位置。一般来说,大部分的下载页面都会提供一个下载按钮或者链接,你只需点击它即可开始下载。 一旦下载完成,你可以找到你的下载文件夹,其中应该已经有了tslib-1.4.tar.gz文件。你可以使用解压软件(例如7-Zip)来解压或打开这个文件。 总之,要下载tslib-1.4.tar.gz文件,你可以通过访问CSDN的网站并搜索相关链接来实现。希望这个回答对你有所帮助。 ### 回答3: 要下载tslib-1.4.tar.gz,首先需要访问CSDN网站。我们可以在浏览器中输入CSDN的网址(https://www.csdn.net/)进行访问。在CSDN网站上,可以找到各种技术资源和开源软件。在搜索框中输入tslib-1.4.tar.gz,并点击搜索按钮,即可找到相关的下载链接。 在下载链接所在的页面上,我们可以找到tslib-1.4.tar.gz的详细信息,如版本号、文件大小以及更新日期等。通常,下载链接会以文本、图片或按钮的形式展示。点击下载链接后,即可开始下载tslib-1.4.tar.gz文件。 下载过程中,我们可以选择保存文件的路径和名称。一般来说,选择一个易于找到和记忆的文件保存路径是很重要的。下载完成后,我们可以在选择的路径下找到tslib-1.4.tar.gz文件。 tslib-1.4.tar.gz是一个压缩文件,我们需要解压缩才能使用其中的内容。可以使用类似WinRAR或7-Zip等解压工具对文件进行解压。解压完成后,可以得到一个名为tslib-1.4的文件夹,里面包含了tslib-1.4的源代码和其他相关文件。 现在,我们可以根据具体需求,使用tslib-1.4.tar.gz文件中的内容了。如果是进行编程开发,需要将tslib-1.4的源代码导入到项目中,并进行编译和运行。如果是进行研究或学习,可以查看文件中的文档或示例代码,以获取更多关于tslib-1.4的使用说明。 总之,通过在CSDN上下载tslib-1.4.tar.gz,我们可以获取到这个开源软件的压缩文件,并通过解压缩获得源代码和其他资源,从而满足我们对tslib-1.4的需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值