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