• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Return-To-The-Roots / s25client / 22039819810

15 Feb 2026 05:18PM UTC coverage: 50.781% (-0.04%) from 50.82%
22039819810

Pull #1890

github

web-flow
Merge ededb8a2f into 6db06730b
Pull Request #1890: Add support for borderless Windows

13 of 115 new or added lines in 10 files covered. (11.3%)

7 existing lines in 4 files now uncovered.

22798 of 44895 relevant lines covered (50.78%)

43455.62 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

8.74
/extras/videoDrivers/SDL2/VideoSDL2.cpp
1
// Copyright (C) 2005 - 2026 Settlers Freaks (sf-team at siedler25.org)
2
//
3
// SPDX-License-Identifier: GPL-2.0-or-later
4

5
#include "VideoSDL2.h"
6
#include "RTTR_Assert.h"
7
#include "driver/Interface.h"
8
#include "driver/VideoDriverLoaderInterface.h"
9
#include "driver/VideoInterface.h"
10
#include "enum_cast.hpp"
11
#include "helpers/LSANUtils.h"
12
#include "helpers/containerUtils.h"
13
#include "icon.h"
14
#include "openglCfg.hpp"
15
#include <s25util/utf8.h>
16
#include <boost/nowide/iostream.hpp>
17
#include <SDL.h>
18
#include <SDL_hints.h>
19
#include <SDL_video.h>
20
#include <algorithm>
21
#include <memory>
22

23
#ifdef _WIN32
24
#    include <boost/nowide/convert.hpp>
25
#    ifndef WIN32_LEAN_AND_MEAN
26
#        define WIN32_LEAN_AND_MEAN
27
#    endif
28
#    include <windows.h> // Avoid "Windows headers require the default packing option" due to SDL2
29
#    include <SDL_syswm.h>
30
#endif // _WIN32
31
#if RTTR_OGL_GL4ES
32
#    include <gl4esinit.h>
33
#endif
34

35
/// Check that the (SDL) call returns success or print the error
36
/// Can be used in conditions: if(CHECK_SDL(SDL_Foo()))
37
#define CHECK_SDL(call) ((call) >= 0 || (PrintError(), false))
38

39
namespace {
40

41
template<typename T>
42
struct SDLMemoryDeleter
43
{
44
    void operator()(T* p) const { SDL_free(p); }
×
45
};
46

47
template<typename T>
48
using SDL_memory = std::unique_ptr<T, SDLMemoryDeleter<T>>;
49

50
void setSpecialKeys(KeyEvent& ke, const SDL_Keymod mod)
×
51
{
52
    ke.ctrl = (mod & KMOD_CTRL);
×
53
    ke.shift = (mod & KMOD_SHIFT);
×
54
    ke.alt = (mod & KMOD_ALT);
×
55
}
×
56
void setSpecialKeys(KeyEvent& ke)
×
57
{
58
    setSpecialKeys(ke, SDL_GetModState());
×
59
}
×
60
} // namespace
61

62
IVideoDriver* CreateVideoInstance(VideoDriverLoaderInterface* CallBack)
1✔
63
{
64
    return new VideoSDL2(CallBack);
1✔
65
}
66

67
void FreeVideoInstance(IVideoDriver* driver)
1✔
68
{
69
    delete driver;
1✔
70
}
1✔
71

72
const char* GetDriverName()
5✔
73
{
74
#if RTTR_OGL_GL4ES
75
    return "(SDL2) OpenGL-ES gl4es via SDL2-Library";
76
#else
77
    return "(SDL2) OpenGL via SDL2-Library";
5✔
78
#endif
79
}
80

81
VideoSDL2::VideoSDL2(VideoDriverLoaderInterface* CallBack) : VideoDriver(CallBack), window(nullptr), context(nullptr) {}
1✔
82

83
VideoSDL2::~VideoSDL2()
2✔
84
{
85
    CleanUp();
1✔
86
}
2✔
87

88
const char* VideoSDL2::GetName() const
2✔
89
{
90
    return GetDriverName();
2✔
91
}
92

