[Scummvm-git-logs] scummvm master -> 7d8d2f80fbc9cf96b3bd03b85a9722b576d23adc

csnover csnover at users.noreply.github.com
Sun Oct 15 20:27:17 CEST 2017


This automated email contains information about 14 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
b53020f704 BACKENDS: Fix some comment typos
969dd565a1 SDL: Allow window resize with non-OpenGL SDL2 backend
0ad03e492a SDL: Accept signed values for mouse cursor warping
de2bbe3b97 BACKENDS: Refactor OpenGL & SDL graphics backends
da0a8db704 BACKENDS: Also hide mouse cursor outside game area when an engine has hidden the cursor
5d8cf6ba42 BACKENDS: Fix GraphicsManager handling of empty cursors
9e9972a55b GRAPHICS: Send blank cursors to graphics backends
319ab07fe0 SDL: Minor code cleanup to declare variables at point of first use
cd538ffffa BACKENDS: Do not send mouse events to games occurring outside the game draw rect
d1b77d4b68 BACKENDS: Fix missing mouse events when system cursor cannot be moved
8b112f57a9 SDL: Support 32bpp cursor rendering
f6ab0e5c10 SDL: Allow window size to be reset whenever launcher is visible
4757c24c68 BACKENDS: Fix up graphics manager ports with const & override where appropriate
7d8d2f80fb Merge branch 'graphics-backends-improvements'


Commit: b53020f70457c059f5028073df493cfc25a5876a
    https://github.com/scummvm/scummvm/commit/b53020f70457c059f5028073df493cfc25a5876a
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-10-15T13:24:20-05:00

Commit Message:
BACKENDS: Fix some comment typos

Changed paths:
    backends/events/sdl/sdl-events.cpp
    backends/graphics/opengl/opengl-graphics.h
    backends/graphics/openglsdl/openglsdl-graphics.cpp
    backends/graphics/sdl/sdl-graphics.h
    backends/graphics/surfacesdl/surfacesdl-graphics.cpp


