146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* 246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL - Simple DirectMedia Layer 346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Copyright (C) 1997-2006 Sam Lantinga 446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner This library is free software; you can redistribute it and/or 646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner modify it under the terms of the GNU Lesser General Public 746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner License as published by the Free Software Foundation; either 846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner version 2.1 of the License, or (at your option) any later version. 946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 1046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner This library is distributed in the hope that it will be useful, 1146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner but WITHOUT ANY WARRANTY; without even the implied warranty of 1246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Lesser General Public License for more details. 1446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 1546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner You should have received a copy of the GNU Lesser General Public 1646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner License along with this library; if not, write to the Free Software 1746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 1846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 1946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Sam Lantinga 2046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner slouken@libsdl.org 2146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner*/ 2246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "SDL_config.h" 2346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 2446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Handle the event stream, converting console events into SDL events */ 2546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 2646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <sys/types.h> 2746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <sys/time.h> 2846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <sys/ioctl.h> 2946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <unistd.h> 3046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <fcntl.h> 3146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <errno.h> 3246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <limits.h> 3346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 3446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* For parsing /proc */ 3546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <dirent.h> 3646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <ctype.h> 3746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 3846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <linux/vt.h> 3946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <linux/kd.h> 4046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <linux/keyboard.h> 4146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 4246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "SDL_mutex.h" 4346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "../SDL_sysvideo.h" 4446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "../../events/SDL_sysevents.h" 4546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "../../events/SDL_events_c.h" 4646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "SDL_gsvideo.h" 4746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "SDL_gsevents_c.h" 4846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "SDL_gskeys.h" 4946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 5046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifndef GPM_NODE_FIFO 5146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#define GPM_NODE_FIFO "/dev/gpmdata" 5246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif 5346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 5446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* The translation tables from a console scancode to a SDL keysym */ 5546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#define NUM_VGAKEYMAPS (1<<KG_CAPSSHIFT) 5646be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic Uint16 vga_keymap[NUM_VGAKEYMAPS][NR_KEYS]; 5746be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic SDLKey keymap[128]; 5846be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic Uint16 keymap_temp[128]; /* only used at startup */ 5946be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym); 6046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 6146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Ugh, we have to duplicate the kernel's keysym mapping code... 6246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Oh, it's not so bad. :-) 6346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 6446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner FIXME: Add keyboard LED handling code 6546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner */ 6646be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic void GS_vgainitkeymaps(int fd) 6746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 6846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner struct kbentry entry; 6946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int map, i; 7046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 7146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Don't do anything if we are passed a closed keyboard */ 7246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( fd < 0 ) { 7346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return; 7446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 7546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 7646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Load all the keysym mappings */ 7746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner for ( map=0; map<NUM_VGAKEYMAPS; ++map ) { 7846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_memset(vga_keymap[map], 0, NR_KEYS*sizeof(Uint16)); 7946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner for ( i=0; i<NR_KEYS; ++i ) { 8046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner entry.kb_table = map; 8146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner entry.kb_index = i; 8246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( ioctl(fd, KDGKBENT, &entry) == 0 ) { 8346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* fill keytemp. This replaces SDL_fbkeys.h */ 8446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( (map == 0) && (i<128) ) { 8546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner keymap_temp[i] = entry.kb_value; 8646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 8746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* The "Enter" key is a special case */ 8846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( entry.kb_value == K_ENTER ) { 8946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner entry.kb_value = K(KT_ASCII,13); 9046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 9146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Handle numpad specially as well */ 9246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( KTYP(entry.kb_value) == KT_PAD ) { 9346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner switch ( entry.kb_value ) { 9446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_P0: 9546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_P1: 9646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_P2: 9746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_P3: 9846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_P4: 9946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_P5: 10046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_P6: 10146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_P7: 10246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_P8: 10346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_P9: 10446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner vga_keymap[map][i]=entry.kb_value; 10546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner vga_keymap[map][i]+= '0'; 10646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 10746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_PPLUS: 10846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner vga_keymap[map][i]=K(KT_ASCII,'+'); 10946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 11046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_PMINUS: 11146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner vga_keymap[map][i]=K(KT_ASCII,'-'); 11246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 11346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_PSTAR: 11446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner vga_keymap[map][i]=K(KT_ASCII,'*'); 11546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 11646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_PSLASH: 11746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner vga_keymap[map][i]=K(KT_ASCII,'/'); 11846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 11946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_PENTER: 12046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner vga_keymap[map][i]=K(KT_ASCII,'\r'); 12146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 12246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_PCOMMA: 12346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner vga_keymap[map][i]=K(KT_ASCII,','); 12446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 12546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_PDOT: 12646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner vga_keymap[map][i]=K(KT_ASCII,'.'); 12746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 12846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner default: 12946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 13046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 13146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 13246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Do the normal key translation */ 13346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( (KTYP(entry.kb_value) == KT_LATIN) || 13446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner (KTYP(entry.kb_value) == KT_ASCII) || 13546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner (KTYP(entry.kb_value) == KT_LETTER) ) { 13646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner vga_keymap[map][i] = entry.kb_value; 13746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 13846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 13946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 14046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 14146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 14246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 14346be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerint GS_InGraphicsMode(_THIS) 14446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 14546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return((keyboard_fd >= 0) && (saved_kbd_mode >= 0)); 14646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 14746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 14846be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerint GS_EnterGraphicsMode(_THIS) 14946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 15046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner struct termios keyboard_termios; 15146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 15246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Set medium-raw keyboard mode */ 15346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( (keyboard_fd >= 0) && !GS_InGraphicsMode(this) ) { 15446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 15546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Switch to the correct virtual terminal */ 15646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( current_vt > 0 ) { 15746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner struct vt_stat vtstate; 15846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 15946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( ioctl(keyboard_fd, VT_GETSTATE, &vtstate) == 0 ) { 16046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner saved_vt = vtstate.v_active; 16146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 16246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( ioctl(keyboard_fd, VT_ACTIVATE, current_vt) == 0 ) { 16346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner ioctl(keyboard_fd, VT_WAITACTIVE, current_vt); 16446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 16546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 16646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 16746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Set the terminal input mode */ 16846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( tcgetattr(keyboard_fd, &saved_kbd_termios) < 0 ) { 16946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_SetError("Unable to get terminal attributes"); 17046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( keyboard_fd > 0 ) { 17146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner close(keyboard_fd); 17246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 17346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner keyboard_fd = -1; 17446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(-1); 17546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 17646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( ioctl(keyboard_fd, KDGKBMODE, &saved_kbd_mode) < 0 ) { 17746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_SetError("Unable to get current keyboard mode"); 17846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( keyboard_fd > 0 ) { 17946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner close(keyboard_fd); 18046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 18146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner keyboard_fd = -1; 18246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(-1); 18346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 18446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner keyboard_termios = saved_kbd_termios; 18546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner keyboard_termios.c_lflag &= ~(ICANON | ECHO | ISIG); 18646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner keyboard_termios.c_iflag &= ~(ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON); 18746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner keyboard_termios.c_cc[VMIN] = 0; 18846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner keyboard_termios.c_cc[VTIME] = 0; 18946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (tcsetattr(keyboard_fd, TCSAFLUSH, &keyboard_termios) < 0) { 19046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner GS_CloseKeyboard(this); 19146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_SetError("Unable to set terminal attributes"); 19246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(-1); 19346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 19446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* This will fail if we aren't root or this isn't our tty */ 19546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( ioctl(keyboard_fd, KDSKBMODE, K_MEDIUMRAW) < 0 ) { 19646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner GS_CloseKeyboard(this); 19746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_SetError("Unable to set keyboard in raw mode"); 19846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(-1); 19946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 20046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( ioctl(keyboard_fd, KDSETMODE, KD_GRAPHICS) < 0 ) { 20146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner GS_CloseKeyboard(this); 20246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_SetError("Unable to set keyboard in graphics mode"); 20346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(-1); 20446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 20546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 20646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(keyboard_fd); 20746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 20846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 20946be48730333120a7b939116cef075e61c12c703David 'Digit' Turnervoid GS_LeaveGraphicsMode(_THIS) 21046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 21146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( GS_InGraphicsMode(this) ) { 21246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner ioctl(keyboard_fd, KDSETMODE, KD_TEXT); 21346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner ioctl(keyboard_fd, KDSKBMODE, saved_kbd_mode); 21446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner tcsetattr(keyboard_fd, TCSAFLUSH, &saved_kbd_termios); 21546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner saved_kbd_mode = -1; 21646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 21746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Head back over to the original virtual terminal */ 21846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( saved_vt > 0 ) { 21946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner ioctl(keyboard_fd, VT_ACTIVATE, saved_vt); 22046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 22146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 22246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 22346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 22446be48730333120a7b939116cef075e61c12c703David 'Digit' Turnervoid GS_CloseKeyboard(_THIS) 22546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 22646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( keyboard_fd >= 0 ) { 22746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner GS_LeaveGraphicsMode(this); 22846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( keyboard_fd > 0 ) { 22946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner close(keyboard_fd); 23046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 23146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 23246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner keyboard_fd = -1; 23346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 23446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 23546be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerint GS_OpenKeyboard(_THIS) 23646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 23746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Open only if not already opened */ 23846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( keyboard_fd < 0 ) { 23946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner char *tty0[] = { "/dev/tty0", "/dev/vc/0", NULL }; 24046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner char *vcs[] = { "/dev/vc/%d", "/dev/tty%d", NULL }; 24146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int i, tty0_fd; 24246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 24346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Try to query for a free virtual terminal */ 24446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner tty0_fd = -1; 24546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner for ( i=0; tty0[i] && (tty0_fd < 0); ++i ) { 24646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner tty0_fd = open(tty0[i], O_WRONLY, 0); 24746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 24846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( tty0_fd < 0 ) { 24946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner tty0_fd = dup(0); /* Maybe stdin is a VT? */ 25046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 25146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner ioctl(tty0_fd, VT_OPENQRY, ¤t_vt); 25246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner close(tty0_fd); 25346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( (geteuid() == 0) && (current_vt > 0) ) { 25446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner for ( i=0; vcs[i] && (keyboard_fd < 0); ++i ) { 25546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner char vtpath[12]; 25646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 25746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_snprintf(vtpath, SDL_arraysize(vtpath), vcs[i], current_vt); 25846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner keyboard_fd = open(vtpath, O_RDWR, 0); 25946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef DEBUG_KEYBOARD 26046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner fprintf(stderr, "vtpath = %s, fd = %d\n", 26146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner vtpath, keyboard_fd); 26246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif /* DEBUG_KEYBOARD */ 26346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 26446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* This needs to be our controlling tty 26546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner so that the kernel ioctl() calls work 26646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner */ 26746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( keyboard_fd >= 0 ) { 26846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner tty0_fd = open("/dev/tty", O_RDWR, 0); 26946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( tty0_fd >= 0 ) { 27046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner ioctl(tty0_fd, TIOCNOTTY, 0); 27146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner close(tty0_fd); 27246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 27346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 27446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 27546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 27646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( keyboard_fd < 0 ) { 27746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Last resort, maybe our tty is a usable VT */ 27846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner current_vt = 0; 27946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner keyboard_fd = open("/dev/tty", O_RDWR); 28046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 28146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef DEBUG_KEYBOARD 28246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner fprintf(stderr, "Current VT: %d\n", current_vt); 28346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif 28446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner saved_kbd_mode = -1; 28546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 28646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Make sure that our input is a console terminal */ 28746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner { int dummy; 28846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( ioctl(keyboard_fd, KDGKBMODE, &dummy) < 0 ) { 28946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner close(keyboard_fd); 29046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner keyboard_fd = -1; 29146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_SetError("Unable to open a console terminal"); 29246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 29346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 29446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 29546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Set up keymap */ 29646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner GS_vgainitkeymaps(keyboard_fd); 29746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 29846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(keyboard_fd); 29946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 30046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 30146be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic enum { 30246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner MOUSE_NONE = -1, 30346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner MOUSE_GPM, /* Note: GPM uses the MSC protocol */ 30446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner MOUSE_PS2, 30546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner MOUSE_IMPS2, 30646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner MOUSE_MS, 30746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner MOUSE_BM, 30846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner NUM_MOUSE_DRVS 30946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} mouse_drv = MOUSE_NONE; 31046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 31146be48730333120a7b939116cef075e61c12c703David 'Digit' Turnervoid GS_CloseMouse(_THIS) 31246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 31346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( mouse_fd > 0 ) { 31446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner close(mouse_fd); 31546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 31646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mouse_fd = -1; 31746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 31846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 31946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Returns processes listed in /proc with the desired name */ 32046be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int find_pid(DIR *proc, const char *wanted_name) 32146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 32246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner struct dirent *entry; 32346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int pid; 32446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 32546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* First scan proc for the gpm process */ 32646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner pid = 0; 32746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner while ( (pid == 0) && ((entry=readdir(proc)) != NULL) ) { 32846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( isdigit(entry->d_name[0]) ) { 32946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner FILE *status; 33046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner char path[PATH_MAX]; 33146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner char name[PATH_MAX]; 33246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 33346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_snprintf(path, SDL_arraysize(path), "/proc/%s/status", entry->d_name); 33446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner status=fopen(path, "r"); 33546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( status ) { 33646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner name[0] = '\0'; 33746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner fscanf(status, "Name: %s", name); 33846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( SDL_strcmp(name, wanted_name) == 0 ) { 33946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner pid = atoi(entry->d_name); 34046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 34146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner fclose(status); 34246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 34346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 34446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 34546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return pid; 34646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 34746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 34846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Returns true if /dev/gpmdata is being written to by gpm */ 34946be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int gpm_available(void) 35046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 35146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int available; 35246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner DIR *proc; 35346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int pid; 35446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int cmdline, len, arglen; 35546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner char path[PATH_MAX]; 35646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner char args[PATH_MAX], *arg; 35746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 35846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Don't bother looking if the fifo isn't there */ 35946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( access(GPM_NODE_FIFO, F_OK) < 0 ) { 36046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(0); 36146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 36246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 36346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner available = 0; 36446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner proc = opendir("/proc"); 36546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( proc ) { 36646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner while ( (pid=find_pid(proc, "gpm")) > 0 ) { 36746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_snprintf(path, SDL_arraysize(path), "/proc/%d/cmdline", pid); 36846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cmdline = open(path, O_RDONLY, 0); 36946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( cmdline >= 0 ) { 37046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner len = read(cmdline, args, sizeof(args)); 37146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner arg = args; 37246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner while ( len > 0 ) { 37346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( SDL_strcmp(arg, "-R") == 0 ) { 37446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner available = 1; 37546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 37646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner arglen = SDL_strlen(arg)+1; 37746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner len -= arglen; 37846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner arg += arglen; 37946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 38046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner close(cmdline); 38146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 38246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 38346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner closedir(proc); 38446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 38546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return available; 38646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 38746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 38846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 38946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* rcg06112001 Set up IMPS/2 mode, if possible. This gives 39046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner * us access to the mousewheel, etc. Returns zero if 39146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner * writes to device failed, but you still need to query the 39246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner * device to see which mode it's actually in. 39346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner */ 39446be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int set_imps2_mode(int fd) 39546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 39646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* If you wanted to control the mouse mode (and we do :) ) ... 39746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Set IMPS/2 protocol: 39846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner {0xf3,200,0xf3,100,0xf3,80} 39946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Reset mouse device: 40046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner {0xFF} 40146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner */ 40246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Uint8 set_imps2[] = {0xf3, 200, 0xf3, 100, 0xf3, 80}; 40346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Uint8 reset = 0xff; 40446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner fd_set fdset; 40546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner struct timeval tv; 40646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int retval = 0; 40746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 40846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( write(fd, &set_imps2, sizeof(set_imps2)) == sizeof(set_imps2) ) { 40946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (write(fd, &reset, sizeof (reset)) == sizeof (reset) ) { 41046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner retval = 1; 41146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 41246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 41346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 41446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Get rid of any chatter from the above */ 41546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner FD_ZERO(&fdset); 41646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner FD_SET(fd, &fdset); 41746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner tv.tv_sec = 0; 41846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner tv.tv_usec = 0; 41946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner while ( select(fd+1, &fdset, 0, 0, &tv) > 0 ) { 42046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner char temp[32]; 42146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner read(fd, temp, sizeof(temp)); 42246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 42346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 42446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return retval; 42546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 42646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 42746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 42846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Returns true if the mouse uses the IMPS/2 protocol */ 42946be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int detect_imps2(int fd) 43046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 43146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int imps2; 43246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 43346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner imps2 = 0; 43446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 43546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( SDL_getenv("SDL_MOUSEDEV_IMPS2") ) { 43646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner imps2 = 1; 43746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 43846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( ! imps2 ) { 43946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Uint8 query_ps2 = 0xF2; 44046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner fd_set fdset; 44146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner struct timeval tv; 44246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 44346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Get rid of any mouse motion noise */ 44446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner FD_ZERO(&fdset); 44546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner FD_SET(fd, &fdset); 44646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner tv.tv_sec = 0; 44746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner tv.tv_usec = 0; 44846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner while ( select(fd+1, &fdset, 0, 0, &tv) > 0 ) { 44946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner char temp[32]; 45046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner read(fd, temp, sizeof(temp)); 45146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 45246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 45346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Query for the type of mouse protocol */ 45446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( write(fd, &query_ps2, sizeof (query_ps2)) == sizeof (query_ps2)) { 45546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Uint8 ch = 0; 45646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 45746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Get the mouse protocol response */ 45846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner do { 45946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner FD_ZERO(&fdset); 46046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner FD_SET(fd, &fdset); 46146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner tv.tv_sec = 1; 46246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner tv.tv_usec = 0; 46346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( select(fd+1, &fdset, 0, 0, &tv) < 1 ) { 46446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 46546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 46646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } while ( (read(fd, &ch, sizeof (ch)) == sizeof (ch)) && 46746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner ((ch == 0xFA) || (ch == 0xAA)) ); 46846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 46946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Experimental values (Logitech wheelmouse) */ 47046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef DEBUG_MOUSE 47146be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerfprintf(stderr, "Last mouse mode: 0x%x\n", ch); 47246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif 47346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( ch == 3 ) { 47446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner imps2 = 1; 47546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 47646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 47746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 47846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return imps2; 47946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 48046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 48146be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerint GS_OpenMouse(_THIS) 48246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 48346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int i; 48446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner const char *mousedev; 48546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner const char *mousedrv; 48646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 48746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mousedrv = SDL_getenv("SDL_MOUSEDRV"); 48846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mousedev = SDL_getenv("SDL_MOUSEDEV"); 48946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mouse_fd = -1; 49046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 49146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* STD MICE */ 49246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 49346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( mousedev == NULL ) { 49446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* FIXME someday... allow multiple mice in this driver */ 49546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner char *ps2mice[] = { 49646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner "/dev/input/mice", "/dev/usbmouse", "/dev/psaux", NULL 49746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner }; 49846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* First try to use GPM in repeater mode */ 49946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( mouse_fd < 0 ) { 50046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( gpm_available() ) { 50146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mouse_fd = open(GPM_NODE_FIFO, O_RDONLY, 0); 50246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( mouse_fd >= 0 ) { 50346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef DEBUG_MOUSE 50446be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerfprintf(stderr, "Using GPM mouse\n"); 50546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif 50646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mouse_drv = MOUSE_GPM; 50746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 50846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 50946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 51046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Now try to use a modern PS/2 mouse */ 51146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner for ( i=0; (mouse_fd < 0) && ps2mice[i]; ++i ) { 51246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mouse_fd = open(ps2mice[i], O_RDWR, 0); 51346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (mouse_fd < 0) { 51446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mouse_fd = open(ps2mice[i], O_RDONLY, 0); 51546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 51646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (mouse_fd >= 0) { 51746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* rcg06112001 Attempt to set IMPS/2 mode */ 51846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( i == 0 ) { 51946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner set_imps2_mode(mouse_fd); 52046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 52146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (detect_imps2(mouse_fd)) { 52246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef DEBUG_MOUSE 52346be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerfprintf(stderr, "Using IMPS2 mouse\n"); 52446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif 52546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mouse_drv = MOUSE_IMPS2; 52646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } else { 52746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mouse_drv = MOUSE_PS2; 52846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef DEBUG_MOUSE 52946be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerfprintf(stderr, "Using PS2 mouse\n"); 53046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif 53146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 53246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 53346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 53446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Next try to use a PPC ADB port mouse */ 53546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( mouse_fd < 0 ) { 53646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mouse_fd = open("/dev/adbmouse", O_RDONLY, 0); 53746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( mouse_fd >= 0 ) { 53846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef DEBUG_MOUSE 53946be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerfprintf(stderr, "Using ADB mouse\n"); 54046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif 54146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mouse_drv = MOUSE_BM; 54246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 54346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 54446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 54546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Default to a serial Microsoft mouse */ 54646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( mouse_fd < 0 ) { 54746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( mousedev == NULL ) { 54846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mousedev = "/dev/mouse"; 54946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 55046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mouse_fd = open(mousedev, O_RDONLY, 0); 55146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( mouse_fd >= 0 ) { 55246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner struct termios mouse_termios; 55346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 55446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Set the sampling speed to 1200 baud */ 55546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner tcgetattr(mouse_fd, &mouse_termios); 55646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mouse_termios.c_iflag = IGNBRK | IGNPAR; 55746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mouse_termios.c_oflag = 0; 55846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mouse_termios.c_lflag = 0; 55946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mouse_termios.c_line = 0; 56046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mouse_termios.c_cc[VTIME] = 0; 56146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mouse_termios.c_cc[VMIN] = 1; 56246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mouse_termios.c_cflag = CREAD | CLOCAL | HUPCL; 56346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mouse_termios.c_cflag |= CS8; 56446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mouse_termios.c_cflag |= B1200; 56546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner tcsetattr(mouse_fd, TCSAFLUSH, &mouse_termios); 56646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef DEBUG_MOUSE 56746be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerfprintf(stderr, "Using Microsoft mouse on %s\n", mousedev); 56846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif 56946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mouse_drv = MOUSE_MS; 57046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 57146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 57246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( mouse_fd < 0 ) { 57346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mouse_drv = MOUSE_NONE; 57446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 57546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(mouse_fd); 57646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 57746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 57846be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int posted = 0; 57946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 58046be48730333120a7b939116cef075e61c12c703David 'Digit' Turnervoid GS_vgamousecallback(int button, int dx, int dy) 58146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 58246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int button_1, button_3; 58346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int button_state; 58446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int state_changed; 58546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int i; 58646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Uint8 state; 58746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 58846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( dx || dy ) { 58946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner posted += SDL_PrivateMouseMotion(0, 1, dx, dy); 59046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 59146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 59246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Swap button 1 and 3 */ 59346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner button_1 = (button & 0x04) >> 2; 59446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner button_3 = (button & 0x01) << 2; 59546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner button &= ~0x05; 59646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner button |= (button_1|button_3); 59746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 59846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* See what changed */ 59946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner button_state = SDL_GetMouseState(NULL, NULL); 60046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner state_changed = button_state ^ button; 60146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner for ( i=0; i<8; ++i ) { 60246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( state_changed & (1<<i) ) { 60346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( button & (1<<i) ) { 60446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner state = SDL_PRESSED; 60546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } else { 60646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner state = SDL_RELEASED; 60746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 60846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner posted += SDL_PrivateMouseButton(state, i+1, 0, 0); 60946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 61046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 61146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 61246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 61346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* For now, use GPM, PS/2, and MS protocols 61446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Driver adapted from the SVGAlib mouse driver code (taken from gpm, etc.) 61546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner */ 61646be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic void handle_mouse(_THIS) 61746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 61846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner static int start = 0; 61946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner static unsigned char mousebuf[BUFSIZ]; 62046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int i, nread; 62146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int button = 0; 62246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int dx = 0, dy = 0; 62346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int packetsize = 0; 62446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 62546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Figure out the mouse packet size */ 62646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner switch (mouse_drv) { 62746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case MOUSE_NONE: 62846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Ack! */ 62946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner read(mouse_fd, mousebuf, BUFSIZ); 63046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return; 63146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case MOUSE_GPM: 63246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner packetsize = 5; 63346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 63446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case MOUSE_IMPS2: 63546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner packetsize = 4; 63646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 63746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case MOUSE_PS2: 63846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case MOUSE_MS: 63946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case MOUSE_BM: 64046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner packetsize = 3; 64146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 64246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case NUM_MOUSE_DRVS: 64346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Uh oh.. */ 64446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner packetsize = 0; 64546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 64646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 64746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 64846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Read as many packets as possible */ 64946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner nread = read(mouse_fd, &mousebuf[start], BUFSIZ-start); 65046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( nread < 0 ) { 65146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return; 65246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 65346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner nread += start; 65446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef DEBUG_MOUSE 65546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner fprintf(stderr, "Read %d bytes from mouse, start = %d\n", nread, start); 65646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif 65746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner for ( i=0; i<(nread-(packetsize-1)); i += packetsize ) { 65846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner switch (mouse_drv) { 65946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case MOUSE_NONE: 66046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 66146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case MOUSE_GPM: 66246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* GPM protocol has 0x80 in high byte */ 66346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( (mousebuf[i] & 0xF8) != 0x80 ) { 66446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Go to next byte */ 66546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner i -= (packetsize-1); 66646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner continue; 66746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 66846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Get current mouse state */ 66946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner button = (~mousebuf[i]) & 0x07; 67046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner dx = (signed char)(mousebuf[i+1]) + 67146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner (signed char)(mousebuf[i+3]); 67246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner dy = -((signed char)(mousebuf[i+2]) + 67346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner (signed char)(mousebuf[i+4])); 67446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 67546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case MOUSE_PS2: 67646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* PS/2 protocol has nothing in high byte */ 67746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( (mousebuf[i] & 0xC0) != 0 ) { 67846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Go to next byte */ 67946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner i -= (packetsize-1); 68046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner continue; 68146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 68246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Get current mouse state */ 68346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner button = (mousebuf[i] & 0x04) >> 1 | /*Middle*/ 68446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner (mousebuf[i] & 0x02) >> 1 | /*Right*/ 68546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner (mousebuf[i] & 0x01) << 2; /*Left*/ 68646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner dx = (mousebuf[i] & 0x10) ? 68746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mousebuf[i+1] - 256 : mousebuf[i+1]; 68846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner dy = (mousebuf[i] & 0x20) ? 68946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner -(mousebuf[i+2] - 256) : -mousebuf[i+2]; 69046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 69146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case MOUSE_IMPS2: 69246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Get current mouse state */ 69346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner button = (mousebuf[i] & 0x04) >> 1 | /*Middle*/ 69446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner (mousebuf[i] & 0x02) >> 1 | /*Right*/ 69546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner (mousebuf[i] & 0x01) << 2 | /*Left*/ 69646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner (mousebuf[i] & 0x40) >> 3 | /* 4 */ 69746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner (mousebuf[i] & 0x80) >> 3; /* 5 */ 69846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner dx = (mousebuf[i] & 0x10) ? 69946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mousebuf[i+1] - 256 : mousebuf[i+1]; 70046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner dy = (mousebuf[i] & 0x20) ? 70146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner -(mousebuf[i+2] - 256) : -mousebuf[i+2]; 70246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner switch (mousebuf[i+3]&0x0F) { 70346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case 0x0E: /* DX = +1 */ 70446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case 0x02: /* DX = -1 */ 70546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 70646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case 0x0F: /* DY = +1 (map button 4) */ 70746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner FB_vgamousecallback(button | (1<<3), 70846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 1, 0, 0); 70946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 71046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case 0x01: /* DY = -1 (map button 5) */ 71146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner FB_vgamousecallback(button | (1<<4), 71246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 1, 0, 0); 71346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 71446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 71546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 71646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case MOUSE_MS: 71746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Microsoft protocol has 0x40 in high byte */ 71846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( (mousebuf[i] & 0x40) != 0x40 ) { 71946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Go to next byte */ 72046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner i -= (packetsize-1); 72146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner continue; 72246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 72346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Get current mouse state */ 72446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner button = ((mousebuf[i] & 0x20) >> 3) | 72546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner ((mousebuf[i] & 0x10) >> 4); 72646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner dx = (signed char)(((mousebuf[i] & 0x03) << 6) | 72746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner (mousebuf[i + 1] & 0x3F)); 72846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner dy = (signed char)(((mousebuf[i] & 0x0C) << 4) | 72946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner (mousebuf[i + 2] & 0x3F)); 73046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 73146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case MOUSE_BM: 73246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* BusMouse protocol has 0xF8 in high byte */ 73346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( (mousebuf[i] & 0xF8) != 0x80 ) { 73446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Go to next byte */ 73546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner i -= (packetsize-1); 73646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner continue; 73746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 73846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Get current mouse state */ 73946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner button = (~mousebuf[i]) & 0x07; 74046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner dx = (signed char)mousebuf[i+1]; 74146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner dy = -(signed char)mousebuf[i+2]; 74246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 74346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case NUM_MOUSE_DRVS: 74446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Uh oh.. */ 74546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner dx = 0; 74646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner dy = 0; 74746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 74846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 74946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner GS_vgamousecallback(button, dx, dy); 75046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 75146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( i < nread ) { 75246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_memcpy(mousebuf, &mousebuf[i], (nread-i)); 75346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner start = (nread-i); 75446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } else { 75546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner start = 0; 75646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 75746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return; 75846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 75946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 76046be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic void handle_keyboard(_THIS) 76146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 76246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner unsigned char keybuf[BUFSIZ]; 76346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int i, nread; 76446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int pressed; 76546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int scancode; 76646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_keysym keysym; 76746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 76846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner nread = read(keyboard_fd, keybuf, BUFSIZ); 76946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner for ( i=0; i<nread; ++i ) { 77046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner scancode = keybuf[i] & 0x7F; 77146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( keybuf[i] & 0x80 ) { 77246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner pressed = SDL_RELEASED; 77346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } else { 77446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner pressed = SDL_PRESSED; 77546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 77646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner TranslateKey(scancode, &keysym); 77746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner posted += SDL_PrivateKeyboard(pressed, &keysym); 77846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 77946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 78046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 78146be48730333120a7b939116cef075e61c12c703David 'Digit' Turnervoid GS_PumpEvents(_THIS) 78246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 78346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner fd_set fdset; 78446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int max_fd; 78546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner static struct timeval zero; 78646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 78746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner do { 78846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner posted = 0; 78946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 79046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner FD_ZERO(&fdset); 79146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner max_fd = 0; 79246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( keyboard_fd >= 0 ) { 79346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner FD_SET(keyboard_fd, &fdset); 79446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( max_fd < keyboard_fd ) { 79546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner max_fd = keyboard_fd; 79646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 79746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 79846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( mouse_fd >= 0 ) { 79946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner FD_SET(mouse_fd, &fdset); 80046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( max_fd < mouse_fd ) { 80146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner max_fd = mouse_fd; 80246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 80346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 80446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( select(max_fd+1, &fdset, NULL, NULL, &zero) > 0 ) { 80546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( keyboard_fd >= 0 ) { 80646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( FD_ISSET(keyboard_fd, &fdset) ) { 80746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner handle_keyboard(this); 80846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 80946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 81046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( mouse_fd >= 0 ) { 81146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( FD_ISSET(mouse_fd, &fdset) ) { 81246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner handle_mouse(this); 81346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 81446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 81546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 81646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } while ( posted ); 81746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 81846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 81946be48730333120a7b939116cef075e61c12c703David 'Digit' Turnervoid GS_InitOSKeymap(_THIS) 82046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 82146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int i; 82246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 82346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Initialize the Linux key translation table */ 82446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 82546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* First get the ascii keys and others not well handled */ 82646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner for (i=0; i<SDL_arraysize(keymap); ++i) { 82746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner switch(i) { 82846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* These aren't handled by the x86 kernel keymapping (?) */ 82946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case SCANCODE_PRINTSCREEN: 83046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner keymap[i] = SDLK_PRINT; 83146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 83246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case SCANCODE_BREAK: 83346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner keymap[i] = SDLK_BREAK; 83446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 83546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case SCANCODE_BREAK_ALTERNATIVE: 83646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner keymap[i] = SDLK_PAUSE; 83746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 83846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case SCANCODE_LEFTSHIFT: 83946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner keymap[i] = SDLK_LSHIFT; 84046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 84146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case SCANCODE_RIGHTSHIFT: 84246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner keymap[i] = SDLK_RSHIFT; 84346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 84446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case SCANCODE_LEFTCONTROL: 84546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner keymap[i] = SDLK_LCTRL; 84646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 84746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case SCANCODE_RIGHTCONTROL: 84846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner keymap[i] = SDLK_RCTRL; 84946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 85046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case SCANCODE_RIGHTWIN: 85146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner keymap[i] = SDLK_RSUPER; 85246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 85346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case SCANCODE_LEFTWIN: 85446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner keymap[i] = SDLK_LSUPER; 85546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 85646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case 127: 85746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner keymap[i] = SDLK_MENU; 85846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 85946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* this should take care of all standard ascii keys */ 86046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner default: 86146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner keymap[i] = KVAL(vga_keymap[0][i]); 86246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 86346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 86446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 86546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner for (i=0; i<SDL_arraysize(keymap); ++i) { 86646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner switch(keymap_temp[i]) { 86746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_F1: keymap[i] = SDLK_F1; break; 86846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_F2: keymap[i] = SDLK_F2; break; 86946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_F3: keymap[i] = SDLK_F3; break; 87046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_F4: keymap[i] = SDLK_F4; break; 87146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_F5: keymap[i] = SDLK_F5; break; 87246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_F6: keymap[i] = SDLK_F6; break; 87346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_F7: keymap[i] = SDLK_F7; break; 87446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_F8: keymap[i] = SDLK_F8; break; 87546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_F9: keymap[i] = SDLK_F9; break; 87646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_F10: keymap[i] = SDLK_F10; break; 87746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_F11: keymap[i] = SDLK_F11; break; 87846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_F12: keymap[i] = SDLK_F12; break; 87946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 88046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_DOWN: keymap[i] = SDLK_DOWN; break; 88146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_LEFT: keymap[i] = SDLK_LEFT; break; 88246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_RIGHT: keymap[i] = SDLK_RIGHT; break; 88346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_UP: keymap[i] = SDLK_UP; break; 88446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 88546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_P0: keymap[i] = SDLK_KP0; break; 88646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_P1: keymap[i] = SDLK_KP1; break; 88746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_P2: keymap[i] = SDLK_KP2; break; 88846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_P3: keymap[i] = SDLK_KP3; break; 88946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_P4: keymap[i] = SDLK_KP4; break; 89046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_P5: keymap[i] = SDLK_KP5; break; 89146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_P6: keymap[i] = SDLK_KP6; break; 89246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_P7: keymap[i] = SDLK_KP7; break; 89346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_P8: keymap[i] = SDLK_KP8; break; 89446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_P9: keymap[i] = SDLK_KP9; break; 89546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_PPLUS: keymap[i] = SDLK_KP_PLUS; break; 89646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_PMINUS: keymap[i] = SDLK_KP_MINUS; break; 89746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_PSTAR: keymap[i] = SDLK_KP_MULTIPLY; break; 89846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_PSLASH: keymap[i] = SDLK_KP_DIVIDE; break; 89946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_PENTER: keymap[i] = SDLK_KP_ENTER; break; 90046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_PDOT: keymap[i] = SDLK_KP_PERIOD; break; 90146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 90246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_SHIFT: if ( keymap[i] != SDLK_RSHIFT ) 90346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner keymap[i] = SDLK_LSHIFT; 90446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 90546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_SHIFTL: keymap[i] = SDLK_LSHIFT; break; 90646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_SHIFTR: keymap[i] = SDLK_RSHIFT; break; 90746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_CTRL: if ( keymap[i] != SDLK_RCTRL ) 90846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner keymap[i] = SDLK_LCTRL; 90946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 91046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_CTRLL: keymap[i] = SDLK_LCTRL; break; 91146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_CTRLR: keymap[i] = SDLK_RCTRL; break; 91246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_ALT: keymap[i] = SDLK_LALT; break; 91346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_ALTGR: keymap[i] = SDLK_RALT; break; 91446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 91546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_INSERT: keymap[i] = SDLK_INSERT; break; 91646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_REMOVE: keymap[i] = SDLK_DELETE; break; 91746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_PGUP: keymap[i] = SDLK_PAGEUP; break; 91846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_PGDN: keymap[i] = SDLK_PAGEDOWN; break; 91946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_FIND: keymap[i] = SDLK_HOME; break; 92046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_SELECT: keymap[i] = SDLK_END; break; 92146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 92246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_NUM: keymap[i] = SDLK_NUMLOCK; break; 92346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_CAPS: keymap[i] = SDLK_CAPSLOCK; break; 92446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 92546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_F13: keymap[i] = SDLK_PRINT; break; 92646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_HOLD: keymap[i] = SDLK_SCROLLOCK; break; 92746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case K_PAUSE: keymap[i] = SDLK_PAUSE; break; 92846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 92946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case 127: keymap[i] = SDLK_BACKSPACE; break; 93046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 93146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner default: break; 93246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 93346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 93446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 93546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 93646be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym) 93746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 93846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Set the keysym information */ 93946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner keysym->scancode = scancode; 94046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner keysym->sym = keymap[scancode]; 94146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner keysym->mod = KMOD_NONE; 94246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 94346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* If UNICODE is on, get the UNICODE value for the key */ 94446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner keysym->unicode = 0; 94546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( SDL_TranslateUNICODE ) { 94646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int map; 94746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDLMod modstate; 94846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 94946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner modstate = SDL_GetModState(); 95046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner map = 0; 95146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( modstate & KMOD_SHIFT ) { 95246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner map |= (1<<KG_SHIFT); 95346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 95446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( modstate & KMOD_CTRL ) { 95546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner map |= (1<<KG_CTRL); 95646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 95746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( modstate & KMOD_ALT ) { 95846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner map |= (1<<KG_ALT); 95946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 96046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( modstate & KMOD_MODE ) { 96146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner map |= (1<<KG_ALTGR); 96246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 96346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( KTYP(vga_keymap[map][scancode]) == KT_LETTER ) { 96446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( modstate & KMOD_CAPS ) { 96546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner map ^= (1<<KG_SHIFT); 96646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 96746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 96846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( KTYP(vga_keymap[map][scancode]) == KT_PAD ) { 96946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( modstate & KMOD_NUM ) { 97046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner keysym->unicode=KVAL(vga_keymap[map][scancode]); 97146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 97246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } else { 97346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner keysym->unicode = KVAL(vga_keymap[map][scancode]); 97446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 97546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 97646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(keysym); 97746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 978