diff options
-rw-r--r-- | backends/events/default/default-events.cpp | 26 | ||||
-rw-r--r-- | backends/events/default/default-events.h | 1 | ||||
-rw-r--r-- | backends/events/sdl/sdl-events.cpp | 14 | ||||
-rw-r--r-- | backends/events/sdl/sdl-events.h | 18 | ||||
-rw-r--r-- | backends/graphics/sdl/sdl-graphics.cpp | 7 | ||||
-rw-r--r-- | backends/graphics/sdl/sdl-graphics.h | 5 | ||||
-rw-r--r-- | backends/modular-backend.cpp | 1 | ||||
-rw-r--r-- | backends/platform/sdl/sdl-window.cpp | 6 | ||||
-rw-r--r-- | backends/platform/sdl/sdl-window.h | 4 | ||||
-rw-r--r-- | common/events.h | 5 |
10 files changed, 80 insertions, 7 deletions
diff --git a/backends/events/default/default-events.cpp b/backends/events/default/default-events.cpp index c7c39da069..667914b023 100644 --- a/backends/events/default/default-events.cpp +++ b/backends/events/default/default-events.cpp @@ -254,4 +254,30 @@ void DefaultEventManager::pushEvent(const Common::Event &event) { _artificialEventSource.addEvent(event); } +void DefaultEventManager::purgeMouseEvents() { + _dispatcher.dispatch(); + + Common::Queue<Common::Event> filteredQueue; + while (!_eventQueue.empty()) { + Common::Event event = _eventQueue.pop(); + switch (event.type) { + case Common::EVENT_MOUSEMOVE: + case Common::EVENT_LBUTTONDOWN: + case Common::EVENT_LBUTTONUP: + case Common::EVENT_RBUTTONDOWN: + case Common::EVENT_RBUTTONUP: + case Common::EVENT_WHEELUP: + case Common::EVENT_WHEELDOWN: + case Common::EVENT_MBUTTONDOWN: + case Common::EVENT_MBUTTONUP: + // do nothing + break; + default: + filteredQueue.push(event); + break; + } + } + _eventQueue = filteredQueue; +} + #endif // !defined(DISABLE_DEFAULT_EVENTMANAGER) diff --git a/backends/events/default/default-events.h b/backends/events/default/default-events.h index f378fb9ff0..38406c25aa 100644 --- a/backends/events/default/default-events.h +++ b/backends/events/default/default-events.h @@ -80,6 +80,7 @@ public: virtual void init(); virtual bool pollEvent(Common::Event &event); virtual void pushEvent(const Common::Event &event); + virtual void purgeMouseEvents() override; virtual Common::Point getMousePos() const { return _mousePos; } virtual int getButtonState() const { return _buttonState; } diff --git a/backends/events/sdl/sdl-events.cpp b/backends/events/sdl/sdl-events.cpp index 6f34420674..91ca0f5df6 100644 --- a/backends/events/sdl/sdl-events.cpp +++ b/backends/events/sdl/sdl-events.cpp @@ -75,7 +75,7 @@ static uint32 convUTF8ToUTF32(const char *src) { #endif SdlEventSource::SdlEventSource() - : EventSource(), _scrollLock(false), _joystick(0), _lastScreenID(0), _graphicsManager(0) + : EventSource(), _scrollLock(false), _joystick(0), _lastScreenID(0), _graphicsManager(0), _queuedFakeMouseMove(false) #if SDL_VERSION_ATLEAST(2, 0, 0) , _queuedFakeKeyUp(false), _fakeKeyUp() #endif @@ -508,6 +508,12 @@ bool SdlEventSource::pollEvent(Common::Event &event) { return true; } + if (_queuedFakeMouseMove) { + event = _fakeMouseMove; + _queuedFakeMouseMove = false; + return true; + } + SDL_Event ev; while (SDL_PollEvent(&ev)) { preprocessEvents(&ev); @@ -1003,6 +1009,12 @@ void SdlEventSource::resetKeyboardEmulation(int16 x_max, int16 y_max) { _km.joy_y = 0; } +void SdlEventSource::fakeWarpMouse(const int x, const int y) { + _queuedFakeMouseMove = true; + _fakeMouseMove.type = Common::EVENT_MOUSEMOVE; + _fakeMouseMove.mouse = Common::Point(x, y); +} + bool SdlEventSource::handleResizeEvent(Common::Event &event, int w, int h) { if (_graphicsManager) { _graphicsManager->notifyResize(w, h); diff --git a/backends/events/sdl/sdl-events.h b/backends/events/sdl/sdl-events.h index 1d701f5ecf..5fd3cb7ea5 100644 --- a/backends/events/sdl/sdl-events.h +++ b/backends/events/sdl/sdl-events.h @@ -51,6 +51,12 @@ public: */ virtual void resetKeyboardEmulation(int16 x_max, int16 y_max); + /** + * Emulates a mouse movement that would normally be caused by a mouse warp + * of the system mouse. + */ + void fakeWarpMouse(const int x, const int y); + protected: /** @name Keyboard mouse emulation * Disabled by fingolfin 2004-12-18. @@ -156,6 +162,18 @@ protected: */ SDLKey obtainKeycode(const SDL_keysym keySym); + /** + * Whether _fakeMouseMove contains an event we need to send. + */ + bool _queuedFakeMouseMove; + + /** + * A fake mouse motion event sent when the graphics manager is told to warp + * the mouse but the system mouse is unable to be warped (e.g. because the + * window is not focused). + */ + Common::Event _fakeMouseMove; + #if SDL_VERSION_ATLEAST(2, 0, 0) /** * Whether _fakeKeyUp contains an event we need to send. diff --git a/backends/graphics/sdl/sdl-graphics.cpp b/backends/graphics/sdl/sdl-graphics.cpp index e6699df1cd..64ee9f7aa1 100644 --- a/backends/graphics/sdl/sdl-graphics.cpp +++ b/backends/graphics/sdl/sdl-graphics.cpp @@ -212,6 +212,13 @@ bool SdlGraphicsManager::notifyMousePosition(Common::Point &mouse) { return valid; } +void SdlGraphicsManager::setSystemMousePosition(const int x, const int y) { + assert(_window); + if (!_window->warpMouseInWindow(x, y)) { + _eventSource->fakeWarpMouse(x, y); + } +} + void SdlGraphicsManager::handleResizeImpl(const int width, const int height) { _eventSource->resetKeyboardEmulation(width - 1, height - 1); _forceRedraw = true; diff --git a/backends/graphics/sdl/sdl-graphics.h b/backends/graphics/sdl/sdl-graphics.h index 993a1c3db6..526306270b 100644 --- a/backends/graphics/sdl/sdl-graphics.h +++ b/backends/graphics/sdl/sdl-graphics.h @@ -150,10 +150,7 @@ protected: #endif } - virtual void setSystemMousePosition(const int x, const int y) override { - assert(_window); - _window->warpMouseInWindow(x, y); - } + virtual void setSystemMousePosition(const int x, const int y) override; virtual void handleResizeImpl(const int width, const int height) override; diff --git a/backends/modular-backend.cpp b/backends/modular-backend.cpp index c9adbd3100..944ddd5a47 100644 --- a/backends/modular-backend.cpp +++ b/backends/modular-backend.cpp @@ -217,6 +217,7 @@ bool ModularBackend::showMouse(bool visible) { } void ModularBackend::warpMouse(int x, int y) { + _eventManager->purgeMouseEvents(); _graphicsManager->warpMouse(x, y); } diff --git a/backends/platform/sdl/sdl-window.cpp b/backends/platform/sdl/sdl-window.cpp index a550fbbd40..fe27d84de2 100644 --- a/backends/platform/sdl/sdl-window.cpp +++ b/backends/platform/sdl/sdl-window.cpp @@ -155,16 +155,20 @@ bool SdlWindow::hasMouseFocus() const { #endif } -void SdlWindow::warpMouseInWindow(int x, int y) { +bool SdlWindow::warpMouseInWindow(int x, int y) { if (hasMouseFocus()) { #if SDL_VERSION_ATLEAST(2, 0, 0) if (_window) { SDL_WarpMouseInWindow(_window, x, y); + return true; } #else SDL_WarpMouse(x, y); + return true; #endif } + + return false; } void SdlWindow::iconifyWindow() { diff --git a/backends/platform/sdl/sdl-window.h b/backends/platform/sdl/sdl-window.h index 4f6d924411..e1a3499d19 100644 --- a/backends/platform/sdl/sdl-window.h +++ b/backends/platform/sdl/sdl-window.h @@ -58,8 +58,10 @@ public: /** * Warp the mouse to the specified position in window coordinates. The mouse * will only be warped if the window is focused in the window manager. + * + * @returns true if the system cursor was warped. */ - void warpMouseInWindow(int x, int y); + bool warpMouseInWindow(int x, int y); /** * Iconifies the window. diff --git a/common/events.h b/common/events.h index 21a65a642b..e5bb8cab50 100644 --- a/common/events.h +++ b/common/events.h @@ -395,6 +395,11 @@ public: */ virtual void pushEvent(const Event &event) = 0; + /** + * Purges all unprocessed mouse events already in the event queue. + */ + virtual void purgeMouseEvents() = 0; + /** Return the current mouse position */ virtual Point getMousePos() const = 0; |