SDL  2.0
SDL.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "./SDL_internal.h"
22 
23 #if defined(__WIN32__)
25 #elif defined(__OS2__)
26 #include <stdlib.h> /* For _exit() */
27 #elif !defined(__WINRT__)
28 #include <unistd.h> /* For _exit(), etc. */
29 #endif
30 #if defined(__OS2__)
31 #include "core/os2/SDL_os2.h"
32 #endif
33 #if SDL_THREAD_OS2
35 #endif
36 
37 #if defined(__EMSCRIPTEN__)
38 #include <emscripten.h>
39 #endif
40 
41 /* Initialization code for SDL */
42 
43 #include "SDL.h"
44 #include "SDL_bits.h"
45 #include "SDL_revision.h"
46 #include "SDL_assert_c.h"
47 #include "events/SDL_events_c.h"
48 #include "haptic/SDL_haptic_c.h"
50 #include "sensor/SDL_sensor_c.h"
51 
52 /* Initialization/Cleanup routines */
53 #if !SDL_TIMERS_DISABLED
54 # include "timer/SDL_timer_c.h"
55 #endif
56 #if SDL_VIDEO_DRIVER_WINDOWS
57 extern int SDL_HelperWindowCreate(void);
58 extern int SDL_HelperWindowDestroy(void);
59 #endif
60 
61 
62 /* This is not declared in any header, although it is shared between some
63  parts of SDL, because we don't want anything calling it without an
64  extremely good reason. */
65 extern SDL_NORETURN void SDL_ExitProcess(int exitcode);
66 SDL_NORETURN void SDL_ExitProcess(int exitcode)
67 {
68 #ifdef __WIN32__
69  /* "if you do not know the state of all threads in your process, it is
70  better to call TerminateProcess than ExitProcess"
71  https://msdn.microsoft.com/en-us/library/windows/desktop/ms682658(v=vs.85).aspx */
72  TerminateProcess(GetCurrentProcess(), exitcode);
73  /* MingW doesn't have TerminateProcess marked as noreturn, so add an
74  ExitProcess here that will never be reached but make MingW happy. */
75  ExitProcess(exitcode);
76 #elif defined(__EMSCRIPTEN__)
77  emscripten_cancel_main_loop(); /* this should "kill" the app. */
78  emscripten_force_exit(exitcode); /* this should "kill" the app. */
79  exit(exitcode);
80 #elif defined(__HAIKU__) /* Haiku has _Exit, but it's not marked noreturn. */
81  _exit(exitcode);
82 #elif defined(HAVE__EXIT) /* Upper case _Exit() */
83  _Exit(exitcode);
84 #else
85  _exit(exitcode);
86 #endif
87 }
88 
89 
90 /* The initialized subsystems */
91 #ifdef SDL_MAIN_NEEDED
93 #else
95 #endif
98 
99 /* Private helper to increment a subsystem's ref counter. */
100 static void
102 {
103  int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
104  SDL_assert(SDL_SubsystemRefCount[subsystem_index] < 255);
105  ++SDL_SubsystemRefCount[subsystem_index];
106 }
107 
108 /* Private helper to decrement a subsystem's ref counter. */
109 static void
111 {
112  int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
113  if (SDL_SubsystemRefCount[subsystem_index] > 0) {
114  --SDL_SubsystemRefCount[subsystem_index];
115  }
116 }
117 
118 /* Private helper to check if a system needs init. */
119 static SDL_bool
121 {
122  int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
123  SDL_assert(SDL_SubsystemRefCount[subsystem_index] < 255);
124  return (SDL_SubsystemRefCount[subsystem_index] == 0) ? SDL_TRUE : SDL_FALSE;
125 }
126 
127 /* Private helper to check if a system needs to be quit. */
128 static SDL_bool
130  int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
131  if (SDL_SubsystemRefCount[subsystem_index] == 0) {
132  return SDL_FALSE;
133  }
134 
135  /* If we're in SDL_Quit, we shut down every subsystem, even if refcount
136  * isn't zero.
137  */
138  return (SDL_SubsystemRefCount[subsystem_index] == 1 || SDL_bInMainQuit) ? SDL_TRUE : SDL_FALSE;
139 }
140 
141 void
143 {
145 }
146 
147 int
149 {
150  if (!SDL_MainIsReady) {
151  SDL_SetError("Application didn't initialize properly, did you include SDL_main.h in the file containing your main() function?");
152  return -1;
153  }
154 
155  /* Clear the error message */
156  SDL_ClearError();
157 
158  if ((flags & SDL_INIT_GAMECONTROLLER)) {
159  /* game controller implies joystick */
161  }
162 
164  /* video or joystick implies events */
166  }
167 
168 #if SDL_THREAD_OS2
169  SDL_OS2TLSAlloc(); /* thread/os2/SDL_systls.c */
170 #endif
171 
172 #if SDL_VIDEO_DRIVER_WINDOWS
174  if (SDL_HelperWindowCreate() < 0) {
175  return -1;
176  }
177  }
178 #endif
179 
180 #if !SDL_TIMERS_DISABLED
181  SDL_TicksInit();
182 #endif
183 
184  /* Initialize the event subsystem */
185  if ((flags & SDL_INIT_EVENTS)) {
186 #if !SDL_EVENTS_DISABLED
188  if (SDL_EventsInit() < 0) {
189  return (-1);
190  }
191  }
193 #else
194  return SDL_SetError("SDL not built with events support");
195 #endif
196  }
197 
198  /* Initialize the timer subsystem */
199  if ((flags & SDL_INIT_TIMER)){
200 #if !SDL_TIMERS_DISABLED
202  if (SDL_TimerInit() < 0) {
203  return (-1);
204  }
205  }
207 #else
208  return SDL_SetError("SDL not built with timer support");
209 #endif
210  }
211 
212  /* Initialize the video subsystem */
213  if ((flags & SDL_INIT_VIDEO)){
214 #if !SDL_VIDEO_DISABLED
216  if (SDL_VideoInit(NULL) < 0) {
217  return (-1);
218  }
219  }
221 #else
222  return SDL_SetError("SDL not built with video support");
223 #endif
224  }
225 
226  /* Initialize the audio subsystem */
227  if ((flags & SDL_INIT_AUDIO)){
228 #if !SDL_AUDIO_DISABLED
230  if (SDL_AudioInit(NULL) < 0) {
231  return (-1);
232  }
233  }
235 #else
236  return SDL_SetError("SDL not built with audio support");
237 #endif
238  }
239 
240  /* Initialize the joystick subsystem */
241  if ((flags & SDL_INIT_JOYSTICK)){
242 #if !SDL_JOYSTICK_DISABLED
244  if (SDL_JoystickInit() < 0) {
245  return (-1);
246  }
247  }
249 #else
250  return SDL_SetError("SDL not built with joystick support");
251 #endif
252  }
253 
255 #if !SDL_JOYSTICK_DISABLED
257  if (SDL_GameControllerInit() < 0) {
258  return (-1);
259  }
260  }
262 #else
263  return SDL_SetError("SDL not built with joystick support");
264 #endif
265  }
266 
267  /* Initialize the haptic subsystem */
268  if ((flags & SDL_INIT_HAPTIC)){
269 #if !SDL_HAPTIC_DISABLED
271  if (SDL_HapticInit() < 0) {
272  return (-1);
273  }
274  }
276 #else
277  return SDL_SetError("SDL not built with haptic (force feedback) support");
278 #endif
279  }
280 
281  /* Initialize the sensor subsystem */
282  if ((flags & SDL_INIT_SENSOR)){
283 #if !SDL_SENSOR_DISABLED
285  if (SDL_SensorInit() < 0) {
286  return (-1);
287  }
288  }
290 #else
291  return SDL_SetError("SDL not built with sensor support");
292 #endif
293  }
294 
295  return (0);
296 }
297 
298 int
300 {
301  return SDL_InitSubSystem(flags);
302 }
303 
304 void
306 {
307 #if SDL_THREAD_OS2
308  SDL_OS2TLSFree(); /* thread/os2/SDL_systls.c */
309 #endif
310 #if defined(__OS2__)
311  SDL_OS2Quit();
312 #endif
313 
314  /* Shut down requested initialized subsystems */
315 #if !SDL_SENSOR_DISABLED
316  if ((flags & SDL_INIT_SENSOR)) {
318  SDL_SensorQuit();
319  }
321  }
322 #endif
323 
324 #if !SDL_JOYSTICK_DISABLED
325  if ((flags & SDL_INIT_GAMECONTROLLER)) {
326  /* game controller implies joystick */
328 
331  }
333  }
334 
335  if ((flags & SDL_INIT_JOYSTICK)) {
336  /* joystick implies events */
338 
341  }
343  }
344 #endif
345 
346 #if !SDL_HAPTIC_DISABLED
347  if ((flags & SDL_INIT_HAPTIC)) {
349  SDL_HapticQuit();
350  }
352  }
353 #endif
354 
355 #if !SDL_AUDIO_DISABLED
356  if ((flags & SDL_INIT_AUDIO)) {
358  SDL_AudioQuit();
359  }
361  }
362 #endif
363 
364 #if !SDL_VIDEO_DISABLED
365  if ((flags & SDL_INIT_VIDEO)) {
366  /* video implies events */
368 
370  SDL_VideoQuit();
371  }
373  }
374 #endif
375 
376 #if !SDL_TIMERS_DISABLED
377  if ((flags & SDL_INIT_TIMER)) {
379  SDL_TimerQuit();
380  }
382  }
383 #endif
384 
385 #if !SDL_EVENTS_DISABLED
386  if ((flags & SDL_INIT_EVENTS)) {
388  SDL_EventsQuit();
389  }
391  }
392 #endif
393 }
394 
395 Uint32
397 {
398  int i;
399  int num_subsystems = SDL_arraysize(SDL_SubsystemRefCount);
400  Uint32 initialized = 0;
401 
402  /* Fast path for checking one flag */
404  int subsystem_index = SDL_MostSignificantBitIndex32(flags);
405  return SDL_SubsystemRefCount[subsystem_index] ? flags : 0;
406  }
407 
408  if (!flags) {
410  }
411 
412  num_subsystems = SDL_min(num_subsystems, SDL_MostSignificantBitIndex32(flags) + 1);
413 
414  /* Iterate over each bit in flags, and check the matching subsystem. */
415  for (i = 0; i < num_subsystems; ++i) {
416  if ((flags & 1) && SDL_SubsystemRefCount[i] > 0) {
417  initialized |= (1 << i);
418  }
419 
420  flags >>= 1;
421  }
422 
423  return initialized;
424 }
425 
426 void
427 SDL_Quit(void)
428 {
430 
431  /* Quit all subsystems */
432 #if SDL_VIDEO_DRIVER_WINDOWS
433  SDL_HelperWindowDestroy();
434 #endif
436 
437 #if !SDL_TIMERS_DISABLED
438  SDL_TicksQuit();
439 #endif
440 
441  SDL_ClearHints();
444 
445  /* Now that every subsystem has been quit, we reset the subsystem refcount
446  * and the list of initialized subsystems.
447  */
449 
451 }
452 
453 /* Get the library version number */
454 void
456 {
457  SDL_VERSION(ver);
458 }
459 
460 /* Get the library source revision */
461 const char *
463 {
464  return SDL_REVISION;
465 }
466 
467 /* Get the library source revision number */
468 int
470 {
471  return SDL_REVISION_NUMBER;
472 }
473 
474 /* Get the name of the platform */
475 const char *
477 {
478 #if __AIX__
479  return "AIX";
480 #elif __ANDROID__
481  return "Android";
482 #elif __BSDI__
483  return "BSDI";
484 #elif __DREAMCAST__
485  return "Dreamcast";
486 #elif __EMSCRIPTEN__
487  return "Emscripten";
488 #elif __FREEBSD__
489  return "FreeBSD";
490 #elif __HAIKU__
491  return "Haiku";
492 #elif __HPUX__
493  return "HP-UX";
494 #elif __IRIX__
495  return "Irix";
496 #elif __LINUX__
497  return "Linux";
498 #elif __MINT__
499  return "Atari MiNT";
500 #elif __MACOS__
501  return "MacOS Classic";
502 #elif __MACOSX__
503  return "Mac OS X";
504 #elif __NACL__
505  return "NaCl";
506 #elif __NETBSD__
507  return "NetBSD";
508 #elif __OPENBSD__
509  return "OpenBSD";
510 #elif __OS2__
511  return "OS/2";
512 #elif __OSF__
513  return "OSF/1";
514 #elif __QNXNTO__
515  return "QNX Neutrino";
516 #elif __RISCOS__
517  return "RISC OS";
518 #elif __SOLARIS__
519  return "Solaris";
520 #elif __WIN32__
521  return "Windows";
522 #elif __WINRT__
523  return "WinRT";
524 #elif __TVOS__
525  return "tvOS";
526 #elif __IPHONEOS__
527  return "iOS";
528 #elif __PSP__
529  return "PlayStation Portable";
530 #else
531  return "Unknown (see SDL_platform.h)";
532 #endif
533 }
534 
535 SDL_bool
537 {
538 #if __ANDROID__
539  extern SDL_bool SDL_IsAndroidTablet(void);
540  return SDL_IsAndroidTablet();
541 #elif __IPHONEOS__
542  extern SDL_bool SDL_IsIPad(void);
543  return SDL_IsIPad();
544 #else
545  return SDL_FALSE;
546 #endif
547 }
548 
549 #if defined(__WIN32__)
550 
551 #if (!defined(HAVE_LIBC) || defined(__WATCOMC__)) && !defined(SDL_STATIC_LIB)
552 /* Need to include DllMain() on Watcom C for some reason.. */
553 
554 BOOL APIENTRY
555 _DllMainCRTStartup(HANDLE hModule,
556  DWORD ul_reason_for_call, LPVOID lpReserved)
557 {
558  switch (ul_reason_for_call) {
559  case DLL_PROCESS_ATTACH:
560  case DLL_THREAD_ATTACH:
561  case DLL_THREAD_DETACH:
562  case DLL_PROCESS_DETACH:
563  break;
564  }
565  return TRUE;
566 }
567 #endif /* Building DLL */
568 
569 #endif /* __WIN32__ */
570 
571 /* vi: set sts=4 ts=4 sw=4 expandtab: */
Uint32 SDL_WasInit(Uint32 flags)
Definition: SDL.c:396
int SDL_GetRevisionNumber(void)
Get the revision number of SDL that is linked against your program.
Definition: SDL.c:469
void SDL_SetMainReady(void)
Definition: SDL.c:142
static Uint8 SDL_SubsystemRefCount[32]
Definition: SDL.c:97
int SDL_InitSubSystem(Uint32 flags)
Definition: SDL.c:148
static SDL_bool SDL_PrivateShouldQuitSubsystem(Uint32 subsystem)
Definition: SDL.c:129
SDL_NORETURN void SDL_ExitProcess(int exitcode)
Definition: SDL.c:66
static void SDL_PrivateSubsystemRefCountIncr(Uint32 subsystem)
Definition: SDL.c:101
void SDL_QuitSubSystem(Uint32 flags)
Definition: SDL.c:305
static SDL_bool SDL_MainIsReady
Definition: SDL.c:94
static SDL_bool SDL_bInMainQuit
Definition: SDL.c:96
void SDL_GetVersion(SDL_version *ver)
Get the version of SDL that is linked against your program.
Definition: SDL.c:455
const char * SDL_GetRevision(void)
Get the code revision of SDL that is linked against your program.
Definition: SDL.c:462
static void SDL_PrivateSubsystemRefCountDecr(Uint32 subsystem)
Definition: SDL.c:110
void SDL_Quit(void)
Definition: SDL.c:427
SDL_bool SDL_IsTablet()
Return true if the current device is a tablet.
Definition: SDL.c:536
const char * SDL_GetPlatform()
Gets the name of the platform.
Definition: SDL.c:476
static SDL_bool SDL_PrivateShouldInitSubsystem(Uint32 subsystem)
Definition: SDL.c:120
int SDL_Init(Uint32 flags)
Definition: SDL.c:299
#define SDL_INIT_SENSOR
Definition: SDL.h:87
#define SDL_INIT_EVERYTHING
Definition: SDL.h:89
#define SDL_INIT_TIMER
Definition: SDL.h:80
#define SDL_INIT_AUDIO
Definition: SDL.h:81
#define SDL_INIT_GAMECONTROLLER
Definition: SDL.h:85
#define SDL_INIT_JOYSTICK
Definition: SDL.h:83
#define SDL_INIT_EVENTS
Definition: SDL.h:86
#define SDL_INIT_HAPTIC
Definition: SDL.h:84
#define SDL_INIT_VIDEO
Definition: SDL.h:82
SDL_bool SDL_IsAndroidTablet(void)
void SDL_AssertionsQuit(void)
Definition: SDL_assert.c:385
#define SDL_assert(condition)
Definition: SDL_assert.h:171
SDL_FORCE_INLINE SDL_bool SDL_HasExactlyOneBitSet32(Uint32 x)
Definition: SDL_bits.h:105
SDL_FORCE_INLINE int SDL_MostSignificantBitIndex32(Uint32 x)
Definition: SDL_bits.h:61
#define SDL_SetError
#define SDL_memset
#define SDL_LogResetPriorities
#define SDL_AudioInit
#define SDL_VideoInit
#define SDL_ClearError
#define SDL_AudioQuit
#define SDL_VideoQuit
#define SDL_ClearHints
int SDL_EventsInit(void)
Definition: SDL_events.c:1078
void SDL_EventsQuit(void)
Definition: SDL_events.c:1098
void SDL_GameControllerQuit(void)
int SDL_GameControllerInit(void)
int SDL_HapticInit(void)
Definition: SDL_haptic.c:38
void SDL_HapticQuit(void)
Definition: SDL_haptic.c:393
int SDL_JoystickInit(void)
Definition: SDL_joystick.c:213
void SDL_JoystickQuit(void)
#define APIENTRY
Definition: SDL_opengl.h:139
GLbitfield flags
void SDL_OS2Quit(void)
#define SDL_REVISION_NUMBER
Definition: SDL_revision.h:2
#define SDL_REVISION
Definition: SDL_revision.h:1
int SDL_SensorInit(void)
Definition: SDL_sensor.c:71
void SDL_SensorQuit(void)
Definition: SDL_sensor.c:442
SDL_bool
Definition: SDL_stdinc.h:168
@ SDL_TRUE
Definition: SDL_stdinc.h:170
@ SDL_FALSE
Definition: SDL_stdinc.h:169
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:121
uint8_t Uint8
Definition: SDL_stdinc.h:185
#define SDL_min(x, y)
Definition: SDL_stdinc.h:412
uint32_t Uint32
Definition: SDL_stdinc.h:209
void SDL_TimerQuit(void)
Definition: SDL_timer.c:239
int SDL_TimerInit(void)
Definition: SDL_timer.c:207
void SDL_TicksQuit(void)
void SDL_TicksInit(void)
#define SDL_VERSION(x)
Macro to determine SDL version program was compiled against.
Definition: SDL_version.h:79
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
#define NULL
Definition: begin_code.h:163
#define SDL_NORETURN
Definition: begin_code.h:153
#define TRUE
Definition: edid-parse.c:33
Information the version of SDL in use.
Definition: SDL_version.h:52