Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions include/SDL3/SDL_main.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,12 +167,10 @@
*/
#define SDL_MAIN_NEEDED

#elif defined(SDL_PLATFORM_IOS)
/* On iOS SDL provides a main function that creates an application delegate
and starts the iOS application run loop.
#elif defined(SDL_PLATFORM_IOS) || defined(SDL_PLATFORM_TVOS)
/* On iOS and tvOS SDL provides a main function that creates an application delegate and starts the application run loop.
To use it, just #include SDL_main.h in the source file that contains your
main() function.
To use it, just #include <SDL3/SDL_main.h> in the source file that contains your main() function.
See src/video/uikit/SDL_uikitappdelegate.m for more details.
*/
Expand Down Expand Up @@ -230,6 +228,15 @@
*/
#define SDL_MAIN_AVAILABLE

#else
/*
This platform SDL provides a main function that sets up the main
thread and calls your main function.
If you provide this yourself, you may define SDL_MAIN_HANDLED
*/
#define SDL_MAIN_AVAILABLE

#endif
#endif /* SDL_MAIN_HANDLED */

Expand Down
36 changes: 28 additions & 8 deletions src/SDL.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ static bool SDL_MainIsReady = false;
static bool SDL_MainIsReady = true;
#endif
static SDL_ThreadID SDL_MainThreadID = 0;
static SDL_ThreadID SDL_EventsThreadID = 0;
static SDL_ThreadID SDL_VideoThreadID = 0;
static bool SDL_bInMainQuit = false;
static Uint8 SDL_SubsystemRefCount[32];

Expand Down Expand Up @@ -266,21 +268,28 @@ void SDL_SetMainReady(void)