93
bool VideoSDL2::Initialize()
1✔
94
{
95
    initialized = false;
1✔
96
    rttr::ScopedLeakDisabler _;
1✔
97
    // Do not emulate mouse events using touch
98
    SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0");
1✔
99
    if(SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
1✔
100
    {
NEW
101
        PrintError();
×
102
        return false;
×
103
    }
104

105
    initialized = true;
1✔
106
    return initialized;
1✔
107
}
108

109
void VideoSDL2::CleanUp()
1✔
110
{
111
    if(!initialized)
1✔
112
        return;
×
113

114
    if(context)
1✔
115
        SDL_GL_DeleteContext(context);
×
116
    if(window)
1✔
117
        SDL_DestroyWindow(window);
×
118
    SDL_QuitSubSystem(SDL_INIT_VIDEO);
1✔
119
    SDL_Quit();
1✔
120
    initialized = false;
1✔
121
}
122

123
void VideoSDL2::UpdateCurrentSizes()
×
124
{
125
    int w, h, w2, h2;
126
    SDL_GetWindowSize(window, &w, &h);
×
127
    SDL_GL_GetDrawableSize(window, &w2, &h2);
×
128
    SetNewSize(VideoMode(w, h), Extent(w2, h2));
×
129
}
×
130

NEW
131
bool VideoSDL2::CreateScreen(const std::string& title, const VideoMode& size, DisplayMode displayMode)
×
132
{
133
    if(!initialized)
×
134
        return false;
×
135

136
    // GL-Attributes
137
    CHECK_SDL(SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, RTTR_OGL_MAJOR));
×
138
    CHECK_SDL(SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, RTTR_OGL_MINOR));
×
139
    SDL_GLprofile profile;
140
    if(RTTR_OGL_ES || RTTR_OGL_GL4ES)
141
        profile = SDL_GL_CONTEXT_PROFILE_ES;
142
    else if(RTTR_OGL_COMPAT)
143
        profile = SDL_GL_CONTEXT_PROFILE_COMPATIBILITY;
×
144
    else
145
        profile = SDL_GL_CONTEXT_PROFILE_CORE;
146

147
    CHECK_SDL(SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, profile));
×
148

149
    CHECK_SDL(SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8));
×
150
    CHECK_SDL(SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8));
×
151
    CHECK_SDL(SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8));
×
152
    CHECK_SDL(SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1));
×
153

NEW
154
    const int wndPos = SDL_WINDOWPOS_CENTERED;
×
NEW
155
    const auto fullscreen = displayMode == DisplayMode::Fullscreen;
×
156
    const auto requestedSize = fullscreen ? FindClosestVideoMode(size) : size;
×
NEW
157
    const unsigned commonFlags = SDL_WINDOW_OPENGL;
×
158
    // TODO: Fix GUI scaling with High DPI support enabled.
159
    // See https://github.com/Return-To-The-Roots/s25client/issues/1621
160
    // commonFlags |= SDL_WINDOW_ALLOW_HIGHDPI;
161

NEW
162
    const unsigned windowTypeFlag =
×
NEW
163
      fullscreen ? SDL_WINDOW_FULLSCREEN :
×
164
                   (displayMode == DisplayMode::BorderlessWindow ? SDL_WINDOW_BORDERLESS : SDL_WINDOW_RESIZABLE);
165

166
    window = SDL_CreateWindow(title.c_str(), wndPos, wndPos, requestedSize.width, requestedSize.height,
×
167
                              commonFlags | windowTypeFlag);
168

NEW
169
    if(!window)
×
170
    {
NEW
171
        PrintError();
×
172
        // Fallback to borderless fullscreen
NEW
173
        if(fullscreen)
×
174
        {
175
            SDL_DisplayMode dskSize;
NEW
176
            if(!CHECK_SDL(SDL_GetDesktopDisplayMode(0, &dskSize)))
×
177
            {
NEW
178
                dskSize.w = size.width;
×
NEW
179
                dskSize.h = size.height;
×
180
            }
NEW
181
            window = SDL_CreateWindow(title.c_str(), wndPos, wndPos, dskSize.w, dskSize.h,
×
182
                                      commonFlags | SDL_WINDOW_BORDERLESS);
183
        }
184
        // No borderless -> Resizable
NEW
185
        if(!window)
×
186
        {
NEW
187
            window = SDL_CreateWindow(title.c_str(), wndPos, wndPos, size.width, size.height,
×
188
                                      commonFlags | SDL_WINDOW_RESIZABLE);
189
        }
190
    }
191

192
    if(!window)
×
193
    {
NEW
194
        PrintError();
×
195
        return false;
×
196
    }
197

NEW
198
    UpdateCurrentDisplayMode();
×
199
    UpdateCurrentSizes();
×
200

NEW
201
    if(displayMode_ != DisplayMode::Fullscreen)
