Пример #1
0
uint32 SdlEventSource::obtainUnicode(const SDL_keysym keySym) {
#if SDL_VERSION_ATLEAST(2, 0, 0)
	SDL_Event events[2];

	// In SDL2, the unicode field has been removed from the keysym struct.
	// Instead a SDL_TEXTINPUT event is generated on key combinations that
	// generates unicode.
	// Here we peek into the event queue for the event to see if it exists.
	int n = SDL_PeepEvents(events, 2, SDL_PEEKEVENT, SDL_KEYDOWN, SDL_TEXTINPUT);
	// Make sure that the TEXTINPUT event belongs to this KEYDOWN
	// event and not another pending one.
	if ((n > 0 && events[0].type == SDL_TEXTINPUT)
	    || (n > 1 && events[0].type != SDL_KEYDOWN && events[1].type == SDL_TEXTINPUT)) {
		// Remove the text input event we associate with the key press. This
		// makes sure we never get any SDL_TEXTINPUT events which do "belong"
		// to SDL_KEYDOWN events.
		n = SDL_PeepEvents(events, 1, SDL_GETEVENT, SDL_TEXTINPUT, SDL_TEXTINPUT);
		// This is basically a paranoia safety check because we know there
		// must be a text input event in the queue.
		if (n > 0) {
			return convUTF8ToUTF32(events[0].text.text);
		} else {
			return 0;
		}
	} else {
		return 0;
	}
#else
	return keySym.unicode;
#endif
}
Пример #2
0
uint32 SdlEventSource::obtainUnicode(const SDL_keysym keySym) {
#if SDL_VERSION_ATLEAST(2, 0, 0)
	SDL_Event events[2];

	// Update the event queue here to give SDL a chance to insert TEXTINPUT
	// events for KEYDOWN events. Otherwise we have a high chance that on
	// Windows the TEXTINPUT event is not in the event queue at this point.
	// In this case we will get two events with ascii values due to mapKey
	// and dispatchSDLEvent. This results in nasty double input of characters
	// in the GUI.
	//
	// FIXME: This is all a bit fragile because in mapKey we derive the ascii
	// value from the key code if no unicode value is given. This is legacy
	// behavior and should be removed anyway. If that is removed, we might not
	// even need to do this peeking here but instead can rely on the
	// SDL_TEXTINPUT case in dispatchSDLEvent to introduce keydown/keyup with
	// proper ASCII values (but with KEYCODE_INVALID as keycode).
	SDL_PumpEvents();

	// In SDL2, the unicode field has been removed from the keysym struct.
	// Instead a SDL_TEXTINPUT event is generated on key combinations that
	// generates unicode.
	// Here we peek into the event queue for the event to see if it exists.
	int n = SDL_PeepEvents(events, 2, SDL_PEEKEVENT, SDL_KEYDOWN, SDL_TEXTINPUT);
	// Make sure that the TEXTINPUT event belongs to this KEYDOWN
	// event and not another pending one.
	if ((n > 0 && events[0].type == SDL_TEXTINPUT)
	    || (n > 1 && events[0].type != SDL_KEYDOWN && events[1].type == SDL_TEXTINPUT)) {
		// Remove the text input event we associate with the key press. This
		// makes sure we never get any SDL_TEXTINPUT events which do "belong"
		// to SDL_KEYDOWN events.
		n = SDL_PeepEvents(events, 1, SDL_GETEVENT, SDL_TEXTINPUT, SDL_TEXTINPUT);
		// This is basically a paranoia safety check because we know there
		// must be a text input event in the queue.
		if (n > 0) {
			return convUTF8ToUTF32(events[0].text.text);
		} else {
			return 0;
		}
	} else {
		return 0;
	}
#else
	return keySym.unicode;
#endif
}
Пример #3
0
bool SdlEventSource::dispatchSDLEvent(SDL_Event &ev, Common::Event &event) {
	switch (ev.type) {
	case SDL_KEYDOWN:
		return handleKeyDown(ev, event);
	case SDL_KEYUP:
		return handleKeyUp(ev, event);
	case SDL_MOUSEMOTION:
		return handleMouseMotion(ev, event);
	case SDL_MOUSEBUTTONDOWN:
		return handleMouseButtonDown(ev, event);
	case SDL_MOUSEBUTTONUP:
		return handleMouseButtonUp(ev, event);
	case SDL_JOYBUTTONDOWN:
		return handleJoyButtonDown(ev, event);
	case SDL_JOYBUTTONUP:
		return handleJoyButtonUp(ev, event);
	case SDL_JOYAXISMOTION:
		return handleJoyAxisMotion(ev, event);

#if SDL_VERSION_ATLEAST(2, 0, 0)
	case SDL_MOUSEWHEEL: {
		Sint32 yDir = ev.wheel.y;
		// HACK: It seems we want the mouse coordinates supplied
		// with a mouse wheel event. However, SDL2 does not supply
		// these, thus we use whatever we got last time. It seems
		// these are always stored in _km.x, _km.y.
		if (!processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER)) {
			return false;
		}
		if (yDir < 0) {
			event.type = Common::EVENT_WHEELDOWN;
			return true;
		} else if (yDir > 0) {
			event.type = Common::EVENT_WHEELUP;
			return true;
		} else {
			return false;
		}
		}

	case SDL_TEXTINPUT: {
		// When we get a TEXTINPUT event it means we got some user input for
		// which no KEYDOWN exists. SDL 1.2 introduces a "fake" key down+up
		// in such cases. We will do the same to mimic it's behavior.
		event.type = Common::EVENT_KEYDOWN;

		event.kbd = Common::KeyState(Common::KEYCODE_INVALID, convUTF8ToUTF32(ev.text.text), 0);

		SDLModToOSystemKeyFlags(SDL_GetModState(), event);
		// Set the scroll lock sticky flag
		if (_scrollLock)
			event.kbd.flags |= Common::KBD_SCRL;

		// Fake a key up when we have a proper ascii value.
		_queuedFakeKeyUp = (event.kbd.ascii != 0);
		_fakeKeyUp = event;
		_fakeKeyUp.type = Common::EVENT_KEYUP;

		return _queuedFakeKeyUp;
		}

	case SDL_WINDOWEVENT:
		switch (ev.window.event) {
		case SDL_WINDOWEVENT_EXPOSED:
			if (_graphicsManager)
				_graphicsManager->notifyVideoExpose();
			return false;

		// SDL2 documentation indicate that SDL_WINDOWEVENT_SIZE_CHANGED is sent either as a result
		// of the size being changed by an external event (for example the user resizing the window
		// or going fullscreen) or a call to the SDL API (for example SDL_SetWindowSize). On the
		// other hand SDL_WINDOWEVENT_RESIZED is only sent for resize resulting from an external event,
		// and is always preceded by a SDL_WINDOWEVENT_SIZE_CHANGED event.
		// We need to handle the programmatic resize as well so that the graphics manager always know
		// the current size. See comments in SdlWindow::createOrUpdateWindow for details of one case
		// where we need to call SDL_SetWindowSize and we need the resulting event to be processed.
		// However if the documentation is correct we can ignore SDL_WINDOWEVENT_RESIZED since when we
		// get one we should always get a SDL_WINDOWEVENT_SIZE_CHANGED as well.
		case SDL_WINDOWEVENT_SIZE_CHANGED:
		//case SDL_WINDOWEVENT_RESIZED:
			return handleResizeEvent(event, ev.window.data1, ev.window.data2);

		default:
			return false;
		}
#else
	case SDL_VIDEOEXPOSE:
		if (_graphicsManager)
			_graphicsManager->notifyVideoExpose();
		return false;

	case SDL_VIDEORESIZE:
		return handleResizeEvent(event, ev.resize.w, ev.resize.h);
#endif

	case SDL_QUIT:
		event.type = Common::EVENT_QUIT;
		return true;

	}

	return false;
}
Пример #4
0
bool SdlEventSource::dispatchSDLEvent(SDL_Event &ev, Common::Event &event) {
	switch (ev.type) {
	case SDL_KEYDOWN:
		return handleKeyDown(ev, event);
	case SDL_KEYUP:
		return handleKeyUp(ev, event);
	case SDL_MOUSEMOTION:
		return handleMouseMotion(ev, event);
	case SDL_MOUSEBUTTONDOWN:
		return handleMouseButtonDown(ev, event);
	case SDL_MOUSEBUTTONUP:
		return handleMouseButtonUp(ev, event);
	case SDL_JOYBUTTONDOWN:
		return handleJoyButtonDown(ev, event);
	case SDL_JOYBUTTONUP:
		return handleJoyButtonUp(ev, event);
	case SDL_JOYAXISMOTION:
		return handleJoyAxisMotion(ev, event);

#if SDL_VERSION_ATLEAST(2, 0, 0)
	case SDL_MOUSEWHEEL: {
		Sint32 yDir = ev.wheel.y;
#if SDL_VERSION_ATLEAST(2, 0, 4)
		if (ev.wheel.direction == SDL_MOUSEWHEEL_FLIPPED) {
			yDir *= -1;
		}
#endif
		// HACK: It seems we want the mouse coordinates supplied
		// with a mouse wheel event. However, SDL2 does not supply
		// these, thus we use whatever we got last time. It seems
		// these are always stored in _km.x, _km.y.
		processMouseEvent(event, _km.x, _km.y);
		if (yDir < 0) {
			event.type = Common::EVENT_WHEELDOWN;
			return true;
		} else if (yDir > 0) {
			event.type = Common::EVENT_WHEELUP;
			return true;
		} else {
			return false;
		}
		}

	case SDL_TEXTINPUT: {
		// When we get a TEXTINPUT event it means we got some user input for
		// which no KEYDOWN exists. SDL 1.2 introduces a "fake" key down+up
		// in such cases. We will do the same to mimic it's behavior.
		event.type = Common::EVENT_KEYDOWN;

		event.kbd = Common::KeyState(Common::KEYCODE_INVALID, convUTF8ToUTF32(ev.text.text), 0);

		SDLModToOSystemKeyFlags(SDL_GetModState(), event);
		// Set the scroll lock sticky flag
		if (_scrollLock)
			event.kbd.flags |= Common::KBD_SCRL;

		// Fake a key up when we have a proper ascii value.
		_queuedFakeKeyUp = (event.kbd.ascii != 0);
		_fakeKeyUp = event;
		_fakeKeyUp.type = Common::EVENT_KEYUP;

		return _queuedFakeKeyUp;
		}

	case SDL_WINDOWEVENT:
		switch (ev.window.event) {
		case SDL_WINDOWEVENT_EXPOSED:
			if (_graphicsManager)
				_graphicsManager->notifyVideoExpose();
			return false;

		case SDL_WINDOWEVENT_RESIZED:
			return handleResizeEvent(event, ev.window.data1, ev.window.data2);

		default:
			return false;
		}
#else
	case SDL_VIDEOEXPOSE:
		if (_graphicsManager)
			_graphicsManager->notifyVideoExpose();
		return false;

	case SDL_VIDEORESIZE:
		return handleResizeEvent(event, ev.resize.w, ev.resize.h);
#endif

	case SDL_QUIT:
		event.type = Common::EVENT_QUIT;
		return true;

	}

	return false;
}