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