| | |
| | | /* |
| | | Simple DirectMedia Layer |
| | | Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org> |
| | | Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org> |
| | | |
| | | This software is provided 'as-is', without any express or implied |
| | | warranty. In no event will the authors be held liable for any damages |
| | |
| | | |
| | | #if defined(__WIN32__) |
| | | #include "core/windows/SDL_windows.h" |
| | | #elif defined(__OS2__) |
| | | #include <stdlib.h> /* For _exit() */ |
| | | #elif !defined(__WINRT__) |
| | | #include <unistd.h> /* For _exit(), etc. */ |
| | | #endif |
| | | #if defined(__OS2__) |
| | | #include "core/os2/SDL_os2.h" |
| | | #endif |
| | | #if SDL_THREAD_OS2 |
| | | #include "thread/os2/SDL_systls_c.h" |
| | | #endif |
| | | |
| | | #if defined(__EMSCRIPTEN__) |
| | | #include <emscripten.h> |
| | | #endif |
| | | |
| | | /* Initialization code for SDL */ |
| | |
| | | #include "events/SDL_events_c.h" |
| | | #include "haptic/SDL_haptic_c.h" |
| | | #include "joystick/SDL_joystick_c.h" |
| | | #include "sensor/SDL_sensor_c.h" |
| | | |
| | | /* Initialization/Cleanup routines */ |
| | | #if !SDL_TIMERS_DISABLED |
| | | extern int SDL_TimerInit(void); |
| | | extern void SDL_TimerQuit(void); |
| | | extern void SDL_TicksInit(void); |
| | | extern void SDL_TicksQuit(void); |
| | | # include "timer/SDL_timer_c.h" |
| | | #endif |
| | | #if SDL_VIDEO_DRIVER_WINDOWS |
| | | extern int SDL_HelperWindowCreate(void); |
| | | extern int SDL_HelperWindowDestroy(void); |
| | | #endif |
| | | |
| | | |
| | | /* This is not declared in any header, although it is shared between some |
| | | parts of SDL, because we don't want anything calling it without an |
| | | extremely good reason. */ |
| | | extern SDL_NORETURN void SDL_ExitProcess(int exitcode); |
| | | SDL_NORETURN void SDL_ExitProcess(int exitcode) |
| | | { |
| | | #ifdef __WIN32__ |
| | | /* "if you do not know the state of all threads in your process, it is |
| | | better to call TerminateProcess than ExitProcess" |
| | | https://msdn.microsoft.com/en-us/library/windows/desktop/ms682658(v=vs.85).aspx */ |
| | | TerminateProcess(GetCurrentProcess(), exitcode); |
| | | /* MingW doesn't have TerminateProcess marked as noreturn, so add an |
| | | ExitProcess here that will never be reached but make MingW happy. */ |
| | | ExitProcess(exitcode); |
| | | #elif defined(__EMSCRIPTEN__) |
| | | emscripten_cancel_main_loop(); /* this should "kill" the app. */ |
| | | emscripten_force_exit(exitcode); /* this should "kill" the app. */ |
| | | exit(exitcode); |
| | | #elif defined(__HAIKU__) /* Haiku has _Exit, but it's not marked noreturn. */ |
| | | _exit(exitcode); |
| | | #elif defined(HAVE__EXIT) /* Upper case _Exit() */ |
| | | _Exit(exitcode); |
| | | #else |
| | | _exit(exitcode); |
| | | #endif |
| | | } |
| | | |
| | | |
| | | /* The initialized subsystems */ |
| | |
| | | { |
| | | int subsystem_index = SDL_MostSignificantBitIndex32(subsystem); |
| | | SDL_assert(SDL_SubsystemRefCount[subsystem_index] < 255); |
| | | return (SDL_SubsystemRefCount[subsystem_index] == 0); |
| | | return (SDL_SubsystemRefCount[subsystem_index] == 0) ? SDL_TRUE : SDL_FALSE; |
| | | } |
| | | |
| | | /* Private helper to check if a system needs to be quit. */ |
| | |
| | | /* If we're in SDL_Quit, we shut down every subsystem, even if refcount |
| | | * isn't zero. |
| | | */ |
| | | return SDL_SubsystemRefCount[subsystem_index] == 1 || SDL_bInMainQuit; |
| | | return (SDL_SubsystemRefCount[subsystem_index] == 1 || SDL_bInMainQuit) ? SDL_TRUE : SDL_FALSE; |
| | | } |
| | | |
| | | void |
| | |
| | | flags |= SDL_INIT_EVENTS; |
| | | } |
| | | |
| | | #if SDL_THREAD_OS2 |
| | | SDL_OS2TLSAlloc(); /* thread/os2/SDL_systls.c */ |
| | | #endif |
| | | |
| | | #if SDL_VIDEO_DRIVER_WINDOWS |
| | | if ((flags & (SDL_INIT_HAPTIC|SDL_INIT_JOYSTICK))) { |
| | | if (SDL_HelperWindowCreate() < 0) { |
| | | return -1; |
| | | } |
| | | } |
| | | if ((flags & (SDL_INIT_HAPTIC|SDL_INIT_JOYSTICK))) { |
| | | if (SDL_HelperWindowCreate() < 0) { |
| | | return -1; |
| | | } |
| | | } |
| | | #endif |
| | | |
| | | #if !SDL_TIMERS_DISABLED |
| | |
| | | if ((flags & SDL_INIT_EVENTS)) { |
| | | #if !SDL_EVENTS_DISABLED |
| | | if (SDL_PrivateShouldInitSubsystem(SDL_INIT_EVENTS)) { |
| | | if (SDL_StartEventLoop() < 0) { |
| | | if (SDL_EventsInit() < 0) { |
| | | return (-1); |
| | | } |
| | | SDL_QuitInit(); |
| | | } |
| | | SDL_PrivateSubsystemRefCountIncr(SDL_INIT_EVENTS); |
| | | #else |
| | |
| | | #endif |
| | | } |
| | | |
| | | /* Initialize the sensor subsystem */ |
| | | if ((flags & SDL_INIT_SENSOR)){ |
| | | #if !SDL_SENSOR_DISABLED |
| | | if (SDL_PrivateShouldInitSubsystem(SDL_INIT_SENSOR)) { |
| | | if (SDL_SensorInit() < 0) { |
| | | return (-1); |
| | | } |
| | | } |
| | | SDL_PrivateSubsystemRefCountIncr(SDL_INIT_SENSOR); |
| | | #else |
| | | return SDL_SetError("SDL not built with sensor support"); |
| | | #endif |
| | | } |
| | | |
| | | return (0); |
| | | } |
| | | |
| | |
| | | void |
| | | SDL_QuitSubSystem(Uint32 flags) |
| | | { |
| | | #if SDL_THREAD_OS2 |
| | | SDL_OS2TLSFree(); /* thread/os2/SDL_systls.c */ |
| | | #endif |
| | | #if defined(__OS2__) |
| | | SDL_OS2Quit(); |
| | | #endif |
| | | |
| | | /* Shut down requested initialized subsystems */ |
| | | #if !SDL_SENSOR_DISABLED |
| | | if ((flags & SDL_INIT_SENSOR)) { |
| | | if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_SENSOR)) { |
| | | SDL_SensorQuit(); |
| | | } |
| | | SDL_PrivateSubsystemRefCountDecr(SDL_INIT_SENSOR); |
| | | } |
| | | #endif |
| | | |
| | | #if !SDL_JOYSTICK_DISABLED |
| | | if ((flags & SDL_INIT_GAMECONTROLLER)) { |
| | | /* game controller implies joystick */ |
| | |
| | | #if !SDL_EVENTS_DISABLED |
| | | if ((flags & SDL_INIT_EVENTS)) { |
| | | if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_EVENTS)) { |
| | | SDL_QuitQuit(); |
| | | SDL_StopEventLoop(); |
| | | SDL_EventsQuit(); |
| | | } |
| | | SDL_PrivateSubsystemRefCountDecr(SDL_INIT_EVENTS); |
| | | } |
| | |
| | | int i; |
| | | int num_subsystems = SDL_arraysize(SDL_SubsystemRefCount); |
| | | Uint32 initialized = 0; |
| | | |
| | | /* Fast path for checking one flag */ |
| | | if (SDL_HasExactlyOneBitSet32(flags)) { |
| | | int subsystem_index = SDL_MostSignificantBitIndex32(flags); |
| | | return SDL_SubsystemRefCount[subsystem_index] ? flags : 0; |
| | | } |
| | | |
| | | if (!flags) { |
| | | flags = SDL_INIT_EVERYTHING; |
| | |
| | | #endif |
| | | } |
| | | |
| | | SDL_bool |
| | | SDL_IsTablet() |
| | | { |
| | | #if __ANDROID__ |
| | | extern SDL_bool SDL_IsAndroidTablet(void); |
| | | return SDL_IsAndroidTablet(); |
| | | #elif __IPHONEOS__ |
| | | extern SDL_bool SDL_IsIPad(void); |
| | | return SDL_IsIPad(); |
| | | #else |
| | | return SDL_FALSE; |
| | | #endif |
| | | } |
| | | |
| | | #if defined(__WIN32__) |
| | | |
| | | #if !defined(HAVE_LIBC) || (defined(__WATCOMC__) && defined(BUILD_DLL)) |
| | | #if (!defined(HAVE_LIBC) || defined(__WATCOMC__)) && !defined(SDL_STATIC_LIB) |
| | | /* Need to include DllMain() on Watcom C for some reason.. */ |
| | | |
| | | BOOL APIENTRY |
| | |
| | | } |
| | | return TRUE; |
| | | } |
| | | #endif /* building DLL with Watcom C */ |
| | | #endif /* Building DLL */ |
| | | |
| | | #endif /* __WIN32__ */ |
| | | |