当前位置: 首页 > news >正文

wap网站预览asp 通过ftp 网站搬家

wap网站预览,asp 通过ftp 网站搬家,模特拍摄,wordpress职业学校模板目录 1. tslib开源库介绍1.1 tslib主要功能1.2 架构 2. tslib代码简单分析2.1 ts_print_mt.c分析代码2.2 ts_setup代码分析2.3 ts_open代码分析2.4 ts_config代码分析2.5 ts_read_mt代码分析2.6 tslib中4个模块的含义 3. 使用tslib库打印触摸屏2点之间的距离 基于韦东山IMX6ULL… 目录 1. tslib开源库介绍1.1 tslib主要功能1.2 架构 2. tslib代码简单分析2.1 ts_print_mt.c分析代码2.2 ts_setup代码分析2.3 ts_open代码分析2.4 ts_config代码分析2.5 ts_read_mt代码分析2.6 tslib中4个模块的含义 3. 使用tslib库打印触摸屏2点之间的距离 基于韦东山IMX6ULL开发板和配套资料学习 参考教程韦东山老师教程 1. tslib开源库介绍 tslib开源库地址是http://www.tslib.org/ tslib 是一个开源的触摸屏校准和事件处理库广泛用于嵌入式系统和 Linux 系统中。它提供了一套工具和库函数用于校准触摸屏、处理触摸事件并将原始触摸数据转换为可用于应用程序的标准化事件。 1.1 tslib主要功能 触摸屏校准tslib 提供了一个校准工具 ts_calibrate用于校准触摸屏生成校准参数文件。事件处理tslib 可以处理触摸屏的原始事件过滤噪声平滑触摸轨迹并将处理后的事件传递给应用程序。插件架构tslib 采用插件架构支持多种输入设备和不同的校准算法。标准化输出tslib 将不同触摸屏设备的原始数据转换为标准化的事件格式便于应用程序使用。 1.2 架构 tslib 的架构主要包括以下几个部分 核心库 libts核心库提供了触摸屏事件处理的基本功能包括读取事件、校准、滤波等。 工具 ts_calibrate用于校准触摸屏。 ts_test用于测试触摸屏的响应。 ts_print用于打印触摸屏事件。 ts_uinput用于生成虚拟的触摸屏事件。 插件 linear线性校准插件。 dejitter去抖动插件。 palm_detect手掌检测插件。 其他插件根据需要扩展的其他处理模块。 核心在于“plugins”目录里的“插件”或称为“module”。这个目录下的每个文件都是一个module每个module都提供2个函数read、read_mt前者用于读取单点触摸屏的数据后者用于读取多点触摸屏的数据。 参考ts_test.c和ts_test_mt.c前者用于一般触摸屏(比如电阻屏、单点电容屏)后者用于多点触摸屏。 2. tslib代码简单分析 tslib的框架图 顺着tslib的框架图对ts_print_mt.c代码进行逐步分析。 2.1 ts_print_mt.c分析代码 ts_print_mt.c文件大致内容分析 #include stdio.h #include stdlib.h #include errno.h #include string.h #include unistd.h #include getopt.h #include tslib.h #include linux/input.h // 可能需要包含此头文件以支持ioctl和ABS_MT_SLOT// 假设usage函数在其他地方定义用于打印程序的使用方法 void usage(char **argv);// 假设errfn和openfn函数在其他地方定义用于错误处理和特定打开逻辑 void errfn(const char *fmt, ...); int openfn(const char *device, int flags);int main(int argc, char **argv) {struct tsdev *ts; // 指向触摸屏设备的指针char *tsdevice NULL; // 触摸屏设备名称struct ts_sample_mt **samp_mt NULL; // 指向多点触控样本数据的指针数组#ifdef TS_HAVE_EVDEVstruct input_absinfo slot; // 用于存储触摸槽位信息的结构体 #endifint32_t user_slots 0; // 用户指定的槽位数int32_t max_slots 1; // 最大槽位数默认为1int ret, i, j; // 返回值、循环变量int read_samples 1; // 要读取的样本数short non_blocking 0; // 是否非阻塞模式short raw 0; // 是否读取原始数据struct ts_lib_version_data *ver ts_libversion(); // 获取tslib版本信息// 检查tslib版本如果低于1.10则提示升级 #ifndef TSLIB_VERSION_MT /* 1.10 */printf(You are running an old version of tslib. Please upgrade.\n); #endif// 解析命令行参数while (1) {const struct option long_options[] {{ help, no_argument, NULL, h },{ idev, required_argument, NULL, i },{ samples, required_argument, NULL, s },{ non-blocking, no_argument, NULL, n },{ raw, no_argument, NULL, r },{ slots, required_argument, NULL, j },{ version, no_argument, NULL, v },};int option_index 0;int c getopt_long(argc, argv, hvi:s:nrj:, long_options, option_index);errno 0;if (c -1)break;switch (c) {case h:usage(argv);return 0;case v:printf(%s\n, tslib_version());return 0;case i:tsdevice optarg; // 设置触摸屏设备名称break;case n:non_blocking 1; // 设置非阻塞模式break;case r:raw 1; // 设置读取原始数据break;case s:read_samples atoi(optarg); // 设置要读取的样本数if (read_samples 0) {usage(argv);return 0;}break;case j:user_slots atoi(optarg); // 设置用户指定的槽位数if (user_slots 0) {usage(argv);return 0;}break;default:usage(argv);return 0;}if (errno) {char str[9];sprintf(str, option ?);str[7] c 0xff;perror(str);}}ts_error_fn errfn; // 设置错误处理函数#ifdef TSLIB_VERSION_OPEN_RESTRICTED// 如果tslib支持受限打开功能则设置特定的打开函数if (ver-features TSLIB_VERSION_OPEN_RESTRICTED)ts_open_restricted openfn; #endif// 根据是否非阻塞模式设置触摸屏设备if (non_blocking)ts ts_setup(tsdevice, 1);elsets ts_setup(tsdevice, 0);if (!ts) {perror(ts_setup);return errno;}// 打印打开的tslib版本和设备路径printf(libts %06X opened device %s\n,ver-version_num, ts_get_eventpath(ts));#ifdef TS_HAVE_EVDEV// 获取触摸槽位信息并计算最大槽位数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; #endif// 如果用户指定了槽位数则使用用户指定的值if (user_slots 0)max_slots user_slots;// 分配内存以存储样本数据samp_mt malloc(read_samples * sizeof(struct ts_sample_mt *));if (!samp_mt) {ts_close(ts);return -ENOMEM;}for (i 0; i read_samples; i) {samp_mt[i] calloc(max_slots, sizeof(struct ts_sample_mt));if (!samp_mt[i]) {free(samp_mt);ts_close(ts);return -ENOMEM;}}// 循环读取触摸数据while (1) {if (raw)ret ts_read_raw_mt(ts, samp_mt, max_slots, read_samples); // 读取原始多点触控数据elseret ts_read_mt(ts, samp_mt, max_slots, read_samples); // 读取多点触控数据if (ret 0) {if (non_blocking) {printf(ts_print_mt: read returns %d\n, ret);continue;}perror(ts_read_mt);ts_close(ts);exit(1);}// 打印读取到的触摸数据for (j 0; j ret; j) {for (i 0; i max_slots; i) {if (!(samp_mt[j][i].valid TSLIB_MT_VALID))continue;// 假设YELLOW和RESET是定义的宏用于改变输出文本的颜色printf(YELLOW sample %d - %ld.%06ld - RESET (slot %d) %6d %6d %6d\n,j,samp_mt[j][i].tv.tv_sec,samp_mt[j][i].tv.tv_usec,samp_mt[j][i].slot,samp_mt[j][i].x,samp_mt[j][i].y,samp_mt[j][i].pressure);}}}ts_close(ts); // 关闭触摸屏设备 }遵循tslib架构图中ts_setup、ts_read_mt、ts_close顺序来读取触摸屏的输入数据。 2.2 ts_setup代码分析 tslib中ts_setup函数简单分析ts_setup中主要是执行ts_open和ts_config函数对tsdev结构体进行设置 #include stdio.h #include stdlib.h #include string.h #include errno.h #include tslib.h// 定义默认设备名称数组 const char *ts_name_default[] {/dev/input/touchscreen0,/dev/input/event0,NULL };// 设置错误处理函数 void ts_error(const char *fmt, ...) {va_list args;va_start(args, fmt);vfprintf(stderr, fmt, args);va_end(args); }// 扫描设备函数假设已实现 char *scan_devices(void) {// 实现扫描设备的逻辑return /dev/input/event0; // 示例返回值 }/*** brief 设置并打开触摸屏设备** param dev_name 设备名称如果为NULL则使用环境变量TSLIB_TSDEVICE或默认设备* param nonblock 是否使用非阻塞模式* return 成功返回触摸屏设备句柄失败返回NULL*/ struct tsdev *ts_setup(const char *dev_name, int nonblock) {const char * const *defname;struct tsdev *ts NULL; #if defined (__linux__)char *fname NULL; #endif /* __linux__ */// 如果dev_name为空则尝试从环境变量TSLIB_TSDEVICE获取设备名称dev_name dev_name ? dev_name : getenv(TSLIB_TSDEVICE);// 尝试打开指定的设备if (dev_name ! NULL) {ts ts_open(dev_name, nonblock); // 打开设备} else {// 如果没有指定设备名称尝试打开默认设备列表中的设备defname ts_name_default[0];while (*defname ! NULL) {ts ts_open(*defname, nonblock); // 尝试打开默认设备if (ts ! NULL)break; // 找到设备后跳出循环defname; // 继续下一个默认设备}}#if defined (__linux__)// 如果仍然没有找到设备尝试扫描所有设备if (!ts) {fname scan_devices(); // 扫描设备if (!fname)return NULL; // 扫描失败返回NULLts ts_open(fname, nonblock); // 打开扫描到的设备free(fname); // 释放扫描结果的内存} #endif /* __linux__ */// 如果成功打开设备尝试配置设备if (ts ts_config(ts) ! 0) {ts_error(ts_config: %s\n, strerror(errno)); // 配置失败打印错误信息ts_close(ts); // 关闭设备return NULL; // 返回NULL}return ts; // 返回设备句柄 }其中tsdev结构体 /*** brief 触摸屏设备结构体** 该结构体用于表示触摸屏设备及其相关信息。*/ struct tsdev {int fd; // 设备文件描述符char *eventpath; // 设备文件路径struct tslib_module_info *list; // 模块链表头指针/*** 指向模块链表中提供原始读取功能的模块。* 默认情况下指向 ts_read_raw 模块。*/struct tslib_module_info *list_raw;unsigned int res_x; // 触摸屏的X轴分辨率unsigned int res_y; // 触摸屏的Y轴分辨率int rotation; // 触摸屏的旋转角度 };2.3 ts_open代码分析 ts_open函数的主要作用是打开设备文件把文件描述符保存到tsdev的fd设备描述符中 #include stdio.h #include stdlib.h #include string.h #include errno.h #include fcntl.h #include unistd.h #include tslib.h// 假设 print_host_os 函数已经实现 void print_host_os(void) {// 打印主机操作系统信息printf(Host OS: Linux\n); // 示例输出 }// 假设 ts_open_restricted 函数已经实现 int (*ts_open_restricted)(const char *path, int flags, void *data) NULL;/*** brief 打开触摸屏设备** param name 设备文件名* param nonblock 是否使用非阻塞模式* return 成功返回触摸屏设备句柄失败返回NULL*/ struct tsdev *ts_open(const char *name, int nonblock) {struct tsdev *ts;int flags O_RDWR; // 默认以读写模式打开设备#ifdef DEBUGprint_host_os(); // 打印主机操作系统信息printf(, trying to open %s\n, name); // 打印尝试打开的设备文件名 #endif// 如果需要非阻塞模式if (nonblock) { #ifndef WIN32flags | O_NONBLOCK; // 在非Windows系统上设置非阻塞标志 #endif}// 分配内存用于tsdev结构体ts malloc(sizeof(struct tsdev));if (!ts)return NULL; // 内存分配失败返回NULL// 初始化tsdev结构体memset(ts, 0, sizeof(struct tsdev));// 复制设备文件名ts-eventpath strdup(name);if (!ts-eventpath)goto free; // 复制设备文件名失败跳转到free标签// 如果设置了受限打开函数if (ts_open_restricted) {ts-fd ts_open_restricted(name, flags, NULL); // 使用受限打开函数打开设备if (ts-fd -1)goto free; // 打开设备失败跳转到free标签return ts; // 打开设备成功返回设备句柄}// 使用标准open函数打开设备ts-fd open(name, flags);/** 如果打开失败且错误码为EACCES权限不足尝试以只读模式打开设备* 这对于大多数驱动程序来说是足够的*/if (ts-fd -1 errno EACCES) { #ifndef WIN32flags nonblock ? (O_RDONLY | O_NONBLOCK) : O_RDONLY; // 设置只读模式和非阻塞标志 #elseflags O_RDONLY; // Windows系统上设置只读模式 #endifts-fd open(name, flags); // 以只读模式重新打开设备}if (ts-fd -1)goto free; // 打开设备失败跳转到free标签return ts; // 打开设备成功返回设备句柄free:// 释放已分配的内存if (ts-eventpath)free(ts-eventpath); // 释放设备文件名字符串free(ts); // 释放tsdev结构体return NULL; // 返回NULL }2.4 ts_config代码分析 ts_config读取/etc/ts.conf文件内容和“plugins”目录里的“插件module”对应 #include stdio.h #include stdlib.h #include string.h #include errno.h #include tslib.h#define BUF_SIZE 1024// 假设 discard_null_tokens 和 ts_load_module、ts_load_module_raw 函数已经实现 void discard_null_tokens(char **p, char **tok) {// 处理空tokenwhile (*tok **tok \0) {*tok *p;*p strchr(*p, );if (*p) {**p \0;*p 1;}} }int ts_load_module(struct tsdev *ts, const char *module, const char *params) {return __ts_load_module(ts, module, params, 0); }int ts_load_module_raw(struct tsdev *ts, const char *module, const char *params) {return __ts_load_module(ts, module, params, 1); }/*** brief 配置触摸屏设备** param ts 触摸屏设备句柄* param conffile_modules 模块名称数组* param conffile_params 模块参数数组* param raw 标记是否为原始模块的数组* return 成功返回0失败返回-1*/ static int __ts_config(struct tsdev *ts, char **conffile_modules,char **conffile_params, int *raw) {char buf[BUF_SIZE], *p;FILE *f;int line 0;int ret 0;short strdup_allocated 0;char *conffile;// 获取配置文件路径if ((conffile getenv(TSLIB_CONFFILE)) NULL) {conffile strdup(TS_CONF); // 使用默认配置文件路径if (conffile) {strdup_allocated 1; // 标记已分配内存} else {ts_error(Couldnt find tslib config file: %s\n, strerror(errno));return -1; // 获取配置文件路径失败}}// 打开配置文件f fopen(conffile, r);if (!f) {if (strdup_allocated)free(conffile); // 释放已分配的内存ts_error(Couldnt open tslib config file %s: %s\n, conffile, strerror(errno));return -1; // 打开配置文件失败}buf[BUF_SIZE - 2] \0; // 确保缓冲区末尾为null终止while ((p fgets(buf, BUF_SIZE, f)) ! NULL) {char *e;char *tok;char *module_name;line; // 行号递增// 去除行尾换行符e strchr(p, \n);if (e)*e \0;// 检查是否读取了完整的一行if (buf[BUF_SIZE - 2] ! \0) {ts_error(%s: line %d too long\n, conffile, line);break; // 行太长退出循环}#if !defined HAVE_STRSEPtok ts_strsep(p, \t); // 使用自定义的ts_strsep函数 #elsetok strsep(p, \t); // 使用标准的strsep函数 #endifdiscard_null_tokens(p, tok); // 处理空token// 忽略注释或空白行if (p NULL || *tok #)continue;// 搜索选项if (strcasecmp(tok, module) 0) { #if !defined HAVE_STRSEPmodule_name ts_strsep(p, \t); // 使用自定义的ts_strsep函数 #elsemodule_name strsep(p, \t); // 使用标准的strsep函数 #endifdiscard_null_tokens(p, module_name); // 处理空tokenif (!conffile_modules) {ret ts_load_module(ts, module_name, p); // 加载模块} else { #ifdef DEBUGprintf(TSLIB_CONFFILE: module %s %s\n, module_name, p); // 调试信息 #endifsprintf(conffile_modules[line], %s, module_name); // 存储模块名称if (conffile_params)sprintf(conffile_params[line], %s, p); // 存储模块参数}} else if (strcasecmp(tok, module_raw) 0) { #if !defined HAVE_STRSEPmodule_name ts_strsep(p, \t); // 使用自定义的ts_strsep函数 #elsemodule_name strsep(p, \t); // 使用标准的strsep函数 #endifdiscard_null_tokens(p, module_name); // 处理空tokenif (!conffile_modules) {ret ts_load_module_raw(ts, module_name, p); // 加载原始模块} else { #ifdef DEBUGprintf(TSLIB_CONFFILE: module_raw %s %s\n, module_name, p); // 调试信息 #endifsprintf(conffile_modules[line], %s, module_name); // 存储模块名称if (conffile_params)sprintf(conffile_params[line], %s, p); // 存储模块参数if (raw)raw[line] 1; // 标记为原始模块}} else {ts_error(%s: Unrecognised option %s:%d:%s\n, conffile, line, tok);break; // 未知选项退出循环}if (ret ! 0) {ts_error(Couldnt load module %s\n, module_name);break; // 加载模块失败退出循环}}if (ts-list_raw NULL) {ts_error(No raw modules loaded.\n);ret -1; // 没有加载任何原始模块}fclose(f); // 关闭配置文件if (strdup_allocated)free(conffile); // 释放已分配的内存return ret; // 返回结果 } ts_load_module()和ts_load_module_raw()代码分析 #include stdio.h #include stdlib.h #include dlfcn.h // 用于动态链接库操作 #include tslib.h// 假设 __ts_load_module_static 和 __ts_attach、__ts_attach_raw 函数已经实现 /*** brief 静态加载触摸屏模块** param ts 触摸屏设备句柄* param module 模块名称* param params 模块参数* return 成功返回模块信息指针失败返回NULL*/ static struct tslib_module_info *__ts_load_module_static(struct tsdev *ts,const char *module,const char *params) {struct tslib_module_info *info NULL;struct tslib_module_desc *result;struct tslib_module_desc key;// 设置查找键key.name module;// 使用二分查找在模块列表中查找匹配的模块描述result bsearch(key, tslib_modules, countof(tslib_modules),sizeof(struct tslib_module_desc), cmp_name);// 如果没有找到匹配的模块返回NULLif (!result)return NULL;// 调用模块的初始化函数info result-mod_init(ts, params);#ifdef DEBUG// 调试信息模块初始化结果fprintf(stderr, static module %s init %s\n, module,info ? succeeded : failed); #endif// 如果初始化成功设置模块句柄为NULLif (info)info-handle NULL;// 返回模块信息指针return info; }/*** brief 将模块附加到触摸屏设备的原始模块链表** param ts 触摸屏设备句柄* param info 模块信息指针* return 成功返回0失败返回-1*/ int __ts_attach_raw(struct tsdev *ts, struct tslib_module_info *info) {struct tslib_module_info *next, *prev, *prev_list ts-list_raw;// 将模块信息中的设备指针设置为当前设备info-dev ts;// 将新模块插入到原始模块链表的头部info-next prev_list;ts-list_raw info;/** 确保正常模块链表的最后一个模块指向原始模块链表的头部。*/if (ts-list NULL || ts-list prev_list) {/* 如果主链表为空或者主链表的最后一个模块就是原始模块链表的第一个模块 *//* 则将主链表的头部指向新插入的模块 */ts-list info;return 0;}// 遍历正常模块链表找到最后一个模块for (next ts-list, prev next;next ! NULL next ! prev_list;next prev-next, prev next);// 将正常模块链表的最后一个模块的 next 指针指向新插入的模块prev-next info;return 0; }/*** brief 将模块附加到触摸屏设备的模块链表** param ts 触摸屏设备句柄* param info 模块信息指针* return 成功返回0失败返回-1*/ int __ts_attach(struct tsdev *ts, struct tslib_module_info *info) {// 将模块信息中的设备指针设置为当前设备info-dev ts;// 将新模块插入到模块链表的头部info-next ts-list;ts-list info;// 返回0表示成功return 0; }/*** brief 加载触摸屏模块** param ts 触摸屏设备句柄* param module 模块名称* param params 模块参数* param raw 是否为原始模块* return 成功返回0失败返回-1*/ static int __ts_load_module(struct tsdev *ts, const char *module,const char *params, int raw) {struct tslib_module_info *info;void *handle;int ret;#ifdef DEBUGif (params)printf(Loading module %s (%s)\n, module, params); // 调试信息加载模块及参数elseprintf(Loading module %s\n, module); // 调试信息加载模块 #endif// 尝试静态加载模块info __ts_load_module_static(ts, module, params);#ifdef HAVE_LIBDL// 如果静态加载失败尝试动态加载模块if (!info)info __ts_load_module_shared(ts, module, params); #endif// 如果加载失败返回-1if (!info)return -1;// 根据是否为原始模块调用相应的附加函数if (raw)ret __ts_attach_raw(ts, info); // 附加原始模块elseret __ts_attach(ts, info); // 附加普通模块// 如果附加失败进行清理if (ret) { #ifdef DEBUGts_error(Cant attach %s\n, module); // 调试信息无法附加模块 #endifhandle info-handle; // 获取模块句柄// 调用模块的fini函数进行清理if (info-ops-fini)info-ops-fini(info);#ifdef HAVE_LIBDL// 如果模块句柄有效关闭动态链接库if (handle)dlclose(handle); #endif}return ret; // 返回结果 }2.5 ts_read_mt代码分析 tslib架构中看到添加了4个模块module_raw input、module pthres pmin1、module dejitter delta100、module linear经过ts_setup配置后形成的链表是 数据的流向是触摸屏数据-input模块-pthres模块-dejitter模块-linear模块。 从代码层面分析 2.6 tslib中4个模块的含义 module_raw input读取原始触摸屏数据。 module pthres pmin1设置触摸屏的最小压力阈值过滤掉压力值低于指定阈值的触摸点。 module dejitter delta100减少触摸点的抖动通过平滑算法使触摸点的移动更加平滑。 module linear进行线性校准将触摸点的坐标映射到屏幕的实际坐标系中。 对每个模块的详细解析 module_raw input 功能读取原始触摸屏数据。 用途这个模块通常作为其他模块的基础提供最原始的触摸屏数据。它不进行任何处理直接将数据传递给下一个模块。 示例配置 module_raw input说明 input 是一个常见的原始输入模块它从触摸屏设备读取原始数据。这个模块通常放在模块链的最前面确保其他模块可以接收到未经处理的原始数据。 module pthres pmin1 功能设置触摸屏的最小压力阈值。 用途这个模块用于过滤掉压力值低于指定阈值的触摸点从而减少误触。 配置示例 module pthres pmin1参数 pmin最小压力阈值。只有当触摸点的压力值大于或等于 pmin 时才会被认为是有效的触摸点。 说明 通过设置 pmin可以过滤掉轻微的触摸或误触提高触摸屏的准确性。例如pmin1 表示只有当压力值大于或等于 1 时触摸点才被认为是有效的。 module dejitter delta100 功能减少触摸点的抖动。 用途这个模块通过平滑算法来减少触摸点的微小抖动提高触摸屏的稳定性。 配置示例 module dejitter delta100参数 delta抖动阈值。只有当触摸点的位置变化超过 delta 时才会被认为是有效的移动。 说明 通过设置 delta可以过滤掉触摸点的微小抖动使触摸点的移动更加平滑。例如delta100 表示只有当触摸点的位置变化超过 100 个单位时才会被认为是有效的移动。 module linear 功能进行线性校准。 用途这个模块通过线性变换将触摸点的坐标映射到屏幕的实际坐标系中。它通常用于校正触摸屏的偏移和缩放。 配置示例 module linear说明 linear 模块通过线性变换将触摸点的坐标从触摸屏的物理坐标系转换到屏幕的逻辑坐标系。通常需要通过校准工具如 ts_calibrate来生成校准参数并将其保存到配置文件中。这个模块确保触摸点的坐标与屏幕的实际位置对齐提高触摸屏的准确性。 3. 使用tslib库打印触摸屏2点之间的距离 #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/*** brief 计算两点之间的距离平方** param point1 第一个点* param point2 第二个点* return 两点之间的距离平方*/ 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; }/*** brief 主函数** param argc 参数个数* param argv 参数列表* return 0 表示成功非0表示失败*/ int main(int argc, char **argv) {struct tsdev *ts; // 触摸屏设备句柄int i;int ret;struct ts_sample_mt **samp_mt; // 当前触摸点数据struct ts_sample_mt **pre_samp_mt; // 上一次触摸点数据int max_slots; // 最大触摸点数int point_pressed[20]; // 存储按下的触摸点索引struct input_absinfo slot; // 触摸点槽的信息int touch_cnt 0; // 当前按下的触摸点数量// 初始化触摸屏设备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;}// 分配内存用于存储上一次触摸点数据pre_samp_mt malloc(sizeof(struct ts_sample_mt *));if (!pre_samp_mt) {ts_close(ts);return -ENOMEM;}pre_samp_mt[0] calloc(max_slots, sizeof(struct ts_sample_mt));if (!pre_samp_mt[0]) {free(pre_samp_mt);ts_close(ts);return -ENOMEM;}// 初始化上一次触摸点数据的有效标志for (i 0; i max_slots; i) {pre_samp_mt[0][i].valid 0;}// 主循环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;}// 更新上一次触摸点数据for (i 0; i max_slots; i) {if (samp_mt[0][i].valid) {memcpy(pre_samp_mt[0][i], samp_mt[0][i], sizeof(struct ts_sample_mt));}}// 统计当前按下的触摸点数量touch_cnt 0;for (i 0; i max_slots; i) {if (pre_samp_mt[0][i].valid pre_samp_mt[0][i].tracking_id ! -1) {point_pressed[touch_cnt] i;}}// 如果有两个触摸点按下计算它们之间的距离if (touch_cnt 2) {printf(distance: %08d\n, distance(pre_samp_mt[0][point_pressed[0]], pre_samp_mt[0][point_pressed[1]]));}}// 释放资源free(samp_mt[0]);free(samp_mt);free(pre_samp_mt[0]);free(pre_samp_mt);ts_close(ts);return 0; }需要明确ts_sample_mt结构体的含义 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; // 触摸点的槽位编号用于多点触控int tracking_id; // 跟踪ID用于标识同一个触摸点的连续事件int tool_type; // 工具类型例如手指、笔等int tool_x; // 工具的X坐标如果有工具类型信息int tool_y; // 工具的Y坐标如果有工具类型信息unsigned int touch_major; // 触摸区域的主要轴长度unsigned int width_major; // 触摸工具的主要轴宽度unsigned int touch_minor; // 触摸区域的次要轴长度unsigned int width_minor; // 触摸工具的次要轴宽度int orientation; // 触摸点的方向角度int distance; // 触摸点与触摸屏表面的距离int blob_id; // 触摸点的Blob ID用于标识多个触摸点的合并struct timeval tv; // 时间戳记录事件发生的时间short pen_down; // 笔触状态1表示按下0表示抬起/* 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; // 标记该样本是否包含新数据非0表示有新数据0表示无新数据 };
http://www.dnsts.com.cn/news/272626.html

