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