×
202
        MoveWindowToCenter();
×
203

204
    SDL_Surface* iconSurf =
205
      SDL_CreateRGBSurfaceFrom(image.data(), 48, 48, 32, 48 * 4, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
×
206
    if(iconSurf)
×
207
    {
208
        SDL_SetWindowIcon(window, iconSurf);
×
209
        SDL_FreeSurface(iconSurf);
×
210
    } else
NEW
211
        PrintError();
×
212

213
    context = SDL_GL_CreateContext(window);
×
214

215
#ifdef _WIN32
216
    SetWindowTextW(GetConsoleWindow(), boost::nowide::widen(title).c_str());
217
#endif
218

219
    std::fill(keyboard.begin(), keyboard.end(), false);
×
220

221
    SDL_ShowCursor(0);
×
222

223
    return true;
×
224
}
225

NEW
226
bool VideoSDL2::ResizeScreen(const VideoMode& newSize, DisplayMode displayMode)
×
227
{
228
    if(!initialized)
×
229
        return false;
×
230

NEW
231
    if(displayMode_ != displayMode)
×
232
    {
NEW
233
        if(displayMode_ == DisplayMode::Fullscreen || displayMode == DisplayMode::Fullscreen)
×
234
        {
NEW
235
            if(!CHECK_SDL(
×
236
                 SDL_SetWindowFullscreen(window, (displayMode == DisplayMode::Fullscreen) ? SDL_WINDOW_FULLSCREEN : 0)))
237
            {
NEW
238
                if(displayMode == DisplayMode::Fullscreen)
×
NEW
239
                    displayMode = DisplayMode::BorderlessWindow;
×
240
            }
241
        }
NEW
242
        SDL_SetWindowResizable(window, static_cast<SDL_bool>(displayMode == DisplayMode::Windowed));
×
NEW
243
        SDL_SetWindowBordered(window, static_cast<SDL_bool>(displayMode != DisplayMode::BorderlessWindow));
×
244

NEW
245
        UpdateCurrentDisplayMode();
×
NEW
246
        if(displayMode_ != DisplayMode::Fullscreen)
×
NEW
247
            MoveWindowToCenter();
×
248
    }
UNCOV
249
    if(newSize != GetWindowSize())
×
250
    {
NEW
251
        if(displayMode_ == DisplayMode::Fullscreen)
×
252
        {
253
            auto const targetMode = FindClosestVideoMode(newSize);
×
254
            SDL_DisplayMode target;
255
            target.w = targetMode.width;
×
256
            target.h = targetMode.height;
×
257
            target.format = 0;           // don't care
×
258
            target.refresh_rate = 0;     // don't care
×
259
            target.driverdata = nullptr; // initialize to 0
×
260
            // Explicitly change the window size to avoid a bug with SDL reporting the wrong size until alt+tab
261
            SDL_SetWindowSize(window, target.w, target.h);
×
NEW
262
            if(!CHECK_SDL(SDL_SetWindowDisplayMode(window, &target)))
×
UNCOV
263
                return false;
×
264
        } else
UNCOV
265
            SDL_SetWindowSize(window, newSize.width, newSize.height);
×
266
        UpdateCurrentSizes();
×
267
    }
268

UNCOV
269
    return true;
×
270
}
271

NEW
272
void VideoSDL2::PrintError()
×
273
{
NEW
274
    PrintError(SDL_GetError());
×
NEW
275
}
×
276

NEW
277
void VideoSDL2::PrintError(const std::string& msg)
×
278
{
279
    boost::nowide::cerr << msg << std::endl;
×
280
}
×
281

282
void VideoSDL2::ShowErrorMessage(const std::string& title, const std::string& message)
×
283
{
284
    // window==nullptr is okay too ("no parent")
285
#ifdef __linux__
286
    // When using window, SDL will try to use a system tool like "zenity" which isn't always installed on every distro
287
    // so rttr will crash. But without a window it will use an x11 backend that should be available on x11 AND wayland
288
    // for compatibility reasons
289
    SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, title.c_str(), message.c_str(), nullptr);
×
290
#else
291
    SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, title.c_str(), message.c_str(), window);
292
#endif
293
}
×
294

