diff options
author | Paul Gilbert | 2015-05-31 14:45:10 -0400 |
---|---|---|
committer | Paul Gilbert | 2015-05-31 14:45:10 -0400 |
commit | e5296ebf8dd09f603499b1894a33865ec71bb28f (patch) | |
tree | d7de032efd54dfdb3159cbc778a0c9ce8cd8aa91 /backends/events | |
parent | 673537bad93f0b440172a0cc263ebf19cc95ffc0 (diff) | |
parent | 141ff4d08dc24b6bb17098bd71801e2a58e6a38f (diff) | |
download | scummvm-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.cpp | 34 | ||||
-rw-r--r-- | backends/events/sdl/sdl-events.cpp | 210 | ||||
-rw-r--r-- | backends/events/sdl/sdl-events.h | 31 | ||||
-rw-r--r-- | backends/events/symbiansdl/symbiansdl-events.cpp | 4 |
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; |