📄 sdl_fbevents.c
字号:
} /* 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 FB_vgamousecallback(int button, int relative, 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, relative, 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 MSC, 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]; static int relative = 1; int i, nread; int button = 0; int dx = 0, dy = 0; int packetsize = 0; int realx, realy; /* Figure out the mouse packet size */ switch (mouse_drv) { case MOUSE_NONE: /* Ack! */ read(mouse_fd, mousebuf, BUFSIZ); return; case MOUSE_MSC: packetsize = 5; break; case MOUSE_IMPS2: packetsize = 4; break; case MOUSE_PS2: case MOUSE_MS: case MOUSE_BM: packetsize = 3; break; case MOUSE_ELO: packetsize = ELO_PACKET_SIZE; relative = 0; break; case NUM_MOUSE_DRVS: /* Uh oh.. */ packetsize = 0; break; } /* Special handling for the quite sensitive ELO controller */ if (mouse_drv == MOUSE_ELO) { /* try to read the next packet */ if(eloReadPosition(this, mouse_fd, &dx, &dy, &button, &realx, &realy)) { button = (button & 0x01) << 2; FB_vgamousecallback(button, relative, dx, dy); } return; } /* 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_MSC: /* MSC 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 MOUSE_ELO: if ( mousebuf[i] != ELO_START_BYTE ) { i -= (packetsize-1); continue; } if(!eloParsePacket(&(mousebuf[i]), &dx, &dy, &button)) { i -= (packetsize-1); continue; } button = (button & 0x01) << 2; eloConvertXY(this, &dx, &dy); break; */ case MOUSE_ELO: case NUM_MOUSE_DRVS: /* Uh oh.. */ dx = 0; dy = 0; break; } FB_vgamousecallback(button, relative, dx, dy); } if ( i < nread ) { memcpy(mousebuf, &mousebuf[i], (nread-i)); start = (nread-i); } else { start = 0; } return;}/* Handle switching to another VC, returns when our VC is back. This isn't necessarily the best solution. For SDL 1.3 we need a way of notifying the application when we lose access to the video hardware and when we regain it. */static void switch_vt(_THIS, unsigned short which){ struct vt_stat vtstate; unsigned short current; SDL_Surface *screen; __u16 saved_pal[3*256]; Uint32 screen_arealen; Uint8 *screen_contents; /* Figure out whether or not we're switching to a new console */ if ( (ioctl(keyboard_fd, VT_GETSTATE, &vtstate) < 0) || (which == vtstate.v_active) ) { return; } current = vtstate.v_active; /* Save the contents of the screen, and go to text mode */ SDL_mutexP(hw_lock); wait_idle(this); screen = SDL_VideoSurface; screen_arealen = (screen->h*screen->pitch); screen_contents = (Uint8 *)malloc(screen_arealen); if ( screen_contents ) { memcpy(screen_contents, screen->pixels, screen_arealen); } FB_SavePaletteTo(this, 256, saved_pal); ioctl(keyboard_fd, KDSETMODE, KD_TEXT); /* New console, switch to it */ if ( ioctl(keyboard_fd, VT_ACTIVATE, which) == 0 ) { /* Wait for our console to be activated again */ ioctl(keyboard_fd, VT_WAITACTIVE, which); while ( ioctl(keyboard_fd, VT_WAITACTIVE, current) < 0 ) { if ( (errno != EINTR) && (errno != EAGAIN) ) { /* Unknown VT error - cancel this */ break; } SDL_Delay(500); } } /* Restore graphics mode and the contents of the screen */ ioctl(keyboard_fd, KDSETMODE, KD_GRAPHICS); FB_RestorePaletteFrom(this, 256, saved_pal); if ( screen_contents ) { memcpy(screen->pixels, screen_contents, screen_arealen); free(screen_contents); } SDL_mutexV(hw_lock);}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); /* Handle Alt-FN for vt switch */ switch (keysym.sym) { case SDLK_F1: case SDLK_F2: case SDLK_F3: case SDLK_F4: case SDLK_F5: case SDLK_F6: case SDLK_F7: case SDLK_F8: case SDLK_F9: case SDLK_F10: case SDLK_F11: case SDLK_F12: if ( SDL_GetModState() & KMOD_ALT ) { if ( pressed ) { switch_vt(this, (keysym.sym-SDLK_F1)+1); } break; } /* Fall through to normal processing */ default: posted += SDL_PrivateKeyboard(pressed, &keysym); break; } }}void FB_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 FB_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 + -