src/video/fbcon/SDL_fbelo.c

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. eloParsePacket
  2. eloConvertXY
  3. eloGetPacket
  4. eloSendPacket
  5. eloWaitForInput
  6. eloWaitReply
  7. eloWaitAck
  8. eloSendQuery
  9. eloSendControl
  10. eloInitController

   1 /*
   2     SDL - Simple DirectMedia Layer
   3     Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
   4 
   5     This library is free software; you can redistribute it and/or
   6     modify it under the terms of the GNU Library General Public
   7     License as published by the Free Software Foundation; either
   8     version 2 of the License, or (at your option) any later version.
   9 
  10     This library is distributed in the hope that it will be useful,
  11     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13     Library General Public License for more details.
  14 
  15     You should have received a copy of the GNU Library General Public
  16     License along with this library; if not, write to the Free
  17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18 
  19     Sam Lantinga
  20     slouken@devolution.com
  21 */
  22 
  23 #ifdef SAVE_RCSID
  24 static char rcsid =
  25  "@(#) $Id: SDL_fbelo.c,v 1.1.2.3 2001/02/28 12:06:11 hercules Exp $";
  26 #endif
  27 
  28 #include <stdlib.h>
  29 #include <unistd.h>
  30 #include <sys/time.h>
  31 #include <ctype.h>
  32 
  33 #include "SDL_fbvideo.h"
  34 #include "SDL_fbelo.h"
  35 
  36 /*
  37         calibration default values
  38         values are read from the following environment variables:
  39 
  40         SDL_ELO_MIN_X
  41         SDL_ELO_MAX_X
  42         SDL_ELO_MIN_Y
  43         SDL_ELO_MAX_Y
  44 */
  45 
  46 static int ELO_MIN_X = 400;
  47 static int ELO_MAX_X = 3670;
  48 static int ELO_MIN_Y = 500;
  49 static int ELO_MAX_Y = 3540;
  50 
  51 #define ELO_SNAP_SIZE 6
  52 #define ELO_TOUCH_BYTE          'T'     
  53 #define ELO_ID                  'I'
  54 #define ELO_MODE                'M'
  55 #define ELO_PARAMETER           'P'
  56 #define ELO_REPORT              'B'
  57 #define ELO_ACK                 'A'     
  58 
  59 #define ELO_INIT_CHECKSUM       0xAA
  60 
  61 #define ELO_BTN_PRESS           0x01    
  62 #define ELO_STREAM              0x02
  63 #define ELO_BTN_RELEASE         0x04
  64 
  65 #define ELO_TOUCH_MODE          0x01
  66 #define ELO_STREAM_MODE         0x02
  67 #define ELO_UNTOUCH_MODE        0x04
  68 #define ELO_RANGE_CHECK_MODE    0x40
  69 #define ELO_TRIM_MODE           0x02
  70 #define ELO_CALIB_MODE          0x04
  71 #define ELO_SCALING_MODE        0x08
  72 #define ELO_TRACKING_MODE       0x40
  73 
  74 #define ELO_SERIAL_MASK         0xF8
  75 
  76 #define ELO_SERIAL_IO           '0'
  77 
  78 #define ELO_MAX_TRIALS  3
  79 #define ELO_MAX_WAIT            100000
  80 #define ELO_UNTOUCH_DELAY       5
  81 #define ELO_REPORT_DELAY        1
  82 
  83 /*      eloParsePacket
  84 */
  85 int eloParsePacket(unsigned char* mousebuf, int* dx, int* dy, int* button_state) {
     /* [<][>][^][v][top][bottom][index][help] */
  86         static int elo_button = 0;
  87         static int last_x = 0;
  88         static int last_y = 0;
  89         int x,y;
  90 
  91         /* Check if we have a touch packet */
  92         if (mousebuf[1] != ELO_TOUCH_BYTE) {
  93                 return 0;
  94         }
  95 
  96         x = ((mousebuf[4] << 8) | mousebuf[3]);
  97         y = ((mousebuf[6] << 8) | mousebuf[5]);
  98 
  99         if((abs(x - last_x) > ELO_SNAP_SIZE) || (abs(y - last_y) > ELO_SNAP_SIZE)) {
 100                 *dx = ((mousebuf[4] << 8) | mousebuf[3]);
 101                 *dy = ((mousebuf[6] << 8) | mousebuf[5]);
 102         }
 103         else {
 104                 *dx = last_x;
 105                 *dy = last_y;
 106         }
 107 
 108         last_x = *dx;
 109         last_y = *dy;
 110 
 111         if ( (mousebuf[2] & 0x07) == ELO_BTN_PRESS ) {
 112                 elo_button = 1;
 113         }
 114         if ( (mousebuf[2] & 0x07) == ELO_BTN_RELEASE ) {
 115                 elo_button = 0;
 116         }
 117 
 118         *button_state = elo_button;
 119         return 1;
 120 }
 121 
 122 /*      Convert the raw coordinates from the ELO controller
 123         to a screen position.
 124 */
 125 void eloConvertXY(_THIS, int *dx,  int *dy) {
     /* [<][>][^][v][top][bottom][index][help] */
 126         int input_x = *dx;
 127         int input_y = *dy;
 128         int width = ELO_MAX_X - ELO_MIN_X;
 129         int height = ELO_MAX_Y - ELO_MIN_Y;
 130 
 131         *dx = (cache_vinfo.xres - (cache_vinfo.xres * (input_x - ELO_MIN_X)) / width);
 132         *dy = (cache_vinfo.yres * (input_y - ELO_MIN_Y)) / height;
 133 }
 134 
 135 
 136 /*      eloGetPacket
 137 */
 138 int eloGetPacket(unsigned char* buffer, int* buffer_p, int* checksum, int fd) {
     /* [<][>][^][v][top][bottom][index][help] */
 139         int num_bytes;
 140         int ok;
 141 
 142         if(fd == 0) {
 143                 num_bytes = ELO_PACKET_SIZE;
 144         }
 145         else {
 146                 num_bytes = read(fd,
 147                         (char *) (buffer + *buffer_p),
 148                         ELO_PACKET_SIZE - *buffer_p);
 149         }
 150 
 151         if (num_bytes < 0) {
 152 #ifdef DEBUG_MOUSE
 153                 fprintf(stderr, "System error while reading from Elographics touchscreen.\n");
 154 #endif
 155                 return 0;
 156         }
 157 
 158         while (num_bytes) {
 159                 if ((*buffer_p == 0) && (buffer[0] != ELO_START_BYTE)) {
 160                         memcpy(&buffer[0], &buffer[1], num_bytes-1);
 161                 }
 162                 else {
 163                         if (*buffer_p < ELO_PACKET_SIZE-1) {
 164                                 *checksum = *checksum + buffer[*buffer_p];
 165                                 *checksum = *checksum % 256;
 166                         }
 167                         (*buffer_p)++;
 168                 }
 169                 num_bytes--;
 170         }
 171 
 172         if (*buffer_p == ELO_PACKET_SIZE) {
 173                 ok = (*checksum == buffer[ELO_PACKET_SIZE-1]);
 174                 *checksum = ELO_INIT_CHECKSUM;
 175                 *buffer_p = 0;
 176 
 177                 if (!ok) {
 178                         return 0;
 179                 }
 180 
 181                 return 1;
 182         }
 183         else {
 184                 return 0;
 185         }
 186 }
 187 
 188 /* eloSendPacket
 189 */
 190 
 191 int eloSendPacket(unsigned char* packet, int fd)
     /* [<][>][^][v][top][bottom][index][help] */
 192 {
 193         int i, result;
 194         int sum = ELO_INIT_CHECKSUM;
 195 
 196         packet[0] = ELO_START_BYTE;
 197         for (i = 0; i < ELO_PACKET_SIZE-1; i++) {
 198                 sum += packet[i];
 199                 sum &= 0xFF;
 200         }
 201         packet[ELO_PACKET_SIZE-1] = sum;
 202 
 203         result = write(fd, packet, ELO_PACKET_SIZE);
 204 
 205         if (result != ELO_PACKET_SIZE) {
 206 #ifdef DEBUG_MOUSE
 207                 printf("System error while sending to Elographics touchscreen.\n");
 208 #endif
 209                 return 0;
 210         }
 211         else {
 212                 return 1;
 213         }
 214 }
 215 
 216 
 217 /*      eloWaitForInput
 218  */
 219 int eloWaitForInput(int fd, int timeout)
     /* [<][>][^][v][top][bottom][index][help] */
 220 {
 221         fd_set readfds;
 222         struct timeval to;
 223         int r;
 224 
 225         FD_ZERO(&readfds);
 226         FD_SET(fd, &readfds);
 227         to.tv_sec = 0;
 228         to.tv_usec = timeout;
 229 
 230         r = select(FD_SETSIZE, &readfds, NULL, NULL, &to);
 231         return r;
 232 }
 233 
 234 /*      eloWaitReply
 235  */
 236 int eloWaitReply(unsigned char type, unsigned char *reply, int fd) {
     /* [<][>][^][v][top][bottom][index][help] */
 237         int ok;
 238         int i, result;
 239         int reply_p = 0;
 240         int sum = ELO_INIT_CHECKSUM;
 241 
 242         i = ELO_MAX_TRIALS;
 243         do {
 244                 ok = 0;
 245 
 246                 result = eloWaitForInput(fd, ELO_MAX_WAIT);
 247 
 248                 if (result > 0) {
 249                         ok = eloGetPacket(reply, &reply_p, &sum, fd);
 250 
 251                         if (ok && reply[1] != type && type != ELO_PARAMETER) {
 252 #ifdef DEBUG_MOUSE
 253                                 fprintf(stderr, "Wrong reply received\n");
 254 #endif
 255                                 ok = 0;
 256                         }
 257                 }
 258                 else {
 259 #ifdef DEBUG_MOUSE
 260                         fprintf(stderr, "No input!\n");
 261 #endif
 262                 }
 263 
 264                 if (result == 0) {
 265                         i--;
 266                 }
 267         } while(!ok && (i>0));
 268 
 269         return ok;
 270 }
 271 
 272 
 273 /*      eloWaitAck
 274  */
 275 
 276 int eloWaitAck(int fd) {
     /* [<][>][^][v][top][bottom][index][help] */
 277         unsigned char packet[ELO_PACKET_SIZE];
 278         int i, nb_errors;
 279 
 280         if (eloWaitReply(ELO_ACK, packet, fd)) {
 281                 for (i = 0, nb_errors = 0; i < 4; i++) {
 282                         if (packet[2 + i] != '0') {
 283                                 nb_errors++;
 284                         }
 285                 }
 286 
 287                 if (nb_errors != 0) {
 288 #ifdef DEBUG_MOUSE
 289                         fprintf(stderr, "Elographics acknowledge packet reports %d errors\n", nb_errors);
 290 #endif
 291                 }
 292                 return 1;
 293         }
 294         else {
 295                 return 0;
 296         }
 297 }
 298 
 299 
 300 /*      eloSendQuery --
 301 */
 302 int eloSendQuery(unsigned char *request, unsigned char* reply, int fd) {
     /* [<][>][^][v][top][bottom][index][help] */
 303         int ok;
 304 
 305         if (eloSendPacket(request, fd)) {
 306                 ok = eloWaitReply(toupper(request[1]), reply, fd);
 307                 if (ok) {
 308                         ok = eloWaitAck(fd);
 309                 }
 310                 return ok;
 311         }
 312         else {
 313                 return 0;
 314         }
 315 }
 316 
 317 
 318 /*      eloSendControl
 319 */
 320 int eloSendControl(unsigned char* control, int fd) {
     /* [<][>][^][v][top][bottom][index][help] */
 321         if (eloSendPacket(control, fd)) {
 322                 return eloWaitAck(fd);
 323         }
 324         else {
 325                 return 0;
 326         }
 327 }
 328 
 329 /*      eloInitController
 330 */
 331 int eloInitController(int fd) {
     /* [<][>][^][v][top][bottom][index][help] */
 332         unsigned char req[ELO_PACKET_SIZE];
 333         unsigned char reply[ELO_PACKET_SIZE];
 334         const char *buffer = NULL;
 335         int result = 0;
 336 
 337         struct termios mouse_termios;
 338 
 339         /* try to read the calibration values */
 340         buffer = getenv("SDL_ELO_MIN_X");
 341         if(buffer) {
 342                 ELO_MIN_X = atoi(buffer);
 343         }
 344         buffer = getenv("SDL_ELO_MAX_X");
 345         if(buffer) {
 346                 ELO_MAX_X = atoi(buffer);
 347         }
 348         buffer = getenv("SDL_ELO_MIN_Y");
 349         if(buffer) {
 350                 ELO_MIN_Y = atoi(buffer);
 351         }
 352         buffer = getenv("SDL_ELO_MAX_Y");
 353         if(buffer) {
 354                 ELO_MAX_Y = atoi(buffer);
 355         }
 356 
 357 #ifdef DEBUG_MOUSE
 358         fprintf( stderr, "ELO calibration values:\nmin_x: %i\nmax_x: %i\nmin_y: %i\nmax_y: %i\n",
 359                 ELO_MIN_X,
 360                 ELO_MAX_X,
 361                 ELO_MIN_Y,
 362                 ELO_MAX_Y);
 363 #endif
 364 
 365         /* set comm params */
 366         memset(&mouse_termios, 0, sizeof(mouse_termios));
 367         mouse_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL;
 368         mouse_termios.c_cc[VMIN] = 1;
 369         result = tcsetattr(fd, TCSANOW, &mouse_termios);
 370 
 371         if (result < 0) {
 372 #ifdef DEBUG_MOUSE
 373                 fprintf( stderr, "Unable to configure Elographics touchscreen port\n");
 374 #endif
 375                 return 0;
 376         }
 377 
 378         memset(req, 0, ELO_PACKET_SIZE);
 379         req[1] = tolower(ELO_PARAMETER);
 380         if (!eloSendQuery(req, reply, fd)) {
 381 #ifdef DEBUG_MOUSE
 382                 fprintf( stderr, "Not at the specified rate or model 2310, will continue\n");
 383 #endif
 384         }
 385 
 386         memset(req, 0, ELO_PACKET_SIZE);
 387         req[1] = tolower(ELO_ID);
 388         if (eloSendQuery(req, reply, fd)) {
 389 #ifdef DEBUG_MOUSE
 390                 fprintf(stderr, "Ok, controller configured!\n");
 391 #endif
 392         }
 393         else {
 394 #ifdef DEBUG_MOUSE
 395                 fprintf( stderr, "Unable to ask Elographics touchscreen identification\n");
 396 #endif
 397                 return 0;
 398         }
 399 
 400         memset(req, 0, ELO_PACKET_SIZE);
 401         req[1] = ELO_MODE;
 402         req[3] = ELO_TOUCH_MODE | ELO_STREAM_MODE | ELO_UNTOUCH_MODE;
 403         req[4] = ELO_TRACKING_MODE;
 404         if (!eloSendControl(req, fd)) {
 405 #ifdef DEBUG_MOUSE
 406                 fprintf( stderr, "Unable to change Elographics touchscreen operating mode\n");
 407 #endif
 408                 return 0;
 409         }
 410 
 411         memset(req, 0, ELO_PACKET_SIZE);
 412         req[1] = ELO_REPORT;
 413         req[2] = ELO_UNTOUCH_DELAY;
 414         req[3] = ELO_REPORT_DELAY;
 415         if (!eloSendControl(req, fd)) {
 416 #ifdef DEBUG_MOUSE
 417                 fprintf( stderr, "Unable to change Elographics touchscreen reports timings\n");
 418 #endif
 419                 return 0;
 420         }
 421 
 422         return 1;
 423 }

/* [<][>][^][v][top][bottom][index][help] */