@@ -99,6 +99,19 @@ _display_state_cleanup(_DisplayState *state)
9999#endif
100100}
101101
102+ /* This macro defines the pixel format we use for pg_renderer.
103+ * On our SDL2 code we used to use SDL_PIXELFORMAT_ARGB8888 but on SDL3 it
104+ * gives incorrect results because it includes alpha when we don't need it, so
105+ * we use the XRGB variant.
106+ * TODO: can consider using XRGB unconditionally on both SDL2 and SDL3
107+ * codepaths
108+ */
109+ #if SDL_VERSION_ATLEAST (3 , 0 , 0 )
110+ #define PG_TEXTURE_FMT SDL_PIXELFORMAT_XRGB8888
111+ #else
112+ #define PG_TEXTURE_FMT SDL_PIXELFORMAT_ARGB8888
113+ #endif
114+
102115// prevent this code block from being linked twice
103116// (this code block is copied by window.c)
104117#ifndef BUILD_STATIC
@@ -464,7 +477,12 @@ pg_GetVideoInfo(pg_VideoInfo *info)
464477 }
465478 else {
466479#if SDL_VERSION_ATLEAST (3 , 0 , 0 )
467- if ((mode_ptr = SDL_GetCurrentDisplayMode (0 ))) {
480+ SDL_DisplayID primary_display = SDL_GetPrimaryDisplay ();
481+ if (primary_display == 0 ) {
482+ PyErr_SetString (pgExc_SDLError , SDL_GetError ());
483+ return (pg_VideoInfo * )NULL ;
484+ }
485+ if ((mode_ptr = SDL_GetCurrentDisplayMode (primary_display ))) {
468486 info -> current_w = mode_ptr -> w ;
469487 info -> current_h = mode_ptr -> h ;
470488 formatenum = mode_ptr -> format ;
@@ -942,9 +960,8 @@ pg_ResizeEventWatch(void *userdata, SDL_Event *event)
942960
943961 SDL_DestroyTexture (pg_texture );
944962
945- pg_texture =
946- SDL_CreateTexture (pg_renderer , SDL_PIXELFORMAT_ARGB8888 ,
947- SDL_TEXTUREACCESS_STREAMING , w , h );
963+ pg_texture = SDL_CreateTexture (pg_renderer , PG_TEXTURE_FMT ,
964+ SDL_TEXTUREACCESS_STREAMING , w , h );
948965 }
949966 return 0 ;
950967 }
@@ -1166,6 +1183,7 @@ PG_SetWindowFullscreen(SDL_Window *window, bool fullscreen,
11661183 }
11671184 }
11681185
1186+ SDL_SyncWindow (window );
11691187 ret = true;
11701188end :
11711189 SDL_free (modes );
@@ -1261,6 +1279,16 @@ pg_set_mode(PyObject *self, PyObject *arg, PyObject *kwds)
12611279 }
12621280 }
12631281
1282+ #if SDL_VERSION_ATLEAST (3 , 0 , 0 )
1283+ /* In SDL2, display == 0 meant primary display, so compat code for it */
1284+ if (display == 0 ) {
1285+ display = SDL_GetPrimaryDisplay ();
1286+ if (display == 0 ) {
1287+ return RAISE (pgExc_SDLError , SDL_GetError ());
1288+ }
1289+ }
1290+ #endif
1291+
12641292 if ((vsync == -1 ) && ((flags & PGS_OPENGL ) == 0 )) {
12651293 return RAISE (PyExc_ValueError ,
12661294 "requested adaptive vsync without OpenGL" );
@@ -1751,9 +1779,9 @@ pg_set_mode(PyObject *self, PyObject *arg, PyObject *kwds)
17511779 }
17521780#endif
17531781
1754- pg_texture = SDL_CreateTexture (
1755- pg_renderer , SDL_PIXELFORMAT_ARGB8888 ,
1756- SDL_TEXTUREACCESS_STREAMING , w , h );
1782+ pg_texture =
1783+ SDL_CreateTexture ( pg_renderer , PG_TEXTURE_FMT ,
1784+ SDL_TEXTUREACCESS_STREAMING , w , h );
17571785 }
17581786 surf = PG_CreateSurface (w , h , SDL_PIXELFORMAT_XRGB8888 );
17591787 newownedsurf = surf ;
@@ -1875,6 +1903,9 @@ pg_set_mode(PyObject *self, PyObject *arg, PyObject *kwds)
18751903 }
18761904 }
18771905 }
1906+ #if SDL_VERSION_ATLEAST (3 , 0 , 0 )
1907+ SDL_SyncWindow (win );
1908+ #endif
18781909
18791910 /*return the window's surface (screen)*/
18801911 Py_INCREF (surface );
@@ -1973,6 +2004,9 @@ pg_set_window_position(PyObject *self, PyObject *arg)
19732004 if (win ) {
19742005 /* Will raise errors with SDL 3, deal with it during the porting */
19752006 SDL_SetWindowPosition (win , x , y );
2007+ #if SDL_VERSION_ATLEAST (3 , 0 , 0 )
2008+ SDL_SyncWindow (win );
2009+ #endif
19762010 }
19772011
19782012 Py_RETURN_NONE ;
@@ -1999,7 +2033,16 @@ pg_mode_ok(PyObject *self, PyObject *args, PyObject *kwds)
19992033 & display_index )) {
20002034 return NULL ;
20012035 }
2002- #if !SDL_VERSION_ATLEAST (3 , 0 , 0 )
2036+
2037+ #if SDL_VERSION_ATLEAST (3 , 0 , 0 )
2038+ /* In SDL2, display == 0 meant primary display, so compat code for it */
2039+ if (display_index == 0 ) {
2040+ display_index = SDL_GetPrimaryDisplay ();
2041+ if (display_index == 0 ) {
2042+ return RAISE (pgExc_SDLError , SDL_GetError ());
2043+ }
2044+ }
2045+ #else
20032046 /* Display ID is not bounded by number of displays in SDL3 */
20042047 if (display_index < 0 || display_index >= SDL_GetNumVideoDisplays ()) {
20052048 return RAISE (PyExc_ValueError ,
@@ -2026,6 +2069,15 @@ pg_mode_ok(PyObject *self, PyObject *args, PyObject *kwds)
20262069 }
20272070
20282071#if SDL_VERSION_ATLEAST (3 , 0 , 0 )
2072+ /* Compat with SDL2 behaviour */
2073+ const SDL_DisplayMode * curmode ;
2074+ if (!(curmode = SDL_GetCurrentDisplayMode (display_index ))) {
2075+ return RAISE (pgExc_SDLError , SDL_GetError ());
2076+ }
2077+ if (curmode -> w == desired .w && curmode -> h == desired .h ) {
2078+ return PyLong_FromLong (SDL_BITSPERPIXEL (curmode -> format ));
2079+ }
2080+
20292081 if (!SDL_GetClosestFullscreenDisplayMode (display_index , desired .w ,
20302082 desired .h , desired .refresh_rate ,
20312083 1 , & closest )) {
@@ -2065,7 +2117,15 @@ pg_list_modes(PyObject *self, PyObject *args, PyObject *kwds)
20652117 return NULL ;
20662118 }
20672119
2068- #if !SDL_VERSION_ATLEAST (3 , 0 , 0 )
2120+ #if SDL_VERSION_ATLEAST (3 , 0 , 0 )
2121+ /* In SDL2, display == 0 meant primary display, so compat code for it */
2122+ if (display_index == 0 ) {
2123+ display_index = SDL_GetPrimaryDisplay ();
2124+ if (display_index == 0 ) {
2125+ return RAISE (pgExc_SDLError , SDL_GetError ());
2126+ }
2127+ }
2128+ #else
20692129 /* Display ID is not bounded by number of displays in SDL3 */
20702130 if (display_index < 0 || display_index >= SDL_GetNumVideoDisplays ()) {
20712131 return RAISE (PyExc_ValueError ,
@@ -2077,19 +2137,31 @@ pg_list_modes(PyObject *self, PyObject *args, PyObject *kwds)
20772137#pragma PG_WARN(Ignoring flags)
20782138
20792139#if SDL_VERSION_ATLEAST (3 , 0 , 0 )
2140+ const SDL_DisplayMode * curmode ;
2141+ if (!(curmode = SDL_GetCurrentDisplayMode (display_index ))) {
2142+ return RAISE (pgExc_SDLError , SDL_GetError ());
2143+ }
20802144 if (bpp == 0 ) {
2081- const SDL_DisplayMode * curmode ;
2082- if (!(curmode = SDL_GetCurrentDisplayMode (display_index ))) {
2083- return RAISE (pgExc_SDLError , SDL_GetError ());
2084- }
20852145 bpp = SDL_BITSPERPIXEL (curmode -> format );
20862146 }
20872147
20882148 SDL_DisplayMode * * modes =
20892149 SDL_GetFullscreenDisplayModes (display_index , & nummodes );
2090- if (nummodes < 0 ) {
2150+ if (! modes || nummodes < 0 ) {
20912151 return RAISE (pgExc_SDLError , SDL_GetError ());
20922152 }
2153+
2154+ /* SDL3 can return empty list here but SDL2 didn't. In that case, use
2155+ * curmode. */
2156+ if (nummodes == 0 ) {
2157+ SDL_free (modes );
2158+ modes = SDL_malloc (sizeof (SDL_DisplayMode * * ));
2159+ if (!modes ) {
2160+ return PyErr_NoMemory ();
2161+ }
2162+ modes [0 ] = (SDL_DisplayMode * )curmode ;
2163+ nummodes = 1 ;
2164+ }
20932165#else
20942166 if (bpp == 0 ) {
20952167 SDL_DisplayMode curmode ;
@@ -2726,6 +2798,9 @@ pg_iconify(PyObject *self, PyObject *_null)
27262798 return RAISE (pgExc_SDLError , "No open window" );
27272799 }
27282800 SDL_MinimizeWindow (win );
2801+ #if SDL_VERSION_ATLEAST (3 , 0 , 0 )
2802+ SDL_SyncWindow (win );
2803+ #endif
27292804 return PyBool_FromLong (1 );
27302805}
27312806
@@ -3219,7 +3294,7 @@ pg_toggle_fullscreen(PyObject *self, PyObject *_null)
32193294 SDL_CreateRenderer (win , -1 , SDL_RENDERER_SOFTWARE );
32203295#endif
32213296 pg_texture =
3222- SDL_CreateTexture (pg_renderer , SDL_PIXELFORMAT_ARGB8888 ,
3297+ SDL_CreateTexture (pg_renderer , PG_TEXTURE_FMT ,
32233298 SDL_TEXTUREACCESS_STREAMING , w , h );
32243299 }
32253300#if SDL_VERSION_ATLEAST (3 , 0 , 0 )
@@ -3372,7 +3447,7 @@ pg_toggle_fullscreen(PyObject *self, PyObject *_null)
33723447 SDL_CreateRenderer (win , -1 , SDL_RENDERER_SOFTWARE );
33733448#endif
33743449 pg_texture =
3375- SDL_CreateTexture (pg_renderer , SDL_PIXELFORMAT_ARGB8888 ,
3450+ SDL_CreateTexture (pg_renderer , PG_TEXTURE_FMT ,
33763451 SDL_TEXTUREACCESS_STREAMING , w , h );
33773452 }
33783453
@@ -3453,6 +3528,9 @@ pg_toggle_fullscreen(PyObject *self, PyObject *_null)
34533528 }
34543529 }
34553530 }
3531+ #if SDL_VERSION_ATLEAST (3 , 0 , 0 )
3532+ SDL_SyncWindow (win );
3533+ #endif
34563534 return PyLong_FromLong (1 );
34573535}
34583536
@@ -3531,6 +3609,9 @@ pg_display_resize_event(PyObject *self, PyObject *event)
35313609 /* do not do anything that would invalidate a display surface! */
35323610 return PyLong_FromLong (-1 );
35333611 }
3612+ #if SDL_VERSION_ATLEAST (3 , 0 , 0 )
3613+ SDL_SyncWindow (win );
3614+ #endif
35343615 Py_RETURN_FALSE ;
35353616}
35363617
0 commit comments