标签:tslib
用tslib进行屏幕检验时,执行./ts_calibrate 校验完成后会生成一个pointercal文件,一直以往我们都是放在了/etc目录下,但是由于文件系统使用了只读方式,文件系统所在的mtd分区为mtd5,只有扩展的文件系统分区,mtd6分区,使用的opt目录是可读可写的,那么我们就需要将tsblib屏幕校验时生成的文件指定到/opt目录下,不过今天发生了一个很有趣的事情,我们都知道tslib生成的检验文件可以有用环境变量的方式指定到一个特定的目录下,如:
export POINTERCAL_FILE=/opt/pointercal export TSLIB_CALIBFILE=/opt/pointercal
这样就可以让生成的文件指定生成到/opt目录下,但是奇怪的是,当我设置好后,并且运行./ts_calibrate完成后,结果却发现/opt目录下并没有出现这个文件,我很奇怪,因为事先我已经将/etc/目录下的pointercal文件删除掉,并且由于文件系统是只读的,所以不可能在/etc/目录下出现这个pointercal文件,为了验证我的环境变量指定的对不对,我又重启系统,进入到uboot中,uboot传参,指定文件系统为可读可写的,系统启动后,我继续执行了./ts_calibrate,执行完毕后,发现也并没有在/opt目录下生成这个pointercal文件,我感觉好像是见鬼了,我好奇的cd到/etc目录下一看,发现pointercal文件如同贞子一般出现了。由于见到了贞子,我开始对人生开始怀疑了,我开始怀疑我的那两个环境变量名字不对,我开始怀疑tslib源码不对,但我还是当我这次见到的贞子可能是意外出现的,下一次并不会出现,于是我继续将/etc/pointercal这个贞子干掉,确定/opt目录下并没有pointercal文件,确定我的/etc/Myprofile脚本文件中的环境变量导出的是
export POINTERCAL_FILE=/opt/pointercal export TSLIB_CALIBFILE=/opt/pointercal
一切确定好后,我重启了系统,手颤抖着敲着回车,进入到了uboot中,确定了uboot参数,确实指定了文件系统为可读可写的方式,于是系统启动成功挂载了文件系统,我在根目录下创建了一个文件a.c,确定文件系统可写。于是我怀着不安的心情继续执行了./ts_calibrate程序,校验完毕后,我快速的跑到了/opt目录下去看我亲爱的pointercal文件,结果我亲爱的pointercal文件并没有在我的/opt目录下的怀抱中,我去/etc/目录下一看,她果然放弃了我/opt,找了她的新欢/etc/,这个时候我严重怀疑环境变量设置的不对或者tslib源码不对,我为了将我亲爱的pointercal下次出现在/opt目录下,我硬件着头皮翻开了tslib的源码。
打开tslib目录文件,观察了tslib目录一番,去src目录下看了一番,看名字决定没有一个是我想要的看的,他们的外貌我很讨厌,这却是是一个看脸的时代。名字如下:
你看了之后是否也决定很恶心,是的!!
我果断退出了src目录,来到了testts目录,在我感觉并不是这个目录时,我的眼睛一闪,灵光一动,我觉得上天还是美好的,第二次邂逅就让我去遇见了那个她
看这些文件的名字,相信不傻的人都知道谁是最美的了,答案肯定是ts_calibrate.c文件,我快速的流着口水打开了他,为了让大家也见一下真相,我将她里面的内容呈现给你们,你们不要流鼻血,不喜欢她里面的人可以跳过,后面我解释重要的部分
/*
* tslib/tests/ts_calibrate.c
*
* Copyright (C) 2001 Russell King.
*
* This file is placed under the GPL. Please see the file
* COPYING for more details.
*
* $Id: ts_calibrate.c,v 1.8 2004/10/19 22:01:27 dlowder Exp $
*
* Basic test program for touchscreen library.
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <sys/fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <linux/kd.h>
#include <linux/vt.h>
#include <linux/fb.h>
#include "tslib.h"
#include "fbutils.h"
#include "testutils.h"
static int palette [] =
{
0x000000, 0xffe080, 0xffffff, 0xe0c0a0
};
#define NR_COLORS (sizeof (palette) / sizeof (palette [0]))
typedef struct {
int x[5], xfb[5];
int y[5], yfb[5];
int a[7];
} calibration;
static void sig(int sig)
{
close_framebuffer ();
fflush (stderr);
printf ("signal %d caught\n", sig);
fflush (stdout);
exit (1);
}
int perform_calibration(calibration *cal) {
int j;
float n, x, y, x2, y2, xy, z, zx, zy;
float det, a, b, c, e, f, i;
float scaling = 65536.0;
// Get sums for matrix
n = x = y = x2 = y2 = xy = 0;
for(j=0;j<5;j++) {
n += 1.0;
x += (float)cal->x[j];
y += (float)cal->y[j];
x2 += (float)(cal->x[j]*cal->x[j]);
y2 += (float)(cal->y[j]*cal->y[j]);
xy += (float)(cal->x[j]*cal->y[j]);
}
// Get determinant of matrix -- check if determinant is too small
det = n*(x2*y2 - xy*xy) + x*(xy*y - x*y2) + y*(x*xy - y*x2);
if(det < 0.1 && det > -0.1) {
printf("ts_calibrate: determinant is too small -- %f\n",det);
return 0;
}
// Get elements of inverse matrix
a = (x2*y2 - xy*xy)/det;
b = (xy*y - x*y2)/det;
c = (x*xy - y*x2)/det;
e = (n*y2 - y*y)/det;
f = (x*y - n*xy)/det;
i = (n*x2 - x*x)/det;
// Get sums for x calibration
z = zx = zy = 0;
for(j=0;j<5;j++) {
z += (float)cal->xfb[j];
zx += (float)(cal->xfb[j]*cal->x[j]);
zy += (float)(cal->xfb[j]*cal->y[j]);
}
// Now multiply out to get the calibration for framebuffer x coord
cal->a[0] = (int)((a*z + b*zx + c*zy)*(scaling));
cal->a[1] = (int)((b*z + e*zx + f*zy)*(scaling));
cal->a[2] = (int)((c*z + f*zx + i*zy)*(scaling));
printf("%f %f %f\n",(a*z + b*zx + c*zy),
(b*z + e*zx + f*zy),
(c*z + f*zx + i*zy));
// Get sums for y calibration
z = zx = zy = 0;
for(j=0;j<5;j++) {
z += (float)cal->yfb[j];
zx += (float)(cal->yfb[j]*cal->x[j]);
zy += (float)(cal->yfb[j]*cal->y[j]);
}
// Now multiply out to get the calibration for framebuffer y coord
cal->a[3] = (int)((a*z + b*zx + c*zy)*(scaling));
cal->a[4] = (int)((b*z + e*zx + f*zy)*(scaling));
cal->a[5] = (int)((c*z + f*zx + i*zy)*(scaling));
printf("%f %f %f\n",(a*z + b*zx + c*zy),
(b*z + e*zx + f*zy),
(c*z + f*zx + i*zy));
// If we got here, we‘re OK, so assign scaling to a[6] and return
cal->a[6] = (int)scaling;
return 1;
/*
// This code was here originally to just insert default values
for(j=0;j<7;j++) {
c->a[j]=0;
}
c->a[1] = c->a[5] = c->a[6] = 1;
return 1;
*/
}
static void get_sample (struct tsdev *ts, calibration *cal,
int index, int x, int y, char *name)
{
static int last_x = -1, last_y;
if (last_x != -1) {
#define NR_STEPS 10
int dx = ((x - last_x) << 16) / NR_STEPS;
int dy = ((y - last_y) << 16) / NR_STEPS;
int i;
last_x <<= 16;
last_y <<= 16;
for (i = 0; i < NR_STEPS; i++) {
put_cross (last_x >> 16, last_y >> 16, 2 | XORMODE);
usleep (1000);
put_cross (last_x >> 16, last_y >> 16, 2 | XORMODE);
last_x += dx;
last_y += dy;
}
}
put_cross(x, y, 2 | XORMODE);
getxy (ts, &cal->x [index], &cal->y [index]);
put_cross(x, y, 2 | XORMODE);
last_x = cal->xfb [index] = x;
last_y = cal->yfb [index] = y;
printf("%s : X = %4d Y = %4d\n", name, cal->x [index], cal->y [index]);
}
int main()
{
struct tsdev *ts;
calibration cal;
int cal_fd;
char cal_buffer[256];
char *tsdevice = NULL;
char *calfile = NULL;
unsigned int i;
signal(SIGSEGV, sig);
signal(SIGINT, sig);
signal(SIGTERM, sig);
if( (tsdevice = getenv("TSLIB_TSDEVICE")) != NULL ) {
ts = ts_open(tsdevice,0);
} else {
#ifdef USE_INPUT_API
ts = ts_open("/dev/input/event0", 0);
#else
ts = ts_open("/dev/touchscreen/ucb1x00", 0);
#endif /* USE_INPUT_API */
}
if (!ts) {
perror("ts_open");
exit(1);
}
if (ts_config(ts)) {
perror("ts_config");
exit(1);
}
if (open_framebuffer()) {
close_framebuffer();
exit(1);
}
for (i = 0; i < NR_COLORS; i++)
setcolor (i, palette [i]);
put_string_center (xres / 2, yres / 4,
"TSLIB calibration utility", 1);
put_string_center (xres / 2, yres / 4 + 20,
"Touch crosshair to calibrate", 2);
printf("xres = %d, yres = %d\n", xres, yres);
// Read a touchscreen event to clear the buffer
//getxy(ts, 0, 0);
get_sample (ts, &cal, 0, 50, 50, "Top left");
get_sample (ts, &cal, 1, xres - 50, 50, "Top right");
get_sample (ts, &cal, 2, xres - 50, yres - 50, "Bot right");
get_sample (ts, &cal, 3, 50, yres - 50, "Bot left");
get_sample (ts, &cal, 4, xres / 2, yres / 2, "Center");
if (perform_calibration (&cal)) {
printf ("Calibration constants: ");
for (i = 0; i < 7; i++) printf("%d ", cal.a [i]);
printf("\n");
if ((calfile = getenv("TSLIB_CALIBFILE")) != NULL) {
cal_fd = open (calfile, O_CREAT | O_RDWR);
} else {
cal_fd = open ("/etc/pointercal", O_CREAT | O_RDWR);
}
sprintf (cal_buffer,"%d %d %d %d %d %d %d",
cal.a[1], cal.a[2], cal.a[0],
cal.a[4], cal.a[5], cal.a[3], cal.a[6]);
write (cal_fd, cal_buffer, strlen (cal_buffer) + 1);
close (cal_fd);
i = 0;
} else {
printf("Calibration failed.\n");
i = -1;
}
close_framebuffer();
return i;
} 快速的看了一个下代码后,终于找到了她最美的位置,如下:
int main()
{
struct tsdev *ts;
calibration cal;
int cal_fd;
char cal_buffer[256];
char *tsdevice = NULL;
char *calfile = NULL;
unsigned int i;
signal(SIGSEGV, sig);
signal(SIGINT, sig);
signal(SIGTERM, sig);
if( (tsdevice = getenv("TSLIB_TSDEVICE")) != NULL ) {
ts = ts_open(tsdevice,0);
} else {
#ifdef USE_INPUT_API
ts = ts_open("/dev/input/event0", 0);
#else
ts = ts_open("/dev/touchscreen/ucb1x00", 0);
#endif /* USE_INPUT_API */
}
if (!ts) {
perror("ts_open");
exit(1);
}
if (ts_config(ts)) {
perror("ts_config");
exit(1);
}
if (open_framebuffer()) {
close_framebuffer();
exit(1);
}
for (i = 0; i < NR_COLORS; i++)
setcolor (i, palette [i]);
put_string_center (xres / 2, yres / 4,
"TSLIB calibration utility", 1);
put_string_center (xres / 2, yres / 4 + 20,
"Touch crosshair to calibrate", 2);
printf("xres = %d, yres = %d\n", xres, yres);
// Read a touchscreen event to clear the buffer
//getxy(ts, 0, 0);
get_sample (ts, &cal, 0, 50, 50, "Top left");
get_sample (ts, &cal, 1, xres - 50, 50, "Top right");
get_sample (ts, &cal, 2, xres - 50, yres - 50, "Bot right");
get_sample (ts, &cal, 3, 50, yres - 50, "Bot left");
get_sample (ts, &cal, 4, xres / 2, yres / 2, "Center");
if (perform_calibration (&cal)) {
printf ("Calibration constants: ");
for (i = 0; i < 7; i++) printf("%d ", cal.a [i]);
printf("\n");
if ((calfile = getenv("TSLIB_CALIBFILE")) != NULL) {
cal_fd = open (calfile, O_CREAT | O_RDWR);
} else {
cal_fd = open ("/etc/pointercal", O_CREAT | O_RDWR);
}
sprintf (cal_buffer,"%d %d %d %d %d %d %d",
cal.a[1], cal.a[2], cal.a[0],
cal.a[4], cal.a[5], cal.a[3], cal.a[6]);
write (cal_fd, cal_buffer, strlen (cal_buffer) + 1);
close (cal_fd);
i = 0;
} else {
printf("Calibration failed.\n");
i = -1;
}
close_framebuffer();
return i;
}果然,最美的位置还是main函数,首先获取了环境变量
TSLIB_TSDEVICE
的值,他的值在我的系统中被我导出成/dev/input/event0,这个环境变量有值,就获取值然后,打开他,得到文件描述符,没有值则打开默认的文件。这里不重要,略过,不过可以知道tslib确实是通过环境变量来得到值,决定行动的。
最后这里
if ((calfile = getenv("TSLIB_CALIBFILE")) != NULL) {
cal_fd = open (calfile, O_CREAT | O_RDWR);
} else {
cal_fd = open ("/etc/pointercal", O_CREAT | O_RDWR);
}
sprintf (cal_buffer,"%d %d %d %d %d %d %d",
cal.a[1], cal.a[2], cal.a[0],
cal.a[4], cal.a[5], cal.a[3], cal.a[6]);
write (cal_fd, cal_buffer, strlen (cal_buffer) + 1);
close (cal_fd);获取了TSLIB_CALBFILE环境变量的值,很显然我的这个环境变量的名字是没有写错的,同时可以发现tsblib的代码是没有问题的,如果这个环境变量有值,则打开这个值对应的文件,如果没有值,则使用默认的/etc/pointercal文件,看来tsblib喜欢/etc/并不是偶然的,之后获取了几个点的值,然后写入到了这个刚打开的文件中,然后关闭了她,至此我们就不在分析她了,看够了,因为我们的目的已经达到了,确定了我的环境变量的名字和环境变量设置的值以及tslib的源码都是正确的了。那么这个时候我相信这个世界是没有见鬼的事情的,而是你不够细心,还没有将其他的可能发现的情况考虑进去,于是我开始怀疑,我的环境变量虽然看脚本是导出了,但真的导出了吗,因为我的这个/etc/Myprofile脚本是自启动执行的,这点我可以确定,于是我重启系统,系统启动后,用echo $TSLIB_CALIBFILE的方式,看了一下这个环境变量的值,结果我正经了,原来值是空的,这是什么情况,于是我手动执行了一遍这个/etc/Myprofile脚本后,再次查看了这个环境变量的值,发现值是有的。问题找到了,解决方法就快了,原来由于该文件系统的设计机制,在用户登录到系统之前执行的是/etc/Myprofile脚本,一切都是对的,应用程序也是可以执行的,但是当用户登录到系统后,你的环境变量需要重新导出,而这次导出环境变量使用的是/etc/profile文件,这个文件大家都不陌生,我打开这个文件一看,这个文件中并没有对其他的环境变量进行导出,也就是说如果你程序不是自启动的话,你登录系统后,手动运行应用程序都是无法运行的,因为你Qt库需要的环境变量并没有被到处。
本文出自 “whylinux” 博客,谢绝转载!
标签:tslib
原文地址:http://whylinux.blog.51cto.com/10900429/1914614