使用tslib库
步骤:
- 第一步打开触摸屏设备;
- 第二步配置触摸屏设备;
- 第三步读取触摸屏数据。
一、打开触摸屏设备
#include "tslib.h"
struct tsdev *ts_open(const char *dev_name, int nonblock);
dev_name
:指定了触摸屏的设备节点
nonblock
:表示是否以非阻塞方式打开触摸屏设备,如果nonblock 等于0 表示阻塞方式,如果为非 0 值则表示 以非阻塞方式打开。
返回值:调用成功返回一个 struct tsdev *
指针, 指向触摸屏设备句柄;如果打开设备失败,将返回 NULL。
#include "tslib.h"
struct tsdev *ts_setup(const char *dev_name, int nonblock)
dev_name
:值可以为NULL
,表示函数内部会读取TSLIB_TSDEVICE 环境变量, 获取该环境变量的内容以得知触 摸屏的设备节点。
差异:ts_setup()
相比 ts_open()
,除了打开触摸屏设备外,还对触摸屏设备进行了配置
//关闭触摸屏设备
int ts_close(struct tsdev *);
二、配置触摸屏设备
#include "tslib.h"
//解析 ts.conf 文件中的配置信息,加载相应的插件
int ts_config(struct tsdev *ts)
返回值:成功返回 0,失败返回-1
三、读取触摸屏数据
#include "tslib.h"
struct ts_sample {
int x; //X 坐标
int y; //Y 坐标
unsigned int pressure; //按压力大小
struct timeval tv; //时间
};
//读取单点触摸数据
int ts_read(struct tsdev *ts, struct ts_sample *samp, int nr)
//读取多点触摸数据
int ts_read_mt(struct tsdev *ts, struct ts_sample_mt **samp, int max_slots, int nr)
ts
:指向一个触摸屏设备句柄
nr
:表示对一个触摸点的采样数,设置为 1 即可!
max_slots
:表示触摸屏支持的最大触摸点数
struct ts_sample *samp
:struct ts_sample
数据结构描述了触摸点的信息;
struct ts_sample_mt **samp
:多点触摸应用程序, 每一个触摸点的信息使用 struct ts_sample_mt
数据结构来描述 一个触摸点的数据使用一个 struct ts_sample_mt 对象来装载,将它们组织成一个 struct ts_sample_mt 数组,调用 ts_read_mt()时, 将数组地址赋值给 samp 参数。
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>
#include <stdlib.h>
#include <stdio.h>
int main(int argc,char *argv[])
{
struct tsdev * ts;
struct ts_sample sample;
unsigned int pressure=0;
if(2!=argc){
fprintf(stderr,"argc err\n");
exit(1);
}
//1.使用ts_setup()不需要在使用ts_config()
//2.使用阻塞模式打开
ts=ts_setup(argv[1],1);
if(NULL==ts){
fprintf(stderr,"ts_setup\n");
exit(1);
}
for(;;)
{
if(0>ts_read(ts,&sample,0)){
fprintf(stderr,"ts_read err\n");
ts_close(ts);
exit(1);
}
if(sample.pressure>0)
{
if(pressure>0)
{
printf("移动(%d,%d)\n",sample.x,sample.y);
}
else
{
printf("按压(%d,%d)\n",sample.x,sample.y);
}
}
else
printf("松开(%d,%d)\n",sample.x,sample.y);
pressure=sample.pressure;
}
exit(0);
}
# -I指定头文件路径
# -L指定动态库路径
# -l用于指定链接库==ts,也可以写成-l ts
# 动态库命名方式lib+名字+.so
${CC} -I /home/dt/tools/tslib/include -L /home/dt/tools/tslib/lib -lts -o testApp testApp.c
五、多点触摸例程
#include <tslib.h>
#include <stdlib.h>
#include <stdio.h>
#include <linux/input.h>
int main(int argc,char * agrv[])
{
struct tsdev *ts;
struct input_absinfo slot;
int max_slots,i;
struct ts_sample_mt *mt_ptr = NULL;
unsigned int pressure[12] = {0};
if(2!=argc){
fprintf(stderr,"argv err\n");
exit(1);
}
ts=ts_setup(NULL,0);
if(NULL==ts){
fprintf(stderr,"ts_setup err\n");
exit(1);
}
/* 获取触摸屏支持的最大触摸点数 */
if (0 > ioctl(ts_fd(ts), EVIOCGABS(ABS_MT_SLOT), &slot)) {
perror("ioctl error");
ts_close(ts);
exit(1);
}
max_slots = slot.maximum + 1 - slot.minimum;
printf("max_slots: %d\n", max_slots);
mt_ptr=calloc(max_slots,sizeof(struct ts_sample_mt));
if(NULL==mt_ptr){
fprintf(stderr,"calloc err\n");
ts_close(ts);
exit(1);
}
for(;;)
{
if(0>ts_read_mt(ts,&mt_ptr,max_slots,1)){
fprintf(stderr,"ts_read_mt err\n");
ts_close(ts);
exit(1);
}
for(i=0;i<max_slots;i++)
{
if((mt_ptr+i)->valid)
{
if(mt_ptr[i].pressure)
{
if(pressure[mt_ptr[i].slot])
{
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>,松开(%d,%d)\n",mt_ptr[i].slot,mt_ptr[i].x,mt_ptr[i].y);
pressure[mt_ptr[i].slot]=mt_ptr[i].pressure;
}
}
}
free(mt_ptr);
ts_close(ts);
exit(0);
}