📄 sdl_gsevents.c
字号:
mousedrv = getenv("SDL_MOUSEDRV"); mousedev = getenv("SDL_MOUSEDEV"); mouse_fd = -1; /* STD MICE */ if ( mousedev == NULL ) { /* FIXME someday... allow multiple mice in this driver */ char *ps2mice[] = { "/dev/input/mice", "/dev/usbmouse", "/dev/psaux", NULL }; /* First try to use GPM in repeater mode */ if ( mouse_fd < 0 ) { if ( gpm_available() ) { mouse_fd = open(GPM_NODE_FIFO, O_RDONLY, 0); if ( mouse_fd >= 0 ) {#ifdef DEBUG_MOUSEfprintf(stderr, "Using GPM mouse\n");#endif mouse_drv = MOUSE_GPM; } } } /* Now try to use a modern PS/2 mouse */ for ( i=0; (mouse_fd < 0) && ps2mice[i]; ++i ) { mouse_fd = open(ps2mice[i], O_RDWR, 0); if (mouse_fd < 0) { mouse_fd = open(ps2mice[i], O_RDONLY, 0); } if (mouse_fd >= 0) { /* rcg06112001 Attempt to set IMPS/2 mode */ if ( i == 0 ) { set_imps2_mode(mouse_fd); } if (detect_imps2(mouse_fd)) {#ifdef DEBUG_MOUSEfprintf(stderr, "Using IMPS2 mouse\n");#endif mouse_drv = MOUSE_IMPS2; } else { mouse_drv = MOUSE_PS2;#ifdef DEBUG_MOUSEfprintf(stderr, "Using PS2 mouse\n");#endif } } } /* Next try to use a PPC ADB port mouse */ if ( mouse_fd < 0 ) { mouse_fd = open("/dev/adbmouse", O_RDONLY, 0); if ( mouse_fd >= 0 ) {#ifdef DEBUG_MOUSEfprintf(stderr, "Using ADB mouse\n");#endif mouse_drv = MOUSE_BM; } } } /* Default to a serial Microsoft mouse */ if ( mouse_fd < 0 ) { if ( mousedev == NULL ) { mousedev = "/dev/mouse"; } mouse_fd = open(mousedev, O_RDONLY, 0); if ( mouse_fd >= 0 ) { struct termios mouse_termios; /* Set the sampling speed to 1200 baud */ tcgetattr(mouse_fd, &mouse_termios); mouse_termios.c_iflag = IGNBRK | IGNPAR; mouse_termios.c_oflag = 0; mouse_termios.c_lflag = 0; mouse_termios.c_line = 0; mouse_termios.c_cc[VTIME] = 0; mouse_termios.c_cc[VMIN] = 1; mouse_termios.c_cflag = CREAD | CLOCAL | HUPCL; mouse_termios.c_cflag |= CS8; mouse_termios.c_cflag |= B1200; tcsetattr(mouse_fd, TCSAFLUSH, &mouse_termios);#ifdef DEBUG_MOUSEfprintf(stderr, "Using Microsoft mouse on %s\n", mousedev);#endif mouse_drv = MOUSE_MS; } } if ( mouse_fd < 0 ) { mouse_drv = MOUSE_NONE; } return(mouse_fd);}static int posted = 0;void GS_vgamousecallback(int button, int dx, int dy){ int button_1, button_3; int button_state; int state_changed; int i; Uint8 state; if ( dx || dy ) { posted += SDL_PrivateMouseMotion(0, 1, dx, dy); } /* Swap button 1 and 3 */ button_1 = (button & 0x04) >> 2; button_3 = (button & 0x01) << 2; button &= ~0x05; button |= (button_1|button_3); /* See what changed */ button_state = SDL_GetMouseState(NULL, NULL); state_changed = button_state ^ button; for ( i=0; i<8; ++i ) { if ( state_changed & (1<<i) ) { if ( button & (1<<i) ) { state = SDL_PRESSED; } else { state = SDL_RELEASED; } posted += SDL_PrivateMouseButton(state, i+1, 0, 0); } }}/* For now, use GPM, PS/2, and MS protocols Driver adapted from the SVGAlib mouse driver code (taken from gpm, etc.) */static void handle_mouse(_THIS){ static int start = 0; static unsigned char mousebuf[BUFSIZ]; int i, nread; int button = 0; int dx = 0, dy = 0; int packetsize = 0; /* Figure out the mouse packet size */ switch (mouse_drv) { case MOUSE_NONE: /* Ack! */ read(mouse_fd, mousebuf, BUFSIZ); return; case MOUSE_GPM: packetsize = 5; break; case MOUSE_IMPS2: packetsize = 4; break; case MOUSE_PS2: case MOUSE_MS: case MOUSE_BM: packetsize = 3; break; case NUM_MOUSE_DRVS: /* Uh oh.. */ packetsize = 0; break; } /* Read as many packets as possible */ nread = read(mouse_fd, &mousebuf[start], BUFSIZ-start); if ( nread < 0 ) { return; } nread += start;#ifdef DEBUG_MOUSE fprintf(stderr, "Read %d bytes from mouse, start = %d\n", nread, start);#endif for ( i=0; i<(nread-(packetsize-1)); i += packetsize ) { switch (mouse_drv) { case MOUSE_NONE: break; case MOUSE_GPM: /* GPM protocol has 0x80 in high byte */ if ( (mousebuf[i] & 0xF8) != 0x80 ) { /* Go to next byte */ i -= (packetsize-1); continue; } /* Get current mouse state */ button = (~mousebuf[i]) & 0x07; dx = (signed char)(mousebuf[i+1]) + (signed char)(mousebuf[i+3]); dy = -((signed char)(mousebuf[i+2]) + (signed char)(mousebuf[i+4])); break; case MOUSE_PS2: /* PS/2 protocol has nothing in high byte */ if ( (mousebuf[i] & 0xC0) != 0 ) { /* Go to next byte */ i -= (packetsize-1); continue; } /* Get current mouse state */ button = (mousebuf[i] & 0x04) >> 1 | /*Middle*/ (mousebuf[i] & 0x02) >> 1 | /*Right*/ (mousebuf[i] & 0x01) << 2; /*Left*/ dx = (mousebuf[i] & 0x10) ? mousebuf[i+1] - 256 : mousebuf[i+1]; dy = (mousebuf[i] & 0x20) ? -(mousebuf[i+2] - 256) : -mousebuf[i+2]; break; case MOUSE_IMPS2: /* Get current mouse state */ button = (mousebuf[i] & 0x04) >> 1 | /*Middle*/ (mousebuf[i] & 0x02) >> 1 | /*Right*/ (mousebuf[i] & 0x01) << 2 | /*Left*/ (mousebuf[i] & 0x40) >> 3 | /* 4 */ (mousebuf[i] & 0x80) >> 3; /* 5 */ dx = (mousebuf[i] & 0x10) ? mousebuf[i+1] - 256 : mousebuf[i+1]; dy = (mousebuf[i] & 0x20) ? -(mousebuf[i+2] - 256) : -mousebuf[i+2]; switch (mousebuf[i+3]&0x0F) { case 0x0E: /* DX = +1 */ case 0x02: /* DX = -1 */ break; case 0x0F: /* DY = +1 (map button 4) */ FB_vgamousecallback(button | (1<<3), 1, 0, 0); break; case 0x01: /* DY = -1 (map button 5) */ FB_vgamousecallback(button | (1<<4), 1, 0, 0); break; } break; case MOUSE_MS: /* Microsoft protocol has 0x40 in high byte */ if ( (mousebuf[i] & 0x40) != 0x40 ) { /* Go to next byte */ i -= (packetsize-1); continue; } /* Get current mouse state */ button = ((mousebuf[i] & 0x20) >> 3) | ((mousebuf[i] & 0x10) >> 4); dx = (signed char)(((mousebuf[i] & 0x03) << 6) | (mousebuf[i + 1] & 0x3F)); dy = (signed char)(((mousebuf[i] & 0x0C) << 4) | (mousebuf[i + 2] & 0x3F)); break; case MOUSE_BM: /* BusMouse protocol has 0xF8 in high byte */ if ( (mousebuf[i] & 0xF8) != 0x80 ) { /* Go to next byte */ i -= (packetsize-1); continue; } /* Get current mouse state */ button = (~mousebuf[i]) & 0x07; dx = (signed char)mousebuf[i+1]; dy = -(signed char)mousebuf[i+2]; break; case NUM_MOUSE_DRVS: /* Uh oh.. */ dx = 0; dy = 0; break; } GS_vgamousecallback(button, dx, dy); } if ( i < nread ) { memcpy(mousebuf, &mousebuf[i], (nread-i)); start = (nread-i); } else { start = 0; } return;}static void handle_keyboard(_THIS){ unsigned char keybuf[BUFSIZ]; int i, nread; int pressed; int scancode; SDL_keysym keysym; nread = read(keyboard_fd, keybuf, BUFSIZ); for ( i=0; i<nread; ++i ) { scancode = keybuf[i] & 0x7F; if ( keybuf[i] & 0x80 ) { pressed = SDL_RELEASED; } else { pressed = SDL_PRESSED; } TranslateKey(scancode, &keysym); posted += SDL_PrivateKeyboard(pressed, &keysym); }}void GS_PumpEvents(_THIS){ fd_set fdset; int max_fd; static struct timeval zero; do { posted = 0; FD_ZERO(&fdset); max_fd = 0; if ( keyboard_fd >= 0 ) { FD_SET(keyboard_fd, &fdset); if ( max_fd < keyboard_fd ) { max_fd = keyboard_fd; } } if ( mouse_fd >= 0 ) { FD_SET(mouse_fd, &fdset); if ( max_fd < mouse_fd ) { max_fd = mouse_fd; } } if ( select(max_fd+1, &fdset, NULL, NULL, &zero) > 0 ) { if ( keyboard_fd >= 0 ) { if ( FD_ISSET(keyboard_fd, &fdset) ) { handle_keyboard(this); } } if ( mouse_fd >= 0 ) { if ( FD_ISSET(mouse_fd, &fdset) ) { handle_mouse(this); } } } } while ( posted );}void GS_InitOSKeymap(_THIS){ int i; /* Initialize the Linux key translation table */ /* First get the ascii keys and others not well handled */ for (i=0; i<SDL_TABLESIZE(keymap); ++i) { switch(i) { /* These aren't handled by the x86 kernel keymapping (?) */ case SCANCODE_PRINTSCREEN: keymap[i] = SDLK_PRINT; break; case SCANCODE_BREAK: keymap[i] = SDLK_BREAK; break; case SCANCODE_BREAK_ALTERNATIVE: keymap[i] = SDLK_PAUSE; break; case SCANCODE_LEFTSHIFT: keymap[i] = SDLK_LSHIFT; break; case SCANCODE_RIGHTSHIFT: keymap[i] = SDLK_RSHIFT; break; case SCANCODE_LEFTCONTROL: keymap[i] = SDLK_LCTRL; break; case SCANCODE_RIGHTCONTROL: keymap[i] = SDLK_RCTRL; break; case SCANCODE_RIGHTWIN: keymap[i] = SDLK_RSUPER; break; case SCANCODE_LEFTWIN: keymap[i] = SDLK_LSUPER; break; case 127: keymap[i] = SDLK_MENU; break; /* this should take care of all standard ascii keys */ default: keymap[i] = KVAL(vga_keymap[0][i]); break; } } for (i=0; i<SDL_TABLESIZE(keymap); ++i) { switch(keymap_temp[i]) { case K_F1: keymap[i] = SDLK_F1; break; case K_F2: keymap[i] = SDLK_F2; break; case K_F3: keymap[i] = SDLK_F3; break; case K_F4: keymap[i] = SDLK_F4; break; case K_F5: keymap[i] = SDLK_F5; break; case K_F6: keymap[i] = SDLK_F6; break; case K_F7: keymap[i] = SDLK_F7; break; case K_F8: keymap[i] = SDLK_F8; break; case K_F9: keymap[i] = SDLK_F9; break; case K_F10: keymap[i] = SDLK_F10; break; case K_F11: keymap[i] = SDLK_F11; break; case K_F12: keymap[i] = SDLK_F12; break; case K_DOWN: keymap[i] = SDLK_DOWN; break; case K_LEFT: keymap[i] = SDLK_LEFT; break; case K_RIGHT: keymap[i] = SDLK_RIGHT; break; case K_UP: keymap[i] = SDLK_UP; break; case K_P0: keymap[i] = SDLK_KP0; break; case K_P1: keymap[i] = SDLK_KP1; break; case K_P2: keymap[i] = SDLK_KP2; break; case K_P3: keymap[i] = SDLK_KP3; break; case K_P4: keymap[i] = SDLK_KP4; break; case K_P5: keymap[i] = SDLK_KP5; break; case K_P6: keymap[i] = SDLK_KP6; break; case K_P7: keymap[i] = SDLK_KP7; break; case K_P8: keymap[i] = SDLK_KP8; break; case K_P9: keymap[i] = SDLK_KP9; break; case K_PPLUS: keymap[i] = SDLK_KP_PLUS; break; case K_PMINUS: keymap[i] = SDLK_KP_MINUS; break; case K_PSTAR: keymap[i] = SDLK_KP_MULTIPLY; break; case K_PSLASH: keymap[i] = SDLK_KP_DIVIDE; break; case K_PENTER: keymap[i] = SDLK_KP_ENTER; break; case K_PDOT: keymap[i] = SDLK_KP_PERIOD; break; case K_SHIFT: if ( keymap[i] != SDLK_RSHIFT ) keymap[i] = SDLK_LSHIFT; break; case K_SHIFTL: keymap[i] = SDLK_LSHIFT; break; case K_SHIFTR: keymap[i] = SDLK_RSHIFT; break; case K_CTRL: if ( keymap[i] != SDLK_RCTRL ) keymap[i] = SDLK_LCTRL; break; case K_CTRLL: keymap[i] = SDLK_LCTRL; break; case K_CTRLR: keymap[i] = SDLK_RCTRL; break; case K_ALT: keymap[i] = SDLK_LALT; break; case K_ALTGR: keymap[i] = SDLK_RALT; break; case K_INSERT: keymap[i] = SDLK_INSERT; break; case K_REMOVE: keymap[i] = SDLK_DELETE; break; case K_PGUP: keymap[i] = SDLK_PAGEUP; break; case K_PGDN: keymap[i] = SDLK_PAGEDOWN; break; case K_FIND: keymap[i] = SDLK_HOME; break; case K_SELECT: keymap[i] = SDLK_END; break; case K_NUM: keymap[i] = SDLK_NUMLOCK; break; case K_CAPS: keymap[i] = SDLK_CAPSLOCK; break; case K_F13: keymap[i] = SDLK_PRINT; break; case K_HOLD: keymap[i] = SDLK_SCROLLOCK; break; case K_PAUSE: keymap[i] = SDLK_PAUSE; break; case 127: keymap[i] = SDLK_BACKSPACE; break; default: break; } }}static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym){ /* Set the keysym information */ keysym->scancode = scancode; keysym->sym = keymap[scancode]; keysym->mod = KMOD_NONE; /* If UNICODE is on, get the UNICODE value for the key */ keysym->unicode = 0; if ( SDL_TranslateUNICODE ) { int map; SDLMod modstate; modstate = SDL_GetModState(); map = 0; if ( modstate & KMOD_SHIFT ) { map |= (1<<KG_SHIFT); } if ( modstate & KMOD_CTRL ) { map |= (1<<KG_CTRL); } if ( modstate & KMOD_ALT ) { map |= (1<<KG_ALT); } if ( modstate & KMOD_MODE ) { map |= (1<<KG_ALTGR); } if ( KTYP(vga_keymap[map][scancode]) == KT_LETTER ) { if ( modstate & KMOD_CAPS ) { map ^= (1<<KG_SHIFT); } } if ( KTYP(vga_keymap[map][scancode]) == KT_PAD ) { if ( modstate & KMOD_NUM ) { keysym->unicode=KVAL(vga_keymap[map][scancode]); } } else { keysym->unicode = KVAL(vga_keymap[map][scancode]); } } return(keysym);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -