/** 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.*** 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 <sys/stat.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 matrixn = 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 smalldet = 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 matrixa = (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 calibrationz = 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 coordcal->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 calibrationz = 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 coordcal->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 returncal->a[6] = (int)scaling;return 1;/*// This code was here originally to just insert default valuesfor(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 10int 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]);}static void clearbuf(struct tsdev *ts){int fd = ts_fd(ts);fd_set fdset;struct timeval tv;int nfds;struct ts_sample sample;while (1) {FD_ZERO(&fdset);FD_SET(fd, &fdset);tv.tv_sec = 0;tv.tv_usec = 0;nfds = select(fd + 1, &fdset, NULL, NULL, &tv);if (nfds == 0) break;if (ts_read_raw(ts, &sample, 1) < 0) {perror("ts_read");exit(1);}}}int main(){struct tsdev *ts;calibration cal;int cal_fd;char cal_buffer[256];char *tsdevice = NULL;char *calfile = NULL;unsigned int i, len;signal(SIGSEGV, sig);signal(SIGINT, sig);signal(SIGTERM, sig);if( (tsdevice = getenv("TSLIB_TSDEVICE")) != NULL ) {ts = ts_open(tsdevice,0);} else {if (!(ts = ts_open("/dev/input/event0", 0)))ts = ts_open("/dev/touchscreen/ucb1x00", 0);}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);// Clear the bufferclearbuf(ts);get_sample (ts, &cal, 0, 50, 50, "Top left");clearbuf(ts);get_sample (ts, &cal, 1, xres - 50, 50, "Top right");clearbuf(ts);get_sample (ts, &cal, 2, xres - 50, yres - 50, "Bot right");clearbuf(ts);get_sample (ts, &cal, 3, 50, yres - 50, "Bot left");clearbuf(ts);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_TRUNC | O_RDWR,S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);} else {cal_fd = open (TS_POINTERCAL, O_CREAT | O_TRUNC | O_RDWR,S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);}len = sprintf(cal_buffer,"%d %d %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],xres, yres);write (cal_fd, cal_buffer, len);close (cal_fd);i = 0;} else {printf("Calibration failed.\n");i = -1;}close_framebuffer();return i;}
tslib中的经典程序-----屏幕校准程序---ts_calibrate.c
最新推荐文章于 2024-07-29 17:58:43 发布