⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdl_x11events.c

📁 MPEG-4编解码的实现(包括MPEG4视音频编解码)
💻 C
📖 第 1 页 / 共 2 页
字号:
			if ( SDL_VideoSurface->flags & SDL_FULLSCREEN ) {
				if ( go_fullscreen ) {
					X11_EnterFullScreen(this);
				} else {
					X11_LeaveFullScreen(this);
				}
			}
			/* Handle focus in/out when grabbed */
			if ( go_fullscreen ) {
				X11_GrabInputNoLock(this, this->input_grab);
			} else {
				X11_GrabInputNoLock(this, SDL_GRAB_OFF);
			}
			X11_CheckMouseModeNoLock(this);
		}
	}
}

void X11_InitKeymap(void)
{
	int i;

	/* Odd keys used in international keyboards */
	for ( i=0; i<SDL_TABLESIZE(ODD_keymap); ++i )
		ODD_keymap[i] = SDLK_UNKNOWN;

#ifdef XK_dead_circumflex
	/* These X keysyms have 0xFE as the high byte */
	ODD_keymap[XK_dead_circumflex&0xFF] = SDLK_CARET;
#endif

	/* Map the miscellaneous keys */
	for ( i=0; i<SDL_TABLESIZE(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 */
}

SDL_keysym *X11_TranslateKey(Display *display, XKeyEvent *xkey, KeyCode kc,
			     SDL_keysym *keysym)
{
	KeySym xsym;

	/* Get the raw keyboard scancode */
	keysym->scancode = kc;
	xsym = XKeycodeToKeysym(display, kc, 0);
#ifdef DEBUG_KEYS
	fprintf(stderr, "Translating key 0x%.4x (%d)\n", xsym, kc);
#endif
	/* Get the translated SDL virtual keysym */
	keysym->sym = SDLK_UNKNOWN;
	if ( xsym ) {
		switch (xsym>>8) {
			case 0x1005FF:
#ifdef SunXK_F36
				if ( xsym == SunXK_F36 )
					keysym->sym = SDLK_F11;
#endif
#ifdef SunXK_F37
				if ( xsym == SunXK_F37 )
					keysym->sym = SDLK_F12;
#endif
				break;
			case 0x00:	/* Latin 1 */
			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 */
				keysym->sym = (SDLKey)(xsym&0xFF);
				/* Map capital letter syms to lowercase */
				if ((keysym->sym >= 'A')&&(keysym->sym <= 'Z'))
					keysym->sym += ('a'-'A');
				break;
			case 0xFE:
				keysym->sym = ODD_keymap[xsym&0xFF];
				break;
			case 0xFF:
				keysym->sym = MISC_keymap[xsym&0xFF];
				break;
			default:
				fprintf(stderr,
					"X11: Unknown 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:
				keysym->sym = SDLK_LSUPER;
				break;
			case 116:
				keysym->sym = SDLK_RSUPER;
				break;
			case 117:
				keysym->sym = SDLK_MENU;
				break;
			default:
				/*
				 * no point in an error message; happens for
				 * several keys when we get a keymap notify
				 */
				break;
		}
	}
	keysym->mod = KMOD_NONE;

	/* If UNICODE is on, get the UNICODE value for the key */
	keysym->unicode = 0;
	if ( SDL_TranslateUNICODE && xkey ) {
		static XComposeStatus state;
		/* Until we handle the IM protocol, use XLookupString() */
		unsigned char keybuf[32];

#define BROKEN_XFREE86_INTERNATIONAL_KBD
/* This appears to be a magical flag that is used with AltGr on
   international keyboards to signal alternate key translations.
   The flag doesn't show up when in fullscreen mode (?)
   FIXME:  Check to see if this code is safe for other servers.
*/
#ifdef BROKEN_XFREE86_INTERNATIONAL_KBD
		/* Work around what appears to be a bug in XFree86 */
		if ( SDL_GetModState() & KMOD_MODE ) {
			xkey->state |= (1<<13);
		}
#endif
		/* Look up the translated value for the key event */
		if ( XLookupString(xkey, (char *)keybuf, sizeof(keybuf),
							NULL, &state) ) {
			/*
			 * FIXME,: XLookupString() may yield more than one
			 * character, so we need a mechanism to allow for
			 * this (perhaps generate null keypress events with
			 * a unicode value)
			 */
			keysym->unicode = keybuf[0];
		}
	}
	return(keysym);
}

/* 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;
	}

	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, gen_event;
	KeyCode xcode[SDLK_LAST];
	Uint8 new_kstate[SDLK_LAST];
	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 ) {
		key_vec = keys_return;
		XQueryKeymap(display, keys_return);
		gen_event = 0;
	} else {
#if 1 /* We no longer generate key down events, just update state */
		gen_event = 0;
#else
		gen_event = 1;
#endif
	}

	/* 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 */
	memset(new_kstate, SDL_RELEASED, sizeof(new_kstate));
	/*
	 * 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)) {
				SDL_keysym sk;
				KeyCode kc = i << 3 | j;
				X11_TranslateKey(display, NULL, kc, &sk);
				new_kstate[sk.sym] = SDL_PRESSED;
				xcode[sk.sym] = kc;
			}
		}
	}
	for(i = SDLK_FIRST+1; i < SDLK_LAST; i++) {
		int state = new_kstate[i];

		if ( state == SDL_PRESSED ) {
			switch (i) {
				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;
			}
		}
		if ( kstate[i] == state )
			continue;

		/*
		 * Send a fake keyboard event correcting the difference between
		 * SDL's keyboard state and the actual. Note that there is no
		 * way to find out the scancode for key releases, but since all
		 * keys are released when focus is lost only keypresses should
		 * be sent here
		 */
		if ( gen_event ) {
			SDL_keysym sk;
			memset(&sk, 0, sizeof(sk));
			sk.sym = i;
			sk.scancode = xcode[i];	/* only valid for key press */
			SDL_PrivateKeyboard(state, &sk);
		} else {
			kstate[i] = state;
		}
	}

	/* 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();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -