Skip to content

Commit 0567326

Browse files
committed
SDL3: display+window: runtime fixes
1 parent 835ed28 commit 0567326

File tree

3 files changed

+135
-59
lines changed

3 files changed

+135
-59
lines changed

src_c/_pygame.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,8 @@ PG_GetSurfaceFormat(SDL_Surface *surf)
167167

168168
#define PG_GetSurfaceClipRect SDL_GetSurfaceClipRect
169169

170+
#define PG_GL_SetSwapInterval SDL_GL_SetSwapInterval
171+
170172
#else /* ~SDL_VERSION_ATLEAST(3, 0, 0)*/
171173
#define PG_ShowCursor() SDL_ShowCursor(SDL_ENABLE)
172174
#define PG_HideCursor() SDL_ShowCursor(SDL_DISABLE)
@@ -375,6 +377,12 @@ PG_GetSurfaceClipRect(SDL_Surface *surface, SDL_Rect *rect)
375377
*rect = surface->clip_rect;
376378
return true;
377379
}
380+
381+
static inline bool
382+
SDL_GL_SetSwapInterval(int interval)
383+
{
384+
return SDL_GL_SetSwapInterval(interval) == 0;
385+
}
378386
#endif
379387

380388
/* DictProxy is useful for event posting with an arbitrary dict. Maintains

src_c/display.c

Lines changed: 97 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,11 @@ pg_get_init(PyObject *self, PyObject *_null)
279279
static PyObject *
280280
pg_get_active(PyObject *self, PyObject *_null)
281281
{
282-
SDL_WindowFlags flags = SDL_GetWindowFlags(pg_GetDefaultWindow());
282+
SDL_Window *win = pg_GetDefaultWindow();
283+
if (!win) {
284+
Py_RETURN_FALSE;
285+
}
286+
SDL_WindowFlags flags = SDL_GetWindowFlags(win);
283287

284288
#if SDL_VERSION_ATLEAST(3, 0, 0)
285289
return PyBool_FromLong(!(flags & SDL_WINDOW_HIDDEN) &&
@@ -460,7 +464,12 @@ pg_GetVideoInfo(pg_VideoInfo *info)
460464
}
461465
else {
462466
#if SDL_VERSION_ATLEAST(3, 0, 0)
463-
if ((mode_ptr = SDL_GetCurrentDisplayMode(0))) {
467+
SDL_DisplayID primary_display = SDL_GetPrimaryDisplay();
468+
if (primary_display == 0) {
469+
PyErr_SetString(pgExc_SDLError, SDL_GetError());
470+
return (pg_VideoInfo *)NULL;
471+
}
472+
if ((mode_ptr = SDL_GetCurrentDisplayMode(primary_display))) {
464473
info->current_w = mode_ptr->w;
465474
info->current_h = mode_ptr->h;
466475
formatenum = mode_ptr->format;
@@ -1118,12 +1127,12 @@ PG_CreateWindowCompat(const char *title, int x, int y, int w, int h,
11181127
}
11191128

11201129
#if SDL_VERSION_ATLEAST(3, 0, 0)
1121-
/* Returns 0 on success, negative on failure. */
1122-
static int
1130+
/* Returns true on success, false on failure. */
1131+
static bool
11231132
PG_SetWindowFullscreen(SDL_Window *window, bool fullscreen,
11241133
bool non_desktop_fullscreen)
11251134
{
1126-
int ret = -1;
1135+
bool ret = false;
11271136
SDL_DisplayMode **modes = NULL;
11281137
SDL_DisplayMode *chosen_mode = NULL;
11291138
if (!SDL_SetWindowFullscreen(window, fullscreen)) {
@@ -1152,11 +1161,24 @@ PG_SetWindowFullscreen(SDL_Window *window, bool fullscreen,
11521161
}
11531162
}
11541163

1155-
ret = 0;
1164+
SDL_SyncWindow(window);
1165+
ret = true;
11561166
end:
11571167
SDL_free(modes);
11581168
return ret;
11591169
}
1170+
#else
1171+
static bool
1172+
PG_SetWindowFullscreen(SDL_Window *window, bool fullscreen,
1173+
bool non_desktop_fullscreen)
1174+
{
1175+
int flags = 0;
1176+
if (fullscreen) {
1177+
flags = non_desktop_fullscreen ? SDL_WINDOW_FULLSCREEN
1178+
: SDL_WINDOW_FULLSCREEN_DESKTOP;
1179+
}
1180+
return (SDL_SetWindowFullscreen(window, flags) == 0) ? true : false;
1181+
}
11601182
#endif
11611183

