diff --git a/CMakeLists.txt b/CMakeLists.txt index a7f342579d..a40bc609a4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1480,8 +1480,6 @@ elseif(EMSCRIPTEN) # project. Uncomment at will for verbose cross-compiling -I/../ path info. sdl_compile_options(PRIVATE "-Wno-warn-absolute-paths") - sdl_glob_sources("${SDL3_SOURCE_DIR}/src/core/emscripten/*.c") - sdl_glob_sources("${SDL3_SOURCE_DIR}/src/main/emscripten/*.c") set(HAVE_SDL_MAIN_CALLBACKS TRUE) @@ -1866,12 +1864,14 @@ elseif(WINDOWS) int main(int argc, char **argv) { return 0; }" HAVE_WIN32_CC) sdl_glob_sources("${SDL3_SOURCE_DIR}/src/core/windows/*.c") + sdl_glob_sources("${SDL3_SOURCE_DIR}/src/main/windows/*.c") if(WINDOWS_STORE) enable_language(CXX) sdl_glob_sources( "${SDL3_SOURCE_DIR}/src/core/winrt/*.c" "${SDL3_SOURCE_DIR}/src/core/winrt/*.cpp" + "${SDL3_SOURCE_DIR}/src/main/winrt/*.cpp" ) endif() @@ -2727,7 +2727,7 @@ elseif(VITA) sdl_compile_definitions(PRIVATE "__VITA__") elseif(PSP) - sdl_glob_sources("${SDL3_SOURCE_DIR}/src/core/psp/*.c") + sdl_glob_sources("${SDL3_SOURCE_DIR}/src/main/psp/*.c") if(SDL_AUDIO) set(SDL_AUDIO_DRIVER_PSP 1) @@ -2796,7 +2796,7 @@ elseif(PS2) sdl_compile_definitions(PRIVATE "PS2" "__PS2__") sdl_include_directories(PRIVATE SYSTEM "$ENV{PS2SDK}/ports/include" "$ENV{PS2DEV}/gsKit/include") - sdl_glob_sources("${SDL3_SOURCE_DIR}/src/core/ps2/*.c") + sdl_glob_sources("${SDL3_SOURCE_DIR}/src/main/ps2/*.c") if(SDL_AUDIO) set(SDL_AUDIO_DRIVER_PS2 1) @@ -2853,7 +2853,7 @@ elseif(PS2) ps2_drivers ) elseif(N3DS) - sdl_glob_sources("${SDL3_SOURCE_DIR}/src/core/n3ds/*.c") + sdl_glob_sources("${SDL3_SOURCE_DIR}/src/main/n3ds/*.c") if(SDL_AUDIO) set(SDL_AUDIO_DRIVER_N3DS 1) diff --git a/VisualC-GDK/SDL/SDL.vcxproj b/VisualC-GDK/SDL/SDL.vcxproj index bb7c85405b..67e74896cd 100644 --- a/VisualC-GDK/SDL/SDL.vcxproj +++ b/VisualC-GDK/SDL/SDL.vcxproj @@ -503,8 +503,10 @@ + + @@ -600,7 +602,6 @@ - diff --git a/VisualC-GDK/SDL/SDL.vcxproj.filters b/VisualC-GDK/SDL/SDL.vcxproj.filters index 2b4f69eb03..478d401f0c 100644 --- a/VisualC-GDK/SDL/SDL.vcxproj.filters +++ b/VisualC-GDK/SDL/SDL.vcxproj.filters @@ -18,6 +18,8 @@ + + @@ -35,7 +37,6 @@ - diff --git a/VisualC-WinRT/SDL-UWP.vcxproj b/VisualC-WinRT/SDL-UWP.vcxproj index 0231e2dd03..072c133d31 100644 --- a/VisualC-WinRT/SDL-UWP.vcxproj +++ b/VisualC-WinRT/SDL-UWP.vcxproj @@ -268,7 +268,6 @@ - @@ -359,8 +358,20 @@ + + + true + $(IntDir)$(TargetName)_cpp.pch + $(IntDir)$(TargetName)_cpp.pch + $(IntDir)$(TargetName)_cpp.pch + $(IntDir)$(TargetName)_cpp.pch + $(IntDir)$(TargetName)_cpp.pch + $(IntDir)$(TargetName)_cpp.pch + $(IntDir)$(TargetName)_cpp.pch + $(IntDir)$(TargetName)_cpp.pch + true diff --git a/VisualC-WinRT/SDL-UWP.vcxproj.filters b/VisualC-WinRT/SDL-UWP.vcxproj.filters index 7112f2f9cc..4e573d6f28 100644 --- a/VisualC-WinRT/SDL-UWP.vcxproj.filters +++ b/VisualC-WinRT/SDL-UWP.vcxproj.filters @@ -34,6 +34,9 @@ {0000c99bfadbbcb05a474a8472910000} + + {00006680a11742e2b280c6453be80000} + @@ -549,9 +552,6 @@ Source Files - - Source Files - Source Files @@ -660,6 +660,12 @@ main + + Source Files + + + main\winrt + Source Files diff --git a/VisualC/SDL/SDL.vcxproj b/VisualC/SDL/SDL.vcxproj index 87dd7ee8ee..879c607e8d 100644 --- a/VisualC/SDL/SDL.vcxproj +++ b/VisualC/SDL/SDL.vcxproj @@ -404,6 +404,8 @@ + + @@ -506,7 +508,6 @@ - diff --git a/VisualC/SDL/SDL.vcxproj.filters b/VisualC/SDL/SDL.vcxproj.filters index 4eb44ad41f..93db4f1994 100644 --- a/VisualC/SDL/SDL.vcxproj.filters +++ b/VisualC/SDL/SDL.vcxproj.filters @@ -202,6 +202,9 @@ {748cf015-00b8-4e71-ac48-02e947e4d93d} + + {00009d5ded166cc6c6680ec771a30000} + @@ -919,6 +922,12 @@ main + + main + + + main\windows + @@ -961,9 +970,6 @@ core - - core - core\windows diff --git a/Xcode/SDL/SDL.xcodeproj/project.pbxproj b/Xcode/SDL/SDL.xcodeproj/project.pbxproj index aace663af0..f13182b501 100644 --- a/Xcode/SDL/SDL.xcodeproj/project.pbxproj +++ b/Xcode/SDL/SDL.xcodeproj/project.pbxproj @@ -1145,6 +1145,7 @@ 00008B5A0CB83D2069E80000 /* ios */, 00009366FB9FBBD54C390000 /* SDL_main_callbacks.c */, 00003260407E1002EAC10000 /* SDL_main_callbacks.h */, + F36C7AD0294BA009004D61C3 /* SDL_runapp.c */, ); path = main; sourceTree = ""; @@ -2255,7 +2256,6 @@ isa = PBXGroup; children = ( E4F798192AD8D84800669F54 /* SDL_core_unsupported.c */, - F36C7AD0294BA009004D61C3 /* SDL_runapp.c */, ); path = core; sourceTree = ""; diff --git a/src/core/gdk/SDL_gdk.cpp b/src/core/gdk/SDL_gdk.cpp index 8e7a8caaa4..80166bae3c 100644 --- a/src/core/gdk/SDL_gdk.cpp +++ b/src/core/gdk/SDL_gdk.cpp @@ -26,7 +26,6 @@ extern "C" { } #include #include -#include /* CommandLineToArgvW() */ #include static XTaskQueueHandle GDK_GlobalTaskQueue; @@ -74,162 +73,6 @@ void GDK_DispatchTaskQueue(void) } } -/* Pop up an out of memory message, returns to Windows */ -static BOOL OutOfMemory(void) -{ - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal Error", "Out of memory - aborting", NULL); - return FALSE; -} - -/* Gets the arguments with GetCommandLine, converts them to argc and argv - and calls SDL_main */ -extern "C" -int SDL_RunApp(int, char**, SDL_main_func mainFunction, void *reserved) -{ - LPWSTR *argvw; - char **argv; - int i, argc, result; - HRESULT hr; - XTaskQueueHandle taskQueue; - - argvw = CommandLineToArgvW(GetCommandLineW(), &argc); - if (argvw == NULL) { - return OutOfMemory(); - } - - /* Note that we need to be careful about how we allocate/free memory here. - * If the application calls SDL_SetMemoryFunctions(), we can't rely on - * SDL_free() to use the same allocator after SDL_main() returns. - */ - - /* Parse it into argv and argc */ - argv = (char **)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (argc + 1) * sizeof(*argv)); - if (argv == NULL) { - return OutOfMemory(); - } - for (i = 0; i < argc; ++i) { - const int utf8size = WideCharToMultiByte(CP_UTF8, 0, argvw[i], -1, NULL, 0, NULL, NULL); - if (!utf8size) { // uhoh? - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal Error", "Error processing command line arguments", NULL); - return -1; - } - - argv[i] = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, utf8size); // this size includes the null-terminator character. - if (!argv[i]) { - return OutOfMemory(); - } - - if (WideCharToMultiByte(CP_UTF8, 0, argvw[i], -1, argv[i], utf8size, NULL, NULL) == 0) { // failed? uhoh! - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal Error", "Error processing command line arguments", NULL); - return -1; - } - } - argv[i] = NULL; - LocalFree(argvw); - - hr = XGameRuntimeInitialize(); - - if (SUCCEEDED(hr) && SDL_GDKGetTaskQueue(&taskQueue) == 0) { - Uint32 titleid = 0; - char scidBuffer[64]; - XblInitArgs xblArgs; - - XTaskQueueSetCurrentProcessTaskQueue(taskQueue); - - /* Try to get the title ID and initialize Xbox Live */ - hr = XGameGetXboxTitleId(&titleid); - if (SUCCEEDED(hr)) { - SDL_zero(xblArgs); - xblArgs.queue = taskQueue; - SDL_snprintf(scidBuffer, 64, "00000000-0000-0000-0000-0000%08X", titleid); - xblArgs.scid = scidBuffer; - hr = XblInitialize(&xblArgs); - } else { - SDL_SetError("[GDK] Unable to get titleid. Will not call XblInitialize. Check MicrosoftGame.config!"); - } - - SDL_SetMainReady(); - - /* Register suspend/resume handling */ - plmSuspendComplete = CreateEventEx(nullptr, nullptr, 0, EVENT_MODIFY_STATE | SYNCHRONIZE); - if (!plmSuspendComplete) { - SDL_SetError("[GDK] Unable to create plmSuspendComplete event"); - return -1; - } - auto rascn = [](BOOLEAN quiesced, PVOID context) { - SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "[GDK] in RegisterAppStateChangeNotification handler"); - if (quiesced) { - ResetEvent(plmSuspendComplete); - SDL_SendAppEvent(SDL_EVENT_DID_ENTER_BACKGROUND); - - // To defer suspension, we must wait to exit this callback. - // IMPORTANT: The app must call SDL_GDKSuspendComplete() to release this lock. - (void)WaitForSingleObject(plmSuspendComplete, INFINITE); - - SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "[GDK] in RegisterAppStateChangeNotification handler: plmSuspendComplete event signaled."); - } else { - SDL_SendAppEvent(SDL_EVENT_WILL_ENTER_FOREGROUND); - } - }; - if (RegisterAppStateChangeNotification(rascn, NULL, &hPLM)) { - SDL_SetError("[GDK] Unable to call RegisterAppStateChangeNotification"); - return -1; - } - - /* Register constrain/unconstrain handling */ - auto raccn = [](BOOLEAN constrained, PVOID context) { - SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "[GDK] in RegisterAppConstrainedChangeNotification handler"); - SDL_VideoDevice *_this = SDL_GetVideoDevice(); - if (_this) { - if (constrained) { - SDL_SetKeyboardFocus(NULL); - } else { - SDL_SetKeyboardFocus(_this->windows); - } - } - }; - if (RegisterAppConstrainedChangeNotification(raccn, NULL, &hCPLM)) { - SDL_SetError("[GDK] Unable to call RegisterAppConstrainedChangeNotification"); - return -1; - } - - /* Run the application main() code */ - result = mainFunction(argc, argv); - - /* Unregister suspend/resume handling */ - UnregisterAppStateChangeNotification(hPLM); - CloseHandle(plmSuspendComplete); - - /* Unregister constrain/unconstrain handling */ - UnregisterAppConstrainedChangeNotification(hCPLM); - - /* !!! FIXME: This follows the docs exactly, but for some reason still leaks handles on exit? */ - /* Terminate the task queue and dispatch any pending tasks */ - XTaskQueueTerminate(taskQueue, false, nullptr, nullptr); - while (XTaskQueueDispatch(taskQueue, XTaskQueuePort::Completion, 0)) - ; - - XTaskQueueCloseHandle(taskQueue); - - XGameRuntimeUninitialize(); - } else { -#ifdef SDL_PLATFORM_WINGDK - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal Error", "[GDK] Could not initialize - aborting", NULL); -#else - SDL_assert_always(0 && "[GDK] Could not initialize - aborting"); -#endif - result = -1; - } - - /* Free argv, to avoid memory leak */ - for (i = 0; i < argc; ++i) { - HeapFree(GetProcessHeap(), 0, argv[i]); - } - HeapFree(GetProcessHeap(), 0, argv); - - return result; -} - extern "C" void SDL_GDKSuspendComplete() { diff --git a/src/core/windows/SDL_windows.c b/src/core/windows/SDL_windows.c index eea88ff8e6..961d4de801 100644 --- a/src/core/windows/SDL_windows.c +++ b/src/core/windows/SDL_windows.c @@ -389,81 +389,4 @@ int WIN_WideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWCH lpWideCharStr, return WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, lpMultiByteStr, cbMultiByte, lpDefaultChar, lpUsedDefaultChar); } - -/* 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 */ -#ifdef SDL_PLATFORM_WIN32 - -#include /* CommandLineToArgvW() */ - -/* Pop up an out of memory message, returns to Windows */ -static int OutOfMemory(void) -{ - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal Error", "Out of memory - aborting", NULL); - return -1; -} - -int MINGW32_FORCEALIGN SDL_RunApp(int _argc, char* _argv[], SDL_main_func mainFunction, void * reserved) -{ - - /* Gets the arguments with GetCommandLine, converts them to argc and argv - and calls SDL_main */ - - LPWSTR *argvw; - char **argv; - int i, argc, result; - - (void)_argc; (void)_argv; (void)reserved; - - argvw = CommandLineToArgvW(GetCommandLineW(), &argc); - if (!argvw) { - return OutOfMemory(); - } - - /* Note that we need to be careful about how we allocate/free memory here. - * If the application calls SDL_SetMemoryFunctions(), we can't rely on - * SDL_free() to use the same allocator after SDL_main() returns. - */ - - /* Parse it into argv and argc */ - argv = (char **)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (argc + 1) * sizeof(*argv)); - if (!argv) { - return OutOfMemory(); - } - for (i = 0; i < argc; ++i) { - const int utf8size = WideCharToMultiByte(CP_UTF8, 0, argvw[i], -1, NULL, 0, NULL, NULL); - if (!utf8size) { // uhoh? - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal Error", "Error processing command line arguments", NULL); - return -1; - } - - argv[i] = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, utf8size); // this size includes the null-terminator character. - if (!argv[i]) { - return OutOfMemory(); - } - - if (WideCharToMultiByte(CP_UTF8, 0, argvw[i], -1, argv[i], utf8size, NULL, NULL) == 0) { // failed? uhoh! - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal Error", "Error processing command line arguments", NULL); - return -1; - } - } - argv[i] = NULL; - LocalFree(argvw); - - SDL_SetMainReady(); - - /* Run the application main() code */ - result = mainFunction(argc, argv); - - /* Free argv, to avoid memory leak */ - for (i = 0; i < argc; ++i) { - HeapFree(GetProcessHeap(), 0, argv[i]); - } - HeapFree(GetProcessHeap(), 0, argv); - - return result; -} - -#endif /* SDL_PLATFORM_WIN32 */ - #endif /* defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_WINRT) || defined(SDL_PLATFORM_GDK) */ diff --git a/src/core/winrt/SDL_winrtapp_common.cpp b/src/core/winrt/SDL_winrtapp_common.cpp index 9df3c1d888..6cdb71d530 100644 --- a/src/core/winrt/SDL_winrtapp_common.cpp +++ b/src/core/winrt/SDL_winrtapp_common.cpp @@ -20,26 +20,10 @@ */ #include "SDL_internal.h" -#include "SDL_winrtapp_direct3d.h" -#include "SDL_winrtapp_xaml.h" - #include int (*WINRT_SDLAppEntryPoint)(int, char **) = NULL; -extern "C" -int SDL_RunApp(int, char**, SDL_main_func mainFunction, void * xamlBackgroundPanel) -{ - if (xamlBackgroundPanel) { - return SDL_WinRTInitXAMLApp(mainFunction, xamlBackgroundPanel); - } else { - if (FAILED(Windows::Foundation::Initialize(RO_INIT_MULTITHREADED))) { - return 1; - } - return SDL_WinRTInitNonXAMLApp(mainFunction); - } -} - extern "C" SDL_WinRT_DeviceFamily SDL_WinRTGetDeviceFamily() { diff --git a/src/core/SDL_runapp.c b/src/main/SDL_runapp.c similarity index 100% rename from src/core/SDL_runapp.c rename to src/main/SDL_runapp.c diff --git a/src/core/emscripten/SDL_emscripten.c b/src/main/emscripten/SDL_sysmain_runapp.c similarity index 100% rename from src/core/emscripten/SDL_emscripten.c rename to src/main/emscripten/SDL_sysmain_runapp.c diff --git a/src/main/gdk/SDL_sysmain_runapp.cpp b/src/main/gdk/SDL_sysmain_runapp.cpp new file mode 100644 index 0000000000..4517b28577 --- /dev/null +++ b/src/main/gdk/SDL_sysmain_runapp.cpp @@ -0,0 +1,187 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_internal.h" + +extern "C" { +#include "../../core/windows/SDL_windows.h" +#include "../../events/SDL_events_c.h" +} +#include +#include +#include /* CommandLineToArgvW() */ +#include + +/* Pop up an out of memory message, returns to Windows */ +static BOOL OutOfMemory(void) +{ + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal Error", "Out of memory - aborting", NULL); + return FALSE; +} + +/* Gets the arguments with GetCommandLine, converts them to argc and argv + and calls SDL_main */ +extern "C" +int SDL_RunApp(int, char**, SDL_main_func mainFunction, void *reserved) +{ + LPWSTR *argvw; + char **argv; + int i, argc, result; + HRESULT hr; + XTaskQueueHandle taskQueue; + + argvw = CommandLineToArgvW(GetCommandLineW(), &argc); + if (argvw == NULL) { + return OutOfMemory(); + } + + /* Note that we need to be careful about how we allocate/free memory here. + * If the application calls SDL_SetMemoryFunctions(), we can't rely on + * SDL_free() to use the same allocator after SDL_main() returns. + */ + + /* Parse it into argv and argc */ + argv = (char **)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (argc + 1) * sizeof(*argv)); + if (argv == NULL) { + return OutOfMemory(); + } + for (i = 0; i < argc; ++i) { + const int utf8size = WideCharToMultiByte(CP_UTF8, 0, argvw[i], -1, NULL, 0, NULL, NULL); + if (!utf8size) { // uhoh? + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal Error", "Error processing command line arguments", NULL); + return -1; + } + + argv[i] = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, utf8size); // this size includes the null-terminator character. + if (!argv[i]) { + return OutOfMemory(); + } + + if (WideCharToMultiByte(CP_UTF8, 0, argvw[i], -1, argv[i], utf8size, NULL, NULL) == 0) { // failed? uhoh! + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal Error", "Error processing command line arguments", NULL); + return -1; + } + } + argv[i] = NULL; + LocalFree(argvw); + + hr = XGameRuntimeInitialize(); + + if (SUCCEEDED(hr) && SDL_GDKGetTaskQueue(&taskQueue) == 0) { + Uint32 titleid = 0; + char scidBuffer[64]; + XblInitArgs xblArgs; + + XTaskQueueSetCurrentProcessTaskQueue(taskQueue); + + /* Try to get the title ID and initialize Xbox Live */ + hr = XGameGetXboxTitleId(&titleid); + if (SUCCEEDED(hr)) { + SDL_zero(xblArgs); + xblArgs.queue = taskQueue; + SDL_snprintf(scidBuffer, 64, "00000000-0000-0000-0000-0000%08X", titleid); + xblArgs.scid = scidBuffer; + hr = XblInitialize(&xblArgs); + } else { + SDL_SetError("[GDK] Unable to get titleid. Will not call XblInitialize. Check MicrosoftGame.config!"); + } + + SDL_SetMainReady(); + + /* Register suspend/resume handling */ + plmSuspendComplete = CreateEventEx(nullptr, nullptr, 0, EVENT_MODIFY_STATE | SYNCHRONIZE); + if (!plmSuspendComplete) { + SDL_SetError("[GDK] Unable to create plmSuspendComplete event"); + return -1; + } + auto rascn = [](BOOLEAN quiesced, PVOID context) { + SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "[GDK] in RegisterAppStateChangeNotification handler"); + if (quiesced) { + ResetEvent(plmSuspendComplete); + SDL_SendAppEvent(SDL_EVENT_DID_ENTER_BACKGROUND); + + // To defer suspension, we must wait to exit this callback. + // IMPORTANT: The app must call SDL_GDKSuspendComplete() to release this lock. + (void)WaitForSingleObject(plmSuspendComplete, INFINITE); + + SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "[GDK] in RegisterAppStateChangeNotification handler: plmSuspendComplete event signaled."); + } else { + SDL_SendAppEvent(SDL_EVENT_WILL_ENTER_FOREGROUND); + } + }; + if (RegisterAppStateChangeNotification(rascn, NULL, &hPLM)) { + SDL_SetError("[GDK] Unable to call RegisterAppStateChangeNotification"); + return -1; + } + + /* Register constrain/unconstrain handling */ + auto raccn = [](BOOLEAN constrained, PVOID context) { + SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "[GDK] in RegisterAppConstrainedChangeNotification handler"); + SDL_VideoDevice *_this = SDL_GetVideoDevice(); + if (_this) { + if (constrained) { + SDL_SetKeyboardFocus(NULL); + } else { + SDL_SetKeyboardFocus(_this->windows); + } + } + }; + if (RegisterAppConstrainedChangeNotification(raccn, NULL, &hCPLM)) { + SDL_SetError("[GDK] Unable to call RegisterAppConstrainedChangeNotification"); + return -1; + } + + /* Run the application main() code */ + result = mainFunction(argc, argv); + + /* Unregister suspend/resume handling */ + UnregisterAppStateChangeNotification(hPLM); + CloseHandle(plmSuspendComplete); + + /* Unregister constrain/unconstrain handling */ + UnregisterAppConstrainedChangeNotification(hCPLM); + + /* !!! FIXME: This follows the docs exactly, but for some reason still leaks handles on exit? */ + /* Terminate the task queue and dispatch any pending tasks */ + XTaskQueueTerminate(taskQueue, false, nullptr, nullptr); + while (XTaskQueueDispatch(taskQueue, XTaskQueuePort::Completion, 0)) + ; + + XTaskQueueCloseHandle(taskQueue); + + XGameRuntimeUninitialize(); + } else { +#ifdef SDL_PLATFORM_WINGDK + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal Error", "[GDK] Could not initialize - aborting", NULL); +#else + SDL_assert_always(0 && "[GDK] Could not initialize - aborting"); +#endif + result = -1; + } + + /* Free argv, to avoid memory leak */ + for (i = 0; i < argc; ++i) { + HeapFree(GetProcessHeap(), 0, argv[i]); + } + HeapFree(GetProcessHeap(), 0, argv); + + return result; +} + diff --git a/src/core/n3ds/SDL_n3ds.c b/src/main/n3ds/SDL_sysmain_runapp.c similarity index 100% rename from src/core/n3ds/SDL_n3ds.c rename to src/main/n3ds/SDL_sysmain_runapp.c diff --git a/src/core/ngage/SDL_ngage_runapp.cpp b/src/main/ngage/SDL_sysmain_runapp.cpp similarity index 100% rename from src/core/ngage/SDL_ngage_runapp.cpp rename to src/main/ngage/SDL_sysmain_runapp.cpp diff --git a/src/core/ps2/SDL_ps2.c b/src/main/ps2/SDL_sysmain_runapp.c similarity index 100% rename from src/core/ps2/SDL_ps2.c rename to src/main/ps2/SDL_sysmain_runapp.c diff --git a/src/core/psp/SDL_psp.c b/src/main/psp/SDL_sysmain_runapp.c similarity index 100% rename from src/core/psp/SDL_psp.c rename to src/main/psp/SDL_sysmain_runapp.c diff --git a/src/main/windows/SDL_sysmain_runapp.c b/src/main/windows/SDL_sysmain_runapp.c new file mode 100644 index 0000000000..426564e0cc --- /dev/null +++ b/src/main/windows/SDL_sysmain_runapp.c @@ -0,0 +1,99 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_internal.h" + +#ifdef SDL_PLATFORM_WIN32 + +#include "../../core/windows/SDL_windows.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 */ + +#include /* CommandLineToArgvW() */ + +/* Pop up an out of memory message, returns to Windows */ +static int OutOfMemory(void) +{ + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal Error", "Out of memory - aborting", NULL); + return -1; +} + +int MINGW32_FORCEALIGN SDL_RunApp(int _argc, char* _argv[], SDL_main_func mainFunction, void * reserved) +{ + /* Gets the arguments with GetCommandLine, converts them to argc and argv + and calls SDL_main */ + + LPWSTR *argvw; + char **argv; + int i, argc, result; + + (void)_argc; (void)_argv; (void)reserved; + + argvw = CommandLineToArgvW(GetCommandLineW(), &argc); + if (!argvw) { + return OutOfMemory(); + } + + /* Note that we need to be careful about how we allocate/free memory here. + * If the application calls SDL_SetMemoryFunctions(), we can't rely on + * SDL_free() to use the same allocator after SDL_main() returns. + */ + + /* Parse it into argv and argc */ + argv = (char **)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (argc + 1) * sizeof(*argv)); + if (!argv) { + return OutOfMemory(); + } + for (i = 0; i < argc; ++i) { + const int utf8size = WideCharToMultiByte(CP_UTF8, 0, argvw[i], -1, NULL, 0, NULL, NULL); + if (!utf8size) { // uhoh? + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal Error", "Error processing command line arguments", NULL); + return -1; + } + + argv[i] = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, utf8size); // this size includes the null-terminator character. + if (!argv[i]) { + return OutOfMemory(); + } + + if (WideCharToMultiByte(CP_UTF8, 0, argvw[i], -1, argv[i], utf8size, NULL, NULL) == 0) { // failed? uhoh! + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal Error", "Error processing command line arguments", NULL); + return -1; + } + } + argv[i] = NULL; + LocalFree(argvw); + + SDL_SetMainReady(); + + /* Run the application main() code */ + result = mainFunction(argc, argv); + + /* Free argv, to avoid memory leak */ + for (i = 0; i < argc; ++i) { + HeapFree(GetProcessHeap(), 0, argv[i]); + } + HeapFree(GetProcessHeap(), 0, argv); + + return result; +} + +#endif /* SDL_PLATFORM_WIN32 */ diff --git a/src/main/winrt/SDL_sysmain_runapp.cpp b/src/main/winrt/SDL_sysmain_runapp.cpp new file mode 100644 index 0000000000..7a6e347c74 --- /dev/null +++ b/src/main/winrt/SDL_sysmain_runapp.cpp @@ -0,0 +1,40 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_internal.h" + +#include "../../core/winrt/SDL_winrtapp_direct3d.h" +#include "../../core/winrt/SDL_winrtapp_xaml.h" + +#include + +extern "C" +int SDL_RunApp(int, char**, SDL_main_func mainFunction, void * xamlBackgroundPanel) +{ + if (xamlBackgroundPanel) { + return SDL_WinRTInitXAMLApp(mainFunction, xamlBackgroundPanel); + } else { + if (FAILED(Windows::Foundation::Initialize(RO_INIT_MULTITHREADED))) { + return 1; + } + return SDL_WinRTInitNonXAMLApp(mainFunction); + } +} +