ts.c

Go to the documentation of this file.
00001 /*
00002  * File Name: ts.c
00003  */
00004 
00005 /*
00006  * This file is part of gtktscal.
00007  *
00008  * gtktscal is free software: you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation, either version 2 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * gtktscal is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program. If not, see <http://www.gnu.org/licenses/>.
00020  */
00021 
00022 /*
00023  * This code is originally from xtscal:
00024  *
00025  * Copyright (C) 2003, 2004 Philip Blundell <philb@gnu.org>
00026  *
00027  * Modifications:
00028  *
00029  * Copyright (C) 2008 iRex Technologies B.V.
00030  */
00031 
00032 #include <stdlib.h>
00033 #include <stdio.h>
00034 #include <errno.h>
00035 #include <unistd.h>
00036 #include <math.h>
00037 #include <string.h>
00038 #include <sys/ioctl.h>
00039 
00040 #include <glib.h>
00041 #include <gtk/gtk.h>
00042 #include <gdk/gdk.h>
00043 #include <gdk/gdkx.h>
00044 
00045 #include <X11/extensions/xcalibrate.h>
00046 
00047 #include "h3600_ts.h"
00048 #include "calibrate.h"
00049 #include "ts.h"
00050 
00051 #define ENOUGH 5
00052 #define MAX_SAMPLES 40
00053 #define OFFSET 150
00054 #define ALLOWED_OFFSET 80
00055 
00056 #define RAW_DEVICE "/dev/ttyS0"
00057 
00058 struct point sample[MAX_SAMPLES];
00059 calibration cal;
00060 int ts_fd;
00061 int samples;
00062 static int a_cur[7];
00063 int event = 0;
00064 
00065 extern int flag_debug;
00066 extern int flag_sanityCheck;
00067 extern void next_target();
00068 
00069 void ts_init(int width, int height, int rotation)
00070 {
00071     int i;
00072 
00073     cal.xscr[0] = OFFSET;
00074     cal.yscr[0] = OFFSET;
00075     cal.xscr[1] = width - OFFSET;
00076     cal.yscr[1] = OFFSET;
00077     cal.xscr[2] = width - OFFSET;
00078     cal.yscr[2] = height - OFFSET;
00079     cal.xscr[3] = OFFSET;
00080     cal.yscr[3] = height - OFFSET;
00081     cal.xscr[4] = (width / 2);
00082     cal.yscr[4] = (height / 2);
00083     
00084     for (i=0;i<NR_POINTS;i++)
00085     {
00086         switch (rotation)
00087         {
00088             case 0:
00089                 cal.xfb[i] = cal.xscr[i];
00090                 cal.yfb[i] = cal.yscr[i];
00091                 break;
00092             case 90:
00093                 cal.xfb[i] = cal.yscr[i];
00094                 cal.yfb[i] = width - cal.xscr[i];
00095                 break;
00096             case 180:
00097                 cal.xfb[i] = width - cal.xscr[i];
00098                 cal.yfb[i] = height - cal.yscr[i];
00099                 break;
00100             case 270:
00101                 cal.xfb[i] = height - cal.yscr[i];
00102                 cal.yfb[i] = cal.xscr[i];
00103                 break;
00104         }
00105     }
00106 } 
00107 
00108 void ts_get_target(int nth, int *x, int *y)
00109 {
00110     *x = cal.xscr[nth];
00111     *y = cal.yscr[nth];
00112 }
00113 
00114 void ts_get_current_target(int *x, int *y)
00115 {
00116     *x = cal.xscr[event];
00117     *y = cal.yscr[event];
00118 }
00119 
00120 int sort_by_x (const void* a, const void *b)
00121 {
00122     return (((struct point *)a)->x - ((struct point *)b)->x);
00123 }
00124 
00125 int sort_by_y (const void* a, const void *b)
00126 {
00127     return (((struct point *)a)->y - ((struct point *)b)->y);
00128 }
00129 
00130 void ts_write_calibration(char *filename)
00131 {
00132     TS_CAL tc;
00133     int xtrans, ytrans, xscale, yscale, xyscale, yxscale;
00134     
00135     FILE *fp;
00136     if (flag_debug)
00137         printf ("constants are: %d %d %d %d %d %d %d\n", 
00138                 cal.a[1], 
00139                 cal.a[2], 
00140                 cal.a[0], 
00141                 cal.a[4], 
00142                 cal.a[5], 
00143                 cal.a[3], 
00144                 cal.a[6]);
00145     
00146     fp = fopen (filename, "w");
00147     if (!fp)
00148     {
00149         perror (filename);
00150         exit (1);
00151     }
00152     fprintf (fp, "%d %d %d %d %d %d %d\n", 
00153             cal.a[1], 
00154             cal.a[2], 
00155             cal.a[0], 
00156             cal.a[4], 
00157             cal.a[5], 
00158             cal.a[3], 
00159             cal.a[6]);
00160     fclose (fp); 
00161     return;
00162     
00163     xtrans = cal.a[0] / cal.a[6];
00164     ytrans = cal.a[3] / cal.a[6];
00165     xscale = cal.a[1] * 256 / cal.a[6];
00166     yscale = cal.a[5] * 256 / cal.a[6];
00167     xyscale = cal.a[2] * 256 / cal.a[6];
00168     yxscale = cal.a[4] * 256 / cal.a[6];
00169     
00170     tc.xtrans = xtrans;
00171     tc.ytrans = ytrans;
00172     tc.xscale = xscale;
00173     tc.yscale = yscale;
00174     tc.xyswap = 0;
00175     
00176     printf ("%d %d %d %d %d\n", 
00177             tc.xscale, tc.xtrans, tc.yscale, tc.ytrans, tc.xyswap);
00178     
00179     if (ioctl (ts_fd, TS_SET_CAL, (void *)&tc) != 0)
00180     {
00181         perror ("TS_SET_CAL");
00182         exit (1);
00183     }
00184 }
00185 
00186 int validate_input(int xin, int yin, int pos)
00187 {
00188     int xconv, yconv;
00189     
00190     xconv = (a_cur[2] + a_cur[0] * xin + a_cur[1] * yin) / a_cur[6];
00191     yconv = (a_cur[5] + a_cur[3] * xin + a_cur[4] * yin) / a_cur[6];
00192     
00193     if (flag_debug)
00194         printf ("validate delta X %d, delta Y %d, checkval %d\n", 
00195                 (xconv - cal.xfb[pos]),
00196                 (yconv - cal.yfb[pos]), 
00197                 abs(xconv - cal.xfb[pos]) + abs(yconv - cal.yfb[pos]));
00198     
00199     // Check to see if the converted x/y is far from current settings
00200     if (abs(xconv - cal.xfb[pos]) + abs(yconv - cal.yfb[pos]) > ALLOWED_OFFSET)
00201     {
00202         fprintf(stderr, "xconv=%d, yconv=%d, cal.xfb[%d]=%d, cal.yfb[%d]=%d (%d > %d)\n", 
00203                 xconv, yconv, pos, cal.xfb[pos], pos, cal.yfb[pos], 
00204                 abs(xconv - cal.xfb[pos]) + abs(yconv - cal.yfb[pos]), 
00205                 ALLOWED_OFFSET);
00206         return 0;
00207     }
00208     return 1;
00209 }
00210 
00211 int ts_handle_event (int x, int y, int pressure)
00212 {
00213     if (pressure)
00214     {
00215         if (samples < MAX_SAMPLES)
00216         {
00217             sample[samples].x = x;
00218             sample[samples].y = y;
00219             samples++;
00220         }
00221     }
00222     else
00223     {
00224         if (samples > ENOUGH)
00225         {
00226             int middle, sx, sy;
00227             
00228             middle = samples / 2;
00229             qsort (sample, samples, sizeof(struct point), sort_by_x);
00230             if (samples & 1)
00231                 sx = sample[middle].x;
00232             else
00233                 sx = (sample[middle-1].x + sample[middle].x) / 2;
00234             qsort (sample, samples, sizeof(struct point), sort_by_y);
00235             if (samples & 1)
00236                 sy = sample[middle].y;
00237             else
00238                 sy = (sample[middle-1].y + sample[middle].y) / 2;
00239             
00240             cal.x[event] = sx;
00241             cal.y[event] = sy;
00242             
00243             if (flag_sanityCheck && !validate_input(cal.x[event], cal.y[event], event))
00244             {
00245                 fprintf(stderr, "Invalid input!\n");
00246                 samples = 0;
00247                 return TS_CALIBRATION_IN_PROGRESS;
00248             }
00249             
00250             if (flag_debug)
00251                 fprintf (stderr, "point %d: [%d %d]\n", 
00252                         event, cal.x[event], cal.y[event]);
00253 
00254             event++;
00255             
00256             if (event < NR_POINTS)
00257             {
00258                 samples = 0;
00259                 next_target();
00260             }
00261             else
00262             {
00263                 if (perform_calibration (&cal))
00264                 {
00265                     return TS_CALIBRATION_DONE;
00266                 }
00267                 else
00268                 {
00269                     samples = 0;
00270                     event = 0;
00271                     next_target();
00272                 }
00273             }
00274         }
00275     }
00276     return TS_CALIBRATION_IN_PROGRESS;
00277 }
00278 
00279 void ts_set_calibration(char **args)
00280 {
00281     TS_CAL tc;
00282     
00283     tc.xscale = atoi (args[0]);
00284     tc.xtrans = atoi (args[1]);
00285     tc.yscale = atoi (args[2]);
00286     tc.ytrans = atoi (args[3]);
00287     tc.xyswap = atoi (args[4]);
00288     
00289     if (flag_debug)
00290         fprintf (stderr, "setting: %d %d %d %d %d\n", 
00291                  tc.xtrans, tc.ytrans, tc.xscale, tc.yscale, tc.xyswap);
00292     
00293     if (ioctl (ts_fd, TS_SET_CAL, (void *)&tc) != 0)
00294     {
00295         perror ("TS_SET_CAL");
00296         exit (1);
00297     }
00298 }
00299 
00300 void ts_show_calibration (void)
00301 {
00302     TS_CAL tc;
00303     
00304     if (ioctl (ts_fd, TS_GET_CAL, (void *)&tc) != 0)
00305     {
00306         perror ("TS_GET_CAL");
00307         exit (1);
00308     }
00309     
00310     printf ("%d %d %d %d %d\n", 
00311             tc.xscale, tc.xtrans, tc.yscale, tc.ytrans, tc.xyswap);
00312 }
00313 
00314 void ts_read_current_settings(char *filename)
00315 {
00316     FILE* fp = NULL;
00317     
00318     // give default value in case the pointercal does not exist
00319    // 4317 -4 -2205916 8 -4189 84612704 65536
00320     a_cur[0] = 4317;
00321     a_cur[1] = -4;
00322     a_cur[2] = -2205916;
00323     a_cur[3] = 8;
00324     a_cur[4] = -4189;
00325     a_cur[5] = 84612704;
00326     a_cur[6] = 65536;
00327 
00328     if ((fp = fopen(filename, "r")) != NULL)
00329     {
00330         fscanf(fp, "%d %d %d %d %d %d %d",
00331                a_cur + 0,
00332                a_cur + 1,
00333                a_cur + 2,
00334                a_cur + 3,
00335                a_cur + 4,
00336                a_cur + 5,
00337                a_cur + 6);
00338         
00339         fclose(fp);
00340     }
00341 }
00342 
Generated by  doxygen 1.6.2-20100208