11621184
static PyObject *
@@ -1235,6 +1257,16 @@ pg_set_mode(PyObject *self, PyObject *arg, PyObject *kwds)
12351257
}
12361258
}
12371259

1260+
#if SDL_VERSION_ATLEAST(3, 0, 0)
1261+
/* In SDL2, display == 0 meant primary display, so compat code for it */
1262+
if (display == 0) {
1263+
display = SDL_GetPrimaryDisplay();
1264+
if (display == 0) {
1265+
return RAISE(pgExc_SDLError, SDL_GetError());
1266+
}
1267+
}
1268+
#endif
1269+
12381270
if ((vsync == -1) && ((flags & PGS_OPENGL) == 0)) {
12391271
return RAISE(PyExc_ValueError,
12401272
"requested adaptive vsync without OpenGL");
@@ -1437,11 +1469,16 @@ pg_set_mode(PyObject *self, PyObject *arg, PyObject *kwds)
14371469
if (flags & PGS_SCALED && !(flags & PGS_FULLSCREEN)) {
14381470
SDL_Rect display_bounds;
14391471
int fractional_scaling = SDL_FALSE;
1440-
1472+
#if SDL_VERSION_ATLEAST(3, 0, 0)
1473+
if (!SDL_GetDisplayUsableBounds(display, &display_bounds)) {
1474+
return RAISE(pgExc_SDLError, SDL_GetError());
1475+
}
1476+
#else
14411477
if (0 !=
14421478
SDL_GetDisplayUsableBounds(display, &display_bounds)) {
14431479
return RAISE(pgExc_SDLError, SDL_GetError());
14441480
}
1481+
#endif
14451482

14461483
if (SDL_GetHintBoolean("SDL_HINT_RENDER_SCALE_QUALITY",
14471484
SDL_FALSE)) {
@@ -1592,7 +1629,7 @@ pg_set_mode(PyObject *self, PyObject *arg, PyObject *kwds)
15921629
vsync to be always on or always off, or vsync is on by default
15931630
for the whole desktop because of wayland GL compositing. */
15941631
if (vsync == -1) {
1595-
if (SDL_GL_SetSwapInterval(-1) != 0) {
1632+
if (!PG_GL_SetSwapInterval(-1)) {
15961633
PyErr_SetString(pgExc_SDLError,
15971634
"adaptive vsync for OpenGL not "
15981635
"available");
@@ -1602,7 +1639,7 @@ pg_set_mode(PyObject *self, PyObject *arg, PyObject *kwds)
16021639
}
16031640
}
16041641
else if (vsync == 1) {
1605-
if (SDL_GL_SetSwapInterval(1) != 0) {
1642+
if (!PG_GL_SetSwapInterval(1)) {
16061643
PyErr_SetString(pgExc_SDLError,
16071644
"regular vsync for OpenGL not "
16081645
"available");
@@ -1611,7 +1648,7 @@ pg_set_mode(PyObject *self, PyObject *arg, PyObject *kwds)
16111648
}
16121649
}
16131650
else {
1614-
SDL_GL_SetSwapInterval(0);
1651+
PG_GL_SetSwapInterval(0);
16151652
}
16161653
}
16171654
else {
@@ -1849,6 +1886,9 @@ pg_set_mode(PyObject *self, PyObject *arg, PyObject *kwds)
18491886
}
18501887
}
18511888
}
1889+
#if SDL_VERSION_ATLEAST(3, 0, 0)
1890+
SDL_SyncWindow(win);
1891+
#endif
18521892

18531893
/*return the window's surface (screen)*/
18541894
Py_INCREF(surface);
@@ -1947,6 +1987,9 @@ pg_set_window_position(PyObject *self, PyObject *arg)
19471987
if (win) {
19481988
/* Will raise errors with SDL 3, deal with it during the porting */
19491989
SDL_SetWindowPosition(win, x, y);
1990+
#if SDL_VERSION_ATLEAST(3, 0, 0)
1991+
SDL_SyncWindow(win);
1992+
#endif
19501993
}
19511994

19521995
Py_RETURN_NONE;
@@ -1973,7 +2016,16 @@ pg_mode_ok(PyObject *self, PyObject *args, PyObject *kwds)
19732016
&display_index)) {
19742017
return NULL;
19752018
}
1976-
#if !SDL_VERSION_ATLEAST(3, 0, 0)
2019+
2020+
#if SDL_VERSION_ATLEAST(3, 0, 0)
2021+
/* In SDL2, display == 0 meant primary display, so compat code for it */
2022+
if (display_index == 0) {
2023+
display_index = SDL_GetPrimaryDisplay();
2024+
if (display_index == 0) {
2025+
return RAISE(pgExc_SDLError, SDL_GetError());
2026+
}
2027+
}
2028+
#else
19772029
/* Display ID is not bounded by number of displays in SDL3 */
19782030
if (display_index < 0 || display_index >= SDL_GetNumVideoDisplays()) {
19792031
return RAISE(PyExc_ValueError,
@@ -2039,7 +2091,15 @@ pg_list_modes(PyObject *self, PyObject *args, PyObject *kwds)
20392091
return NULL;
20402092
}
20412093

2042-
#if !SDL_VERSION_ATLEAST(3, 0, 0)
2094+
#if SDL_VERSION_ATLEAST(3, 0, 0)
2095+
/* In SDL2, display == 0 meant primary display, so compat code for it */
2096+
if (display_index == 0) {
2097+
display_index = SDL_GetPrimaryDisplay();
2098+
if (display_index == 0) {
2099+
return RAISE(pgExc_SDLError, SDL_GetError());
2100+
}
2101+
}
2102+
#else
20432103
/* Display ID is not bounded by number of displays in SDL3 */
20442104
if (display_index < 0 || display_index >= SDL_GetNumVideoDisplays()) {
20452105
return RAISE(PyExc_ValueError,
@@ -2700,6 +2760,9 @@ pg_iconify(PyObject *self, PyObject *_null)
27002760
return RAISE(pgExc_SDLError, "No open window");
27012761
}
27022762
SDL_MinimizeWindow(win);
2763+
#if SDL_VERSION_ATLEAST(3, 0, 0)
2764+
SDL_SyncWindow(win);
2765+
#endif
27032766
return PyBool_FromLong(1);
27042767
}
27052768

@@ -3035,7 +3098,6 @@ static PyObject *
30353098
pg_toggle_fullscreen(PyObject *self, PyObject *_null)
30363099
{
30373100
SDL_Window *win = pg_GetDefaultWindow();
3038-
int result;
30393101
SDL_WindowFlags flags;
30403102
int window_w, window_h, w, h, window_display, x, y;
30413103
pgSurfaceObject *display_surface;
@@ -3164,8 +3226,7 @@ pg_toggle_fullscreen(PyObject *self, PyObject *_null)
31643226
/* TOGGLE FULLSCREEN OFF */
31653227

31663228
if (state->unscaled_render) {
3167-
result = SDL_SetWindowFullscreen(win, 0);
3168-
if (result != 0) {
3229+
if (!PG_SetWindowFullscreen(win, 0, 0)) {
31693230
return RAISE(pgExc_SDLError, SDL_GetError());
31703231
}
31713232
}
@@ -3179,8 +3240,7 @@ pg_toggle_fullscreen(PyObject *self, PyObject *_null)
31793240
if (scale < 1) {
31803241
scale = 1;
31813242
}
3182-
result = SDL_SetWindowFullscreen(win, 0);
3183-
if (result != 0) {
3243+
if (!PG_SetWindowFullscreen(win, 0, 0)) {
31843244
return RAISE(pgExc_SDLError, SDL_GetError());
31853245
}
31863246
SDL_SetWindowSize(win, w * scale, h * scale);
@@ -3220,8 +3280,7 @@ pg_toggle_fullscreen(PyObject *self, PyObject *_null)
32203280
/* this is literally the only place where state->toggle_windowed_w
32213281
* should ever be read. We only use it because with GL, there is no
32223282
* display surface we can query for dimensions. */
3223-
result = SDL_SetWindowFullscreen(win, 0);
3224-
if (result != 0) {
3283+
if (!PG_SetWindowFullscreen(win, 0, 0)) {
32253284
return RAISE(pgExc_SDLError, SDL_GetError());
32263285
}
32273286
SDL_GL_MakeCurrent(win, state->gl_context);
@@ -3257,8 +3316,7 @@ pg_toggle_fullscreen(PyObject *self, PyObject *_null)
32573316
else if ((flags & SDL_WINDOW_FULLSCREEN_DESKTOP) ==
32583317
SDL_WINDOW_FULLSCREEN_DESKTOP) {
32593318
#endif
3260-
result = SDL_SetWindowFullscreen(win, 0);
3261-
if (result != 0) {
3319+
if (!PG_SetWindowFullscreen(win, 0, 0)) {
32623320
return RAISE(pgExc_SDLError, SDL_GetError());
32633321
}
32643322
display_surface->surf = SDL_GetWindowSurface(win);
@@ -3287,15 +3345,11 @@ pg_toggle_fullscreen(PyObject *self, PyObject *_null)
32873345
if (win == NULL) {
32883346
return RAISE(pgExc_SDLError, SDL_GetError());
32893347
}
3290-
else {
3291-
result = 0;
3292-
}
32933348
display_surface->surf = SDL_GetWindowSurface(win);
32943349
pg_SetDefaultWindow(win);
32953350
}
32963351
else {
3297-
result = SDL_SetWindowFullscreen(win, 0);
3298-
if (result != 0) {
3352+
if (!PG_SetWindowFullscreen(win, 0, 0)) {
32993353
return RAISE(pgExc_SDLError, SDL_GetError());
33003354
}
33013355
display_surface->surf = SDL_GetWindowSurface(win);
@@ -3330,24 +3384,12 @@ pg_toggle_fullscreen(PyObject *self, PyObject *_null)
33303384
state->fullscreen_backup_y = y;
33313385

33323386
if (state->unscaled_render) {
3333-
#if SDL_VERSION_ATLEAST(3, 0, 0)
3334-
result = PG_SetWindowFullscreen(win, 1, 0);
3335-
#else
3336-
result =
3337-
SDL_SetWindowFullscreen(win, SDL_WINDOW_FULLSCREEN_DESKTOP);
3338-
#endif
3339-
if (result != 0) {
3387+
if (!PG_SetWindowFullscreen(win, 1, 0)) {
33403388
return RAISE(pgExc_SDLError, SDL_GetError());
33413389
}
33423390
}
33433391
else if (pg_renderer != NULL) {
3344-
#if SDL_VERSION_ATLEAST(3, 0, 0)
3345-
result = PG_SetWindowFullscreen(win, 1, 0);
3346-
#else
3347-
result =
3348-
SDL_SetWindowFullscreen(win, SDL_WINDOW_FULLSCREEN_DESKTOP);
3349-
#endif
3350-
if (result != 0) {
3392+
if (!PG_SetWindowFullscreen(win, 1, 0)) {
33513393
return RAISE(pgExc_SDLError, SDL_GetError());
33523394
}
33533395
if (is_renderer_software && subsystem == SDL_SYSWM_X11) {
@@ -3380,13 +3422,7 @@ pg_toggle_fullscreen(PyObject *self, PyObject *_null)
33803422
#endif
33813423
}
33823424
else if (state->using_gl) {
3383-
#if SDL_VERSION_ATLEAST(3, 0, 0)
3384-
result = PG_SetWindowFullscreen(win, 1, 0);
3385-
#else
3386-
result =
3387-
SDL_SetWindowFullscreen(win, SDL_WINDOW_FULLSCREEN_DESKTOP);
3388-
#endif
3389-
if (result != 0) {
3425+
if (!PG_SetWindowFullscreen(win, 1, 0)) {
33903426
return RAISE(pgExc_SDLError, SDL_GetError());
33913427
}
33923428
SDL_GL_MakeCurrent(win, state->gl_context);
@@ -3411,13 +3447,7 @@ pg_toggle_fullscreen(PyObject *self, PyObject *_null)
34113447
}
34123448
}
34133449
else if (w == display_mode->w && h == display_mode->h) {
3414-
#if SDL_VERSION_ATLEAST(3, 0, 0)
3415-
result = PG_SetWindowFullscreen(win, 1, 0);
3416-
#else
3417-
result =
3418-
SDL_SetWindowFullscreen(win, SDL_WINDOW_FULLSCREEN_DESKTOP);
3419-
#endif
3420-
if (result != 0) {
3450+
if (!PG_SetWindowFullscreen(win, 1, 0)) {
34213451
return RAISE(pgExc_SDLError, SDL_GetError());
34223452
}
34233453
display_surface->surf = SDL_GetWindowSurface(win);
@@ -3434,8 +3464,7 @@ pg_toggle_fullscreen(PyObject *self, PyObject *_null)
34343464
return PyLong_FromLong(-1);
34353465
}
34363466
else {
3437-
result = SDL_SetWindowFullscreen(win, SDL_WINDOW_FULLSCREEN);
3438-
if (result != 0) {
3467+
if (!PG_SetWindowFullscreen(win, 1, 1)) {
34393468
return RAISE(pgExc_SDLError, SDL_GetError());
34403469
}
34413470
display_surface->surf = SDL_GetWindowSurface(win);
@@ -3447,7 +3476,7 @@ pg_toggle_fullscreen(PyObject *self, PyObject *_null)
34473476
if (win == NULL) {
34483477
return RAISE(pgExc_SDLError, SDL_GetError());
34493478
}
3450-
if (0 != SDL_SetWindowFullscreen(win, SDL_WINDOW_FULLSCREEN)) {
3479+
if (!PG_SetWindowFullscreen(win, 1, 1)) {
34513480
return RAISE(pgExc_SDLError, SDL_GetError());
34523481
}
34533482
display_surface->surf = SDL_GetWindowSurface(win);
@@ -3461,7 +3490,10 @@ pg_toggle_fullscreen(PyObject *self, PyObject *_null)
34613490
}
34623491
}
34633492
}
3464-
return PyLong_FromLong(result != 0);
3493+
#if SDL_VERSION_ATLEAST(3, 0, 0)
3494+
SDL_SyncWindow(win);
3495+
#endif
3496+
return PyLong_FromLong(1);
34653497
}
34663498

34673499
/* This API is provisional, and, not finalised, and should not be documented
@@ -3539,6 +3571,9 @@ pg_display_resize_event(PyObject *self, PyObject *event)
35393571
/* do not do anything that would invalidate a display surface! */
35403572
return PyLong_FromLong(-1);
35413573
}
3574+
#if SDL_VERSION_ATLEAST(3, 0, 0)
3575+
SDL_SyncWindow(win);
3576+
#endif
35423577
Py_RETURN_FALSE;
35433578
}
35443579

@@ -3771,7 +3806,11 @@ pg_message_box(PyObject *self, PyObject *arg, PyObject *kwargs)
37713806

37723807
int clicked_button_id;
37733808

3809+
#if SDL_VERSION_ATLEAST(3, 0, 0)
3810+
if (!SDL_ShowMessageBox(&msgbox_data, &clicked_button_id)) {
3811+
#else
37743812
if (SDL_ShowMessageBox(&msgbox_data, &clicked_button_id)) {
3813+
#endif
37753814
PyErr_SetString(pgExc_SDLError, SDL_GetError());
37763815
goto error;
37773816
}

0 commit comments

Comments
 (0)