tslib中的经典程序-----屏幕校准程序---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.
*
*
* 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 ;
}

你可能感兴趣的:(tslib中的经典程序-----屏幕校准程序---ts_calibrate.c)