bool SDL_IsMainThread(void)
{
if (SDL_MainThreadID == 0) {
// Not initialized yet?
return true;
if (SDL_VideoThreadID) {
return (SDL_GetCurrentThreadID() == SDL_VideoThreadID);
}
if (SDL_MainThreadID == SDL_GetCurrentThreadID()) {
return true;
if (SDL_EventsThreadID) {
return (SDL_GetCurrentThreadID() == SDL_EventsThreadID);
}
return false;
if (SDL_MainThreadID) {
return (SDL_GetCurrentThreadID() == SDL_MainThreadID);
}
return true;
}

// Initialize all the subsystems that require initialization before threads start
void SDL_InitMainThread(void)
{
static bool done_info = false;

// If we haven't done it by now, mark this as the main thread
if (SDL_MainThreadID == 0) {
SDL_MainThreadID = SDL_GetCurrentThreadID();
}

SDL_InitTLSData();
SDL_InitEnvironment();
SDL_InitTicks();
Expand Down Expand Up @@ -335,6 +344,11 @@ bool SDL_InitSubSystem(SDL_InitFlags flags)
if (flags & SDL_INIT_EVENTS) {
if (SDL_ShouldInitSubsystem(SDL_INIT_EVENTS)) {
SDL_IncrementSubsystemRefCount(SDL_INIT_EVENTS);

// Note which thread initialized events
// This is the thread which should be pumping events
SDL_EventsThreadID = SDL_GetCurrentThreadID();

if (!SDL_InitEvents()) {
SDL_DecrementSubsystemRefCount(SDL_INIT_EVENTS);
goto quit_and_error;
Expand All @@ -354,12 +368,16 @@ bool SDL_InitSubSystem(SDL_InitFlags flags)
goto quit_and_error;
}

SDL_IncrementSubsystemRefCount(SDL_INIT_VIDEO);

// We initialize video on the main thread
// On Apple platforms this is a requirement.
// On other platforms, this is the definition.
SDL_MainThreadID = SDL_GetCurrentThreadID();
SDL_VideoThreadID = SDL_GetCurrentThreadID();
#ifdef SDL_PLATFORM_APPLE
SDL_assert(SDL_VideoThreadID == SDL_MainThreadID);
#endif

SDL_IncrementSubsystemRefCount(SDL_INIT_VIDEO);
if (!SDL_VideoInit(NULL)) {
SDL_DecrementSubsystemRefCount(SDL_INIT_VIDEO);
SDL_PushError();
Expand Down Expand Up @@ -609,6 +627,7 @@ void SDL_QuitSubSystem(SDL_InitFlags flags)
if (SDL_ShouldQuitSubsystem(SDL_INIT_VIDEO)) {
SDL_QuitRender();
SDL_VideoQuit();
SDL_VideoThreadID = 0;
// video implies events
SDL_QuitSubSystem(SDL_INIT_EVENTS);
}
Expand All @@ -619,6 +638,7 @@ void SDL_QuitSubSystem(SDL_InitFlags flags)
if (flags & SDL_INIT_EVENTS) {
if (SDL_ShouldQuitSubsystem(SDL_INIT_EVENTS)) {
SDL_QuitEvents();
SDL_EventsThreadID = 0;
}
SDL_DecrementSubsystemRefCount(SDL_INIT_EVENTS);
}
Expand Down
1 change: 1 addition & 0 deletions src/SDL_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ extern "C" {
#include "SDL_utils_c.h"
#include "SDL_hashtable.h"


/* SDL_ExitProcess is not declared in any public header, although
it is shared between some parts of SDL, because we don't want
anything calling it without an extremely good reason. */
Expand Down
3 changes: 3 additions & 0 deletions src/events/SDL_events.c
Original file line number Diff line number Diff line change
Expand Up @@ -1494,6 +1494,9 @@ void SDL_PumpEventMaintenance(void)
// Run the system dependent event loops
static void SDL_PumpEventsInternal(bool push_sentinel)
{
// This should only be called on the main thread, check in debug builds
SDL_assert(SDL_IsMainThread());

// Free any temporary memory from old events
SDL_FreeTemporaryMemory();

Expand Down
12 changes: 9 additions & 3 deletions src/main/SDL_main_callbacks.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,13 +147,19 @@ void SDL_QuitMainCallbacks(SDL_AppResult result)
SDL_Quit();
}

void SDL_CheckDefaultArgcArgv(int *argc, char ***argv)
static void SDL_CheckDefaultArgcArgv(int *argc, char ***argv)
{
if (!argv)
{
if (!*argv) {
static char dummyargv0[] = { 'S', 'D', 'L', '_', 'a', 'p', 'p', '\0' };
static char *argvdummy[2] = { dummyargv0, NULL };
*argc = 1;
*argv = argvdummy;
}
}

int SDL_CallMainFunction(int argc, char *argv[], SDL_main_func mainFunction)
{
SDL_CheckDefaultArgcArgv(&argc, &argv);
SDL_SetMainReady();
return mainFunction(argc, argv);
}
7 changes: 2 additions & 5 deletions src/main/SDL_main_callbacks.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,7 @@ SDL_AppResult SDL_InitMainCallbacks(int argc, char *argv[], SDL_AppInit_func app
SDL_AppResult SDL_IterateMainCallbacks(bool pump_events);
void SDL_QuitMainCallbacks(SDL_AppResult result);

// (not a callback thing, but convenient to stick this in here.)
// If *_argv is NULL, update *_argc and *_argv to point at a static array of { "SDL_app", NULL }.
void SDL_CheckDefaultArgcArgv(int *_argc, char ***_argv);
// Check args and call the main function
extern int SDL_CallMainFunction(int argc, char *argv[], SDL_main_func mainFunction);

#endif // SDL_main_callbacks_h_


15 changes: 10 additions & 5 deletions src/main/SDL_runapp.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,20 @@
#include "SDL_internal.h"
#include "SDL_main_callbacks.h"

/* Most platforms that use/need SDL_main have their own SDL_RunApp() implementation.
* If not, you can special case it here by appending || defined(__YOUR_PLATFORM__) */
#if ( !defined(SDL_MAIN_NEEDED) && !defined(SDL_MAIN_AVAILABLE) ) || defined(SDL_PLATFORM_ANDROID)
// Add your platform here if you define a custom SDL_RunApp() implementation
#if !defined(SDL_PLATFORM_WIN32) && \
!defined(SDL_PLATFORM_GDK) && \
!defined(SDL_PLATFORM_IOS) && \
!defined(SDL_PLATFORM_TVOS) && \
!defined(SDL_PLATFORM_EMSCRIPTEN) && \
!defined(SDL_PLATFORM_PSP) && \
!defined(SDL_PLATFORM_PS2) && \
!defined(SDL_PLATFORM_3DS)

int SDL_RunApp(int argc, char *argv[], SDL_main_func mainFunction, void * reserved)
{
(void)reserved;
SDL_CheckDefaultArgcArgv(&argc, &argv);
return mainFunction(argc, argv);
return SDL_CallMainFunction(argc, argv, mainFunction);
}

#endif
4 changes: 1 addition & 3 deletions src/main/emscripten/SDL_sysmain_runapp.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@ int SDL_RunApp(int argc, char *argv[], SDL_main_func mainFunction, void * reserv
{
(void)reserved;

SDL_CheckDefaultArgcArgv(&argc, &argv);

// Move any URL params that start with "SDL_" over to environment
// variables, so the hint system can pick them up, etc, much like a user
// can set them from a shell prompt on a desktop machine. Ignore all
Expand All @@ -59,7 +57,7 @@ int SDL_RunApp(int argc, char *argv[], SDL_main_func mainFunction, void * reserv
}
}, SDL_setenv_unsafe);

return mainFunction(argc, argv);
return SDL_CallMainFunction(argc, argv, mainFunction);
}

#endif
5 changes: 2 additions & 3 deletions src/main/gdk/SDL_sysmain_runapp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ extern "C" {
#include "../../core/gdk/SDL_gdk.h"
#include "../../core/windows/SDL_windows.h"
#include "../../events/SDL_events_c.h"
#include "../SDL_main_callbacks.h"
}
#include <XGameRuntime.h>
#include <xsapi-c/services_c.h>
Expand Down Expand Up @@ -65,14 +66,12 @@ int SDL_RunApp(int argc, char **argv, SDL_main_func mainFunction, void *reserved
SDL_SetError("[GDK] Unable to get titleid. Will not call XblInitialize. Check MicrosoftGame.config!");
}

SDL_SetMainReady();

if (!GDK_RegisterChangeNotifications()) {
return -1;
}

// Run the application main() code
result = mainFunction(argc, argv);
result = SDL_CallMainFunction(argc, argv, mainFunction);

GDK_UnregisterChangeNotifications();

Expand Down
5 changes: 1 addition & 4 deletions src/main/n3ds/SDL_sysmain_runapp.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,11 @@ int SDL_RunApp(int argc, char *argv[], SDL_main_func mainFunction, void * reserv
{
int result;

SDL_CheckDefaultArgcArgv(&argc, &argv);

// init
osSetSpeedupEnable(true);
romfsInit();

SDL_SetMainReady();
result = mainFunction(argc, argv);
result = SDL_CallMainFunction(argc, argv, mainFunction);

// quit
romfsExit();
Expand Down
10 changes: 3 additions & 7 deletions src/main/ps2/SDL_sysmain_runapp.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,21 +68,17 @@ static void deinit_drivers(void)

int SDL_RunApp(int argc, char *argv[], SDL_main_func mainFunction, void * reserved)
{
int res;
int result;
(void)reserved;

SDL_CheckDefaultArgcArgv(&argc, &argv);

prepare_IOP();
init_drivers();

SDL_SetMainReady();

res = mainFunction(argc, argv);
result = SDL_CallMainFunction(argc, argv, mainFunction);

deinit_drivers();

return res;
return result;
}

#endif // SDL_PLATFORM_PS2
6 changes: 1 addition & 5 deletions src/main/psp/SDL_sysmain_runapp.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,9 @@ int SDL_RunApp(int argc, char *argv[], SDL_main_func mainFunction, void * reserv
{
(void)reserved;

SDL_CheckDefaultArgcArgv(&argc, &argv);

sdl_psp_setup_callbacks();

SDL_SetMainReady();

return mainFunction(argc, argv);
return SDL_CallMainFunction(argc, argv, mainFunction);
}

#endif // SDL_PLATFORM_PSP
4 changes: 2 additions & 2 deletions src/main/windows/SDL_sysmain_runapp.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#ifdef SDL_PLATFORM_WIN32

#include "../../core/windows/SDL_windows.h"
#include "../SDL_main_callbacks.h"

/* Win32-specific SDL_RunApp(), which does most of the SDL_main work,
based on SDL_windows_main.c, placed in the public domain by Sam Lantinga 4/13/98 */
Expand All @@ -37,8 +38,7 @@ int MINGW32_FORCEALIGN SDL_RunApp(int argc, char *argv[], SDL_main_func mainFunc
if (args_error) {
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal Error", args_error, NULL);
} else {
SDL_SetMainReady();
result = mainFunction(argc, argv);
result = SDL_CallMainFunction(argc, argv, mainFunction);
if (heap_allocated) {
HeapFree(GetProcessHeap(), 0, heap_allocated);
}
Expand Down
6 changes: 2 additions & 4 deletions src/video/uikit/SDL_uikitappdelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@

int SDL_RunApp(int argc, char *argv[], SDL_main_func mainFunction, void *reserved)
{
SDL_CheckDefaultArgcArgv(&argc, &argv);

// store arguments
forward_main = mainFunction;
forward_argc = argc;
Expand Down Expand Up @@ -483,7 +481,7 @@ - (void)postFinishLaunch
[self performSelector:@selector(hideLaunchScreen) withObject:nil afterDelay:0.0];

SDL_SetiOSEventPump(true);
exit_status = forward_main(forward_argc, forward_argv);
exit_status = SDL_CallMainFunction(forward_argc, forward_argv, forward_main);
SDL_SetiOSEventPump(false);

if (launchWindow) {
Expand Down Expand Up @@ -553,7 +551,7 @@ - (void)postFinishLaunch

// run the user's application, passing argc and argv
SDL_SetiOSEventPump(true);
exit_status = forward_main(forward_argc, forward_argv);
exit_status = SDL_CallMainFunction(forward_argc, forward_argv, forward_main);
SDL_SetiOSEventPump(false);

if (launchWindow) {
Expand Down
Loading
Loading