Browse Source

Changed main callback return values to an enumeration

Fixes https://github.com/libsdl-org/SDL/issues/10515
Sam Lantinga 8 months ago
parent
commit
438a214420

+ 3 - 3
examples/audio/01-simple-playback/simple-playback.c

@@ -17,7 +17,7 @@ static SDL_AudioStream *stream = NULL;
 static int total_samples_generated = 0;
 
 /* This function runs once at startup. */
-int SDL_AppInit(void **appstate, int argc, char *argv[])
+SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
 {
     SDL_AudioSpec spec;
 
@@ -51,7 +51,7 @@ int SDL_AppInit(void **appstate, int argc, char *argv[])
 }
 
 /* This function runs when a new event (mouse input, keypresses, etc) occurs. */
-int SDL_AppEvent(void *appstate, const SDL_Event *event)
+SDL_AppResult SDL_AppEvent(void *appstate, const SDL_Event *event)
 {
     if (event->type == SDL_EVENT_QUIT) {
         return SDL_APP_SUCCESS;  /* end the program, reporting success to the OS. */
@@ -60,7 +60,7 @@ int SDL_AppEvent(void *appstate, const SDL_Event *event)
 }
 
 /* This function runs once per frame, and is the heart of the program. */
-int SDL_AppIterate(void *appstate)
+SDL_AppResult SDL_AppIterate(void *appstate)
 {
     /* see if we need to feed the audio stream more data yet.
        We're being lazy here, but if there's less than half a second queued, generate more.

+ 3 - 3
examples/audio/02-simple-playback-callback/simple-playback-callback.c

@@ -49,7 +49,7 @@ static void SDLCALL FeedTheAudioStreamMore(void *userdata, SDL_AudioStream *astr
 }
 
 /* This function runs once at startup. */
-int SDL_AppInit(void **appstate, int argc, char *argv[])
+SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
 {
     SDL_AudioSpec spec;
 
@@ -83,7 +83,7 @@ int SDL_AppInit(void **appstate, int argc, char *argv[])
 }
 
 /* This function runs when a new event (mouse input, keypresses, etc) occurs. */
-int SDL_AppEvent(void *appstate, const SDL_Event *event)
+SDL_AppResult SDL_AppEvent(void *appstate, const SDL_Event *event)
 {
     if (event->type == SDL_EVENT_QUIT) {
         return SDL_APP_SUCCESS;  /* end the program, reporting success to the OS. */
@@ -92,7 +92,7 @@ int SDL_AppEvent(void *appstate, const SDL_Event *event)
 }
 
 /* This function runs once per frame, and is the heart of the program. */
-int SDL_AppIterate(void *appstate)
+SDL_AppResult SDL_AppIterate(void *appstate)
 {
     /* we're not doing anything with the renderer, so just blank it out. */
     SDL_RenderClear(renderer);

+ 3 - 3
examples/audio/03-load-wav/load-wav.c

@@ -26,7 +26,7 @@ static Uint8 *wav_data = NULL;
 static Uint32 wav_data_len = 0;
 
 /* This function runs once at startup. */
-int SDL_AppInit(void **appstate, int argc, char *argv[])
+SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
 {
     SDL_AudioSpec spec;
     char *wav_path = NULL;
@@ -65,7 +65,7 @@ int SDL_AppInit(void **appstate, int argc, char *argv[])
 }
 
 /* This function runs when a new event (mouse input, keypresses, etc) occurs. */
-int SDL_AppEvent(void *appstate, const SDL_Event *event)
+SDL_AppResult SDL_AppEvent(void *appstate, const SDL_Event *event)
 {
     if (event->type == SDL_EVENT_QUIT) {
         return SDL_APP_SUCCESS;  /* end the program, reporting success to the OS. */
@@ -74,7 +74,7 @@ int SDL_AppEvent(void *appstate, const SDL_Event *event)
 }
 
 /* This function runs once per frame, and is the heart of the program. */
-int SDL_AppIterate(void *appstate)
+SDL_AppResult SDL_AppIterate(void *appstate)
 {
     /* see if we need to feed the audio stream more data yet.
        We're being lazy here, but if there's less than the entire wav file left to play,

+ 3 - 3
examples/game/01-snake/main.c

@@ -76,7 +76,7 @@ static void set_rect_xy_(SDL_FRect *r, short x, short y)
     r->y = (float)(y * SNAKE_BLOCK_SIZE_IN_PIXELS);
 }
 
-int SDL_AppIterate(void *appstate)
+SDL_AppResult SDL_AppIterate(void *appstate)
 {
     AppState *as;
     SnakeContext *ctx;
@@ -109,7 +109,7 @@ int SDL_AppIterate(void *appstate)
     return SDL_APP_CONTINUE;
 }
 
-int SDL_AppInit(void **appstate, int argc, char *argv[])
+SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
 {
     (void)argc;
     (void)argv;
@@ -134,7 +134,7 @@ int SDL_AppInit(void **appstate, int argc, char *argv[])
     return SDL_APP_CONTINUE;
 }
 
-int SDL_AppEvent(void *appstate, const SDL_Event *event)
+SDL_AppResult SDL_AppEvent(void *appstate, const SDL_Event *event)
 {
     SnakeContext *ctx = &((AppState *)appstate)->snake_ctx;
     switch (event->type) {

+ 3 - 3
examples/pen/01-drawing-lines/drawing-lines.c

@@ -21,7 +21,7 @@ static float previous_touch_x = -1.0f;
 static float previous_touch_y = -1.0f;
 
 /* This function runs once at startup. */
-int SDL_AppInit(void **appstate, int argc, char *argv[])
+SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
 {
     if (SDL_Init(SDL_INIT_VIDEO) == -1) {
         SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't initialize SDL!", SDL_GetError(), NULL);
@@ -52,7 +52,7 @@ int SDL_AppInit(void **appstate, int argc, char *argv[])
 }
 
 /* This function runs when a new event (mouse input, keypresses, etc) occurs. */
-int SDL_AppEvent(void *appstate, const SDL_Event *event)
+SDL_AppResult SDL_AppEvent(void *appstate, const SDL_Event *event)
 {
     if (event->type == SDL_EVENT_QUIT) {
         return SDL_APP_SUCCESS;  /* end the program, reporting success to the OS. */
@@ -84,7 +84,7 @@ int SDL_AppEvent(void *appstate, const SDL_Event *event)
 }
 
 /* This function runs once per frame, and is the heart of the program. */
-int SDL_AppIterate(void *appstate)
+SDL_AppResult SDL_AppIterate(void *appstate)
 {
     /* make sure we're drawing to the window and not the render target */
     SDL_SetRenderTarget(renderer, NULL);

+ 3 - 3
examples/renderer/01-clear/renderer-clear.c

@@ -23,7 +23,7 @@ static int fade_direction = 1;
 
 
 /* This function runs once at startup. */
-int SDL_AppInit(void **appstate, int argc, char *argv[])
+SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
 {
     if (SDL_Init(SDL_INIT_VIDEO) == -1) {
         SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't initialize SDL!", SDL_GetError(), NULL);
@@ -39,7 +39,7 @@ int SDL_AppInit(void **appstate, int argc, char *argv[])
 }
 
 /* This function runs when a new event (mouse input, keypresses, etc) occurs. */
-int SDL_AppEvent(void *appstate, const SDL_Event *event)
+SDL_AppResult SDL_AppEvent(void *appstate, const SDL_Event *event)
 {
     if (event->type == SDL_EVENT_QUIT) {
         return SDL_APP_SUCCESS;  /* end the program, reporting success to the OS. */
@@ -48,7 +48,7 @@ int SDL_AppEvent(void *appstate, const SDL_Event *event)
 }
 
 /* This function runs once per frame, and is the heart of the program. */
-int SDL_AppIterate(void *appstate)
+SDL_AppResult SDL_AppIterate(void *appstate)
 {
     /* since we're always fading red, we leave green and blue at zero.
        alpha doesn't mean much here, so leave it at full (255, no transparency). */

+ 3 - 3
examples/renderer/02-primitives/renderer-primitives.c

@@ -15,7 +15,7 @@ static SDL_Renderer *renderer = NULL;
 static SDL_FPoint points[500];
 
 /* This function runs once at startup. */
-int SDL_AppInit(void **appstate, int argc, char *argv[])
+SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
 {
     int i;
 
@@ -39,7 +39,7 @@ int SDL_AppInit(void **appstate, int argc, char *argv[])
 }
 
 /* This function runs when a new event (mouse input, keypresses, etc) occurs. */
-int SDL_AppEvent(void *appstate, const SDL_Event *event)
+SDL_AppResult SDL_AppEvent(void *appstate, const SDL_Event *event)
 {
     if (event->type == SDL_EVENT_QUIT) {
         return SDL_APP_SUCCESS;  /* end the program, reporting success to the OS. */
@@ -48,7 +48,7 @@ int SDL_AppEvent(void *appstate, const SDL_Event *event)
 }
 
 /* This function runs once per frame, and is the heart of the program. */
-int SDL_AppIterate(void *appstate)
+SDL_AppResult SDL_AppIterate(void *appstate)
 {
     SDL_FRect rect;
 

+ 3 - 3
examples/template.c

@@ -14,7 +14,7 @@ static SDL_Renderer *renderer = NULL;
 
 
 /* This function runs once at startup. */
-int SDL_AppInit(void **appstate, int argc, char *argv[])
+SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
 {
     if (SDL_Init(SDL_INIT_VIDEO) == -1) {
         SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't initialize SDL!", SDL_GetError(), NULL);
@@ -29,7 +29,7 @@ int SDL_AppInit(void **appstate, int argc, char *argv[])
 }
 
 /* This function runs when a new event (mouse input, keypresses, etc) occurs. */
-int SDL_AppEvent(void *appstate, const SDL_Event *event)
+SDL_AppResult SDL_AppEvent(void *appstate, const SDL_Event *event)
 {
     if (event->type == SDL_EVENT_QUIT) {
         return SDL_APP_SUCCESS;  /* end the program, reporting success to the OS. */
@@ -38,7 +38,7 @@ int SDL_AppEvent(void *appstate, const SDL_Event *event)
 }
 
 /* This function runs once per frame, and is the heart of the program. */
-int SDL_AppIterate(void *appstate)
+SDL_AppResult SDL_AppIterate(void *appstate)
 {
     return SDL_APP_CONTINUE;  /* carry on with the program! */
 }

+ 19 - 0
include/SDL3/SDL_init.h

@@ -66,6 +66,25 @@ typedef Uint32 SDL_InitFlags;
 #define SDL_INIT_SENSOR     0x00008000u /**< `SDL_INIT_SENSOR` implies `SDL_INIT_EVENTS` */
 #define SDL_INIT_CAMERA     0x00010000u /**< `SDL_INIT_CAMERA` implies `SDL_INIT_EVENTS` */
 
+/**
+ * Return values for optional main callbacks.
+ *
+ * See https://wiki.libsdl.org/SDL3/README/main-functions#main-callbacks-in-sdl3 for details.
+ *
+ * \since This enum is available since SDL 3.0.0.
+ */
+typedef enum SDL_AppResult
+{
+    SDL_APP_CONTINUE,   /** Value that requests that the app continue from the main callbacks. If SDL_AppInit, SDL_AppEvent, or SDL_AppIterate returns this value, the program will continue to run. */
+    SDL_APP_SUCCESS,    /** Value that requests termination with success from the main callbacks. If SDL_AppInit, SDL_AppEvent, or SDL_AppIterate returns this value, the program will terminate and report success to the operating system. What that success looks like is platform-dependent. On Unix, for example, the process error code will be zero. */
+    SDL_APP_FAILURE     /** Value that requests termination with error from the main callbacks. If SDL_AppInit, SDL_AppEvent, or SDL_AppIterate returns this value, the program will terminate and report failure to the operating system. What that failure looks like is platform-dependent. On Unix, for example, the process error code will be non-zero. */
+} SDL_AppResult;
+
+typedef SDL_AppResult (SDLCALL *SDL_AppInit_func)(void **appstate, int argc, char *argv[]);
+typedef SDL_AppResult (SDLCALL *SDL_AppIterate_func)(void *appstate);
+typedef SDL_AppResult (SDLCALL *SDL_AppEvent_func)(void *appstate, const SDL_Event *event);
+typedef void (SDLCALL *SDL_AppQuit_func)(void *appstate);
+
 /**
  * Initialize the SDL library.
  *

+ 4 - 51
include/SDL3/SDL_main.h

@@ -188,16 +188,12 @@
 #define main SDL_main
 #endif
 
+#include <SDL3/SDL_init.h>
 #include <SDL3/SDL_begin_code.h>
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-typedef int (SDLCALL *SDL_AppInit_func)(void **appstate, int argc, char *argv[]);
-typedef int (SDLCALL *SDL_AppIterate_func)(void *appstate);
-typedef int (SDLCALL *SDL_AppEvent_func)(void *appstate, const SDL_Event *event);
-typedef void (SDLCALL *SDL_AppQuit_func)(void *appstate);
-
 /*
  * You can (optionally!) define SDL_MAIN_USE_CALLBACKS before including
  * SDL_main.h, and then your application will _not_ have a standard
@@ -224,49 +220,6 @@ typedef void (SDLCALL *SDL_AppQuit_func)(void *appstate);
  */
 #ifdef SDL_MAIN_USE_CALLBACKS
 
-/**
- * Value that requests that the app continue from the main callbacks.
- *
- * If SDL_AppInit, SDL_AppEvent, or SDL_AppIterate returns this value, the
- * program will continue to run. This is the normal return value case.
- *
- * This is always 0; using this macro may be clearer, but is not required.
- *
- * \since This macro is available since SDL 3.0.0.
- */
-#define SDL_APP_CONTINUE 0
-
-/**
- * Value that requests termination with error from the main callbacks.
- *
- * If SDL_AppInit, SDL_AppEvent, or SDL_AppIterate returns this value, the
- * program will terminate and report failure to the operating system.
- *
- * What that failure looks like is platform-dependent. On Unix, for example,
- * the process error code will be non-zero.
- *
- * This is always -1; using this macro may be clearer, but is not required.
- *
- * \since This macro is available since SDL 3.0.0.
- */
-#define SDL_APP_FAILURE -1
-
-/**
- * Value that requests termination with success from the main callbacks.
- *
- * If SDL_AppInit, SDL_AppEvent, or SDL_AppIterate returns this value, the
- * program will terminate and report success to the operating system.
- *
- * What that success looks like is platform-dependent. On Unix, for example,
- * the process error code will be zero.
- *
- * This is always 1; using this macro may be clearer, but is not required.
- *
- * \since This macro is available since SDL 3.0.0.
- */
-#define SDL_APP_SUCCESS 1
-
-
 /**
  * App-implemented initial entry point for SDL_MAIN_USE_CALLBACKS apps.
  *
@@ -311,7 +264,7 @@ typedef void (SDLCALL *SDL_AppQuit_func)(void *appstate);
  * \sa SDL_AppEvent
  * \sa SDL_AppQuit
  */
-extern SDLMAIN_DECLSPEC int SDLCALL SDL_AppInit(void **appstate, int argc, char *argv[]);
+extern SDLMAIN_DECLSPEC SDL_AppResult SDLCALL SDL_AppInit(void **appstate, int argc, char *argv[]);
 
 /**
  * App-implemented iteration entry point for SDL_MAIN_USE_CALLBACKS apps.
@@ -359,7 +312,7 @@ extern SDLMAIN_DECLSPEC int SDLCALL SDL_AppInit(void **appstate, int argc, char
  * \sa SDL_AppInit
  * \sa SDL_AppEvent
  */
-extern SDLMAIN_DECLSPEC int SDLCALL SDL_AppIterate(void *appstate);
+extern SDLMAIN_DECLSPEC SDL_AppResult SDLCALL SDL_AppIterate(void *appstate);
 
 /**
  * App-implemented event entry point for SDL_MAIN_USE_CALLBACKS apps.
@@ -406,7 +359,7 @@ extern SDLMAIN_DECLSPEC int SDLCALL SDL_AppIterate(void *appstate);
  * \sa SDL_AppInit
  * \sa SDL_AppIterate
  */
-extern SDLMAIN_DECLSPEC int SDLCALL SDL_AppEvent(void *appstate, const SDL_Event *event);
+extern SDLMAIN_DECLSPEC SDL_AppResult SDLCALL SDL_AppEvent(void *appstate, const SDL_Event *event);
 
 /**
  * App-implemented deinit entry point for SDL_MAIN_USE_CALLBACKS apps.

+ 1 - 1
include/SDL3/SDL_test_common.h

@@ -234,7 +234,7 @@ void SDLTest_CommonEvent(SDLTest_CommonState *state, SDL_Event *event, int *done
  * \param event The event to handle.
  * \returns Value suitable for returning from SDL_AppEvent().
  */
-int SDLTest_CommonEventMainCallbacks(SDLTest_CommonState *state, const SDL_Event *event);
+SDL_AppResult SDLTest_CommonEventMainCallbacks(SDLTest_CommonState *state, const SDL_Event *event);
 
 /**
  * Close test window.

+ 12 - 12
src/main/SDL_main_callbacks.c

@@ -46,8 +46,8 @@ static SDL_bool ShouldDispatchImmediately(SDL_Event *event)
 
 static void SDL_DispatchMainCallbackEvent(SDL_Event *event)
 {
-    if (SDL_AtomicGet(&apprc) == 0) { // if already quitting, don't send the event to the app.
-        SDL_AtomicCompareAndSwap(&apprc, 0, SDL_main_event_callback(SDL_main_appstate, event));
+    if (SDL_AtomicGet(&apprc) == SDL_APP_CONTINUE) { // if already quitting, don't send the event to the app.
+        SDL_AtomicCompareAndSwap(&apprc, SDL_APP_CONTINUE, SDL_main_event_callback(SDL_main_appstate, event));
     }
 }
 
@@ -89,23 +89,23 @@ SDL_bool SDL_HasMainCallbacks(void)
     return SDL_FALSE;
 }
 
-int SDL_InitMainCallbacks(int argc, char* argv[], SDL_AppInit_func appinit, SDL_AppIterate_func appiter, SDL_AppEvent_func appevent, SDL_AppQuit_func appquit)
+SDL_AppResult SDL_InitMainCallbacks(int argc, char* argv[], SDL_AppInit_func appinit, SDL_AppIterate_func appiter, SDL_AppEvent_func appevent, SDL_AppQuit_func appquit)
 {
     SDL_main_iteration_callback = appiter;
     SDL_main_event_callback = appevent;
     SDL_main_quit_callback = appquit;
-    SDL_AtomicSet(&apprc, 0);
+    SDL_AtomicSet(&apprc, SDL_APP_CONTINUE);
 
-    const int rc = appinit(&SDL_main_appstate, argc, argv);
-    if (SDL_AtomicCompareAndSwap(&apprc, 0, rc) && (rc == 0)) {  // bounce if SDL_AppInit already said abort, otherwise...
+    const SDL_AppResult rc = appinit(&SDL_main_appstate, argc, argv);
+    if (SDL_AtomicCompareAndSwap(&apprc, SDL_APP_CONTINUE, rc) && (rc == SDL_APP_CONTINUE)) { // bounce if SDL_AppInit already said abort, otherwise...
         // make sure we definitely have events initialized, even if the app didn't do it.
         if (SDL_InitSubSystem(SDL_INIT_EVENTS) == -1) {
-            SDL_AtomicSet(&apprc, -1);
+            SDL_AtomicSet(&apprc, SDL_APP_FAILURE);
             return -1;
         }
 
         if (SDL_AddEventWatch(SDL_MainCallbackEventWatcher, NULL) < 0) {
-            SDL_AtomicSet(&apprc, -1);
+            SDL_AtomicSet(&apprc, SDL_APP_FAILURE);
             return -1;
         }
     }
@@ -113,17 +113,17 @@ int SDL_InitMainCallbacks(int argc, char* argv[], SDL_AppInit_func appinit, SDL_
     return SDL_AtomicGet(&apprc);
 }
 
-int SDL_IterateMainCallbacks(SDL_bool pump_events)
+SDL_AppResult SDL_IterateMainCallbacks(SDL_bool pump_events)
 {
     if (pump_events) {
         SDL_PumpEvents();
     }
     SDL_DispatchMainCallbackEvents();
 
-    int rc = SDL_AtomicGet(&apprc);
-    if (rc == 0) {
+    SDL_AppResult rc = SDL_AtomicGet(&apprc);
+    if (rc == SDL_APP_CONTINUE) {
         rc = SDL_main_iteration_callback(SDL_main_appstate);
-        if (!SDL_AtomicCompareAndSwap(&apprc, 0, rc)) {
+        if (!SDL_AtomicCompareAndSwap(&apprc, SDL_APP_CONTINUE, rc)) {
             rc = SDL_AtomicGet(&apprc); // something else already set a quit result, keep that.
         }
     }

+ 2 - 2
src/main/SDL_main_callbacks.h

@@ -23,8 +23,8 @@
 #define SDL_main_callbacks_h_
 
 SDL_bool SDL_HasMainCallbacks(void);
-int SDL_InitMainCallbacks(int argc, char *argv[], SDL_AppInit_func appinit, SDL_AppIterate_func _appiter, SDL_AppEvent_func _appevent, SDL_AppQuit_func _appquit);
-int SDL_IterateMainCallbacks(SDL_bool pump_events);
+SDL_AppResult SDL_InitMainCallbacks(int argc, char *argv[], SDL_AppInit_func appinit, SDL_AppIterate_func _appiter, SDL_AppEvent_func _appevent, SDL_AppQuit_func _appquit);
+SDL_AppResult SDL_IterateMainCallbacks(SDL_bool pump_events);
 void SDL_QuitMainCallbacks(void);
 
 #endif // SDL_main_callbacks_h_

+ 6 - 6
src/main/emscripten/SDL_sysmain_callbacks.c

@@ -26,22 +26,22 @@
 
 static void EmscriptenInternalMainloop(void)
 {
-    const int rc = SDL_IterateMainCallbacks(SDL_TRUE);
-    if (rc != 0) {
+    const SDL_AppResult rc = SDL_IterateMainCallbacks(SDL_TRUE);
+    if (rc != SDL_APP_CONTINUE) {
         SDL_QuitMainCallbacks();
         emscripten_cancel_main_loop();  // kill" the mainloop, so it stops calling back into it.
-        exit((rc < 0) ? 1 : 0);  // hopefully this takes down everything else, too.
+        exit((rc == SDL_APP_FAILURE) ? 1 : 0);  // hopefully this takes down everything else, too.
     }
 }
 
 int SDL_EnterAppMainCallbacks(int argc, char* argv[], SDL_AppInit_func appinit, SDL_AppIterate_func appiter, SDL_AppEvent_func appevent, SDL_AppQuit_func appquit)
 {
-    const int rc = SDL_InitMainCallbacks(argc, argv, appinit, appiter, appevent, appquit);
-    if (rc == 0) {
+    const SDL_AppResult rc = SDL_InitMainCallbacks(argc, argv, appinit, appiter, appevent, appquit);
+    if (rc == SDL_APP_CONTINUE) {
         emscripten_set_main_loop(EmscriptenInternalMainloop, 0, 0);  // run at refresh rate, don't throw an exception since we do an orderly return.
     } else {
         SDL_QuitMainCallbacks();
     }
-    return (rc < 0) ? 1 : 0;
+    return (rc == SDL_APP_FAILURE) ? 1 : 0;
 }
 

+ 3 - 3
src/main/generic/SDL_sysmain_callbacks.c

@@ -39,13 +39,13 @@ static void SDLCALL MainCallbackRateHintChanged(void *userdata, const char *name
 
 int SDL_EnterAppMainCallbacks(int argc, char* argv[], SDL_AppInit_func appinit, SDL_AppIterate_func appiter, SDL_AppEvent_func appevent, SDL_AppQuit_func appquit)
 {
-    int rc = SDL_InitMainCallbacks(argc, argv, appinit, appiter, appevent, appquit);
+    SDL_AppResult rc = SDL_InitMainCallbacks(argc, argv, appinit, appiter, appevent, appquit);
     if (rc == 0) {
         SDL_AddHintCallback(SDL_HINT_MAIN_CALLBACK_RATE, MainCallbackRateHintChanged, NULL);
 
         Uint64 next_iteration = callback_rate_increment ? (SDL_GetTicksNS() + callback_rate_increment) : 0;
 
-        while ((rc = SDL_IterateMainCallbacks(SDL_TRUE)) == 0) {
+        while ((rc = SDL_IterateMainCallbacks(SDL_TRUE)) == SDL_APP_CONTINUE) {
             // !!! FIXME: this can be made more complicated if we decide to
             // !!! FIXME: optionally hand off callback responsibility to the
             // !!! FIXME: video subsystem (for example, if Wayland has a
@@ -77,7 +77,7 @@ int SDL_EnterAppMainCallbacks(int argc, char* argv[], SDL_AppInit_func appinit,
     }
     SDL_QuitMainCallbacks();
 
-    return (rc < 0) ? 1 : 0;
+    return (rc == SDL_APP_FAILURE) ? 1 : 0;
 }
 
 #endif // !SDL_PLATFORM_IOS

+ 6 - 6
src/main/ios/SDL_sysmain_callbacks.m

@@ -50,14 +50,14 @@ static SDLIosMainCallbacksDisplayLink *globalDisplayLink;
 
 - (void)appIteration:(CADisplayLink *)sender
 {
-    const int rc = SDL_IterateMainCallbacks(SDL_TRUE);
-    if (rc != 0) {
+    const SDL_AppResult rc = SDL_IterateMainCallbacks(SDL_TRUE);
+    if (rc != SDL_APP_CONTINUE) {
         [self.displayLink invalidate];
         self.displayLink = nil;
         globalDisplayLink = nil;
         SDL_QuitMainCallbacks();
         SDL_UpdateLifecycleObserver();
-        exit((rc < 0) ? 1 : 0);
+        exit((rc == SDL_APP_FAILURE) ? 1 : 0);
     }
 }
 @end
@@ -66,8 +66,8 @@ static SDLIosMainCallbacksDisplayLink *globalDisplayLink;
 // When we return from here, we're living in the RunLoop, and a CADisplayLink is firing regularly for us.
 int SDL_EnterAppMainCallbacks(int argc, char* argv[], SDL_AppInit_func appinit, SDL_AppIterate_func appiter, SDL_AppEvent_func appevent, SDL_AppQuit_func appquit)
 {
-    const int rc = SDL_InitMainCallbacks(argc, argv, appinit, appiter, appevent, appquit);
-    if (rc == 0) {
+    const SDL_AppResult rc = SDL_InitMainCallbacks(argc, argv, appinit, appiter, appevent, appquit);
+    if (rc == SDL_APP_CONTINUE) {
         globalDisplayLink = [[SDLIosMainCallbacksDisplayLink alloc] init:appiter quitfunc:appquit];
         if (globalDisplayLink != nil) {
             return 0;  // this will fall all the way out of SDL_main, where UIApplicationMain will keep running the RunLoop.
@@ -76,7 +76,7 @@ int SDL_EnterAppMainCallbacks(int argc, char* argv[], SDL_AppInit_func appinit,
 
     // appinit requested quit, just bounce out now.
     SDL_QuitMainCallbacks();
-    exit((rc < 0) ? 1 : 0);
+    exit((rc == SDL_APP_FAILURE) ? 1 : 0);
 
     return 1;  // just in case.
 }

+ 2 - 2
src/test/SDL_test_common.c

@@ -2090,7 +2090,7 @@ static void FullscreenTo(SDLTest_CommonState *state, int index, int windowId)
     SDL_free(displays);
 }
 
-int SDLTest_CommonEventMainCallbacks(SDLTest_CommonState *state, const SDL_Event *event)
+SDL_AppResult SDLTest_CommonEventMainCallbacks(SDLTest_CommonState *state, const SDL_Event *event)
 {
     int i;
 
@@ -2487,7 +2487,7 @@ int SDLTest_CommonEventMainCallbacks(SDLTest_CommonState *state, const SDL_Event
 
 void SDLTest_CommonEvent(SDLTest_CommonState *state, SDL_Event *event, int *done)
 {
-    if (SDLTest_CommonEventMainCallbacks(state, event)) {
+    if (SDLTest_CommonEventMainCallbacks(state, event) != SDL_APP_CONTINUE) {
         *done = 1;
     }
 }

+ 3 - 3
test/loopwave.c

@@ -42,7 +42,7 @@ static int fillerup(void)
     return SDL_APP_CONTINUE;
 }
 
-int SDL_AppInit(void **appstate, int argc, char *argv[])
+SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
 {
     int i;
     char *filename = NULL;
@@ -120,12 +120,12 @@ int SDL_AppInit(void **appstate, int argc, char *argv[])
     return SDL_APP_CONTINUE;
 }
 
-int SDL_AppEvent(void *appstate, const SDL_Event *event)
+SDL_AppResult SDL_AppEvent(void *appstate, const SDL_Event *event)
 {
     return (event->type == SDL_EVENT_QUIT) ? SDL_APP_SUCCESS : SDL_APP_CONTINUE;
 }
 
-int SDL_AppIterate(void *appstate)
+SDL_AppResult SDL_AppIterate(void *appstate)
 {
     return fillerup();
 }

+ 3 - 3
test/testaudio.c

@@ -1073,7 +1073,7 @@ static void WindowResized(const int newwinw, const int newwinh)
     state->window_h = newwinh;
 }
 
-int SDL_AppInit(void **appstate, int argc, char *argv[])
+SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
 {
     int i;
 
@@ -1131,7 +1131,7 @@ int SDL_AppInit(void **appstate, int argc, char *argv[])
 
 static SDL_bool saw_event = SDL_FALSE;
 
-int SDL_AppEvent(void *appstate, const SDL_Event *event)
+SDL_AppResult SDL_AppEvent(void *appstate, const SDL_Event *event)
 {
     Thing *thing = NULL;
 
@@ -1254,7 +1254,7 @@ int SDL_AppEvent(void *appstate, const SDL_Event *event)
     return SDLTest_CommonEventMainCallbacks(state, event);
 }
 
-int SDL_AppIterate(void *appstate)
+SDL_AppResult SDL_AppIterate(void *appstate)
 {
     if (app_ready_ticks == 0) {
         app_ready_ticks = SDL_GetTicks();

+ 3 - 3
test/testaudiorecording.c

@@ -21,7 +21,7 @@ static SDL_AudioStream *stream_in = NULL;
 static SDL_AudioStream *stream_out = NULL;
 static SDLTest_CommonState *state = NULL;
 
-int SDL_AppInit(void **appstate, int argc, char **argv)
+SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv)
 {
     SDL_AudioDeviceID *devices;
     SDL_AudioSpec outspec;
@@ -149,7 +149,7 @@ int SDL_AppInit(void **appstate, int argc, char **argv)
     return SDL_APP_CONTINUE;
 }
 
-int SDL_AppEvent(void *appstate, const SDL_Event *event)
+SDL_AppResult SDL_AppEvent(void *appstate, const SDL_Event *event)
 {
     if (event->type == SDL_EVENT_QUIT) {
         return SDL_APP_SUCCESS;
@@ -173,7 +173,7 @@ int SDL_AppEvent(void *appstate, const SDL_Event *event)
     return SDL_APP_CONTINUE;
 }
 
-int SDL_AppIterate(void *appstate)
+SDL_AppResult SDL_AppIterate(void *appstate)
 {
     if (!SDL_AudioDevicePaused(SDL_GetAudioStreamDevice(stream_in))) {
         SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);

+ 3 - 3
test/testcamera.c

@@ -46,7 +46,7 @@ static void PrintCameraSpecs(SDL_CameraID camera_id)
     }
 }
 
-int SDL_AppInit(void **appstate, int argc, char *argv[])
+SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
 {
     char window_title[128];
     int devcount = 0;
@@ -216,7 +216,7 @@ static int FlipCamera(void)
     return SDL_APP_CONTINUE;
 }
 
-int SDL_AppEvent(void *appstate, const SDL_Event *event)
+SDL_AppResult SDL_AppEvent(void *appstate, const SDL_Event *event)
 {
     switch (event->type) {
         case SDL_EVENT_KEY_DOWN: {
@@ -262,7 +262,7 @@ int SDL_AppEvent(void *appstate, const SDL_Event *event)
     return SDLTest_CommonEventMainCallbacks(state, event);
 }
 
-int SDL_AppIterate(void *appstate)
+SDL_AppResult SDL_AppIterate(void *appstate)
 {
     iterate_count++;
 

+ 45 - 44
test/testdropfile.c

@@ -22,51 +22,8 @@ typedef struct {
     unsigned int windowID;
 } dropfile_dialog;
 
-int SDL_AppEvent(void *appstate, const SDL_Event *event)
+SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
 {
-    dropfile_dialog *dialog = appstate;
-    if (event->type == SDL_EVENT_DROP_BEGIN) {
-        SDL_Log("Drop beginning on window %u at (%f, %f)", (unsigned int)event->drop.windowID, event->drop.x, event->drop.y);
-    } else if (event->type == SDL_EVENT_DROP_COMPLETE) {
-        dialog->is_hover = SDL_FALSE;
-        SDL_Log("Drop complete on window %u at (%f, %f)", (unsigned int)event->drop.windowID, event->drop.x, event->drop.y);
-    } else if ((event->type == SDL_EVENT_DROP_FILE) || (event->type == SDL_EVENT_DROP_TEXT)) {
-        const char *typestr = (event->type == SDL_EVENT_DROP_FILE) ? "File" : "Text";
-        SDL_Log("%s dropped on window %u: %s at (%f, %f)", typestr, (unsigned int)event->drop.windowID, event->drop.data, event->drop.x, event->drop.y);
-    } else if (event->type == SDL_EVENT_DROP_POSITION) {
-        dialog->is_hover = SDL_TRUE;
-        dialog->x = event->drop.x;
-        dialog->y = event->drop.y;
-        dialog->windowID = event->drop.windowID;
-        SDL_Log("Drop position on window %u at (%f, %f) data = %s", (unsigned int)event->drop.windowID, event->drop.x, event->drop.y, event->drop.data);
-    }
-
-    return SDLTest_CommonEventMainCallbacks(dialog->state, event);
-}
-
-int SDL_AppIterate(void *appstate)
-{
-    dropfile_dialog *dialog = appstate;
-    int i;
-
-    for (i = 0; i < dialog->state->num_windows; ++i) {
-        SDL_Renderer *renderer = dialog->state->renderers[i];
-        SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);
-        SDL_RenderClear(renderer);
-        if (dialog->is_hover) {
-            if (dialog->windowID == SDL_GetWindowID(SDL_GetRenderWindow(renderer))) {
-                int len = 2000;
-                SDL_SetRenderDrawColor(renderer, 0x0A, 0x0A, 0x0A, 0xFF);
-                SDL_RenderLine(renderer, dialog->x, dialog->y - len, dialog->x, dialog->y + len);
-                SDL_RenderLine(renderer, dialog->x - len, dialog->y, dialog->x + len, dialog->y);
-            }
-        }
-        SDL_RenderPresent(renderer);
-    }
-    return SDL_APP_CONTINUE;
-}
-
-int SDL_AppInit(void **appstate, int argc, char *argv[]) {
     int i;
     dropfile_dialog *dialog;
     SDLTest_CommonState *state;
@@ -113,6 +70,50 @@ onerror:
     return SDL_APP_FAILURE;
 }
 
+SDL_AppResult SDL_AppEvent(void *appstate, const SDL_Event *event)
+{
+    dropfile_dialog *dialog = appstate;
+    if (event->type == SDL_EVENT_DROP_BEGIN) {
+        SDL_Log("Drop beginning on window %u at (%f, %f)", (unsigned int)event->drop.windowID, event->drop.x, event->drop.y);
+    } else if (event->type == SDL_EVENT_DROP_COMPLETE) {
+        dialog->is_hover = SDL_FALSE;
+        SDL_Log("Drop complete on window %u at (%f, %f)", (unsigned int)event->drop.windowID, event->drop.x, event->drop.y);
+    } else if ((event->type == SDL_EVENT_DROP_FILE) || (event->type == SDL_EVENT_DROP_TEXT)) {
+        const char *typestr = (event->type == SDL_EVENT_DROP_FILE) ? "File" : "Text";
+        SDL_Log("%s dropped on window %u: %s at (%f, %f)", typestr, (unsigned int)event->drop.windowID, event->drop.data, event->drop.x, event->drop.y);
+    } else if (event->type == SDL_EVENT_DROP_POSITION) {
+        dialog->is_hover = SDL_TRUE;
+        dialog->x = event->drop.x;
+        dialog->y = event->drop.y;
+        dialog->windowID = event->drop.windowID;
+        SDL_Log("Drop position on window %u at (%f, %f) data = %s", (unsigned int)event->drop.windowID, event->drop.x, event->drop.y, event->drop.data);
+    }
+
+    return SDLTest_CommonEventMainCallbacks(dialog->state, event);
+}
+
+SDL_AppResult SDL_AppIterate(void *appstate)
+{
+    dropfile_dialog *dialog = appstate;
+    int i;
+
+    for (i = 0; i < dialog->state->num_windows; ++i) {
+        SDL_Renderer *renderer = dialog->state->renderers[i];
+        SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);
+        SDL_RenderClear(renderer);
+        if (dialog->is_hover) {
+            if (dialog->windowID == SDL_GetWindowID(SDL_GetRenderWindow(renderer))) {
+                int len = 2000;
+                SDL_SetRenderDrawColor(renderer, 0x0A, 0x0A, 0x0A, 0xFF);
+                SDL_RenderLine(renderer, dialog->x, dialog->y - len, dialog->x, dialog->y + len);
+                SDL_RenderLine(renderer, dialog->x - len, dialog->y, dialog->x + len, dialog->y);
+            }
+        }
+        SDL_RenderPresent(renderer);
+    }
+    return SDL_APP_CONTINUE;
+}
+
 void SDL_AppQuit(void *appstate)
 {
     dropfile_dialog *dialog = appstate;

+ 3 - 3
test/testpen.c

@@ -34,7 +34,7 @@ static SDL_Texture *white_pixel = NULL;
 static Pen pens;
 
 
-int SDL_AppInit(void **appstate, int argc, char *argv[])
+SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
 {
     int i;
 
@@ -107,7 +107,7 @@ static Pen *FindPen(SDL_PenID which)
     return NULL;
 }
 
-int SDL_AppEvent(void *appstate, const SDL_Event *event)
+SDL_AppResult SDL_AppEvent(void *appstate, const SDL_Event *event)
 {
     Pen *pen = NULL;
 
@@ -259,7 +259,7 @@ static void DrawOnePen(Pen *pen, int num)
     }
 }
 
-int SDL_AppIterate(void *appstate)
+SDL_AppResult SDL_AppIterate(void *appstate)
 {
     int num = 0;
     Pen *pen;

+ 41 - 41
test/testsprite.c

@@ -385,46 +385,7 @@ static void MoveSprites(SDL_Renderer *renderer, SDL_Texture *sprite)
     SDL_RenderPresent(renderer);
 }
 
-int SDL_AppEvent(void *appstate, const SDL_Event *event)
-{
-    return SDLTest_CommonEventMainCallbacks(state, event);
-}
-
-int SDL_AppIterate(void *appstate)
-{
-    Uint64 now;
-    int i;
-    int active_windows = 0;
-
-    for (i = 0; i < state->num_windows; ++i) {
-        if (state->windows[i] == NULL ||
-            (suspend_when_occluded && (SDL_GetWindowFlags(state->windows[i]) & SDL_WINDOW_OCCLUDED))) {
-            continue;
-        }
-        ++active_windows;
-        MoveSprites(state->renderers[i], sprites[i]);
-    }
-
-    /* If all windows are occluded, throttle the event polling to 15hz. */
-    if (!active_windows) {
-        SDL_DelayNS(SDL_NS_PER_SECOND / 15);
-    }
-
-    frames++;
-    now = SDL_GetTicks();
-    if (now >= next_fps_check) {
-        /* Print out some timing information */
-        const Uint64 then = next_fps_check - fps_check_delay;
-        const double fps = ((double)frames * 1000) / (now - then);
-        SDL_Log("%2.2f frames per second\n", fps);
-        next_fps_check = now + fps_check_delay;
-        frames = 0;
-    }
-
-    return SDL_APP_CONTINUE;
-}
-
-int SDL_AppInit(void **appstate, int argc, char *argv[])
+SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
 {
     SDL_Rect safe_area;
     int i;
@@ -488,7 +449,7 @@ int SDL_AppInit(void **appstate, int argc, char *argv[])
             } else if (SDL_strcasecmp(argv[i], "--cyclealpha") == 0) {
                 cycle_alpha = SDL_TRUE;
                 consumed = 1;
-            } else if(SDL_strcasecmp(argv[i], "--suspend-when-occluded") == 0) {
+            } else if (SDL_strcasecmp(argv[i], "--suspend-when-occluded") == 0) {
                 suspend_when_occluded = SDL_TRUE;
                 consumed = 1;
             } else if (SDL_strcasecmp(argv[i], "--use-rendergeometry") == 0) {
@@ -589,3 +550,42 @@ int SDL_AppInit(void **appstate, int argc, char *argv[])
     return SDL_APP_CONTINUE;
 }
 
+
+SDL_AppResult SDL_AppEvent(void *appstate, const SDL_Event *event)
+{
+    return SDLTest_CommonEventMainCallbacks(state, event);
+}
+
+SDL_AppResult SDL_AppIterate(void *appstate)
+{
+    Uint64 now;
+    int i;
+    int active_windows = 0;
+
+    for (i = 0; i < state->num_windows; ++i) {
+        if (state->windows[i] == NULL ||
+            (suspend_when_occluded && (SDL_GetWindowFlags(state->windows[i]) & SDL_WINDOW_OCCLUDED))) {
+            continue;
+        }
+        ++active_windows;
+        MoveSprites(state->renderers[i], sprites[i]);
+    }
+
+    /* If all windows are occluded, throttle the event polling to 15hz. */
+    if (!active_windows) {
+        SDL_DelayNS(SDL_NS_PER_SECOND / 15);
+    }
+
+    frames++;
+    now = SDL_GetTicks();
+    if (now >= next_fps_check) {
+        /* Print out some timing information */
+        const Uint64 then = next_fps_check - fps_check_delay;
+        const double fps = ((double)frames * 1000) / (now - then);
+        SDL_Log("%2.2f frames per second\n", fps);
+        next_fps_check = now + fps_check_delay;
+        frames = 0;
+    }
+
+    return SDL_APP_CONTINUE;
+}