aboutsummaryrefslogtreecommitdiff
path: root/backends/events
diff options
context:
space:
mode:
authorPaul Gilbert2015-05-31 14:45:10 -0400
committerPaul Gilbert2015-05-31 14:45:10 -0400
commite5296ebf8dd09f603499b1894a33865ec71bb28f (patch)
treed7de032efd54dfdb3159cbc778a0c9ce8cd8aa91 /backends/events
parent673537bad93f0b440172a0cc263ebf19cc95ffc0 (diff)
parent141ff4d08dc24b6bb17098bd71801e2a58e6a38f (diff)
downloadscummvm-rg350-e5296ebf8dd09f603499b1894a33865ec71bb28f.tar.gz
scummvm-rg350-e5296ebf8dd09f603499b1894a33865ec71bb28f.tar.bz2
scummvm-rg350-e5296ebf8dd09f603499b1894a33865ec71bb28f.zip
Merge branch 'master' into phantom
Diffstat (limited to 'backends/events')
-rw-r--r--backends/events/dinguxsdl/dinguxsdl-events.cpp34
-rw-r--r--backends/events/sdl/sdl-events.cpp210
-rw-r--r--backends/events/sdl/sdl-events.h31
-rw-r--r--backends/events/symbiansdl/symbiansdl-events.cpp4
4 files changed, 236 insertions, 43 deletions
diff --git a/backends/events/dinguxsdl/dinguxsdl-events.cpp b/backends/events/dinguxsdl/dinguxsdl-events.cpp
index 6f9f2a7748..cc15f2666c 100644
--- a/backends/events/dinguxsdl/dinguxsdl-events.cpp
+++ b/backends/events/dinguxsdl/dinguxsdl-events.cpp
@@ -26,18 +26,48 @@
#include "backends/events/dinguxsdl/dinguxsdl-events.h"
+#ifndef GCW0
#define PAD_UP SDLK_UP
#define PAD_DOWN SDLK_DOWN
#define PAD_LEFT SDLK_LEFT
#define PAD_RIGHT SDLK_RIGHT
#define BUT_A SDLK_LCTRL
#define BUT_B SDLK_LALT
-#define BUT_X SDLK_SPACE
-#define BUT_Y SDLK_LSHIFT
+#define BUT_X SDLK_SPACE // BUT_Y in GCW0
+#define BUT_Y SDLK_LSHIFT // BUT_X in GCW0
#define BUT_SELECT SDLK_ESCAPE
#define BUT_START SDLK_RETURN
#define TRIG_L SDLK_TAB
#define TRIG_R SDLK_BACKSPACE
+#else // GCW0
+
+/******
+ * GCW0 keymap
+ * Dingoo button
+ * A -> Left Button BUT_Y
+ * B -> right button BUT_B
+ * X -> ' ' BUT_A '0'
+ * Y -> '.' BUT_X
+ * Select -> ESC TRIG_R
+ * Start -> F5 TRIG_L
+ * L -> Shift BUT_START
+ * R -> VK BUT_SELECT
+ */
+
+#define PAD_UP SDLK_UP
+#define PAD_DOWN SDLK_DOWN
+#define PAD_LEFT SDLK_LEFT
+#define PAD_RIGHT SDLK_RIGHT
+#define BUT_A SDLK_LSHIFT
+#define BUT_B SDLK_LALT
+#define BUT_X SDLK_SPACE
+#define BUT_Y SDLK_LCTRL
+#define BUT_SELECT SDLK_BACKSPACE
+#define BUT_START SDLK_TAB
+#define TRIG_L SDLK_RETURN
+#define TRIG_R SDLK_ESCAPE
+
+#endif
bool DINGUXSdlEventSource::remapKey(SDL_Event &ev, Common::Event &event) {
if (ev.key.keysym.sym == PAD_UP) {
diff --git a/backends/events/sdl/sdl-events.cpp b/backends/events/sdl/sdl-events.cpp
index 2480e7c370..1e5119dbec 100644
--- a/backends/events/sdl/sdl-events.cpp
+++ b/backends/events/sdl/sdl-events.cpp
@@ -49,22 +49,55 @@
#define JOY_BUT_SPACE 4
#define JOY_BUT_F5 5
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+static uint32 convUTF8ToUTF32(const char *src) {
+ uint32 utf32 = 0;
+
+ char *dst = SDL_iconv_string(
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ "UTF-32BE",
+#else
+ "UTF-32LE",
+#endif
+ "UTF-8", src, SDL_strlen(src) + 1);
+
+ if (dst) {
+ utf32 = *((uint32 *)dst);
+ SDL_free(dst);
+ }
+
+ return utf32;
+}
+#endif
+
SdlEventSource::SdlEventSource()
- : EventSource(), _scrollLock(false), _joystick(0), _lastScreenID(0), _graphicsManager(0) {
+ : EventSource(), _scrollLock(false), _joystick(0), _lastScreenID(0), _graphicsManager(0)
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ , _queuedFakeKeyUp(false), _fakeKeyUp()
+#endif
+ {
// Reset mouse state
memset(&_km, 0, sizeof(_km));
int joystick_num = ConfMan.getInt("joystick_num");
- if (joystick_num > -1) {
+ if (joystick_num >= 0) {
// Initialize SDL joystick subsystem
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1) {
error("Could not initialize SDL: %s", SDL_GetError());
}
// Enable joystick
- if (SDL_NumJoysticks() > 0) {
- debug("Using joystick: %s", SDL_JoystickName(0));
+ if (SDL_NumJoysticks() > joystick_num) {
_joystick = SDL_JoystickOpen(joystick_num);
+ debug("Using joystick: %s",
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ SDL_JoystickName(_joystick)
+#else
+ SDL_JoystickName(joystick_num)
+#endif
+ );
+ } else {
+ warning("Invalid joystick: %d", joystick_num);
}
}
}
@@ -74,21 +107,24 @@ SdlEventSource::~SdlEventSource() {
SDL_JoystickClose(_joystick);
}
-int SdlEventSource::mapKey(SDLKey key, SDLMod mod, Uint16 unicode) {
- if (key >= SDLK_F1 && key <= SDLK_F9) {
+int SdlEventSource::mapKey(SDLKey sdlKey, SDLMod mod, Uint16 unicode) {
+ Common::KeyCode key = SDLToOSystemKeycode(sdlKey);
+
+ if (key >= Common::KEYCODE_F1 && key <= Common::KEYCODE_F9) {
return key - SDLK_F1 + Common::ASCII_F1;
- } else if (key >= SDLK_KP0 && key <= SDLK_KP9) {
- return key - SDLK_KP0 + '0';
- } else if (key >= SDLK_UP && key <= SDLK_PAGEDOWN) {
+ } else if (key >= Common::KEYCODE_KP0 && key <= Common::KEYCODE_KP9) {
+ return key - Common::KEYCODE_KP0 + '0';
+ } else if (key >= Common::KEYCODE_UP && key <= Common::KEYCODE_PAGEDOWN) {
return key;
} else if (unicode) {
return unicode;
} else if (key >= 'a' && key <= 'z' && (mod & KMOD_SHIFT)) {
return key & ~0x20;
- } else if (key >= SDLK_NUMLOCK && key <= SDLK_EURO) {
+ } else if (key >= Common::KEYCODE_NUMLOCK && key <= Common::KEYCODE_EURO) {
return 0;
+ } else {
+ return key;
}
- return key;
}
void SdlEventSource::processMouseEvent(Common::Event &event, int x, int y) {
@@ -171,7 +207,9 @@ void SdlEventSource::handleKbdMouse() {
_km.y_down_count = 1;
}
- SDL_WarpMouse((Uint16)_km.x, (Uint16)_km.y);
+ if (_graphicsManager) {
+ _graphicsManager->getWindow()->warpMouseInWindow((Uint16)_km.x, (Uint16)_km.y);
+ }
}
}
}
@@ -338,7 +376,9 @@ Common::KeyCode SdlEventSource::SDLToOSystemKeycode(const SDLKey key) {
case SDLK_HELP: return Common::KEYCODE_HELP;
case SDLK_PRINT: return Common::KEYCODE_PRINT;
case SDLK_SYSREQ: return Common::KEYCODE_SYSREQ;
+#if !SDL_VERSION_ATLEAST(2, 0, 0)
case SDLK_BREAK: return Common::KEYCODE_BREAK;
+#endif
case SDLK_MENU: return Common::KEYCODE_MENU;
case SDLK_POWER: return Common::KEYCODE_POWER;
case SDLK_UNDO: return Common::KEYCODE_UNDO;
@@ -349,6 +389,16 @@ Common::KeyCode SdlEventSource::SDLToOSystemKeycode(const SDLKey key) {
bool SdlEventSource::pollEvent(Common::Event &event) {
handleKbdMouse();
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ // In case we still need to send a key up event for a key down from a
+ // TEXTINPUT event we do this immediately.
+ if (_queuedFakeKeyUp) {
+ event = _fakeKeyUp;
+ _queuedFakeKeyUp = false;
+ return true;
+ }
+#endif
+
// If the screen changed, send an Common::EVENT_SCREEN_CHANGED
int screenID = ((OSystem_SDL *)g_system)->getGraphicsManager()->getScreenChangeID();
if (screenID != _lastScreenID) {
@@ -385,24 +435,73 @@ bool SdlEventSource::dispatchSDLEvent(SDL_Event &ev, Common::Event &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:
- if (_graphicsManager) {
- _graphicsManager->notifyResize(ev.resize.w, ev.resize.h);
-
- // If the screen changed, send an Common::EVENT_SCREEN_CHANGED
- int screenID = ((OSystem_SDL *)g_system)->getGraphicsManager()->getScreenChangeID();
- if (screenID != _lastScreenID) {
- _lastScreenID = screenID;
- event.type = Common::EVENT_SCREEN_CHANGED;
- return true;
- }
- }
- return false;
+ return handleResizeEvent(event, ev.resize.w, ev.resize.h);
+#endif
case SDL_QUIT:
event.type = Common::EVENT_QUIT;
@@ -427,7 +526,9 @@ bool SdlEventSource::handleKeyDown(SDL_Event &ev, Common::Event &event) {
// Ctrl-m toggles mouse capture
if (event.kbd.hasFlags(Common::KBD_CTRL) && ev.key.keysym.sym == 'm') {
- toggleMouseGrab();
+ if (_graphicsManager) {
+ _graphicsManager->getWindow()->toggleMouseGrab();
+ }
return false;
}
@@ -470,7 +571,7 @@ bool SdlEventSource::handleKeyDown(SDL_Event &ev, Common::Event &event) {
event.type = Common::EVENT_KEYDOWN;
event.kbd.keycode = SDLToOSystemKeycode(ev.key.keysym.sym);
- event.kbd.ascii = mapKey(ev.key.keysym.sym, (SDLMod)ev.key.keysym.mod, (Uint16)ev.key.keysym.unicode);
+ event.kbd.ascii = mapKey(ev.key.keysym.sym, (SDLMod)ev.key.keysym.mod, obtainUnicode(ev.key.keysym));
return true;
}
@@ -514,7 +615,7 @@ bool SdlEventSource::handleKeyUp(SDL_Event &ev, Common::Event &event) {
event.type = Common::EVENT_KEYUP;
event.kbd.keycode = SDLToOSystemKeycode(ev.key.keysym.sym);
- event.kbd.ascii = mapKey(ev.key.keysym.sym, (SDLMod)ev.key.keysym.mod, (Uint16)ev.key.keysym.unicode);
+ event.kbd.ascii = mapKey(ev.key.keysym.sym, (SDLMod)ev.key.keysym.mod, 0);
// Ctrl-Alt-<key> will change the GFX mode
SDLModToOSystemKeyFlags(mod, event);
@@ -750,13 +851,6 @@ bool SdlEventSource::remapKey(SDL_Event &ev, Common::Event &event) {
return false;
}
-void SdlEventSource::toggleMouseGrab() {
- if (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_OFF)
- SDL_WM_GrabInput(SDL_GRAB_ON);
- else
- SDL_WM_GrabInput(SDL_GRAB_OFF);
-}
-
void SdlEventSource::resetKeyboadEmulation(int16 x_max, int16 y_max) {
_km.x_max = x_max;
_km.y_max = y_max;
@@ -764,4 +858,52 @@ void SdlEventSource::resetKeyboadEmulation(int16 x_max, int16 y_max) {
_km.last_time = 0;
}
+bool SdlEventSource::handleResizeEvent(Common::Event &event, int w, int h) {
+ if (_graphicsManager) {
+ _graphicsManager->notifyResize(w, h);
+
+ // If the screen changed, send an Common::EVENT_SCREEN_CHANGED
+ int screenID = ((OSystem_SDL *)g_system)->getGraphicsManager()->getScreenChangeID();
+ if (screenID != _lastScreenID) {
+ _lastScreenID = screenID;
+ event.type = Common::EVENT_SCREEN_CHANGED;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+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
+}
+
#endif
diff --git a/backends/events/sdl/sdl-events.h b/backends/events/sdl/sdl-events.h
index a1b6d5ec3c..caa60c1354 100644
--- a/backends/events/sdl/sdl-events.h
+++ b/backends/events/sdl/sdl-events.h
@@ -49,11 +49,6 @@ public:
*/
virtual void resetKeyboadEmulation(int16 x_max, int16 y_max);
- /**
- * Toggles mouse input grab
- */
- virtual void toggleMouseGrab();
-
protected:
/** @name Keyboard mouse emulation
* Disabled by fingolfin 2004-12-18.
@@ -130,7 +125,7 @@ protected:
/**
* Maps the ASCII value of key
*/
- virtual int mapKey(SDLKey key, SDLMod mod, Uint16 unicode);
+ int mapKey(SDLKey key, SDLMod mod, Uint16 unicode);
/**
* Configures the key modifiers flags status
@@ -141,6 +136,30 @@ protected:
* Translates SDL key codes to OSystem key codes
*/
Common::KeyCode SDLToOSystemKeycode(const SDLKey key);
+
+ /**
+ * Notify graphics manager of a resize request.
+ */
+ bool handleResizeEvent(Common::Event &event, int w, int h);
+
+ /**
+ * Extracts unicode information for the specific key sym.
+ * May only be used for key down events.
+ */
+ uint32 obtainUnicode(const SDL_keysym keySym);
+
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ /**
+ * Whether _fakeKeyUp contains an event we need to send.
+ */
+ bool _queuedFakeKeyUp;
+
+ /**
+ * A fake key up event when we receive a TEXTINPUT without any previous
+ * KEYDOWN event.
+ */
+ Common::Event _fakeKeyUp;
+#endif
};
#endif
diff --git a/backends/events/symbiansdl/symbiansdl-events.cpp b/backends/events/symbiansdl/symbiansdl-events.cpp
index 36018f1024..b0d2c25302 100644
--- a/backends/events/symbiansdl/symbiansdl-events.cpp
+++ b/backends/events/symbiansdl/symbiansdl-events.cpp
@@ -133,7 +133,9 @@ bool SymbianSdlEventSource::remapKey(SDL_Event &ev, Common::Event &event) {
_currentZone = 0;
event.type = Common::EVENT_MOUSEMOVE;
processMouseEvent(event, _mouseXZone[_currentZone], _mouseYZone[_currentZone]);
- SDL_WarpMouse(event.mouse.x, event.mouse.y);
+ if (_graphicsManager) {
+ _graphicsManager->getWindow()->warpMouseInWindow(event.mouse.x, event.mouse.y);
+ }
}
return true;