From 627d766325e1d435816648f85dbf9c007269b3f2 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Mon, 16 Feb 2015 00:49:42 +0100 Subject: SDL: Add basic abstraction class for the SDL window. --- backends/platform/dingux/dingux.cpp | 2 +- backends/platform/gph/gph-backend.cpp | 2 +- backends/platform/linuxmoto/linuxmoto-sdl.cpp | 2 +- backends/platform/maemo/maemo.cpp | 2 +- backends/platform/openpandora/op-backend.cpp | 2 +- backends/platform/samsungtv/samsungtv.cpp | 2 +- backends/platform/sdl/module.mk | 3 +- backends/platform/sdl/sdl-window.cpp | 155 ++++++++++++++++++++++++++ backends/platform/sdl/sdl-window.h | 103 +++++++++++++++++ backends/platform/sdl/sdl.cpp | 24 ++-- backends/platform/sdl/sdl.h | 6 + backends/platform/symbian/src/SymbianOS.cpp | 2 +- backends/platform/wince/wince-sdl.cpp | 2 +- 13 files changed, 289 insertions(+), 18 deletions(-) create mode 100644 backends/platform/sdl/sdl-window.cpp create mode 100644 backends/platform/sdl/sdl-window.h (limited to 'backends/platform') diff --git a/backends/platform/dingux/dingux.cpp b/backends/platform/dingux/dingux.cpp index 2f11dd31ad..afd80acc1b 100644 --- a/backends/platform/dingux/dingux.cpp +++ b/backends/platform/dingux/dingux.cpp @@ -33,7 +33,7 @@ void OSystem_SDL_Dingux::initBackend() { // Create the graphics manager if (_graphicsManager == 0) { - _graphicsManager = new DINGUXSdlGraphicsManager(_eventSource); + _graphicsManager = new DINGUXSdlGraphicsManager(_eventSource, _window); } // Call parent implementation of this method diff --git a/backends/platform/gph/gph-backend.cpp b/backends/platform/gph/gph-backend.cpp index d033191d54..fb1cbe030c 100644 --- a/backends/platform/gph/gph-backend.cpp +++ b/backends/platform/gph/gph-backend.cpp @@ -159,7 +159,7 @@ void OSystem_GPH::initBackend() { // Create the graphics manager if (_graphicsManager == 0) { - _graphicsManager = new GPHGraphicsManager(_eventSource); + _graphicsManager = new GPHGraphicsManager(_eventSource, _window); } /* Pass to POSIX method to do the heavy lifting */ diff --git a/backends/platform/linuxmoto/linuxmoto-sdl.cpp b/backends/platform/linuxmoto/linuxmoto-sdl.cpp index a0310079de..a2b527e6ce 100644 --- a/backends/platform/linuxmoto/linuxmoto-sdl.cpp +++ b/backends/platform/linuxmoto/linuxmoto-sdl.cpp @@ -31,7 +31,7 @@ void OSystem_LINUXMOTO::initBackend() { _eventSource = new LinuxmotoSdlEventSource(); if (_graphicsManager == 0) - _graphicsManager = new LinuxmotoSdlGraphicsManager(_eventSource); + _graphicsManager = new LinuxmotoSdlGraphicsManager(_eventSource, _window); // Call parent implementation of this method OSystem_POSIX::initBackend(); diff --git a/backends/platform/maemo/maemo.cpp b/backends/platform/maemo/maemo.cpp index e81a208f7b..0ada9da313 100644 --- a/backends/platform/maemo/maemo.cpp +++ b/backends/platform/maemo/maemo.cpp @@ -93,7 +93,7 @@ void OSystem_SDL_Maemo::initBackend() { _eventSource = new MaemoSdlEventSource(); if (_graphicsManager == 0) - _graphicsManager = new MaemoSdlGraphicsManager(_eventSource); + _graphicsManager = new MaemoSdlGraphicsManager(_eventSource, _window); if (_eventObserver == 0) _eventObserver = new MaemoSdlEventObserver((MaemoSdlEventSource *)_eventSource); diff --git a/backends/platform/openpandora/op-backend.cpp b/backends/platform/openpandora/op-backend.cpp index abe288f5d7..e7975a6aa0 100644 --- a/backends/platform/openpandora/op-backend.cpp +++ b/backends/platform/openpandora/op-backend.cpp @@ -147,7 +147,7 @@ void OSystem_OP::initBackend() { // Create the graphics manager if (_graphicsManager == 0) { - _graphicsManager = new OPGraphicsManager(_eventSource); + _graphicsManager = new OPGraphicsManager(_eventSource, _window); } /* Pass to POSIX method to do the heavy lifting */ diff --git a/backends/platform/samsungtv/samsungtv.cpp b/backends/platform/samsungtv/samsungtv.cpp index a1d15930f2..a766916fab 100644 --- a/backends/platform/samsungtv/samsungtv.cpp +++ b/backends/platform/samsungtv/samsungtv.cpp @@ -40,7 +40,7 @@ void OSystem_SDL_SamsungTV::initBackend() { _eventSource = new SamsungTVSdlEventSource(); if (_graphicsManager == 0) - _graphicsManager = new SamsungTVSdlGraphicsManager(_eventSource); + _graphicsManager = new SamsungTVSdlGraphicsManager(_eventSource, _window); // Call parent implementation of this method OSystem_POSIX::initBackend(); diff --git a/backends/platform/sdl/module.mk b/backends/platform/sdl/module.mk index a17a326889..6da86706c6 100644 --- a/backends/platform/sdl/module.mk +++ b/backends/platform/sdl/module.mk @@ -1,7 +1,8 @@ MODULE := backends/platform/sdl MODULE_OBJS := \ - sdl.o + sdl.o \ + sdl-window.o ifdef POSIX MODULE_OBJS += \ diff --git a/backends/platform/sdl/sdl-window.cpp b/backends/platform/sdl/sdl-window.cpp new file mode 100644 index 0000000000..b8cf4cfb4d --- /dev/null +++ b/backends/platform/sdl/sdl-window.cpp @@ -0,0 +1,155 @@ +/* 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. + * + */ + +#define FORBIDDEN_SYMBOL_ALLOW_ALL + +#include "backends/platform/sdl/sdl-window.h" + +SdlWindow::SdlWindow() +#if SDL_VERSION_ATLEAST(2, 0, 0) + : _window(nullptr), _inputGrabState(false), _windowCaption("ScummVM"), _windowIcon(nullptr) +#endif + { +} + +SdlWindow::~SdlWindow() { +#if SDL_VERSION_ATLEAST(2, 0, 0) + SDL_FreeSurface(_windowIcon); + destroyWindow(); +#endif +} + +void SdlWindow::setWindowCaption(const Common::String &caption) { +#if SDL_VERSION_ATLEAST(2, 0, 0) + _windowCaption = caption; + if (_window) { + SDL_SetWindowTitle(_window, caption.c_str()); + } +#else + SDL_WM_SetCaption(caption.c_str(), caption.c_str()); +#endif +} + +void SdlWindow::setWindowIcon(SDL_Surface *icon) { +#if SDL_VERSION_ATLEAST(2, 0, 0) + SDL_FreeSurface(_windowIcon); + _windowIcon = icon; + if (_window) { + SDL_SetWindowIcon(_window, icon); + } +#else + SDL_WM_SetIcon(icon, NULL); + SDL_FreeSurface(icon); +#endif +} + +void SdlWindow::toggleMouseGrab() { +#if SDL_VERSION_ATLEAST(2, 0, 0) + if (_window) { + _inputGrabState = !(SDL_GetWindowGrab(_window) == SDL_TRUE); + SDL_SetWindowGrab(_window, _inputGrabState ? SDL_TRUE : SDL_FALSE); + } +#else + if (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_OFF) { + SDL_WM_GrabInput(SDL_GRAB_ON); + } else { + SDL_WM_GrabInput(SDL_GRAB_OFF); + } +#endif +} + +bool SdlWindow::hasMouseFocus() const { +#if SDL_VERSION_ATLEAST(2, 0, 0) + if (_window) { + return (SDL_GetWindowFlags(_window) & SDL_WINDOW_MOUSE_FOCUS); + } else { + return false; + } +#else + return (SDL_GetAppState() & SDL_APPMOUSEFOCUS); +#endif +} + +void SdlWindow::warpMouseInWindow(uint x, uint y) { +#if SDL_VERSION_ATLEAST(2, 0, 0) + if (_window) { + SDL_WarpMouseInWindow(_window, x, y); + } +#else + SDL_WarpMouse(x, y); +#endif +} + +void SdlWindow::iconifyWindow() { +#if SDL_VERSION_ATLEAST(2, 0, 0) + if (_window) { + SDL_MinimizeWindow(_window); + } +#else + SDL_WM_IconifyWindow(); +#endif +} + +#if SDL_VERSION_ATLEAST(2, 0, 0) +SDL_Surface *copySDLSurface(SDL_Surface *src) { + const bool locked = SDL_MUSTLOCK(src) == SDL_TRUE; + + if (locked) { + if (SDL_LockSurface(src) != 0) { + return nullptr; + } + } + + SDL_Surface *res = SDL_CreateRGBSurfaceFrom(src->pixels, + src->w, src->h, src->format->BitsPerPixel, + src->pitch, src->format->Rmask, src->format->Gmask, + src->format->Bmask, src->format->Amask); + + if (locked) { + SDL_UnlockSurface(src); + } + + return res; +} + +bool SdlWindow::createWindow(int width, int height, uint32 flags) { + destroyWindow(); + + if (_inputGrabState) { + flags |= SDL_WINDOW_INPUT_GRABBED; + } + + _window = SDL_CreateWindow(_windowCaption.c_str(), SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, width, height, flags); + if (!_window) { + return false; + } + SDL_SetWindowIcon(_window, _windowIcon); + + return true; +} + +void SdlWindow::destroyWindow() { + SDL_DestroyWindow(_window); + _window = nullptr; +} +#endif diff --git a/backends/platform/sdl/sdl-window.h b/backends/platform/sdl/sdl-window.h new file mode 100644 index 0000000000..da3dda7f2d --- /dev/null +++ b/backends/platform/sdl/sdl-window.h @@ -0,0 +1,103 @@ +/* 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_PLATFORM_SDL_WINDOW_H +#define BACKENDS_PLATFORM_SDL_WINDOW_H + +#include "backends/platform/sdl/sdl-sys.h" + +#include "common/str.h" + +class SdlWindow { +public: + SdlWindow(); + virtual ~SdlWindow(); + + /** + * Change the caption of the window. + * + * @param caption New window caption in UTF-8 encoding. + */ + void setWindowCaption(const Common::String &caption); + + /** + * Attach an icon to the window. + * + * @param icon The surface to use as icon. SdlGraphicsManager takes + * ownership over it. + */ + void setWindowIcon(SDL_Surface *icon); + + /** + * Toggle mouse grab state. This decides whether the cursor can leave the + * window or not. + */ + void toggleMouseGrab(); + + /** + * Check whether the application has mouse focus. + */ + bool hasMouseFocus() const; + + /** + * Warp the mouse to the specified position in window coordinates. + */ + void warpMouseInWindow(uint x, uint y); + + /** + * Iconifies the window. + */ + void iconifyWindow(); + +#if SDL_VERSION_ATLEAST(2, 0, 0) +public: + /** + * @return The window ScummVM has setup with SDL. + */ + SDL_Window *getSDLWindow() const { return _window; } + + /** + * Creates a new SDL window (and destroies the old one). + * + * @param width Width of the window. + * @param height Height of the window. + * @param flags SDL flags passed to SDL_CreateWindow + * @return true on success, false otherwise + */ + bool createWindow(int width, int height, uint32 flags); + + /** + * Destroies the current SDL window. + */ + void destroyWindow(); + +protected: + SDL_Window *_window; + +private: + bool _inputGrabState; + Common::String _windowCaption; + SDL_Surface *_windowIcon; +#endif +}; + +#endif diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp index 434a4ce18a..7978022d6b 100644 --- a/backends/platform/sdl/sdl.cpp +++ b/backends/platform/sdl/sdl.cpp @@ -77,7 +77,8 @@ OSystem_SDL::OSystem_SDL() _initedSDL(false), _logger(0), _mixerManager(0), - _eventSource(0) { + _eventSource(0), + _window(0) { } @@ -95,6 +96,8 @@ OSystem_SDL::~OSystem_SDL() { } delete _graphicsManager; _graphicsManager = 0; + delete _window; + _window = 0; delete _eventManager; _eventManager = 0; delete _eventSource; @@ -149,6 +152,9 @@ void OSystem_SDL::init() { if (_mutexManager == 0) _mutexManager = new SdlMutexManager(); + if (_window == 0) + _window = new SdlWindow(); + #if defined(USE_TASKBAR) if (_taskbarManager == 0) _taskbarManager = new Common::TaskbarManager(); @@ -210,7 +216,7 @@ void OSystem_SDL::initBackend() { Common::String gfxMode(ConfMan.get("gfx_mode")); for (uint i = _firstGLMode; i < _graphicsModeIds.size(); ++i) { if (!scumm_stricmp(_graphicsModes[i].name, gfxMode.c_str())) { - _graphicsManager = new OpenGLSdlGraphicsManager(_desktopWidth, _desktopHeight, _eventSource); + _graphicsManager = new OpenGLSdlGraphicsManager(_desktopWidth, _desktopHeight, _eventSource, _window); _graphicsMode = i; break; } @@ -219,7 +225,7 @@ void OSystem_SDL::initBackend() { #endif if (_graphicsManager == 0) { - _graphicsManager = new SurfaceSdlGraphicsManager(_eventSource); + _graphicsManager = new SurfaceSdlGraphicsManager(_eventSource, _window); } } @@ -328,7 +334,7 @@ void OSystem_SDL::setWindowCaption(const char *caption) { } } - dynamic_cast(_graphicsManager)->setWindowCaption(cap); + _window->setWindowCaption(cap); } void OSystem_SDL::quit() { @@ -491,7 +497,7 @@ void OSystem_SDL::setupIcon() { if (!sdl_surf) { warning("SDL_CreateRGBSurfaceFrom(icon) failed"); } - dynamic_cast(_graphicsManager)->setWindowIcon(sdl_surf); + _window->setWindowIcon(sdl_surf); free(icon); } @@ -596,14 +602,14 @@ bool OSystem_SDL::setGraphicsMode(int mode) { debug(1, "switching to plain SDL graphics"); sdlGraphicsManager->deactivateManager(); delete _graphicsManager; - _graphicsManager = sdlGraphicsManager = new SurfaceSdlGraphicsManager(_eventSource); + _graphicsManager = sdlGraphicsManager = new SurfaceSdlGraphicsManager(_eventSource, _window); switchedManager = true; } else if (_graphicsMode < _firstGLMode && mode >= _firstGLMode) { debug(1, "switching to OpenGL graphics"); sdlGraphicsManager->deactivateManager(); delete _graphicsManager; - _graphicsManager = sdlGraphicsManager = new OpenGLSdlGraphicsManager(_desktopWidth, _desktopHeight, _eventSource); + _graphicsManager = sdlGraphicsManager = new OpenGLSdlGraphicsManager(_desktopWidth, _desktopHeight, _eventSource, _window); switchedManager = true; } @@ -653,7 +659,7 @@ void OSystem_SDL::setupGraphicsModes() { const OSystem::GraphicsMode *srcMode; int defaultMode; - GraphicsManager *manager = new SurfaceSdlGraphicsManager(_eventSource); + GraphicsManager *manager = new SurfaceSdlGraphicsManager(_eventSource, _window); srcMode = manager->getSupportedGraphicsModes(); defaultMode = manager->getDefaultGraphicsMode(); while (srcMode->name) { @@ -667,7 +673,7 @@ void OSystem_SDL::setupGraphicsModes() { assert(_defaultSDLMode != -1); _firstGLMode = _graphicsModes.size(); - manager = new OpenGLSdlGraphicsManager(_desktopWidth, _desktopHeight, _eventSource); + manager = new OpenGLSdlGraphicsManager(_desktopWidth, _desktopHeight, _eventSource, _window); srcMode = manager->getSupportedGraphicsModes(); defaultMode = manager->getDefaultGraphicsMode(); while (srcMode->name) { diff --git a/backends/platform/sdl/sdl.h b/backends/platform/sdl/sdl.h index 5dcc269e55..0f07f6d18d 100644 --- a/backends/platform/sdl/sdl.h +++ b/backends/platform/sdl/sdl.h @@ -29,6 +29,7 @@ #include "backends/mixer/sdl/sdl-mixer.h" #include "backends/events/sdl/sdl-events.h" #include "backends/log/log.h" +#include "backends/platform/sdl/sdl-window.h" #include "common/array.h" @@ -91,6 +92,11 @@ protected: */ SdlEventSource *_eventSource; + /** + * The SDL output window. + */ + SdlWindow *_window; + virtual Common::EventSource *getDefaultEventSource() { return _eventSource; } /** diff --git a/backends/platform/symbian/src/SymbianOS.cpp b/backends/platform/symbian/src/SymbianOS.cpp index 1fca7f5df5..57903d3d26 100644 --- a/backends/platform/symbian/src/SymbianOS.cpp +++ b/backends/platform/symbian/src/SymbianOS.cpp @@ -109,7 +109,7 @@ void OSystem_SDL_Symbian::initBackend() { _mixerManager->init(); } if (_graphicsManager == 0) - _graphicsManager = new SymbianSdlGraphicsManager(_eventSource); + _graphicsManager = new SymbianSdlGraphicsManager(_eventSource, _window); // Call parent implementation of this method OSystem_SDL::initBackend(); diff --git a/backends/platform/wince/wince-sdl.cpp b/backends/platform/wince/wince-sdl.cpp index 96c9313c5d..c1b0c7f692 100644 --- a/backends/platform/wince/wince-sdl.cpp +++ b/backends/platform/wince/wince-sdl.cpp @@ -420,7 +420,7 @@ void OSystem_WINCE3::initBackend() { } if (_graphicsManager == 0) - _graphicsManager = new WINCESdlGraphicsManager(_eventSource); + _graphicsManager = new WINCESdlGraphicsManager(_eventSource, _window); ((WINCESdlEventSource *)_eventSource)->init(dynamic_cast(_graphicsManager)); -- cgit v1.2.3