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

流媒体/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_gsevents.c,v 1.3 2002/04/22 21:38:05 wmay Exp $";
  21. #endif
  22. /* Handle the event stream, converting console events into SDL events */
  23. #include <sys/types.h>
  24. #include <sys/time.h>
  25. #include <sys/ioctl.h>
  26. #include <stdlib.h>
  27. #include <stdio.h>
  28. #include <unistd.h>
  29. #include <fcntl.h>
  30. #include <string.h>
  31. #include <errno.h>
  32. #include <limits.h>
  33. /* For parsing /proc */
  34. #include <dirent.h>
  35. #include <ctype.h>
  36. #include <linux/vt.h>
  37. #include <linux/kd.h>
  38. #include <linux/keyboard.h>
  39. #include "SDL.h"
  40. #include "SDL_mutex.h"
  41. #include "SDL_sysevents.h"
  42. #include "SDL_sysvideo.h"
  43. #include "SDL_events_c.h"
  44. #include "SDL_gsvideo.h"
  45. #include "SDL_gsevents_c.h"
  46. #include "SDL_gskeys.h"
  47. #ifndef GPM_NODE_FIFO
  48. #define GPM_NODE_FIFO "/dev/gpmdata"
  49. #endif
  50. /* The translation tables from a console scancode to a SDL keysym */
  51. #define NUM_VGAKEYMAPS (1<<KG_CAPSSHIFT)
  52. static Uint16 vga_keymap[NUM_VGAKEYMAPS][NR_KEYS];
  53. static SDLKey keymap[128];
  54. static Uint16 keymap_temp[128]; /* only used at startup */
  55. static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym);
  56. /* Ugh, we have to duplicate the kernel's keysym mapping code...
  57.    Oh, it's not so bad. :-)
  58.    FIXME: Add keyboard LED handling code
  59.  */
  60. static void GS_vgainitkeymaps(int fd)
  61. {
  62. struct kbentry entry;
  63. int map, i;
  64. /* Don't do anything if we are passed a closed keyboard */
  65. if ( fd < 0 ) {
  66. return;
  67. }
  68. /* Load all the keysym mappings */
  69. for ( map=0; map<NUM_VGAKEYMAPS; ++map ) {
  70. memset(vga_keymap[map], 0, NR_KEYS*sizeof(Uint16));
  71. for ( i=0; i<NR_KEYS; ++i ) {
  72. entry.kb_table = map;
  73. entry.kb_index = i;
  74. if ( ioctl(fd, KDGKBENT, &entry) == 0 ) {
  75. /* fill keytemp. This replaces SDL_fbkeys.h */
  76. if ( (map == 0) && (i<128) ) {
  77. keymap_temp[i] = entry.kb_value;
  78. }
  79. /* The "Enter" key is a special case */
  80. if ( entry.kb_value == K_ENTER ) {
  81. entry.kb_value = K(KT_ASCII,13);
  82. }
  83. /* Handle numpad specially as well */
  84. if ( KTYP(entry.kb_value) == KT_PAD ) {
  85. switch ( entry.kb_value ) {
  86. case K_P0:
  87. case K_P1:
  88. case K_P2:
  89. case K_P3:
  90. case K_P4:
  91. case K_P5:
  92. case K_P6:
  93. case K_P7:
  94. case K_P8:
  95. case K_P9:
  96. vga_keymap[map][i]=entry.kb_value;
  97. vga_keymap[map][i]+= '0';
  98. break;
  99. case K_PPLUS:
  100. vga_keymap[map][i]=K(KT_ASCII,'+');
  101. break;
  102. case K_PMINUS:
  103. vga_keymap[map][i]=K(KT_ASCII,'-');
  104. break;
  105. case K_PSTAR:
  106. vga_keymap[map][i]=K(KT_ASCII,'*');
  107. break;
  108. case K_PSLASH:
  109. vga_keymap[map][i]=K(KT_ASCII,'/');
  110. break;
  111. case K_PENTER:
  112. vga_keymap[map][i]=K(KT_ASCII,'r');
  113. break;
  114. case K_PCOMMA:
  115. vga_keymap[map][i]=K(KT_ASCII,',');
  116. break;
  117. case K_PDOT:
  118. vga_keymap[map][i]=K(KT_ASCII,'.');
  119. break;
  120. default:
  121. break;
  122. }
  123. }
  124. /* Do the normal key translation */
  125. if ( (KTYP(entry.kb_value) == KT_LATIN) ||
  126.  (KTYP(entry.kb_value) == KT_ASCII) ||
  127.  (KTYP(entry.kb_value) == KT_LETTER) ) {
  128. vga_keymap[map][i] = entry.kb_value;
  129. }
  130. }
  131. }
  132. }
  133. }
  134. int GS_InGraphicsMode(_THIS)
  135. {
  136. return((keyboard_fd >= 0) && (saved_kbd_mode >= 0));
  137. }
  138. int GS_EnterGraphicsMode(_THIS)
  139. {
  140. struct termios keyboard_termios;
  141. /* Set medium-raw keyboard mode */
  142. if ( (keyboard_fd >= 0) && !GS_InGraphicsMode(this) ) {
  143. /* Switch to the correct virtual terminal */
  144. if ( current_vt > 0 ) {
  145. struct vt_stat vtstate;
  146. if ( ioctl(keyboard_fd, VT_GETSTATE, &vtstate) == 0 ) {
  147. saved_vt = vtstate.v_active;
  148. }
  149. if ( ioctl(keyboard_fd, VT_ACTIVATE, current_vt) == 0 ) {
  150. ioctl(keyboard_fd, VT_WAITACTIVE, current_vt);
  151. }
  152. }
  153. /* Set the terminal input mode */
  154. if ( tcgetattr(keyboard_fd, &saved_kbd_termios) < 0 ) {
  155. SDL_SetError("Unable to get terminal attributes");
  156. if ( keyboard_fd > 0 ) {
  157. close(keyboard_fd);
  158. }
  159. keyboard_fd = -1;
  160. return(-1);
  161. }
  162. if ( ioctl(keyboard_fd, KDGKBMODE, &saved_kbd_mode) < 0 ) {
  163. SDL_SetError("Unable to get current keyboard mode");
  164. if ( keyboard_fd > 0 ) {
  165. close(keyboard_fd);
  166. }
  167. keyboard_fd = -1;
  168. return(-1);
  169. }
  170. keyboard_termios = saved_kbd_termios;
  171. keyboard_termios.c_lflag &= ~(ICANON | ECHO | ISIG);
  172. keyboard_termios.c_iflag &= ~(ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON);
  173. keyboard_termios.c_cc[VMIN] = 0;
  174. keyboard_termios.c_cc[VTIME] = 0;
  175. if (tcsetattr(keyboard_fd, TCSAFLUSH, &keyboard_termios) < 0) {
  176. GS_CloseKeyboard(this);
  177. SDL_SetError("Unable to set terminal attributes");
  178. return(-1);
  179. }
  180. /* This will fail if we aren't root or this isn't our tty */
  181. if ( ioctl(keyboard_fd, KDSKBMODE, K_MEDIUMRAW) < 0 ) {
  182. GS_CloseKeyboard(this);
  183. SDL_SetError("Unable to set keyboard in raw mode");
  184. return(-1);
  185. }
  186. if ( ioctl(keyboard_fd, KDSETMODE, KD_GRAPHICS) < 0 ) {
  187. GS_CloseKeyboard(this);
  188. SDL_SetError("Unable to set keyboard in graphics mode");
  189. return(-1);
  190. }
  191. }
  192. return(keyboard_fd);
  193. }
  194. void GS_LeaveGraphicsMode(_THIS)
  195. {
  196. if ( GS_InGraphicsMode(this) ) {
  197. ioctl(keyboard_fd, KDSETMODE, KD_TEXT);
  198. ioctl(keyboard_fd, KDSKBMODE, saved_kbd_mode);
  199. tcsetattr(keyboard_fd, TCSAFLUSH, &saved_kbd_termios);
  200. saved_kbd_mode = -1;
  201. /* Head back over to the original virtual terminal */
  202. if ( saved_vt > 0 ) {
  203. ioctl(keyboard_fd, VT_ACTIVATE, saved_vt);
  204. }
  205. }
  206. }
  207. void GS_CloseKeyboard(_THIS)
  208. {
  209. if ( keyboard_fd >= 0 ) {
  210. GS_LeaveGraphicsMode(this);
  211. if ( keyboard_fd > 0 ) {
  212. close(keyboard_fd);
  213. }
  214. }
  215. keyboard_fd = -1;
  216. }
  217. int GS_OpenKeyboard(_THIS)
  218. {
  219. /* Open only if not already opened */
  220.   if ( keyboard_fd < 0 ) {
  221. char *tty0[] = { "/dev/tty0", "/dev/vc/0", NULL };
  222. char *vcs[] = { "/dev/vc/%d", "/dev/tty%d", NULL };
  223. int i, tty0_fd;
  224. /* Try to query for a free virtual terminal */
  225. tty0_fd = -1;
  226. for ( i=0; tty0[i] && (tty0_fd < 0); ++i ) {
  227. tty0_fd = open(tty0[i], O_WRONLY, 0);
  228. }
  229. if ( tty0_fd < 0 ) {
  230. tty0_fd = dup(0); /* Maybe stdin is a VT? */
  231. }
  232. ioctl(tty0_fd, VT_OPENQRY, &current_vt);
  233. close(tty0_fd);
  234. if ( (geteuid() == 0) && (current_vt > 0) ) {
  235. for ( i=0; vcs[i] && (keyboard_fd < 0); ++i ) {
  236. char vtpath[12];
  237. sprintf(vtpath, vcs[i], current_vt);
  238. keyboard_fd = open(vtpath, O_RDWR, 0);
  239. #ifdef DEBUG_KEYBOARD
  240. fprintf(stderr, "vtpath = %s, fd = %dn",
  241. vtpath, keyboard_fd);
  242. #endif /* DEBUG_KEYBOARD */
  243. /* This needs to be our controlling tty
  244.    so that the kernel ioctl() calls work
  245. */
  246. if ( keyboard_fd >= 0 ) {
  247. tty0_fd = open("/dev/tty", O_RDWR, 0);
  248. if ( tty0_fd >= 0 ) {
  249. ioctl(tty0_fd, TIOCNOTTY, 0);
  250. close(tty0_fd);
  251. }
  252. }
  253. }
  254. }
  255.   if ( keyboard_fd < 0 ) {
  256. /* Last resort, maybe our tty is a usable VT */
  257. current_vt = 0;
  258. keyboard_fd = open("/dev/tty", O_RDWR);
  259.   }
  260. #ifdef DEBUG_KEYBOARD
  261. fprintf(stderr, "Current VT: %dn", current_vt);
  262. #endif
  263.   saved_kbd_mode = -1;
  264. /* Make sure that our input is a console terminal */
  265. { int dummy;
  266.   if ( ioctl(keyboard_fd, KDGKBMODE, &dummy) < 0 ) {
  267. close(keyboard_fd);
  268. keyboard_fd = -1;
  269. SDL_SetError("Unable to open a console terminal");
  270.   }
  271. }
  272. /* Set up keymap */
  273. GS_vgainitkeymaps(keyboard_fd);
  274.   }
  275.   return(keyboard_fd);
  276. }
  277. static enum {
  278. MOUSE_NONE = -1,
  279. MOUSE_GPM, /* Note: GPM uses the MSC protocol */
  280. MOUSE_PS2,
  281. MOUSE_IMPS2,
  282. MOUSE_MS,
  283. MOUSE_BM,
  284. NUM_MOUSE_DRVS
  285. } mouse_drv = MOUSE_NONE;
  286. void GS_CloseMouse(_THIS)
  287. {
  288. if ( mouse_fd > 0 ) {
  289. close(mouse_fd);
  290. }
  291. mouse_fd = -1;
  292. }
  293. /* Returns processes listed in /proc with the desired name */
  294. static int find_pid(DIR *proc, const char *wanted_name)
  295. {
  296. struct dirent *entry;
  297. int pid;
  298. /* First scan proc for the gpm process */
  299. pid = 0;
  300. while ( (pid == 0) && ((entry=readdir(proc)) != NULL) ) {
  301. if ( isdigit(entry->d_name[0]) ) {
  302. FILE *status;
  303. char path[PATH_MAX];
  304. char name[PATH_MAX];
  305. sprintf(path, "/proc/%s/status", entry->d_name);
  306. status=fopen(path, "r");
  307. if ( status ) {
  308. name[0] = '';
  309. fscanf(status, "Name: %s", name);
  310. if ( strcmp(name, wanted_name) == 0 ) {
  311. pid = atoi(entry->d_name);
  312. }
  313. fclose(status);
  314. }
  315. }
  316. }
  317. return pid;
  318. }
  319. /* Returns true if /dev/gpmdata is being written to by gpm */
  320. static int gpm_available(void)
  321. {
  322. int available;
  323. DIR *proc;
  324. int pid;
  325. int cmdline, len, arglen;
  326. char path[PATH_MAX];
  327. char args[PATH_MAX], *arg;
  328. /* Don't bother looking if the fifo isn't there */
  329. if ( access(GPM_NODE_FIFO, F_OK) < 0 ) {
  330. return(0);
  331. }
  332. available = 0;
  333. proc = opendir("/proc");
  334. if ( proc ) {
  335. while ( (pid=find_pid(proc, "gpm")) > 0 ) {
  336. sprintf(path, "/proc/%d/cmdline", pid);
  337. cmdline = open(path, O_RDONLY, 0);
  338. if ( cmdline >= 0 ) {
  339. len = read(cmdline, args, sizeof(args));
  340. arg = args;
  341. while ( len > 0 ) {
  342. if ( strcmp(arg, "-R") == 0 ) {
  343. available = 1;
  344. }
  345. arglen = strlen(arg)+1;
  346. len -= arglen;
  347. arg += arglen;
  348. }
  349. close(cmdline);
  350. }
  351. }
  352. closedir(proc);
  353. }
  354. return available;
  355. }
  356. /* rcg06112001 Set up IMPS/2 mode, if possible. This gives
  357.  *  us access to the mousewheel, etc. Returns zero if
  358.  *  writes to device failed, but you still need to query the
  359.  *  device to see which mode it's actually in.
  360.  */
  361. static int set_imps2_mode(int fd)
  362. {
  363. /* If you wanted to control the mouse mode (and we do :)  ) ...
  364. Set IMPS/2 protocol:
  365. {0xf3,200,0xf3,100,0xf3,80}
  366. Reset mouse device:
  367. {0xFF}
  368. */
  369. Uint8 set_imps2[] = {0xf3, 200, 0xf3, 100, 0xf3, 80};
  370. Uint8 reset = 0xff;
  371. fd_set fdset;
  372. struct timeval tv;
  373. int retval = 0;
  374. if ( write(fd, &set_imps2, sizeof(set_imps2)) == sizeof(set_imps2) ) {
  375. if (write(fd, &reset, sizeof (reset)) == sizeof (reset) ) {
  376. retval = 1;
  377. }
  378. }
  379. /* Get rid of any chatter from the above */
  380. FD_ZERO(&fdset);
  381. FD_SET(fd, &fdset);
  382. tv.tv_sec = 0;
  383. tv.tv_usec = 0;
  384. while ( select(fd+1, &fdset, 0, 0, &tv) > 0 ) {
  385. char temp[32];
  386. read(fd, temp, sizeof(temp));
  387. }
  388. return retval;
  389. }
  390. /* Returns true if the mouse uses the IMPS/2 protocol */
  391. static int detect_imps2(int fd)
  392. {
  393. int imps2;
  394. imps2 = 0;
  395. if ( getenv("SDL_MOUSEDEV_IMPS2") ) {
  396. imps2 = 1;
  397. }
  398. if ( ! imps2 ) {
  399. Uint8 query_ps2 = 0xF2;
  400. fd_set fdset;
  401. struct timeval tv;
  402. /* Get rid of any mouse motion noise */
  403. FD_ZERO(&fdset);
  404. FD_SET(fd, &fdset);
  405. tv.tv_sec = 0;
  406. tv.tv_usec = 0;
  407. while ( select(fd+1, &fdset, 0, 0, &tv) > 0 ) {
  408. char temp[32];
  409. read(fd, temp, sizeof(temp));
  410. }
  411.     /* Query for the type of mouse protocol */
  412.     if ( write(fd, &query_ps2, sizeof (query_ps2)) == sizeof (query_ps2)) {
  413.     Uint8 ch = 0;
  414. /* Get the mouse protocol response */
  415. do {
  416. FD_ZERO(&fdset);
  417. FD_SET(fd, &fdset);
  418. tv.tv_sec = 1;
  419. tv.tv_usec = 0;
  420. if ( select(fd+1, &fdset, 0, 0, &tv) < 1 ) {
  421. break;
  422. }
  423. } while ( (read(fd, &ch, sizeof (ch)) == sizeof (ch)) &&
  424.           ((ch == 0xFA) || (ch == 0xAA)) );
  425. /* Experimental values (Logitech wheelmouse) */
  426. #ifdef DEBUG_MOUSE
  427. fprintf(stderr, "Last mouse mode: 0x%xn", ch);
  428. #endif
  429. if ( ch == 3 ) {
  430. imps2 = 1;
  431. }
  432. }
  433. }
  434. return imps2;
  435. }
  436. int GS_OpenMouse(_THIS)
  437. {
  438. int i;
  439. const char *mousedev;
  440. const char *mousedrv;
  441. mousedrv = getenv("SDL_MOUSEDRV");
  442. mousedev = getenv("SDL_MOUSEDEV");
  443. mouse_fd = -1;
  444. /* STD MICE */
  445. if ( mousedev == NULL ) {
  446. /* FIXME someday... allow multiple mice in this driver */
  447. char *ps2mice[] = {
  448.     "/dev/input/mice", "/dev/usbmouse", "/dev/psaux", NULL
  449. };
  450. /* First try to use GPM in repeater mode */
  451. if ( mouse_fd < 0 ) {
  452. if ( gpm_available() ) {
  453. mouse_fd = open(GPM_NODE_FIFO, O_RDONLY, 0);
  454. if ( mouse_fd >= 0 ) {
  455. #ifdef DEBUG_MOUSE
  456. fprintf(stderr, "Using GPM mousen");
  457. #endif
  458. mouse_drv = MOUSE_GPM;
  459. }
  460. }
  461. }
  462. /* Now try to use a modern PS/2 mouse */
  463. for ( i=0; (mouse_fd < 0) && ps2mice[i]; ++i ) {
  464. mouse_fd = open(ps2mice[i], O_RDWR, 0);
  465. if (mouse_fd < 0) {
  466. mouse_fd = open(ps2mice[i], O_RDONLY, 0);
  467. }
  468. if (mouse_fd >= 0) {
  469. /* rcg06112001 Attempt to set IMPS/2 mode */
  470. if ( i == 0 ) {
  471. set_imps2_mode(mouse_fd);
  472. }
  473. if (detect_imps2(mouse_fd)) {
  474. #ifdef DEBUG_MOUSE
  475. fprintf(stderr, "Using IMPS2 mousen");
  476. #endif
  477. mouse_drv = MOUSE_IMPS2;
  478. } else {
  479. mouse_drv = MOUSE_PS2;
  480. #ifdef DEBUG_MOUSE
  481. fprintf(stderr, "Using PS2 mousen");
  482. #endif
  483. }
  484. }
  485. }
  486. /* Next try to use a PPC ADB port mouse */
  487. if ( mouse_fd < 0 ) {
  488. mouse_fd = open("/dev/adbmouse", O_RDONLY, 0);
  489. if ( mouse_fd >= 0 ) {
  490. #ifdef DEBUG_MOUSE
  491. fprintf(stderr, "Using ADB mousen");
  492. #endif
  493. mouse_drv = MOUSE_BM;
  494. }
  495. }
  496. }
  497. /* Default to a serial Microsoft mouse */
  498. if ( mouse_fd < 0 ) {
  499. if ( mousedev == NULL ) {
  500. mousedev = "/dev/mouse";
  501. }
  502. mouse_fd = open(mousedev, O_RDONLY, 0);
  503. if ( mouse_fd >= 0 ) {
  504. struct termios mouse_termios;
  505. /* Set the sampling speed to 1200 baud */
  506. tcgetattr(mouse_fd, &mouse_termios);
  507. mouse_termios.c_iflag = IGNBRK | IGNPAR;
  508. mouse_termios.c_oflag = 0;
  509. mouse_termios.c_lflag = 0;
  510. mouse_termios.c_line = 0;
  511. mouse_termios.c_cc[VTIME] = 0;
  512. mouse_termios.c_cc[VMIN] = 1;
  513. mouse_termios.c_cflag = CREAD | CLOCAL | HUPCL;
  514. mouse_termios.c_cflag |= CS8;
  515. mouse_termios.c_cflag |= B1200;
  516. tcsetattr(mouse_fd, TCSAFLUSH, &mouse_termios);
  517. #ifdef DEBUG_MOUSE
  518. fprintf(stderr, "Using Microsoft mouse on %sn", mousedev);
  519. #endif
  520. mouse_drv = MOUSE_MS;
  521. }
  522. }
  523. if ( mouse_fd < 0 ) {
  524. mouse_drv = MOUSE_NONE;
  525. }
  526. return(mouse_fd);
  527. }
  528. static int posted = 0;
  529. void GS_vgamousecallback(int button, int dx, int dy)
  530. {
  531. int button_1, button_3;
  532. int button_state;
  533. int state_changed;
  534. int i;
  535. Uint8 state;
  536. if ( dx || dy ) {
  537. posted += SDL_PrivateMouseMotion(0, 1, dx, dy);
  538. }
  539. /* Swap button 1 and 3 */
  540. button_1 = (button & 0x04) >> 2;
  541. button_3 = (button & 0x01) << 2;
  542. button &= ~0x05;
  543. button |= (button_1|button_3);
  544. /* See what changed */
  545. button_state = SDL_GetMouseState(NULL, NULL);
  546. state_changed = button_state ^ button;
  547. for ( i=0; i<8; ++i ) {
  548. if ( state_changed & (1<<i) ) {
  549. if ( button & (1<<i) ) {
  550. state = SDL_PRESSED;
  551. } else {
  552. state = SDL_RELEASED;
  553. }
  554. posted += SDL_PrivateMouseButton(state, i+1, 0, 0);
  555. }
  556. }
  557. }
  558. /* For now, use GPM, PS/2, and MS protocols
  559.    Driver adapted from the SVGAlib mouse driver code (taken from gpm, etc.)
  560.  */
  561. static void handle_mouse(_THIS)
  562. {
  563. static int start = 0;
  564. static unsigned char mousebuf[BUFSIZ];
  565. int i, nread;
  566. int button = 0;
  567. int dx = 0, dy = 0;
  568. int packetsize = 0;
  569. /* Figure out the mouse packet size */
  570. switch (mouse_drv) {
  571. case MOUSE_NONE:
  572. /* Ack! */
  573. read(mouse_fd, mousebuf, BUFSIZ);
  574. return;
  575. case MOUSE_GPM:
  576. packetsize = 5;
  577. break;
  578. case MOUSE_IMPS2:
  579. packetsize = 4;
  580. break;
  581. case MOUSE_PS2:
  582. case MOUSE_MS:
  583. case MOUSE_BM:
  584. packetsize = 3;
  585. break;
  586. case NUM_MOUSE_DRVS:
  587. /* Uh oh.. */
  588. packetsize = 0;
  589. break;
  590. }
  591. /* Read as many packets as possible */
  592. nread = read(mouse_fd, &mousebuf[start], BUFSIZ-start);
  593. if ( nread < 0 ) {
  594. return;
  595. }
  596. nread += start;
  597. #ifdef DEBUG_MOUSE
  598. fprintf(stderr, "Read %d bytes from mouse, start = %dn", nread, start);
  599. #endif
  600. for ( i=0; i<(nread-(packetsize-1)); i += packetsize ) {
  601. switch (mouse_drv) {
  602. case MOUSE_NONE:
  603. break;
  604. case MOUSE_GPM:
  605. /* GPM protocol has 0x80 in high byte */
  606. if ( (mousebuf[i] & 0xF8) != 0x80 ) {
  607. /* Go to next byte */
  608. i -= (packetsize-1);
  609. continue;
  610. }
  611. /* Get current mouse state */
  612. button = (~mousebuf[i]) & 0x07;
  613. dx =   (signed char)(mousebuf[i+1]) +
  614.        (signed char)(mousebuf[i+3]);
  615. dy = -((signed char)(mousebuf[i+2]) +
  616.        (signed char)(mousebuf[i+4]));
  617. break;
  618. case MOUSE_PS2:
  619. /* PS/2 protocol has nothing in high byte */
  620. if ( (mousebuf[i] & 0xC0) != 0 ) {
  621. /* Go to next byte */
  622. i -= (packetsize-1);
  623. continue;
  624. }
  625. /* Get current mouse state */
  626. button = (mousebuf[i] & 0x04) >> 1 | /*Middle*/
  627.     (mousebuf[i] & 0x02) >> 1 | /*Right*/
  628.     (mousebuf[i] & 0x01) << 2;  /*Left*/
  629.    dx = (mousebuf[i] & 0x10) ?
  630.          mousebuf[i+1] - 256 : mousebuf[i+1];
  631.    dy = (mousebuf[i] & 0x20) ?
  632.          -(mousebuf[i+2] - 256) : -mousebuf[i+2];
  633. break;
  634. case MOUSE_IMPS2:
  635. /* Get current mouse state */
  636. button = (mousebuf[i] & 0x04) >> 1 | /*Middle*/
  637.     (mousebuf[i] & 0x02) >> 1 | /*Right*/
  638.     (mousebuf[i] & 0x01) << 2 | /*Left*/
  639.     (mousebuf[i] & 0x40) >> 3 | /* 4 */
  640.     (mousebuf[i] & 0x80) >> 3;  /* 5 */
  641.    dx = (mousebuf[i] & 0x10) ?
  642.          mousebuf[i+1] - 256 : mousebuf[i+1];
  643.    dy = (mousebuf[i] & 0x20) ?
  644.          -(mousebuf[i+2] - 256) : -mousebuf[i+2];
  645. switch (mousebuf[i+3]&0x0F) {
  646.     case 0x0E: /* DX = +1 */
  647.     case 0x02: /* DX = -1 */
  648. break;
  649.     case 0x0F: /* DY = +1 (map button 4) */
  650.                                        FB_vgamousecallback(button | (1<<3),
  651.                                                            1, 0, 0);
  652. break;
  653.     case 0x01: /* DY = -1 (map button 5) */
  654.                                        FB_vgamousecallback(button | (1<<4),
  655.                                                            1, 0, 0);
  656. break;
  657. }
  658. break;
  659. case MOUSE_MS:
  660. /* Microsoft protocol has 0x40 in high byte */
  661. if ( (mousebuf[i] & 0x40) != 0x40 ) {
  662. /* Go to next byte */
  663. i -= (packetsize-1);
  664. continue;
  665. }
  666. /* Get current mouse state */
  667. button = ((mousebuf[i] & 0x20) >> 3) |
  668.          ((mousebuf[i] & 0x10) >> 4);
  669. dx = (signed char)(((mousebuf[i] & 0x03) << 6) |
  670.                    (mousebuf[i + 1] & 0x3F));
  671. dy = (signed char)(((mousebuf[i] & 0x0C) << 4) |
  672.                     (mousebuf[i + 2] & 0x3F));
  673. break;
  674. case MOUSE_BM:
  675. /* BusMouse protocol has 0xF8 in high byte */
  676. if ( (mousebuf[i] & 0xF8) != 0x80 ) {
  677. /* Go to next byte */
  678. i -= (packetsize-1);
  679. continue;
  680. }
  681. /* Get current mouse state */
  682. button = (~mousebuf[i]) & 0x07;
  683. dx =  (signed char)mousebuf[i+1];
  684. dy = -(signed char)mousebuf[i+2];
  685. break;
  686. case NUM_MOUSE_DRVS:
  687. /* Uh oh.. */
  688. dx = 0;
  689. dy = 0;
  690. break;
  691. }
  692. GS_vgamousecallback(button, dx, dy);
  693. }
  694. if ( i < nread ) {
  695. memcpy(mousebuf, &mousebuf[i], (nread-i));
  696. start = (nread-i);
  697. } else {
  698. start = 0;
  699. }
  700. return;
  701. }
  702. static void handle_keyboard(_THIS)
  703. {
  704. unsigned char keybuf[BUFSIZ];
  705. int i, nread;
  706. int pressed;
  707. int scancode;
  708. SDL_keysym keysym;
  709. nread = read(keyboard_fd, keybuf, BUFSIZ);
  710. for ( i=0; i<nread; ++i ) {
  711. scancode = keybuf[i] & 0x7F;
  712. if ( keybuf[i] & 0x80 ) {
  713. pressed = SDL_RELEASED;
  714. } else {
  715. pressed = SDL_PRESSED;
  716. }
  717. TranslateKey(scancode, &keysym);
  718. posted += SDL_PrivateKeyboard(pressed, &keysym);
  719. }
  720. }
  721. void GS_PumpEvents(_THIS)
  722. {
  723. fd_set fdset;
  724. int max_fd;
  725. static struct timeval zero;
  726. do {
  727. posted = 0;
  728. FD_ZERO(&fdset);
  729. max_fd = 0;
  730. if ( keyboard_fd >= 0 ) {
  731. FD_SET(keyboard_fd, &fdset);
  732. if ( max_fd < keyboard_fd ) {
  733. max_fd = keyboard_fd;
  734. }
  735. }
  736. if ( mouse_fd >= 0 ) {
  737. FD_SET(mouse_fd, &fdset);
  738. if ( max_fd < mouse_fd ) {
  739. max_fd = mouse_fd;
  740. }
  741. }
  742. if ( select(max_fd+1, &fdset, NULL, NULL, &zero) > 0 ) {
  743. if ( keyboard_fd >= 0 ) {
  744. if ( FD_ISSET(keyboard_fd, &fdset) ) {
  745. handle_keyboard(this);
  746. }
  747. }
  748. if ( mouse_fd >= 0 ) {
  749. if ( FD_ISSET(mouse_fd, &fdset) ) {
  750. handle_mouse(this);
  751. }
  752. }
  753. }
  754. } while ( posted );
  755. }
  756. void GS_InitOSKeymap(_THIS)
  757. {
  758. int i;
  759. /* Initialize the Linux key translation table */
  760. /* First get the ascii keys and others not well handled */
  761. for (i=0; i<SDL_TABLESIZE(keymap); ++i) {
  762.   switch(i) {
  763.   /* These aren't handled by the x86 kernel keymapping (?) */
  764.   case SCANCODE_PRINTSCREEN:
  765.     keymap[i] = SDLK_PRINT;
  766.     break;
  767.   case SCANCODE_BREAK:
  768.     keymap[i] = SDLK_BREAK;
  769.     break;
  770.   case SCANCODE_BREAK_ALTERNATIVE:
  771.     keymap[i] = SDLK_PAUSE;
  772.     break;
  773.   case SCANCODE_LEFTSHIFT:
  774.     keymap[i] = SDLK_LSHIFT;
  775.     break;
  776.   case SCANCODE_RIGHTSHIFT:
  777.     keymap[i] = SDLK_RSHIFT;
  778.     break;
  779.   case SCANCODE_LEFTCONTROL:
  780.     keymap[i] = SDLK_LCTRL;
  781.     break;
  782.   case SCANCODE_RIGHTCONTROL:
  783.     keymap[i] = SDLK_RCTRL;
  784.     break;
  785.   case SCANCODE_RIGHTWIN:
  786.     keymap[i] = SDLK_RSUPER;
  787.     break;
  788.   case SCANCODE_LEFTWIN:
  789.     keymap[i] = SDLK_LSUPER;
  790.     break;
  791.   case 127:
  792.     keymap[i] = SDLK_MENU;
  793.     break;
  794.   /* this should take care of all standard ascii keys */
  795.   default:
  796.     keymap[i] = KVAL(vga_keymap[0][i]);
  797.     break;
  798.           }
  799. }
  800. for (i=0; i<SDL_TABLESIZE(keymap); ++i) {
  801.   switch(keymap_temp[i]) {
  802.     case K_F1:  keymap[i] = SDLK_F1;  break;
  803.     case K_F2:  keymap[i] = SDLK_F2;  break;
  804.     case K_F3:  keymap[i] = SDLK_F3;  break;
  805.     case K_F4:  keymap[i] = SDLK_F4;  break;
  806.     case K_F5:  keymap[i] = SDLK_F5;  break;
  807.     case K_F6:  keymap[i] = SDLK_F6;  break;
  808.     case K_F7:  keymap[i] = SDLK_F7;  break;
  809.     case K_F8:  keymap[i] = SDLK_F8;  break;
  810.     case K_F9:  keymap[i] = SDLK_F9;  break;
  811.     case K_F10: keymap[i] = SDLK_F10; break;
  812.     case K_F11: keymap[i] = SDLK_F11; break;
  813.     case K_F12: keymap[i] = SDLK_F12; break;
  814.     case K_DOWN:  keymap[i] = SDLK_DOWN;  break;
  815.     case K_LEFT:  keymap[i] = SDLK_LEFT;  break;
  816.     case K_RIGHT: keymap[i] = SDLK_RIGHT; break;
  817.     case K_UP:    keymap[i] = SDLK_UP;    break;
  818.     case K_P0:     keymap[i] = SDLK_KP0; break;
  819.     case K_P1:     keymap[i] = SDLK_KP1; break;
  820.     case K_P2:     keymap[i] = SDLK_KP2; break;
  821.     case K_P3:     keymap[i] = SDLK_KP3; break;
  822.     case K_P4:     keymap[i] = SDLK_KP4; break;
  823.     case K_P5:     keymap[i] = SDLK_KP5; break;
  824.     case K_P6:     keymap[i] = SDLK_KP6; break;
  825.     case K_P7:     keymap[i] = SDLK_KP7; break;
  826.     case K_P8:     keymap[i] = SDLK_KP8; break;
  827.     case K_P9:     keymap[i] = SDLK_KP9; break;
  828.     case K_PPLUS:  keymap[i] = SDLK_KP_PLUS; break;
  829.     case K_PMINUS: keymap[i] = SDLK_KP_MINUS; break;
  830.     case K_PSTAR:  keymap[i] = SDLK_KP_MULTIPLY; break;
  831.     case K_PSLASH: keymap[i] = SDLK_KP_DIVIDE; break;
  832.     case K_PENTER: keymap[i] = SDLK_KP_ENTER; break;
  833.     case K_PDOT:   keymap[i] = SDLK_KP_PERIOD; break;
  834.     case K_SHIFT:  if ( keymap[i] != SDLK_RSHIFT )
  835.                      keymap[i] = SDLK_LSHIFT;
  836.                    break;
  837.     case K_SHIFTL: keymap[i] = SDLK_LSHIFT; break;
  838.     case K_SHIFTR: keymap[i] = SDLK_RSHIFT; break;
  839.     case K_CTRL:  if ( keymap[i] != SDLK_RCTRL )
  840.                      keymap[i] = SDLK_LCTRL;
  841.                    break;
  842.     case K_CTRLL:  keymap[i] = SDLK_LCTRL;  break;
  843.     case K_CTRLR:  keymap[i] = SDLK_RCTRL;  break;
  844.     case K_ALT:    keymap[i] = SDLK_LALT;   break;
  845.     case K_ALTGR:  keymap[i] = SDLK_RALT;   break;
  846.     case K_INSERT: keymap[i] = SDLK_INSERT;   break;
  847.     case K_REMOVE: keymap[i] = SDLK_DELETE;   break;
  848.     case K_PGUP:   keymap[i] = SDLK_PAGEUP;   break;
  849.     case K_PGDN:   keymap[i] = SDLK_PAGEDOWN; break;
  850.     case K_FIND:   keymap[i] = SDLK_HOME;     break;
  851.     case K_SELECT: keymap[i] = SDLK_END;      break;
  852.     case K_NUM:  keymap[i] = SDLK_NUMLOCK;   break;
  853.     case K_CAPS: keymap[i] = SDLK_CAPSLOCK;  break;
  854.     case K_F13:   keymap[i] = SDLK_PRINT;     break;
  855.     case K_HOLD:  keymap[i] = SDLK_SCROLLOCK; break;
  856.     case K_PAUSE: keymap[i] = SDLK_PAUSE;     break;
  857.     case 127: keymap[i] = SDLK_BACKSPACE; break;
  858.      
  859.     default: break;
  860.   }
  861. }
  862. }
  863. static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym)
  864. {
  865. /* Set the keysym information */
  866. keysym->scancode = scancode;
  867. keysym->sym = keymap[scancode];
  868. keysym->mod = KMOD_NONE;
  869. /* If UNICODE is on, get the UNICODE value for the key */
  870. keysym->unicode = 0;
  871. if ( SDL_TranslateUNICODE ) {
  872. int map;
  873. SDLMod modstate;
  874. modstate = SDL_GetModState();
  875. map = 0;
  876. if ( modstate & KMOD_SHIFT ) {
  877. map |= (1<<KG_SHIFT);
  878. }
  879. if ( modstate & KMOD_CTRL ) {
  880. map |= (1<<KG_CTRL);
  881. }
  882. if ( modstate & KMOD_ALT ) {
  883. map |= (1<<KG_ALT);
  884. }
  885. if ( modstate & KMOD_MODE ) {
  886. map |= (1<<KG_ALTGR);
  887. }
  888. if ( KTYP(vga_keymap[map][scancode]) == KT_LETTER ) {
  889. if ( modstate & KMOD_CAPS ) {
  890. map ^= (1<<KG_SHIFT);
  891. }
  892. }
  893. if ( KTYP(vga_keymap[map][scancode]) == KT_PAD ) {
  894. if ( modstate & KMOD_NUM ) {
  895. keysym->unicode=KVAL(vga_keymap[map][scancode]);
  896. }
  897. } else {
  898. keysym->unicode = KVAL(vga_keymap[map][scancode]);
  899. }
  900. }
  901. return(keysym);
  902. }