00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
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     
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     
00319    
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