295
void VideoSDL2::HandlePaste()
×
296
{
297
    if(!SDL_HasClipboardText())
×
298
        return;
×
299

300
    SDL_memory<char> text(SDL_GetClipboardText());
×
301
    if(!text || *text == '\0') // empty string indicates error
×
302
        PrintError(text ? SDL_GetError() : "Paste failed.");
×
303

304
    for(const char32_t c : s25util::utf8to32(text.get()))
×
305
        CallBack->Msg_KeyDown(KeyEvent(c));
×
306
}
307

308
void VideoSDL2::DestroyScreen()
×
309
{
310
    CleanUp();
×
311
}
×
312

313
bool VideoSDL2::SwapBuffers()
×
314
{
315
    SDL_GL_SwapWindow(window);
×
316
    return true;
×
317
}
318

319
bool VideoSDL2::MessageLoop()
×
320
{
321
    SDL_Event ev;
322
    while(SDL_PollEvent(&ev))
×
323
    {
324
        switch(ev.type)
×
325
        {
326
            default: break;
×
327

328
            case SDL_QUIT: return false;
×
329
            case SDL_WINDOWEVENT:
×
330
            {
331
                switch(ev.window.event)
×
332
                {
333
                    case SDL_WINDOWEVENT_RESIZED:
×
334
                    {
NEW
335
                        UpdateCurrentDisplayMode();
×
336
                        VideoMode newSize(ev.window.data1, ev.window.data2);
×
337
                        if(newSize != GetWindowSize())
×
338
                        {
339
                            UpdateCurrentSizes();
×
340
                            CallBack->WindowResized();
×
341
                        }
342
                    }
343
                    break;
×
344
                }
345
            }
346
            break;
×
347

348
            case SDL_KEYDOWN:
×
349
            {
350
                KeyEvent ke;
×
351

352
                switch(ev.key.keysym.sym)
×
353
                {
354
                    default:
×
355
                    {
356
                        // Die 12 F-Tasten
357
                        if(ev.key.keysym.sym >= SDLK_F1 && ev.key.keysym.sym <= SDLK_F12)
×
358
                            ke.kt = static_cast<KeyType>(rttr::enum_cast(KeyType::F1) + ev.key.keysym.sym - SDLK_F1);
×
359
                    }
360
                    break;
×
361
                    case SDLK_RETURN: ke.kt = KeyType::Return; break;
×
362
                    case SDLK_SPACE: ke.kt = KeyType::Space; break;
×
363
                    case SDLK_LEFT: ke.kt = KeyType::Left; break;
×
364
                    case SDLK_RIGHT: ke.kt = KeyType::Right; break;
×
365
                    case SDLK_UP: ke.kt = KeyType::Up; break;
×
366
                    case SDLK_DOWN: ke.kt = KeyType::Down; break;
×
367
                    case SDLK_BACKSPACE: ke.kt = KeyType::Backspace; break;
×
368
                    case SDLK_DELETE: ke.kt = KeyType::Delete; break;
×
369
                    case SDLK_LSHIFT:
×
370
                    case SDLK_RSHIFT: ke.kt = KeyType::Shift; break;
×
371
                    case SDLK_TAB: ke.kt = KeyType::Tab; break;
×
372
                    case SDLK_HOME: ke.kt = KeyType::Home; break;
×
373
                    case SDLK_END: ke.kt = KeyType::End; break;
×
374
                    case SDLK_ESCAPE: ke.kt = KeyType::Escape; break;
×
375
                    case SDLK_PRINTSCREEN: ke.kt = KeyType::Print; break;
×
376
                    // case SDLK_BACKQUOTE: ev.key.keysym.scancode = '^'; break;
377
                    case SDLK_v:
×
378
                        if(SDL_GetModState() & KMOD_CTRL)
×
379
                        {
380
                            HandlePaste();
×
381
                            continue;
×
382
                        }
383
                        break;
×
384
                }
385

386
                setSpecialKeys(ke, SDL_Keymod(ev.key.keysym.mod));
×
387

388
                if(ke.kt != KeyType::Invalid)
×
389
                    CallBack->Msg_KeyDown(ke);
×
390
                else if(ke.alt || ke.ctrl)
×
391
                {
392
                    // Handle shortcuts (CTRL+x, ALT+y)
393
                    // but not possible combinations (ALT+0054)
394
                    const SDL_Keycode keycode = ev.key.keysym.sym;
×
395
                    if(keycode >= 'a' && keycode <= 'z')
×
396
                    {
397
                        ke.kt = KeyType::Char;
×
398
                        ke.c = static_cast<char32_t>(keycode);
×
399
                        CallBack->Msg_KeyDown(ke);
×
400
                    }
401
                }
402
            }
403
            break;
×
404
            case SDL_TEXTINPUT:
×
405
            {
406
                const std::u32string text = s25util::utf8to32(ev.text.text);
×
407
                KeyEvent ke(0);
×
408
                setSpecialKeys(ke);
×
409
                for(char32_t c : text)
×
410
                {
411
                    ke.c = c;
×
412
                    CallBack->Msg_KeyDown(ke);
×
413
                }
414
                break;
×
415
            }
416
            case SDL_MOUSEBUTTONDOWN:
×
417
                mouse_xy.pos = getGuiScale().screenToView(Position(ev.button.x, ev.button.y));
×
418

419
                if(/*!mouse_xy.ldown && */ ev.button.button == SDL_BUTTON_LEFT)
×
420
                {
421
                    mouse_xy.ldown = true;
×
422
                    CallBack->Msg_LeftDown(mouse_xy);
×
423
                }
424
                if(/*!mouse_xy.rdown &&*/ ev.button.button == SDL_BUTTON_RIGHT)
×
425
                {
426
                    mouse_xy.rdown = true;
×
427
                    CallBack->Msg_RightDown(mouse_xy);
×
428
                }
429
                break;
×
430
            case SDL_MOUSEBUTTONUP:
×
431
                mouse_xy.pos = getGuiScale().screenToView(Position(ev.button.x, ev.button.y));
×
432

433
                if(/*mouse_xy.ldown &&*/ ev.button.button == SDL_BUTTON_LEFT)
×
434
                {
435
                    mouse_xy.ldown = false;
×
436
                    CallBack->Msg_LeftUp(mouse_xy);
×
437
                }
438
                if(/*mouse_xy.rdown &&*/ ev.button.button == SDL_BUTTON_RIGHT)
×
439
                {
440
                    mouse_xy.rdown = false;
×
441
                    CallBack->Msg_RightUp(mouse_xy);
×
442
                }
443
                break;
×
444
            case SDL_MOUSEWHEEL:
×
445
            {
446
                int y = ev.wheel.y;
×
447
                if(ev.wheel.direction == SDL_MOUSEWHEEL_FLIPPED)
×
448
                    y = -y;
×
449
                if(y > 0)
×
450
                    CallBack->Msg_WheelUp(mouse_xy);
×
451
                else if(y < 0)
×
452
                    CallBack->Msg_WheelDown(mouse_xy);
×
453
            }
454
            break;
×
455
            case SDL_MOUSEMOTION:
×
456
            {
457
                const auto newPos = getGuiScale().screenToView(Position(ev.motion.x, ev.motion.y));
×
458
                // Avoid duplicate events especially when warping the mouse
459
                if(newPos != mouse_xy.pos)
×
460
                {
461
                    mouse_xy.pos = newPos;
×
462
                    CallBack->Msg_MouseMove(mouse_xy);
×
463
                }
464
            }
465
            break;
×
466
            case SDL_FINGERDOWN:
×
467
            {
468
                VideoMode wnSize = GetWindowSize();
×
469
                mouse_xy.pos = getGuiScale().screenToView(Position(static_cast<int>(ev.tfinger.x * wnSize.width),
×
470
                                                                   static_cast<int>(ev.tfinger.y * wnSize.height)));
×
471
                mouse_xy.ldown = true;
×
472
                mouse_xy.num_tfingers++;
×
473
                CallBack->Msg_LeftDown(mouse_xy);
×
474
                break;
×
475
            }
476
            case SDL_FINGERUP:
×
477
            {
478
                VideoMode wnSize = GetWindowSize();
×
479
                mouse_xy.pos = getGuiScale().screenToView(Position(static_cast<int>(ev.tfinger.x * wnSize.width),
×
480
                                                                   static_cast<int>(ev.tfinger.y * wnSize.height)));
×
481
                mouse_xy.ldown = false;
×
482
                CallBack->Msg_LeftUp(mouse_xy);
×
483
                mouse_xy.num_tfingers--; // Dirty way to count leftUp as touch event without extra isTouch bool
×
484
                break;
×
485
            }
486
            case SDL_FINGERMOTION:
×
487
            {
488
                VideoMode wnSize = GetWindowSize();
×
489
                const auto newPos = getGuiScale().screenToView(Position(
×
490
                  static_cast<int>(ev.tfinger.x * wnSize.width), static_cast<int>(ev.tfinger.y * wnSize.height)));
×
491

492
                if(newPos != mouse_xy.pos)
×
493
                {
494
                    mouse_xy.pos = newPos;
×
495
                    CallBack->Msg_MouseMove(mouse_xy);
×
496
                }
497
                break;
×
498
            }
499
            case SDL_MULTIGESTURE:
×
500
            {
501
                if(std::fabs(ev.mgesture.dDist) > 0.001)
×
502
                {
503
                    if(ev.mgesture.dDist > 0)
×
504
                        CallBack->Msg_WheelUp(mouse_xy);
×
505
                    else
506
                        CallBack->Msg_WheelDown(mouse_xy);
×
507
                }
508
                break;
×
509
            }
510
        }
511
    }
512

513
    return true;
×
514
}
515

