especially SDL_VIDEODRIVER is commonly used to use the native Wayland
backend, so I think it's a good idea to keep supporting the old name
instead of forcing users to find out that they now have to add an
underscore..
Not sure how popular SDL_AUDIODRIVER is, but with all the audio backends
that exist on Linux alone I'm sure some people use it to work around
sound issues.
Note: Doing this in the SDL_hints implementation instead of the
call-sites of SDL_GetHint(SDL_HINT_VIDEO_DRIVER) etc ensures that
1. Hint priorities work (env var overriding hint set by application with normal
priority, but not when application used SDL_HINT_OVERRIDE)
2. SDL_ResetHint() (called by user code) respects the fallback
environment variable
My simplification of the conditions for including SDL_main_impl.h
had one problem: I forgot that SDL_main_impl.h must be included
even on Android when SDL_MAIN_USE_CALLBACKS is used, because then a
SDL_main() function that makes sure the callbacks get called is needed,
and that function is implemented in SDL_main_impl.h
But OTOH, even when SDL_MAIN_USE_CALLBACKS is used, SDL_main_impl.h
should not implement a standard `int main(...)` function on Android
(because there the SDL-using native code is compiled as a library and
the entry point is in SDLActivity.java, which calls SDL_main()
in said library).
So the check for platforms that don't have *any* native main function
but just SDL_main() called from the outside should be handled in
SDL_main_impl.h, so both the normal and the callback case can avoid
generating a standard main() in the same way.
To do this, SDL_MAIN_EXPORTED is defined for platforms like Android,
where the real entry point (main() function) is outside of the code
that uses SDL, so
- SDL_main() must be visibly exported with SDL_DECLSPEC, so the outside
code can call it
- SDL_main_impl.h must not implement a "real" main() function
Another small change based on this is defining SDLMAIN_DECLSPEC
at a more general place.
If another platform like Android (where the entry point is somewhere
else entirely, possibly implemented in a different programming language)
turns up, defining SDL_MAIN_NEEDED (so the users main() is renamed
to SDL_main()) and SDL_MAIN_EXPORTED should be all that's needed on the
SDL_main.h side - and if not then at least the implementation is
cleaner and clearer now, IMHO.
fixes#11162
If WinRT returns after all, or a similarly bad platforms turns up,
the code can still be found in the git history.
But keep in mind that it then will have to be added *before* the
#if ( defined(SDL_MAIN_USE_CALLBACKS) || defined(SDL_MAIN_NEEDED) ...
case for platforms that support plain C to work correctly
Basically all platforms where SDL_main.h renames main() to SDL_main()
use the platform-specific main() (or WinMain() or whatever)
implementations in SDL_main_impl.h - and that renaming is enabled with:
#if defined(SDL_MAIN_NEEDED) || defined(SDL_MAIN_AVAILABLE) \
|| defined(SDL_MAIN_USE_CALLBACKS)
#define main SDL_main
#endif
The only exception is Android, where main() *is* renamed, but
SDL_main_impl.h isn't used, because SDL_main() is called from Java.
So I think it's cleaner and less error-prone (for adding additional
platforms that need SDL_main() in the future), to use the same check
for including SDL_main_impl.h as is used for `#define main SDL_main`
and only list the exceptions (currently Android) there explicitly.
If new platforms like Android turn up, they can easily be added there
by inserting "|| defined(SDL_PLATFORM_WEIRDPLATFORM)" right next
to the Android check.
See also https://github.com/libsdl-org/SDL/issues/11068#issuecomment-2399907535
I don't think there's any point in console_*main() for non-MSVC - I think
it can't be called anyway now that SDL_main is header-only.
So I renamed those functions to main() and wmain() and made them MSVC-only
For reference, MinGW (at least the version I tested) supports both main()
and WinMain(), no matter if compiled with -mconsole or -mwindows (it seems
to prefer main() over WinMain() if both are available, in both cases).
But when building with -municode, it needs wmain() or wWinMain(), so
that case is now handled with wWinMain()
makes the SDL_main code shorter
Also added a generic SDL_RunApp() implementation for platforms that
don't really need it.
Some platforms (that use SDL_main but haven't been ported yet) are
still missing, but are added in the following commits.
and move the #undef main and #define main SDL_main to the start/end of
SDL_main_impl.h instead of repeating it in every platform implementation
Thanks to SDL_N3DSRunApp we don't need the #include <3ds.h> in
SDL_main_impl.h - that caused conflicts with testthread.c, because both
have (different) ThreadFunc typedefs.
and update README-visualc.md and README-gdk.md accordingly
Also moved src/main/windows/version.rc to src/core/windows/
and adjusted VS solutions, CMakeLists.txt and versioning scripts
in build-scripts/ accordingly.
This will eventually allow us to remove all of src/main/
# Conflicts:
# VisualC/tests/testgesture/testgesture.vcxproj
As the implementation requires C++, the user will have to include
SDL_main.h in a C++ source file (that needs to be compiled with /ZW).
It's ok to keep the standard main() implementation in plain C and use
an otherwise empty C++ source file for the SDL_main implementation part,
if both source files #include <SDL3/SDL_main.h>
Including SDL_main.h in a C source file will print a message at
compilation (when building for WinRT or possibly other not yet implemented
platforms that require C++ for main), to remind the user of also
including it in a .cpp source file. This message/warning can be disabled
with #define SDL_MAIN_NOIMPL before including SDL_main.h in the C file.
When including it in a .cpp file, there will be a compiler error with
helpful message if it's not compiled with /ZW
For this I renamend _SDL_MAIN_NOIMPL to SDL_MAIN_NOIMPL, because now it's
not for internal use only anymore, but also useful for users (that want
their main() function in a different file than the SDL_main implementation)
Add a project for the testdraw2.c test to the WinRT solution to at least
get some minimal testing on WinRT.
I won't add all tests because it's a lot of manual clicking per test,
but this should be better than nothing :)
Also adjusted iOS demo's includes to <SDL3/..> and explicit SDL_main.h
untested, I don't have Xcode (or a Mac, for that matter)
The xcode projects (for both Xcode-iOS/ and Xcode/) will probably
have to be adjusted for the SDL_main changes to work, but now at least
the iOS demo source should work as is :)
this should hopefully make the automated builds work again
(this commit can probably be removed once all affected platforms are
converted to header-only SDL_main)
(remaining platforms will follow)
SDL_main.h is *not* included by SDL.h anymore, users are supposed to
include it directly now, usually only in the file they implement main() in.
If they need the header elsewhere or don't want SDL_main to implement
main() (but only call SDL_SetMainReady() or whatever), they
can #define SDL_MAIN_HANDLED first, same as before.
For SDL-internal usage, I added _SDL_MAIN_NOIMPL, which *also* skips the
implementation and `#define main SDL_main`, but still defines
SDL_MAIN_AVAILABLE and SDL_MAIN_NEEDED in SDL_main.h, as before.
To make the implementaion in the header shorter and avoid including windows.h,
I moved most of the Win32 SDL_main code into SDL3.dll via SDL_Win32RunApp(),
so the header-only part is just the different main functions calling
SDL_Win32RunApp(SDL_main, NULL)
Note that I changed changed the return value and type of OutOfMemory()
to return -1 instead of FALSE, so main() (or WinMain() or whatever)
returns -1 instead of 0 in case of an out-of-memory error
Compared to original Win32 SDL_main, I tweaked the part of the
implementation in SDL_main_impl.h a bit to avoid linker warnings
and conflicts with stuff from windows.h:
- replaced windows.h with own define of WINAPI
and typedef-ing HINSTANCE and LPSTR.
This prevents conflicts between all the generically-named #defines and
types in windows.h and user code (like DrawState in some SDL tests)
- only using one of main() or wmain() gets rid of a MSVC linker error
("warning LNK4067: ambiguous entry point")
If this still causes problems, we might try getting rid of wmain(),
seemed to me like MSVC can use regular main() in UNICODE mode as well
- simplified the UNICODE logic for that - while this is not exactly
equivalent to the old, it should make sense and Works For Me
"get_filename_component(SDL2_LIBDIR ${sdl2implib} PATH)" failed if
sdl2implib was set from sdl2implibdbg instead of ${sdl2implibdbg}
Thanks to seyuup from the SDL Discourse for pointing this out.
Otherwise only the display resolution is changed, but the SDL window size
(and for example the window-surface size) aren't adjusted accordingly
and thus don't fill the whole screen.
See #3313
.. and maybe other platforms as well (though X11 was not affected)?
The issue was that passing a higher resolution than the current desktop
resolution to SDL_CreateWindow() with SDL_WINDOW_FULLSCREEN didn't switch
to that resolution (even though it did switch to lower resolutions).
When creating a fullscreen window, window->fullscreen wasn't even set
at all (only zeroed out), setting it only happened if the user explicitly
called SDL_SetWindowDisplayMode(). So without that, SDL_CreateWindow()
-> SDL_UpdateFullscreenMode() -> SDL_GetWindowDisplayMode() used the
resolution from window->windowed.w/h which were limited to the desktop size
due to some weird combination of WIN_AdjustWindowRectWithStyle() and
WIN_WindowProc() being called after a call to SetWindowPos().
fixes#3313
When building SDL2 from git with CMake, you got libSDL2-2.0.so.1
instead of .0 (as it's the case when building with autotools).
This was caused by using LT_REVISION instead of LT_MAJOR for SOVERSION.
fixes#4310
The GCC-style SDL2_LIBRARIES were lacking the rpath on Linux, which
seems to be implicitly set when linking path/to/libSDL2-2.0.so.0.*
and is explicitly set in the SDL2_LIBRARIES in sdl2-config.cmake
(from some autotools variable), so I removed that hack and the format
remains sth like "path/to/libSDL2main.a;path/to/libSDL2-2.0.so.0.14.1".
It's still in the revision history in case it turns out that some
platform really needs the "-L/path/to/bla/lib -lSDL2main -lSDL2" format
It didn't work at all because shared libs defined in CMake with
add_library() need something like IMPORTED_IMPLIB (pointing to a .dll.a
or .lib for th DLLs) set to link on Windows.
But even with that it didn't work because the order of the libs is very
important: it must be -lmingw32 -lSDL2main -lSDL -mwindows - but
with normal add_library(SDL2::SDL2 SHARED IMPORTED) libs, SDL2 itself
is always linked first.
So I use an "INTERFACE" library (usually used for header-only libs), which
doesn't implicitly/automatically link anything so I can specify the whole
order of the linked libs.
(SDL2::SDL2-static is completely untested)
this makes it easier to create a portable sdl2-config.cmake that doesn't
hardcode its path (by replacing the hardcoded prefix with something
like "${CMAKE_CURRENT_LIST_DIR}/../../..")