openMSX
SDLVisibleSurfaceBase.cc
Go to the documentation of this file.
2 #include "InitException.hh"
3 #include "Icon.hh"
4 #include "Display.hh"
5 #include "RenderSettings.hh"
6 #include "PNG.hh"
7 #include "FileContext.hh"
8 #include "CliComm.hh"
9 #include "build-info.hh"
10 #include <cassert>
11 
12 namespace openmsx {
13 
14 int SDLVisibleSurfaceBase::windowPosX = SDL_WINDOWPOS_UNDEFINED;
15 int SDLVisibleSurfaceBase::windowPosY = SDL_WINDOWPOS_UNDEFINED;
16 
18 {
19  // store last known position for when we recreate it
20  // the window gets recreated when changing renderers, for instance.
21  // Do not store if we're fullscreen, the location is the top-left
22  if ((SDL_GetWindowFlags(window.get()) & SDL_WINDOW_FULLSCREEN) == 0) {
23  SDL_GetWindowPosition(window.get(), &windowPosX, &windowPosY);
24  }
25 }
26 
27 // TODO: The video subsystem is not de-inited on errors.
28 // While it would be consistent to do so, doing it in this class is
29 // not ideal since the init doesn't happen here.
30 void SDLVisibleSurfaceBase::createSurface(int width, int height, unsigned flags)
31 {
32  if (getDisplay().getRenderSettings().getFullScreen()) {
33  flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
34  }
35  flags |= SDL_WINDOW_ALLOW_HIGHDPI;
36 
37  assert(!window);
38  window.reset(SDL_CreateWindow(
39  getDisplay().getWindowTitle().c_str(),
40  windowPosX, windowPosY,
41  width, height,
42  flags));
43  if (!window) {
44  std::string err = SDL_GetError();
45  throw InitException("Could not create window: ", err);
46  }
47 
49 
50  // prefer linear filtering (instead of nearest neighbour)
51  SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1");
52 
53  // set icon
54  if (OPENMSX_SET_WINDOW_ICON) {
55  SDLSurfacePtr iconSurf;
56  // always use 32x32 icon on Windows, for some reason you get badly scaled icons there
57 #ifndef _WIN32
58  try {
59  iconSurf = PNG::load(preferSystemFileContext().resolve("icons/openMSX-logo-256.png"), true);
60  } catch (MSXException& e) {
62  "Falling back to built in 32x32 icon, because failed to load icon: ",
63  e.getMessage());
64 #endif
65  iconSurf.reset(SDL_CreateRGBSurfaceFrom(
66  const_cast<char*>(openMSX_icon.pixel_data),
70  OPENMSX_BIGENDIAN ? 0xFF000000 : 0x000000FF,
71  OPENMSX_BIGENDIAN ? 0x00FF0000 : 0x0000FF00,
72  OPENMSX_BIGENDIAN ? 0x0000FF00 : 0x00FF0000,
73  OPENMSX_BIGENDIAN ? 0x000000FF : 0xFF000000));
74 #ifndef _WIN32
75  }
76 #endif
77  SDL_SetColorKey(iconSurf.get(), SDL_TRUE, 0);
78  SDL_SetWindowIcon(window.get(), iconSurf.get());
79  }
80 }
81 
83 {
84  assert(window);
85  SDL_SetWindowTitle(window.get(), getDisplay().getWindowTitle().c_str());
86 }
87 
89 {
90  auto flags = SDL_GetWindowFlags(window.get());
91  // Note: SDL_WINDOW_FULLSCREEN_DESKTOP also has the SDL_WINDOW_FULLSCREEN
92  // bit set.
93  bool currentState = (flags & SDL_WINDOW_FULLSCREEN) != 0;
94  if (currentState == fullscreen) {
95  // already wanted stated
96  return true;
97  }
98 
99  if (SDL_SetWindowFullscreen(window.get(),
100  fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0) != 0) {
101  return false; // error, try re-creating the window
102  }
103  fullScreenUpdated(fullscreen);
104  return true; // success
105 }
106 
107 } // namespace openmsx
openmsx::SDLVisibleSurfaceBase::updateWindowTitle
void updateWindowTitle() override
Definition: SDLVisibleSurfaceBase.cc:82
openmsx::SDLVisibleSurfaceBase::fullScreenUpdated
virtual void fullScreenUpdated(bool fullscreen)=0
Display.hh
openmsx::OpenMSX_Icon::pixel_data
const char * pixel_data
Definition: Icon.hh:11
SDLSurfacePtr
Wrapper around a SDL_Surface.
Definition: SDLSurfacePtr.hh:34
openmsx::OpenMSX_Icon::bytes_per_pixel
unsigned bytes_per_pixel
Definition: Icon.hh:10
openmsx::SDLVisibleSurfaceBase::setFullScreen
bool setFullScreen(bool fullscreen) override
Definition: SDLVisibleSurfaceBase.cc:88
openmsx::MSXException
Definition: MSXException.hh:10
openmsx::SDLVisibleSurfaceBase::~SDLVisibleSurfaceBase
~SDLVisibleSurfaceBase() override
Definition: SDLVisibleSurfaceBase.cc:17
openmsx::OpenMSX_Icon::width
unsigned width
Definition: Icon.hh:8
PNG.hh
Icon.hh
openmsx::CliComm::printWarning
void printWarning(std::string_view message)
Definition: CliComm.cc:10
openmsx::openMSX_icon
OpenMSX_Icon openMSX_icon
Definition: Icon.cc:17
openmsx::OpenMSX_Icon::height
unsigned height
Definition: Icon.hh:9
openmsx::InitException
Thrown when a subsystem initialisation fails.
Definition: InitException.hh:12
build-info.hh
RenderSettings.hh
FileContext.hh
openmsx::SDLVisibleSurfaceBase::createSurface
void createSurface(int width, int height, unsigned flags)
Definition: SDLVisibleSurfaceBase.cc:30
SDLSurfacePtr::get
SDL_Surface * get()
Definition: SDLSurfacePtr.hh:77
openmsx::SDLVisibleSurfaceBase::window
SDLWindowPtr window
Definition: SDLVisibleSurfaceBase.hh:26
InitException.hh
SDLVisibleSurfaceBase.hh
SDLSurfacePtr::reset
void reset(SDL_Surface *surface_=nullptr)
Definition: SDLSurfacePtr.hh:71
openmsx::PNG::load
SDLSurfacePtr load(const std::string &filename, bool want32bpp)
Load the given PNG file in a SDL_Surface.
Definition: PNG.cc:95
CliComm.hh
openmsx::MSXException::getMessage
const std::string & getMessage() const &
Definition: MSXException.hh:23
openmsx::VisibleSurface::getDisplay
Display & getDisplay() const
Definition: VisibleSurface.hh:52
openmsx
This file implemented 3 utility functions:
Definition: Autofire.cc:5
openmsx::VisibleSurface::getCliComm
CliComm & getCliComm() const
Definition: VisibleSurface.hh:51
openmsx::preferSystemFileContext
FileContext preferSystemFileContext()
Definition: FileContext.cc:158