#include "SDL_internal.h"
#include "SDL3/SDL_revision.h"
#if defined(SDL_PLATFORM_WINDOWS)
#include "core/windows/SDL_windows.h"
#else
#include <unistd.h>
#endif
#include "core/linux/SDL_dbus.h"
#ifdef SDL_PLATFORM_EMSCRIPTEN
#include <emscripten.h>
#endif
#include "SDL_assert_c.h"
#include "SDL_hints_c.h"
#include "SDL_log_c.h"
#include "SDL_properties_c.h"
#include "events/SDL_events_c.h"
#include "haptic/SDL_haptic_c.h"
#include "joystick/SDL_gamepad_c.h"
#include "joystick/SDL_joystick_c.h"
#include "sensor/SDL_sensor_c.h"
#include "stdlib/SDL_getenv_c.h"
#include "thread/SDL_thread_c.h"
#ifdef SDL_PLATFORM_ANDROID
#include "core/android/SDL_android.h"
#endif
#define SDL_INIT_EVERYTHING ~0U
#include "timer/SDL_timer_c.h"
#ifdef SDL_VIDEO_DRIVER_WINDOWS
extern bool SDL_HelperWindowCreate(void);
extern void SDL_HelperWindowDestroy(void);
#endif
#ifdef SDL_BUILD_MAJOR_VERSION
SDL_COMPILE_TIME_ASSERT(SDL_BUILD_MAJOR_VERSION,
SDL_MAJOR_VERSION == SDL_BUILD_MAJOR_VERSION);
SDL_COMPILE_TIME_ASSERT(SDL_BUILD_MINOR_VERSION,
SDL_MINOR_VERSION == SDL_BUILD_MINOR_VERSION);
SDL_COMPILE_TIME_ASSERT(SDL_BUILD_MICRO_VERSION,
SDL_MICRO_VERSION == SDL_BUILD_MICRO_VERSION);
#endif
SDL_COMPILE_TIME_ASSERT(SDL_MAJOR_VERSION_min, SDL_MAJOR_VERSION >= 0);
SDL_COMPILE_TIME_ASSERT(SDL_MAJOR_VERSION_max, SDL_MAJOR_VERSION <= 10);
SDL_COMPILE_TIME_ASSERT(SDL_MINOR_VERSION_min, SDL_MINOR_VERSION >= 0);
SDL_COMPILE_TIME_ASSERT(SDL_MINOR_VERSION_max, SDL_MINOR_VERSION <= 999);
SDL_COMPILE_TIME_ASSERT(SDL_MICRO_VERSION_min, SDL_MICRO_VERSION >= 0);
SDL_COMPILE_TIME_ASSERT(SDL_MICRO_VERSION_max, SDL_MICRO_VERSION <= 999);
extern SDL_NORETURN void SDL_ExitProcess(int exitcode);
SDL_NORETURN void SDL_ExitProcess(int exitcode)
{
#if defined(SDL_PLATFORM_WINDOWS)
TerminateProcess(GetCurrentProcess(), exitcode);
ExitProcess(exitcode);
#elif defined(SDL_PLATFORM_EMSCRIPTEN)
emscripten_cancel_main_loop();
emscripten_force_exit(exitcode);
exit(exitcode);
#elif defined(SDL_PLATFORM_HAIKU)
_exit(exitcode);
#elif defined(HAVE__EXIT)
_Exit(exitcode);
#else
_exit(exitcode);
#endif
}
bool SDL_SetAppMetadata(const char *appname, const char *appversion, const char *appidentifier)
{
SDL_SetAppMetadataProperty(SDL_PROP_APP_METADATA_NAME_STRING, appname);
SDL_SetAppMetadataProperty(SDL_PROP_APP_METADATA_VERSION_STRING, appversion);
SDL_SetAppMetadataProperty(SDL_PROP_APP_METADATA_IDENTIFIER_STRING, appidentifier);
return true;
}
static bool SDL_ValidMetadataProperty(const char *name)
{
if (!name || !*name) {
return false;
}
if (SDL_strcmp(name, SDL_PROP_APP_METADATA_NAME_STRING) == 0 ||
SDL_strcmp(name, SDL_PROP_APP_METADATA_VERSION_STRING) == 0 ||
SDL_strcmp(name, SDL_PROP_APP_METADATA_IDENTIFIER_STRING) == 0 ||
SDL_strcmp(name, SDL_PROP_APP_METADATA_CREATOR_STRING) == 0 ||
SDL_strcmp(name, SDL_PROP_APP_METADATA_COPYRIGHT_STRING) == 0 ||
SDL_strcmp(name, SDL_PROP_APP_METADATA_URL_STRING) == 0 ||
SDL_strcmp(name, SDL_PROP_APP_METADATA_TYPE_STRING) == 0) {
return true;
}
return false;
}
bool SDL_SetAppMetadataProperty(const char *name, const char *value)
{
if (!SDL_ValidMetadataProperty(name)) {
return SDL_InvalidParamError("name");
}
return SDL_SetStringProperty(SDL_GetGlobalProperties(), name, value);
}
const char *SDL_GetAppMetadataProperty(const char *name)
{
if (!SDL_ValidMetadataProperty(name)) {
SDL_InvalidParamError("name");
return NULL;
}
const char *value = NULL;
if (SDL_strcmp(name, SDL_PROP_APP_METADATA_NAME_STRING) == 0) {
value = SDL_GetHint(SDL_HINT_APP_NAME);
} else if (SDL_strcmp(name, SDL_PROP_APP_METADATA_IDENTIFIER_STRING) == 0) {
value = SDL_GetHint(SDL_HINT_APP_ID);
}
if (!value || !*value) {
value = SDL_GetStringProperty(SDL_GetGlobalProperties(), name, NULL);
}
if (!value || !*value) {
if (SDL_strcmp(name, SDL_PROP_APP_METADATA_NAME_STRING) == 0) {
value = "SDL Application";
} else if (SDL_strcmp(name, SDL_PROP_APP_METADATA_TYPE_STRING) == 0) {
value = "application";
}
}
return value;
}
#ifdef SDL_MAIN_NEEDED
static bool SDL_MainIsReady = false;
#else
static bool SDL_MainIsReady = true;
#endif
static SDL_ThreadID SDL_MainThreadID = 0;
static bool SDL_bInMainQuit = false;
static Uint8 SDL_SubsystemRefCount[32];
static void SDL_IncrementSubsystemRefCount(Uint32 subsystem)
{
const int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
SDL_assert((subsystem_index < 0) || (SDL_SubsystemRefCount[subsystem_index] < 255));
if (subsystem_index >= 0) {
++SDL_SubsystemRefCount[subsystem_index];
}
}
static void SDL_DecrementSubsystemRefCount(Uint32 subsystem)
{
const int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
if ((subsystem_index >= 0) && (SDL_SubsystemRefCount[subsystem_index] > 0)) {
if (SDL_bInMainQuit) {
SDL_SubsystemRefCount[subsystem_index] = 0;
} else {
--SDL_SubsystemRefCount[subsystem_index];
}
}
}
static bool SDL_ShouldInitSubsystem(Uint32 subsystem)
{
const int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
SDL_assert((subsystem_index < 0) || (SDL_SubsystemRefCount[subsystem_index] < 255));
return ((subsystem_index >= 0) && (SDL_SubsystemRefCount[subsystem_index] == 0));
}
static bool SDL_ShouldQuitSubsystem(Uint32 subsystem)
{
const int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
if ((subsystem_index >= 0) && (SDL_SubsystemRefCount[subsystem_index] == 0)) {
return false;
}
return (((subsystem_index >= 0) && (SDL_SubsystemRefCount[subsystem_index] == 1)) || SDL_bInMainQuit);
}
static bool SDL_InitOrIncrementSubsystem(Uint32 subsystem)
{
int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
SDL_assert((subsystem_index < 0) || (SDL_SubsystemRefCount[subsystem_index] < 255));
if (subsystem_index < 0) {
return false;
}
if (SDL_SubsystemRefCount[subsystem_index] > 0) {
++SDL_SubsystemRefCount[subsystem_index];
return true;
}
return SDL_InitSubSystem(subsystem);
}
void SDL_SetMainReady(void)
{
SDL_MainIsReady = true;
if (SDL_MainThreadID == 0) {
SDL_MainThreadID = SDL_GetCurrentThreadID();
}
}
bool SDL_IsMainThread(void)
{
if (SDL_MainThreadID == 0) {
return true;
}
if (SDL_MainThreadID == SDL_GetCurrentThreadID()) {
return true;
}
return false;
}
void SDL_InitMainThread(void)
{
static bool done_info = false;
SDL_InitTLSData();
SDL_InitEnvironment();
SDL_InitTicks();
if (!done_info) {
const char *value;
value = SDL_GetAppMetadataProperty(SDL_PROP_APP_METADATA_NAME_STRING);
SDL_LogInfo(SDL_LOG_CATEGORY_SYSTEM, "App name: %s", value ? value : "<unspecified>");
value = SDL_GetAppMetadataProperty(SDL_PROP_APP_METADATA_VERSION_STRING);
SDL_LogInfo(SDL_LOG_CATEGORY_SYSTEM, "App version: %s", value ? value : "<unspecified>");
value = SDL_GetAppMetadataProperty(SDL_PROP_APP_METADATA_IDENTIFIER_STRING);
SDL_LogInfo(SDL_LOG_CATEGORY_SYSTEM, "App ID: %s", value ? value : "<unspecified>");
SDL_LogInfo(SDL_LOG_CATEGORY_SYSTEM, "SDL revision: %s", SDL_REVISION);
done_info = true;
}
}
static void SDL_QuitMainThread(void)
{
SDL_QuitTicks();
SDL_QuitEnvironment();
SDL_QuitTLSData();
}
bool SDL_InitSubSystem(SDL_InitFlags flags)
{
Uint32 flags_initialized = 0;
if (!SDL_MainIsReady) {
return SDL_SetError("Application didn't initialize properly, did you include SDL_main.h in the file containing your main() function?");
}
SDL_InitMainThread();
#ifdef SDL_USE_LIBDBUS
SDL_DBus_Init();
#endif
#ifdef SDL_VIDEO_DRIVER_WINDOWS
if (flags & (SDL_INIT_HAPTIC | SDL_INIT_JOYSTICK)) {
if (!SDL_HelperWindowCreate()) {
goto quit_and_error;
}
}
#endif
if (flags & SDL_INIT_EVENTS) {
if (SDL_ShouldInitSubsystem(SDL_INIT_EVENTS)) {
SDL_IncrementSubsystemRefCount(SDL_INIT_EVENTS);
if (!SDL_InitEvents()) {
SDL_DecrementSubsystemRefCount(SDL_INIT_EVENTS);
goto quit_and_error;
}
} else {
SDL_IncrementSubsystemRefCount(SDL_INIT_EVENTS);
}
flags_initialized |= SDL_INIT_EVENTS;
}
if (flags & SDL_INIT_VIDEO) {
#ifndef SDL_VIDEO_DISABLED
if (SDL_ShouldInitSubsystem(SDL_INIT_VIDEO)) {
if (!SDL_InitOrIncrementSubsystem(SDL_INIT_EVENTS)) {
goto quit_and_error;
}
SDL_MainThreadID = SDL_GetCurrentThreadID();
SDL_IncrementSubsystemRefCount(SDL_INIT_VIDEO);
if (!SDL_VideoInit(NULL)) {
SDL_DecrementSubsystemRefCount(SDL_INIT_VIDEO);
SDL_PushError();
SDL_QuitSubSystem(SDL_INIT_EVENTS);
SDL_PopError();
goto quit_and_error;
}
} else {
SDL_IncrementSubsystemRefCount(SDL_INIT_VIDEO);
}
flags_initialized |= SDL_INIT_VIDEO;
#else
SDL_SetError("SDL not built with video support");
goto quit_and_error;
#endif
}
if (flags & SDL_INIT_AUDIO) {
#ifndef SDL_AUDIO_DISABLED
if (SDL_ShouldInitSubsystem(SDL_INIT_AUDIO)) {
if (!SDL_InitOrIncrementSubsystem(SDL_INIT_EVENTS)) {
goto quit_and_error;
}
SDL_IncrementSubsystemRefCount(SDL_INIT_AUDIO);
if (!SDL_InitAudio(NULL)) {
SDL_DecrementSubsystemRefCount(SDL_INIT_AUDIO);
SDL_PushError();
SDL_QuitSubSystem(SDL_INIT_EVENTS);
SDL_PopError();
goto quit_and_error;
}
} else {
SDL_IncrementSubsystemRefCount(SDL_INIT_AUDIO);
}
flags_initialized |= SDL_INIT_AUDIO;
#else
SDL_SetError("SDL not built with audio support");
goto quit_and_error;
#endif
}
if (flags & SDL_INIT_JOYSTICK) {
#ifndef SDL_JOYSTICK_DISABLED
if (SDL_ShouldInitSubsystem(SDL_INIT_JOYSTICK)) {
if (!SDL_InitOrIncrementSubsystem(SDL_INIT_EVENTS)) {
goto quit_and_error;
}
SDL_IncrementSubsystemRefCount(SDL_INIT_JOYSTICK);
if (!SDL_InitJoysticks()) {
SDL_DecrementSubsystemRefCount(SDL_INIT_JOYSTICK);
SDL_PushError();
SDL_QuitSubSystem(SDL_INIT_EVENTS);
SDL_PopError();
goto quit_and_error;
}
} else {
SDL_IncrementSubsystemRefCount(SDL_INIT_JOYSTICK);
}
flags_initialized |= SDL_INIT_JOYSTICK;
#else
SDL_SetError("SDL not built with joystick support");
goto quit_and_error;
#endif
}
if (flags & SDL_INIT_GAMEPAD) {
#ifndef SDL_JOYSTICK_DISABLED
if (SDL_ShouldInitSubsystem(SDL_INIT_GAMEPAD)) {
if (!SDL_InitOrIncrementSubsystem(SDL_INIT_JOYSTICK)) {
goto quit_and_error;
}
SDL_IncrementSubsystemRefCount(SDL_INIT_GAMEPAD);
if (!SDL_InitGamepads()) {
SDL_DecrementSubsystemRefCount(SDL_INIT_GAMEPAD);
SDL_PushError();
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
SDL_PopError();
goto quit_and_error;
}
} else {
SDL_IncrementSubsystemRefCount(SDL_INIT_GAMEPAD);
}
flags_initialized |= SDL_INIT_GAMEPAD;
#else
SDL_SetError("SDL not built with joystick support");
goto quit_and_error;
#endif
}
if (flags & SDL_INIT_HAPTIC) {
#ifndef SDL_HAPTIC_DISABLED
if (SDL_ShouldInitSubsystem(SDL_INIT_HAPTIC)) {
SDL_IncrementSubsystemRefCount(SDL_INIT_HAPTIC);
if (!SDL_InitHaptics()) {
SDL_DecrementSubsystemRefCount(SDL_INIT_HAPTIC);
goto quit_and_error;
}
} else {
SDL_IncrementSubsystemRefCount(SDL_INIT_HAPTIC);
}
flags_initialized |= SDL_INIT_HAPTIC;
#else
SDL_SetError("SDL not built with haptic (force feedback) support");
goto quit_and_error;
#endif
}
if (flags & SDL_INIT_SENSOR) {
#ifndef SDL_SENSOR_DISABLED
if (SDL_ShouldInitSubsystem(SDL_INIT_SENSOR)) {
SDL_IncrementSubsystemRefCount(SDL_INIT_SENSOR);
if (!SDL_InitSensors()) {
SDL_DecrementSubsystemRefCount(SDL_INIT_SENSOR);
goto quit_and_error;
}
} else {
SDL_IncrementSubsystemRefCount(SDL_INIT_SENSOR);
}
flags_initialized |= SDL_INIT_SENSOR;
#else
SDL_SetError("SDL not built with sensor support");
goto quit_and_error;
#endif
}
if (flags & SDL_INIT_CAMERA) {
#ifndef SDL_CAMERA_DISABLED
if (SDL_ShouldInitSubsystem(SDL_INIT_CAMERA)) {
if (!SDL_InitOrIncrementSubsystem(SDL_INIT_EVENTS)) {
goto quit_and_error;
}
SDL_IncrementSubsystemRefCount(SDL_INIT_CAMERA);
if (!SDL_CameraInit(NULL)) {
SDL_DecrementSubsystemRefCount(SDL_INIT_CAMERA);
SDL_PushError();
SDL_QuitSubSystem(SDL_INIT_EVENTS);
SDL_PopError();
goto quit_and_error;
}
} else {
SDL_IncrementSubsystemRefCount(SDL_INIT_CAMERA);
}
flags_initialized |= SDL_INIT_CAMERA;
#else
SDL_SetError("SDL not built with camera support");
goto quit_and_error;
#endif
}
(void)flags_initialized;
return SDL_ClearError();
quit_and_error:
{
SDL_PushError();
SDL_QuitSubSystem(flags_initialized);
SDL_PopError();
}
return false;
}
bool SDL_Init(SDL_InitFlags flags)
{
return SDL_InitSubSystem(flags);
}
void SDL_QuitSubSystem(SDL_InitFlags flags)
{
#ifndef SDL_CAMERA_DISABLED
if (flags & SDL_INIT_CAMERA) {
if (SDL_ShouldQuitSubsystem(SDL_INIT_CAMERA)) {
SDL_QuitCamera();
SDL_QuitSubSystem(SDL_INIT_EVENTS);
}
SDL_DecrementSubsystemRefCount(SDL_INIT_CAMERA);
}
#endif
#ifndef SDL_SENSOR_DISABLED
if (flags & SDL_INIT_SENSOR) {
if (SDL_ShouldQuitSubsystem(SDL_INIT_SENSOR)) {
SDL_QuitSensors();
}
SDL_DecrementSubsystemRefCount(SDL_INIT_SENSOR);
}
#endif
#ifndef SDL_JOYSTICK_DISABLED
if (flags & SDL_INIT_GAMEPAD) {
if (SDL_ShouldQuitSubsystem(SDL_INIT_GAMEPAD)) {
SDL_QuitGamepads();
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
}
SDL_DecrementSubsystemRefCount(SDL_INIT_GAMEPAD);
}
if (flags & SDL_INIT_JOYSTICK) {
if (SDL_ShouldQuitSubsystem(SDL_INIT_JOYSTICK)) {
SDL_QuitJoysticks();
SDL_QuitSubSystem(SDL_INIT_EVENTS);
}
SDL_DecrementSubsystemRefCount(SDL_INIT_JOYSTICK);
}
#endif
#ifndef SDL_HAPTIC_DISABLED
if (flags & SDL_INIT_HAPTIC) {
if (SDL_ShouldQuitSubsystem(SDL_INIT_HAPTIC)) {
SDL_QuitHaptics();
}
SDL_DecrementSubsystemRefCount(SDL_INIT_HAPTIC);
}
#endif
#ifndef SDL_AUDIO_DISABLED
if (flags & SDL_INIT_AUDIO) {
if (SDL_ShouldQuitSubsystem(SDL_INIT_AUDIO)) {
SDL_QuitAudio();
SDL_QuitSubSystem(SDL_INIT_EVENTS);
}
SDL_DecrementSubsystemRefCount(SDL_INIT_AUDIO);
}
#endif
#ifndef SDL_VIDEO_DISABLED
if (flags & SDL_INIT_VIDEO) {
if (SDL_ShouldQuitSubsystem(SDL_INIT_VIDEO)) {
SDL_QuitRender();
SDL_VideoQuit();
SDL_QuitSubSystem(SDL_INIT_EVENTS);
}
SDL_DecrementSubsystemRefCount(SDL_INIT_VIDEO);
}
#endif
if (flags & SDL_INIT_EVENTS) {
if (SDL_ShouldQuitSubsystem(SDL_INIT_EVENTS)) {
SDL_QuitEvents();
}
SDL_DecrementSubsystemRefCount(SDL_INIT_EVENTS);
}
}
Uint32 SDL_WasInit(SDL_InitFlags flags)
{
int i;
int num_subsystems = SDL_arraysize(SDL_SubsystemRefCount);
Uint32 initialized = 0;
if (SDL_HasExactlyOneBitSet32(flags)) {
int subsystem_index = SDL_MostSignificantBitIndex32(flags);
return SDL_SubsystemRefCount[subsystem_index] ? flags : 0;
}
if (!flags) {
flags = SDL_INIT_EVERYTHING;
}
num_subsystems = SDL_min(num_subsystems, SDL_MostSignificantBitIndex32(flags) + 1);
for (i = 0; i < num_subsystems; ++i) {
if ((flags & 1) && SDL_SubsystemRefCount[i] > 0) {
initialized |= (1 << i);
}
flags >>= 1;
}
return initialized;
}
void SDL_Quit(void)
{
SDL_bInMainQuit = true;
#ifdef SDL_VIDEO_DRIVER_WINDOWS
SDL_HelperWindowDestroy();
#endif
SDL_QuitSubSystem(SDL_INIT_EVERYTHING);
#ifdef SDL_USE_LIBDBUS
SDL_DBus_Quit();
#endif
SDL_QuitTimers();
SDL_SetObjectsInvalid();
SDL_AssertionsQuit();
SDL_memset(SDL_SubsystemRefCount, 0x0, sizeof(SDL_SubsystemRefCount));
SDL_QuitLog();
SDL_QuitHints();
SDL_QuitProperties();
SDL_QuitMainThread();
SDL_bInMainQuit = false;
}
int SDL_GetVersion(void)
{
return SDL_VERSION;
}
const char *SDL_GetRevision(void)
{
return SDL_REVISION;
}
const char *SDL_GetPlatform(void)
{
#if defined(SDL_PLATFORM_PRIVATE)
return SDL_PLATFORM_PRIVATE_NAME;
#elif defined(SDL_PLATFORM_AIX)
return "AIX";
#elif defined(SDL_PLATFORM_ANDROID)
return "Android";
#elif defined(SDL_PLATFORM_BSDI)
return "BSDI";
#elif defined(SDL_PLATFORM_EMSCRIPTEN)
return "Emscripten";
#elif defined(SDL_PLATFORM_FREEBSD)
return "FreeBSD";
#elif defined(SDL_PLATFORM_HAIKU)
return "Haiku";
#elif defined(SDL_PLATFORM_HPUX)
return "HP-UX";
#elif defined(SDL_PLATFORM_IRIX)
return "Irix";
#elif defined(SDL_PLATFORM_LINUX)
return "Linux";
#elif defined(__MINT__)
return "Atari MiNT";
#elif defined(SDL_PLATFORM_MACOS)
return "macOS";
#elif defined(SDL_PLATFORM_NETBSD)
return "NetBSD";
#elif defined(SDL_PLATFORM_OPENBSD)
return "OpenBSD";
#elif defined(SDL_PLATFORM_OS2)
return "OS/2";
#elif defined(SDL_PLATFORM_OSF)
return "OSF/1";
#elif defined(SDL_PLATFORM_QNXNTO)
return "QNX Neutrino";
#elif defined(SDL_PLATFORM_RISCOS)
return "RISC OS";
#elif defined(SDL_PLATFORM_SOLARIS)
return "Solaris";
#elif defined(SDL_PLATFORM_WIN32)
return "Windows";
#elif defined(SDL_PLATFORM_WINGDK)
return "WinGDK";
#elif defined(SDL_PLATFORM_XBOXONE)
return "Xbox One";
#elif defined(SDL_PLATFORM_XBOXSERIES)
return "Xbox Series X|S";
#elif defined(SDL_PLATFORM_IOS)
return "iOS";
#elif defined(SDL_PLATFORM_TVOS)
return "tvOS";
#elif defined(SDL_PLATFORM_PS2)
return "PlayStation 2";
#elif defined(SDL_PLATFORM_PSP)
return "PlayStation Portable";
#elif defined(SDL_PLATFORM_VITA)
return "PlayStation Vita";
#elif defined(SDL_PLATFORM_3DS)
return "Nintendo 3DS";
#elif defined(__managarm__)
return "Managarm";
#else
return "Unknown (see SDL_platform.h)";
#endif
}
bool SDL_IsTablet(void)
{
#ifdef SDL_PLATFORM_ANDROID
return SDL_IsAndroidTablet();
#elif defined(SDL_PLATFORM_IOS)
extern bool SDL_IsIPad(void);
return SDL_IsIPad();
#else
return false;
#endif
}
bool SDL_IsTV(void)
{
#ifdef SDL_PLATFORM_ANDROID
return SDL_IsAndroidTV();
#elif defined(SDL_PLATFORM_IOS)
extern bool SDL_IsAppleTV(void);
return SDL_IsAppleTV();
#else
return false;
#endif
}
static SDL_Sandbox SDL_DetectSandbox(void)
{
#if defined(SDL_PLATFORM_LINUX)
if (access("/.flatpak-info", F_OK) == 0) {
return SDL_SANDBOX_FLATPAK;
}
if (SDL_getenv("SNAP") && SDL_getenv("SNAP_NAME") && SDL_getenv("SNAP_REVISION")) {
return SDL_SANDBOX_SNAP;
}
if (access("/run/host/container-manager", F_OK) == 0) {
return SDL_SANDBOX_UNKNOWN_CONTAINER;
}
#elif defined(SDL_PLATFORM_MACOS)
if (SDL_getenv("APP_SANDBOX_CONTAINER_ID")) {
return SDL_SANDBOX_MACOS;
}
#endif
return SDL_SANDBOX_NONE;
}
SDL_Sandbox SDL_GetSandbox(void)
{
static SDL_Sandbox sandbox;
static bool sandbox_initialized;
if (!sandbox_initialized) {
sandbox = SDL_DetectSandbox();
sandbox_initialized = true;
}
return sandbox;
}
#ifdef SDL_PLATFORM_WIN32
#if (!defined(HAVE_LIBC) || defined(__WATCOMC__)) && !defined(SDL_STATIC_LIB)
BOOL APIENTRY MINGW32_FORCEALIGN _DllMainCRTStartup(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
#endif
#endif