相关文章:

  • 肥西网站建设关键词排名霸屏代做
  • 邢台建设企业网站费用给wordpress添加表单
  • hp网站工商注册推荐
  • 合肥做网站推荐 晨飞网络湖北定制型网站建设
  • 做阿里巴巴网站可以贷款吗网站建设合同模版
  • 做视频网站要什么主机关注网站制作
  • 西宁网站建设王道下拉惠网站有后台更新不了
  • 香河县住房和城乡建设局网站做微网站 主机 域名
  • 泰安网站建设收费标准新沂今天重大新闻
  • 建立网站需要注意什么淘宝网站怎么做的好
  • 深圳西丽网站建设官方网站营销
  • 做首图的网站百度搜索引擎怎么弄
  • 好网站建设公司收费展示类网站
  • 玉器哪家网站做的好杭州专业做网站公司
  • 贸易公司 网站 扶持电子商务公司名称起名
  • 做网站的公司简介网站开发费走什么科目
  • 网站建设怎么管理业务员兰州网站排名优化服务
  • 服装网站建设开发语言上海市建设工程交易服务中心
  • 深圳网站和app建设方案js开发手机app
  • 淘宝网站的推广方案福田祥菱q双排小货车报价及图片
  • 搭建网站属于什么专业上海网站推广服务
  • 中国建设银行官网站网点网站微信认证费用多少
  • 网站引导页动态效果怎么做的成都定制软件开发公司
  • 做网站需要提交深圳专业网站建设多少钱
  • 网页制作网站制作网络技术工程师是干嘛的
  • 电子商务网站解决方案网站建设要符合哪些标准
  • 网站开发是什么专业百度宿迁莱布拉网站建设
  • 优秀作文大全网站如何做自己微网站
  • 网站改变配色方案wordpress强大之处
  • 装饰公司网站建设方案舆情分析案例