目录
1、简介
2、源码编译
2.1、下载源码
2.2、配置工程
2.3、编译工程
2.4、安装
3、编译生成文件
3.1、ts.conf
4、移植
4.1、拷贝文件
4.2、配置环境变量
4.3、设置LD_LIBRARY_PATH
5、tslib库函数
5.1、ts_open()函数
5.2、ts_setup()函数
5.3、ts_close()函数
5.4、ts_config()函数
5.5、ts_read()函数
5.6、ts_read_mt()函数
6、测试代码
6.1、单点触摸测试程序
6.2、多点触摸测试程序
tslib是触摸屏驱动和应用层之间的适配层(tslib库是 Linux 系统下, 专门为触摸屏开发的应用层函数库), 它把应用程序中读取触摸屏input_event结构体类型数据并进行解析的操作过程进行了封装,向使用者提供了封装好的 API 接口。 tslib从触摸屏中获得原始的坐标数据, 并通过一系列的去噪、去抖、坐标变换等操作,来去除噪声并将原始的触摸屏坐标转换为相应的屏幕坐标。
注:tslib 可以作为 Qt 的触摸屏输入插件,为 Qt 提供触摸输入支持。
https://github.com/libts/tslib/releases
1)指定指定交叉编译工具链
--host 选项用于指定交叉编译工具链,通常将--host 设置为交叉编译器名称的前缀,譬如 arm-linux-gnueabi-gcc 前缀就是 arm-linux-gnueabi;
2)指定install路径
--prefix 选项则用于指定库文件的安装路径。
例如 ./configure --host=arm-linux-gnueabi --prefix="路径"
使用make命令编译工程
使用make install命令进行安装。
目录 | 说明 |
bin | bin 目录下有一些 tslib 提供的小工具,可以用于测试触摸屏 |
etc | 有一个配置文件 ts.conf |
include | 有一个头文件 tslib.h,该头文件中包含了一些结构体数据结构以及 API 接口的申明 |
lib | 编译 tslib 源码所得到的库文件。 注:默认都是动态库文件,也可以通过配置 tslib 工程使其生成静态库文件。 |
lib/ts | ts插件 |
tslib 有一个配置文件 ts.conf, 该配置文件中提供了一些配置参数、用户可以对其进行修改!
选项 | 说明 |
module_raw input | 取消注释,使能支持 input 输入事件 |
module pthres pmin | 用于调节按压力灵敏度。如果设备支持按压力大小测试,那么可以取消注释, pmin 用于调节按压力灵敏度,默认就是等于 1。 |
module dejitter delta | 过滤噪声样本。tslib 提供了触摸屏去噪算法插件,如果需要过滤噪声样本, 取消注释,默认参数 delta=100。 |
module linear | 坐标变换。tslib 提供了触摸屏坐标变换的功能,譬如将 X、 Y 坐标互换、坐标旋转等之类,如果需要实现坐标变换,可以把注释去掉。 |
1)bin/目录下的所有可执行文件;
2)etc/目录下的配置文件 ts.conf;
3)lib/目录下的所有库文件;
变量 | 说明 |
TSLIB_CONSOLEDEVICE | 用于配置控制台设备文件名(一般设置为none) |
TSLIB_FBDEVICE | 用于配置显示设备的设备节点 |
TSLIB_TSDEVICE | 用于配置触摸屏对应的设备节点 |
TSLIB_CONFFILE | 用于配置 ts.conf 文件的所在路径。 |
TSLIB_PLUGINDIR | 用于配置插件所在路径。 |
TSLIB_CALIBFILE | 指定触摸屏校准文件pointercal的存放位置 |
export LD_LIBRARY_PATH="运行库路径"
打开触摸屏设备。
#include "tslib.h"
struct tsdev *ts_open(const char *dev_name, int nonblock);
参数 dev_name:指定了触摸屏的设备节点;
参数 nonblock:表示是否以非阻塞方式打开触摸屏设备,如果nonblock 等于 0 表示阻塞方式,如果为非 0 值则表示以非阻塞方式打开。
返回值:调用成功返回一个 struct tsdev *指针, 指向触摸屏设备句柄;如果打开设备失败,将返回 NULL。
ts_setup()相比 ts_open(),除了打开触摸屏设备外,还对触摸屏设备进行了配置!!!
#include "tslib.h"
struct tsdev *ts_setup(const char *dev_name, int nonblock)
参数 dev_name:指定了触摸屏的设备节点;当 dev_name 设置为 NULL 时, ts_setup()函数内部会读取TSLIB_TSDEVICE 环境变量, 获取该环境变量的内容以得知触摸屏的设备节点。
参数 nonblock:表示是否以非阻塞方式打开触摸屏设备。
返回值:调用成功返回一个 struct tsdev *指针, 指向触摸屏设备句柄;如果打开设备失败,将返回 NULL。
关闭触摸屏设备。
#include "tslib.h"
int ts_close(struct tsdev *);
配置触摸屏设备。
注:所谓配置其实指的就是解析 ts.conf 文件中的配置信息,加载相应的插件。
#include "tslib.h"
int ts_config(struct tsdev *ts);
参数 ts: 指向触摸屏句柄。
返回值:成功返回 0,失败返回-1。
读取单点触摸数据。
struct ts_sample {
int x; //X 坐标
int y; //Y 坐标
unsigned int pressure; //按压力大小
struct timeval tv; //时间
};
#include "tslib.h"
int ts_read(struct tsdev *ts, struct ts_sample *samp, int nr);
参数 ts :指向一个触摸屏设备句柄。
参数samp:指向一个 struct ts_sample 对象。
参数 nr :表示对一个触摸点的采样数。
用于读取多点触摸数据。
struct ts_sample_mt {
/* ABS_MT_* event codes. linux/include/uapi/linux/input-event-codes.h
* has the definitions.
*/
int x; //X 坐标
int y; //Y 坐标
unsigned int pressure; //按压力大小
int slot; //触摸点 slot
int tracking_id; //ID
int tool_type;
int tool_x;
int tool_y;
unsigned int touch_major;
unsigned int width_major;
unsigned int touch_minor;
unsigned int width_minor;
int orientation;
int distance;
int blob_id;
struct timeval tv; //时间
/* BTN_TOUCH state */
short pen_down; //BTN_TOUCH 的状态
/* valid is set != 0 if this sample
* contains new data; see below for the
* bits that get set.
* valid is set to 0 otherwise
*/
short valid; //此次样本是否有效标志 触摸点数据是否发生更新
};
#include "tslib.h"
int ts_read_mt(struct tsdev *ts, struct ts_sample_mt **samp, int max_slots, int nr);
参数 ts :指向一个触摸屏设备句柄。
参数samp:指向一个struct ts_sample_mt *对象。
参数max_slots :表示触摸屏支持的最大触摸点数(可以通过调用 ioctl()函数获取到)。
参数 nr :表示对一个触摸点的采样数。
#include
#include
#include
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);
}
#include
#include
#include
#include
#include
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);
}