From 3f22c12c56572d7c0b46e734179255062f81f45c Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Mon, 16 Feb 2015 01:24:42 +0100 Subject: SDL: Handle icon setup in SdlWindow. --- backends/platform/maemo/maemo.cpp | 15 +++-- backends/platform/maemo/maemo.h | 2 +- backends/platform/sdl/macosx/macosx.cpp | 5 +- backends/platform/sdl/macosx/macosx.h | 1 - backends/platform/sdl/module.mk | 1 + backends/platform/sdl/sdl-window.cpp | 82 ++++++++++++++++++++++++---- backends/platform/sdl/sdl-window.h | 18 +++--- backends/platform/sdl/sdl.cpp | 65 +--------------------- backends/platform/sdl/sdl.h | 5 -- backends/platform/sdl/win32/win32-window.cpp | 58 ++++++++++++++++++++ backends/platform/sdl/win32/win32-window.h | 37 +++++++++++++ backends/platform/sdl/win32/win32.cpp | 28 ++-------- backends/platform/sdl/win32/win32.h | 1 - backends/platform/symbian/src/SymbianOS.cpp | 6 +- backends/platform/symbian/src/SymbianOS.h | 1 - 15 files changed, 198 insertions(+), 127 deletions(-) create mode 100644 backends/platform/sdl/win32/win32-window.cpp create mode 100644 backends/platform/sdl/win32/win32-window.h (limited to 'backends/platform') diff --git a/backends/platform/maemo/maemo.cpp b/backends/platform/maemo/maemo.cpp index 0ada9da313..5e1ecfe335 100644 --- a/backends/platform/maemo/maemo.cpp +++ b/backends/platform/maemo/maemo.cpp @@ -84,6 +84,15 @@ static void registerDefaultKeyBindings(Common::KeymapperDefaultBindings *_keymap } #endif +void OSystem_SDL_Maemo::init() { + // Use an iconless window for Maemo + // also N900 is hit by SDL_WM_SetIcon bug (window cannot receive input) + // http://bugzilla.libsdl.org/show_bug.cgi?id=586 + _window = new SdlIconlessWindow(); + + OSystem_POSIX::init(); +} + void OSystem_SDL_Maemo::initBackend() { ConfMan.registerDefault("fullscreen", true); ConfMan.registerDefault("aspect_ratio", true); @@ -178,12 +187,6 @@ const Maemo::Model OSystem_SDL_Maemo::detectModel() { return *model; } -void OSystem_SDL_Maemo::setupIcon() { - // no Maemo version needs setupIcon - // also N900 is hit by SDL_WM_SetIcon bug (window cannot receive input) - // http://bugzilla.libsdl.org/show_bug.cgi?id=586 -} - #ifdef ENABLE_KEYMAPPER static const Common::KeyTableEntry maemoKeys[] = { // Function keys diff --git a/backends/platform/maemo/maemo.h b/backends/platform/maemo/maemo.h index 532a2de08c..6d6e09bee1 100644 --- a/backends/platform/maemo/maemo.h +++ b/backends/platform/maemo/maemo.h @@ -36,11 +36,11 @@ public: OSystem_SDL_Maemo(); ~OSystem_SDL_Maemo(); + virtual void init(); virtual void initBackend(); virtual void quit(); virtual void fatalError(); virtual void setWindowCaption(const char *caption); - virtual void setupIcon(); #ifdef ENABLE_KEYMAPPER virtual Common::HardwareInputSet *getHardwareInputSet(); virtual Common::Keymap *getGlobalKeymap(); diff --git a/backends/platform/sdl/macosx/macosx.cpp b/backends/platform/sdl/macosx/macosx.cpp index c48076c42f..fa9f3ad16c 100644 --- a/backends/platform/sdl/macosx/macosx.cpp +++ b/backends/platform/sdl/macosx/macosx.cpp @@ -47,6 +47,9 @@ OSystem_MacOSX::OSystem_MacOSX() } void OSystem_MacOSX::init() { + // Use an iconless window on OS X, as we use a nicer external icon there. + _window = new SdlIconlessWindow(); + #if defined(USE_TASKBAR) // Initialize taskbar manager _taskbarManager = new MacOSXTaskbarManager(); @@ -101,8 +104,6 @@ void OSystem_MacOSX::addSysArchivesToSearchSet(Common::SearchSet &s, int priorit } } -void OSystem_MacOSX::setupIcon() { - // Don't set icon on OS X, as we use a nicer external icon there. } bool OSystem_MacOSX::hasFeature(Feature f) { diff --git a/backends/platform/sdl/macosx/macosx.h b/backends/platform/sdl/macosx/macosx.h index 50cef60353..c8b4beaeec 100644 --- a/backends/platform/sdl/macosx/macosx.h +++ b/backends/platform/sdl/macosx/macosx.h @@ -38,7 +38,6 @@ public: virtual void init(); virtual void initBackend(); virtual void addSysArchivesToSearchSet(Common::SearchSet &s, int priority = 0); - virtual void setupIcon(); }; #endif diff --git a/backends/platform/sdl/module.mk b/backends/platform/sdl/module.mk index 6da86706c6..74dd506d31 100644 --- a/backends/platform/sdl/module.mk +++ b/backends/platform/sdl/module.mk @@ -20,6 +20,7 @@ endif ifdef WIN32 MODULE_OBJS += \ win32/win32-main.o \ + win32/win32-window.o \ win32/win32.o endif diff --git a/backends/platform/sdl/sdl-window.cpp b/backends/platform/sdl/sdl-window.cpp index b8cf4cfb4d..d603ba0114 100644 --- a/backends/platform/sdl/sdl-window.cpp +++ b/backends/platform/sdl/sdl-window.cpp @@ -24,6 +24,10 @@ #include "backends/platform/sdl/sdl-window.h" +#include "common/textconsole.h" + +#include "icons/scummvm.xpm" + SdlWindow::SdlWindow() #if SDL_VERSION_ATLEAST(2, 0, 0) : _window(nullptr), _inputGrabState(false), _windowCaption("ScummVM"), _windowIcon(nullptr) @@ -38,27 +42,85 @@ SdlWindow::~SdlWindow() { #endif } -void SdlWindow::setWindowCaption(const Common::String &caption) { +void SdlWindow::setupIcon() { + int x, y, w, h, ncols, nbytes, i; + unsigned int rgba[256]; + unsigned int *icon; + + if (sscanf(scummvm_icon[0], "%d %d %d %d", &w, &h, &ncols, &nbytes) != 4) { + warning("Wrong format of scummvm_icon[0] (%s)", scummvm_icon[0]); + + return; + } + if ((w > 512) || (h > 512) || (ncols > 255) || (nbytes > 1)) { + warning("Could not load the built-in icon (%d %d %d %d)", w, h, ncols, nbytes); + return; + } + icon = (unsigned int*)malloc(w*h*sizeof(unsigned int)); + if (!icon) { + warning("Could not allocate temp storage for the built-in icon"); + return; + } + + for (i = 0; i < ncols; i++) { + unsigned char code; + char color[32]; + memset(color, 0, sizeof(color)); + unsigned int col; + if (sscanf(scummvm_icon[1 + i], "%c c %s", &code, color) != 2) { + warning("Wrong format of scummvm_icon[%d] (%s)", 1 + i, scummvm_icon[1 + i]); + } + if (!strcmp(color, "None")) + col = 0x00000000; + else if (!strcmp(color, "black")) + col = 0xFF000000; + else if (color[0] == '#') { + if (sscanf(color + 1, "%06x", &col) != 1) { + warning("Wrong format of color (%s)", color + 1); + } + col |= 0xFF000000; + } else { + warning("Could not load the built-in icon (%d %s - %s) ", code, color, scummvm_icon[1 + i]); + free(icon); + return; + } + + rgba[code] = col; + } + for (y = 0; y < h; y++) { + const char *line = scummvm_icon[1 + ncols + y]; + for (x = 0; x < w; x++) { + icon[x + w * y] = rgba[(int)line[x]]; + } + } + + SDL_Surface *sdl_surf = SDL_CreateRGBSurfaceFrom(icon, w, h, 32, w * 4, 0xFF0000, 0x00FF00, 0x0000FF, 0xFF000000); + if (!sdl_surf) { + warning("SDL_CreateRGBSurfaceFrom(icon) failed"); + } + #if SDL_VERSION_ATLEAST(2, 0, 0) - _windowCaption = caption; + SDL_FreeSurface(_windowIcon); + _windowIcon = sdl_surf; if (_window) { - SDL_SetWindowTitle(_window, caption.c_str()); + SDL_SetWindowIcon(_window, sdl_surf); } #else - SDL_WM_SetCaption(caption.c_str(), caption.c_str()); + SDL_WM_SetIcon(sdl_surf, NULL); + SDL_FreeSurface(sdl_surf); #endif + + free(icon); } -void SdlWindow::setWindowIcon(SDL_Surface *icon) { +void SdlWindow::setWindowCaption(const Common::String &caption) { #if SDL_VERSION_ATLEAST(2, 0, 0) - SDL_FreeSurface(_windowIcon); - _windowIcon = icon; + _windowCaption = caption; if (_window) { - SDL_SetWindowIcon(_window, icon); + SDL_SetWindowTitle(_window, caption.c_str()); } #else - SDL_WM_SetIcon(icon, NULL); - SDL_FreeSurface(icon); + SDL_WM_SetCaption(caption.c_str(), caption.c_str()); #endif } diff --git a/backends/platform/sdl/sdl-window.h b/backends/platform/sdl/sdl-window.h index da3dda7f2d..46997f373d 100644 --- a/backends/platform/sdl/sdl-window.h +++ b/backends/platform/sdl/sdl-window.h @@ -33,19 +33,16 @@ public: virtual ~SdlWindow(); /** - * Change the caption of the window. - * - * @param caption New window caption in UTF-8 encoding. + * Setup the window icon. */ - void setWindowCaption(const Common::String &caption); + virtual void setupIcon(); /** - * Attach an icon to the window. + * Change the caption of the window. * - * @param icon The surface to use as icon. SdlGraphicsManager takes - * ownership over it. + * @param caption New window caption in UTF-8 encoding. */ - void setWindowIcon(SDL_Surface *icon); + void setWindowCaption(const Common::String &caption); /** * Toggle mouse grab state. This decides whether the cursor can leave the @@ -100,4 +97,9 @@ private: #endif }; +class SdlIconlessWindow : public SdlWindow { +public: + virtual void setupIcon() {} +}; + #endif diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp index 7978022d6b..6d4dede212 100644 --- a/backends/platform/sdl/sdl.cpp +++ b/backends/platform/sdl/sdl.cpp @@ -52,8 +52,6 @@ #include "graphics/cursorman.h" #endif -#include "icons/scummvm.xpm" - #include // for getTimeAndDate() #ifdef USE_DETECTLANG @@ -258,7 +256,7 @@ void OSystem_SDL::initBackend() { } // Setup a custom program icon. - setupIcon(); + _window->setupIcon(); _inited = true; @@ -441,67 +439,6 @@ Common::String OSystem_SDL::getSystemLanguage() const { #endif // USE_DETECTLANG } -void OSystem_SDL::setupIcon() { - int x, y, w, h, ncols, nbytes, i; - unsigned int rgba[256]; - unsigned int *icon; - - if (sscanf(scummvm_icon[0], "%d %d %d %d", &w, &h, &ncols, &nbytes) != 4) { - warning("Wrong format of scummvm_icon[0] (%s)", scummvm_icon[0]); - - return; - } - if ((w > 512) || (h > 512) || (ncols > 255) || (nbytes > 1)) { - warning("Could not load the built-in icon (%d %d %d %d)", w, h, ncols, nbytes); - return; - } - icon = (unsigned int*)malloc(w*h*sizeof(unsigned int)); - if (!icon) { - warning("Could not allocate temp storage for the built-in icon"); - return; - } - - for (i = 0; i < ncols; i++) { - unsigned char code; - char color[32]; - memset(color, 0, sizeof(color)); - unsigned int col; - if (sscanf(scummvm_icon[1 + i], "%c c %s", &code, color) != 2) { - warning("Wrong format of scummvm_icon[%d] (%s)", 1 + i, scummvm_icon[1 + i]); - } - if (!strcmp(color, "None")) - col = 0x00000000; - else if (!strcmp(color, "black")) - col = 0xFF000000; - else if (color[0] == '#') { - if (sscanf(color + 1, "%06x", &col) != 1) { - warning("Wrong format of color (%s)", color + 1); - } - col |= 0xFF000000; - } else { - warning("Could not load the built-in icon (%d %s - %s) ", code, color, scummvm_icon[1 + i]); - free(icon); - return; - } - - rgba[code] = col; - } - for (y = 0; y < h; y++) { - const char *line = scummvm_icon[1 + ncols + y]; - for (x = 0; x < w; x++) { - icon[x + w * y] = rgba[(int)line[x]]; - } - } - - SDL_Surface *sdl_surf = SDL_CreateRGBSurfaceFrom(icon, w, h, 32, w * 4, 0xFF0000, 0x00FF00, 0x0000FF, 0xFF000000); - if (!sdl_surf) { - warning("SDL_CreateRGBSurfaceFrom(icon) failed"); - } - _window->setWindowIcon(sdl_surf); - free(icon); -} - - uint32 OSystem_SDL::getMillis(bool skipRecord) { uint32 millis = SDL_GetTicks(); diff --git a/backends/platform/sdl/sdl.h b/backends/platform/sdl/sdl.h index 0f07f6d18d..5ee56d0568 100644 --- a/backends/platform/sdl/sdl.h +++ b/backends/platform/sdl/sdl.h @@ -104,11 +104,6 @@ protected: */ virtual void initSDL(); - /** - * Setup the window icon. - */ - virtual void setupIcon(); - // Logging virtual Common::WriteStream *createLogFile() { return 0; } Backends::Log::Log *_logger; diff --git a/backends/platform/sdl/win32/win32-window.cpp b/backends/platform/sdl/win32/win32-window.cpp new file mode 100644 index 0000000000..a418d899d5 --- /dev/null +++ b/backends/platform/sdl/win32/win32-window.cpp @@ -0,0 +1,58 @@ +/* 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. + * + */ + +// Disable symbol overrides so that we can use system headers. +#define FORBIDDEN_SYMBOL_ALLOW_ALL + +#ifdef WIN32 + +#include "backends/platform/sdl/win32/win32-window.h" + +#define WIN32_LEAN_AND_MEAN +#include +#undef ARRAYSIZE // winnt.h defines ARRAYSIZE, but we want our own one... + +#include // For setting the icon + +void SdlWindow_Win32::setupIcon() { + HMODULE handle = GetModuleHandle(NULL); + HICON ico = LoadIcon(handle, MAKEINTRESOURCE(1001 /* IDI_ICON */)); + if (ico) { + SDL_SysWMinfo wminfo; + SDL_VERSION(&wminfo.version); + if (SDL_GetWMInfo(&wminfo)) { + // Replace the handle to the icon associated with the window class by our custom icon + SetClassLongPtr(wminfo.window, GCLP_HICON, (ULONG_PTR)ico); + + // Since there wasn't any default icon, we can't use the return value from SetClassLong + // to check for errors (it would be 0 in both cases: error or no previous value for the + // icon handle). Instead we check for the last-error code value. + if (GetLastError() == ERROR_SUCCESS) + return; + } + } + + // If no icon has been set, fallback to default path + SdlWindow::setupIcon(); +} + +#endif diff --git a/backends/platform/sdl/win32/win32-window.h b/backends/platform/sdl/win32/win32-window.h new file mode 100644 index 0000000000..3bda697bc7 --- /dev/null +++ b/backends/platform/sdl/win32/win32-window.h @@ -0,0 +1,37 @@ +/* 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_WIN32_WIN32_WINDOW_H +#define BACKENDS_PLATFORM_SDL_WIN32_WIN32_WINDOW_H + +#ifdef WIN32 + +#include "backends/platform/sdl/sdl-window.h" + +class SdlWindow_Win32 : public SdlWindow { +public: + virtual void setupIcon(); +}; + +#endif + +#endif diff --git a/backends/platform/sdl/win32/win32.cpp b/backends/platform/sdl/win32/win32.cpp index 5f860ad32d..78a7c685eb 100644 --- a/backends/platform/sdl/win32/win32.cpp +++ b/backends/platform/sdl/win32/win32.cpp @@ -35,9 +35,8 @@ #include "common/error.h" #include "common/textconsole.h" -#include // For setting the icon - #include "backends/platform/sdl/win32/win32.h" +#include "backends/platform/sdl/win32/win32-window.h" #include "backends/saves/windows/windows-saves.h" #include "backends/fs/windows/windows-fs-factory.h" #include "backends/taskbar/win32/win32-taskbar.h" @@ -50,6 +49,9 @@ void OSystem_Win32::init() { // Initialize File System Factory _fsFactory = new WindowsFilesystemFactory(); + // Create Win32 specific window + _window = new SdlWindow_Win32(); + #if defined(USE_TASKBAR) // Initialize taskbar manager _taskbarManager = new Win32TaskbarManager(); @@ -126,28 +128,6 @@ bool OSystem_Win32::displayLogFile() { return false; } -void OSystem_Win32::setupIcon() { - HMODULE handle = GetModuleHandle(NULL); - HICON ico = LoadIcon(handle, MAKEINTRESOURCE(1001 /* IDI_ICON */)); - if (ico) { - SDL_SysWMinfo wminfo; - SDL_VERSION(&wminfo.version); - if (SDL_GetWMInfo(&wminfo)) { - // Replace the handle to the icon associated with the window class by our custom icon - SetClassLongPtr(wminfo.window, GCLP_HICON, (ULONG_PTR)ico); - - // Since there wasn't any default icon, we can't use the return value from SetClassLong - // to check for errors (it would be 0 in both cases: error or no previous value for the - // icon handle). Instead we check for the last-error code value. - if (GetLastError() == ERROR_SUCCESS) - return; - } - } - - // If no icon has been set, fallback to default path - OSystem_SDL::setupIcon(); -} - Common::String OSystem_Win32::getDefaultConfigFileName() { char configFile[MAXPATHLEN]; diff --git a/backends/platform/sdl/win32/win32.h b/backends/platform/sdl/win32/win32.h index d72d80bc26..473e78ff0b 100644 --- a/backends/platform/sdl/win32/win32.h +++ b/backends/platform/sdl/win32/win32.h @@ -47,7 +47,6 @@ protected: */ Common::String _logFilePath; - virtual void setupIcon(); virtual Common::String getDefaultConfigFileName(); virtual Common::WriteStream *createLogFile(); }; diff --git a/backends/platform/symbian/src/SymbianOS.cpp b/backends/platform/symbian/src/SymbianOS.cpp index 57903d3d26..e28b78900c 100644 --- a/backends/platform/symbian/src/SymbianOS.cpp +++ b/backends/platform/symbian/src/SymbianOS.cpp @@ -63,6 +63,8 @@ OSystem_SDL_Symbian::OSystem_SDL_Symbian() void OSystem_SDL_Symbian::init() { _RFs = &CEikonEnv::Static()->FsSession(); + // Use iconless window: it uses the EScummVM.aif file for the icon. + _window = new SdlIconlessWindow(); _fsFactory = new SymbianFilesystemFactory(); OSystem_SDL::init(); } @@ -171,10 +173,6 @@ Common::String OSystem_SDL_Symbian::getDefaultConfigFileName() { return configFile; } -void OSystem_SDL_Symbian::setupIcon() { - // Don't for Symbian: it uses the EScummVM.aif file for the icon. -} - RFs& OSystem_SDL_Symbian::FsSession() { return *_RFs; } diff --git a/backends/platform/symbian/src/SymbianOS.h b/backends/platform/symbian/src/SymbianOS.h index 57a471f1a9..617540941d 100644 --- a/backends/platform/symbian/src/SymbianOS.h +++ b/backends/platform/symbian/src/SymbianOS.h @@ -39,7 +39,6 @@ public: virtual void engineDone(); virtual bool setGraphicsMode(const char *name); virtual Common::String getDefaultConfigFileName(); - virtual void setupIcon(); /** * Returns reference to File session -- cgit v1.2.3