The Battle for Wesnoth  1.19.13+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 "sdl/window.hpp"
17 
18 #include "sdl/exception.hpp"
19 #include "sdl/surface.hpp"
20 
21 #include <SDL2/SDL_hints.h>
22 #include <SDL2/SDL_render.h>
23 
24 #ifdef __ANDROID__
25 #include <SDL2/SDL_mouse.h>
26 #endif
27 
28 namespace sdl
29 {
30 
31 window::window(const std::string& title,
32  const int x,
33  const int y,
34  const int w,
35  const int h,
36  const uint32_t window_flags,
37  const uint32_t render_flags)
38  : window_(SDL_CreateWindow(
39  title.c_str(), x, y, w, h, window_flags | SDL_WINDOW_HIDDEN))
40  , pixel_format_(SDL_PIXELFORMAT_UNKNOWN)
41 {
42  if(!window_) {
43  throw exception("Failed to create a SDL_Window object.", true);
44  }
45 
46 #ifdef _WIN32
47  // SDL uses Direct3D v9 by default on Windows systems. However, returning
48  // from the Windows lock screen causes issues with rendering. Resolution
49  // is either to rebuild render textures on the SDL_RENDER_TARGETS_RESET
50  // event or use an alternative renderer that does not have this issue.
51  // Suitable options are Direct3D v11+ or OpenGL.
52  // See https://github.com/wesnoth/wesnoth/issues/8038 for details.
53  // Note that SDL_HINT_RENDER_DRIVER implies SDL_HINT_RENDER_BATCHING is
54  // disabled, according to https://discourse.libsdl.org/t/a-couple-of-questions-regarding-batching-in-sdl-2-0-10/26453/2.
55  SDL_SetHint(SDL_HINT_RENDER_DRIVER, "direct3d11");
56 #endif
57 
58 #ifdef __ANDROID__
59  SDL_SetHint(SDL_HINT_ORIENTATIONS, "LandscapeLeft LandscapeRight");
60 #endif
61 
62  if(!SDL_CreateRenderer(window_, -1, render_flags)) {
63  throw exception("Failed to create a SDL_Renderer object.", true);
64  }
65 
66  SDL_RendererInfo info;
67  if(SDL_GetRendererInfo(*this, &info) != 0) {
68  throw exception("Failed to retrieve the information of the renderer.",
69  true);
70  }
71 
72  if(info.num_texture_formats == 0) {
73  throw exception("The renderer has no texture information available.\n",
74  false);
75  }
76 
77  if((info.flags & SDL_RENDERER_TARGETTEXTURE) == 0) {
78  throw exception("Render-to-texture not supported or enabled!", false);
79  }
80 
81  // Set default blend mode to blend.
82  SDL_SetRenderDrawBlendMode(*this, SDL_BLENDMODE_BLEND);
83 
84  // In fullscreen mode, do not minimize on focus loss.
85  // Minimizing was reported as bug #1606 with blocker priority.
86  SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
87 
88  pixel_format_ = info.texture_formats[0];
89 
90  fill(0,0,0);
91 
92  render();
93 
94  // If we didn't explicitly ask for the window to be hidden, show it
95  if(!(window_flags & SDL_WINDOW_HIDDEN)) {
96  SDL_ShowWindow(window_);
97  }
98 }
99 
101 {
102  if(window_) {
103  SDL_DestroyWindow(window_);
104  }
105 }
106 
107 void window::set_size(const int w, const int h)
108 {
109 #ifdef __ANDROID__
110  SDL_RenderSetLogicalSize(SDL_GetRenderer(window_), w, h);
111  SDL_WarpMouseInWindow(window_, w / 2, h / 2);
112 #else
113  SDL_SetWindowSize(window_, w, h);
114 #endif
115 }
116 
117 SDL_Point window::get_size()
118 {
119  SDL_Point res;
120 #ifdef __ANDROID__
121  SDL_RenderGetLogicalSize(SDL_GetRenderer(window_), &res.x, &res.y);
122 #else
123  SDL_GetWindowSize(*this, &res.x, &res.y);
124 #endif
125 
126  return res;
127 }
128 
130 {
131  SDL_Point res;
132  SDL_GetRendererOutputSize(*this, &res.x, &res.y);
133 
134  return res;
135 }
136 
138 {
139 #ifndef __ANDROID__
140  SDL_SetWindowPosition(window_, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
141 #endif
142 }
143 
145 {
146 #ifndef __ANDROID__
147  SDL_MaximizeWindow(window_);
148 #endif
149 }
150 
152 {
153 #ifndef __ANDROID__
154  SDL_SetWindowFullscreen(window_, 0);
155 #endif
156 }
157 
159 {
160 #ifndef __ANDROID__
161  SDL_RestoreWindow(window_);
162 #endif
163 }
164 
166 {
167 #ifndef __ANDROID__
168  SDL_SetWindowFullscreen(window_, SDL_WINDOW_FULLSCREEN_DESKTOP);
169 #endif
170 }
171 
172 void window::fill(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
173 {
174  SDL_SetRenderDrawColor(*this, r, g, b, a);
175  if(SDL_RenderClear(*this) != 0) {
176  throw exception("Failed to clear the SDL_Renderer object.",
177  true);
178  }
179 }
180 
182 {
183  SDL_RenderPresent(*this);
184 }
185 
186 #ifndef __ANDROID__
187 void window::set_title(const std::string& title)
188 {
189  SDL_SetWindowTitle(window_, title.c_str());
190 }
191 
192 void window::set_icon(const surface& icon)
193 {
194  SDL_SetWindowIcon(window_, icon);
195 }
196 
197 void window::set_minimum_size(int min_w, int min_h)
198 {
199  SDL_SetWindowMinimumSize(window_, min_w, min_h);
200 }
201 #else
202 void window::set_title(const std::string&) {};
203 void window::set_icon(const surface&) {};
204 void window::set_minimum_size(int, int) {};
205 #endif
206 
208 {
209  return SDL_GetWindowFlags(window_);
210 }
211 
213 {
214  return SDL_GetWindowDisplayIndex(window_);
215 }
216 
218 {
219  SDL_Renderer* r = SDL_GetRenderer(window_);
220  SDL_RenderSetLogicalSize(r, w, h);
221 }
222 
224 {
225  set_logical_size(p.x, p.y);
226 }
227 
229 {
230  SDL_Renderer* r = SDL_GetRenderer(window_);
231  int w, h;
232  SDL_RenderGetLogicalSize(r, &w, &h);
233  return {w, h};
234 }
235 
236 void window::get_logical_size(int& w, int& h) const
237 {
238  SDL_Renderer* r = SDL_GetRenderer(window_);
239  SDL_RenderGetLogicalSize(r, &w, &h);
240 }
241 
243 {
244  return pixel_format_;
245 }
246 
247 window::operator SDL_Window*()
248 {
249  return window_;
250 }
251 
252 window::operator SDL_Renderer*()
253 {
254  return SDL_GetRenderer(window_);
255 }
256 
257 } // namespace sdl
double g
Definition: astarsearch.cpp:63
SDL_Point get_output_size()
Gets the window's renderer output size, in pixels.
Definition: window.cpp:129
void set_size(const int w, const int h)
Wrapper for SDL_SetWindowSize.
Definition: window.cpp:107
void to_window()
Dummy function for returning the window to windowed mode.
Definition: window.cpp:151
uint32_t pixel_format()
The current pixel format of the renderer.
Definition: window.cpp:242
window(const window &)=delete
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:172
point get_logical_size() const
Definition: window.cpp:228
void center()
Dummy function for centering the window.
Definition: window.cpp:137
void render()
Renders the contents of the window.
Definition: window.cpp:181
void restore()
Dummy function for restoring the window.
Definition: window.cpp:158
void set_minimum_size(int min_w, int min_h)
Set minimum size of the window.
Definition: window.cpp:197
SDL_Window * window_
The SDL_Window we own.
Definition: window.hpp:209
void full_screen()
Dummy function for setting the window to fullscreen mode.
Definition: window.cpp:165
int get_display_index()
Definition: window.cpp:212
SDL_Point get_size()
Gets the window's size, in screen coordinates.
Definition: window.cpp:117
void set_icon(const surface &icon)
Sets the icon of the window.
Definition: window.cpp:192
void set_logical_size(int w, int h)
Sets the desired size of the rendering surface.
Definition: window.cpp:217
void maximize()
Dummy function for maximizing the window.
Definition: window.cpp:144
uint32_t pixel_format_
The preferred pixel format for the renderer.
Definition: window.hpp:212
uint32_t get_flags()
Definition: window.cpp:207
void set_title(const std::string &title)
Sets the title of the window.
Definition: window.cpp:187
int w
logger & info()
Definition: log.cpp:351
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