SDL.c (12069B)
1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2014 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__) 24#include "core/windows/SDL_windows.h" 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" 35#include "joystick/SDL_joystick_c.h" 36 37/* Initialization/Cleanup routines */ 38#if !SDL_TIMERS_DISABLED 39extern int SDL_TimerInit(void); 40extern void SDL_TimerQuit(void); 41extern void SDL_TicksInit(void); 42extern void SDL_TicksQuit(void); 43#endif 44#if SDL_VIDEO_DRIVER_WINDOWS 45extern int SDL_HelperWindowCreate(void); 46extern int SDL_HelperWindowDestroy(void); 47#endif 48 49 50/* The initialized subsystems */ 51#ifdef SDL_MAIN_NEEDED 52static SDL_bool SDL_MainIsReady = SDL_FALSE; 53#else 54static SDL_bool SDL_MainIsReady = SDL_TRUE; 55#endif 56static SDL_bool SDL_bInMainQuit = SDL_FALSE; 57static Uint8 SDL_SubsystemRefCount[ 32 ]; 58 59/* Private helper to increment a subsystem's ref counter. */ 60static void 61SDL_PrivateSubsystemRefCountIncr(Uint32 subsystem) 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. */ 69static void 70SDL_PrivateSubsystemRefCountDecr(Uint32 subsystem) 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. */ 79static SDL_bool 80SDL_PrivateShouldInitSubsystem(Uint32 subsystem) 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. */ 88static SDL_bool 89SDL_PrivateShouldQuitSubsystem(Uint32 subsystem) { 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 101void 102SDL_SetMainReady(void) 103{ 104 SDL_MainIsReady = SDL_TRUE; 105} 106 107int 108SDL_InitSubSystem(Uint32 flags) 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 SDL_VIDEO_DRIVER_WINDOWS 119 if ((flags & (SDL_INIT_HAPTIC|SDL_INIT_JOYSTICK))) { 120 if (SDL_HelperWindowCreate() < 0) { 121 return -1; 122 } 123 } 124#endif 125 126#if !SDL_TIMERS_DISABLED 127 SDL_TicksInit(); 128#endif 129 130 if ((flags & SDL_INIT_GAMECONTROLLER)) { 131 /* game controller implies joystick */ 132 flags |= SDL_INIT_JOYSTICK; 133 } 134 135 if ((flags & (SDL_INIT_VIDEO|SDL_INIT_JOYSTICK))) { 136 /* video or joystick implies events */ 137 flags |= SDL_INIT_EVENTS; 138 } 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 241int 242SDL_Init(Uint32 flags) 243{ 244 return SDL_InitSubSystem(flags); 245} 246 247void 248SDL_QuitSubSystem(Uint32 flags) 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)) { 257 SDL_GameControllerQuit(); 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)) { 267 SDL_JoystickQuit(); 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(); 316 SDL_StopEventLoop(); 317 } 318 SDL_PrivateSubsystemRefCountDecr(SDL_INIT_EVENTS); 319 } 320#endif 321} 322 323Uint32 324SDL_WasInit(Uint32 flags) 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 348void 349SDL_Quit(void) 350{ 351 SDL_bInMainQuit = SDL_TRUE; 352 353 /* Quit all subsystems */ 354#if SDL_VIDEO_DRIVER_WINDOWS 355 SDL_HelperWindowDestroy(); 356#endif 357 SDL_QuitSubSystem(SDL_INIT_EVERYTHING); 358 359#if !SDL_TIMERS_DISABLED 360 SDL_TicksQuit(); 361#endif 362 363 SDL_ClearHints(); 364 SDL_AssertionsQuit(); 365 SDL_LogResetPriorities(); 366 367 /* Now that every subsystem has been quit, we reset the subsystem refcount 368 * and the list of initialized subsystems. 369 */ 370 SDL_memset( SDL_SubsystemRefCount, 0x0, sizeof(SDL_SubsystemRefCount) ); 371 372 SDL_bInMainQuit = SDL_FALSE; 373} 374 375/* Get the library version number */ 376void 377SDL_GetVersion(SDL_version * ver) 378{ 379 SDL_VERSION(ver); 380} 381 382/* Get the library source revision */ 383const char * 384SDL_GetRevision(void) 385{ 386 return SDL_REVISION; 387} 388 389/* Get the library source revision number */ 390int 391SDL_GetRevisionNumber(void) 392{ 393 return SDL_REVISION_NUMBER; 394} 395 396/* Get the name of the platform */ 397const char * 398SDL_GetPlatform() 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 __FREEBSD__ 409 return "FreeBSD"; 410#elif __HAIKU__ 411 return "Haiku"; 412#elif __HPUX__ 413 return "HP-UX"; 414#elif __IRIX__ 415 return "Irix"; 416#elif __LINUX__ 417 return "Linux"; 418#elif __MINT__ 419 return "Atari MiNT"; 420#elif __MACOS__ 421 return "MacOS Classic"; 422#elif __MACOSX__ 423 return "Mac OS X"; 424#elif __NACL__ 425 return "NaCl"; 426#elif __NETBSD__ 427 return "NetBSD"; 428#elif __OPENBSD__ 429 return "OpenBSD"; 430#elif __OS2__ 431 return "OS/2"; 432#elif __OSF__ 433 return "OSF/1"; 434#elif __QNXNTO__ 435 return "QNX Neutrino"; 436#elif __RISCOS__ 437 return "RISC OS"; 438#elif __SOLARIS__ 439 return "Solaris"; 440#elif __WIN32__ 441 return "Windows"; 442#elif __IPHONEOS__ 443 return "iOS"; 444#elif __PSP__ 445 return "PlayStation Portable"; 446#else 447 return "Unknown (see SDL_platform.h)"; 448#endif 449} 450 451#if defined(__WIN32__) 452 453#if !defined(HAVE_LIBC) || (defined(__WATCOMC__) && defined(BUILD_DLL)) 454/* Need to include DllMain() on Watcom C for some reason.. */ 455 456BOOL APIENTRY 457_DllMainCRTStartup(HANDLE hModule, 458 DWORD ul_reason_for_call, LPVOID lpReserved) 459{ 460 switch (ul_reason_for_call) { 461 case DLL_PROCESS_ATTACH: 462 case DLL_THREAD_ATTACH: 463 case DLL_THREAD_DETACH: 464 case DLL_PROCESS_DETACH: 465 break; 466 } 467 return TRUE; 468} 469#endif /* building DLL with Watcom C */ 470 471#endif /* __WIN32__ */ 472 473/* vi: set sts=4 ts=4 sw=4 expandtab: */