SDL_fbelo.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:9k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

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