aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backends/events/default/default-events.cpp26
-rw-r--r--backends/events/default/default-events.h1
-rw-r--r--backends/events/sdl/sdl-events.cpp14
-rw-r--r--backends/events/sdl/sdl-events.h18
-rw-r--r--backends/graphics/sdl/sdl-graphics.cpp7
-rw-r--r--backends/graphics/sdl/sdl-graphics.h5
-rw-r--r--backends/modular-backend.cpp1
-rw-r--r--backends/platform/sdl/sdl-window.cpp6
-rw-r--r--backends/platform/sdl/sdl-window.h4
-rw-r--r--common/events.h5
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;