Mercurial > sdl-ios-xcode
annotate src/video/fbcon/SDL_fbelo.c @ 893:8762a202f121
Fixed crash on exit
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sun, 16 May 2004 19:02:19 +0000 |
parents | b8d311d90021 |
children | 36f24cdfcda7 |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
769
b8d311d90021
Updated copyright information for 2004 (Happy New Year!)
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
3 Copyright (C) 1997-2004 Sam Lantinga |
0 | 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 | |
252
e8157fcb3114
Updated the source with the correct e-mail address
Sam Lantinga <slouken@libsdl.org>
parents:
152
diff
changeset
|
20 slouken@libsdl.org |
0 | 21 */ |
22 | |
23 #ifdef SAVE_RCSID | |
24 static char rcsid = | |
25 "@(#) $Id$"; | |
26 #endif | |
27 | |
28 #include <stdlib.h> | |
29 #include <unistd.h> | |
30 #include <sys/time.h> | |
31 #include <ctype.h> | |
152 | 32 #include <string.h> |
0 | 33 |
34 #include "SDL_fbvideo.h" | |
35 #include "SDL_fbelo.h" | |
36 | |
37 /* | |
38 calibration default values | |
39 values are read from the following environment variables: | |
40 | |
41 SDL_ELO_MIN_X | |
42 SDL_ELO_MAX_X | |
43 SDL_ELO_MIN_Y | |
44 SDL_ELO_MAX_Y | |
45 */ | |
46 | |
47 static int ELO_MIN_X = 400; | |
48 static int ELO_MAX_X = 3670; | |
49 static int ELO_MIN_Y = 500; | |
50 static int ELO_MAX_Y = 3540; | |
51 | |
52 #define ELO_SNAP_SIZE 6 | |
53 #define ELO_TOUCH_BYTE 'T' | |
54 #define ELO_ID 'I' | |
55 #define ELO_MODE 'M' | |
56 #define ELO_PARAMETER 'P' | |
57 #define ELO_REPORT 'B' | |
58 #define ELO_ACK 'A' | |
59 | |
60 #define ELO_INIT_CHECKSUM 0xAA | |
61 | |
62 #define ELO_BTN_PRESS 0x01 | |
63 #define ELO_STREAM 0x02 | |
64 #define ELO_BTN_RELEASE 0x04 | |
65 | |
66 #define ELO_TOUCH_MODE 0x01 | |
67 #define ELO_STREAM_MODE 0x02 | |
68 #define ELO_UNTOUCH_MODE 0x04 | |
69 #define ELO_RANGE_CHECK_MODE 0x40 | |
70 #define ELO_TRIM_MODE 0x02 | |
71 #define ELO_CALIB_MODE 0x04 | |
72 #define ELO_SCALING_MODE 0x08 | |
73 #define ELO_TRACKING_MODE 0x40 | |
74 | |
75 #define ELO_SERIAL_MASK 0xF8 | |
76 | |
77 #define ELO_SERIAL_IO '0' | |
78 | |
79 #define ELO_MAX_TRIALS 3 | |
80 #define ELO_MAX_WAIT 100000 | |
81 #define ELO_UNTOUCH_DELAY 5 | |
82 #define ELO_REPORT_DELAY 1 | |
83 | |
84 /* eloParsePacket | |
85 */ | |
86 int eloParsePacket(unsigned char* mousebuf, int* dx, int* dy, int* button_state) { | |
87 static int elo_button = 0; | |
88 static int last_x = 0; | |
89 static int last_y = 0; | |
90 int x,y; | |
91 | |
92 /* Check if we have a touch packet */ | |
93 if (mousebuf[1] != ELO_TOUCH_BYTE) { | |
94 return 0; | |
95 } | |
96 | |
97 x = ((mousebuf[4] << 8) | mousebuf[3]); | |
98 y = ((mousebuf[6] << 8) | mousebuf[5]); | |
99 | |
100 if((abs(x - last_x) > ELO_SNAP_SIZE) || (abs(y - last_y) > ELO_SNAP_SIZE)) { | |
101 *dx = ((mousebuf[4] << 8) | mousebuf[3]); | |
102 *dy = ((mousebuf[6] << 8) | mousebuf[5]); | |
103 } | |
104 else { | |
105 *dx = last_x; | |
106 *dy = last_y; | |
107 } | |
108 | |
109 last_x = *dx; | |
110 last_y = *dy; | |
111 | |
112 if ( (mousebuf[2] & 0x07) == ELO_BTN_PRESS ) { | |
113 elo_button = 1; | |
114 } | |
115 if ( (mousebuf[2] & 0x07) == ELO_BTN_RELEASE ) { | |
116 elo_button = 0; | |
117 } | |
118 | |
119 *button_state = elo_button; | |
120 return 1; | |
121 } | |
122 | |
123 /* Convert the raw coordinates from the ELO controller | |
124 to a screen position. | |
125 */ | |
126 void eloConvertXY(_THIS, int *dx, int *dy) { | |
127 int input_x = *dx; | |
128 int input_y = *dy; | |
129 int width = ELO_MAX_X - ELO_MIN_X; | |
130 int height = ELO_MAX_Y - ELO_MIN_Y; | |
131 | |
132 *dx = (cache_vinfo.xres - (cache_vinfo.xres * (input_x - ELO_MIN_X)) / width); | |
133 *dy = (cache_vinfo.yres * (input_y - ELO_MIN_Y)) / height; | |
134 } | |
135 | |
136 | |
137 /* eloGetPacket | |
138 */ | |
139 int eloGetPacket(unsigned char* buffer, int* buffer_p, int* checksum, int fd) { | |
140 int num_bytes; | |
141 int ok; | |
142 | |
143 if(fd == 0) { | |
144 num_bytes = ELO_PACKET_SIZE; | |
145 } | |
146 else { | |
147 num_bytes = read(fd, | |
148 (char *) (buffer + *buffer_p), | |
149 ELO_PACKET_SIZE - *buffer_p); | |
150 } | |
151 | |
152 if (num_bytes < 0) { | |
153 #ifdef DEBUG_MOUSE | |
154 fprintf(stderr, "System error while reading from Elographics touchscreen.\n"); | |
155 #endif | |
156 return 0; | |
157 } | |
158 | |
159 while (num_bytes) { | |
160 if ((*buffer_p == 0) && (buffer[0] != ELO_START_BYTE)) { | |
161 memcpy(&buffer[0], &buffer[1], num_bytes-1); | |
162 } | |
163 else { | |
164 if (*buffer_p < ELO_PACKET_SIZE-1) { | |
165 *checksum = *checksum + buffer[*buffer_p]; | |
166 *checksum = *checksum % 256; | |
167 } | |
168 (*buffer_p)++; | |
169 } | |
170 num_bytes--; | |
171 } | |
172 | |
173 if (*buffer_p == ELO_PACKET_SIZE) { | |
174 ok = (*checksum == buffer[ELO_PACKET_SIZE-1]); | |
175 *checksum = ELO_INIT_CHECKSUM; | |
176 *buffer_p = 0; | |
177 | |
178 if (!ok) { | |
179 return 0; | |
180 } | |
181 | |
182 return 1; | |
183 } | |
184 else { | |
185 return 0; | |
186 } | |
187 } | |
188 | |
189 /* eloSendPacket | |
190 */ | |
191 | |
192 int eloSendPacket(unsigned char* packet, int fd) | |
193 { | |
194 int i, result; | |
195 int sum = ELO_INIT_CHECKSUM; | |
196 | |
197 packet[0] = ELO_START_BYTE; | |
198 for (i = 0; i < ELO_PACKET_SIZE-1; i++) { | |
199 sum += packet[i]; | |
200 sum &= 0xFF; | |
201 } | |
202 packet[ELO_PACKET_SIZE-1] = sum; | |
203 | |
204 result = write(fd, packet, ELO_PACKET_SIZE); | |
205 | |
206 if (result != ELO_PACKET_SIZE) { | |
207 #ifdef DEBUG_MOUSE | |
208 printf("System error while sending to Elographics touchscreen.\n"); | |
209 #endif | |
210 return 0; | |
211 } | |
212 else { | |
213 return 1; | |
214 } | |
215 } | |
216 | |
217 | |
218 /* eloWaitForInput | |
219 */ | |
220 int eloWaitForInput(int fd, int timeout) | |
221 { | |
222 fd_set readfds; | |
223 struct timeval to; | |
224 int r; | |
225 | |
226 FD_ZERO(&readfds); | |
227 FD_SET(fd, &readfds); | |
228 to.tv_sec = 0; | |
229 to.tv_usec = timeout; | |
230 | |
231 r = select(FD_SETSIZE, &readfds, NULL, NULL, &to); | |
232 return r; | |
233 } | |
234 | |
235 /* eloWaitReply | |
236 */ | |
237 int eloWaitReply(unsigned char type, unsigned char *reply, int fd) { | |
238 int ok; | |
239 int i, result; | |
240 int reply_p = 0; | |
241 int sum = ELO_INIT_CHECKSUM; | |
242 | |
243 i = ELO_MAX_TRIALS; | |
244 do { | |
245 ok = 0; | |
246 | |
247 result = eloWaitForInput(fd, ELO_MAX_WAIT); | |
248 | |
249 if (result > 0) { | |
250 ok = eloGetPacket(reply, &reply_p, &sum, fd); | |
251 | |
252 if (ok && reply[1] != type && type != ELO_PARAMETER) { | |
253 #ifdef DEBUG_MOUSE | |
254 fprintf(stderr, "Wrong reply received\n"); | |
255 #endif | |
256 ok = 0; | |
257 } | |
258 } | |
259 else { | |
260 #ifdef DEBUG_MOUSE | |
261 fprintf(stderr, "No input!\n"); | |
262 #endif | |
263 } | |
264 | |
265 if (result == 0) { | |
266 i--; | |
267 } | |
268 } while(!ok && (i>0)); | |
269 | |
270 return ok; | |
271 } | |
272 | |
273 | |
274 /* eloWaitAck | |
275 */ | |
276 | |
277 int eloWaitAck(int fd) { | |
278 unsigned char packet[ELO_PACKET_SIZE]; | |
279 int i, nb_errors; | |
280 | |
281 if (eloWaitReply(ELO_ACK, packet, fd)) { | |
282 for (i = 0, nb_errors = 0; i < 4; i++) { | |
283 if (packet[2 + i] != '0') { | |
284 nb_errors++; | |
285 } | |
286 } | |
287 | |
288 if (nb_errors != 0) { | |
289 #ifdef DEBUG_MOUSE | |
290 fprintf(stderr, "Elographics acknowledge packet reports %d errors\n", nb_errors); | |
291 #endif | |
292 } | |
293 return 1; | |
294 } | |
295 else { | |
296 return 0; | |
297 } | |
298 } | |
299 | |
300 | |
301 /* eloSendQuery -- | |
302 */ | |
303 int eloSendQuery(unsigned char *request, unsigned char* reply, int fd) { | |
304 int ok; | |
305 | |
306 if (eloSendPacket(request, fd)) { | |
307 ok = eloWaitReply(toupper(request[1]), reply, fd); | |
308 if (ok) { | |
309 ok = eloWaitAck(fd); | |
310 } | |
311 return ok; | |
312 } | |
313 else { | |
314 return 0; | |
315 } | |
316 } | |
317 | |
318 | |
319 /* eloSendControl | |
320 */ | |
321 int eloSendControl(unsigned char* control, int fd) { | |
322 if (eloSendPacket(control, fd)) { | |
323 return eloWaitAck(fd); | |
324 } | |
325 else { | |
326 return 0; | |
327 } | |
328 } | |
329 | |
330 /* eloInitController | |
331 */ | |
332 int eloInitController(int fd) { | |
333 unsigned char req[ELO_PACKET_SIZE]; | |
334 unsigned char reply[ELO_PACKET_SIZE]; | |
335 const char *buffer = NULL; | |
336 int result = 0; | |
337 | |
338 struct termios mouse_termios; | |
339 | |
340 /* try to read the calibration values */ | |
341 buffer = getenv("SDL_ELO_MIN_X"); | |
342 if(buffer) { | |
343 ELO_MIN_X = atoi(buffer); | |
344 } | |
345 buffer = getenv("SDL_ELO_MAX_X"); | |
346 if(buffer) { | |
347 ELO_MAX_X = atoi(buffer); | |
348 } | |
349 buffer = getenv("SDL_ELO_MIN_Y"); | |
350 if(buffer) { | |
351 ELO_MIN_Y = atoi(buffer); | |
352 } | |
353 buffer = getenv("SDL_ELO_MAX_Y"); | |
354 if(buffer) { | |
355 ELO_MAX_Y = atoi(buffer); | |
356 } | |
357 | |
358 #ifdef DEBUG_MOUSE | |
359 fprintf( stderr, "ELO calibration values:\nmin_x: %i\nmax_x: %i\nmin_y: %i\nmax_y: %i\n", | |
360 ELO_MIN_X, | |
361 ELO_MAX_X, | |
362 ELO_MIN_Y, | |
363 ELO_MAX_Y); | |
364 #endif | |
365 | |
366 /* set comm params */ | |
367 memset(&mouse_termios, 0, sizeof(mouse_termios)); | |
368 mouse_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL; | |
369 mouse_termios.c_cc[VMIN] = 1; | |
370 result = tcsetattr(fd, TCSANOW, &mouse_termios); | |
371 | |
372 if (result < 0) { | |
373 #ifdef DEBUG_MOUSE | |
374 fprintf( stderr, "Unable to configure Elographics touchscreen port\n"); | |
375 #endif | |
376 return 0; | |
377 } | |
378 | |
379 memset(req, 0, ELO_PACKET_SIZE); | |
380 req[1] = tolower(ELO_PARAMETER); | |
381 if (!eloSendQuery(req, reply, fd)) { | |
382 #ifdef DEBUG_MOUSE | |
383 fprintf( stderr, "Not at the specified rate or model 2310, will continue\n"); | |
384 #endif | |
385 } | |
386 | |
387 memset(req, 0, ELO_PACKET_SIZE); | |
388 req[1] = tolower(ELO_ID); | |
389 if (eloSendQuery(req, reply, fd)) { | |
390 #ifdef DEBUG_MOUSE | |
391 fprintf(stderr, "Ok, controller configured!\n"); | |
392 #endif | |
393 } | |
394 else { | |
395 #ifdef DEBUG_MOUSE | |
396 fprintf( stderr, "Unable to ask Elographics touchscreen identification\n"); | |
397 #endif | |
398 return 0; | |
399 } | |
400 | |
401 memset(req, 0, ELO_PACKET_SIZE); | |
402 req[1] = ELO_MODE; | |
403 req[3] = ELO_TOUCH_MODE | ELO_STREAM_MODE | ELO_UNTOUCH_MODE; | |
404 req[4] = ELO_TRACKING_MODE; | |
405 if (!eloSendControl(req, fd)) { | |
406 #ifdef DEBUG_MOUSE | |
407 fprintf( stderr, "Unable to change Elographics touchscreen operating mode\n"); | |
408 #endif | |
409 return 0; | |
410 } | |
411 | |
412 memset(req, 0, ELO_PACKET_SIZE); | |
413 req[1] = ELO_REPORT; | |
414 req[2] = ELO_UNTOUCH_DELAY; | |
415 req[3] = ELO_REPORT_DELAY; | |
416 if (!eloSendControl(req, fd)) { | |
417 #ifdef DEBUG_MOUSE | |
418 fprintf( stderr, "Unable to change Elographics touchscreen reports timings\n"); | |
419 #endif | |
420 return 0; | |
421 } | |
422 | |
423 return 1; | |
424 } | |
4
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
425 |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
426 int eloReadPosition(_THIS, int fd, int* x, int* y, int* button_state, int* realx, int* realy) { |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
427 unsigned char buffer[ELO_PACKET_SIZE]; |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
428 int pointer = 0; |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
429 int checksum = ELO_INIT_CHECKSUM; |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
430 |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
431 while(pointer < ELO_PACKET_SIZE) { |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
432 if(eloGetPacket(buffer, &pointer, &checksum, fd)) { |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
433 break; |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
434 } |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
435 } |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
436 |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
437 if(!eloParsePacket(buffer, realx, realy, button_state)) { |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
438 return 0; |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
439 } |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
440 |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
441 *x = *realx; |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
442 *y = *realy; |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
443 |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
444 eloConvertXY(this, x, y); |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
445 |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
446 return 1; |
4f6c5f021323
Date: Thu, 26 Apr 2001 10:46:23 +0200
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
447 } |