📄 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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -