SDL.c
Go to the documentation of this file.
/*
Simple DirectMedia Layer
Copyright (C) 1997-2019 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
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"
#if defined(__WIN32__)
#include "core/windows/SDL_windows.h"
#endif
/* Initialization code for SDL */
#include "SDL.h"
#include "SDL_bits.h"
#include "SDL_revision.h"
#include "SDL_assert_c.h"
#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
# include "timer/SDL_timer_c.h"
#endif
#if SDL_VIDEO_DRIVER_WINDOWS
extern int SDL_HelperWindowCreate(void);
extern int SDL_HelperWindowDestroy(void);
#endif
/* The initialized subsystems */
#ifdef SDL_MAIN_NEEDED
static SDL_bool SDL_MainIsReady = SDL_FALSE;
#else
static SDL_bool SDL_MainIsReady = SDL_TRUE;
#endif
static SDL_bool SDL_bInMainQuit = SDL_FALSE;
static Uint8 SDL_SubsystemRefCount[ 32 ];
/* Private helper to increment a subsystem's ref counter. */
static void
SDL_PrivateSubsystemRefCountIncr(Uint32 subsystem)
{
int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
SDL_assert(SDL_SubsystemRefCount[subsystem_index] < 255);
++SDL_SubsystemRefCount[subsystem_index];
}
/* Private helper to decrement a subsystem's ref counter. */
static void
SDL_PrivateSubsystemRefCountDecr(Uint32 subsystem)
{
int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
if (SDL_SubsystemRefCount[subsystem_index] > 0) {
--SDL_SubsystemRefCount[subsystem_index];
}
}
/* Private helper to check if a system needs init. */
static SDL_bool
SDL_PrivateShouldInitSubsystem(Uint32 subsystem)
{
int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
SDL_assert(SDL_SubsystemRefCount[subsystem_index] < 255);
return (SDL_SubsystemRefCount[subsystem_index] == 0) ? SDL_TRUE : SDL_FALSE;
}
/* Private helper to check if a system needs to be quit. */
static SDL_bool
SDL_PrivateShouldQuitSubsystem(Uint32 subsystem) {
int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
if (SDL_SubsystemRefCount[subsystem_index] == 0) {
return SDL_FALSE;
}
/* 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) ? SDL_TRUE : SDL_FALSE;
}
void
SDL_SetMainReady(void)
{
SDL_MainIsReady = SDL_TRUE;
}
int
SDL_InitSubSystem(Uint32 flags)
{
if (!SDL_MainIsReady) {
SDL_SetError("Application didn't initialize properly, did you include SDL_main.h in the file containing your main() function?");
return -1;
}
/* Clear the error message */
SDL_ClearError();
if ((flags & SDL_INIT_GAMECONTROLLER)) {
/* game controller implies joystick */
flags |= SDL_INIT_JOYSTICK;
}
if ((flags & (SDL_INIT_VIDEO|SDL_INIT_JOYSTICK))) {
/* video or joystick implies events */
flags |= SDL_INIT_EVENTS;
}
#if SDL_VIDEO_DRIVER_WINDOWS
if ((flags & (SDL_INIT_HAPTIC|SDL_INIT_JOYSTICK))) {
if (SDL_HelperWindowCreate() < 0) {
return -1;
}
}
#endif
#if !SDL_TIMERS_DISABLED
SDL_TicksInit();
#endif
/* Initialize the event subsystem */
if ((flags & SDL_INIT_EVENTS)) {
#if !SDL_EVENTS_DISABLED
if (SDL_PrivateShouldInitSubsystem(SDL_INIT_EVENTS)) {
if (SDL_EventsInit() < 0) {
return (-1);
}
}
SDL_PrivateSubsystemRefCountIncr(SDL_INIT_EVENTS);
#else
return SDL_SetError("SDL not built with events support");
#endif
}
/* Initialize the timer subsystem */
if ((flags & SDL_INIT_TIMER)){
#if !SDL_TIMERS_DISABLED
if (SDL_PrivateShouldInitSubsystem(SDL_INIT_TIMER)) {
if (SDL_TimerInit() < 0) {
return (-1);
}
}
SDL_PrivateSubsystemRefCountIncr(SDL_INIT_TIMER);
#else
return SDL_SetError("SDL not built with timer support");
#endif
}
/* Initialize the video subsystem */
if ((flags & SDL_INIT_VIDEO)){
#if !SDL_VIDEO_DISABLED
if (SDL_PrivateShouldInitSubsystem(SDL_INIT_VIDEO)) {
if (SDL_VideoInit(NULL) < 0) {
return (-1);
}
}
SDL_PrivateSubsystemRefCountIncr(SDL_INIT_VIDEO);
#else
return SDL_SetError("SDL not built with video support");
#endif
}
/* Initialize the audio subsystem */
if ((flags & SDL_INIT_AUDIO)){
#if !SDL_AUDIO_DISABLED
if (SDL_PrivateShouldInitSubsystem(SDL_INIT_AUDIO)) {
if (SDL_AudioInit(NULL) < 0) {
return (-1);
}
}
SDL_PrivateSubsystemRefCountIncr(SDL_INIT_AUDIO);
#else
return SDL_SetError("SDL not built with audio support");
#endif
}
/* Initialize the joystick subsystem */
if ((flags & SDL_INIT_JOYSTICK)){
#if !SDL_JOYSTICK_DISABLED
if (SDL_PrivateShouldInitSubsystem(SDL_INIT_JOYSTICK)) {
if (SDL_JoystickInit() < 0) {
return (-1);
}
}
SDL_PrivateSubsystemRefCountIncr(SDL_INIT_JOYSTICK);
#else
return SDL_SetError("SDL not built with joystick support");
#endif
}
if ((flags & SDL_INIT_GAMECONTROLLER)){
#if !SDL_JOYSTICK_DISABLED
if (SDL_PrivateShouldInitSubsystem(SDL_INIT_GAMECONTROLLER)) {
if (SDL_GameControllerInit() < 0) {
return (-1);
}
}
SDL_PrivateSubsystemRefCountIncr(SDL_INIT_GAMECONTROLLER);
#else
return SDL_SetError("SDL not built with joystick support");
#endif
}
/* Initialize the haptic subsystem */
if ((flags & SDL_INIT_HAPTIC)){
#if !SDL_HAPTIC_DISABLED
if (SDL_PrivateShouldInitSubsystem(SDL_INIT_HAPTIC)) {
if (SDL_HapticInit() < 0) {
return (-1);
}
}
SDL_PrivateSubsystemRefCountIncr(SDL_INIT_HAPTIC);
#else
return SDL_SetError("SDL not built with haptic (force feedback) support");
#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);
}
int
SDL_Init(Uint32 flags)
{
return SDL_InitSubSystem(flags);
}
void
SDL_QuitSubSystem(Uint32 flags)
{
/* 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 */
flags |= SDL_INIT_JOYSTICK;
if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_GAMECONTROLLER)) {
SDL_GameControllerQuit();
}
SDL_PrivateSubsystemRefCountDecr(SDL_INIT_GAMECONTROLLER);
}
if ((flags & SDL_INIT_JOYSTICK)) {
/* joystick implies events */
flags |= SDL_INIT_EVENTS;
if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_JOYSTICK)) {
SDL_JoystickQuit();
}
SDL_PrivateSubsystemRefCountDecr(SDL_INIT_JOYSTICK);
}
#endif
#if !SDL_HAPTIC_DISABLED
if ((flags & SDL_INIT_HAPTIC)) {
if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_HAPTIC)) {
SDL_HapticQuit();
}
SDL_PrivateSubsystemRefCountDecr(SDL_INIT_HAPTIC);
}
#endif
#if !SDL_AUDIO_DISABLED
if ((flags & SDL_INIT_AUDIO)) {
if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_AUDIO)) {
SDL_AudioQuit();
}
SDL_PrivateSubsystemRefCountDecr(SDL_INIT_AUDIO);
}
#endif
#if !SDL_VIDEO_DISABLED
if ((flags & SDL_INIT_VIDEO)) {
/* video implies events */
flags |= SDL_INIT_EVENTS;
if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_VIDEO)) {
SDL_VideoQuit();
}
SDL_PrivateSubsystemRefCountDecr(SDL_INIT_VIDEO);
}
#endif
#if !SDL_TIMERS_DISABLED
if ((flags & SDL_INIT_TIMER)) {
if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_TIMER)) {
SDL_TimerQuit();
}
SDL_PrivateSubsystemRefCountDecr(SDL_INIT_TIMER);
}
#endif
#if !SDL_EVENTS_DISABLED
if ((flags & SDL_INIT_EVENTS)) {
if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_EVENTS)) {
SDL_EventsQuit();
}
SDL_PrivateSubsystemRefCountDecr(SDL_INIT_EVENTS);
}
#endif
}
Uint32
SDL_WasInit(Uint32 flags)
{
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;
}
num_subsystems = SDL_min(num_subsystems, SDL_MostSignificantBitIndex32(flags) + 1);
/* Iterate over each bit in flags, and check the matching subsystem. */
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 = SDL_TRUE;
/* Quit all subsystems */
#if SDL_VIDEO_DRIVER_WINDOWS
SDL_HelperWindowDestroy();
#endif
SDL_QuitSubSystem(SDL_INIT_EVERYTHING);
#if !SDL_TIMERS_DISABLED
SDL_TicksQuit();
#endif
SDL_ClearHints();
SDL_AssertionsQuit();
SDL_LogResetPriorities();
/* Now that every subsystem has been quit, we reset the subsystem refcount
* and the list of initialized subsystems.
*/
SDL_memset( SDL_SubsystemRefCount, 0x0, sizeof(SDL_SubsystemRefCount) );
SDL_bInMainQuit = SDL_FALSE;
}
/* Get the library version number */
void
SDL_GetVersion(SDL_version * ver)
{
SDL_VERSION(ver);
}
/* Get the library source revision */
const char *
SDL_GetRevision(void)
{
return SDL_REVISION;
}
/* Get the library source revision number */
int
SDL_GetRevisionNumber(void)
{
return SDL_REVISION_NUMBER;
}
/* Get the name of the platform */
const char *
SDL_GetPlatform()
{
#if __AIX__
return "AIX";
#elif __ANDROID__
return "Android";
#elif __BSDI__
return "BSDI";
#elif __DREAMCAST__
return "Dreamcast";
#elif __EMSCRIPTEN__
return "Emscripten";
#elif __FREEBSD__
return "FreeBSD";
#elif __HAIKU__
return "Haiku";
#elif __HPUX__
return "HP-UX";
#elif __IRIX__
return "Irix";
#elif __LINUX__
return "Linux";
#elif __MINT__
return "Atari MiNT";
#elif __MACOS__
return "MacOS Classic";
#elif __MACOSX__
return "Mac OS X";
#elif __NACL__
return "NaCl";
#elif __NETBSD__
return "NetBSD";
#elif __OPENBSD__
return "OpenBSD";
#elif __OS2__
return "OS/2";
#elif __OSF__
return "OSF/1";
#elif __QNXNTO__
return "QNX Neutrino";
#elif __RISCOS__
return "RISC OS";
#elif __SOLARIS__
return "Solaris";
#elif __WIN32__
return "Windows";
#elif __WINRT__
return "WinRT";
#elif __TVOS__
return "tvOS";
#elif __IPHONEOS__
return "iOS";
#elif __PSP__
return "PlayStation Portable";
#else
return "Unknown (see SDL_platform.h)";
#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(SDL_STATIC_LIB)
/* Need to include DllMain() on Watcom C for some reason.. */
BOOL APIENTRY
_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 /* Building DLL */
#endif /* __WIN32__ */
/* vi: set sts=4 ts=4 sw=4 expandtab: */
SDL.h
SDL_memset
#define SDL_memset
Definition: SDL_dynapi_overrides.h:386
SDL_GetRevision
const char * SDL_GetRevision(void)
Get the code revision of SDL that is linked against your program.
Definition: SDL.c:409
Uint32
uint32_t Uint32
Definition: SDL_stdinc.h:203
SDL_GetPlatform
const char * SDL_GetPlatform()
Gets the name of the platform.
Definition: SDL.c:423
SDL_GetRevisionNumber
int SDL_GetRevisionNumber(void)
Get the revision number of SDL that is linked against your program.
Definition: SDL.c:416
SDL_AudioInit
#define SDL_AudioInit
Definition: SDL_dynapi_overrides.h:75
SDL_PrivateShouldInitSubsystem
static SDL_bool SDL_PrivateShouldInitSubsystem(Uint32 subsystem)
Definition: SDL.c:78
SDL_TimerQuit
void SDL_TimerQuit(void)
Definition: SDL_timer.c:239
SDL_ClearError
#define SDL_ClearError
Definition: SDL_dynapi_overrides.h:114
SDL_HapticQuit
void SDL_HapticQuit(void)
Definition: SDL_haptic.c:394
SDL_PrivateSubsystemRefCountIncr
static void SDL_PrivateSubsystemRefCountIncr(Uint32 subsystem)
Definition: SDL.c:59
SDL_joystick_c.h
NULL
#define NULL
Definition: begin_code.h:167
SDL_JoystickInit
int SDL_JoystickInit(void)
Definition: SDL_joystick.c:114
SDL_SubsystemRefCount
static Uint8 SDL_SubsystemRefCount[32]
Definition: SDL.c:55
SDL_version
Information the version of SDL in use.
Definition: SDL_version.h:51
TRUE
#define TRUE
Definition: edid-parse.c:33
SDL_LogResetPriorities
#define SDL_LogResetPriorities
Definition: SDL_dynapi_overrides.h:238
SDL_INIT_JOYSTICK
#define SDL_INIT_JOYSTICK
Definition: SDL.h:80
SDL_VERSION
#define SDL_VERSION(x)
Macro to determine SDL version program was compiled against.
Definition: SDL_version.h:79
SDL_IsAndroidTablet
SDL_bool SDL_IsAndroidTablet(void)
SDL_INIT_EVENTS
#define SDL_INIT_EVENTS
Definition: SDL.h:83
SDL_TimerInit
int SDL_TimerInit(void)
Definition: SDL_timer.c:207
SDL_TicksInit
void SDL_TicksInit(void)
SDL_SensorInit
int SDL_SensorInit(void)
Definition: SDL_sensor.c:69
SDL_revision.h
x0
GLuint GLfloat x0
Definition: SDL_opengl_glext.h:8583
SDL_ClearHints
#define SDL_ClearHints
Definition: SDL_dynapi_overrides.h:194
SDL_assert_c.h
SDL_AudioQuit
#define SDL_AudioQuit
Definition: SDL_dynapi_overrides.h:76
SDL_bits.h
SDL_GameControllerInit
int SDL_GameControllerInit(void)
Definition: SDL_gamecontroller.c:1374
SDL_SensorQuit
void SDL_SensorQuit(void)
Definition: SDL_sensor.c:440
SDL_INIT_SENSOR
#define SDL_INIT_SENSOR
Definition: SDL.h:84
SDL_FALSE
@ SDL_FALSE
Definition: SDL_stdinc.h:163
SDL_PrivateSubsystemRefCountDecr
static void SDL_PrivateSubsystemRefCountDecr(Uint32 subsystem)
Definition: SDL.c:68
SDL_GetVersion
void SDL_GetVersion(SDL_version *ver)
Get the version of SDL that is linked against your program.
Definition: SDL.c:402
SDL_bInMainQuit
static SDL_bool SDL_bInMainQuit
Definition: SDL.c:54
SDL_internal.h
SDL_TicksQuit
void SDL_TicksQuit(void)
SDL_HapticInit
int SDL_HapticInit(void)
Definition: SDL_haptic.c:39
SDL_HasExactlyOneBitSet32
SDL_FORCE_INLINE SDL_bool SDL_HasExactlyOneBitSet32(Uint32 x)
Definition: SDL_bits.h:105
SDL_REVISION_NUMBER
#define SDL_REVISION_NUMBER
Definition: SDL_revision.h:2
SDL_JoystickQuit
void SDL_JoystickQuit(void)
Definition: SDL_joystick.c:697
SDL_VideoInit
#define SDL_VideoInit
Definition: SDL_dynapi_overrides.h:498
SDL_min
#define SDL_min(x, y)
Definition: SDL_stdinc.h:406
SDL_PrivateShouldQuitSubsystem
static SDL_bool SDL_PrivateShouldQuitSubsystem(Uint32 subsystem)
Definition: SDL.c:87
SDL_AssertionsQuit
void SDL_AssertionsQuit(void)
Definition: SDL_assert.c:404
SDL_WasInit
Uint32 SDL_WasInit(Uint32 flags)
Definition: SDL.c:343
SDL_assert
#define SDL_assert(condition)
Definition: SDL_assert.h:169
SDL_INIT_HAPTIC
#define SDL_INIT_HAPTIC
Definition: SDL.h:81
APIENTRY
#define APIENTRY
Definition: SDL_opengl.h:139
SDL_Quit
void SDL_Quit(void)
Definition: SDL.c:374
SDL_IsTablet
SDL_bool SDL_IsTablet()
Return true if the current device is a tablet.
Definition: SDL.c:483
SDL_arraysize
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:115
SDL_INIT_VIDEO
#define SDL_INIT_VIDEO
Definition: SDL.h:79
SDL_TRUE
@ SDL_TRUE
Definition: SDL_stdinc.h:164
SDL_haptic_c.h
SDL_REVISION
#define SDL_REVISION
Definition: SDL_revision.h:1
SDL_INIT_TIMER
#define SDL_INIT_TIMER
Definition: SDL.h:77
SDL_SetError
#define SDL_SetError
Definition: SDL_dynapi_overrides.h:30
SDL_InitSubSystem
int SDL_InitSubSystem(Uint32 flags)
Definition: SDL.c:106
SDL_GameControllerQuit
void SDL_GameControllerQuit(void)
Definition: SDL_gamecontroller.c:1931
SDL_events_c.h
SDL_SetMainReady
void SDL_SetMainReady(void)
Definition: SDL.c:100
SDL_VideoQuit
#define SDL_VideoQuit
Definition: SDL_dynapi_overrides.h:499
SDL_MostSignificantBitIndex32
SDL_FORCE_INLINE int SDL_MostSignificantBitIndex32(Uint32 x)
Definition: SDL_bits.h:61
SDL_windows.h
SDL_sensor_c.h
SDL_INIT_GAMECONTROLLER
#define SDL_INIT_GAMECONTROLLER
Definition: SDL.h:82
SDL_EventsInit
int SDL_EventsInit(void)
Definition: SDL_events.c:1002
SDL_EventsQuit
void SDL_EventsQuit(void)
Definition: SDL_events.c:1016
flags
GLbitfield flags
Definition: SDL_opengl_glext.h:1480
SDL_INIT_EVERYTHING
#define SDL_INIT_EVERYTHING
Definition: SDL.h:86
SDL_QuitSubSystem
void SDL_QuitSubSystem(Uint32 flags)
Definition: SDL.c:259
SDL_Init
int SDL_Init(Uint32 flags)
Definition: SDL.c:253
i
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
SDL_MainIsReady
static SDL_bool SDL_MainIsReady
Definition: SDL.c:52
SDL_timer_c.h
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:161
SDL_INIT_AUDIO
#define SDL_INIT_AUDIO
Definition: SDL.h:78
Uint8
uint8_t Uint8
Definition: SDL_stdinc.h:179