diff --git a/backends/events/sdl/sdl-events.cpp b/backends/events/sdl/sdl-events.cpp
index fb5a4c9..2c6fe85 100644
--- a/backends/events/sdl/sdl-events.cpp
+++ b/backends/events/sdl/sdl-events.cpp
@@ -158,7 +158,7 @@ int SdlEventSource::mapKey(SDLKey sdlKey, SDLMod mod, Uint16 unicode) {
 	} else if (key >= Common::KEYCODE_UP && key <= Common::KEYCODE_PAGEDOWN) {
 		return key;
 	} else if (unicode) {
-		// Return unicode in case it's stil set and wasn't filtered.
+		// Return unicode in case it's still set and wasn't filtered.
 		return unicode;
 	} else if (key >= 'a' && key <= 'z' && (mod & KMOD_SHIFT)) {
 		return key & ~0x20;
@@ -968,9 +968,8 @@ bool SdlEventSource::remapKey(SDL_Event &ev, Common::Event &event) {
 		event.kbd.keycode = Common::KEYCODE_F5;
 		event.kbd.ascii = mapKey(SDLK_F5, ev.key.keysym.mod, 0);
 	}
-	// Nap center (space) to tab (default action )
+	// Map center (space) to tab (default action)
 	// I wanted to map the calendar button but the calendar comes up
-	//
 	else if (ev.key.keysym.sym == SDLK_SPACE) {
 		event.type = Common::EVENT_KEYDOWN;
 		event.kbd.keycode = Common::KEYCODE_TAB;
diff --git a/backends/graphics/opengl/opengl-graphics.h b/backends/graphics/opengl/opengl-graphics.h
index e02137b..cbf68d9 100644
--- a/backends/graphics/opengl/opengl-graphics.h
+++ b/backends/graphics/opengl/opengl-graphics.h
@@ -241,7 +241,7 @@ private:
 	};
 
 	/**
-	 * The currently setup video state.
+	 * The currently set up video state.
 	 */
 	VideoState _currentState;
 
@@ -444,7 +444,7 @@ private:
 	Surface *_cursor;
 
 	/**
-	 * X coordinate of the cursor in phyiscal coordinates.
+	 * X coordinate of the cursor in physical coordinates.
 	 */
 	int _cursorX;
 
diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp
index 73fc87a..46940d7 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.cpp
+++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp
@@ -46,7 +46,7 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(uint desktopWidth, uint deskt
 	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
 	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
 
-	// Setup proper SDL OpenGL context creation.
+	// Set up proper SDL OpenGL context creation.
 #if SDL_VERSION_ATLEAST(2, 0, 0)
 	OpenGL::ContextType glContextType;
 
diff --git a/backends/graphics/sdl/sdl-graphics.h b/backends/graphics/sdl/sdl-graphics.h
index 74ee283..ce282d8 100644
--- a/backends/graphics/sdl/sdl-graphics.h
+++ b/backends/graphics/sdl/sdl-graphics.h
@@ -62,10 +62,10 @@ public:
 	virtual void notifyVideoExpose() = 0;
 
 	/**
-	 * Notify the graphics manager about an resize event.
+	 * Notify the graphics manager about a resize event.
 	 *
 	 * It is noteworthy that the requested width/height should actually be set
-	 * up as is and not changed by the graphics manager, since else it might
+	 * up as is and not changed by the graphics manager, since otherwise it may
 	 * lead to odd behavior for certain window managers.
 	 *
 	 * It is only required to overwrite this method in case you want a
@@ -94,7 +94,7 @@ public:
 
 	/**
 	 * A (subset) of the graphic manager's state. This is used when switching
-	 * between different SDL graphic managers on runtime.
+	 * between different SDL graphic managers at runtime.
 	 */
 	struct State {
 		int screenWidth, screenHeight;
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
index 897cdcb..9d0f217 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
@@ -1139,14 +1139,14 @@ void SurfaceSdlGraphicsManager::updateScreen() {
 }
 
 void SurfaceSdlGraphicsManager::updateShader() {
-// shader init code goes here
-// currently only used on Vita port
-// the user-selected shaderID should be obtained via ConfMan.getInt("shader")
-// and the corresponding shader should then be activated here
-// this way the user can combine any software scaling (scalers)
-// with any hardware shading (shaders). The shaders could provide
-// scanline masks, overlays, but could also serve for
-// hardware-based up-scaling (sharp-bilinear-simple, etc.)
+	// shader init code goes here
+	// currently only used on Vita port
+	// the user-selected shaderID should be obtained via ConfMan.getInt("shader")
+	// and the corresponding shader should then be activated here
+	// this way the user can combine any software scaling (scalers)
+	// with any hardware shading (shaders). The shaders could provide
+	// scanline masks, overlays, but could also serve for
+	// hardware-based up-scaling (sharp-bilinear-simple, etc.)
 }
 
 void SurfaceSdlGraphicsManager::internUpdateScreen() {


Commit: 969dd565a135664dcf341af9132dd97b6ec357e9
    https://github.com/scummvm/scummvm/commit/969dd565a135664dcf341af9132dd97b6ec357e9
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-10-15T13:24:20-05:00

Commit Message:
SDL: Allow window resize with non-OpenGL SDL2 backend

The GUI is not redrawn when the window size changes, but that is
not as important as being able to resize the games themselves.

Changed paths:
    backends/graphics/surfacesdl/surfacesdl-graphics.cpp
    backends/graphics/surfacesdl/surfacesdl-graphics.h


diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
index 9d0f217..fb98709 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
@@ -2792,10 +2792,7 @@ void SurfaceSdlGraphicsManager::recreateScreenTexture() {
 SDL_Surface *SurfaceSdlGraphicsManager::SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags) {
 	deinitializeRenderer();
 
-	uint32 createWindowFlags = 0;
-#ifdef USE_SDL_RESIZABLE_WINDOW
-	createWindowFlags |= SDL_WINDOW_RESIZABLE;
-#endif
+	uint32 createWindowFlags = SDL_WINDOW_RESIZABLE;
 	if ((flags & SDL_FULLSCREEN) != 0) {
 		createWindowFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
 	}
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.h b/backends/graphics/surfacesdl/surfacesdl-graphics.h
index 62a4a38..85f63cb 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.h
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.h
@@ -39,15 +39,6 @@
 #define USE_SDL_DEBUG_FOCUSRECT
 #endif
 
-// We have (some) support for resizable windows when SDL2 is used. However
-// the overlay still uses the resolution setup with SDL_SetVideoMode. This
-// makes the GUI look subpar when the user resizes the window. In addition
-// we do not adapt the scale factor right now. Thus, we disable this code
-// path for now.
-#if SDL_VERSION_ATLEAST(2, 0, 0) && 0
-#define USE_SDL_RESIZABLE_WINDOW
-#endif
-
 #if !defined(_WIN32_WCE) && !defined(__SYMBIAN32__)
 // Uncomment this to enable the 'on screen display' code.
 #define USE_OSD	1


Commit: 0ad03e492ac030193536e3167e8bf428e88cafb3
    https://github.com/scummvm/scummvm/commit/0ad03e492ac030193536e3167e8bf428e88cafb3
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-10-15T13:24:20-05:00

Commit Message:
SDL: Accept signed values for mouse cursor warping

This matches the other ScummVM and SDL APIs for mouse warp.

Changed paths:
    backends/platform/sdl/sdl-window.cpp
    backends/platform/sdl/sdl-window.h


diff --git a/backends/platform/sdl/sdl-window.cpp b/backends/platform/sdl/sdl-window.cpp
index 75cf813..16b978d 100644
--- a/backends/platform/sdl/sdl-window.cpp
+++ b/backends/platform/sdl/sdl-window.cpp
@@ -153,7 +153,7 @@ bool SdlWindow::hasMouseFocus() const {
 #endif
 }
 
-void SdlWindow::warpMouseInWindow(uint x, uint y) {
+void SdlWindow::warpMouseInWindow(int x, int y) {
 #if SDL_VERSION_ATLEAST(2, 0, 0)
 	if (_window && hasMouseFocus()) {
 		SDL_WarpMouseInWindow(_window, x, y);
diff --git a/backends/platform/sdl/sdl-window.h b/backends/platform/sdl/sdl-window.h
index d75e811..fb7607b 100644
--- a/backends/platform/sdl/sdl-window.h
+++ b/backends/platform/sdl/sdl-window.h
@@ -58,7 +58,7 @@ public:
 	/**
 	 * Warp the mouse to the specified position in window coordinates.
 	 */
-	void warpMouseInWindow(uint x, uint y);
+	void warpMouseInWindow(int x, int y);
 
 	/**
 	 * Iconifies the window.


Commit: de2bbe3b9738ef95b2529db989570770ef434f9d
    https://github.com/scummvm/scummvm/commit/de2bbe3b9738ef95b2529db989570770ef434f9d
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-10-15T13:24:20-05:00

Commit Message:
BACKENDS: Refactor OpenGL & SDL graphics backends

This patch refactors the OpenGL and SDL graphics backends,
primarily to unify window scaling and mouse handling, and to
fix coordinate mapping between the ScummVM window and the
virtual game screen when they have different aspect ratios.

Unified code for these two backends has been moved to a new
header-only WindowedGraphicsManager class, so named because it
contains code for managing graphics managers that interact with
a windowing system and render virtual screens within a larger
physical content window.

The biggest behavioral change here is with the coordinate
system mapping:

Previously, mouse offsets were converted by mapping the whole
space within the window as input to the virtual game screen
without maintaining aspect ratio. This was done to prevent
'stickiness' when the mouse cursor was within the window but
outside of the virtual game screen, but it caused noticeable
distortion of mouse movement speed on the axis with blank
space.

Instead of introducing mouse speed distortion to prevent
stickiness, this patch changes coordinate transformation to
show the system cursor when the mouse moves outside of the virtual
game screen when mouse grab is off, or by holding the mouse inside
the virtual game screen (instead of the entire window) when mouse
grab is on.

This patch also improves some other properties of the
GraphicsManager/PaletteManager interfaces:

* Nullipotent operations (getWidth, getHeight, etc.) of the
  PaletteManager/GraphicsManager interfaces are now const
* Methods marked `virtual` but not inherited by any subclass have
  been de-virtualized
* Extra unnecessary calculations of hardware height in
  SurfaceSdlGraphicsManager have been removed
* Methods have been renamed where appropriate for clarity
  (setWindowSize -> handleResize, etc.)
* C++11 support improved with `override` specifier added on
  overridden virtual methods in subclasses (primarily to avoid
  myself accidentally creating new methods in the subclasses
  by changing types/names during refactoring)

Additional refactoring can and should be done at some point to
continue to deduplicate code between the OpenGL and SDL backends.
Since the primary goal here was to improve the coordinate mapping,
full refactoring of these backends was not completed here.

Changed paths:
  A backends/graphics/windowed.h
    backends/events/sdl/sdl-events.cpp
    backends/graphics/graphics.h
    backends/graphics/null/null-graphics.h
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/opengl/opengl-graphics.h
    backends/graphics/openglsdl/openglsdl-graphics.cpp
    backends/graphics/openglsdl/openglsdl-graphics.h
    backends/graphics/sdl/sdl-graphics.cpp
    backends/graphics/sdl/sdl-graphics.h
    backends/graphics/surfacesdl/surfacesdl-graphics.cpp
    backends/graphics/surfacesdl/surfacesdl-graphics.h
    backends/platform/sdl/sdl-window.cpp
    backends/platform/sdl/sdl-window.h
    graphics/palette.h


diff --git a/backends/events/sdl/sdl-events.cpp b/backends/events/sdl/sdl-events.cpp
index 2c6fe85..db4aa21 100644
--- a/backends/events/sdl/sdl-events.cpp
+++ b/backends/events/sdl/sdl-events.cpp
@@ -174,8 +174,7 @@ void SdlEventSource::processMouseEvent(Common::Event &event, int x, int y) {
 	event.mouse.y = y;
 
 	if (_graphicsManager) {
-		_graphicsManager->notifyMousePos(Common::Point(x, y));
-		_graphicsManager->transformMouseCoordinates(event.mouse);
+		_graphicsManager->notifyMousePosition(event.mouse);
 	}
 }
 
diff --git a/backends/graphics/graphics.h b/backends/graphics/graphics.h
index bcd659a..cf33803 100644
--- a/backends/graphics/graphics.h
+++ b/backends/graphics/graphics.h
@@ -38,9 +38,9 @@ class GraphicsManager : public PaletteManager {
 public:
 	virtual ~GraphicsManager() {}
 
-	virtual bool hasFeature(OSystem::Feature f) = 0;
+	virtual bool hasFeature(OSystem::Feature f) const = 0;
 	virtual void setFeatureState(OSystem::Feature f, bool enable) = 0;
-	virtual bool getFeatureState(OSystem::Feature f) = 0;
+	virtual bool getFeatureState(OSystem::Feature f) const = 0;
 
 	virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const = 0;
 	virtual int getDefaultGraphicsMode() const = 0;
@@ -65,10 +65,10 @@ public:
 	virtual void beginGFXTransaction() = 0;
 	virtual OSystem::TransactionError endGFXTransaction() = 0;
 
-	virtual int16 getHeight() = 0;
-	virtual int16 getWidth() = 0;
+	virtual int16 getHeight() const = 0;
+	virtual int16 getWidth() const = 0;
 	virtual void setPalette(const byte *colors, uint start, uint num) = 0;
-	virtual void grabPalette(byte *colors, uint start, uint num) = 0;
+	virtual void grabPalette(byte *colors, uint start, uint num) const = 0;
 	virtual void copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) = 0;
 	virtual Graphics::Surface *lockScreen() = 0;
 	virtual void unlockScreen() = 0;
@@ -82,10 +82,10 @@ public:
 	virtual void hideOverlay() = 0;
 	virtual Graphics::PixelFormat getOverlayFormat() const = 0;
 	virtual void clearOverlay() = 0;
-	virtual void grabOverlay(void *buf, int pitch) = 0;
-	virtual void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h)= 0;
-	virtual int16 getOverlayHeight() = 0;
-	virtual int16 getOverlayWidth() = 0;
+	virtual void grabOverlay(void *buf, int pitch) const = 0;
+	virtual void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) = 0;
+	virtual int16 getOverlayHeight() const = 0;
+	virtual int16 getOverlayWidth() const = 0;
 
 	virtual bool showMouse(bool visible) = 0;
 	virtual void warpMouse(int x, int y) = 0;
diff --git a/backends/graphics/null/null-graphics.h b/backends/graphics/null/null-graphics.h
index 67306c2..a870a76 100644
--- a/backends/graphics/null/null-graphics.h
+++ b/backends/graphics/null/null-graphics.h
@@ -54,8 +54,8 @@ public:
 	void beginGFXTransaction() {}
 	OSystem::TransactionError endGFXTransaction() { return OSystem::kTransactionSuccess; }
 
-	int16 getHeight() { return 0; }
-	int16 getWidth() { return 0; }
+	int16 getHeight() const { return 0; }
+	int16 getWidth() const { return 0; }
 	void setPalette(const byte *colors, uint start, uint num) {}
 	void grabPalette(byte *colors, uint start, uint num) {}
 	void copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) {}
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 28ca110..d98dcda 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -53,14 +53,12 @@ namespace OpenGL {
 OpenGLGraphicsManager::OpenGLGraphicsManager()
     : _currentState(), _oldState(), _transactionMode(kTransactionNone), _screenChangeID(1 << (sizeof(int) * 8 - 2)),
       _pipeline(nullptr),
-      _outputScreenWidth(0), _outputScreenHeight(0), _displayX(0), _displayY(0),
-      _displayWidth(0), _displayHeight(0), _defaultFormat(), _defaultFormatAlpha(),
+      _defaultFormat(), _defaultFormatAlpha(),
       _gameScreen(nullptr), _gameScreenShakeOffset(0), _overlay(nullptr),
-      _overlayVisible(false), _cursor(nullptr),
-      _cursorX(0), _cursorY(0), _cursorDisplayX(0),_cursorDisplayY(0), _cursorHotspotX(0), _cursorHotspotY(0),
+      _cursor(nullptr),
+      _cursorHotspotX(0), _cursorHotspotY(0),
       _cursorHotspotXScaled(0), _cursorHotspotYScaled(0), _cursorWidthScaled(0), _cursorHeightScaled(0),
-      _cursorKeyColor(0), _cursorVisible(false), _cursorDontScale(false), _cursorPaletteEnabled(false),
-      _forceRedraw(false)
+      _cursorKeyColor(0), _cursorVisible(false), _cursorDontScale(false), _cursorPaletteEnabled(false)
 #ifdef USE_OSD
       , _osdMessageChangeRequest(false), _osdMessageAlpha(0), _osdMessageFadeStartTime(0), _osdMessageSurface(nullptr),
       _osdIconSurface(nullptr)
@@ -83,7 +81,7 @@ OpenGLGraphicsManager::~OpenGLGraphicsManager() {
 #endif
 }
 
-bool OpenGLGraphicsManager::hasFeature(OSystem::Feature f) {
+bool OpenGLGraphicsManager::hasFeature(OSystem::Feature f) const {
 	switch (f) {
 	case OSystem::kFeatureAspectRatioCorrection:
 	case OSystem::kFeatureCursorPalette:
@@ -129,7 +127,7 @@ void OpenGLGraphicsManager::setFeatureState(OSystem::Feature f, bool enable) {
 	}
 }
 
-bool OpenGLGraphicsManager::getFeatureState(OSystem::Feature f) {
+bool OpenGLGraphicsManager::getFeatureState(OSystem::Feature f) const {
 	switch (f) {
 	case OSystem::kFeatureAspectRatioCorrection:
 		return _currentState.aspectRatioCorrection;
@@ -220,10 +218,9 @@ OSystem::TransactionError OpenGLGraphicsManager::endGFXTransaction() {
 #endif
 
 	do {
-		uint requestedWidth  = _currentState.gameWidth;
-		uint requestedHeight = _currentState.gameHeight;
-		const uint desiredAspect = getDesiredGameScreenAspect();
-		requestedHeight = intToFrac(requestedWidth) / desiredAspect;
+		const uint desiredAspect = getDesiredGameAspectRatio();
+		const uint requestedWidth  = _currentState.gameWidth;
+		const uint requestedHeight = intToFrac(requestedWidth) / desiredAspect;
 
 		if (!loadVideoMode(requestedWidth, requestedHeight,
 #ifdef USE_RGB_COLOR
@@ -317,7 +314,7 @@ OSystem::TransactionError OpenGLGraphicsManager::endGFXTransaction() {
 
 	// Update our display area and cursor scaling. This makes sure we pick up
 	// aspect ratio correction and game screen changes correctly.
-	recalculateDisplayArea();
+	recalculateDisplayAreas();
 	recalculateCursorScaling();
 
 	// Something changed, so update the screen change ID.
@@ -347,11 +344,11 @@ void OpenGLGraphicsManager::initSize(uint width, uint height, const Graphics::Pi
 	_currentState.gameHeight = height;
 }
 
-int16 OpenGLGraphicsManager::getWidth() {
+int16 OpenGLGraphicsManager::getWidth() const {
 	return _currentState.gameWidth;
 }
 
-int16 OpenGLGraphicsManager::getHeight() {
+int16 OpenGLGraphicsManager::getHeight() const {
 	return _currentState.gameHeight;
 }
 
@@ -392,6 +389,7 @@ void OpenGLGraphicsManager::updateScreen() {
 
 	// We only update the screen when there actually have been any changes.
 	if (   !_forceRedraw
+		&& !_cursorNeedsRedraw
 	    && !_gameScreen->isDirty()
 	    && !(_overlayVisible && _overlay->isDirty())
 	    && !(_cursorVisible && _cursor && _cursor->isDirty())
@@ -401,7 +399,6 @@ void OpenGLGraphicsManager::updateScreen() {
 	    ) {
 		return;
 	}
-	_forceRedraw = false;
 
 	// Update changes to textures.
 	_gameScreen->updateGLTexture();
@@ -420,14 +417,14 @@ void OpenGLGraphicsManager::updateScreen() {
 		_backBuffer.enableScissorTest(true);
 	}
 
-	const GLfloat shakeOffset = _gameScreenShakeOffset * (GLfloat)_displayHeight / _gameScreen->getHeight();
+	const GLfloat shakeOffset = _gameScreenShakeOffset * (GLfloat)_gameDrawRect.height() / _gameScreen->getHeight();
 
 	// First step: Draw the (virtual) game screen.
-	g_context.getActivePipeline()->drawTexture(_gameScreen->getGLTexture(), _displayX, _displayY + shakeOffset, _displayWidth, _displayHeight);
+	g_context.getActivePipeline()->drawTexture(_gameScreen->getGLTexture(), _gameDrawRect.left, _gameDrawRect.top + shakeOffset, _gameDrawRect.width(), _gameDrawRect.height());
 
 	// Second step: Draw the overlay if visible.
 	if (_overlayVisible) {
-		g_context.getActivePipeline()->drawTexture(_overlay->getGLTexture(), 0, 0, _outputScreenWidth, _outputScreenHeight);
+		g_context.getActivePipeline()->drawTexture(_overlay->getGLTexture(), 0, 0, _overlayDrawRect.width(), _overlayDrawRect.height());
 	}
 
 	// Third step: Draw the cursor if visible.
@@ -437,8 +434,8 @@ void OpenGLGraphicsManager::updateScreen() {
 		const GLfloat cursorOffset = _overlayVisible ? 0 : shakeOffset;
 
 		g_context.getActivePipeline()->drawTexture(_cursor->getGLTexture(),
-		                         _cursorDisplayX - _cursorHotspotXScaled,
-		                         _cursorDisplayY - _cursorHotspotYScaled + cursorOffset,
+		                         _cursorX - _cursorHotspotXScaled,
+		                         _cursorY - _cursorHotspotYScaled + cursorOffset,
 		                         _cursorWidthScaled, _cursorHeightScaled);
 	}
 
@@ -464,8 +461,8 @@ void OpenGLGraphicsManager::updateScreen() {
 		// Set the OSD transparency.
 		g_context.getActivePipeline()->setColor(1.0f, 1.0f, 1.0f, _osdMessageAlpha / 100.0f);
 
-		int dstX = (_outputScreenWidth - _osdMessageSurface->getWidth()) / 2;
-		int dstY = (_outputScreenHeight - _osdMessageSurface->getHeight()) / 2;
+		int dstX = (_windowWidth - _osdMessageSurface->getWidth()) / 2;
+		int dstY = (_windowHeight - _osdMessageSurface->getHeight()) / 2;
 
 		// Draw the OSD texture.
 		g_context.getActivePipeline()->drawTexture(_osdMessageSurface->getGLTexture(),
@@ -481,7 +478,7 @@ void OpenGLGraphicsManager::updateScreen() {
 	}
 
 	if (_osdIconSurface) {
-		int dstX = _outputScreenWidth - _osdIconSurface->getWidth() - kOSDIconRightMargin;
+		int dstX = _windowWidth - _osdIconSurface->getWidth() - kOSDIconRightMargin;
 		int dstY = kOSDIconTopMargin;
 
 		// Draw the OSD icon texture.
@@ -490,6 +487,8 @@ void OpenGLGraphicsManager::updateScreen() {
 	}
 #endif
 
+	_cursorNeedsRedraw = false;
+	_forceRedraw = false;
 	refreshScreen();
 }
 
@@ -507,7 +506,7 @@ void OpenGLGraphicsManager::setFocusRectangle(const Common::Rect& rect) {
 void OpenGLGraphicsManager::clearFocusRectangle() {
 }
 
-int16 OpenGLGraphicsManager::getOverlayWidth() {
+int16 OpenGLGraphicsManager::getOverlayWidth() const {
 	if (_overlay) {
 		return _overlay->getWidth();
 	} else {
@@ -515,7 +514,7 @@ int16 OpenGLGraphicsManager::getOverlayWidth() {
 	}
 }
 
-int16 OpenGLGraphicsManager::getOverlayHeight() {
+int16 OpenGLGraphicsManager::getOverlayHeight() const {
 	if (_overlay) {
 		return _overlay->getHeight();
 	} else {
@@ -523,22 +522,6 @@ int16 OpenGLGraphicsManager::getOverlayHeight() {
 	}
 }
 
-void OpenGLGraphicsManager::showOverlay() {
-	_overlayVisible = true;
-	_forceRedraw = true;
-
-	// Update cursor position.
-	setMousePosition(_cursorX, _cursorY);
-}
-
-void OpenGLGraphicsManager::hideOverlay() {
-	_overlayVisible = false;
-	_forceRedraw = true;
-
-	// Update cursor position.
-	setMousePosition(_cursorX, _cursorY);
-}
-
 Graphics::PixelFormat OpenGLGraphicsManager::getOverlayFormat() const {
 	return _overlay->getFormat();
 }
@@ -551,7 +534,7 @@ void OpenGLGraphicsManager::clearOverlay() {
 	_overlay->fill(0);
 }
 
-void OpenGLGraphicsManager::grabOverlay(void *buf, int pitch) {
+void OpenGLGraphicsManager::grabOverlay(void *buf, int pitch) const {
 	const Graphics::Surface *overlayData = _overlay->getSurface();
 
 	const byte *src = (const byte *)overlayData->getPixels();
@@ -568,7 +551,7 @@ bool OpenGLGraphicsManager::showMouse(bool visible) {
 	// In case the mouse cursor visibility changed we need to redraw the whole
 	// screen even when nothing else changed.
 	if (_cursorVisible != visible) {
-		_forceRedraw = true;
+		_cursorNeedsRedraw = true;
 	}
 
 	bool last = _cursorVisible;
@@ -576,43 +559,6 @@ bool OpenGLGraphicsManager::showMouse(bool visible) {
 	return last;
 }
 
-void OpenGLGraphicsManager::warpMouse(int x, int y) {
-	int16 currentX = _cursorX;
-	int16 currentY = _cursorY;
-	adjustMousePosition(currentX, currentY);
-
-	// Check whether the (virtual) coordinate actually changed. If not, then
-	// simply do nothing. This avoids ugly "jittering" due to the actual
-	// output screen having a bigger resolution than the virtual coordinates.
-	if (currentX == x && currentY == y) {
-		return;
-	}
-
-	// Scale the virtual coordinates into actual physical coordinates.
-	if (_overlayVisible) {
-		if (!_overlay) {
-			return;
-		}
-
-		// It might be confusing that we actually have to handle something
-		// here when the overlay is visible. This is because for very small
-		// resolutions we have a minimal overlay size and have to adjust
-		// for that.
-		x = (x * _outputScreenWidth)  / _overlay->getWidth();
-		y = (y * _outputScreenHeight) / _overlay->getHeight();
-	} else {
-		if (!_gameScreen) {
-			return;
-		}
-
-		x = (x * _outputScreenWidth)  / _gameScreen->getWidth();
-		y = (y * _outputScreenHeight) / _gameScreen->getHeight();
-	}
-
-	setMousePosition(x, y);
-	setInternalMousePosition(x, y);
-}
-
 namespace {
 template<typename DstPixel, typename SrcPixel>
 void applyColorKey(DstPixel *dst, const SrcPixel *src, uint w, uint h, uint dstPitch, uint srcPitch, SrcPixel keyColor, DstPixel alphaMask) {
@@ -720,7 +666,6 @@ void OpenGLGraphicsManager::setMouseCursor(const void *buf, uint w, uint h, int
 		updateCursorPalette();
 	}
 
-	// Update the scaling.
 	recalculateCursorScaling();
 }
 
@@ -765,8 +710,8 @@ void OpenGLGraphicsManager::osdMessageUpdateSurface() {
 	}
 
 	// Clip the rect
-	width  = MIN<uint>(width,  _displayWidth);
-	height = MIN<uint>(height, _displayHeight);
+	width  = MIN<uint>(width,  _gameDrawRect.width());
+	height = MIN<uint>(height, _gameDrawRect.height());
 
 	delete _osdMessageSurface;
 	_osdMessageSurface = nullptr;
@@ -849,16 +794,13 @@ void OpenGLGraphicsManager::setPalette(const byte *colors, uint start, uint num)
 	updateCursorPalette();
 }
 
-void OpenGLGraphicsManager::grabPalette(byte *colors, uint start, uint num) {
+void OpenGLGraphicsManager::grabPalette(byte *colors, uint start, uint num) const {
 	assert(_gameScreen->hasPalette());
 
 	memcpy(colors, _gamePalette + start * 3, num * 3);
 }
 
-void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
-	_outputScreenWidth = width;
-	_outputScreenHeight = height;
-
+void OpenGLGraphicsManager::handleResizeImpl(const int width, const int height) {
 	// Setup backbuffer size.
 	_backBuffer.setDimensions(width, height);
 
@@ -873,7 +815,7 @@ void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
 	// anyway. Thus, it should not be a real issue for modern hardware.
 	if (   overlayWidth  > (uint)g_context.maxTextureSize
 	    || overlayHeight > (uint)g_context.maxTextureSize) {
-		const frac_t outputAspect = intToFrac(_outputScreenWidth) / _outputScreenHeight;
+		const frac_t outputAspect = intToFrac(_windowWidth) / _windowHeight;
 
 		if (outputAspect > (frac_t)FRAC_ONE) {
 			overlayWidth  = g_context.maxTextureSize;
@@ -906,7 +848,7 @@ void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
 	_overlay->fill(0);
 
 	// Re-setup the scaling for the screen and cursor
-	recalculateDisplayArea();
+	recalculateDisplayAreas();
 	recalculateCursorScaling();
 
 	// Something changed, so update the screen change ID.
@@ -960,8 +902,8 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
 	GL_CALL(glPixelStorei(GL_PACK_ALIGNMENT, 4));
 
 	// Refresh the output screen dimensions if some are set up.
-	if (_outputScreenWidth != 0 && _outputScreenHeight != 0) {
-		setActualScreenSize(_outputScreenWidth, _outputScreenHeight);
+	if (_windowWidth != 0 && _windowHeight != 0) {
+		handleResize(_windowWidth, _windowHeight);
 	}
 
 	// TODO: Should we try to convert textures into one of those formats if
@@ -1031,46 +973,6 @@ void OpenGLGraphicsManager::notifyContextDestroy() {
 	g_context.reset();
 }
 
-void OpenGLGraphicsManager::adjustMousePosition(int16 &x, int16 &y) {
-	if (_overlayVisible) {
-		// It might be confusing that we actually have to handle something
-		// here when the overlay is visible. This is because for very small
-		// resolutions we have a minimal overlay size and have to adjust
-		// for that.
-		// This can also happen when the overlay is smaller than the actual
-		// display size because of texture size limitations.
-		if (_overlay) {
-			x = (x * _overlay->getWidth())  / _outputScreenWidth;
-			y = (y * _overlay->getHeight()) / _outputScreenHeight;
-		}
-	} else if (_gameScreen) {
-		const int16 width  = _gameScreen->getWidth();
-		const int16 height = _gameScreen->getHeight();
-
-		x = (x * width)  / (int)_outputScreenWidth;
-		y = (y * height) / (int)_outputScreenHeight;
-	}
-}
-
-void OpenGLGraphicsManager::setMousePosition(int x, int y) {
-	// Whenever the mouse position changed we force a screen redraw to reflect
-	// changes properly.
-	if (_cursorX != x || _cursorY != y) {
-		_forceRedraw = true;
-	}
-
-	_cursorX = x;
-	_cursorY = y;
-
-	if (_overlayVisible) {
-		_cursorDisplayX = x;
-		_cursorDisplayY = y;
-	} else {
-		_cursorDisplayX = _displayX + (x * _displayWidth)  / _outputScreenWidth;
-		_cursorDisplayY = _displayY + (y * _displayHeight) / _outputScreenHeight;
-	}
-}
-
 Surface *OpenGLGraphicsManager::createSurface(const Graphics::PixelFormat &format, bool wantAlpha) {
 	GLenum glIntFormat, glFormat, glType;
 	if (format.bytesPerPixel == 1) {
@@ -1191,51 +1093,34 @@ bool OpenGLGraphicsManager::getGLPixelFormat(const Graphics::PixelFormat &pixelF
 	}
 }
 
-frac_t OpenGLGraphicsManager::getDesiredGameScreenAspect() const {
-	const uint width  = _currentState.gameWidth;
-	const uint height = _currentState.gameHeight;
-
+bool OpenGLGraphicsManager::gameNeedsAspectRatioCorrection() const {
 	if (_currentState.aspectRatioCorrection) {
+		const uint width = getWidth();
+		const uint height = getHeight();
+
 		// In case we enable aspect ratio correction we force a 4/3 ratio.
 		// But just for 320x200 and 640x400 games, since other games do not need
 		// this.
-		if ((width == 320 && height == 200) || (width == 640 && height == 400)) {
-			return intToFrac(4) / 3;
-		}
+		return (width == 320 && height == 200) || (width == 640 && height == 400);
 	}
 
-	return intToFrac(width) / height;
+	return false;
 }
 
-void OpenGLGraphicsManager::recalculateDisplayArea() {
-	if (!_gameScreen || _outputScreenHeight == 0) {
+void OpenGLGraphicsManager::recalculateDisplayAreas() {
+	if (!_gameScreen) {
 		return;
 	}
 
-	const frac_t outputAspect = intToFrac(_outputScreenWidth) / _outputScreenHeight;
-	const frac_t desiredAspect = getDesiredGameScreenAspect();
-
-	_displayWidth = _outputScreenWidth;
-	_displayHeight = _outputScreenHeight;
-
-	// Adjust one dimension for mantaining the aspect ratio.
-	if (outputAspect < desiredAspect) {
-		_displayHeight = intToFrac(_displayWidth) / desiredAspect;
-	} else if (outputAspect > desiredAspect) {
-		_displayWidth = fracToInt(_displayHeight * desiredAspect);
-	}
-
-	// We center the screen in the middle for now.
-	_displayX = (_outputScreenWidth  - _displayWidth ) / 2;
-	_displayY = (_outputScreenHeight - _displayHeight) / 2;
+	WindowedGraphicsManager::recalculateDisplayAreas();
 
 	// Setup drawing limitation for game graphics.
 	// This involves some trickery because OpenGL's viewport coordinate system
 	// is upside down compared to ours.
-	_backBuffer.setScissorBox(_displayX,
-	                          _outputScreenHeight - _displayHeight - _displayY,
-	                          _displayWidth,
-	                          _displayHeight);
+	_backBuffer.setScissorBox(_gameDrawRect.left,
+	                          _windowHeight - _gameDrawRect.height() - _gameDrawRect.top,
+	                          _gameDrawRect.width(),
+	                          _gameDrawRect.height());
 
 	// Update the cursor position to adjust for new display area.
 	setMousePosition(_cursorX, _cursorY);
@@ -1272,8 +1157,8 @@ void OpenGLGraphicsManager::recalculateCursorScaling() {
 	// In case scaling is actually enabled we will scale the cursor according
 	// to the game screen.
 	if (!_cursorDontScale) {
-		const frac_t screenScaleFactorX = intToFrac(_displayWidth)  / _gameScreen->getWidth();
-		const frac_t screenScaleFactorY = intToFrac(_displayHeight) / _gameScreen->getHeight();
+		const frac_t screenScaleFactorX = intToFrac(_gameDrawRect.width()) / _gameScreen->getWidth();
+		const frac_t screenScaleFactorY = intToFrac(_gameDrawRect.height()) / _gameScreen->getHeight();
 
 		_cursorHotspotXScaled = fracToInt(_cursorHotspotXScaled * screenScaleFactorX);
 		_cursorWidthScaled    = fracToInt(_cursorWidthScaled    * screenScaleFactorX);
@@ -1284,14 +1169,14 @@ void OpenGLGraphicsManager::recalculateCursorScaling() {
 }
 
 #ifdef USE_OSD
-const Graphics::Font *OpenGLGraphicsManager::getFontOSD() {
+const Graphics::Font *OpenGLGraphicsManager::getFontOSD() const {
 	return FontMan.getFontByUsage(Graphics::FontManager::kLocalizedFont);
 }
 #endif
 
 bool OpenGLGraphicsManager::saveScreenshot(const Common::String &filename) const {
-	const uint width  = _outputScreenWidth;
-	const uint height = _outputScreenHeight;
+	const uint width  = _windowWidth;
+	const uint height = _windowHeight;
 
 	// A line of a BMP image must have a size divisible by 4.
 	// We calculate the padding bytes needed here.
diff --git a/backends/graphics/opengl/opengl-graphics.h b/backends/graphics/opengl/opengl-graphics.h
index cbf68d9..92bb988 100644
--- a/backends/graphics/opengl/opengl-graphics.h
+++ b/backends/graphics/opengl/opengl-graphics.h
@@ -25,7 +25,7 @@
 
 #include "backends/graphics/opengl/opengl-sys.h"
 #include "backends/graphics/opengl/framebuffer.h"
-#include "backends/graphics/graphics.h"
+#include "backends/graphics/windowed.h"
 
 #include "common/frac.h"
 #include "common/mutex.h"
@@ -53,74 +53,70 @@ enum {
 	GFX_OPENGL = 0
 };
 
-class OpenGLGraphicsManager : virtual public GraphicsManager {
+class OpenGLGraphicsManager : virtual public WindowedGraphicsManager {
 public:
 	OpenGLGraphicsManager();
 	virtual ~OpenGLGraphicsManager();
 
 	// GraphicsManager API
-	virtual bool hasFeature(OSystem::Feature f);
-	virtual void setFeatureState(OSystem::Feature f, bool enable);
-	virtual bool getFeatureState(OSystem::Feature f);
+	virtual bool hasFeature(OSystem::Feature f) const override;
+	virtual void setFeatureState(OSystem::Feature f, bool enable) override;
+	virtual bool getFeatureState(OSystem::Feature f) const override;
 
-	virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const;
-	virtual int getDefaultGraphicsMode() const;
-	virtual bool setGraphicsMode(int mode);
-	virtual int getGraphicsMode() const;
+	virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const override;
+	virtual int getDefaultGraphicsMode() const override;
+	virtual bool setGraphicsMode(int mode) override;
+	virtual int getGraphicsMode() const override;
 
-	virtual void resetGraphicsScale() {}
+	virtual void resetGraphicsScale() override {}
 
 #ifdef USE_RGB_COLOR
-	virtual Graphics::PixelFormat getScreenFormat() const;
-	virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const = 0;
+	virtual Graphics::PixelFormat getScreenFormat() const override;
+	virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const override = 0;
 #endif
 
-	virtual void beginGFXTransaction();
-	virtual OSystem::TransactionError endGFXTransaction();
+	virtual void beginGFXTransaction() override;
+	virtual OSystem::TransactionError endGFXTransaction() override;
 
-	virtual int getScreenChangeID() const;
+	virtual int getScreenChangeID() const override;
 
-	virtual void initSize(uint width, uint height, const Graphics::PixelFormat *format);
+	virtual void initSize(uint width, uint height, const Graphics::PixelFormat *format) override;
 
-	virtual int16 getWidth();
-	virtual int16 getHeight();
+	virtual int16 getWidth() const override;
+	virtual int16 getHeight() const override;
 
-	virtual void copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h);
-	virtual void fillScreen(uint32 col);
+	virtual void copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) override;
+	virtual void fillScreen(uint32 col) override;
 
-	virtual void setShakePos(int shakeOffset);
+	virtual void setShakePos(int shakeOffset) override;
 
-	virtual void updateScreen();
+	virtual void updateScreen() override;
 
-	virtual Graphics::Surface *lockScreen();
-	virtual void unlockScreen();
+	virtual Graphics::Surface *lockScreen() override;
+	virtual void unlockScreen() override;
 
-	virtual void setFocusRectangle(const Common::Rect& rect);
-	virtual void clearFocusRectangle();
+	virtual void setFocusRectangle(const Common::Rect& rect) override;
+	virtual void clearFocusRectangle() override;
 
-	virtual int16 getOverlayWidth();
-	virtual int16 getOverlayHeight();
+	virtual int16 getOverlayWidth() const override;
+	virtual int16 getOverlayHeight() const override;
 
-	virtual void showOverlay();
-	virtual void hideOverlay();
+	virtual Graphics::PixelFormat getOverlayFormat() const override;
 
-	virtual Graphics::PixelFormat getOverlayFormat() const;
+	virtual void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) override;
+	virtual void clearOverlay() override;
+	virtual void grabOverlay(void *buf, int pitch) const override;
 
-	virtual void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h);
-	virtual void clearOverlay();
-	virtual void grabOverlay(void *buf, int pitch);
+	virtual bool showMouse(bool visible) override;
+	virtual void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) override;
+	virtual void setCursorPalette(const byte *colors, uint start, uint num) override;
 
-	virtual bool showMouse(bool visible);
-	virtual void warpMouse(int x, int y);
-	virtual void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format);
-	virtual void setCursorPalette(const byte *colors, uint start, uint num);
-
-	virtual void displayMessageOnOSD(const char *msg);
-	virtual void displayActivityIconOnOSD(const Graphics::Surface *icon);
+	virtual void displayMessageOnOSD(const char *msg) override;
+	virtual void displayActivityIconOnOSD(const Graphics::Surface *icon) override;
 
 	// PaletteManager interface
-	virtual void setPalette(const byte *colors, uint start, uint num);
-	virtual void grabPalette(byte *colors, uint start, uint num);
+	virtual void setPalette(const byte *colors, uint start, uint num) override;
+	virtual void grabPalette(byte *colors, uint start, uint num) const override;
 
 protected:
 	/**
@@ -129,15 +125,6 @@ protected:
 	bool isGLESContext() const { return g_context.type == kContextGLES || g_context.type == kContextGLES2; }
 
 	/**
-	 * Set up the actual screen size available for the OpenGL code to do any
-	 * drawing.
-	 *
-	 * @param width  The width of the screen.
-	 * @param height The height of the screen.
-	 */
-	void setActualScreenSize(uint width, uint height);
-
-	/**
 	 * Sets the OpenGL (ES) type the graphics manager shall work with.
 	 *
 	 * This needs to be called at least once (and before ever calling
@@ -167,33 +154,6 @@ protected:
 	void notifyContextDestroy();
 
 	/**
-	 * Adjust the physical mouse coordinates according to the currently visible screen.
-	 */
-	void adjustMousePosition(int16 &x, int16 &y);
-
-	/**
-	 * Set up the mouse position for graphics output.
-	 *
-	 * @param x X coordinate in physical coordinates.
-	 * @param y Y coordinate in physical coordinates.
-	 */
-	void setMousePosition(int x, int y);
-
-	/**
-	 * Query the mouse position in physical coordinates.
-	 */
-	void getMousePosition(int16 &x, int16 &y) const { x = _cursorX; y = _cursorY; }
-
-	/**
-	 * Set up the mouse position for the (event) system.
-	 *
-	 * @param x X coordinate in physical coordinates.
-	 * @param y Y coordinate in physical coordinates.
-	 */
-	virtual void setInternalMousePosition(int x, int y) = 0;
-
-private:
-	/**
 	 * Create a surface with the specified pixel format.
 	 *
 	 * @param format    The pixel format the Surface object should accept as
@@ -292,8 +252,7 @@ protected:
 	virtual void refreshScreen() = 0;
 
 	/**
-	 * Save a screenshot of the full display as BMP to the given file. This
-	 * uses Common::DumpFile for writing the screenshot.
+	 * Saves a screenshot of the entire window, excluding window decorations.
 	 *
 	 * @param filename The output filename.
 	 * @return true on success, false otherwise
@@ -334,7 +293,6 @@ protected:
 	 */
 	virtual void *getProcAddress(const char *name) const = 0;
 
-private:
 	/**
 	 * Try to determine the internal parameters for a given pixel format.
 	 *
@@ -342,49 +300,9 @@ private:
 	 */
 	bool getGLPixelFormat(const Graphics::PixelFormat &pixelFormat, GLenum &glIntFormat, GLenum &glFormat, GLenum &glType) const;
 
-	//
-	// Actual hardware screen
-	//
-
-	/**
-	 * The width of the physical output.
-	 */
-	uint _outputScreenWidth;
-
-	/**
-	 * The height of the physical output.
-	 */
-	uint _outputScreenHeight;
-
-	/**
-	 * @return The desired aspect of the game screen.
-	 */
-	frac_t getDesiredGameScreenAspect() const;
-
-	/**
-	 * Recalculates the area used to display the game screen.
-	 */
-	void recalculateDisplayArea();
-
-	/**
-	 * The X coordinate of the game screen.
-	 */
-	uint _displayX;
-
-	/**
-	 * The Y coordinate of the game screen.
-	 */
-	uint _displayY;
-
-	/**
-	 * The width of the game screen in physical coordinates.
-	 */
-	uint _displayWidth;
-
-	/**
-	 * The height of the game screen in physical coordinates.
-	 */
-	uint _displayHeight;
+	virtual bool gameNeedsAspectRatioCorrection() const override;
+	virtual void recalculateDisplayAreas() override;
+	virtual void handleResizeImpl(const int width, const int height) override;
 
 	/**
 	 * The default pixel format of the backend.
@@ -396,12 +314,8 @@ private:
 	 */
 	Graphics::PixelFormat _defaultFormatAlpha;
 
-	//
-	// Game screen
-	//
-
 	/**
-	 * The virtual game screen.
+	 * The rendering surface for the virtual game screen.
 	 */
 	Surface *_gameScreen;
 
@@ -420,15 +334,10 @@ private:
 	//
 
 	/**
-	 * The overlay screen.
+	 * The rendering surface for the overlay.
 	 */
 	Surface *_overlay;
 
-	/**
-	 * Whether the overlay is visible or not.
-	 */
-	bool _overlayVisible;
-
 	//
 	// Cursor
 	//
@@ -439,37 +348,17 @@ private:
 	void updateCursorPalette();
 
 	/**
-	 * The cursor image.
+	 * The rendering surface for the mouse cursor.
 	 */
 	Surface *_cursor;
 
 	/**
-	 * X coordinate of the cursor in physical coordinates.
-	 */
-	int _cursorX;
-
-	/**
-	 * Y coordinate of the cursor in physical coordinates.
-	 */
-	int _cursorY;
-
-	/**
-	 * X coordinate used for drawing the cursor.
-	 */
-	int _cursorDisplayX;
-
-	/**
-	 * Y coordinate used for drawing the cursor.
-	 */
-	int _cursorDisplayY;
-
-	/**
-	 * The X offset for the cursor hotspot in unscaled coordinates.
+	 * The X offset for the cursor hotspot in unscaled game coordinates.
 	 */
 	int _cursorHotspotX;
 
 	/**
-	 * The Y offset for the cursor hotspot in unscaled coordinates.
+	 * The Y offset for the cursor hotspot in unscaled game coordinates.
 	 */
 	int _cursorHotspotY;
 
@@ -480,22 +369,24 @@ private:
 	void recalculateCursorScaling();
 
 	/**
-	 * The X offset for the cursor hotspot in scaled coordinates.
+	 * The X offset for the cursor hotspot in scaled game display area
+	 * coordinates.
 	 */
 	int _cursorHotspotXScaled;
 
 	/**
-	 * The Y offset for the cursor hotspot in scaled coordinates.
+	 * The Y offset for the cursor hotspot in scaled game display area
+	 * coordinates.
 	 */
 	int _cursorHotspotYScaled;
 
 	/**
-	 * The width of the cursor scaled coordinates.
+	 * The width of the cursor in scaled game display area coordinates.
 	 */
 	uint _cursorWidthScaled;
 
 	/**
-	 * The height of the cursor scaled coordinates.
+	 * The height of the cursor in scaled game display area coordinates.
 	 */
 	uint _cursorHeightScaled;
 
@@ -524,15 +415,6 @@ private:
 	 */
 	byte _cursorPalette[3 * 256];
 
-	//
-	// Misc
-	//
-
-	/**
-	 * Whether the screen contents shall be forced to redrawn.
-	 */
-	bool _forceRedraw;
-
 #ifdef USE_OSD
 	//
 	// OSD
@@ -541,7 +423,7 @@ protected:
 	/**
 	 * Returns the font used for on screen display
 	 */
-	virtual const Graphics::Font *getFontOSD();
+	virtual const Graphics::Font *getFontOSD() const;
 
 private:
 	/**
diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp
index 46940d7..c77e9da 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.cpp
+++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp
@@ -21,8 +21,10 @@
  */
 
 #include "backends/graphics/openglsdl/openglsdl-graphics.h"
+#include "backends/graphics/opengl/texture.h"
 #include "backends/events/sdl/sdl-events.h"
 #include "backends/platform/sdl/sdl.h"
+#include "graphics/scaler/aspect.h"
 
 #include "common/textconsole.h"
 #include "common/config-manager.h"
@@ -35,7 +37,7 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(uint desktopWidth, uint deskt
 #if SDL_VERSION_ATLEAST(2, 0, 0)
       _glContext(),
 #else
-      _lastVideoModeLoad(0), _hwScreen(nullptr),
+      _lastVideoModeLoad(0),
 #endif
       _graphicsScale(2), _ignoreLoadVideoMode(false), _gotResize(false), _wantsFullScreen(false), _ignoreResizeEvents(0),
       _desiredFullscreenWidth(0), _desiredFullscreenHeight(0) {
@@ -52,14 +54,16 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(uint desktopWidth, uint deskt
 
 	// Context version 1.4 is choosen arbitrarily based on what most shader
 	// extensions were written against.
-#define DEFAULT_GL_MAJOR 1
-#define DEFAULT_GL_MINOR 4
+	enum {
+		DEFAULT_GL_MAJOR = 1,
+		DEFAULT_GL_MINOR = 4,
 
-#define DEFAULT_GLES_MAJOR 1
-#define DEFAULT_GLES_MINOR 1
+		DEFAULT_GLES_MAJOR = 1,
+		DEFAULT_GLES_MINOR = 1,
 
-#define DEFAULT_GLES2_MAJOR 2
-#define DEFAULT_GLES2_MINOR 0
+		DEFAULT_GLES2_MAJOR = 2,
+		DEFAULT_GLES2_MINOR = 0
+	};
 
 #if USE_FORCED_GL
 	glContextType = OpenGL::kContextGL;
@@ -127,12 +131,6 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(uint desktopWidth, uint deskt
 	} else {
 		glContextType = OpenGL::kContextGL;
 	}
-#undef DEFAULT_GL_MAJOR
-#undef DEFAULT_GL_MINOR
-#undef DEFAULT_GLES_MAJOR
-#undef DEFAULT_GLES_MINOR
-#undef DEFAULT_GLES2_MAJOR
-#undef DEFAULT_GLES2_MINOR
 #endif
 
 	setContextType(glContextType);
@@ -217,7 +215,7 @@ void OpenGLSdlGraphicsManager::deactivateManager() {
 	SdlGraphicsManager::deactivateManager();
 }
 
-bool OpenGLSdlGraphicsManager::hasFeature(OSystem::Feature f) {
+bool OpenGLSdlGraphicsManager::hasFeature(OSystem::Feature f) const {
 	switch (f) {
 	case OSystem::kFeatureFullscreenMode:
 	case OSystem::kFeatureIconifyWindow:
@@ -246,7 +244,7 @@ void OpenGLSdlGraphicsManager::setFeatureState(OSystem::Feature f, bool enable)
 	}
 }
 
-bool OpenGLSdlGraphicsManager::getFeatureState(OSystem::Feature f) {
+bool OpenGLSdlGraphicsManager::getFeatureState(OSystem::Feature f) const {
 	switch (f) {
 	case OSystem::kFeatureFullscreenMode:
 #if SDL_VERSION_ATLEAST(2, 0, 0)
@@ -344,7 +342,7 @@ void OpenGLSdlGraphicsManager::updateScreen() {
 void OpenGLSdlGraphicsManager::notifyVideoExpose() {
 }
 
-void OpenGLSdlGraphicsManager::notifyResize(const uint width, const uint height) {
+void OpenGLSdlGraphicsManager::notifyResize(const int width, const int height) {
 #if SDL_VERSION_ATLEAST(2, 0, 0)
 	// We sometime get outdated resize events from SDL2. So check that the size we get
 	// is the actual current window size. If not ignore the resize.
@@ -354,11 +352,10 @@ void OpenGLSdlGraphicsManager::notifyResize(const uint width, const uint height)
 	// causes a SDL_WINDOWEVENT_RESIZED event with the old resolution to be sent, and this
 	// event is processed after recreating the window at the new resolution.
 	int currentWidth, currentHeight;
-	getWindowDimensions(&currentWidth, &currentHeight);
-	if (width != (uint)currentWidth || height != (uint)currentHeight)
+	getWindowSizeFromSdl(&currentWidth, &currentHeight);
+	if (width != currentWidth || height != currentHeight)
 		return;
-	setActualScreenSize(width, height);
-	_eventSource->resetKeyboardEmulation(width - 1, height - 1);
+	handleResize(width, height);
 #else
 	if (!_ignoreResizeEvents && _hwScreen && !(_hwScreen->flags & SDL_FULLSCREEN)) {
 		// We save that we handled a resize event here. We need to know this
@@ -373,18 +370,6 @@ void OpenGLSdlGraphicsManager::notifyResize(const uint width, const uint height)
 #endif
 }
 
-void OpenGLSdlGraphicsManager::transformMouseCoordinates(Common::Point &point) {
-	adjustMousePosition(point.x, point.y);
-}
-
-void OpenGLSdlGraphicsManager::notifyMousePos(Common::Point mouse) {
-	setMousePosition(mouse.x, mouse.y);
-}
-
-void OpenGLSdlGraphicsManager::setInternalMousePosition(int x, int y) {
-	_window->warpMouseInWindow(x, y);
-}
-
 bool OpenGLSdlGraphicsManager::loadVideoMode(uint requestedWidth, uint requestedHeight, const Graphics::PixelFormat &format) {
 	// In some cases we might not want to load the requested video mode. This
 	// will assure that the window size is not altered.
@@ -422,6 +407,11 @@ void *OpenGLSdlGraphicsManager::getProcAddress(const char *name) const {
 	return SDL_GL_GetProcAddress(name);
 }
 
+void OpenGLSdlGraphicsManager::handleResizeImpl(const int width, const int height) {
+	OpenGLGraphicsManager::handleResizeImpl(width, height);
+	SdlGraphicsManager::handleResizeImpl(width, height);
+}
+
 bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
 	// In case we request a fullscreen mode we will use the mode the user
 	// has chosen last time or the biggest mode available.
@@ -517,9 +507,8 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
 
 	notifyContextCreate(rgba8888, rgba8888);
 	int actualWidth, actualHeight;
-	getWindowDimensions(&actualWidth, &actualHeight);
-	setActualScreenSize(actualWidth, actualHeight);
-	_eventSource->resetKeyboardEmulation(actualWidth - 1, actualHeight - 1);
+	getWindowSizeFromSdl(&actualWidth, &actualHeight);
+	handleResize(actualWidth, actualHeight);
 	return true;
 #else
 	// WORKAROUND: Working around infamous SDL bugs when switching
@@ -566,8 +555,7 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
 
 	if (_hwScreen) {
 		notifyContextCreate(rgba8888, rgba8888);
-		setActualScreenSize(_hwScreen->w, _hwScreen->h);
-		_eventSource->resetKeyboardEmulation(_hwScreen->w - 1, _hwScreen->h - 1);
+		handleResize(_hwScreen->w, _hwScreen->h);
 	}
 
 	// Ignore resize events (from SDL) for a few frames, if this isn't
@@ -580,20 +568,6 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
 #endif
 }
 
-void OpenGLSdlGraphicsManager::getWindowDimensions(int *width, int *height) {
-#if SDL_VERSION_ATLEAST(2, 0, 0)
-	SDL_GetWindowSize(_window->getSDLWindow(), width, height);
-#else
-	if (width) {
-		*width = _hwScreen->w;
-	}
-
-	if (height) {
-		*height = _hwScreen->h;
-	}
-#endif
-}
-
 bool OpenGLSdlGraphicsManager::notifyEvent(const Common::Event &event) {
 	switch (event.type) {
 	case Common::EVENT_KEYUP:
@@ -707,7 +681,7 @@ bool OpenGLSdlGraphicsManager::notifyEvent(const Common::Event &event) {
 					// current scale setting in case the user resized the
 					// window. Then we apply the direction change.
 					int windowWidth = 0, windowHeight = 0;
-					getWindowDimensions(&windowWidth, &windowHeight);
+					getWindowSizeFromSdl(&windowWidth, &windowHeight);
 					_graphicsScale = MAX<int>(windowWidth / _lastRequestedWidth, windowHeight / _lastRequestedHeight);
 					_graphicsScale = MAX<int>(_graphicsScale + direction, 1);
 
@@ -725,7 +699,7 @@ bool OpenGLSdlGraphicsManager::notifyEvent(const Common::Event &event) {
 
 #ifdef USE_OSD
 				int windowWidth = 0, windowHeight = 0;
-				getWindowDimensions(&windowWidth, &windowHeight);
+				getWindowSizeFromSdl(&windowWidth, &windowHeight);
 				const Common::String osdMsg = Common::String::format(_("Resolution: %dx%d"), windowWidth, windowHeight);
 				displayMessageOnOSD(osdMsg.c_str());
 #endif
@@ -785,7 +759,7 @@ bool OpenGLSdlGraphicsManager::notifyEvent(const Common::Event &event) {
 	}
 }
 
-bool OpenGLSdlGraphicsManager::isHotkey(const Common::Event &event) {
+bool OpenGLSdlGraphicsManager::isHotkey(const Common::Event &event) const {
 	if (event.kbd.hasFlags(Common::KBD_ALT)) {
 		return    event.kbd.keycode == Common::KEYCODE_RETURN
 		       || event.kbd.keycode == (Common::KeyCode)SDLK_KP_ENTER
diff --git a/backends/graphics/openglsdl/openglsdl-graphics.h b/backends/graphics/openglsdl/openglsdl-graphics.h
index c5003d8..954c721 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.h
+++ b/backends/graphics/openglsdl/openglsdl-graphics.h
@@ -36,38 +36,37 @@ public:
 	virtual ~OpenGLSdlGraphicsManager();
 
 	// GraphicsManager API
-	virtual void activateManager();
-	virtual void deactivateManager();
+	virtual void activateManager() override;
+	virtual void deactivateManager() override;
 
-	virtual bool hasFeature(OSystem::Feature f);
-	virtual void setFeatureState(OSystem::Feature f, bool enable);
-	virtual bool getFeatureState(OSystem::Feature f);
+	virtual bool hasFeature(OSystem::Feature f) const override;
+	virtual void setFeatureState(OSystem::Feature f, bool enable) override;
+	virtual bool getFeatureState(OSystem::Feature f) const override;
 
 	virtual void initSize(uint w, uint h, const Graphics::PixelFormat *format) override;
 
 #ifdef USE_RGB_COLOR
-	virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const;
+	virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const override;
 #endif
 
-	virtual void updateScreen();
+	virtual void updateScreen() override;
 
 	// EventObserver API
-	virtual bool notifyEvent(const Common::Event &event);
+	virtual bool notifyEvent(const Common::Event &event) override;
 
 	// SdlGraphicsManager API
-	virtual void notifyVideoExpose();
-	virtual void notifyResize(const uint width, const uint height);
-	virtual void transformMouseCoordinates(Common::Point &point);
-	virtual void notifyMousePos(Common::Point mouse);
+	virtual void notifyVideoExpose() override;
+	virtual void notifyResize(const int width, const int height) override;
 
 protected:
-	virtual void setInternalMousePosition(int x, int y);
+	virtual bool loadVideoMode(uint requestedWidth, uint requestedHeight, const Graphics::PixelFormat &format) override;
 
-	virtual bool loadVideoMode(uint requestedWidth, uint requestedHeight, const Graphics::PixelFormat &format);
+	virtual void refreshScreen() override;
 
-	virtual void refreshScreen();
+	virtual void *getProcAddress(const char *name) const override;
+
+	virtual void handleResizeImpl(const int width, const int height) override;
 
-	virtual void *getProcAddress(const char *name) const;
 	virtual int getGraphicsModeScale(int mode) const override { return 1; }
 
 private:
@@ -78,11 +77,8 @@ private:
 	SDL_GLContext _glContext;
 #else
 	uint32 _lastVideoModeLoad;
-	SDL_Surface *_hwScreen;
 #endif
 
-	void getWindowDimensions(int *width, int *height);
-
 	uint _lastRequestedWidth;
 	uint _lastRequestedHeight;
 	uint _graphicsScale;
@@ -122,7 +118,7 @@ private:
 	uint _desiredFullscreenWidth;
 	uint _desiredFullscreenHeight;
 
-	virtual bool isHotkey(const Common::Event &event);
+	bool isHotkey(const Common::Event &event) const;
 };
 
 #endif
diff --git a/backends/graphics/sdl/sdl-graphics.cpp b/backends/graphics/sdl/sdl-graphics.cpp
index a181582..ea947c1 100644
--- a/backends/graphics/sdl/sdl-graphics.cpp
+++ b/backends/graphics/sdl/sdl-graphics.cpp
@@ -28,15 +28,11 @@
 #include "graphics/scaler/aspect.h"
 
 SdlGraphicsManager::SdlGraphicsManager(SdlEventSource *source, SdlWindow *window)
-	: _eventSource(source), _window(window)
+	: _eventSource(source), _window(window), _hwScreen(nullptr)
 #if SDL_VERSION_ATLEAST(2, 0, 0)
 	, _allowWindowSizeReset(false), _hintedWidth(0), _hintedHeight(0), _lastFlags(0)
 #endif
-	  {
-}
-
-SdlGraphicsManager::~SdlGraphicsManager() {
-}
+{}
 
 void SdlGraphicsManager::activateManager() {
 	_eventSource->setGraphicsManager(this);
@@ -46,7 +42,7 @@ void SdlGraphicsManager::deactivateManager() {
 	_eventSource->setGraphicsManager(0);
 }
 
-SdlGraphicsManager::State SdlGraphicsManager::getState() {
+SdlGraphicsManager::State SdlGraphicsManager::getState() const {
 	State state;
 
 	state.screenWidth   = getWidth();
@@ -152,6 +148,32 @@ void SdlGraphicsManager::initSizeHint(const Graphics::ModeList &modes) {
 #endif
 }
 
+void SdlGraphicsManager::notifyMousePosition(Common::Point &mouse) {
+	int showCursor;
+	if (_activeArea.drawRect.contains(mouse)) {
+		showCursor = SDL_DISABLE;
+	} else {
+		mouse.x = CLIP<int>(mouse.x, _activeArea.drawRect.left, _activeArea.drawRect.right - 1);
+		mouse.y = CLIP<int>(mouse.y, _activeArea.drawRect.top, _activeArea.drawRect.bottom - 1);
+
+		if (_window->mouseIsGrabbed()) {
+			setSystemMousePosition(mouse.x, mouse.y);
+			showCursor = SDL_DISABLE;
+		} else {
+			showCursor = SDL_ENABLE;
+		}
+	}
+
+	SDL_ShowCursor(showCursor);
+	setMousePosition(mouse.x, mouse.y);
+	mouse = convertWindowToVirtual(mouse.x, mouse.y);
+}
+
+void SdlGraphicsManager::handleResizeImpl(const int width, const int height) {
+	_eventSource->resetKeyboardEmulation(width - 1, height - 1);
+	_forceRedraw = true;
+}
+
 #if SDL_VERSION_ATLEAST(2, 0, 0)
 bool SdlGraphicsManager::createOrUpdateWindow(int width, int height, const Uint32 flags) {
 	if (!_window) {
diff --git a/backends/graphics/sdl/sdl-graphics.h b/backends/graphics/sdl/sdl-graphics.h
index ce282d8..886070a 100644
--- a/backends/graphics/sdl/sdl-graphics.h
+++ b/backends/graphics/sdl/sdl-graphics.h
@@ -23,7 +23,7 @@
 #ifndef BACKENDS_GRAPHICS_SDL_SDLGRAPHICS_H
 #define BACKENDS_GRAPHICS_SDL_SDLGRAPHICS_H
 
-#include "backends/graphics/graphics.h"
+#include "backends/graphics/windowed.h"
 #include "backends/platform/sdl/sdl-window.h"
 
 #include "common/rect.h"
@@ -32,13 +32,11 @@ class SdlEventSource;
 
 /**
  * Base class for a SDL based graphics manager.
- *
- * It features a few extra a few extra features required by SdlEventSource.
  */
-class SdlGraphicsManager : virtual public GraphicsManager {
+class SdlGraphicsManager : virtual public WindowedGraphicsManager {
 public:
 	SdlGraphicsManager(SdlEventSource *source, SdlWindow *window);
-	virtual ~SdlGraphicsManager();
+	virtual ~SdlGraphicsManager() {}
 
 	/**
 	 * Makes this graphics manager active. That means it should be ready to
@@ -74,23 +72,20 @@ public:
 	 * @param width Requested window width.
 	 * @param height Requested window height.
 	 */
-	virtual void notifyResize(const uint width, const uint height) {}
+	virtual void notifyResize(const int width, const int height) {}
 
 	/**
-	 * Transforms real screen coordinates into the current active screen
-	 * coordinates (may be either game screen or overlay).
+	 * Notifies the graphics manager about a mouse position change.
 	 *
-	 * @param point Mouse coordinates to transform.
-	 */
-	virtual void transformMouseCoordinates(Common::Point &point) = 0;
-
-	/**
-	 * Notifies the graphics manager about a position change according to the
-	 * real screen coordinates.
+	 * The passed point *must* be converted from window coordinates to virtual
+	 * coordinates in order for the event to be processed correctly by the game
+	 * engine. Just use `convertWindowToVirtual` for this unless you need to do
+	 * something special.
 	 *
-	 * @param mouse Mouse position.
+	 * @param mouse The mouse position in window coordinates, which must be
+	 * converted synchronously to virtual coordinates.
 	 */
-	virtual void notifyMousePos(Common::Point mouse) = 0;
+	virtual void notifyMousePosition(Common::Point &mouse);
 
 	/**
 	 * A (subset) of the graphic manager's state. This is used when switching
@@ -108,17 +103,17 @@ public:
 	};
 
 	/**
-	 * Queries the current state of the graphic manager.
+	 * Gets the current state of the graphics manager.
 	 */
-	State getState();
+	State getState() const;
 
 	/**
-	 * Setup a basic state of the graphic manager.
+	 * Sets up a basic state of the graphics manager.
 	 */
 	bool setState(const State &state);
 
 	/**
-	 * Queries the SDL window.
+	 * @returns the SDL window.
 	 */
 	SdlWindow *getWindow() const { return _window; }
 
@@ -130,6 +125,34 @@ protected:
 	bool defaultGraphicsModeConfig() const;
 	int getGraphicsModeIdByName(const Common::String &name) const;
 
+	/**
+	 * Gets the dimensions of the window directly from SDL instead of from the
+	 * values stored by the graphics manager.
+	 */
+	void getWindowSizeFromSdl(int *width, int *height) const {
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+		assert(_window);
+		SDL_GetWindowSize(_window->getSDLWindow(), width, height);
+#else
+		assert(_hwScreen);
+
+		if (width) {
+			*width = _hwScreen->w;
+		}
+
+		if (height) {
+			*height = _hwScreen->h;
+		}
+#endif
+	}
+
+	virtual void setSystemMousePosition(const int x, const int y) override {
+		assert(_window);
+		_window->warpMouseInWindow(x, y);
+	}
+
+	virtual void handleResizeImpl(const int width, const int height) override;
+
 #if SDL_VERSION_ATLEAST(2, 0, 0)
 public:
 	void unlockWindowSize() {
@@ -146,6 +169,7 @@ protected:
 	bool createOrUpdateWindow(const int width, const int height, const Uint32 flags);
 #endif
 
+	SDL_Surface *_hwScreen;
 	SdlEventSource *_eventSource;
 	SdlWindow *_window;
 };
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
index fb98709..52104ff 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
@@ -23,7 +23,6 @@
 #include "common/scummsys.h"
 
 #if defined(SDL_BACKEND)
-
 #include "backends/graphics/surfacesdl/surfacesdl-graphics.h"
 #include "backends/events/sdl/sdl-events.h"
 #include "backends/platform/sdl/sdl.h"
@@ -133,10 +132,8 @@ SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSou
 	_osdMessageSurface(nullptr), _osdMessageAlpha(SDL_ALPHA_TRANSPARENT), _osdMessageFadeStartTime(0),
 	_osdIconSurface(nullptr),
 #endif
-	_hwscreen(0),
 #if SDL_VERSION_ATLEAST(2, 0, 0)
 	_renderer(nullptr), _screenTexture(nullptr),
-	_viewport(), _windowWidth(1), _windowHeight(1),
 #endif
 #if defined(WIN32) && !SDL_VERSION_ATLEAST(2, 0, 0)
 	_originalBitsPerPixel(0),
@@ -146,10 +143,9 @@ SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSou
 	_screenFormat(Graphics::PixelFormat::createFormatCLUT8()),
 	_cursorFormat(Graphics::PixelFormat::createFormatCLUT8()),
 #endif
-	_overlayVisible(false),
 	_overlayscreen(0), _tmpscreen2(0),
 	_scalerProc(0), _screenChangeCount(0),
-	_mouseVisible(false), _mouseNeedsRedraw(false), _mouseData(0), _mouseSurface(0),
+	_mouseVisible(false), _mouseData(0), _mouseSurface(0),
 	_mouseOrigSurface(0), _cursorDontScale(false), _cursorPaletteDisabled(true),
 	_currentShakePos(0), _newShakePos(0),
 	_paletteDirtyStart(0), _paletteDirtyEnd(0),
@@ -247,7 +243,7 @@ void SurfaceSdlGraphicsManager::deactivateManager() {
 	SdlGraphicsManager::deactivateManager();
 }
 
-bool SurfaceSdlGraphicsManager::hasFeature(OSystem::Feature f) {
+bool SurfaceSdlGraphicsManager::hasFeature(OSystem::Feature f) const {
 	return
 		(f == OSystem::kFeatureFullscreenMode) ||
 		(f == OSystem::kFeatureAspectRatioCorrection) ||
@@ -284,7 +280,7 @@ void SurfaceSdlGraphicsManager::setFeatureState(OSystem::Feature f, bool enable)
 	}
 }
 
-bool SurfaceSdlGraphicsManager::getFeatureState(OSystem::Feature f) {
+bool SurfaceSdlGraphicsManager::getFeatureState(OSystem::Feature f) const {
 	// We need to allow this to be called from within a transaction, since we
 	// currently use it to retreive the graphics state, when switching from
 	// SDL->OpenGL mode for example.
@@ -555,16 +551,16 @@ void SurfaceSdlGraphicsManager::detectSupportedFormats() {
 		Graphics::PixelFormat(2, 4, 4, 4, 4, 4, 8, 12, 0)
 	};
 
-	if (_hwscreen) {
+	if (_hwScreen) {
 		// Get our currently set hardware format
-		Graphics::PixelFormat hwFormat(_hwscreen->format->BytesPerPixel,
-			8 - _hwscreen->format->Rloss, 8 - _hwscreen->format->Gloss,
-			8 - _hwscreen->format->Bloss, 8 - _hwscreen->format->Aloss,
-			_hwscreen->format->Rshift, _hwscreen->format->Gshift,
-			_hwscreen->format->Bshift, _hwscreen->format->Ashift);
+		Graphics::PixelFormat hwFormat(_hwScreen->format->BytesPerPixel,
+			8 - _hwScreen->format->Rloss, 8 - _hwScreen->format->Gloss,
+			8 - _hwScreen->format->Bloss, 8 - _hwScreen->format->Aloss,
+			_hwScreen->format->Rshift, _hwScreen->format->Gshift,
+			_hwScreen->format->Bshift, _hwScreen->format->Ashift);
 
 		// Workaround to SDL not providing an accurate Aloss value on Mac OS X.
-		if (_hwscreen->format->Amask == 0)
+		if (_hwScreen->format->Amask == 0)
 			hwFormat.aLoss = 8;
 
 		_supportedFormats.push_back(hwFormat);
@@ -579,7 +575,7 @@ void SurfaceSdlGraphicsManager::detectSupportedFormats() {
 
 	// Push some RGB formats
 	for (i = 0; i < ARRAYSIZE(RGBList); i++) {
-		if (_hwscreen && (RGBList[i].bytesPerPixel > format.bytesPerPixel))
+		if (_hwScreen && (RGBList[i].bytesPerPixel > format.bytesPerPixel))
 			continue;
 		if (RGBList[i] != format)
 			_supportedFormats.push_back(RGBList[i]);
@@ -587,7 +583,7 @@ void SurfaceSdlGraphicsManager::detectSupportedFormats() {
 
 	// Push some BGR formats
 	for (i = 0; i < ARRAYSIZE(BGRList); i++) {
-		if (_hwscreen && (BGRList[i].bytesPerPixel > format.bytesPerPixel))
+		if (_hwScreen && (BGRList[i].bytesPerPixel > format.bytesPerPixel))
 			continue;
 		if (BGRList[i] != format)
 			_supportedFormats.push_back(BGRList[i]);
@@ -722,11 +718,11 @@ void SurfaceSdlGraphicsManager::setGraphicsModeIntern() {
 		}
 	}
 
-	if (!_screen || !_hwscreen)
+	if (!_screen || !_hwScreen)
 		return;
 
 	// Blit everything to the screen
-	_forceFull = true;
+	_forceRedraw = true;
 
 	// Even if the old and new scale factors are the same, we may have a
 	// different scaler for the cursor now.
@@ -797,13 +793,6 @@ void SurfaceSdlGraphicsManager::initSize(uint w, uint h, const Graphics::PixelFo
 	_transactionDetails.sizeChanged = true;
 }
 
-int SurfaceSdlGraphicsManager::effectiveScreenHeight() const {
-	return _videoMode.scaleFactor *
-				(_videoMode.aspectRatioCorrection
-					? real2Aspect(_videoMode.screenHeight)
-					: _videoMode.screenHeight);
-}
-
 static void fixupResolutionForAspectRatio(AspectRatio desiredAspectRatio, int &width, int &height) {
 	assert(&width != &height);
 
@@ -864,7 +853,7 @@ static void fixupResolutionForAspectRatio(AspectRatio desiredAspectRatio, int &w
 }
 
 bool SurfaceSdlGraphicsManager::loadGFXMode() {
-	_forceFull = true;
+	_forceRedraw = true;
 
 #if !defined(__MAEMO__) && !defined(DINGUX) && !defined(GPH_DEVICE) && !defined(LINUXMOTO) && !defined(OPENPANDORA)
 	_videoMode.overlayWidth = _videoMode.screenWidth * _videoMode.scaleFactor;
@@ -873,11 +862,14 @@ bool SurfaceSdlGraphicsManager::loadGFXMode() {
 	if (_videoMode.screenHeight != 200 && _videoMode.screenHeight != 400)
 		_videoMode.aspectRatioCorrection = false;
 
-	if (_videoMode.aspectRatioCorrection)
+	_videoMode.hardwareWidth = _videoMode.screenWidth * _videoMode.scaleFactor;
+	_videoMode.hardwareHeight = _videoMode.screenHeight * _videoMode.scaleFactor;
+
+	if (_videoMode.aspectRatioCorrection) {
 		_videoMode.overlayHeight = real2Aspect(_videoMode.overlayHeight);
+		_videoMode.hardwareHeight = real2Aspect(_videoMode.hardwareHeight);
+	}
 
-	_videoMode.hardwareWidth = _videoMode.screenWidth * _videoMode.scaleFactor;
-	_videoMode.hardwareHeight = effectiveScreenHeight();
 // On GPH devices ALL the _videoMode.hardware... are setup in GPHGraphicsManager::loadGFXMode()
 #elif !defined(GPH_DEVICE)
 	_videoMode.hardwareWidth = _videoMode.overlayWidth;
@@ -924,7 +916,7 @@ bool SurfaceSdlGraphicsManager::loadGFXMode() {
 	_displayDisabled = ConfMan.getBool("disable_display");
 
 	if (_displayDisabled) {
-		_hwscreen = g_eventRec.getSurface(_videoMode.hardwareWidth, _videoMode.hardwareHeight);
+		_hwScreen = g_eventRec.getSurface(_videoMode.hardwareWidth, _videoMode.hardwareHeight);
 	} else
 #endif
 	{
@@ -937,7 +929,7 @@ bool SurfaceSdlGraphicsManager::loadGFXMode() {
 		}
 #endif
 
-		_hwscreen = SDL_SetVideoMode(_videoMode.hardwareWidth, _videoMode.hardwareHeight, 16,
+		_hwScreen = SDL_SetVideoMode(_videoMode.hardwareWidth, _videoMode.hardwareHeight, 16,
 			_videoMode.fullscreen ? (SDL_FULLSCREEN|SDL_SWSURFACE) : SDL_SWSURFACE
 			);
 	}
@@ -946,9 +938,9 @@ bool SurfaceSdlGraphicsManager::loadGFXMode() {
 	detectSupportedFormats();
 #endif
 
-	if (_hwscreen == NULL) {
+	if (_hwScreen == NULL) {
 		// DON'T use error(), as this tries to bring up the debug
-		// console, which WON'T WORK now that _hwscreen is hosed.
+		// console, which WON'T WORK now that _hwScreen is hosed.
 
 		if (!_oldVideoMode.setup) {
 			warning("SDL_SetVideoMode says we can't switch to that mode (%s)", SDL_GetError());
@@ -958,6 +950,10 @@ bool SurfaceSdlGraphicsManager::loadGFXMode() {
 		}
 	}
 
+#if !SDL_VERSION_ATLEAST(2, 0, 0)
+	handleResize(_videoMode.hardwareWidth, _videoMode.hardwareHeight);
+#endif
+
 	//
 	// Create the surface used for the graphics in 16 bit before scaling, and also the overlay
 	//
@@ -965,20 +961,20 @@ bool SurfaceSdlGraphicsManager::loadGFXMode() {
 	// Need some extra bytes around when using 2xSaI
 	_tmpscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth + 3, _videoMode.screenHeight + 3,
 						16,
-						_hwscreen->format->Rmask,
-						_hwscreen->format->Gmask,
-						_hwscreen->format->Bmask,
-						_hwscreen->format->Amask);
+						_hwScreen->format->Rmask,
+						_hwScreen->format->Gmask,
+						_hwScreen->format->Bmask,
+						_hwScreen->format->Amask);
 
 	if (_tmpscreen == NULL)
 		error("allocating _tmpscreen failed");
 
 	_overlayscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth, _videoMode.overlayHeight,
 						16,
-						_hwscreen->format->Rmask,
-						_hwscreen->format->Gmask,
-						_hwscreen->format->Bmask,
-						_hwscreen->format->Amask);
+						_hwScreen->format->Rmask,
+						_hwScreen->format->Gmask,
+						_hwScreen->format->Bmask,
+						_hwScreen->format->Amask);
 
 	if (_overlayscreen == NULL)
 		error("allocating _overlayscreen failed");
@@ -997,25 +993,16 @@ bool SurfaceSdlGraphicsManager::loadGFXMode() {
 
 	_tmpscreen2 = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth + 3, _videoMode.overlayHeight + 3,
 						16,
-						_hwscreen->format->Rmask,
-						_hwscreen->format->Gmask,
-						_hwscreen->format->Bmask,
-						_hwscreen->format->Amask);
+						_hwScreen->format->Rmask,
+						_hwScreen->format->Gmask,
+						_hwScreen->format->Bmask,
+						_hwScreen->format->Amask);
 
 	if (_tmpscreen2 == NULL)
 		error("allocating _tmpscreen2 failed");
 
-#if !SDL_VERSION_ATLEAST(2, 0, 0)
-	// For SDL2 the output resolution might differ from the requested
-	// resolution. We handle resetting the keyboard emulation properly inside
-	// our SDL_SetVideoMode wrapper for SDL2.
-	_eventSource->resetKeyboardEmulation(
-		_videoMode.screenWidth * _videoMode.scaleFactor - 1,
-		effectiveScreenHeight() - 1);
-#endif
-
 	// Distinguish 555 and 565 mode
-	if (_hwscreen->format->Rmask == 0x7C00)
+	if (_hwScreen->format->Rmask == 0x7C00)
 		InitScalers(555);
 	else
 		InitScalers(565);
@@ -1033,9 +1020,9 @@ void SurfaceSdlGraphicsManager::unloadGFXMode() {
 	deinitializeRenderer();
 #endif
 
-	if (_hwscreen) {
-		SDL_FreeSurface(_hwscreen);
-		_hwscreen = NULL;
+	if (_hwScreen) {
+		SDL_FreeSurface(_hwScreen);
+		_hwScreen = NULL;
 	}
 
 	if (_tmpscreen) {
@@ -1087,9 +1074,9 @@ bool SurfaceSdlGraphicsManager::hotswapGFXMode() {
 	_overlayscreen = NULL;
 
 	// Release the HW screen surface
-	if (_hwscreen) {
-		SDL_FreeSurface(_hwscreen);
-		_hwscreen = NULL;
+	if (_hwScreen) {
+		SDL_FreeSurface(_hwScreen);
+		_hwScreen = NULL;
 	}
 	if (_tmpscreen) {
 		SDL_FreeSurface(_tmpscreen);
@@ -1155,25 +1142,19 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
 	ScalerProc *scalerProc;
 	int scale1;
 
-	// definitions not available for non-DEBUG here. (needed this to compile in SYMBIAN32 & linux?)
-#if defined(DEBUG) && !defined(WIN32) && !defined(_WIN32_WCE)
-	assert(_hwscreen != NULL);
-	assert(_hwscreen->map->sw_data != NULL);
-#endif
-
 	// If the shake position changed, fill the dirty area with blackness
 	if (_currentShakePos != _newShakePos ||
-		(_mouseNeedsRedraw && _mouseBackup.y <= _currentShakePos)) {
+		(_cursorNeedsRedraw && _mouseBackup.y <= _currentShakePos)) {
 		SDL_Rect blackrect = {0, 0, (Uint16)(_videoMode.screenWidth * _videoMode.scaleFactor), (Uint16)(_newShakePos * _videoMode.scaleFactor)};
 
 		if (_videoMode.aspectRatioCorrection && !_overlayVisible)
 			blackrect.h = real2Aspect(blackrect.h - 1) + 1;
 
-		SDL_FillRect(_hwscreen, &blackrect, 0);
+		SDL_FillRect(_hwScreen, &blackrect, 0);
 
 		_currentShakePos = _newShakePos;
 
-		_forceFull = true;
+		_forceRedraw = true;
 	}
 
 	// Check whether the palette was changed in the meantime and update the
@@ -1185,7 +1166,7 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
 
 		_paletteDirtyEnd = 0;
 
-		_forceFull = true;
+		_forceRedraw = true;
 	}
 
 	if (!_overlayVisible) {
@@ -1207,7 +1188,7 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
 
 	// Add the area covered by the mouse cursor to the list of dirty rects if
 	// we have to redraw the mouse.
-	if (_mouseNeedsRedraw)
+	if (_cursorNeedsRedraw)
 		undrawMouse();
 
 #ifdef USE_OSD
@@ -1215,7 +1196,7 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
 #endif
 
 	// Force a full redraw if requested
-	if (_forceFull) {
+	if (_forceRedraw) {
 		_numDirtyRects = 1;
 		_dirtyRectList[0].x = 0;
 		_dirtyRectList[0].y = 0;
@@ -1224,7 +1205,7 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
 	}
 
 	// Only draw anything if necessary
-	if (_numDirtyRects > 0 || _mouseNeedsRedraw) {
+	if (_numDirtyRects > 0 || _cursorNeedsRedraw) {
 		SDL_Rect *r;
 		SDL_Rect dst;
 		uint32 srcPitch, dstPitch;
@@ -1240,10 +1221,10 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
 		}
 
 		SDL_LockSurface(srcSurf);
-		SDL_LockSurface(_hwscreen);
+		SDL_LockSurface(_hwScreen);
 
 		srcPitch = srcSurf->pitch;
-		dstPitch = _hwscreen->pitch;
+		dstPitch = _hwScreen->pitch;
 
 		for (r = _dirtyRectList; r != lastRect; ++r) {
 			register int dst_y = r->y + _currentShakePos;
@@ -1268,7 +1249,7 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
 
 				assert(scalerProc != NULL);
 				scalerProc((byte *)srcSurf->pixels + (r->x * 2 + 2) + (r->y + 1) * srcPitch, srcPitch,
-					(byte *)_hwscreen->pixels + rx1 * 2 + dst_y * dstPitch, dstPitch, r->w, dst_h);
+					(byte *)_hwScreen->pixels + rx1 * 2 + dst_y * dstPitch, dstPitch, r->w, dst_h);
 			}
 
 			r->x = rx1;
@@ -1278,17 +1259,17 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
 
 #ifdef USE_SCALERS
 			if (_videoMode.aspectRatioCorrection && orig_dst_y < height && !_overlayVisible)
-				r->h = stretch200To240((uint8 *) _hwscreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y * scale1);
+				r->h = stretch200To240((uint8 *) _hwScreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y * scale1);
 #endif
 		}
 		SDL_UnlockSurface(srcSurf);
-		SDL_UnlockSurface(_hwscreen);
+		SDL_UnlockSurface(_hwScreen);
 
 		// Readjust the dirty rect list in case we are doing a full update.
 		// This is necessary if shaking is active.
-		if (_forceFull) {
+		if (_forceRedraw) {
 			_dirtyRectList[0].y = 0;
-			_dirtyRectList[0].h = effectiveScreenHeight();
+			_dirtyRectList[0].h = _videoMode.hardwareHeight;
 		}
 
 		drawMouse();
@@ -1318,18 +1299,18 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
 					y = real2Aspect(y);
 
 				if (h > 0 && w > 0) {
-					SDL_LockSurface(_hwscreen);
+					SDL_LockSurface(_hwScreen);
 
 					// Use white as color for now.
-					Uint32 rectColor = SDL_MapRGB(_hwscreen->format, 0xFF, 0xFF, 0xFF);
+					Uint32 rectColor = SDL_MapRGB(_hwScreen->format, 0xFF, 0xFF, 0xFF);
 
 					// First draw the top and bottom lines
 					// then draw the left and right lines
-					if (_hwscreen->format->BytesPerPixel == 2) {
-						uint16 *top = (uint16 *)((byte *)_hwscreen->pixels + y * _hwscreen->pitch + x * 2);
-						uint16 *bottom = (uint16 *)((byte *)_hwscreen->pixels + (y + h) * _hwscreen->pitch + x * 2);
-						byte *left = ((byte *)_hwscreen->pixels + y * _hwscreen->pitch + x * 2);
-						byte *right = ((byte *)_hwscreen->pixels + y * _hwscreen->pitch + (x + w - 1) * 2);
+					if (_hwScreen->format->BytesPerPixel == 2) {
+						uint16 *top = (uint16 *)((byte *)_hwScreen->pixels + y * _hwScreen->pitch + x * 2);
+						uint16 *bottom = (uint16 *)((byte *)_hwScreen->pixels + (y + h) * _hwScreen->pitch + x * 2);
+						byte *left = ((byte *)_hwScreen->pixels + y * _hwScreen->pitch + x * 2);
+						byte *right = ((byte *)_hwScreen->pixels + y * _hwScreen->pitch + (x + w - 1) * 2);
 
 						while (w--) {
 							*top++ = rectColor;
@@ -1340,14 +1321,14 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
 							*(uint16 *)left = rectColor;
 							*(uint16 *)right = rectColor;
 
-							left += _hwscreen->pitch;
-							right += _hwscreen->pitch;
+							left += _hwScreen->pitch;
+							right += _hwScreen->pitch;
 						}
-					} else if (_hwscreen->format->BytesPerPixel == 4) {
-						uint32 *top = (uint32 *)((byte *)_hwscreen->pixels + y * _hwscreen->pitch + x * 4);
-						uint32 *bottom = (uint32 *)((byte *)_hwscreen->pixels + (y + h) * _hwscreen->pitch + x * 4);
-						byte *left = ((byte *)_hwscreen->pixels + y * _hwscreen->pitch + x * 4);
-						byte *right = ((byte *)_hwscreen->pixels + y * _hwscreen->pitch + (x + w - 1) * 4);
+					} else if (_hwScreen->format->BytesPerPixel == 4) {
+						uint32 *top = (uint32 *)((byte *)_hwScreen->pixels + y * _hwScreen->pitch + x * 4);
+						uint32 *bottom = (uint32 *)((byte *)_hwScreen->pixels + (y + h) * _hwScreen->pitch + x * 4);
+						byte *left = ((byte *)_hwScreen->pixels + y * _hwScreen->pitch + x * 4);
+						byte *right = ((byte *)_hwScreen->pixels + y * _hwScreen->pitch + (x + w - 1) * 4);
 
 						while (w--) {
 							*top++ = rectColor;
@@ -1358,12 +1339,12 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
 							*(uint32 *)left = rectColor;
 							*(uint32 *)right = rectColor;
 
-							left += _hwscreen->pitch;
-							right += _hwscreen->pitch;
+							left += _hwScreen->pitch;
+							right += _hwScreen->pitch;
 						}
 					}
 
-					SDL_UnlockSurface(_hwscreen);
+					SDL_UnlockSurface(_hwScreen);
 				}
 			}
 		}
@@ -1371,17 +1352,17 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
 
 		// Finally, blit all our changes to the screen
 		if (!_displayDisabled) {
-			SDL_UpdateRects(_hwscreen, _numDirtyRects, _dirtyRectList);
+			SDL_UpdateRects(_hwScreen, _numDirtyRects, _dirtyRectList);
 		}
 	}
 
 	_numDirtyRects = 0;
-	_forceFull = false;
-	_mouseNeedsRedraw = false;
+	_forceRedraw = false;
+	_cursorNeedsRedraw = false;
 }
 
 bool SurfaceSdlGraphicsManager::saveScreenshot(const char *filename) {
-	assert(_hwscreen != NULL);
+	assert(_hwScreen != NULL);
 
 	Common::StackLock lock(_graphicsMutex);
 #ifdef USE_PNG
@@ -1391,12 +1372,12 @@ bool SurfaceSdlGraphicsManager::saveScreenshot(const char *filename) {
 	}
 
 #if SDL_VERSION_ATLEAST(2, 0, 0)
-	SDL_Surface *rgbScreen = SDL_ConvertSurfaceFormat(_hwscreen, SDL_PIXELFORMAT_RGB24, 0);
+	SDL_Surface *rgbScreen = SDL_ConvertSurfaceFormat(_hwScreen, SDL_PIXELFORMAT_RGB24, 0);
 #else
 	// This block of code was taken mostly as-is from SDL 1.2's SDL_SaveBMP_RW
 	SDL_Surface *rgbScreen = SDL_CreateRGBSurface(SDL_SWSURFACE,
-												  _hwscreen->w,
-												  _hwscreen->h,
+												  _hwScreen->w,
+												  _hwScreen->h,
 												  24,
 #ifdef SCUMM_LITTLE_ENDIAN
 												  0x0000FF, 0x00FF00, 0xFF0000,
@@ -1411,9 +1392,9 @@ bool SurfaceSdlGraphicsManager::saveScreenshot(const char *filename) {
 
 	SDL_Rect bounds;
 	bounds.x = bounds.y = 0;
-	bounds.w = _hwscreen->w;
-	bounds.h = _hwscreen->h;
-	if (SDL_LowerBlit(_hwscreen, &bounds, rgbScreen, &bounds) < 0) {
+	bounds.w = _hwScreen->w;
+	bounds.h = _hwScreen->h;
+	if (SDL_LowerBlit(_hwScreen, &bounds, rgbScreen, &bounds) < 0) {
 		SDL_FreeSurface(rgbScreen);
 		rgbScreen = nullptr;
 	}
@@ -1441,7 +1422,7 @@ bool SurfaceSdlGraphicsManager::saveScreenshot(const char *filename) {
 
 	return success;
 #else
-	return SDL_SaveBMP(_hwscreen, filename) == 0;
+	return SDL_SaveBMP(_hwScreen, filename) == 0;
 #endif
 }
 
@@ -1571,7 +1552,7 @@ void SurfaceSdlGraphicsManager::unlockScreen() {
 	SDL_UnlockSurface(_screen);
 
 	// Trigger a full screen update
-	_forceFull = true;
+	_forceRedraw = true;
 
 	// Finally unlock the graphics mutex
 	g_system->unlockMutex(_graphicsMutex);
@@ -1585,11 +1566,11 @@ void SurfaceSdlGraphicsManager::fillScreen(uint32 col) {
 }
 
 void SurfaceSdlGraphicsManager::addDirtyRect(int x, int y, int w, int h, bool realCoordinates) {
-	if (_forceFull)
+	if (_forceRedraw)
 		return;
 
 	if (_numDirtyRects == NUM_DIRTY_RECT) {
-		_forceFull = true;
+		_forceRedraw = true;
 		return;
 	}
 
@@ -1608,8 +1589,8 @@ void SurfaceSdlGraphicsManager::addDirtyRect(int x, int y, int w, int h, bool re
 	if (!realCoordinates) {
 		x--;
 		y--;
-		w+=2;
-		h+=2;
+		w += 2;
+		h += 2;
 	}
 
 	// clip
@@ -1620,7 +1601,7 @@ void SurfaceSdlGraphicsManager::addDirtyRect(int x, int y, int w, int h, bool re
 
 	if (y < 0) {
 		h += y;
-		y=0;
+		y = 0;
 	}
 
 	if (w > width - x) {
@@ -1638,7 +1619,7 @@ void SurfaceSdlGraphicsManager::addDirtyRect(int x, int y, int w, int h, bool re
 #endif
 
 	if (w == width && h == height) {
-		_forceFull = true;
+		_forceRedraw = true;
 		return;
 	}
 
@@ -1652,11 +1633,11 @@ void SurfaceSdlGraphicsManager::addDirtyRect(int x, int y, int w, int h, bool re
 	}
 }
 
-int16 SurfaceSdlGraphicsManager::getHeight() {
+int16 SurfaceSdlGraphicsManager::getHeight() const {
 	return _videoMode.screenHeight;
 }
 
-int16 SurfaceSdlGraphicsManager::getWidth() {
+int16 SurfaceSdlGraphicsManager::getWidth() const {
 	return _videoMode.screenWidth;
 }
 
@@ -1697,7 +1678,7 @@ void SurfaceSdlGraphicsManager::setPalette(const byte *colors, uint start, uint
 		blitCursor();
 }
 
-void SurfaceSdlGraphicsManager::grabPalette(byte *colors, uint start, uint num) {
+void SurfaceSdlGraphicsManager::grabPalette(byte *colors, uint start, uint num) const {
 	assert(colors);
 
 #ifdef USE_RGB_COLOR
@@ -1777,56 +1758,7 @@ void SurfaceSdlGraphicsManager::clearFocusRectangle() {
 #pragma mark --- Overlays ---
 #pragma mark -
 
-void SurfaceSdlGraphicsManager::showOverlay() {
-	assert(_transactionMode == kTransactionNone);
-
-	int x, y;
-
-	if (_overlayVisible)
-		return;
-
-	_overlayVisible = true;
-
-	// Since resolution could change, put mouse to adjusted position
-	// Fixes bug #1349059
-	x = _mouseCurState.x * _videoMode.scaleFactor;
-	if (_videoMode.aspectRatioCorrection)
-		y = real2Aspect(_mouseCurState.y) * _videoMode.scaleFactor;
-	else
-		y = _mouseCurState.y * _videoMode.scaleFactor;
-
-	warpMouse(x, y);
-
-	clearOverlay();
-}
-
-void SurfaceSdlGraphicsManager::hideOverlay() {
-	assert(_transactionMode == kTransactionNone);
-
-	if (!_overlayVisible)
-		return;
-
-	int x, y;
-
-	_overlayVisible = false;
-
-	// Since resolution could change, put mouse to adjusted position
-	// Fixes bug #1349059
-	x = _mouseCurState.x / _videoMode.scaleFactor;
-	y = _mouseCurState.y / _videoMode.scaleFactor;
-	if (_videoMode.aspectRatioCorrection)
-		y = aspect2Real(y);
-
-	warpMouse(x, y);
-
-	clearOverlay();
-
-	_forceFull = true;
-}
-
 void SurfaceSdlGraphicsManager::clearOverlay() {
-	//assert(_transactionMode == kTransactionNone);
-
 	Common::StackLock lock(_graphicsMutex);	// Lock the mutex until this function ends
 
 	if (!_overlayVisible)
@@ -1854,10 +1786,10 @@ void SurfaceSdlGraphicsManager::clearOverlay() {
 	SDL_UnlockSurface(_tmpscreen);
 	SDL_UnlockSurface(_overlayscreen);
 
-	_forceFull = true;
+	_forceRedraw = true;
 }
 
-void SurfaceSdlGraphicsManager::grabOverlay(void *buf, int pitch) {
+void SurfaceSdlGraphicsManager::grabOverlay(void *buf, int pitch) const {
 	assert(_transactionMode == kTransactionNone);
 
 	if (_overlayscreen == NULL)
@@ -1937,56 +1869,11 @@ bool SurfaceSdlGraphicsManager::showMouse(bool visible) {
 
 	bool last = _mouseVisible;
 	_mouseVisible = visible;
-	_mouseNeedsRedraw = true;
+	_cursorNeedsRedraw = true;
 
 	return last;
 }
 
-void SurfaceSdlGraphicsManager::setMousePos(int x, int y) {
-	if (x != _mouseCurState.x || y != _mouseCurState.y) {
-		_mouseNeedsRedraw = true;
-		_mouseCurState.x = x;
-		_mouseCurState.y = y;
-	}
-}
-
-void SurfaceSdlGraphicsManager::warpMouse(int x, int y) {
-	// Don't change actual mouse position, when mouse is outside of our window (in case of windowed mode)
-	if (!_window->hasMouseFocus()) {
-		setMousePos(x, y); // but change game cursor position
-		return;
-	}
-
-	int x1 = x, y1 = y;
-	if (_videoMode.aspectRatioCorrection && !_overlayVisible)
-		y1 = real2Aspect(y1);
-
-	if (_mouseCurState.x != x || _mouseCurState.y != y) {
-		if (!_overlayVisible) {
-			x1 *= _videoMode.scaleFactor;
-			y1 *= _videoMode.scaleFactor;
-		}
-
-#if SDL_VERSION_ATLEAST(2, 0, 0)
-		// Transform our coordinates in "virtual" output coordinate space into
-		// actual output coordinate space.
-		x1 = x1 * _windowWidth  / _videoMode.hardwareWidth;
-		y1 = y1 * _windowHeight / _videoMode.hardwareHeight;
-#endif
-
-		_window->warpMouseInWindow(x1, y1);
-
-		// SDL_WarpMouse() generates a mouse movement event, so
-		// setMousePos() would be called eventually. However, the
-		// cannon script in CoMI calls this function twice each time
-		// the cannon is reloaded. Unless we update the mouse position
-		// immediately the second call is ignored, causing the cannon
-		// to change its aim.
-
-		setMousePos(x, y);
-	}
-}
-
 void SurfaceSdlGraphicsManager::setMouseCursor(const void *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
 #ifdef USE_RGB_COLOR
 	if (!format)
@@ -2022,10 +1909,10 @@ void SurfaceSdlGraphicsManager::setMouseCursor(const void *buf, uint w, uint h,
 						_mouseCurState.w + 2,
 						_mouseCurState.h + 2,
 						16,
-						_hwscreen->format->Rmask,
-						_hwscreen->format->Gmask,
-						_hwscreen->format->Bmask,
-						_hwscreen->format->Amask);
+						_hwScreen->format->Rmask,
+						_hwScreen->format->Gmask,
+						_hwScreen->format->Bmask,
+						_hwScreen->format->Amask);
 
 		if (_mouseOrigSurface == NULL)
 			error("allocating _mouseOrigSurface failed");
@@ -2057,7 +1944,7 @@ void SurfaceSdlGraphicsManager::blitCursor() {
 	if (!_mouseOrigSurface || !_mouseData)
 		return;
 
-	_mouseNeedsRedraw = true;
+	_cursorNeedsRedraw = true;
 
 	w = _mouseCurState.w;
 	h = _mouseCurState.h;
@@ -2159,10 +2046,10 @@ void SurfaceSdlGraphicsManager::blitCursor() {
 						_mouseCurState.rW,
 						_mouseCurState.rH,
 						16,
-						_hwscreen->format->Rmask,
-						_hwscreen->format->Gmask,
-						_hwscreen->format->Bmask,
-						_hwscreen->format->Amask);
+						_hwScreen->format->Rmask,
+						_hwScreen->format->Gmask,
+						_hwScreen->format->Bmask,
+						_hwScreen->format->Amask);
 
 		if (_mouseSurface == NULL)
 			error("allocating _mouseSurface failed");
@@ -2245,8 +2132,10 @@ void SurfaceSdlGraphicsManager::drawMouse() {
 	int scale;
 	int hotX, hotY;
 
-	dst.x = _mouseCurState.x;
-	dst.y = _mouseCurState.y;
+	const Common::Point virtualCursor = convertWindowToVirtual(_cursorX, _cursorY);
+
+	dst.x = virtualCursor.x;
+	dst.y = virtualCursor.y;
 
 	if (!_overlayVisible) {
 		scale = _videoMode.scaleFactor;
@@ -2286,7 +2175,7 @@ void SurfaceSdlGraphicsManager::drawMouse() {
 	// Note that SDL_BlitSurface() and addDirtyRect() will both perform any
 	// clipping necessary
 
-	if (SDL_BlitSurface(_mouseSurface, NULL, _hwscreen, &dst) != 0)
+	if (SDL_BlitSurface(_mouseSurface, NULL, _hwScreen, &dst) != 0)
 		error("SDL_BlitSurface failed: %s", SDL_GetError());
 
 	// The screen will be updated using real surface coordinates, i.e.
@@ -2335,14 +2224,14 @@ void SurfaceSdlGraphicsManager::displayMessageOnOSD(const char *msg) {
 	}
 
 	// Clip the rect
-	if (width > _hwscreen->w)
-		width = _hwscreen->w;
-	if (height > _hwscreen->h)
-		height = _hwscreen->h;
+	if (width > _hwScreen->w)
+		width = _hwScreen->w;
+	if (height > _hwScreen->h)
+		height = _hwScreen->h;
 
 	_osdMessageSurface = SDL_CreateRGBSurface(
 		SDL_SWSURFACE | SDL_RLEACCEL | SDL_SRCALPHA,
-		width, height, 16, _hwscreen->format->Rmask, _hwscreen->format->Gmask, _hwscreen->format->Bmask, _hwscreen->format->Amask
+		width, height, 16, _hwScreen->format->Rmask, _hwScreen->format->Gmask, _hwScreen->format->Bmask, _hwScreen->format->Amask
 	);
 
 	// Lock the surface
@@ -2379,8 +2268,8 @@ void SurfaceSdlGraphicsManager::displayMessageOnOSD(const char *msg) {
 
 SDL_Rect SurfaceSdlGraphicsManager::getOSDMessageRect() const {
 	SDL_Rect rect;
-	rect.x = (_hwscreen->w - _osdMessageSurface->w) / 2;
-	rect.y = (_hwscreen->h - _osdMessageSurface->h) / 2;
+	rect.x = (_hwScreen->w - _osdMessageSurface->w) / 2;
+	rect.y = (_hwScreen->h - _osdMessageSurface->h) / 2;
 	rect.w = _osdMessageSurface->w;
 	rect.h = _osdMessageSurface->h;
 	return rect;
@@ -2393,7 +2282,7 @@ void SurfaceSdlGraphicsManager::displayActivityIconOnOSD(const Graphics::Surface
 
 	if (_osdIconSurface && !icon) {
 		// Force a redraw to clear the icon on the next update
-		_forceFull = true;
+		_forceRedraw = true;
 	}
 
 	if (_osdIconSurface) {
@@ -2432,7 +2321,7 @@ void SurfaceSdlGraphicsManager::displayActivityIconOnOSD(const Graphics::Surface
 
 SDL_Rect SurfaceSdlGraphicsManager::getOSDIconRect() const {
 	SDL_Rect dstRect;
-	dstRect.x = _hwscreen->w - _osdIconSurface->w - 10;
+	dstRect.x = _hwScreen->w - _osdIconSurface->w - 10;
 	dstRect.y = 10;
 	dstRect.w = _osdIconSurface->w;
 	dstRect.h = _osdIconSurface->h;
@@ -2464,7 +2353,7 @@ void SurfaceSdlGraphicsManager::updateOSD() {
 				_osdMessageAlpha = startAlpha + diff * (SDL_ALPHA_TRANSPARENT - startAlpha) / kOSDFadeOutDuration;
 			}
 			SDL_SetAlpha(_osdMessageSurface, SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA, _osdMessageAlpha);
-			_forceFull = true;
+			_forceRedraw = true;
 		}
 
 		if (_osdMessageAlpha == SDL_ALPHA_TRANSPARENT) {
@@ -2474,26 +2363,30 @@ void SurfaceSdlGraphicsManager::updateOSD() {
 
 	if (_osdIconSurface) {
 		// Redraw the area below the icon for the transparent blit to give correct results.
-		_forceFull = true;
+		_forceRedraw = true;
 	}
 }
 
 void SurfaceSdlGraphicsManager::drawOSD() {
 	if (_osdMessageSurface) {
 		SDL_Rect dstRect = getOSDMessageRect();
-		SDL_BlitSurface(_osdMessageSurface, 0, _hwscreen, &dstRect);
+		SDL_BlitSurface(_osdMessageSurface, 0, _hwScreen, &dstRect);
 	}
 
 	if (_osdIconSurface) {
 		SDL_Rect dstRect = getOSDIconRect();
-		SDL_BlitSurface(_osdIconSurface, 0, _hwscreen, &dstRect);
+		SDL_BlitSurface(_osdIconSurface, 0, _hwScreen, &dstRect);
 	}
 }
 
 #endif
 
-bool SurfaceSdlGraphicsManager::handleScalerHotkeys(Common::KeyCode key) {
+void SurfaceSdlGraphicsManager::handleResizeImpl(const int width, const int height) {
+	SdlGraphicsManager::handleResizeImpl(width, height);
+	recalculateDisplayAreas();
+}
 
+bool SurfaceSdlGraphicsManager::handleScalerHotkeys(Common::KeyCode key) {
 	// Ctrl-Alt-a toggles aspect ratio correction
 	if (key == 'a') {
 		beginGFXTransaction();
@@ -2505,13 +2398,13 @@ bool SurfaceSdlGraphicsManager::handleScalerHotkeys(Common::KeyCode key) {
 			message = Common::String::format("%s\n%d x %d -> %d x %d",
 				_("Enabled aspect ratio correction"),
 				_videoMode.screenWidth, _videoMode.screenHeight,
-				_hwscreen->w, _hwscreen->h
+				_hwScreen->w, _hwScreen->h
 				);
 		else
 			message = Common::String::format("%s\n%d x %d -> %d x %d",
 				_("Disabled aspect ratio correction"),
 				_videoMode.screenWidth, _videoMode.screenHeight,
-				_hwscreen->w, _hwscreen->h
+				_hwScreen->w, _hwScreen->h
 				);
 		displayMessageOnOSD(message.c_str());
 #endif
@@ -2532,7 +2425,7 @@ bool SurfaceSdlGraphicsManager::handleScalerHotkeys(Common::KeyCode key) {
 			displayMessageOnOSD(_("Filtering disabled"));
 		}
 #endif
-		_forceFull = true;
+		_forceRedraw = true;
 		internUpdateScreen();
 		return true;
 	}
@@ -2542,12 +2435,19 @@ bool SurfaceSdlGraphicsManager::handleScalerHotkeys(Common::KeyCode key) {
 	int factor = _videoMode.scaleFactor - 1;
 	SDLKey sdlKey = (SDLKey)key;
 
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+	bool sizeChanged = false;
+#endif
+
 	// Increase/decrease the scale factor
 	if (sdlKey == SDLK_EQUALS || sdlKey == SDLK_PLUS || sdlKey == SDLK_MINUS ||
 		sdlKey == SDLK_KP_PLUS || sdlKey == SDLK_KP_MINUS) {
 		factor += (sdlKey == SDLK_MINUS || sdlKey == SDLK_KP_MINUS) ? -1 : +1;
 		if (0 <= factor && factor <= 3) {
 			newMode = s_gfxModeSwitchTable[_scalerType][factor];
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+			sizeChanged = true;
+#endif
 		}
 	}
 
@@ -2585,10 +2485,19 @@ bool SurfaceSdlGraphicsManager::handleScalerHotkeys(Common::KeyCode key) {
 				_("Active graphics filter:"),
 				newScalerName,
 				_videoMode.screenWidth, _videoMode.screenHeight,
-				_hwscreen->w, _hwscreen->h);
+				_hwScreen->w, _hwScreen->h);
 			displayMessageOnOSD(message.c_str());
 		}
 #endif
+
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+		if (sizeChanged) {
+			// Forcibly resizing the window here since a user switching scaler
+			// size will not normally cause the window to update
+			_window->createOrUpdateWindow(_hwScreen->w, _hwScreen->h, _lastFlags);
+		}
+#endif
+
 		internUpdateScreen();
 
 		return true;
@@ -2700,37 +2609,11 @@ bool SurfaceSdlGraphicsManager::notifyEvent(const Common::Event &event) {
 }
 
 void SurfaceSdlGraphicsManager::notifyVideoExpose() {
-	_forceFull = true;
-}
-
-void SurfaceSdlGraphicsManager::notifyResize(const uint width, const uint height) {
-#if SDL_VERSION_ATLEAST(2, 0, 0)
-	setWindowResolution(width, height);
-#endif
-}
-
-void SurfaceSdlGraphicsManager::transformMouseCoordinates(Common::Point &point) {
-#if SDL_VERSION_ATLEAST(2, 0, 0)
-	// In SDL2 the actual output resolution might be different from what we
-	// requested. Thus, we transform the coordinates from actual output
-	// coordinate space into the "virtual" output coordinate space.
-	// Please note that we ignore the possible existence of black bars here,
-	// this avoids the feeling of stickyness to black bars.
-	point.x = point.x * _videoMode.hardwareWidth  / _windowWidth;
-	point.y = point.y * _videoMode.hardwareHeight / _windowHeight;
-#endif
-
-	if (!_overlayVisible) {
-		point.x /= _videoMode.scaleFactor;
-		point.y /= _videoMode.scaleFactor;
-		if (_videoMode.aspectRatioCorrection)
-			point.y = aspect2Real(point.y);
-	}
+	_forceRedraw = true;
 }
 
-void SurfaceSdlGraphicsManager::notifyMousePos(Common::Point mouse) {
-	transformMouseCoordinates(mouse);
-	setMousePos(mouse.x, mouse.y);
+void SurfaceSdlGraphicsManager::notifyResize(const int width, const int height) {
+	handleResize(width, height);
 }
 
 #if SDL_VERSION_ATLEAST(2, 0, 0)
@@ -2742,39 +2625,6 @@ void SurfaceSdlGraphicsManager::deinitializeRenderer() {
 	_renderer = nullptr;
 }
 
-void SurfaceSdlGraphicsManager::setWindowResolution(int width, int height) {
-	_windowWidth  = width;
-	_windowHeight = height;
-
-	// We expect full screen resolution as inputs coming from the event system.
-	_eventSource->resetKeyboardEmulation(_windowWidth - 1, _windowHeight - 1);
-
-	// Calculate the "viewport" for the actual area we draw in. In fullscreen
-	// we can easily get a different resolution than what we requested. In
-	// this case, we add black bars if necessary to assure the aspect ratio
-	// is preserved.
-	const frac_t outputAspect  = intToFrac(_windowWidth) / _windowHeight;
-	const frac_t desiredAspect = intToFrac(_videoMode.hardwareWidth) / _videoMode.hardwareHeight;
-
-	_viewport.w = _windowWidth;
-	_viewport.h = _windowHeight;
-
-	// Adjust one dimension for mantaining the aspect ratio.
-	if (abs(outputAspect - desiredAspect) >= (int)(FRAC_ONE / 1000)) {
-		if (outputAspect < desiredAspect) {
-			_viewport.h = _videoMode.hardwareHeight * _windowWidth / _videoMode.hardwareWidth;
-		} else if (outputAspect > desiredAspect) {
-			_viewport.w = _videoMode.hardwareWidth * _windowHeight / _videoMode.hardwareHeight;
-		}
-	}
-
-	_viewport.x = (_windowWidth  - _viewport.w) / 2;
-	_viewport.y = (_windowHeight - _viewport.h) / 2;
-
-	// Force a full redraw because we changed the viewport.
-	_forceFull = true;
-}
-
 void SurfaceSdlGraphicsManager::recreateScreenTexture() {
 	if (!_renderer)
 		return;
@@ -2807,8 +2657,8 @@ SDL_Surface *SurfaceSdlGraphicsManager::SDL_SetVideoMode(int width, int height,
 		return nullptr;
 	}
 
-	SDL_GetWindowSize(_window->getSDLWindow(), &_windowWidth, &_windowHeight);
-	setWindowResolution(_windowWidth, _windowHeight);
+	getWindowSizeFromSdl(&_windowWidth, &_windowHeight);
+	handleResize(_windowWidth, _windowHeight);
 
 	SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, _videoMode.filtering ? "linear" : "nearest");
 
@@ -2830,8 +2680,14 @@ SDL_Surface *SurfaceSdlGraphicsManager::SDL_SetVideoMode(int width, int height,
 void SurfaceSdlGraphicsManager::SDL_UpdateRects(SDL_Surface *screen, int numrects, SDL_Rect *rects) {
 	SDL_UpdateTexture(_screenTexture, nullptr, screen->pixels, screen->pitch);
 
+	SDL_Rect viewport;
+	viewport.x = _activeArea.drawRect.left;
+	viewport.y = _activeArea.drawRect.top;
+	viewport.w = _activeArea.drawRect.width();
+	viewport.h = _activeArea.drawRect.height();
+
 	SDL_RenderClear(_renderer);
-	SDL_RenderCopy(_renderer, _screenTexture, NULL, &_viewport);
+	SDL_RenderCopy(_renderer, _screenTexture, NULL, &viewport);
 	SDL_RenderPresent(_renderer);
 }
 #endif // SDL_VERSION_ATLEAST(2, 0, 0)
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.h b/backends/graphics/surfacesdl/surfacesdl-graphics.h
index 85f63cb..c1e49b9 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.h
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.h
@@ -40,7 +40,6 @@
 #endif
 
 #if !defined(_WIN32_WCE) && !defined(__SYMBIAN32__)
-// Uncomment this to enable the 'on screen display' code.
 #define USE_OSD	1
 #endif
 
@@ -80,76 +79,71 @@ public:
 	SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window);
 	virtual ~SurfaceSdlGraphicsManager();
 
-	virtual void activateManager();
-	virtual void deactivateManager();
+	virtual void activateManager() override;
+	virtual void deactivateManager() override;
 
-	virtual bool hasFeature(OSystem::Feature f);
-	virtual void setFeatureState(OSystem::Feature f, bool enable);
-	virtual bool getFeatureState(OSystem::Feature f);
+	virtual bool hasFeature(OSystem::Feature f) const override;
+	virtual void setFeatureState(OSystem::Feature f, bool enable) override;
+	virtual bool getFeatureState(OSystem::Feature f) const override;
 
-	virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const;
-	virtual int getDefaultGraphicsMode() const;
-	virtual bool setGraphicsMode(int mode);
-	virtual int getGraphicsMode() const;
-	virtual void resetGraphicsScale();
+	virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const override;
+	virtual int getDefaultGraphicsMode() const override;
+	virtual bool setGraphicsMode(int mode) override;
+	virtual int getGraphicsMode() const override;
+	virtual void resetGraphicsScale() override;
 #ifdef USE_RGB_COLOR
-	virtual Graphics::PixelFormat getScreenFormat() const { return _screenFormat; }
-	virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const;
+	virtual Graphics::PixelFormat getScreenFormat() const override { return _screenFormat; }
+	virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const override;
 #endif
-	virtual const OSystem::GraphicsMode *getSupportedShaders() const;
-	virtual int getShader() const;
-	virtual bool setShader(int id);
-	virtual void initSize(uint w, uint h, const Graphics::PixelFormat *format = NULL);
-	virtual int getScreenChangeID() const { return _screenChangeCount; }
+	virtual const OSystem::GraphicsMode *getSupportedShaders() const override;
+	virtual int getShader() const override;
+	virtual bool setShader(int id) override;
+	virtual void initSize(uint w, uint h, const Graphics::PixelFormat *format = NULL) override;
+	virtual int getScreenChangeID() const override { return _screenChangeCount; }
 
-	virtual void beginGFXTransaction();
-	virtual OSystem::TransactionError endGFXTransaction();
+	virtual void beginGFXTransaction() override;
+	virtual OSystem::TransactionError endGFXTransaction() override;
 
-	virtual int16 getHeight();
-	virtual int16 getWidth();
+	virtual int16 getHeight() const override;
+	virtual int16 getWidth() const override;
 
 protected:
 	// PaletteManager API
-	virtual void setPalette(const byte *colors, uint start, uint num);
-	virtual void grabPalette(byte *colors, uint start, uint num);
+	virtual void setPalette(const byte *colors, uint start, uint num) override;
+	virtual void grabPalette(byte *colors, uint start, uint num) const override;
 
 public:
-	virtual void copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h);
-	virtual Graphics::Surface *lockScreen();
-	virtual void unlockScreen();
-	virtual void fillScreen(uint32 col);
-	virtual void updateScreen();
-	virtual void setShakePos(int shakeOffset);
-	virtual void setFocusRectangle(const Common::Rect& rect);
-	virtual void clearFocusRectangle();
-
-	virtual void showOverlay();
-	virtual void hideOverlay();
-	virtual Graphics::PixelFormat getOverlayFormat() const { return _overlayFormat; }
-	virtual void clearOverlay();
-	virtual void grabOverlay(void *buf, int pitch);
-	virtual void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h);
-	virtual int16 getOverlayHeight() { return _videoMode.overlayHeight; }
-	virtual int16 getOverlayWidth() { return _videoMode.overlayWidth; }
-
-	virtual bool showMouse(bool visible);
-	virtual void warpMouse(int x, int y);
-	virtual void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL);
-	virtual void setCursorPalette(const byte *colors, uint start, uint num);
+	virtual void copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) override;
+	virtual Graphics::Surface *lockScreen() override;
+	virtual void unlockScreen() override;
+	virtual void fillScreen(uint32 col) override;
+	virtual void updateScreen() override;
+	virtual void setShakePos(int shakeOffset) override;
+	virtual void setFocusRectangle(const Common::Rect& rect) override;
+	virtual void clearFocusRectangle() override;
+
+	virtual Graphics::PixelFormat getOverlayFormat() const override { return _overlayFormat; }
+	virtual void clearOverlay() override;
+	virtual void grabOverlay(void *buf, int pitch) const override;
+	virtual void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) override;
+	virtual int16 getOverlayHeight() const override { return _videoMode.overlayHeight; }
+	virtual int16 getOverlayWidth() const override { return _videoMode.overlayWidth; }
+
+	virtual bool showMouse(bool visible) override;
+	virtual void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL) override;
+	virtual void setCursorPalette(const byte *colors, uint start, uint num) override;
 
 #ifdef USE_OSD
-	virtual void displayMessageOnOSD(const char *msg);
-	virtual void displayActivityIconOnOSD(const Graphics::Surface *icon);
+	virtual void displayMessageOnOSD(const char *msg) override;
+	virtual void displayActivityIconOnOSD(const Graphics::Surface *icon) override;
 #endif
 
 	// Override from Common::EventObserver
-	bool notifyEvent(const Common::Event &event);
+	virtual bool notifyEvent(const Common::Event &event) override;
 
 	// SdlGraphicsManager interface
-	virtual void notifyVideoExpose();
-	virtual void notifyResize(const uint width, const uint height);
-	virtual void transformMouseCoordinates(Common::Point &point);
-	virtual void notifyMousePos(Common::Point mouse);
+	virtual void notifyVideoExpose() override;
+	virtual void notifyResize(const int width, const int height) override;
 
 protected:
 #ifdef USE_OSD
@@ -178,8 +172,11 @@ protected:
 	void drawOSD();
 #endif
 
-	/** Hardware screen */
-	SDL_Surface *_hwscreen;
+	virtual bool gameNeedsAspectRatioCorrection() const override {
+		return _videoMode.aspectRatioCorrection;
+	}
+
+	virtual void handleResizeImpl(const int width, const int height) override;
 
 	virtual int getGraphicsModeScale(int mode) const override;
 
@@ -188,10 +185,7 @@ protected:
 	 * around this API to keep the code paths as close as possible. */
 	SDL_Renderer *_renderer;
 	SDL_Texture *_screenTexture;
-	SDL_Rect _viewport;
-	int _windowWidth, _windowHeight;
 	void deinitializeRenderer();
-	void setWindowResolution(int width, int height);
 	void recreateScreenTexture();
 
 	virtual SDL_Surface *SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags);
@@ -218,7 +212,6 @@ protected:
 	SDL_Surface *_tmpscreen2;
 
 	SDL_Surface *_overlayscreen;
-	bool _overlayVisible;
 	Graphics::PixelFormat _overlayFormat;
 
 	enum {
@@ -280,14 +273,11 @@ protected:
 	uint8 _originalBitsPerPixel;
 #endif
 
-	/** Force full redraw on next updateScreen */
-	bool _forceFull;
-
 	ScalerProc *_scalerProc;
 	int _scalerType;
 	int _transactionMode;
 
-	// Indicates whether it is needed to free _hwsurface in destructor
+	// Indicates whether it is needed to free _hwSurface in destructor
 	bool _displayDisabled;
 
 	bool _screenIsLocked;
@@ -308,10 +298,6 @@ protected:
 	int _numDirtyRects;
 
 	struct MousePos {
-		// The mouse position, using either virtual (game) or real
-		// (overlay) coordinates.
-		int16 x, y;
-
 		// The size and hotspot of the original cursor image.
 		int16 w, h;
 		int16 hotX, hotY;
@@ -326,14 +312,13 @@ protected:
 		int16 vW, vH;
 		int16 vHotX, vHotY;
 
-		MousePos() : x(0), y(0), w(0), h(0), hotX(0), hotY(0),
+		MousePos() : w(0), h(0), hotX(0), hotY(0),
 					rW(0), rH(0), rHotX(0), rHotY(0), vW(0), vH(0),
 					vHotX(0), vHotY(0)
 			{ }
 	};
 
 	bool _mouseVisible;
-	bool _mouseNeedsRedraw;
 	byte *_mouseData;
 	SDL_Rect _mouseBackup;
 	MousePos _mouseCurState;
@@ -386,21 +371,45 @@ protected:
 	virtual void unloadGFXMode();
 	virtual bool hotswapGFXMode();
 
-	virtual void setFullscreenMode(bool enable);
 	virtual void setAspectRatioCorrection(bool enable);
 #if SDL_VERSION_ATLEAST(2, 0, 0)
-	virtual void setFilteringMode(bool enable);
+	void setFilteringMode(bool enable);
 #endif
 
-	virtual int effectiveScreenHeight() const;
-
+	virtual bool saveScreenshot(const char *filename);
 	virtual void setGraphicsModeIntern();
 
-	virtual bool handleScalerHotkeys(Common::KeyCode key);
-	virtual bool isScalerHotkey(const Common::Event &event);
-	virtual void setMousePos(int x, int y);
-	virtual void toggleFullScreen();
-	virtual bool saveScreenshot(const char *filename);
+private:
+	void setFullscreenMode(bool enable);
+	bool handleScalerHotkeys(Common::KeyCode key);
+	bool isScalerHotkey(const Common::Event &event);
+	void toggleFullScreen();
+
+	/**
+	 * Converts the given point from the overlay's coordinate space to the
+	 * game's coordinate space.
+	 */
+	Common::Point convertOverlayToGame(const int x, const int y) const {
+		if (getOverlayWidth() == 0 || getOverlayHeight() == 0) {
+			error("convertOverlayToGame called without a valid overlay");
+		}
+
+		return Common::Point(x * getWidth() / getOverlayWidth(),
+							 y * getHeight() / getOverlayHeight());
+	}
+
+	/**
+	 * Converts the given point from the game's coordinate space to the
+	 * overlay's coordinate space.
+	 */
+	Common::Point convertGameToOverlay(const int x, const int y) const {
+		if (getWidth() == 0 || getHeight() == 0) {
+			error("convertGameToOverlay called without a valid overlay");
+		}
+
+		return Common::Point(x * getOverlayWidth() / getWidth(),
+							 y * getOverlayHeight() / getHeight());
+	}
 };
 
 #endif
diff --git a/backends/graphics/windowed.h b/backends/graphics/windowed.h
new file mode 100644
index 0000000..b3e5b83
--- /dev/null
+++ b/backends/graphics/windowed.h
@@ -0,0 +1,313 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BACKENDS_GRAPHICS_WINDOWED_H
+#define BACKENDS_GRAPHICS_WINDOWED_H
+
+#include "backends/graphics/graphics.h"
+#include "common/frac.h"
+#include "common/rect.h"
+#include "common/textconsole.h"
+#include "graphics/scaler/aspect.h"
+
+class WindowedGraphicsManager : virtual public GraphicsManager {
+public:
+	WindowedGraphicsManager() :
+		_windowWidth(0),
+		_windowHeight(0),
+		_overlayVisible(false),
+		_forceRedraw(false),
+		_cursorX(0),
+		_cursorY(0),
+		_cursorNeedsRedraw(false) {}
+
+	virtual void showOverlay() override {
+		if (_overlayVisible)
+			return;
+
+		_activeArea.drawRect = _overlayDrawRect;
+		_activeArea.width = getOverlayWidth();
+		_activeArea.height = getOverlayHeight();
+		_overlayVisible = true;
+		_forceRedraw = true;
+	}
+
+	virtual void hideOverlay() override {
+		if (!_overlayVisible)
+			return;
+
+		_activeArea.drawRect = _gameDrawRect;
+		_activeArea.width = getWidth();
+		_activeArea.height = getHeight();
+		_overlayVisible = false;
+		_forceRedraw = true;
+	}
+
+protected:
+	/**
+	 * @returns whether or not the game screen must have aspect ratio correction
+	 * applied for correct rendering.
+	 */
+	virtual bool gameNeedsAspectRatioCorrection() const = 0;
+
+	/**
+	 * Backend-specific implementation for updating internal surfaces that need
+	 * to reflect the new window size.
+	 */
+	virtual void handleResizeImpl(const int width, const int height) = 0;
+
+	/**
+	 * Converts the given point from the active virtual screen's coordinate
+	 * space to the window's coordinate space (i.e. game-to-window or
+	 * overlay-to-window).
+	 */
+	Common::Point convertVirtualToWindow(const int x, const int y) const {
+		const int targetX = _activeArea.drawRect.left;
+		const int targetY = _activeArea.drawRect.top;
+		const int targetWidth = _activeArea.drawRect.width();
+		const int targetHeight = _activeArea.drawRect.height();
+		const int sourceWidth = _activeArea.width;
+		const int sourceHeight = _activeArea.height;
+
+		if (sourceWidth == 0 || sourceHeight == 0) {
+			error("convertVirtualToWindow called without a valid draw rect");
+		}
+
+		return Common::Point(targetX + x * targetWidth / sourceWidth,
+							 targetY + y * targetHeight / sourceHeight);
+	}
+
+	/**
+	 * Converts the given point from the window's coordinate space to the
+	 * active virtual screen's coordinate space (i.e. window-to-game or
+	 * window-to-overlay).
+	 */
+	Common::Point convertWindowToVirtual(int x, int y) const {
+		const int sourceX = _activeArea.drawRect.left;
+		const int sourceY = _activeArea.drawRect.top;
+		const int sourceMaxX = _activeArea.drawRect.right - 1;
+		const int sourceMaxY = _activeArea.drawRect.bottom - 1;
+		const int sourceWidth = _activeArea.drawRect.width();
+		const int sourceHeight = _activeArea.drawRect.height();
+		const int targetWidth = _activeArea.width;
+		const int targetHeight = _activeArea.height;
+
+		if (sourceWidth == 0 || sourceHeight == 0) {
+			error("convertWindowToVirtual called without a valid draw rect");
+		}
+
+		x = CLIP<int>(x, sourceX, sourceMaxX);
+		y = CLIP<int>(y, sourceY, sourceMaxY);
+
+		return Common::Point(((x - sourceX) * targetWidth) / sourceWidth,
+							 ((y - sourceY) * targetHeight) / sourceHeight);
+	}
+
+	/**
+	 * @returns the desired aspect ratio of the game surface.
+	 */
+	frac_t getDesiredGameAspectRatio() const {
+		if (getHeight() == 0 || gameNeedsAspectRatioCorrection()) {
+			return intToFrac(4) / 3;
+		}
+
+		return intToFrac(getWidth()) / getHeight();
+	}
+
+	/**
+	 * Called after the window has been updated with new dimensions.
+	 *
+	 * @param width The new width of the window, excluding window decoration.
+	 * @param height The new height of the window, excluding window decoration.
+	 */
+	void handleResize(const int width, const int height) {
+		_windowWidth = width;
+		_windowHeight = height;
+		handleResizeImpl(width, height);
+	}
+
+	/**
+	 * Recalculates the display areas for the game and overlay surfaces within
+	 * the window.
+	 */
+	virtual void recalculateDisplayAreas() {
+		if (_windowHeight == 0) {
+			return;
+		}
+
+		const frac_t outputAspect = intToFrac(_windowWidth) / _windowHeight;
+
+		populateDisplayAreaDrawRect(getDesiredGameAspectRatio(), outputAspect, _gameDrawRect);
+
+		if (getOverlayHeight()) {
+			const frac_t overlayAspect = intToFrac(getOverlayWidth()) / getOverlayHeight();
+			populateDisplayAreaDrawRect(overlayAspect, outputAspect, _overlayDrawRect);
+		}
+
+		if (_overlayVisible) {
+			_activeArea.drawRect = _overlayDrawRect;
+			_activeArea.width = getOverlayWidth();
+			_activeArea.height = getOverlayHeight();
+		} else {
+			_activeArea.drawRect = _gameDrawRect;
+			_activeArea.width = getWidth();
+			_activeArea.height = getHeight();
+		}
+	}
+	/**
+	 * Sets the position of the hardware mouse cursor in the host system,
+	 * relative to the window.
+	 *
+	 * @param x X coordinate in window coordinates.
+	 * @param y Y coordinate in window coordinates.
+	 */
+	virtual void setSystemMousePosition(const int x, const int y) = 0;
+
+	/**
+	 * Move ("warp") the mouse cursor to the specified position.
+	 *
+	 * @param x	The new X position of the mouse in virtual screen coordinates.
+	 * @param y	The new Y position of the mouse in virtual screen coordinates.
+	 */
+	void warpMouse(const int x, const int y) {
+		// Check active coordinate instead of window coordinate to avoid warping
+		// the mouse if it is still within the same virtual pixel
+		const Common::Point virtualCursor = convertWindowToVirtual(_cursorX, _cursorY);
+		if (virtualCursor.x != x || virtualCursor.y != y) {
+			// Warping the mouse in SDL generates a mouse movement event, so
+			// `setMousePosition` would be called eventually through the
+			// `notifyMousePosition` callback if we *only* set the system mouse
+			// position here. However, this can cause problems with some games.
+			// For example, the cannon script in CoMI calls to warp the mouse
+			// twice each time the cannon is reloaded, and unless we update the
+			// mouse position immediately, the second call is ignored, which
+			// causes the cannon to change its aim.
+			const Common::Point windowCursor = convertVirtualToWindow(x, y);
+			setMousePosition(windowCursor.x, windowCursor.y);
+			setSystemMousePosition(windowCursor.x, windowCursor.y);
+		}
+	}
+
+	/**
+	 * Sets the position of the rendered mouse cursor in the window.
+	 *
+	 * @param x X coordinate in window coordinates.
+	 * @param y Y coordinate in window coordinates.
+	 */
+	void setMousePosition(int x, int y) {
+		if (_cursorX != x || _cursorY != y) {
+			_cursorNeedsRedraw = true;
+		}
+
+		_cursorX = x;
+		_cursorY = y;
+	}
+
+	/**
+	 * The width of the window, excluding window decoration.
+	 */
+	int _windowWidth;
+
+	/**
+	 * The height of the window, excluding window decoration.
+	 */
+	int _windowHeight;
+
+	/**
+	 * Whether the overlay (i.e. launcher, including the out-of-game launcher)
+	 * is visible or not.
+	 */
+	bool _overlayVisible;
+
+	/**
+	 * The scaled draw rectangle for the game surface within the window.
+	 */
+	Common::Rect _gameDrawRect;
+
+	/**
+	 * The scaled draw rectangle for the overlay (launcher) surface within the
+	 * window.
+	 */
+	Common::Rect _overlayDrawRect;
+
+	/**
+	 * Data about the display area of a virtual screen.
+	 */
+	struct DisplayArea {
+		/**
+		 * The scaled area where the virtual screen is drawn within the window.
+		 */
+		Common::Rect drawRect;
+
+		/**
+		 * The width of the virtual screen's unscaled coordinate space.
+		 */
+		int width;
+
+		/**
+		 * The height of the virtual screen's unscaled coordinate space.
+		 */
+		int height;
+	};
+
+	/**
+	 * Display area information about the currently active virtual screen. This
+	 * will be the overlay screen when the overlay is active, and the game
+	 * screen otherwise.
+	 */
+	DisplayArea _activeArea;
+
+	/**
+	 * Whether the screen must be redrawn on the next frame.
+	 */
+	bool _forceRedraw;
+
+	/**
+	 * Whether the mouse cursor needs to be redrawn on the next frame.
+	 */
+	bool _cursorNeedsRedraw;
+
+	/**
+	 * The position of the mouse cursor, in window coordinates.
+	 */
+	int _cursorX, _cursorY;
+
+private:
+	void populateDisplayAreaDrawRect(const frac_t inputAspect, const frac_t outputAspect, Common::Rect &drawRect) const {
+		int width = _windowWidth;
+		int height = _windowHeight;
+
+		// Maintain aspect ratios
+		if (outputAspect < inputAspect) {
+			height = intToFrac(width) / inputAspect;
+		} else if (outputAspect > inputAspect) {
+			width = fracToInt(height * inputAspect);
+		}
+
+		drawRect.left = (_windowWidth - width) / 2;
+		drawRect.top = (_windowHeight - height) / 2;
+		drawRect.setWidth(width);
+		drawRect.setHeight(height);
+	}
+};
+
+#endif
diff --git a/backends/platform/sdl/sdl-window.cpp b/backends/platform/sdl/sdl-window.cpp
index 16b978d..a550fbb 100644
--- a/backends/platform/sdl/sdl-window.cpp
+++ b/backends/platform/sdl/sdl-window.cpp
@@ -135,8 +135,10 @@ void SdlWindow::toggleMouseGrab() {
 #else
 	if (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_OFF) {
 		SDL_WM_GrabInput(SDL_GRAB_ON);
+		_inputGrabState = true;
 	} else {
 		SDL_WM_GrabInput(SDL_GRAB_OFF);
+		_inputGrabState = false;
 	}
 #endif
 }
@@ -154,13 +156,15 @@ bool SdlWindow::hasMouseFocus() const {
 }
 
 void SdlWindow::warpMouseInWindow(int x, int y) {
+	if (hasMouseFocus()) {
 #if SDL_VERSION_ATLEAST(2, 0, 0)
-	if (_window && hasMouseFocus()) {
-		SDL_WarpMouseInWindow(_window, x, y);
-	}
+		if (_window) {
+			SDL_WarpMouseInWindow(_window, x, y);
+		}
 #else
-	SDL_WarpMouse(x, y);
+		SDL_WarpMouse(x, y);
 #endif
+	}
 }
 
 void SdlWindow::iconifyWindow() {
diff --git a/backends/platform/sdl/sdl-window.h b/backends/platform/sdl/sdl-window.h
index fb7607b..4f6d924 100644
--- a/backends/platform/sdl/sdl-window.h
+++ b/backends/platform/sdl/sdl-window.h
@@ -56,7 +56,8 @@ public:
 	bool hasMouseFocus() const;
 
 	/**
-	 * Warp the mouse to the specified position in window coordinates.
+	 * 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.
 	 */
 	void warpMouseInWindow(int x, int y);
 
@@ -73,6 +74,11 @@ public:
 	 */
 	bool getSDLWMInformation(SDL_SysWMinfo *info) const;
 
+	bool mouseIsGrabbed() const { return _inputGrabState; }
+
+private:
+	bool _inputGrabState;
+
 #if SDL_VERSION_ATLEAST(2, 0, 0)
 public:
 	/**
@@ -108,7 +114,6 @@ private:
 	 */
 	int _lastX, _lastY;
 
-	bool _inputGrabState;
 	Common::String _windowCaption;
 #endif
 };
diff --git a/graphics/palette.h b/graphics/palette.h
index 2884bef..0b9b861 100644
--- a/graphics/palette.h
+++ b/graphics/palette.h
@@ -96,7 +96,7 @@ public:
 	 *
 	 * @see getScreenFormat
 	 */
-	virtual void grabPalette(byte *colors, uint start, uint num) = 0;
+	virtual void grabPalette(byte *colors, uint start, uint num) const = 0;
 };
 
 #endif


Commit: da0a8db704f610994d665dfd7c080b49476ce76d
    https://github.com/scummvm/scummvm/commit/da0a8db704f610994d665dfd7c080b49476ce76d
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-10-15T13:24:20-05:00

Commit Message:
BACKENDS: Also hide mouse cursor outside game area when an engine has hidden the cursor

The only reason we show the system cursor outside the game area is
to show users where their mouse is when the window is resized and
the mouse is outside the game area. If the game cannot be
interacted with, then the mouse also does not need to be shown in
the black areas.

Changed paths:
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/opengl/opengl-graphics.h
    backends/graphics/sdl/sdl-graphics.cpp
    backends/graphics/sdl/sdl-graphics.h
    backends/graphics/surfacesdl/surfacesdl-graphics.cpp
    backends/graphics/surfacesdl/surfacesdl-graphics.h
    backends/graphics/windowed.h


diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index d98dcda..f3ea372 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -58,7 +58,7 @@ OpenGLGraphicsManager::OpenGLGraphicsManager()
       _cursor(nullptr),
       _cursorHotspotX(0), _cursorHotspotY(0),
       _cursorHotspotXScaled(0), _cursorHotspotYScaled(0), _cursorWidthScaled(0), _cursorHeightScaled(0),
-      _cursorKeyColor(0), _cursorVisible(false), _cursorDontScale(false), _cursorPaletteEnabled(false)
+      _cursorKeyColor(0), _cursorDontScale(false), _cursorPaletteEnabled(false)
 #ifdef USE_OSD
       , _osdMessageChangeRequest(false), _osdMessageAlpha(0), _osdMessageFadeStartTime(0), _osdMessageSurface(nullptr),
       _osdIconSurface(nullptr)
@@ -547,18 +547,6 @@ void OpenGLGraphicsManager::grabOverlay(void *buf, int pitch) const {
 	}
 }
 
-bool OpenGLGraphicsManager::showMouse(bool visible) {
-	// In case the mouse cursor visibility changed we need to redraw the whole
-	// screen even when nothing else changed.
-	if (_cursorVisible != visible) {
-		_cursorNeedsRedraw = true;
-	}
-
-	bool last = _cursorVisible;
-	_cursorVisible = visible;
-	return last;
-}
-
 namespace {
 template<typename DstPixel, typename SrcPixel>
 void applyColorKey(DstPixel *dst, const SrcPixel *src, uint w, uint h, uint dstPitch, uint srcPitch, SrcPixel keyColor, DstPixel alphaMask) {
diff --git a/backends/graphics/opengl/opengl-graphics.h b/backends/graphics/opengl/opengl-graphics.h
index 92bb988..df968aa 100644
--- a/backends/graphics/opengl/opengl-graphics.h
+++ b/backends/graphics/opengl/opengl-graphics.h
@@ -107,7 +107,6 @@ public:
 	virtual void clearOverlay() override;
 	virtual void grabOverlay(void *buf, int pitch) const override;
 
-	virtual bool showMouse(bool visible) override;
 	virtual void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) override;
 	virtual void setCursorPalette(const byte *colors, uint start, uint num) override;
 
@@ -396,11 +395,6 @@ protected:
 	uint32 _cursorKeyColor;
 
 	/**
-	 * Whether the cursor is actually visible.
-	 */
-	bool _cursorVisible;
-
-	/**
 	 * Whether no cursor scaling should be applied.
 	 */
 	bool _cursorDontScale;
diff --git a/backends/graphics/sdl/sdl-graphics.cpp b/backends/graphics/sdl/sdl-graphics.cpp
index ea947c1..6ce0bc7 100644
--- a/backends/graphics/sdl/sdl-graphics.cpp
+++ b/backends/graphics/sdl/sdl-graphics.cpp
@@ -148,18 +148,36 @@ void SdlGraphicsManager::initSizeHint(const Graphics::ModeList &modes) {
 #endif
 }
 
+bool SdlGraphicsManager::showMouse(const bool visible) {
+	if (visible == _cursorVisible) {
+		return visible;
+	}
+
+	int showCursor = SDL_DISABLE;
+	if (visible) {
+		// _cursorX and _cursorY are currently always clipped to the active
+		// area, so we need to ask SDL where the system's mouse cursor is
+		// instead
+		int x, y;
+		SDL_GetMouseState(&x, &y);
+		if (!_activeArea.drawRect.contains(Common::Point(x, y))) {
+			showCursor = SDL_ENABLE;
+		}
+	}
+	SDL_ShowCursor(showCursor);
+
+	return WindowedGraphicsManager::showMouse(visible);
+}
+
 void SdlGraphicsManager::notifyMousePosition(Common::Point &mouse) {
-	int showCursor;
-	if (_activeArea.drawRect.contains(mouse)) {
-		showCursor = SDL_DISABLE;
-	} else {
+	int showCursor = SDL_DISABLE;
+	if (!_activeArea.drawRect.contains(mouse)) {
 		mouse.x = CLIP<int>(mouse.x, _activeArea.drawRect.left, _activeArea.drawRect.right - 1);
 		mouse.y = CLIP<int>(mouse.y, _activeArea.drawRect.top, _activeArea.drawRect.bottom - 1);
 
 		if (_window->mouseIsGrabbed()) {
 			setSystemMousePosition(mouse.x, mouse.y);
-			showCursor = SDL_DISABLE;
-		} else {
+		} else if (_cursorVisible) {
 			showCursor = SDL_ENABLE;
 		}
 	}
diff --git a/backends/graphics/sdl/sdl-graphics.h b/backends/graphics/sdl/sdl-graphics.h
index 886070a..772bc88 100644
--- a/backends/graphics/sdl/sdl-graphics.h
+++ b/backends/graphics/sdl/sdl-graphics.h
@@ -87,6 +87,8 @@ public:
 	 */
 	virtual void notifyMousePosition(Common::Point &mouse);
 
+	virtual bool showMouse(const bool visible) override;
+
 	/**
 	 * A (subset) of the graphic manager's state. This is used when switching
 	 * between different SDL graphic managers at runtime.
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
index 52104ff..f610922 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
@@ -145,7 +145,7 @@ SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSou
 #endif
 	_overlayscreen(0), _tmpscreen2(0),
 	_scalerProc(0), _screenChangeCount(0),
-	_mouseVisible(false), _mouseData(0), _mouseSurface(0),
+	_mouseData(0), _mouseSurface(0),
 	_mouseOrigSurface(0), _cursorDontScale(false), _cursorPaletteDisabled(true),
 	_currentShakePos(0), _newShakePos(0),
 	_paletteDirtyStart(0), _paletteDirtyEnd(0),
@@ -1863,17 +1863,6 @@ void SurfaceSdlGraphicsManager::copyRectToOverlay(const void *buf, int pitch, in
 #pragma mark --- Mouse ---
 #pragma mark -
 
-bool SurfaceSdlGraphicsManager::showMouse(bool visible) {
-	if (_mouseVisible == visible)
-		return visible;
-
-	bool last = _mouseVisible;
-	_mouseVisible = visible;
-	_cursorNeedsRedraw = true;
-
-	return last;
-}
-
 void SurfaceSdlGraphicsManager::setMouseCursor(const void *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
 #ifdef USE_RGB_COLOR
 	if (!format)
@@ -2123,7 +2112,7 @@ void SurfaceSdlGraphicsManager::undrawMouse() {
 }
 
 void SurfaceSdlGraphicsManager::drawMouse() {
-	if (!_mouseVisible || !_mouseSurface) {
+	if (!_cursorVisible || !_mouseSurface) {
 		_mouseBackup.x = _mouseBackup.y = _mouseBackup.w = _mouseBackup.h = 0;
 		return;
 	}
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.h b/backends/graphics/surfacesdl/surfacesdl-graphics.h
index c1e49b9..0ed8d79 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.h
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.h
@@ -129,7 +129,6 @@ public:
 	virtual int16 getOverlayHeight() const override { return _videoMode.overlayHeight; }
 	virtual int16 getOverlayWidth() const override { return _videoMode.overlayWidth; }
 
-	virtual bool showMouse(bool visible) override;
 	virtual void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL) override;
 	virtual void setCursorPalette(const byte *colors, uint start, uint num) override;
 
@@ -318,7 +317,6 @@ protected:
 			{ }
 	};
 
-	bool _mouseVisible;
 	byte *_mouseData;
 	SDL_Rect _mouseBackup;
 	MousePos _mouseCurState;
diff --git a/backends/graphics/windowed.h b/backends/graphics/windowed.h
index b3e5b83..52bb96c 100644
--- a/backends/graphics/windowed.h
+++ b/backends/graphics/windowed.h
@@ -36,6 +36,7 @@ public:
 		_windowHeight(0),
 		_overlayVisible(false),
 		_forceRedraw(false),
+		_cursorVisible(false),
 		_cursorX(0),
 		_cursorY(0),
 		_cursorNeedsRedraw(false) {}
@@ -182,6 +183,17 @@ protected:
 	 */
 	virtual void setSystemMousePosition(const int x, const int y) = 0;
 
+	virtual bool showMouse(const bool visible) override {
+		if (_cursorVisible == visible) {
+			return visible;
+		}
+
+		const bool last = _cursorVisible;
+		_cursorVisible = visible;
+		_cursorNeedsRedraw = true;
+		return last;
+	}
+
 	/**
 	 * Move ("warp") the mouse cursor to the specified position.
 	 *
@@ -282,6 +294,11 @@ protected:
 	bool _forceRedraw;
 
 	/**
+	 * Whether the cursor is actually visible.
+	 */
+	bool _cursorVisible;
+
+	/**
 	 * Whether the mouse cursor needs to be redrawn on the next frame.
 	 */
 	bool _cursorNeedsRedraw;


Commit: 5d8cf6ba42c71e37530e83bb766b60bf1388a904
    https://github.com/scummvm/scummvm/commit/5d8cf6ba42c71e37530e83bb766b60bf1388a904
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-10-15T13:24:20-05:00

Commit Message:
BACKENDS: Fix GraphicsManager handling of empty cursors

The SDL graphics manager was just ignoring calls from CursorMan to
set the cursor to a blank cursor, which meant engines that did not
immediately send a cursor to CursorMan at startup would still show
the launcher's cursor (usually with a broken palette).

The OpenGL graphics manager would try to generate and draw an
invalid cursor surface when receiving an empty cursor.

Changed paths:
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/surfacesdl/surfacesdl-graphics.cpp


diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index f3ea372..7bac4c8 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -567,6 +567,18 @@ void applyColorKey(DstPixel *dst, const SrcPixel *src, uint w, uint h, uint dstP
 } // End of anonymous namespace
 
 void OpenGLGraphicsManager::setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
+
+	_cursorKeyColor = keycolor;
+	_cursorHotspotX = hotspotX;
+	_cursorHotspotY = hotspotY;
+	_cursorDontScale = dontScale;
+
+	if (!w || !h) {
+		delete _cursor;
+		_cursor = nullptr;
+		return;
+	}
+
 	Graphics::PixelFormat inputFormat;
 #ifdef USE_RGB_COLOR
 	if (format) {
@@ -602,11 +614,6 @@ void OpenGLGraphicsManager::setMouseCursor(const void *buf, uint w, uint h, int
 		_cursor->enableLinearFiltering(_currentState.filtering);
 	}
 
-	_cursorKeyColor = keycolor;
-	_cursorHotspotX = hotspotX;
-	_cursorHotspotY = hotspotY;
-	_cursorDontScale = dontScale;
-
 	_cursor->allocate(w, h);
 	if (inputFormat.bytesPerPixel == 1) {
 		// For CLUT8 cursors we can simply copy the input data into the
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
index f610922..9b6cbb9 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
@@ -1876,9 +1876,6 @@ void SurfaceSdlGraphicsManager::setMouseCursor(const void *buf, uint w, uint h,
 	assert(keycolor <= 0xFF);
 #endif
 
-	if (w == 0 || h == 0)
-		return;
-
 	_mouseCurState.hotX = hotspot_x;
 	_mouseCurState.hotY = hotspot_y;
 
@@ -1890,6 +1887,10 @@ void SurfaceSdlGraphicsManager::setMouseCursor(const void *buf, uint w, uint h,
 		_mouseCurState.w = w;
 		_mouseCurState.h = h;
 
+		if (!w || !h) {
+			return;
+		}
+
 		if (_mouseOrigSurface)
 			SDL_FreeSurface(_mouseOrigSurface);
 
@@ -1928,22 +1929,21 @@ void SurfaceSdlGraphicsManager::blitCursor() {
 #else
 	byte color;
 #endif
-	int w, h, i, j;
 
-	if (!_mouseOrigSurface || !_mouseData)
+	int w = _mouseCurState.w;
+	int h = _mouseCurState.h;
+
+	if (!_mouseOrigSurface || !_mouseData || !w || !h)
 		return;
 
 	_cursorNeedsRedraw = true;
 
-	w = _mouseCurState.w;
-	h = _mouseCurState.h;
-
 	SDL_LockSurface(_mouseOrigSurface);
 
 	// Make whole surface transparent
-	for (i = 0; i < h + 2; i++) {
+	for (int i = 0; i < h + 2; i++) {
 		dstPtr = (byte *)_mouseOrigSurface->pixels + _mouseOrigSurface->pitch * i;
-		for (j = 0; j < w + 2; j++) {
+		for (int j = 0; j < w + 2; j++) {
 			*(uint16 *)dstPtr = kMouseColorKey;
 			dstPtr += 2;
 		}
@@ -1959,8 +1959,8 @@ void SurfaceSdlGraphicsManager::blitCursor() {
 	else
 		palette = _cursorPalette;
 
-	for (i = 0; i < h; i++) {
-		for (j = 0; j < w; j++) {
+	for (int i = 0; i < h; i++) {
+		for (int j = 0; j < w; j++) {
 #ifdef USE_RGB_COLOR
 			if (_cursorFormat.bytesPerPixel > 1) {
 				if (_cursorFormat.bytesPerPixel == 2)
@@ -2112,7 +2112,7 @@ void SurfaceSdlGraphicsManager::undrawMouse() {
 }
 
 void SurfaceSdlGraphicsManager::drawMouse() {
-	if (!_cursorVisible || !_mouseSurface) {
+	if (!_cursorVisible || !_mouseSurface || !_mouseCurState.w || !_mouseCurState.h) {
 		_mouseBackup.x = _mouseBackup.y = _mouseBackup.w = _mouseBackup.h = 0;
 		return;
 	}


Commit: 9e9972a55b6a9e19f8bff37e023d622262e22096
    https://github.com/scummvm/scummvm/commit/9e9972a55b6a9e19f8bff37e023d622262e22096
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-10-15T13:24:20-05:00

Commit Message:
GRAPHICS: Send blank cursors to graphics backends

Blank cursors don't mean to continue drawing the previous cursor,
they mean that the cursor in the backend needs to be blank.

Changed paths:
    graphics/cursorman.cpp


diff --git a/graphics/cursorman.cpp b/graphics/cursorman.cpp
index 5fcd2a3..678b074 100644
--- a/graphics/cursorman.cpp
+++ b/graphics/cursorman.cpp
@@ -65,9 +65,7 @@ void CursorManager::pushCursor(const void *buf, uint w, uint h, int hotspotX, in
 	cur->_visible = isVisible();
 	_cursorStack.push(cur);
 
-	if (buf) {
-		g_system->setMouseCursor(cur->_data, w, h, hotspotX, hotspotY, keycolor, dontScale, format);
-	}
+	g_system->setMouseCursor(cur->_data, w, h, hotspotX, hotspotY, keycolor, dontScale, format);
 }
 
 void CursorManager::popCursor() {
@@ -80,6 +78,8 @@ void CursorManager::popCursor() {
 	if (!_cursorStack.empty()) {
 		cur = _cursorStack.top();
 		g_system->setMouseCursor(cur->_data, cur->_width, cur->_height, cur->_hotspotX, cur->_hotspotY, cur->_keycolor, cur->_dontScale, &cur->_format);
+	} else {
+		g_system->setMouseCursor(nullptr, 0, 0, 0, 0, 0);
 	}
 
 	g_system->showMouse(isVisible());
@@ -99,6 +99,7 @@ void CursorManager::popAllCursors() {
 		}
 	}
 
+	g_system->setMouseCursor(nullptr, 0, 0, 0, 0, 0);
 	g_system->showMouse(isVisible());
 }
 


Commit: 319ab07fe0900e6ec2f89666b544e695edca6dde
    https://github.com/scummvm/scummvm/commit/319ab07fe0900e6ec2f89666b544e695edca6dde
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-10-15T13:24:20-05:00

Commit Message:
SDL: Minor code cleanup to declare variables at point of first use

Changed paths:
    backends/graphics/surfacesdl/surfacesdl-graphics.cpp


diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
index 9b6cbb9..ceb1a37 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
@@ -1991,9 +1991,7 @@ void SurfaceSdlGraphicsManager::blitCursor() {
 		dstPtr += _mouseOrigSurface->pitch - w * 2;
 	}
 
-	int rW, rH;
 	int cursorScale;
-
 	if (_cursorDontScale) {
 		// Don't scale the cursor at all if the user requests this behavior.
 		cursorScale = 1;
@@ -2003,8 +2001,8 @@ void SurfaceSdlGraphicsManager::blitCursor() {
 	}
 
 	// Adapt the real hotspot according to the scale factor.
-	rW = w * cursorScale;
-	rH = h * cursorScale;
+	int rW = w * cursorScale;
+	int rH = h * cursorScale;
 	_mouseCurState.rHotX = _mouseCurState.hotX * cursorScale;
 	_mouseCurState.rHotY = _mouseCurState.hotY * cursorScale;
 


Commit: cd538ffffab9e49443da4ee043916d8dc22c3c07
    https://github.com/scummvm/scummvm/commit/cd538ffffab9e49443da4ee043916d8dc22c3c07
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-10-15T13:24:21-05:00

Commit Message:
BACKENDS: Do not send mouse events to games occurring outside the game draw rect

Changed paths:
    backends/events/sdl/sdl-events.cpp
    backends/events/sdl/sdl-events.h
    backends/graphics/sdl/sdl-graphics.cpp
    backends/graphics/sdl/sdl-graphics.h
    backends/graphics/windowed.h


diff --git a/backends/events/sdl/sdl-events.cpp b/backends/events/sdl/sdl-events.cpp
index db4aa21..6f34420 100644
--- a/backends/events/sdl/sdl-events.cpp
+++ b/backends/events/sdl/sdl-events.cpp
@@ -169,13 +169,15 @@ int SdlEventSource::mapKey(SDLKey sdlKey, SDLMod mod, Uint16 unicode) {
 	}
 }
 
-void SdlEventSource::processMouseEvent(Common::Event &event, int x, int y) {
+bool SdlEventSource::processMouseEvent(Common::Event &event, int x, int y) {
 	event.mouse.x = x;
 	event.mouse.y = y;
 
 	if (_graphicsManager) {
-		_graphicsManager->notifyMousePosition(event.mouse);
+		return _graphicsManager->notifyMousePosition(event.mouse);
 	}
+
+	return true;
 }
 
 bool SdlEventSource::handleKbdMouse(Common::Event &event) {
@@ -307,8 +309,7 @@ bool SdlEventSource::handleKbdMouse(Common::Event &event) {
 
 			if (_km.x != oldKmX || _km.y != oldKmY) {
 				event.type = Common::EVENT_MOUSEMOVE;
-				processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
-				return true;
+				return processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
 			}
 		}
 	}
@@ -548,7 +549,9 @@ bool SdlEventSource::dispatchSDLEvent(SDL_Event &ev, Common::Event &event) {
 		// 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 / MULTIPLIER, _km.y / MULTIPLIER);
+		if (!processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER)) {
+			return false;
+		}
 		if (yDir < 0) {
 			event.type = Common::EVENT_WHEELDOWN;
 			return true;
@@ -739,12 +742,12 @@ bool SdlEventSource::handleKeyUp(SDL_Event &ev, Common::Event &event) {
 
 bool SdlEventSource::handleMouseMotion(SDL_Event &ev, Common::Event &event) {
 	event.type = Common::EVENT_MOUSEMOVE;
-	processMouseEvent(event, ev.motion.x, ev.motion.y);
+
 	// update KbdMouse
 	_km.x = ev.motion.x * MULTIPLIER;
 	_km.y = ev.motion.y * MULTIPLIER;
 
-	return true;
+	return processMouseEvent(event, ev.motion.x, ev.motion.y);
 }
 
 bool SdlEventSource::handleMouseButtonDown(SDL_Event &ev, Common::Event &event) {
@@ -765,12 +768,11 @@ bool SdlEventSource::handleMouseButtonDown(SDL_Event &ev, Common::Event &event)
 	else
 		return false;
 
-	processMouseEvent(event, ev.button.x, ev.button.y);
 	// update KbdMouse
 	_km.x = ev.button.x * MULTIPLIER;
 	_km.y = ev.button.y * MULTIPLIER;
 
-	return true;
+	return processMouseEvent(event, ev.button.x, ev.button.y);
 }
 
 bool SdlEventSource::handleMouseButtonUp(SDL_Event &ev, Common::Event &event) {
@@ -784,21 +786,21 @@ bool SdlEventSource::handleMouseButtonUp(SDL_Event &ev, Common::Event &event) {
 #endif
 	else
 		return false;
-	processMouseEvent(event, ev.button.x, ev.button.y);
+
 	// update KbdMouse
 	_km.x = ev.button.x * MULTIPLIER;
 	_km.y = ev.button.y * MULTIPLIER;
 
-	return true;
+	return processMouseEvent(event, ev.button.x, ev.button.y);
 }
 
 bool SdlEventSource::handleJoyButtonDown(SDL_Event &ev, Common::Event &event) {
 	if (ev.jbutton.button == JOY_BUT_LMOUSE) {
 		event.type = Common::EVENT_LBUTTONDOWN;
-		processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
+		return processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
 	} else if (ev.jbutton.button == JOY_BUT_RMOUSE) {
 		event.type = Common::EVENT_RBUTTONDOWN;
-		processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
+		return processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
 	} else {
 		event.type = Common::EVENT_KEYDOWN;
 		switch (ev.jbutton.button) {
@@ -819,17 +821,17 @@ bool SdlEventSource::handleJoyButtonDown(SDL_Event &ev, Common::Event &event) {
 			event.kbd.ascii = mapKey(SDLK_F5, (SDLMod)ev.key.keysym.mod, 0);
 			break;
 		}
+		return true;
 	}
-	return true;
 }
 
 bool SdlEventSource::handleJoyButtonUp(SDL_Event &ev, Common::Event &event) {
 	if (ev.jbutton.button == JOY_BUT_LMOUSE) {
 		event.type = Common::EVENT_LBUTTONUP;
-		processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
+		return processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
 	} else if (ev.jbutton.button == JOY_BUT_RMOUSE) {
 		event.type = Common::EVENT_RBUTTONUP;
-		processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
+		return processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
 	} else {
 		event.type = Common::EVENT_KEYUP;
 		switch (ev.jbutton.button) {
@@ -850,8 +852,8 @@ bool SdlEventSource::handleJoyButtonUp(SDL_Event &ev, Common::Event &event) {
 			event.kbd.ascii = mapKey(SDLK_F5, (SDLMod)ev.key.keysym.mod, 0);
 			break;
 		}
+		return true;
 	}
-	return true;
 }
 
 bool SdlEventSource::handleJoyAxisMotion(SDL_Event &ev, Common::Event &event) {
diff --git a/backends/events/sdl/sdl-events.h b/backends/events/sdl/sdl-events.h
index cf445e9..1d701f5 100644
--- a/backends/events/sdl/sdl-events.h
+++ b/backends/events/sdl/sdl-events.h
@@ -117,7 +117,7 @@ protected:
 	 * Assigns the mouse coords to the mouse event. Furthermore notify the
 	 * graphics manager about the position change.
 	 */
-	virtual void processMouseEvent(Common::Event &event, int x, int y);
+	virtual bool processMouseEvent(Common::Event &event, int x, int y);
 
 	/**
 	 * Remaps key events. This allows platforms to configure
diff --git a/backends/graphics/sdl/sdl-graphics.cpp b/backends/graphics/sdl/sdl-graphics.cpp
index 6ce0bc7..e6699df 100644
--- a/backends/graphics/sdl/sdl-graphics.cpp
+++ b/backends/graphics/sdl/sdl-graphics.cpp
@@ -169,22 +169,47 @@ bool SdlGraphicsManager::showMouse(const bool visible) {
 	return WindowedGraphicsManager::showMouse(visible);
 }
 
-void SdlGraphicsManager::notifyMousePosition(Common::Point &mouse) {
+bool SdlGraphicsManager::notifyMousePosition(Common::Point &mouse) {
 	int showCursor = SDL_DISABLE;
-	if (!_activeArea.drawRect.contains(mouse)) {
+	bool valid = true;
+	if (_activeArea.drawRect.contains(mouse)) {
+		_cursorLastInActiveArea = true;
+	} else {
 		mouse.x = CLIP<int>(mouse.x, _activeArea.drawRect.left, _activeArea.drawRect.right - 1);
 		mouse.y = CLIP<int>(mouse.y, _activeArea.drawRect.top, _activeArea.drawRect.bottom - 1);
 
-		if (_window->mouseIsGrabbed()) {
+		if (_window->mouseIsGrabbed() ||
+			// Keep the mouse inside the game area during dragging to prevent an
+			// event mismatch where the mouseup event gets lost because it is
+			// performed outside of the game area
+			(_cursorLastInActiveArea && SDL_GetMouseState(nullptr, nullptr) != 0)) {
 			setSystemMousePosition(mouse.x, mouse.y);
-		} else if (_cursorVisible) {
-			showCursor = SDL_ENABLE;
+		} else {
+			// Allow the in-game mouse to get a final movement event to the edge
+			// of the window if the mouse was moved out of the game area
+			if (_cursorLastInActiveArea) {
+				_cursorLastInActiveArea = false;
+			} else if (_cursorVisible) {
+				// Keep sending events to the game if the cursor is invisible,
+				// since otherwise if a game lets you skip a cutscene by
+				// clicking and the user moved the mouse outside the active
+				// area, the clicks wouldn't do anything, which would be
+				// confusing
+				valid = false;
+			}
+
+			if (_cursorVisible) {
+				showCursor = SDL_ENABLE;
+			}
 		}
 	}
 
 	SDL_ShowCursor(showCursor);
-	setMousePosition(mouse.x, mouse.y);
-	mouse = convertWindowToVirtual(mouse.x, mouse.y);
+	if (valid) {
+		setMousePosition(mouse.x, mouse.y);
+		mouse = convertWindowToVirtual(mouse.x, mouse.y);
+	}
+	return valid;
 }
 
 void SdlGraphicsManager::handleResizeImpl(const int width, const int height) {
diff --git a/backends/graphics/sdl/sdl-graphics.h b/backends/graphics/sdl/sdl-graphics.h
index 772bc88..993a1c3 100644
--- a/backends/graphics/sdl/sdl-graphics.h
+++ b/backends/graphics/sdl/sdl-graphics.h
@@ -84,8 +84,10 @@ public:
 	 *
 	 * @param mouse The mouse position in window coordinates, which must be
 	 * converted synchronously to virtual coordinates.
+	 * @returns true if the mouse was in a valid position for the game and
+	 * should cause the event to be sent to the game.
 	 */
-	virtual void notifyMousePosition(Common::Point &mouse);
+	virtual bool notifyMousePosition(Common::Point &mouse);
 
 	virtual bool showMouse(const bool visible) override;
 
diff --git a/backends/graphics/windowed.h b/backends/graphics/windowed.h
index 52bb96c..1d4958c 100644
--- a/backends/graphics/windowed.h
+++ b/backends/graphics/windowed.h
@@ -39,7 +39,8 @@ public:
 		_cursorVisible(false),
 		_cursorX(0),
 		_cursorY(0),
-		_cursorNeedsRedraw(false) {}
+		_cursorNeedsRedraw(false),
+		_cursorLastInActiveArea(true) {}
 
 	virtual void showOverlay() override {
 		if (_overlayVisible)
@@ -304,6 +305,12 @@ protected:
 	bool _cursorNeedsRedraw;
 
 	/**
+	 * Whether the last position of the system cursor was within the active area
+	 * of the window.
+	 */
+	bool _cursorLastInActiveArea;
+
+	/**
 	 * The position of the mouse cursor, in window coordinates.
 	 */
 	int _cursorX, _cursorY;


Commit: d1b77d4b68fbf1129fd84a8d411d1c12d57ba0ee
    https://github.com/scummvm/scummvm/commit/d1b77d4b68fbf1129fd84a8d411d1c12d57ba0ee
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-10-15T13:24:21-05:00

Commit Message:
BACKENDS: Fix missing mouse events when system cursor cannot be moved

Normally with SDL, a mouse motion event will be sent after the
system mouse cursor has been moved by a call to
SDL_WarpMouseInWindow, but if the system cursor cannot be moved
(e.g. because the window does not have mouse focus), games still
need to receive these mouse events so they can successfully update
the mouse position internally. Otherwise, games continue to think
the mouse is still in the original position and will continue to
try to perform whatever action is associated with that mouse
position.

Refs Trac#9689.

Changed paths:
    backends/events/default/default-events.cpp
    backends/events/default/default-events.h
    backends/events/sdl/sdl-events.cpp
    backends/events/sdl/sdl-events.h
    backends/graphics/sdl/sdl-graphics.cpp
    backends/graphics/sdl/sdl-graphics.h
    backends/modular-backend.cpp
    backends/platform/sdl/sdl-window.cpp
    backends/platform/sdl/sdl-window.h
    common/events.h


diff --git a/backends/events/default/default-events.cpp b/backends/events/default/default-events.cpp
index c7c39da..667914b 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 f378fb9..38406c2 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 6f34420..91ca0f5 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 1d701f5..5fd3cb7 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 e6699df..64ee9f7 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 993a1c3..5263062 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 c9adbd3..944ddd5 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 a550fbb..fe27d84 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 4f6d924..e1a3499 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 21a65a6..e5bb8ca 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;
 


Commit: 8b112f57a9b5d27f79cebb28fa14ed7761270795
    https://github.com/scummvm/scummvm/commit/8b112f57a9b5d27f79cebb28fa14ed7761270795
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-10-15T13:24:21-05:00

Commit Message:
SDL: Support 32bpp cursor rendering

32bpp cursor scaling is not available, but this should be fine as
many of the software scalers are not designed to work with >16bpp
data in any case.

This change also includes some minor cleanup of unnecessary #ifdefs
around code that works equally well with or without USE_RGB_COLOR,
to simplify the implementation.

Changed paths:
    backends/graphics/surfacesdl/surfacesdl-graphics.cpp
    backends/graphics/surfacesdl/surfacesdl-graphics.h


diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
index ceb1a37..f025cfa 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
@@ -139,14 +139,12 @@ SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSou
 	_originalBitsPerPixel(0),
 #endif
 	_screen(0), _tmpscreen(0),
-#ifdef USE_RGB_COLOR
 	_screenFormat(Graphics::PixelFormat::createFormatCLUT8()),
 	_cursorFormat(Graphics::PixelFormat::createFormatCLUT8()),
-#endif
 	_overlayscreen(0), _tmpscreen2(0),
 	_scalerProc(0), _screenChangeCount(0),
-	_mouseData(0), _mouseSurface(0),
-	_mouseOrigSurface(0), _cursorDontScale(false), _cursorPaletteDisabled(true),
+	_mouseData(nullptr), _mouseSurface(nullptr),
+	_mouseOrigSurface(nullptr), _cursorDontScale(false), _cursorPaletteDisabled(true),
 	_currentShakePos(0), _newShakePos(0),
 	_paletteDirtyStart(0), _paletteDirtyEnd(0),
 	_screenIsLocked(false),
@@ -210,21 +208,19 @@ SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSou
 
 SurfaceSdlGraphicsManager::~SurfaceSdlGraphicsManager() {
 	unloadGFXMode();
-#if SDL_VERSION_ATLEAST(2, 0, 0)
-	if (_window)
-		_window->destroyWindow();
-#endif
-	if (_mouseSurface)
-		SDL_FreeSurface(_mouseSurface);
-	_mouseSurface = 0;
-	if (_mouseOrigSurface)
+	if (_mouseOrigSurface) {
 		SDL_FreeSurface(_mouseOrigSurface);
-	_mouseOrigSurface = 0;
+		if (_mouseOrigSurface == _mouseSurface) {
+			_mouseSurface = nullptr;
+		}
+	}
+	if (_mouseSurface) {
+		SDL_FreeSurface(_mouseSurface);
+	}
 	g_system->deleteMutex(_graphicsMutex);
-
 	free(_currentPalette);
 	free(_cursorPalette);
-	free(_mouseData);
+	delete[] _mouseData;
 }
 
 void SurfaceSdlGraphicsManager::activateManager() {
@@ -879,22 +875,20 @@ bool SurfaceSdlGraphicsManager::loadGFXMode() {
 	//
 	// Create the surface that contains the 8 bit game data
 	//
-#ifdef USE_RGB_COLOR
+
+	const Graphics::PixelFormat &format = _screenFormat;
+	const Uint32 rMask = ((0xFF >> format.rLoss) << format.rShift);
+	const Uint32 gMask = ((0xFF >> format.gLoss) << format.gShift);
+	const Uint32 bMask = ((0xFF >> format.bLoss) << format.bShift);
+	const Uint32 aMask = ((0xFF >> format.aLoss) << format.aShift);
 	_screen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth, _videoMode.screenHeight,
-						_screenFormat.bytesPerPixel << 3,
-						((1 << _screenFormat.rBits()) - 1) << _screenFormat.rShift ,
-						((1 << _screenFormat.gBits()) - 1) << _screenFormat.gShift ,
-						((1 << _screenFormat.bBits()) - 1) << _screenFormat.bShift ,
-						((1 << _screenFormat.aBits()) - 1) << _screenFormat.aShift );
+						_screenFormat.bytesPerPixel * 8, rMask, gMask, bMask, aMask);
 	if (_screen == NULL)
 		error("allocating _screen failed");
 
+#ifdef USE_RGB_COLOR
 	// Avoid having SDL_SRCALPHA set even if we supplied an alpha-channel in the format.
 	SDL_SetAlpha(_screen, 0, 255);
-#else
-	_screen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth, _videoMode.screenHeight, 8, 0, 0, 0, 0);
-	if (_screen == NULL)
-		error("allocating _screen failed");
 #endif
 
 	// SDL 1.2 palettes default to all black,
@@ -1486,7 +1480,6 @@ void SurfaceSdlGraphicsManager::copyRectToScreen(const void *buf, int pitch, int
 	if (SDL_LockSurface(_screen) == -1)
 		error("SDL_LockSurface failed: %s", SDL_GetError());
 
-#ifdef USE_RGB_COLOR
 	byte *dst = (byte *)_screen->pixels + y * _screen->pitch + x * _screenFormat.bytesPerPixel;
 	if (_videoMode.screenWidth == w && pitch == _screen->pitch) {
 		memcpy(dst, buf, h*pitch);
@@ -1498,19 +1491,6 @@ void SurfaceSdlGraphicsManager::copyRectToScreen(const void *buf, int pitch, int
 			dst += _screen->pitch;
 		} while (--h);
 	}
-#else
-	byte *dst = (byte *)_screen->pixels + y * _screen->pitch + x;
-	if (_screen->pitch == pitch && pitch == w) {
-		memcpy(dst, buf, h*w);
-	} else {
-		const byte *src = (const byte *)buf;
-		do {
-			memcpy(dst, src, w);
-			src += pitch;
-			dst += _screen->pitch;
-		} while (--h);
-	}
-#endif
 
 	// Unlock the screen surface
 	SDL_UnlockSurface(_screen);
@@ -1530,13 +1510,7 @@ Graphics::Surface *SurfaceSdlGraphicsManager::lockScreen() {
 	if (SDL_LockSurface(_screen) == -1)
 		error("SDL_LockSurface failed: %s", SDL_GetError());
 
-	_framebuffer.init(_screen->w, _screen->h, _screen->pitch, _screen->pixels,
-#ifdef USE_RGB_COLOR
-	                  _screenFormat
-#else
-	                  Graphics::PixelFormat::createFormatCLUT8()
-#endif
-	                 );
+	_framebuffer.init(_screen->w, _screen->h, _screen->pitch, _screen->pixels, _screenFormat);
 
 	return &_framebuffer;
 }
@@ -1643,10 +1617,7 @@ int16 SurfaceSdlGraphicsManager::getWidth() const {
 
 void SurfaceSdlGraphicsManager::setPalette(const byte *colors, uint start, uint num) {
 	assert(colors);
-
-#ifdef USE_RGB_COLOR
 	assert(_screenFormat.bytesPerPixel == 1);
-#endif
 
 	// Setting the palette before _screen is created is allowed - for now -
 	// since we don't actually set the palette until the screen is updated.
@@ -1680,10 +1651,7 @@ void SurfaceSdlGraphicsManager::setPalette(const byte *colors, uint start, uint
 
 void SurfaceSdlGraphicsManager::grabPalette(byte *colors, uint start, uint num) const {
 	assert(colors);
-
-#ifdef USE_RGB_COLOR
 	assert(_screenFormat.bytesPerPixel == 1);
-#endif
 
 	const SDL_Color *base = _currentPalette + start;
 
@@ -1863,23 +1831,27 @@ void SurfaceSdlGraphicsManager::copyRectToOverlay(const void *buf, int pitch, in
 #pragma mark --- Mouse ---
 #pragma mark -
 
-void SurfaceSdlGraphicsManager::setMouseCursor(const void *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
-#ifdef USE_RGB_COLOR
-	if (!format)
-		_cursorFormat = Graphics::PixelFormat::createFormatCLUT8();
-	else if (format->bytesPerPixel <= _screenFormat.bytesPerPixel)
+void SurfaceSdlGraphicsManager::setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keyColor, bool dontScale, const Graphics::PixelFormat *format) {
+	if (format) {
+#ifndef USE_RGB_COLOR
+		assert(format->bytesPerPixel == 1);
+#endif
 		_cursorFormat = *format;
+	} else {
+		_cursorFormat = Graphics::PixelFormat::createFormatCLUT8();
+	}
 
-	if (_cursorFormat.bytesPerPixel < 4)
-		assert(keycolor < (uint)(1 << (_cursorFormat.bytesPerPixel << 3)));
-#else
-	assert(keycolor <= 0xFF);
-#endif
+	if (_cursorFormat.bytesPerPixel == 4) {
+		assert(keyColor == 0);
+		dontScale = true;
+	} else {
+		assert(keyColor < 1U << (_cursorFormat.bytesPerPixel * 8));
+	}
 
-	_mouseCurState.hotX = hotspot_x;
-	_mouseCurState.hotY = hotspot_y;
+	_mouseCurState.hotX = hotspotX;
+	_mouseCurState.hotY = hotspotY;
 
-	_mouseKeyColor = keycolor;
+	_mouseKeyColor = keyColor;
 
 	_cursorDontScale = dontScale;
 
@@ -1891,55 +1863,123 @@ void SurfaceSdlGraphicsManager::setMouseCursor(const void *buf, uint w, uint h,
 			return;
 		}
 
-		if (_mouseOrigSurface)
+		if (_mouseOrigSurface) {
 			SDL_FreeSurface(_mouseOrigSurface);
 
-		// Allocate bigger surface because AdvMame2x adds black pixel at [0,0]
-		_mouseOrigSurface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA,
-						_mouseCurState.w + 2,
-						_mouseCurState.h + 2,
-						16,
-						_hwScreen->format->Rmask,
-						_hwScreen->format->Gmask,
-						_hwScreen->format->Bmask,
-						_hwScreen->format->Amask);
+			if (_mouseSurface == _mouseOrigSurface) {
+				_mouseSurface = nullptr;
+			}
+		}
+
+		if (_cursorFormat.bytesPerPixel == 4) {
+			if (_mouseSurface != _mouseOrigSurface) {
+				SDL_FreeSurface(_mouseSurface);
+			}
+
+			const Uint32 rMask = ((0xFF >> format->rLoss) << format->rShift);
+			const Uint32 gMask = ((0xFF >> format->gLoss) << format->gShift);
+			const Uint32 bMask = ((0xFF >> format->bLoss) << format->bShift);
+			const Uint32 aMask = ((0xFF >> format->aLoss) << format->aShift);
+			_mouseSurface = _mouseOrigSurface = SDL_CreateRGBSurfaceFrom(const_cast<void *>(buf), w, h, format->bytesPerPixel * 8, w * format->bytesPerPixel, rMask, gMask, bMask, aMask);
+		} else {
+			// Allocate bigger surface because AdvMame2x adds black pixel at [0,0]
+			_mouseOrigSurface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA,
+							_mouseCurState.w + 2,
+							_mouseCurState.h + 2,
+							16,
+							_hwScreen->format->Rmask,
+							_hwScreen->format->Gmask,
+							_hwScreen->format->Bmask,
+							_hwScreen->format->Amask);
+		}
 
-		if (_mouseOrigSurface == NULL)
-			error("allocating _mouseOrigSurface failed");
-		SDL_SetColorKey(_mouseOrigSurface, SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA, kMouseColorKey);
+		if (_mouseOrigSurface == nullptr) {
+			error("Allocating _mouseOrigSurface failed");
+		}
+
+		if (_cursorFormat.bytesPerPixel < 4) {
+			SDL_SetColorKey(_mouseOrigSurface, SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA, kMouseColorKey);
+		}
 	}
 
-	free(_mouseData);
-#ifdef USE_RGB_COLOR
-	_mouseData = (byte *)malloc(w * h * _cursorFormat.bytesPerPixel);
-	memcpy(_mouseData, buf, w * h * _cursorFormat.bytesPerPixel);
-#else
-	_mouseData = (byte *)malloc(w * h);
-	memcpy(_mouseData, buf, w * h);
-#endif
+	delete[] _mouseData;
+	if (_cursorFormat.bytesPerPixel == 4) {
+		_mouseData = nullptr;
+	} else {
+		_mouseData = new byte[w * h * _cursorFormat.bytesPerPixel];
+		assert(_mouseData);
+		memcpy(_mouseData, buf, w * h * _cursorFormat.bytesPerPixel);
+	}
 
 	blitCursor();
 }
 
 void SurfaceSdlGraphicsManager::blitCursor() {
-	byte *dstPtr;
-	const byte *srcPtr = _mouseData;
-#ifdef USE_RGB_COLOR
-	uint32 color;
-#else
-	byte color;
-#endif
+	const int w = _mouseCurState.w;
+	const int h = _mouseCurState.h;
 
-	int w = _mouseCurState.w;
-	int h = _mouseCurState.h;
+	if (!w || !h || !_mouseOrigSurface) {
+		return;
+	}
 
-	if (!_mouseOrigSurface || !_mouseData || !w || !h)
+	if (_cursorFormat.bytesPerPixel != 4 && !_mouseData) {
 		return;
+	}
 
 	_cursorNeedsRedraw = true;
 
+	int cursorScale;
+	if (_cursorDontScale) {
+		// Don't scale the cursor at all if the user requests this behavior.
+		cursorScale = 1;
+	} else {
+		// Scale the cursor with the game screen scale factor.
+		cursorScale = _videoMode.scaleFactor;
+	}
+
+	assert(_cursorFormat.bytesPerPixel != 4 || cursorScale == 1);
+
+	// Adapt the real hotspot according to the scale factor.
+	int rW = w * cursorScale;
+	int rH = h * cursorScale;
+	_mouseCurState.rHotX = _mouseCurState.hotX * cursorScale;
+	_mouseCurState.rHotY = _mouseCurState.hotY * cursorScale;
+
+	// The virtual dimensions will be the same as the original.
+
+	_mouseCurState.vW = w;
+	_mouseCurState.vH = h;
+	_mouseCurState.vHotX = _mouseCurState.hotX;
+	_mouseCurState.vHotY = _mouseCurState.hotY;
+
+#ifdef USE_SCALERS
+	// store original to pass to aspect-correction function later
+	const int rH1 = rH;
+#endif
+
+	if (!_cursorDontScale && _videoMode.aspectRatioCorrection) {
+		rH = real2Aspect(rH - 1) + 1;
+		_mouseCurState.rHotY = real2Aspect(_mouseCurState.rHotY);
+	}
+
+	bool sizeChanged = false;
+	if (_mouseCurState.rW != rW || _mouseCurState.rH != rH) {
+		_mouseCurState.rW = rW;
+		_mouseCurState.rH = rH;
+		sizeChanged = true;
+	}
+
+	// 32bpp always blits directly, so no need to do any more work here
+	if (_cursorFormat.bytesPerPixel == 4) {
+		return;
+	}
+
 	SDL_LockSurface(_mouseOrigSurface);
 
+	byte *dstPtr;
+	const byte *srcPtr = _mouseData;
+	uint32 color;
+
 	// Make whole surface transparent
 	for (int i = 0; i < h + 2; i++) {
 		dstPtr = (byte *)_mouseOrigSurface->pixels + _mouseOrigSurface->pitch * i;
@@ -1961,71 +2001,29 @@ void SurfaceSdlGraphicsManager::blitCursor() {
 
 	for (int i = 0; i < h; i++) {
 		for (int j = 0; j < w; j++) {
-#ifdef USE_RGB_COLOR
-			if (_cursorFormat.bytesPerPixel > 1) {
-				if (_cursorFormat.bytesPerPixel == 2)
-					color = *(const uint16 *)srcPtr;
-				else
-					color = *(const uint32 *)srcPtr;
-				if (color != _mouseKeyColor) {	// transparent, don't draw
+			if (_cursorFormat.bytesPerPixel == 2) {
+				color = *(const uint16 *)srcPtr;
+				if (color != _mouseKeyColor) {
 					uint8 r, g, b;
 					_cursorFormat.colorToRGB(color, r, g, b);
-					*(uint16 *)dstPtr = SDL_MapRGB(_mouseOrigSurface->format,
-						r, g, b);
+					*(uint16 *)dstPtr = SDL_MapRGB(_mouseOrigSurface->format, r, g, b);
 				}
 				dstPtr += 2;
 				srcPtr += _cursorFormat.bytesPerPixel;
 			} else {
-#endif
 				color = *srcPtr;
-				if (color != _mouseKeyColor) {	// transparent, don't draw
+				if (color != _mouseKeyColor) {
 					*(uint16 *)dstPtr = SDL_MapRGB(_mouseOrigSurface->format,
 						palette[color].r, palette[color].g, palette[color].b);
 				}
 				dstPtr += 2;
 				srcPtr++;
-#ifdef USE_RGB_COLOR
 			}
-#endif
 		}
 		dstPtr += _mouseOrigSurface->pitch - w * 2;
 	}
 
-	int cursorScale;
-	if (_cursorDontScale) {
-		// Don't scale the cursor at all if the user requests this behavior.
-		cursorScale = 1;
-	} else {
-		// Scale the cursor with the game screen scale factor.
-		cursorScale = _videoMode.scaleFactor;
-	}
-
-	// Adapt the real hotspot according to the scale factor.
-	int rW = w * cursorScale;
-	int rH = h * cursorScale;
-	_mouseCurState.rHotX = _mouseCurState.hotX * cursorScale;
-	_mouseCurState.rHotY = _mouseCurState.hotY * cursorScale;
-
-	// The virtual dimensions will be the same as the original.
-
-	_mouseCurState.vW = w;
-	_mouseCurState.vH = h;
-	_mouseCurState.vHotX = _mouseCurState.hotX;
-	_mouseCurState.vHotY = _mouseCurState.hotY;
-
-#ifdef USE_SCALERS
-	int rH1 = rH; // store original to pass to aspect-correction function later
-#endif
-
-	if (!_cursorDontScale && _videoMode.aspectRatioCorrection) {
-		rH = real2Aspect(rH - 1) + 1;
-		_mouseCurState.rHotY = real2Aspect(_mouseCurState.rHotY);
-	}
-
-	if (_mouseCurState.rW != rW || _mouseCurState.rH != rH) {
-		_mouseCurState.rW = rW;
-		_mouseCurState.rH = rH;
-
+	if (sizeChanged) {
 		if (_mouseSurface)
 			SDL_FreeSurface(_mouseSurface);
 
@@ -2038,8 +2036,8 @@ void SurfaceSdlGraphicsManager::blitCursor() {
 						_hwScreen->format->Bmask,
 						_hwScreen->format->Amask);
 
-		if (_mouseSurface == NULL)
-			error("allocating _mouseSurface failed");
+		if (_mouseSurface == nullptr)
+			error("Allocating _mouseSurface failed");
 
 		SDL_SetColorKey(_mouseSurface, SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA, kMouseColorKey);
 	}
@@ -2159,10 +2157,17 @@ void SurfaceSdlGraphicsManager::drawMouse() {
 	dst.w = _mouseCurState.rW;
 	dst.h = _mouseCurState.rH;
 
+	// Alpha-blended cursors will happily blend into themselves if the hardware
+	// surface under the cursor is not reset first
+	if (!_forceRedraw && _cursorFormat.bytesPerPixel == 4) {
+		if (SDL_BlitSurface(_screen, &dst, _hwScreen, &dst) != 0)
+			error("SD_BlitSurface failed: %s", SDL_GetError());
+	}
+
 	// Note that SDL_BlitSurface() and addDirtyRect() will both perform any
 	// clipping necessary
 
-	if (SDL_BlitSurface(_mouseSurface, NULL, _hwScreen, &dst) != 0)
+	if (SDL_BlitSurface(_mouseSurface, nullptr, _hwScreen, &dst) != 0)
 		error("SDL_BlitSurface failed: %s", SDL_GetError());
 
 	// The screen will be updated using real surface coordinates, i.e.
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.h b/backends/graphics/surfacesdl/surfacesdl-graphics.h
index 0ed8d79..60f5d29 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.h
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.h
@@ -193,9 +193,9 @@ protected:
 
 	/** Unseen game screen */
 	SDL_Surface *_screen;
-#ifdef USE_RGB_COLOR
 	Graphics::PixelFormat _screenFormat;
 	Graphics::PixelFormat _cursorFormat;
+#ifdef USE_RGB_COLOR
 	Common::List<Graphics::PixelFormat> _supportedFormats;
 
 	/**


Commit: f6ab0e5c10921be55e719ba93f8b5b980d4439e7
    https://github.com/scummvm/scummvm/commit/f6ab0e5c10921be55e719ba93f8b5b980d4439e7
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-10-15T13:24:21-05:00

Commit Message:
SDL: Allow window size to be reset whenever launcher is visible

This ensures the window gets resized properly when a user changes
the scaler options in the GUI. Simply unlocking the window size on
a call to setGraphicsMode is not good enough, because the scaler
mode can be changed by games during mode switches, and we don't
want to reset the window size in that case.

Changed paths:
    backends/graphics/sdl/sdl-graphics.cpp


diff --git a/backends/graphics/sdl/sdl-graphics.cpp b/backends/graphics/sdl/sdl-graphics.cpp
index 64ee9f7..0e0a45a 100644
--- a/backends/graphics/sdl/sdl-graphics.cpp
+++ b/backends/graphics/sdl/sdl-graphics.cpp
@@ -231,11 +231,12 @@ bool SdlGraphicsManager::createOrUpdateWindow(int width, int height, const Uint3
 	}
 
 	// We only update the actual window when flags change (which usually means
-	// fullscreen mode is entered/exited) or when updates are forced so that we
+	// fullscreen mode is entered/exited), when updates are forced so that we
 	// do not reset the window size whenever a game makes a call to change the
 	// size or pixel format of the internal game surface (since a user may have
-	// resized the game window)
-	if (!_window->getSDLWindow() || _lastFlags != flags || _allowWindowSizeReset) {
+	// resized the game window), or when the launcher is visible (since a user
+	// may change the scaler, which should reset the window size)
+	if (!_window->getSDLWindow() || _lastFlags != flags || _overlayVisible || _allowWindowSizeReset) {
 		if (_hintedWidth) {
 			width = _hintedWidth;
 		}


Commit: 4757c24c683c2f2b8e3b55aa8d7a767aad9e947e
    https://github.com/scummvm/scummvm/commit/4757c24c683c2f2b8e3b55aa8d7a767aad9e947e
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-10-15T13:24:21-05:00

Commit Message:
BACKENDS: Fix up graphics manager ports with const & override where appropriate

Changed paths:
    backends/graphics/dinguxsdl/dinguxsdl-graphics.cpp
    backends/graphics/dinguxsdl/dinguxsdl-graphics.h
    backends/graphics/gph/gph-graphics.cpp
    backends/graphics/gph/gph-graphics.h
    backends/graphics/linuxmotosdl/linuxmotosdl-graphics.h
    backends/graphics/maemosdl/maemosdl-graphics.h
    backends/graphics/null/null-graphics.h
    backends/graphics/openpandora/op-graphics.h
    backends/graphics/psp2sdl/psp2sdl-graphics.h
    backends/graphics/samsungtvsdl/samsungtvsdl-graphics.cpp
    backends/graphics/samsungtvsdl/samsungtvsdl-graphics.h
    backends/graphics/symbiansdl/symbiansdl-graphics.cpp
    backends/graphics/symbiansdl/symbiansdl-graphics.h
    backends/graphics/wincesdl/wincesdl-graphics.cpp
    backends/graphics/wincesdl/wincesdl-graphics.h


diff --git a/backends/graphics/dinguxsdl/dinguxsdl-graphics.cpp b/backends/graphics/dinguxsdl/dinguxsdl-graphics.cpp
index 10605f4..3de6439 100644
--- a/backends/graphics/dinguxsdl/dinguxsdl-graphics.cpp
+++ b/backends/graphics/dinguxsdl/dinguxsdl-graphics.cpp
@@ -487,14 +487,6 @@ bool DINGUXSdlGraphicsManager::getFeatureState(OSystem::Feature f) {
 	}
 }
 
-SurfaceSdlGraphicsManager::MousePos *DINGUXSdlGraphicsManager::getMouseCurState() {
-	return &_mouseCurState;
-}
-
-SurfaceSdlGraphicsManager::VideoState *DINGUXSdlGraphicsManager::getVideoMode() {
-	return &_videoMode;
-}
-
 void DINGUXSdlGraphicsManager::warpMouse(int x, int y) {
 	if (_mouseCurState.x != x || _mouseCurState.y != y) {
 		if (_videoMode.mode == GFX_HALF && !_overlayVisible) {
diff --git a/backends/graphics/dinguxsdl/dinguxsdl-graphics.h b/backends/graphics/dinguxsdl/dinguxsdl-graphics.h
index 8a35610..89ee141 100644
--- a/backends/graphics/dinguxsdl/dinguxsdl-graphics.h
+++ b/backends/graphics/dinguxsdl/dinguxsdl-graphics.h
@@ -36,26 +36,23 @@ class DINGUXSdlGraphicsManager : public SurfaceSdlGraphicsManager {
 public:
 	DINGUXSdlGraphicsManager(SdlEventSource *boss, SdlWindow *window);
 
-	bool hasFeature(OSystem::Feature f);
-	void setFeatureState(OSystem::Feature f, bool enable);
-	bool getFeatureState(OSystem::Feature f);
-	int getDefaultGraphicsMode() const;
-
-	void initSize(uint w, uint h);
-	const OSystem::GraphicsMode *getSupportedGraphicsModes() const;
-	bool setGraphicsMode(const char *name);
-	bool setGraphicsMode(int mode);
-	void setGraphicsModeIntern();
-	void internUpdateScreen();
-	void showOverlay();
-	void hideOverlay();
-	bool loadGFXMode();
-	void drawMouse();
-	void undrawMouse();
-	virtual void warpMouse(int x, int y);
-
-	SurfaceSdlGraphicsManager::MousePos *getMouseCurState();
-	SurfaceSdlGraphicsManager::VideoState *getVideoMode();
+	bool hasFeature(OSystem::Feature f) const override;
+	void setFeatureState(OSystem::Feature f, bool enable) override;
+	bool getFeatureState(OSystem::Feature f) override;
+	int getDefaultGraphicsMode() const override;
+
+	void initSize(uint w, uint h) override;
+	const OSystem::GraphicsMode *getSupportedGraphicsModes() const override;
+	bool setGraphicsMode(const char *name) override;
+	bool setGraphicsMode(int mode) override;
+	void setGraphicsModeIntern() override;
+	void internUpdateScreen() override;
+	void showOverlay() override;
+	void hideOverlay() override;
+	bool loadGFXMode() override;
+	void drawMouse() override;
+	void undrawMouse() override;
+	void warpMouse(int x, int y) override;
 
 	virtual void transformMouseCoordinates(Common::Point &point);
 };
diff --git a/backends/graphics/gph/gph-graphics.cpp b/backends/graphics/gph/gph-graphics.cpp
index 767fb57..e2c8411 100644
--- a/backends/graphics/gph/gph-graphics.cpp
+++ b/backends/graphics/gph/gph-graphics.cpp
@@ -477,7 +477,7 @@ bool GPHGraphicsManager::loadGFXMode() {
 	return true;
 }
 
-bool GPHGraphicsManager::hasFeature(OSystem::Feature f) {
+bool GPHGraphicsManager::hasFeature(OSystem::Feature f) const {
 	return
 	    (f == OSystem::kFeatureAspectRatioCorrection) ||
 	    (f == OSystem::kFeatureCursorPalette);
@@ -497,7 +497,7 @@ void GPHGraphicsManager::setFeatureState(OSystem::Feature f, bool enable) {
 	}
 }
 
-bool GPHGraphicsManager::getFeatureState(OSystem::Feature f) {
+bool GPHGraphicsManager::getFeatureState(OSystem::Feature f) const {
 	assert(_transactionMode == kTransactionNone);
 
 	switch (f) {
@@ -510,14 +510,6 @@ bool GPHGraphicsManager::getFeatureState(OSystem::Feature f) {
 	}
 }
 
-SurfaceSdlGraphicsManager::MousePos *GPHGraphicsManager::getMouseCurState() {
-	return &_mouseCurState;
-}
-
-SurfaceSdlGraphicsManager::VideoState *GPHGraphicsManager::getVideoMode() {
-	return &_videoMode;
-}
-
 void GPHGraphicsManager::warpMouse(int x, int y) {
 	if (_mouseCurState.x != x || _mouseCurState.y != y) {
 		if (_videoMode.mode == GFX_HALF && !_overlayVisible) {
diff --git a/backends/graphics/gph/gph-graphics.h b/backends/graphics/gph/gph-graphics.h
index 152d29d..69e3b89 100644
--- a/backends/graphics/gph/gph-graphics.h
+++ b/backends/graphics/gph/gph-graphics.h
@@ -35,26 +35,23 @@ class GPHGraphicsManager : public SurfaceSdlGraphicsManager {
 public:
 	GPHGraphicsManager(SdlEventSource *boss, SdlWindow *window);
 
-	bool hasFeature(OSystem::Feature f);
-	void setFeatureState(OSystem::Feature f, bool enable);
-	bool getFeatureState(OSystem::Feature f);
-	int getDefaultGraphicsMode() const;
-
-	void initSize(uint w, uint h, const Graphics::PixelFormat *format = NULL);
-	const OSystem::GraphicsMode *getSupportedGraphicsModes() const;
-	bool setGraphicsMode(const char *name);
-	bool setGraphicsMode(int mode);
-	void setGraphicsModeIntern();
-	void internUpdateScreen();
-	void showOverlay();
-	void hideOverlay();
-	bool loadGFXMode();
-	void drawMouse();
-	void undrawMouse();
-	virtual void warpMouse(int x, int y);
-
-	SurfaceSdlGraphicsManager::MousePos *getMouseCurState();
-	SurfaceSdlGraphicsManager::VideoState *getVideoMode();
+	bool hasFeature(OSystem::Feature f) const override;
+	void setFeatureState(OSystem::Feature f, bool enable) override;
+	bool getFeatureState(OSystem::Feature f) const;
+	int getDefaultGraphicsMode() const override;
+
+	void initSize(uint w, uint h, const Graphics::PixelFormat *format = NULL) override;
+	const OSystem::GraphicsMode *getSupportedGraphicsModes() const override;
+	bool setGraphicsMode(const char *name) override;
+	bool setGraphicsMode(int mode) override;
+	void setGraphicsModeIntern() override;
+	void internUpdateScreen() override;
+	void showOverlay() override;
+	void hideOverlay() override;
+	bool loadGFXMode() override;
+	void drawMouse() override;
+	void undrawMouse() override;
+	void warpMouse(int x, int y) override;
 
 	virtual void transformMouseCoordinates(Common::Point &point);
 };
diff --git a/backends/graphics/linuxmotosdl/linuxmotosdl-graphics.h b/backends/graphics/linuxmotosdl/linuxmotosdl-graphics.h
index d7a13b1..e7f96e8 100644
--- a/backends/graphics/linuxmotosdl/linuxmotosdl-graphics.h
+++ b/backends/graphics/linuxmotosdl/linuxmotosdl-graphics.h
@@ -29,18 +29,18 @@ class LinuxmotoSdlGraphicsManager : public SurfaceSdlGraphicsManager {
 public:
 	LinuxmotoSdlGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window);
 
-	virtual void initSize(uint w, uint h);
-	virtual void setGraphicsModeIntern();
-	virtual bool setGraphicsMode(int mode);
-	virtual void internUpdateScreen();
-	virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const;
-	virtual int getDefaultGraphicsMode() const;
-	virtual bool loadGFXMode();
-	virtual void drawMouse();
-	virtual void undrawMouse();
-	virtual void showOverlay();
-	virtual void hideOverlay();
-	virtual void warpMouse(int x, int y);
+	virtual void initSize(uint w, uint h) override;
+	virtual void setGraphicsModeIntern() override;
+	virtual bool setGraphicsMode(int mode) override;
+	virtual void internUpdateScreen() override;
+	virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const override;
+	virtual int getDefaultGraphicsMode() const override;
+	virtual bool loadGFXMode() override;
+	virtual void drawMouse() override;
+	virtual void undrawMouse() override;
+	virtual void showOverlay() override;
+	virtual void hideOverlay() override;
+	virtual void warpMouse(int x, int y) override;
 
 	virtual void transformMouseCoordinates(Common::Point &point);
 };
diff --git a/backends/graphics/maemosdl/maemosdl-graphics.h b/backends/graphics/maemosdl/maemosdl-graphics.h
index 4cb84c8..ff4278b 100644
--- a/backends/graphics/maemosdl/maemosdl-graphics.h
+++ b/backends/graphics/maemosdl/maemosdl-graphics.h
@@ -32,7 +32,7 @@ public:
 	MaemoSdlGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window);
 
 protected:
-	virtual bool loadGFXMode();
+	virtual bool loadGFXMode() override;
 };
 
 #endif
diff --git a/backends/graphics/null/null-graphics.h b/backends/graphics/null/null-graphics.h
index a870a76..4c62856 100644
--- a/backends/graphics/null/null-graphics.h
+++ b/backends/graphics/null/null-graphics.h
@@ -31,55 +31,55 @@ class NullGraphicsManager : public GraphicsManager {
 public:
 	virtual ~NullGraphicsManager() {}
 
-	bool hasFeature(OSystem::Feature f) { return false; }
-	void setFeatureState(OSystem::Feature f, bool enable) {}
-	bool getFeatureState(OSystem::Feature f) { return false; }
+	bool hasFeature(OSystem::Feature f) const override { return false; }
+	void setFeatureState(OSystem::Feature f, bool enable) override {}
+	bool getFeatureState(OSystem::Feature f) const override { return false; }
 
-	const OSystem::GraphicsMode *getSupportedGraphicsModes() const { return s_noGraphicsModes; }
-	int getDefaultGraphicsMode() const { return 0; }
-	bool setGraphicsMode(int mode) { return true; }
-	void resetGraphicsScale(){}
-	int getGraphicsMode() const { return 0; }
-	inline Graphics::PixelFormat getScreenFormat() const {
+	const OSystem::GraphicsMode *getSupportedGraphicsModes() const override { return s_noGraphicsModes; }
+	int getDefaultGraphicsMode() const override { return 0; }
+	bool setGraphicsMode(int mode) override { return true; }
+	void resetGraphicsScale() override {}
+	int getGraphicsMode() const override { return 0; }
+	inline Graphics::PixelFormat getScreenFormat() const override {
 		return Graphics::PixelFormat::createFormatCLUT8();
 	}
-	inline Common::List<Graphics::PixelFormat> getSupportedFormats() const {
+	inline Common::List<Graphics::PixelFormat> getSupportedFormats() const override {
 		Common::List<Graphics::PixelFormat> list;
 		list.push_back(Graphics::PixelFormat::createFormatCLUT8());
 		return list;
 	}
-	void initSize(uint width, uint height, const Graphics::PixelFormat *format = NULL) {}
-	virtual int getScreenChangeID() const { return 0; }
+	void initSize(uint width, uint height, const Graphics::PixelFormat *format = NULL) override {}
+	virtual int getScreenChangeID() const override { return 0; }
 
-	void beginGFXTransaction() {}
-	OSystem::TransactionError endGFXTransaction() { return OSystem::kTransactionSuccess; }
+	void beginGFXTransaction() override {}
+	OSystem::TransactionError endGFXTransaction() override { return OSystem::kTransactionSuccess; }
 
-	int16 getHeight() const { return 0; }
-	int16 getWidth() const { return 0; }
-	void setPalette(const byte *colors, uint start, uint num) {}
-	void grabPalette(byte *colors, uint start, uint num) {}
-	void copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) {}
-	Graphics::Surface *lockScreen() { return NULL; }
-	void unlockScreen() {}
-	void fillScreen(uint32 col) {}
-	void updateScreen() {}
-	void setShakePos(int shakeOffset) {}
-	void setFocusRectangle(const Common::Rect& rect) {}
-	void clearFocusRectangle() {}
+	int16 getHeight() const override { return 0; }
+	int16 getWidth() const override { return 0; }
+	void setPalette(const byte *colors, uint start, uint num) override {}
+	void grabPalette(byte *colors, uint start, uint num) const override {}
+	void copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) override {}
+	Graphics::Surface *lockScreen() override { return NULL; }
+	void unlockScreen() override {}
+	void fillScreen(uint32 col) override {}
+	void updateScreen() override {}
+	void setShakePos(int shakeOffset) override {}
+	void setFocusRectangle(const Common::Rect& rect) override {}
+	void clearFocusRectangle() override {}
 
-	void showOverlay() {}
-	void hideOverlay() {}
-	Graphics::PixelFormat getOverlayFormat() const { return Graphics::PixelFormat(); }
-	void clearOverlay() {}
-	void grabOverlay(void *buf, int pitch) {}
-	void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) {}
-	int16 getOverlayHeight() { return 0; }
-	int16 getOverlayWidth() { return 0; }
+	void showOverlay() override {}
+	void hideOverlay() override {}
+	Graphics::PixelFormat getOverlayFormat() const override { return Graphics::PixelFormat(); }
+	void clearOverlay() override {}
+	void grabOverlay(void *buf, int pitch) const override {}
+	void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) override {}
+	int16 getOverlayHeight() const override { return 0; }
+	int16 getOverlayWidth() const override { return 0; }
 
-	bool showMouse(bool visible) { return !visible; }
-	void warpMouse(int x, int y) {}
-	void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL) {}
-	void setCursorPalette(const byte *colors, uint start, uint num) {}
+	bool showMouse(bool visible) override { return !visible; }
+	void warpMouse(int x, int y) override {}
+	void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL) override {}
+	void setCursorPalette(const byte *colors, uint start, uint num) override {}
 };
 
 #endif
diff --git a/backends/graphics/openpandora/op-graphics.h b/backends/graphics/openpandora/op-graphics.h
index 5099407..56777dc 100644
--- a/backends/graphics/openpandora/op-graphics.h
+++ b/backends/graphics/openpandora/op-graphics.h
@@ -34,8 +34,8 @@ class OPGraphicsManager : public SurfaceSdlGraphicsManager {
 public:
 	OPGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window);
 
-	bool loadGFXMode();
-	void unloadGFXMode();
+	bool loadGFXMode() override;
+	void unloadGFXMode() override;
 };
 
 #endif /* BACKENDS_GRAPHICS_OP_H */
diff --git a/backends/graphics/psp2sdl/psp2sdl-graphics.h b/backends/graphics/psp2sdl/psp2sdl-graphics.h
index 638437c..0cabeb0 100644
--- a/backends/graphics/psp2sdl/psp2sdl-graphics.h
+++ b/backends/graphics/psp2sdl/psp2sdl-graphics.h
@@ -30,19 +30,19 @@ class PSP2SdlGraphicsManager : public SurfaceSdlGraphicsManager {
 public:
 	PSP2SdlGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window);
 	virtual ~PSP2SdlGraphicsManager();
-	
-	virtual OSystem::TransactionError endGFXTransaction();
-	virtual const OSystem::GraphicsMode *getSupportedShaders() const;
+
+	virtual OSystem::TransactionError endGFXTransaction() override;
+	virtual const OSystem::GraphicsMode *getSupportedShaders() const override;
 
 protected:
-	virtual void setGraphicsModeIntern();
-	virtual void unloadGFXMode();
-	virtual bool hotswapGFXMode();
-
-	virtual void internUpdateScreen();
-	virtual void updateShader();
-	virtual void setAspectRatioCorrection(bool enable);
-	virtual SDL_Surface *SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags);
+	virtual void setGraphicsModeIntern() override;
+	virtual void unloadGFXMode() override;
+	virtual bool hotswapGFXMode() override;
+
+	virtual void internUpdateScreen() override;
+	virtual void updateShader() override;
+	virtual void setAspectRatioCorrection(bool enable) override;
+	virtual SDL_Surface *SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags) override;
 	void PSP2_UpdateRects(SDL_Surface *screen, int numrects, SDL_Rect *rects);
 	void PSP2_UpdateFiltering();
 
diff --git a/backends/graphics/samsungtvsdl/samsungtvsdl-graphics.cpp b/backends/graphics/samsungtvsdl/samsungtvsdl-graphics.cpp
index 0c98462..befa793 100644
--- a/backends/graphics/samsungtvsdl/samsungtvsdl-graphics.cpp
+++ b/backends/graphics/samsungtvsdl/samsungtvsdl-graphics.cpp
@@ -32,7 +32,7 @@ SamsungTVSdlGraphicsManager::SamsungTVSdlGraphicsManager(SdlEventSource *sdlEven
 	: SurfaceSdlGraphicsManager(sdlEventSource, window) {
 }
 
-bool SamsungTVSdlGraphicsManager::hasFeature(OSystem::Feature f) {
+bool SamsungTVSdlGraphicsManager::hasFeature(OSystem::Feature f) const {
 	return
 		(f == OSystem::kFeatureAspectRatioCorrection) ||
 		(f == OSystem::kFeatureCursorPalette);
@@ -48,7 +48,7 @@ void SamsungTVSdlGraphicsManager::setFeatureState(OSystem::Feature f, bool enabl
 	}
 }
 
-bool SamsungTVSdlGraphicsManager::getFeatureState(OSystem::Feature f) {
+bool SamsungTVSdlGraphicsManager::getFeatureState(OSystem::Feature f) const {
 	switch (f) {
 	case OSystem::kFeatureAspectRatioCorrection:
 		return SurfaceSdlGraphicsManager::getFeatureState(f);
diff --git a/backends/graphics/samsungtvsdl/samsungtvsdl-graphics.h b/backends/graphics/samsungtvsdl/samsungtvsdl-graphics.h
index 8699d77..b86ebe2 100644
--- a/backends/graphics/samsungtvsdl/samsungtvsdl-graphics.h
+++ b/backends/graphics/samsungtvsdl/samsungtvsdl-graphics.h
@@ -31,9 +31,9 @@ class SamsungTVSdlGraphicsManager : public SurfaceSdlGraphicsManager {
 public:
 	SamsungTVSdlGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window);
 
-	bool hasFeature(OSystem::Feature f);
-	void setFeatureState(OSystem::Feature f, bool enable);
-	bool getFeatureState(OSystem::Feature f);
+	bool hasFeature(OSystem::Feature f) const override;
+	void setFeatureState(OSystem::Feature f, bool enable) override;
+	bool getFeatureState(OSystem::Feature f) const override;
 };
 
 #endif
diff --git a/backends/graphics/symbiansdl/symbiansdl-graphics.cpp b/backends/graphics/symbiansdl/symbiansdl-graphics.cpp
index c17cfd5..227674f 100644
--- a/backends/graphics/symbiansdl/symbiansdl-graphics.cpp
+++ b/backends/graphics/symbiansdl/symbiansdl-graphics.cpp
@@ -50,7 +50,7 @@ bool SymbianSdlGraphicsManager::setGraphicsMode(int /*name*/) {
 	return SurfaceSdlGraphicsManager::setGraphicsMode(getDefaultGraphicsMode());
 }
 
-bool SymbianSdlGraphicsManager::hasFeature(OSystem::Feature f) {
+bool SymbianSdlGraphicsManager::hasFeature(OSystem::Feature f) const {
 	switch (f) {
 	case OSystem::kFeatureFullscreenMode:
 	case OSystem::kFeatureAspectRatioCorrection:
diff --git a/backends/graphics/symbiansdl/symbiansdl-graphics.h b/backends/graphics/symbiansdl/symbiansdl-graphics.h
index fb9a49a..0fcfb70 100644
--- a/backends/graphics/symbiansdl/symbiansdl-graphics.h
+++ b/backends/graphics/symbiansdl/symbiansdl-graphics.h
@@ -30,12 +30,12 @@ public:
 	SymbianSdlGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window);
 
 public:
-	virtual bool hasFeature(OSystem::Feature f);
-	virtual void setFeatureState(OSystem::Feature f, bool enable);
+	virtual bool hasFeature(OSystem::Feature f) const override;
+	virtual void setFeatureState(OSystem::Feature f, bool enable) override;
 
-	virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const;
-	virtual int getDefaultGraphicsMode() const;
-	virtual bool setGraphicsMode(int mode);
+	virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const override;
+	virtual int getDefaultGraphicsMode() const override;
+	virtual bool setGraphicsMode(int mode) override;
 };
 
 #endif
diff --git a/backends/graphics/wincesdl/wincesdl-graphics.cpp b/backends/graphics/wincesdl/wincesdl-graphics.cpp
index 44a1214..1677eca 100644
--- a/backends/graphics/wincesdl/wincesdl-graphics.cpp
+++ b/backends/graphics/wincesdl/wincesdl-graphics.cpp
@@ -115,7 +115,7 @@ const OSystem::GraphicsMode *WINCESdlGraphicsManager::getSupportedGraphicsModes(
 		return s_supportedGraphicsModesLow;
 }
 
-bool WINCESdlGraphicsManager::hasFeature(OSystem::Feature f) {
+bool WINCESdlGraphicsManager::hasFeature(OSystem::Feature f) const {
 	return (f == OSystem::kFeatureVirtualKeyboard);
 }
 
@@ -153,7 +153,7 @@ void WINCESdlGraphicsManager::setFeatureState(OSystem::Feature f, bool enable) {
 	}
 }
 
-bool WINCESdlGraphicsManager::getFeatureState(OSystem::Feature f) {
+bool WINCESdlGraphicsManager::getFeatureState(OSystem::Feature f) const {
 	switch (f) {
 	case OSystem::kFeatureFullscreenMode:
 		return false;
diff --git a/backends/graphics/wincesdl/wincesdl-graphics.h b/backends/graphics/wincesdl/wincesdl-graphics.h
index 9316c69..4842d49 100644
--- a/backends/graphics/wincesdl/wincesdl-graphics.h
+++ b/backends/graphics/wincesdl/wincesdl-graphics.h
@@ -46,9 +46,9 @@ public:
 	const OSystem::GraphicsMode *getSupportedGraphicsModes() const;
 	void initSize(uint w, uint h, const Graphics::PixelFormat *format = NULL);
 
-	bool hasFeature(OSystem::Feature f);
+	bool hasFeature(OSystem::Feature f) const;
 	void setFeatureState(OSystem::Feature f, bool enable);
-	bool getFeatureState(OSystem::Feature f);
+	bool getFeatureState(OSystem::Feature f) const;
 
 	int getDefaultGraphicsMode() const;
 	bool setGraphicsMode(int mode);


Commit: 7d8d2f80fbc9cf96b3bd03b85a9722b576d23adc
    https://github.com/scummvm/scummvm/commit/7d8d2f80fbc9cf96b3bd03b85a9722b576d23adc
Author: Colin Snover (github.com at zetafleet.com)
Date: 2017-10-15T13:26:39-05:00

Commit Message:
Merge branch 'graphics-backends-improvements'

Changed paths:
  A backends/graphics/windowed.h
    backends/events/default/default-events.cpp
    backends/events/default/default-events.h
    backends/events/sdl/sdl-events.cpp
    backends/events/sdl/sdl-events.h
    backends/graphics/dinguxsdl/dinguxsdl-graphics.cpp
    backends/graphics/dinguxsdl/dinguxsdl-graphics.h
    backends/graphics/gph/gph-graphics.cpp
    backends/graphics/gph/gph-graphics.h
    backends/graphics/graphics.h
    backends/graphics/linuxmotosdl/linuxmotosdl-graphics.h
    backends/graphics/maemosdl/maemosdl-graphics.h
    backends/graphics/null/null-graphics.h
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/opengl/opengl-graphics.h
    backends/graphics/openglsdl/openglsdl-graphics.cpp
    backends/graphics/openglsdl/openglsdl-graphics.h
    backends/graphics/openpandora/op-graphics.h
    backends/graphics/psp2sdl/psp2sdl-graphics.h
    backends/graphics/samsungtvsdl/samsungtvsdl-graphics.cpp
    backends/graphics/samsungtvsdl/samsungtvsdl-graphics.h
    backends/graphics/sdl/sdl-graphics.cpp
    backends/graphics/sdl/sdl-graphics.h
    backends/graphics/surfacesdl/surfacesdl-graphics.cpp
    backends/graphics/surfacesdl/surfacesdl-graphics.h
    backends/graphics/symbiansdl/symbiansdl-graphics.cpp
    backends/graphics/symbiansdl/symbiansdl-graphics.h
    backends/graphics/wincesdl/wincesdl-graphics.cpp
    backends/graphics/wincesdl/wincesdl-graphics.h
    backends/modular-backend.cpp
    backends/platform/sdl/sdl-window.cpp
    backends/platform/sdl/sdl-window.h
    common/events.h
    graphics/cursorman.cpp
    graphics/palette.h







More information about the Scummvm-git-logs mailing list