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 __ANDROID__
48  SDL_SetHint(SDL_HINT_ORIENTATIONS, "LandscapeLeft LandscapeRight");
49 #endif
50 
51  sdl3_properties props;
52 
53  if(prefs::get().vsync()) {
54  if(!SDL_SetNumberProperty(props, SDL_PROP_RENDERER_CREATE_PRESENT_VSYNC_NUMBER, 1)) {
55  throw exception("Failed to set vsync", true);
56  };
57  }
58 
59  if(!SDL_SetPointerProperty(props, SDL_PROP_RENDERER_CREATE_WINDOW_POINTER, window_)) {
60  throw exception("Failed to set window pointer property", true);
61  }
62 
63  // try using the default
64  // if that fails, try opengl
65  // and if that fails, try software
66  PLAIN_LOG << "Available renderers: " << utils::join(video::get_available_renderers(), " ");
67  if(!SDL_CreateRendererWithProperties(props)) {
68  PLAIN_LOG << "Trying opengl renderer after failing to create default renderer with error: " << SDL_GetError();
69 
71  SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl");
72 
73  if(!SDL_CreateRendererWithProperties(props)) {
74  PLAIN_LOG << "Trying software renderer after failing to create opengl renderer with error: " << SDL_GetError();
75 
77  SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software");
78 
79  if(!SDL_CreateRendererWithProperties(props)) {
80  throw exception("Failed to create software renderer.", true);
81  } else {
82  PLAIN_LOG << "Failed to create default renderer and opengl renderer but created fallback software renderer";
83  }
84  }
85  } else {
86  PLAIN_LOG << "Failed to create default renderer but created fallback opengl renderer";
87  }
88  } else {
89  throw exception("Failed to create default renderer and opengl fallback isn't supported.", true);
90  }
91  }
92 
93  // Set default blend mode to blend.
94  SDL_SetRenderDrawBlendMode(*this, SDL_BLENDMODE_BLEND);
95 
96  // In fullscreen mode, do not minimize on focus loss.
97  // Minimizing was reported as bug #1606 with blocker priority.
98  SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
99 
100  fill(0,0,0);
101 
102  render();
103 
104  // If we didn't explicitly ask for the window to be hidden, show it
105  if(!(window_flags & SDL_WINDOW_HIDDEN)) {
106  SDL_ShowWindow(window_);
107  }
108 }
109 
111 {
112  if(window_) {
113  SDL_DestroyWindow(window_);
114  }
115 }
116 
117 void window::set_size(const int w, const int h)
118 {
119 #ifdef __ANDROID__
120  SDL_SetRenderLogicalPresentation(SDL_GetRenderer(window_), w, h, SDL_LOGICAL_PRESENTATION_INTEGER_SCALE);
121  SDL_WarpMouseInWindow(window_, w / 2, h / 2);
122 #else
123  SDL_SetWindowSize(window_, w, h);
124 #endif
125 }
126 
128 {
129  point res;
130 #ifdef __ANDROID__
131  SDL_GetRenderLogicalPresentation(SDL_GetRenderer(window_), &res.x, &res.y, nullptr);
132 #else
133  SDL_GetWindowSize(*this, &res.x, &res.y);
134 #endif
135 
136  return res;
137 }
138 
140 {
141  point res;
142  SDL_GetCurrentRenderOutputSize(*this, &res.x, &res.y);
143 
144  return res;
145 }
146 
148 {
149 #ifndef __ANDROID__
150  SDL_SetWindowPosition(window_, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
151 #endif
152 }
153 
155 {
156 #ifndef __ANDROID__
157  SDL_MaximizeWindow(window_);
158 #endif
159 }
160 
162 {
163 #ifndef __ANDROID__
164  SDL_SetWindowFullscreen(window_, false);
165 #endif
166 }
167 
169 {
170 #ifndef __ANDROID__
171  SDL_RestoreWindow(window_);
172 #endif
173 }
174 
176 {
177 #ifndef __ANDROID__
178  SDL_SetWindowFullscreen(window_, true);
179 #endif
180 }
181 
182 void window::fill(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
183 {
184  SDL_SetRenderDrawColor(*this, r, g, b, a);
185  if(!SDL_RenderClear(*this)) {
186  throw exception("Failed to clear the SDL_Renderer object.", true);
187  }
188 }
189 
191 {
192  SDL_RenderPresent(*this);
193 }
194 
195 #ifndef __ANDROID__
196 void window::set_title(const std::string& title)
197 {
198  SDL_SetWindowTitle(window_, title.c_str());
199 }
200 
201 void window::set_icon(const surface& icon)
202 {
203  SDL_SetWindowIcon(window_, icon);
204 }
205 
206 void window::set_minimum_size(int min_w, int min_h)
207 {
208  SDL_SetWindowMinimumSize(window_, min_w, min_h);
209 }
210 #else
211 void window::set_title(const std::string&) {};
212 void window::set_icon(const surface&) {};
213 void window::set_minimum_size(int, int) {};
214 #endif
215 
217 {
218  return SDL_GetWindowFlags(window_);
219 }
220 
222 {
223  return SDL_GetDisplayForWindow(window_);
224 }
225 
227 {
228  SDL_Renderer* r = SDL_GetRenderer(window_);
229  // Non-integer scales are not currently supported.
230  // This option makes things neater when window size is not a perfect
231  // multiple of logical size, which can happen when manually resizing.
232  SDL_SetRenderLogicalPresentation(r, w, h, SDL_LOGICAL_PRESENTATION_INTEGER_SCALE);
233 }
234 
236 {
237  set_logical_size(p.x, p.y);
238 }
239 
241 {
242  SDL_Renderer* r = SDL_GetRenderer(window_);
243  int w, h;
244  SDL_RendererLogicalPresentation mode = SDL_LOGICAL_PRESENTATION_INTEGER_SCALE;
245  SDL_GetRenderLogicalPresentation(r, &w, &h, &mode);
246  return {w, h};
247 }
248 
249 void window::get_logical_size(int& w, int& h) const
250 {
251  SDL_Renderer* r = SDL_GetRenderer(window_);
252  SDL_RendererLogicalPresentation mode = SDL_LOGICAL_PRESENTATION_INTEGER_SCALE;
253  SDL_GetRenderLogicalPresentation(r, &w, &h, &mode);
254 }
255 
256 window::operator SDL_Window*()
257 {
258  return window_;
259 }
260 
261 window::operator SDL_Renderer*()
262 {
263  return SDL_GetRenderer(window_);
264 }
265 
266 } // 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:117
void to_window()
Dummy function for returning the window to windowed mode.
Definition: window.cpp:161
window(const window &)=delete
point get_size()
Gets the window's size, in screen coordinates.
Definition: window.cpp:127
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:182
point get_logical_size() const
Definition: window.cpp:240
void center()
Dummy function for centering the window.
Definition: window.cpp:147
void render()
Renders the contents of the window.
Definition: window.cpp:190
void restore()
Dummy function for restoring the window.
Definition: window.cpp:168
void set_minimum_size(int min_w, int min_h)
Set minimum size of the window.
Definition: window.cpp:206
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:175
int get_display_index()
Definition: window.cpp:221
void set_icon(const surface &icon)
Sets the icon of the window.
Definition: window.cpp:201
void set_logical_size(int w, int h)
Sets the desired size of the rendering surface.
Definition: window.cpp:226
void maximize()
Dummy function for maximizing the window.
Definition: window.cpp:154
uint32_t get_flags()
Definition: window.cpp:216
void set_title(const std::string &title)
Sets the title of the window.
Definition: window.cpp:196
point get_output_size()
Gets the window's renderer output size, in pixels.
Definition: window.cpp:139
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