The Battle for Wesnoth  1.19.25+dev
window.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014 - 2025
3  by Mark de Wever <koraq@xs4all.nl>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #include "log.hpp"
18 #include "sdl/window.hpp"
19 #include "sdl/exception.hpp"
20 #include "sdl/surface.hpp"
23 #include "utils/general.hpp"
24 #include "video.hpp"
25 
26 #include <SDL3/SDL_hints.h>
27 #include <SDL3/SDL_render.h>
28 
29 
30 #ifdef __ANDROID__
31 #include <SDL3/SDL_mouse.h>
32 #endif
33 
34 namespace sdl
35 {
36 
37 window::window(const std::string& title,
38  const int w,
39  const int h,
40  const uint32_t window_flags)
41  : window_(SDL_CreateWindow(title.c_str(), w, h, window_flags | SDL_WINDOW_HIDDEN))
42 {
43  if(!window_) {
44  throw exception("Failed to create a SDL_Window object.", true);
45  }
46 
47 #ifdef _WIN32
48  // SDL uses Direct3D v9 by default on Windows systems. However, returning
49  // from the Windows lock screen causes issues with rendering. Resolution
50  // is either to rebuild render textures on the SDL_EVENT_RENDER_TARGETS_RESET
51  // event or use an alternative renderer that does not have this issue.
52  // Suitable options are Direct3D v11+ or OpenGL.
53  // See https://github.com/wesnoth/wesnoth/issues/8038 for details.
54  // Note that SDL_HINT_RENDER_DRIVER implies SDL_HINT_RENDER_BATCHING is
55  // disabled, according to https://discourse.libsdl.org/t/a-couple-of-questions-regarding-batching-in-sdl-2-0-10/26453/2.
56  SDL_SetHint(SDL_HINT_RENDER_DRIVER, "direct3d11");
57 #endif
58 
59 #ifdef __ANDROID__
60  SDL_SetHint(SDL_HINT_ORIENTATIONS, "LandscapeLeft LandscapeRight");
61 #endif
62 
63  sdl3_properties props;
64 
65  if(prefs::get().vsync()) {
66  if(!SDL_SetNumberProperty(props, SDL_PROP_RENDERER_CREATE_PRESENT_VSYNC_NUMBER, 1)) {
67  throw exception("Failed to set vsync", true);
68  };
69  }
70 
71  if(!SDL_SetPointerProperty(props, SDL_PROP_RENDERER_CREATE_WINDOW_POINTER, window_)) {
72  throw exception("Failed to set window pointer property", true);
73  }
74 
75  // try using the default
76  // if that fails, try opengl
77  PLAIN_LOG << "Available renderers: " << utils::join(video::get_available_renderers(), " ");
78  if(!SDL_CreateRendererWithProperties(props)) {
79  PLAIN_LOG << "Failed to create default renderer, checking for opengl";
80 
82  SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl");
83 
84  if(!SDL_CreateRendererWithProperties(props)) {
85  throw exception("Failed to create an opengl SDL_Renderer object as a fallback.", true);
86  }
87 
88  PLAIN_LOG << "Failed to create default renderer but created fallback opengl renderer";
89  } else {
90  PLAIN_LOG << "Available renderers: " << utils::join(video::get_available_renderers(), " ");
91  throw exception("Failed to create default renderer and opengl fallback isn't supported.", true);
92  }
93  }
94 
95  // Set default blend mode to blend.
96  SDL_SetRenderDrawBlendMode(*this, SDL_BLENDMODE_BLEND);
97 
98  // In fullscreen mode, do not minimize on focus loss.
99  // Minimizing was reported as bug #1606 with blocker priority.
100  SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
101 
102  fill(0,0,0);
103 
104  render();
105 
106  // If we didn't explicitly ask for the window to be hidden, show it
107  if(!(window_flags & SDL_WINDOW_HIDDEN)) {
108  SDL_ShowWindow(window_);
109  }
110 }
111 
113 {
114  if(window_) {
115  SDL_DestroyWindow(window_);
116  }
117 }
118 
119 void window::set_size(const int w, const int h)
120 {
121 #ifdef __ANDROID__
122  SDL_SetRenderLogicalPresentation(SDL_GetRenderer(window_), w, h, SDL_LOGICAL_PRESENTATION_INTEGER_SCALE);
123  SDL_WarpMouseInWindow(window_, w / 2, h / 2);
124 #else
125  SDL_SetWindowSize(window_, w, h);
126 #endif
127 }
128 
130 {
131  point res;
132 #ifdef __ANDROID__
133  SDL_GetRenderLogicalPresentation(SDL_GetRenderer(window_), &res.x, &res.y, nullptr);
134 #else
135  SDL_GetWindowSize(*this, &res.x, &res.y);
136 #endif
137 
138  return res;
139 }
140 
142 {
143  point res;
144  SDL_GetCurrentRenderOutputSize(*this, &res.x, &res.y);
145 
146  return res;
147 }
148 
150 {
151 #ifndef __ANDROID__
152  SDL_SetWindowPosition(window_, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
153 #endif
154 }
155 
157 {
158 #ifndef __ANDROID__
159  SDL_MaximizeWindow(window_);
160 #endif
161 }
162 
164 {
165 #ifndef __ANDROID__
166  SDL_SetWindowFullscreen(window_, false);
167 #endif
168 }
169 
171 {
172 #ifndef __ANDROID__
173  SDL_RestoreWindow(window_);
174 #endif
175 }
176 
178 {
179 #ifndef __ANDROID__
180  SDL_SetWindowFullscreen(window_, true);
181 #endif
182 }
183 
184 void window::fill(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
185 {
186  SDL_SetRenderDrawColor(*this, r, g, b, a);
187  if(!SDL_RenderClear(*this)) {
188  throw exception("Failed to clear the SDL_Renderer object.", true);
189  }
190 }
191 
193 {
194  SDL_RenderPresent(*this);
195 }
196 
197 #ifndef __ANDROID__
198 void window::set_title(const std::string& title)
199 {
200  SDL_SetWindowTitle(window_, title.c_str());
201 }
202 
203 void window::set_icon(const surface& icon)
204 {
205  SDL_SetWindowIcon(window_, icon);
206 }
207 
208 void window::set_minimum_size(int min_w, int min_h)
209 {
210  SDL_SetWindowMinimumSize(window_, min_w, min_h);
211 }
212 #else
213 void window::set_title(const std::string&) {};
214 void window::set_icon(const surface&) {};
215 void window::set_minimum_size(int, int) {};
216 #endif
217 
219 {
220  return SDL_GetWindowFlags(window_);
221 }
222 
224 {
225  return SDL_GetDisplayForWindow(window_);
226 }
227 
229 {
230  SDL_Renderer* r = SDL_GetRenderer(window_);
231  // Non-integer scales are not currently supported.
232  // This option makes things neater when window size is not a perfect
233  // multiple of logical size, which can happen when manually resizing.
234  SDL_SetRenderLogicalPresentation(r, w, h, SDL_LOGICAL_PRESENTATION_INTEGER_SCALE);
235 }
236 
238 {
239  set_logical_size(p.x, p.y);
240 }
241 
243 {
244  SDL_Renderer* r = SDL_GetRenderer(window_);
245  int w, h;
246  SDL_RendererLogicalPresentation mode = SDL_LOGICAL_PRESENTATION_INTEGER_SCALE;
247  SDL_GetRenderLogicalPresentation(r, &w, &h, &mode);
248  return {w, h};
249 }
250 
251 void window::get_logical_size(int& w, int& h) const
252 {
253  SDL_Renderer* r = SDL_GetRenderer(window_);
254  SDL_RendererLogicalPresentation mode = SDL_LOGICAL_PRESENTATION_INTEGER_SCALE;
255  SDL_GetRenderLogicalPresentation(r, &w, &h, &mode);
256 }
257 
258 window::operator SDL_Window*()
259 {
260  return window_;
261 }
262 
263 window::operator SDL_Renderer*()
264 {
265  return SDL_GetRenderer(window_);
266 }
267 
268 } // namespace sdl
double g
Definition: astarsearch.cpp:63
static prefs & get()
void set_size(const int w, const int h)
Wrapper for SDL_SetWindowSize.
Definition: window.cpp:119
void to_window()
Dummy function for returning the window to windowed mode.
Definition: window.cpp:163
window(const window &)=delete
point get_size()
Gets the window's size, in screen coordinates.
Definition: window.cpp:129
void fill(uint8_t r, uint8_t g, uint8_t b, uint8_t a=0)
Clears the contents of the window with a given color.
Definition: window.cpp:184
point get_logical_size() const
Definition: window.cpp:242
void center()
Dummy function for centering the window.
Definition: window.cpp:149
void render()
Renders the contents of the window.
Definition: window.cpp:192
void restore()
Dummy function for restoring the window.
Definition: window.cpp:170
void set_minimum_size(int min_w, int min_h)
Set minimum size of the window.
Definition: window.cpp:208
SDL_Window * window_
The SDL_Window we own.
Definition: window.hpp:202
void full_screen()
Dummy function for setting the window to fullscreen mode.
Definition: window.cpp:177
int get_display_index()
Definition: window.cpp:223
void set_icon(const surface &icon)
Sets the icon of the window.
Definition: window.cpp:203
void set_logical_size(int w, int h)
Sets the desired size of the rendering surface.
Definition: window.cpp:228
void maximize()
Dummy function for maximizing the window.
Definition: window.cpp:156
uint32_t get_flags()
Definition: window.cpp:218
void set_title(const std::string &title)
Sets the title of the window.
Definition: window.cpp:198
point get_output_size()
Gets the window's renderer output size, in pixels.
Definition: window.cpp:141
Standard logging facilities (interface).
#define PLAIN_LOG
Definition: log.hpp:296
bool contains(const Container &container, const Value &value)
Returns true iff value is found in container.
Definition: general.hpp:87
std::string join(const Range &v, const std::string &s=",")
Generates a new string joining container items in a list.
std::vector< std::string > get_available_renderers()
Returns a list of all available renderers.
Definition: video.cpp:872
int w
Definition: pathfind.cpp:188
Contains a basic exception class for SDL operations.
Contains a wrapper class for the SDL_Window class.
Holds a 2D point.
Definition: point.hpp:25
mock_party p
#define h
#define b