516
unsigned long VideoSDL2::GetTickCount() const
×
517
{
518
    return SDL_GetTicks();
×
519
}
520

521
void VideoSDL2::ListVideoModes(std::vector<VideoMode>& video_modes) const
×
522
{
523
    int display = SDL_GetWindowDisplayIndex(window);
×
524
    if(display < 0)
×
525
        display = 0;
×
526
    for(int i = SDL_GetNumDisplayModes(display) - 1; i >= 0; --i)
×
527
    {
528
        SDL_DisplayMode mode;
529
        if(SDL_GetDisplayMode(display, i, &mode) != 0)
×
NEW
530
            PrintError();
×
531
        else
532
        {
533
            VideoMode vm(mode.w, mode.h);
×
534
            if(!helpers::contains(video_modes, vm))
×
535
                video_modes.push_back(vm);
×
536
        }
537
    }
538
}
×
539

540
OpenGL_Loader_Proc VideoSDL2::GetLoaderFunction() const
×
541
{
542
#if RTTR_OGL_GL4ES
543
    return gl4es_GetProcAddress;
544
#else
545
    return SDL_GL_GetProcAddress;
×
546
#endif
547
}
548

549
void VideoSDL2::SetMousePos(Position pos)
×
550
{
551
    const auto screenPos = getGuiScale().viewToScreen(pos);
×
552
    mouse_xy.pos = pos;
×
553
    SDL_WarpMouseInWindow(window, screenPos.x, screenPos.y);
×
554
}
×
555

