tslib中的经典程序-----屏幕校准程序---ts_calibrate.c

本文介绍了一个用于触摸屏校准的基础测试程序。该程序通过获取触摸坐标并进行数学运算来生成校准参数,并最终将这些参数写入指定文件中。程序还包括了信号处理和错误处理机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*
* 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 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]);
}
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 buffer
        clearbuf(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;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值