📄 sdl_x11events.c
字号:
ODD_keymap[XK_dead_acute&0xFF] = SDLK_COMPOSE; ODD_keymap[XK_dead_tilde&0xFF] = SDLK_COMPOSE; ODD_keymap[XK_dead_macron&0xFF] = SDLK_COMPOSE; ODD_keymap[XK_dead_breve&0xFF] = SDLK_COMPOSE; ODD_keymap[XK_dead_abovedot&0xFF] = SDLK_COMPOSE; ODD_keymap[XK_dead_diaeresis&0xFF] = SDLK_COMPOSE; ODD_keymap[XK_dead_abovering&0xFF] = SDLK_COMPOSE; ODD_keymap[XK_dead_doubleacute&0xFF] = SDLK_COMPOSE; ODD_keymap[XK_dead_caron&0xFF] = SDLK_COMPOSE; ODD_keymap[XK_dead_cedilla&0xFF] = SDLK_COMPOSE; ODD_keymap[XK_dead_ogonek&0xFF] = SDLK_COMPOSE; ODD_keymap[XK_dead_iota&0xFF] = SDLK_COMPOSE; ODD_keymap[XK_dead_voiced_sound&0xFF] = SDLK_COMPOSE; ODD_keymap[XK_dead_semivoiced_sound&0xFF] = SDLK_COMPOSE; ODD_keymap[XK_dead_belowdot&0xFF] = SDLK_COMPOSE;#ifdef XK_dead_hook ODD_keymap[XK_dead_hook&0xFF] = SDLK_COMPOSE;#endif#ifdef XK_dead_horn ODD_keymap[XK_dead_horn&0xFF] = SDLK_COMPOSE;#endif#ifdef XK_dead_circumflex /* These X keysyms have 0xFE as the high byte */ ODD_keymap[XK_dead_circumflex&0xFF] = SDLK_CARET;#endif#ifdef XK_ISO_Level3_Shift ODD_keymap[XK_ISO_Level3_Shift&0xFF] = SDLK_MODE; /* "Alt Gr" key */#endif /* Map the miscellaneous keys */ for ( i=0; i<SDL_arraysize(MISC_keymap); ++i ) MISC_keymap[i] = SDLK_UNKNOWN; /* These X keysyms have 0xFF as the high byte */ MISC_keymap[XK_BackSpace&0xFF] = SDLK_BACKSPACE; MISC_keymap[XK_Tab&0xFF] = SDLK_TAB; MISC_keymap[XK_Clear&0xFF] = SDLK_CLEAR; MISC_keymap[XK_Return&0xFF] = SDLK_RETURN; MISC_keymap[XK_Pause&0xFF] = SDLK_PAUSE; MISC_keymap[XK_Escape&0xFF] = SDLK_ESCAPE; MISC_keymap[XK_Delete&0xFF] = SDLK_DELETE; MISC_keymap[XK_KP_0&0xFF] = SDLK_KP0; /* Keypad 0-9 */ MISC_keymap[XK_KP_1&0xFF] = SDLK_KP1; MISC_keymap[XK_KP_2&0xFF] = SDLK_KP2; MISC_keymap[XK_KP_3&0xFF] = SDLK_KP3; MISC_keymap[XK_KP_4&0xFF] = SDLK_KP4; MISC_keymap[XK_KP_5&0xFF] = SDLK_KP5; MISC_keymap[XK_KP_6&0xFF] = SDLK_KP6; MISC_keymap[XK_KP_7&0xFF] = SDLK_KP7; MISC_keymap[XK_KP_8&0xFF] = SDLK_KP8; MISC_keymap[XK_KP_9&0xFF] = SDLK_KP9; MISC_keymap[XK_KP_Insert&0xFF] = SDLK_KP0; MISC_keymap[XK_KP_End&0xFF] = SDLK_KP1; MISC_keymap[XK_KP_Down&0xFF] = SDLK_KP2; MISC_keymap[XK_KP_Page_Down&0xFF] = SDLK_KP3; MISC_keymap[XK_KP_Left&0xFF] = SDLK_KP4; MISC_keymap[XK_KP_Begin&0xFF] = SDLK_KP5; MISC_keymap[XK_KP_Right&0xFF] = SDLK_KP6; MISC_keymap[XK_KP_Home&0xFF] = SDLK_KP7; MISC_keymap[XK_KP_Up&0xFF] = SDLK_KP8; MISC_keymap[XK_KP_Page_Up&0xFF] = SDLK_KP9; MISC_keymap[XK_KP_Delete&0xFF] = SDLK_KP_PERIOD; MISC_keymap[XK_KP_Decimal&0xFF] = SDLK_KP_PERIOD; MISC_keymap[XK_KP_Divide&0xFF] = SDLK_KP_DIVIDE; MISC_keymap[XK_KP_Multiply&0xFF] = SDLK_KP_MULTIPLY; MISC_keymap[XK_KP_Subtract&0xFF] = SDLK_KP_MINUS; MISC_keymap[XK_KP_Add&0xFF] = SDLK_KP_PLUS; MISC_keymap[XK_KP_Enter&0xFF] = SDLK_KP_ENTER; MISC_keymap[XK_KP_Equal&0xFF] = SDLK_KP_EQUALS; MISC_keymap[XK_Up&0xFF] = SDLK_UP; MISC_keymap[XK_Down&0xFF] = SDLK_DOWN; MISC_keymap[XK_Right&0xFF] = SDLK_RIGHT; MISC_keymap[XK_Left&0xFF] = SDLK_LEFT; MISC_keymap[XK_Insert&0xFF] = SDLK_INSERT; MISC_keymap[XK_Home&0xFF] = SDLK_HOME; MISC_keymap[XK_End&0xFF] = SDLK_END; MISC_keymap[XK_Page_Up&0xFF] = SDLK_PAGEUP; MISC_keymap[XK_Page_Down&0xFF] = SDLK_PAGEDOWN; MISC_keymap[XK_F1&0xFF] = SDLK_F1; MISC_keymap[XK_F2&0xFF] = SDLK_F2; MISC_keymap[XK_F3&0xFF] = SDLK_F3; MISC_keymap[XK_F4&0xFF] = SDLK_F4; MISC_keymap[XK_F5&0xFF] = SDLK_F5; MISC_keymap[XK_F6&0xFF] = SDLK_F6; MISC_keymap[XK_F7&0xFF] = SDLK_F7; MISC_keymap[XK_F8&0xFF] = SDLK_F8; MISC_keymap[XK_F9&0xFF] = SDLK_F9; MISC_keymap[XK_F10&0xFF] = SDLK_F10; MISC_keymap[XK_F11&0xFF] = SDLK_F11; MISC_keymap[XK_F12&0xFF] = SDLK_F12; MISC_keymap[XK_F13&0xFF] = SDLK_F13; MISC_keymap[XK_F14&0xFF] = SDLK_F14; MISC_keymap[XK_F15&0xFF] = SDLK_F15; MISC_keymap[XK_Num_Lock&0xFF] = SDLK_NUMLOCK; MISC_keymap[XK_Caps_Lock&0xFF] = SDLK_CAPSLOCK; MISC_keymap[XK_Scroll_Lock&0xFF] = SDLK_SCROLLOCK; MISC_keymap[XK_Shift_R&0xFF] = SDLK_RSHIFT; MISC_keymap[XK_Shift_L&0xFF] = SDLK_LSHIFT; MISC_keymap[XK_Control_R&0xFF] = SDLK_RCTRL; MISC_keymap[XK_Control_L&0xFF] = SDLK_LCTRL; MISC_keymap[XK_Alt_R&0xFF] = SDLK_RALT; MISC_keymap[XK_Alt_L&0xFF] = SDLK_LALT; MISC_keymap[XK_Meta_R&0xFF] = SDLK_RMETA; MISC_keymap[XK_Meta_L&0xFF] = SDLK_LMETA; MISC_keymap[XK_Super_L&0xFF] = SDLK_LSUPER; /* Left "Windows" */ MISC_keymap[XK_Super_R&0xFF] = SDLK_RSUPER; /* Right "Windows */ MISC_keymap[XK_Mode_switch&0xFF] = SDLK_MODE; /* "Alt Gr" key */ MISC_keymap[XK_Multi_key&0xFF] = SDLK_COMPOSE; /* Multi-key compose */ MISC_keymap[XK_Help&0xFF] = SDLK_HELP; MISC_keymap[XK_Print&0xFF] = SDLK_PRINT; MISC_keymap[XK_Sys_Req&0xFF] = SDLK_SYSREQ; MISC_keymap[XK_Break&0xFF] = SDLK_BREAK; MISC_keymap[XK_Menu&0xFF] = SDLK_MENU; MISC_keymap[XK_Hyper_R&0xFF] = SDLK_MENU; /* Windows "Menu" key */}/* Get the translated SDL virtual keysym */SDLKey X11_TranslateKeycode(Display *display, KeyCode kc){ KeySym xsym; SDLKey key; xsym = XKeycodeToKeysym(display, kc, 0);#ifdef DEBUG_KEYS fprintf(stderr, "Translating key code %d -> 0x%.4x\n", kc, xsym);#endif key = SDLK_UNKNOWN; if ( xsym ) { switch (xsym>>8) { case 0x1005FF:#ifdef SunXK_F36 if ( xsym == SunXK_F36 ) key = SDLK_F11;#endif#ifdef SunXK_F37 if ( xsym == SunXK_F37 ) key = SDLK_F12;#endif break; case 0x00: /* Latin 1 */ key = (SDLKey)(xsym & 0xFF); break; case 0x01: /* Latin 2 */ case 0x02: /* Latin 3 */ case 0x03: /* Latin 4 */ case 0x04: /* Katakana */ case 0x05: /* Arabic */ case 0x06: /* Cyrillic */ case 0x07: /* Greek */ case 0x08: /* Technical */ case 0x0A: /* Publishing */ case 0x0C: /* Hebrew */ case 0x0D: /* Thai */ /* These are wrong, but it's better than nothing */ key = (SDLKey)(xsym & 0xFF); break; case 0xFE: key = ODD_keymap[xsym&0xFF]; break; case 0xFF: key = MISC_keymap[xsym&0xFF]; break; default: /* fprintf(stderr, "X11: Unhandled xsym, sym = 0x%04x\n", (unsigned int)xsym); */ break; } } else { /* X11 doesn't know how to translate the key! */ switch (kc) { /* Caution: These keycodes are from the Microsoft Keyboard */ case 115: key = SDLK_LSUPER; break; case 116: key = SDLK_RSUPER; break; case 117: key = SDLK_MENU; break; default: /* * no point in an error message; happens for * several keys when we get a keymap notify */ break; } } return key;}/* X11 modifier masks for various keys */static unsigned meta_l_mask, meta_r_mask, alt_l_mask, alt_r_mask;static unsigned num_mask, mode_switch_mask;static void get_modifier_masks(Display *display){ static unsigned got_masks; int i, j; XModifierKeymap *xmods; unsigned n; if(got_masks) return; xmods = XGetModifierMapping(display); n = xmods->max_keypermod; for(i = 3; i < 8; i++) { for(j = 0; j < n; j++) { KeyCode kc = xmods->modifiermap[i * n + j]; KeySym ks = XKeycodeToKeysym(display, kc, 0); unsigned mask = 1 << i; switch(ks) { case XK_Num_Lock: num_mask = mask; break; case XK_Alt_L: alt_l_mask = mask; break; case XK_Alt_R: alt_r_mask = mask; break; case XK_Meta_L: meta_l_mask = mask; break; case XK_Meta_R: meta_r_mask = mask; break; case XK_Mode_switch: mode_switch_mask = mask; break; } } } XFreeModifiermap(xmods); got_masks = 1;}/* * This function is semi-official; it is not officially exported and should * not be considered part of the SDL API, but may be used by client code * that *really* needs it (including legacy code). * It is slow, though, and should be avoided if possible. * * Note that it isn't completely accurate either; in particular, multi-key * sequences (dead accents, compose key sequences) will not work since the * state has been irrevocably lost. */Uint16 X11_KeyToUnicode(SDLKey keysym, SDLMod modifiers){ struct SDL_VideoDevice *this = current_video; char keybuf[32]; int i; KeySym xsym = 0; XKeyEvent xkey; Uint16 unicode; if ( !this || !SDL_Display ) { return 0; } SDL_memset(&xkey, 0, sizeof(xkey)); xkey.display = SDL_Display; xsym = keysym; /* last resort if not found */ for (i = 0; i < 256; ++i) { if ( MISC_keymap[i] == keysym ) { xsym = 0xFF00 | i; break; } else if ( ODD_keymap[i] == keysym ) { xsym = 0xFE00 | i; break; } } xkey.keycode = XKeysymToKeycode(xkey.display, xsym); get_modifier_masks(SDL_Display); if(modifiers & KMOD_SHIFT) xkey.state |= ShiftMask; if(modifiers & KMOD_CAPS) xkey.state |= LockMask; if(modifiers & KMOD_CTRL) xkey.state |= ControlMask; if(modifiers & KMOD_MODE) xkey.state |= mode_switch_mask; if(modifiers & KMOD_LALT) xkey.state |= alt_l_mask; if(modifiers & KMOD_RALT) xkey.state |= alt_r_mask; if(modifiers & KMOD_LMETA) xkey.state |= meta_l_mask; if(modifiers & KMOD_RMETA) xkey.state |= meta_r_mask; if(modifiers & KMOD_NUM) xkey.state |= num_mask; unicode = 0; if ( XLookupString(&xkey, keybuf, sizeof(keybuf), NULL, NULL) ) unicode = (unsigned char)keybuf[0]; return(unicode);}/* * Called when focus is regained, to read the keyboard state and generate * synthetic keypress/release events. * key_vec is a bit vector of keycodes (256 bits) */void X11_SetKeyboardState(Display *display, const char *key_vec){ char keys_return[32]; int i; Uint8 *kstate = SDL_GetKeyState(NULL); SDLMod modstate; Window junk_window; int x, y; unsigned int mask; /* The first time the window is mapped, we initialize key state */ if ( ! key_vec ) { XQueryKeymap(display, keys_return); key_vec = keys_return; } /* Get the keyboard modifier state */ modstate = 0; get_modifier_masks(display); if ( XQueryPointer(display, DefaultRootWindow(display), &junk_window, &junk_window, &x, &y, &x, &y, &mask) ) { if ( mask & LockMask ) { modstate |= KMOD_CAPS; } if ( mask & mode_switch_mask ) { modstate |= KMOD_MODE; } if ( mask & num_mask ) { modstate |= KMOD_NUM; } } /* Zero the new keyboard state and generate it */ SDL_memset(kstate, 0, SDLK_LAST); /* * An obvious optimisation is to check entire longwords at a time in * both loops, but we can't be sure the arrays are aligned so it's not * worth the extra complexity */ for ( i = 0; i < 32; i++ ) { int j; if ( !key_vec[i] ) continue; for ( j = 0; j < 8; j++ ) { if ( key_vec[i] & (1 << j) ) { SDLKey key; KeyCode kc = (i << 3 | j); key = X11_TranslateKeycode(display, kc); if ( key == SDLK_UNKNOWN ) { continue; } kstate[key] = SDL_PRESSED; switch (key) { case SDLK_LSHIFT: modstate |= KMOD_LSHIFT; break; case SDLK_RSHIFT: modstate |= KMOD_RSHIFT; break; case SDLK_LCTRL: modstate |= KMOD_LCTRL; break; case SDLK_RCTRL: modstate |= KMOD_RCTRL; break; case SDLK_LALT: modstate |= KMOD_LALT; break; case SDLK_RALT: modstate |= KMOD_RALT; break; case SDLK_LMETA: modstate |= KMOD_LMETA; break; case SDLK_RMETA: modstate |= KMOD_RMETA; break; default: break; } } } } /* Hack - set toggle key state */ if ( modstate & KMOD_CAPS ) { kstate[SDLK_CAPSLOCK] = SDL_PRESSED; } else { kstate[SDLK_CAPSLOCK] = SDL_RELEASED; } if ( modstate & KMOD_NUM ) { kstate[SDLK_NUMLOCK] = SDL_PRESSED; } else { kstate[SDLK_NUMLOCK] = SDL_RELEASED; } /* Set the final modifier state */ SDL_SetModState(modstate);}void X11_InitOSKeymap(_THIS){ X11_InitKeymap();}void X11_SaveScreenSaver(Display *display, int *saved_timeout, BOOL *dpms){ int timeout, interval, prefer_blank, allow_exp; XGetScreenSaver(display, &timeout, &interval, &prefer_blank, &allow_exp); *saved_timeout = timeout;#if SDL_VIDEO_DRIVER_X11_DPMS if ( SDL_X11_HAVE_DPMS ) { int dummy; if ( DPMSQueryExtension(display, &dummy, &dummy) ) { CARD16 state; DPMSInfo(display, &state, dpms); } }#else *dpms = 0;#endif /* SDL_VIDEO_DRIVER_X11_DPMS */}void X11_DisableScreenSaver(_THIS, Display *display){ int timeout, interval, prefer_blank, allow_exp; if (this->hidden->allow_screensaver) { return; } XGetScreenSaver(display, &timeout, &interval, &prefer_blank, &allow_exp); timeout = 0; XSetScreenSaver(display, timeout, interval, prefer_blank, allow_exp);#if SDL_VIDEO_DRIVER_X11_DPMS if ( SDL_X11_HAVE_DPMS ) { int dummy; if ( DPMSQueryExtension(display, &dummy, &dummy) ) { DPMSDisable(display); } }#endif /* SDL_VIDEO_DRIVER_X11_DPMS */}void X11_RestoreScreenSaver(_THIS, Display *display, int saved_timeout, BOOL dpms){ int timeout, interval, prefer_blank, allow_exp; if (this->hidden->allow_screensaver) { return; } XGetScreenSaver(display, &timeout, &interval, &prefer_blank, &allow_exp); timeout = saved_timeout; XSetScreenSaver(display, timeout, interval, prefer_blank, allow_exp);#if SDL_VIDEO_DRIVER_X11_DPMS if ( SDL_X11_HAVE_DPMS ) { int dummy; if ( DPMSQueryExtension(display, &dummy, &dummy) ) { if ( dpms ) { DPMSEnable(display); } } }#endif /* SDL_VIDEO_DRIVER_X11_DPMS */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -