SDL  2.0
SDL.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2016 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 #endif
26 
27 /* Initialization code for SDL */
28 
29 #include "SDL.h"
30 #include "SDL_bits.h"
31 #include "SDL_revision.h"
32 #include "SDL_assert_c.h"
33 #include "events/SDL_events_c.h"
34 #include "haptic/SDL_haptic_c.h"
36 
37 /* Initialization/Cleanup routines */
38 #if !SDL_TIMERS_DISABLED
39 extern int SDL_TimerInit(void);
40 extern void SDL_TimerQuit(void);
41 extern void SDL_TicksInit(void);
42 extern void SDL_TicksQuit(void);
43 #endif
44 #if SDL_VIDEO_DRIVER_WINDOWS
45 extern int SDL_HelperWindowCreate(void);
46 extern int SDL_HelperWindowDestroy(void);
47 #endif
48 
49 
50 /* The initialized subsystems */
51 #ifdef SDL_MAIN_NEEDED
53 #else
55 #endif
58 
59 /* Private helper to increment a subsystem's ref counter. */
60 static void
62 {
63  int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
64  SDL_assert(SDL_SubsystemRefCount[subsystem_index] < 255);
65  ++SDL_SubsystemRefCount[subsystem_index];
66 }
67 
68 /* Private helper to decrement a subsystem's ref counter. */
69 static void
71 {
72  int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
73  if (SDL_SubsystemRefCount[subsystem_index] > 0) {
74  --SDL_SubsystemRefCount[subsystem_index];
75  }
76 }
77 
78 /* Private helper to check if a system needs init. */
79 static SDL_bool
81 {
82  int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
83  SDL_assert(SDL_SubsystemRefCount[subsystem_index] < 255);
84  return (SDL_SubsystemRefCount[subsystem_index] == 0);
85 }
86 
87 /* Private helper to check if a system needs to be quit. */
88 static SDL_bool
90  int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
91  if (SDL_SubsystemRefCount[subsystem_index] == 0) {
92  return SDL_FALSE;
93  }
94 
95  /* If we're in SDL_Quit, we shut down every subsystem, even if refcount
96  * isn't zero.
97  */
98  return SDL_SubsystemRefCount[subsystem_index] == 1 || SDL_bInMainQuit;
99 }
100 
101 void
103 {
105 }
106 
107 int
109 {
110  if (!SDL_MainIsReady) {
111  SDL_SetError("Application didn't initialize properly, did you include SDL_main.h in the file containing your main() function?");
112  return -1;
113  }
114 
115  /* Clear the error message */
116  SDL_ClearError();
117 
118  if ((flags & SDL_INIT_GAMECONTROLLER)) {
119  /* game controller implies joystick */
120  flags |= SDL_INIT_JOYSTICK;
121  }
122 
123  if ((flags & (SDL_INIT_VIDEO|SDL_INIT_JOYSTICK))) {
124  /* video or joystick implies events */
125  flags |= SDL_INIT_EVENTS;
126  }
127 
128 #if SDL_VIDEO_DRIVER_WINDOWS
129  if ((flags & (SDL_INIT_HAPTIC|SDL_INIT_JOYSTICK))) {
130  if (SDL_HelperWindowCreate() < 0) {
131  return -1;
132  }
133  }
134 #endif
135 
136 #if !SDL_TIMERS_DISABLED
137  SDL_TicksInit();
138 #endif
139 
140  /* Initialize the event subsystem */
141  if ((flags & SDL_INIT_EVENTS)) {
142 #if !SDL_EVENTS_DISABLED
143  if (SDL_PrivateShouldInitSubsystem(SDL_INIT_EVENTS)) {
144  if (SDL_StartEventLoop() < 0) {
145  return (-1);
146  }
147  SDL_QuitInit();
148  }
149  SDL_PrivateSubsystemRefCountIncr(SDL_INIT_EVENTS);
150 #else
151  return SDL_SetError("SDL not built with events support");
152 #endif
153  }
154 
155  /* Initialize the timer subsystem */
156  if ((flags & SDL_INIT_TIMER)){
157 #if !SDL_TIMERS_DISABLED
158  if (SDL_PrivateShouldInitSubsystem(SDL_INIT_TIMER)) {
159  if (SDL_TimerInit() < 0) {
160  return (-1);
161  }
162  }
163  SDL_PrivateSubsystemRefCountIncr(SDL_INIT_TIMER);
164 #else
165  return SDL_SetError("SDL not built with timer support");
166 #endif
167  }
168 
169  /* Initialize the video subsystem */
170  if ((flags & SDL_INIT_VIDEO)){
171 #if !SDL_VIDEO_DISABLED
172  if (SDL_PrivateShouldInitSubsystem(SDL_INIT_VIDEO)) {
173  if (SDL_VideoInit(NULL) < 0) {
174  return (-1);
175  }
176  }
177  SDL_PrivateSubsystemRefCountIncr(SDL_INIT_VIDEO);
178 #else
179  return SDL_SetError("SDL not built with video support");
180 #endif
181  }
182 
183  /* Initialize the audio subsystem */
184  if ((flags & SDL_INIT_AUDIO)){
185 #if !SDL_AUDIO_DISABLED
186  if (SDL_PrivateShouldInitSubsystem(SDL_INIT_AUDIO)) {
187  if (SDL_AudioInit(NULL) < 0) {
188  return (-1);
189  }
190  }
191  SDL_PrivateSubsystemRefCountIncr(SDL_INIT_AUDIO);
192 #else
193  return SDL_SetError("SDL not built with audio support");
194 #endif
195  }
196 
197  /* Initialize the joystick subsystem */
198  if ((flags & SDL_INIT_JOYSTICK)){
199 #if !SDL_JOYSTICK_DISABLED
200  if (SDL_PrivateShouldInitSubsystem(SDL_INIT_JOYSTICK)) {
201  if (SDL_JoystickInit() < 0) {
202  return (-1);
203  }
204  }
205  SDL_PrivateSubsystemRefCountIncr(SDL_INIT_JOYSTICK);
206 #else
207  return SDL_SetError("SDL not built with joystick support");
208 #endif
209  }
210 
211  if ((flags & SDL_INIT_GAMECONTROLLER)){
212 #if !SDL_JOYSTICK_DISABLED
213  if (SDL_PrivateShouldInitSubsystem(SDL_INIT_GAMECONTROLLER)) {
214  if (SDL_GameControllerInit() < 0) {
215  return (-1);
216  }
217  }
218  SDL_PrivateSubsystemRefCountIncr(SDL_INIT_GAMECONTROLLER);
219 #else
220  return SDL_SetError("SDL not built with joystick support");
221 #endif
222  }
223 
224  /* Initialize the haptic subsystem */
225  if ((flags & SDL_INIT_HAPTIC)){
226 #if !SDL_HAPTIC_DISABLED
227  if (SDL_PrivateShouldInitSubsystem(SDL_INIT_HAPTIC)) {
228  if (SDL_HapticInit() < 0) {
229  return (-1);
230  }
231  }
232  SDL_PrivateSubsystemRefCountIncr(SDL_INIT_HAPTIC);
233 #else
234  return SDL_SetError("SDL not built with haptic (force feedback) support");
235 #endif
236  }
237 
238  return (0);
239 }
240 
241 int
243 {
244  return SDL_InitSubSystem(flags);
245 }
246 
247 void
249 {
250  /* Shut down requested initialized subsystems */
251 #if !SDL_JOYSTICK_DISABLED
252  if ((flags & SDL_INIT_GAMECONTROLLER)) {
253  /* game controller implies joystick */
254  flags |= SDL_INIT_JOYSTICK;
255 
256  if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_GAMECONTROLLER)) {
258  }
259  SDL_PrivateSubsystemRefCountDecr(SDL_INIT_GAMECONTROLLER);
260  }
261 
262  if ((flags & SDL_INIT_JOYSTICK)) {
263  /* joystick implies events */
264  flags |= SDL_INIT_EVENTS;
265 
266  if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_JOYSTICK)) {
268  }
269  SDL_PrivateSubsystemRefCountDecr(SDL_INIT_JOYSTICK);
270  }
271 #endif
272 
273 #if !SDL_HAPTIC_DISABLED
274  if ((flags & SDL_INIT_HAPTIC)) {
275  if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_HAPTIC)) {
276  SDL_HapticQuit();
277  }
278  SDL_PrivateSubsystemRefCountDecr(SDL_INIT_HAPTIC);
279  }
280 #endif
281 
282 #if !SDL_AUDIO_DISABLED
283  if ((flags & SDL_INIT_AUDIO)) {
284  if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_AUDIO)) {
285  SDL_AudioQuit();
286  }
287  SDL_PrivateSubsystemRefCountDecr(SDL_INIT_AUDIO);
288  }
289 #endif
290 
291 #if !SDL_VIDEO_DISABLED
292  if ((flags & SDL_INIT_VIDEO)) {
293  /* video implies events */
294  flags |= SDL_INIT_EVENTS;
295 
296  if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_VIDEO)) {
297  SDL_VideoQuit();
298  }
299  SDL_PrivateSubsystemRefCountDecr(SDL_INIT_VIDEO);
300  }
301 #endif
302 
303 #if !SDL_TIMERS_DISABLED
304  if ((flags & SDL_INIT_TIMER)) {
305  if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_TIMER)) {
306  SDL_TimerQuit();
307  }
308  SDL_PrivateSubsystemRefCountDecr(SDL_INIT_TIMER);
309  }
310 #endif
311 
312 #if !SDL_EVENTS_DISABLED
313  if ((flags & SDL_INIT_EVENTS)) {
314  if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_EVENTS)) {
315  SDL_QuitQuit();
317  }
318  SDL_PrivateSubsystemRefCountDecr(SDL_INIT_EVENTS);
319  }
320 #endif
321 }
322 
323 Uint32
325 {
326  int i;
327  int num_subsystems = SDL_arraysize(SDL_SubsystemRefCount);
328  Uint32 initialized = 0;
329 
330  if (!flags) {
331  flags = SDL_INIT_EVERYTHING;
332  }
333 
334  num_subsystems = SDL_min(num_subsystems, SDL_MostSignificantBitIndex32(flags) + 1);
335 
336  /* Iterate over each bit in flags, and check the matching subsystem. */
337  for (i = 0; i < num_subsystems; ++i) {
338  if ((flags & 1) && SDL_SubsystemRefCount[i] > 0) {
339  initialized |= (1 << i);
340  }
341 
342  flags >>= 1;
343  }
344 
345  return initialized;
346 }
347 
348 void
349 SDL_Quit(void)
350 {
352 
353  /* Quit all subsystems */
354 #if SDL_VIDEO_DRIVER_WINDOWS
355  SDL_HelperWindowDestroy();
356 #endif
358 
359 #if !SDL_TIMERS_DISABLED
360  SDL_TicksQuit();
361 #endif
362 
363  SDL_ClearHints();
366 
367  /* Now that every subsystem has been quit, we reset the subsystem refcount
368  * and the list of initialized subsystems.
369  */
371 
373 }
374 
375 /* Get the library version number */
376 void
378 {
379  SDL_VERSION(ver);
380 }
381 
382 /* Get the library source revision */
383 const char *
385 {
386  return SDL_REVISION;
387 }
388 
389 /* Get the library source revision number */
390 int
392 {
393  return SDL_REVISION_NUMBER;
394 }
395 
396 /* Get the name of the platform */
397 const char *
399 {
400 #if __AIX__
401  return "AIX";
402 #elif __ANDROID__
403  return "Android";
404 #elif __BSDI__
405  return "BSDI";
406 #elif __DREAMCAST__
407  return "Dreamcast";
408 #elif __EMSCRIPTEN__
409  return "Emscripten";
410 #elif __FREEBSD__
411  return "FreeBSD";
412 #elif __HAIKU__
413  return "Haiku";
414 #elif __HPUX__
415  return "HP-UX";
416 #elif __IRIX__
417  return "Irix";
418 #elif __LINUX__
419  return "Linux";
420 #elif __MINT__
421  return "Atari MiNT";
422 #elif __MACOS__
423  return "MacOS Classic";
424 #elif __MACOSX__
425  return "Mac OS X";
426 #elif __NACL__
427  return "NaCl";
428 #elif __NETBSD__
429  return "NetBSD";
430 #elif __OPENBSD__
431  return "OpenBSD";
432 #elif __OS2__
433  return "OS/2";
434 #elif __OSF__
435  return "OSF/1";
436 #elif __QNXNTO__
437  return "QNX Neutrino";
438 #elif __RISCOS__
439  return "RISC OS";
440 #elif __SOLARIS__
441  return "Solaris";
442 #elif __WIN32__
443  return "Windows";
444 #elif __WINRT__
445  return "WinRT";
446 #elif __TVOS__
447  return "tvOS";
448 #elif __IPHONEOS__
449  return "iOS";
450 #elif __PSP__
451  return "PlayStation Portable";
452 #else
453  return "Unknown (see SDL_platform.h)";
454 #endif
455 }
456 
457 #if defined(__WIN32__)
458 
459 #if !defined(HAVE_LIBC) || (defined(__WATCOMC__) && defined(BUILD_DLL))
460 /* Need to include DllMain() on Watcom C for some reason.. */
461 
462 BOOL APIENTRY
463 _DllMainCRTStartup(HANDLE hModule,
464  DWORD ul_reason_for_call, LPVOID lpReserved)
465 {
466  switch (ul_reason_for_call) {
467  case DLL_PROCESS_ATTACH:
468  case DLL_THREAD_ATTACH:
469  case DLL_THREAD_DETACH:
470  case DLL_PROCESS_DETACH:
471  break;
472  }
473  return TRUE;
474 }
475 #endif /* building DLL with Watcom C */
476 
477 #endif /* __WIN32__ */
478 
479 /* vi: set sts=4 ts=4 sw=4 expandtab: */
#define SDL_ClearError
#define SDL_INIT_EVENTS
Definition: SDL.h:81
const char * SDL_GetRevision(void)
Get the code revision of SDL that is linked against your program.
Definition: SDL.c:384
#define SDL_min(x, y)
Definition: SDL_stdinc.h:351
static SDL_bool SDL_MainIsReady
Definition: SDL.c:54
void SDL_HapticQuit(void)
Definition: SDL_haptic.c:389
#define SDL_LogResetPriorities
#define SDL_INIT_JOYSTICK
Definition: SDL.h:78
#define SDL_AudioInit
static Uint8 SDL_SubsystemRefCount[32]
Definition: SDL.c:57
void SDL_QuitSubSystem(Uint32 flags)
Definition: SDL.c:248
int SDL_Init(Uint32 flags)
Definition: SDL.c:242
int SDL_JoystickInit(void)
Definition: SDL_joystick.c:50
#define APIENTRY
Definition: SDL_opengl.h:132
int SDL_StartEventLoop(void)
Definition: SDL_events.c:160
SDL_FORCE_INLINE int SDL_MostSignificantBitIndex32(Uint32 x)
Definition: SDL_bits.h:51
void SDL_TimerQuit(void)
Definition: SDL_timer.c:238
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:161
void SDL_Quit(void)
Definition: SDL.c:349
#define SDL_ClearHints
static SDL_bool SDL_bInMainQuit
Definition: SDL.c:56
Uint32 SDL_WasInit(Uint32 flags)
Definition: SDL.c:324
void SDL_TicksQuit(void)
int SDL_QuitInit(void)
Definition: SDL_quit.c:92
#define SDL_AudioQuit
#define SDL_REVISION_NUMBER
Definition: SDL_revision.h:2
#define SDL_VERSION(x)
Macro to determine SDL version program was compiled against.
Definition: SDL_version.h:79
void SDL_AssertionsQuit(void)
Definition: SDL_assert.c:332
void SDL_GetVersion(SDL_version *ver)
Get the version of SDL that is linked against your program.
Definition: SDL.c:377
Information the version of SDL in use.
Definition: SDL_version.h:51
static void SDL_PrivateSubsystemRefCountIncr(Uint32 subsystem)
Definition: SDL.c:61
#define SDL_VideoInit
void SDL_GameControllerQuit(void)
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:143
#define TRUE
Definition: edid-parse.c:33
#define SDL_INIT_EVERYTHING
Definition: SDL.h:83
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 SDL_assert(condition)
Definition: SDL_assert.h:167
const char * SDL_GetPlatform()
Gets the name of the platform.
Definition: SDL.c:398
#define NULL
Definition: begin_code.h:143
SDL_bool
Definition: SDL_stdinc.h:130
static SDL_bool SDL_PrivateShouldInitSubsystem(Uint32 subsystem)
Definition: SDL.c:80
#define SDL_SetError
#define SDL_INIT_TIMER
Definition: SDL.h:75
#define SDL_INIT_AUDIO
Definition: SDL.h:76
static void SDL_PrivateSubsystemRefCountDecr(Uint32 subsystem)
Definition: SDL.c:70
#define SDL_REVISION
Definition: SDL_revision.h:1
#define SDL_VideoQuit
void SDL_TicksInit(void)
GLuint GLfloat x0
static SDL_bool SDL_PrivateShouldQuitSubsystem(Uint32 subsystem)
Definition: SDL.c:89
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:90
GLbitfield flags
#define SDL_INIT_GAMECONTROLLER
Definition: SDL.h:80
void SDL_JoystickQuit(void)
Definition: SDL_joystick.c:459
#define SDL_INIT_HAPTIC
Definition: SDL.h:79
int SDL_InitSubSystem(Uint32 flags)
Definition: SDL.c:108
int SDL_GameControllerInit(void)
int SDL_HapticInit(void)
Definition: SDL_haptic.c:35
int SDL_GetRevisionNumber(void)
Get the revision number of SDL that is linked against your program.
Definition: SDL.c:391
#define SDL_INIT_VIDEO
Definition: SDL.h:77
#define SDL_memset
void SDL_SetMainReady(void)
Definition: SDL.c:102
void SDL_QuitQuit(void)
Definition: SDL_quit.c:128
int SDL_TimerInit(void)
Definition: SDL_timer.c:206
void SDL_StopEventLoop(void)
Definition: SDL_events.c:90