556
KeyEvent VideoSDL2::GetModKeyState() const
×
557
{
558
    KeyEvent ke;
×
559
    setSpecialKeys(ke);
×
560
    return ke;
×
561
}
562

563
void* VideoSDL2::GetMapPointer() const
×
564
{
565
#ifdef WIN32
566
    SDL_SysWMinfo wmInfo;
567
    SDL_VERSION(&wmInfo.version);
568
    SDL_GetWindowWMInfo(window, &wmInfo);
569
    // return (void*)wmInfo.info.win.window;
570
    return (void*)wmInfo.info.win.window;
571
#else
572
    return nullptr;
×
573
#endif
574
}
575

576
void VideoSDL2::MoveWindowToCenter()
×
577
{
578
    SDL_Rect usableBounds;
579
    CHECK_SDL(SDL_GetDisplayUsableBounds(SDL_GetWindowDisplayIndex(window), &usableBounds));
×
580
    int top, left, bottom, right;
581
    if(CHECK_SDL(SDL_GetWindowBordersSize(window, &top, &left, &bottom, &right)) != 0)
×
582
        top = left = bottom = right = 0;
×
583
    usableBounds.w -= left + right;
×
584
    usableBounds.h -= top + bottom;
×
585
    if(usableBounds.w < GetWindowSize().width || usableBounds.h < GetWindowSize().height)
×
586
    {
587
        SDL_SetWindowSize(window, usableBounds.w, usableBounds.h);
×
588
        UpdateCurrentSizes();
×
589
    }
590
    SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
×
591
}
×
592

NEW
593
void VideoSDL2::UpdateCurrentDisplayMode()
×
594
{
NEW
595
    RTTR_Assert(window);
×
NEW
596
    const auto flags = SDL_GetWindowFlags(window);
×
NEW
597
    if(flags & SDL_WINDOW_FULLSCREEN)
×
NEW
598
        displayMode_ = DisplayMode::Fullscreen;
×
NEW
599
    else if((flags & SDL_WINDOW_BORDERLESS) != 0)
×
NEW
600
        displayMode_ = DisplayMode::BorderlessWindow;
×
601
    else
NEW
602
        displayMode_ = DisplayMode::Windowed;
×
NEW
603
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc