1 /* 2 SDL - Simple DirectMedia Layer 3 Copyright (C) 1997-2012 Sam Lantinga 4 5 This library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with this library; if not, write to the Free Software 17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 19 Sam Lantinga 20 slouken (at) libsdl.org 21 */ 22 #include "SDL_config.h" 23 24 /* Initialization code for SDL */ 25 26 #include "SDL.h" 27 #include "SDL_fatal.h" 28 #if !SDL_VIDEO_DISABLED 29 #include "video/SDL_leaks.h" 30 #endif 31 32 #if SDL_THREAD_PTH 33 #include <pth.h> 34 #endif 35 36 /* Initialization/Cleanup routines */ 37 #if !SDL_JOYSTICK_DISABLED 38 extern int SDL_JoystickInit(void); 39 extern void SDL_JoystickQuit(void); 40 #endif 41 #if !SDL_CDROM_DISABLED 42 extern int SDL_CDROMInit(void); 43 extern void SDL_CDROMQuit(void); 44 #endif 45 #if !SDL_TIMERS_DISABLED 46 extern void SDL_StartTicks(void); 47 extern int SDL_TimerInit(void); 48 extern void SDL_TimerQuit(void); 49 #endif 50 51 /* The current SDL version */ 52 static SDL_version version = 53 { SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL }; 54 55 /* The initialized subsystems */ 56 static Uint32 SDL_initialized = 0; 57 #if !SDL_TIMERS_DISABLED 58 static Uint32 ticks_started = 0; 59 #endif 60 61 #ifdef CHECK_LEAKS 62 int surfaces_allocated = 0; 63 #endif 64 65 int SDL_InitSubSystem(Uint32 flags) 66 { 67 #if !SDL_TIMERS_DISABLED 68 /* Initialize the timer subsystem */ 69 if ( ! ticks_started ) { 70 SDL_StartTicks(); 71 ticks_started = 1; 72 } 73 if ( (flags & SDL_INIT_TIMER) && !(SDL_initialized & SDL_INIT_TIMER) ) { 74 if ( SDL_TimerInit() < 0 ) { 75 return(-1); 76 } 77 SDL_initialized |= SDL_INIT_TIMER; 78 } 79 #else 80 if ( flags & SDL_INIT_TIMER ) { 81 SDL_SetError("SDL not built with timer support"); 82 return(-1); 83 } 84 #endif 85 86 #if !SDL_VIDEO_DISABLED 87 /* Initialize the video/event subsystem */ 88 if ( (flags & SDL_INIT_VIDEO) && !(SDL_initialized & SDL_INIT_VIDEO) ) { 89 if ( SDL_VideoInit(SDL_getenv("SDL_VIDEODRIVER"), 90 (flags&SDL_INIT_EVENTTHREAD)) < 0 ) { 91 return(-1); 92 } 93 SDL_initialized |= SDL_INIT_VIDEO; 94 } 95 #else 96 if ( flags & SDL_INIT_VIDEO ) { 97 SDL_SetError("SDL not built with video support"); 98 return(-1); 99 } 100 #endif 101 102 #if !SDL_AUDIO_DISABLED 103 /* Initialize the audio subsystem */ 104 if ( (flags & SDL_INIT_AUDIO) && !(SDL_initialized & SDL_INIT_AUDIO) ) { 105 if ( SDL_AudioInit(SDL_getenv("SDL_AUDIODRIVER")) < 0 ) { 106 return(-1); 107 } 108 SDL_initialized |= SDL_INIT_AUDIO; 109 } 110 #else 111 if ( flags & SDL_INIT_AUDIO ) { 112 SDL_SetError("SDL not built with audio support"); 113 return(-1); 114 } 115 #endif 116 117 #if !SDL_JOYSTICK_DISABLED 118 /* Initialize the joystick subsystem */ 119 if ( (flags & SDL_INIT_JOYSTICK) && 120 !(SDL_initialized & SDL_INIT_JOYSTICK) ) { 121 if ( SDL_JoystickInit() < 0 ) { 122 return(-1); 123 } 124 SDL_initialized |= SDL_INIT_JOYSTICK; 125 } 126 #else 127 if ( flags & SDL_INIT_JOYSTICK ) { 128 SDL_SetError("SDL not built with joystick support"); 129 return(-1); 130 } 131 #endif 132 133 #if !SDL_CDROM_DISABLED 134 /* Initialize the CD-ROM subsystem */ 135 if ( (flags & SDL_INIT_CDROM) && !(SDL_initialized & SDL_INIT_CDROM) ) { 136 if ( SDL_CDROMInit() < 0 ) { 137 return(-1); 138 } 139 SDL_initialized |= SDL_INIT_CDROM; 140 } 141 #else 142 if ( flags & SDL_INIT_CDROM ) { 143 SDL_SetError("SDL not built with cdrom support"); 144 return(-1); 145 } 146 #endif 147 return(0); 148 } 149 150 int SDL_Init(Uint32 flags) 151 { 152 #if !SDL_THREADS_DISABLED && SDL_THREAD_PTH 153 if (!pth_init()) { 154 return -1; 155 } 156 #endif 157 158 /* Clear the error message */ 159 SDL_ClearError(); 160 161 /* Initialize the desired subsystems */ 162 if ( SDL_InitSubSystem(flags) < 0 ) { 163 return(-1); 164 } 165 166 /* Everything is initialized */ 167 if ( !(flags & SDL_INIT_NOPARACHUTE) ) { 168 SDL_InstallParachute(); 169 } 170 return(0); 171 } 172 173 void SDL_QuitSubSystem(Uint32 flags) 174 { 175 /* Shut down requested initialized subsystems */ 176 #if !SDL_CDROM_DISABLED 177 if ( (flags & SDL_initialized & SDL_INIT_CDROM) ) { 178 SDL_CDROMQuit(); 179 SDL_initialized &= ~SDL_INIT_CDROM; 180 } 181 #endif 182 #if !SDL_JOYSTICK_DISABLED 183 if ( (flags & SDL_initialized & SDL_INIT_JOYSTICK) ) { 184 SDL_JoystickQuit(); 185 SDL_initialized &= ~SDL_INIT_JOYSTICK; 186 } 187 #endif 188 #if !SDL_AUDIO_DISABLED 189 if ( (flags & SDL_initialized & SDL_INIT_AUDIO) ) { 190 SDL_AudioQuit(); 191 SDL_initialized &= ~SDL_INIT_AUDIO; 192 } 193 #endif 194 #if !SDL_VIDEO_DISABLED 195 if ( (flags & SDL_initialized & SDL_INIT_VIDEO) ) { 196 SDL_VideoQuit(); 197 SDL_initialized &= ~SDL_INIT_VIDEO; 198 } 199 #endif 200 #if !SDL_TIMERS_DISABLED 201 if ( (flags & SDL_initialized & SDL_INIT_TIMER) ) { 202 SDL_TimerQuit(); 203 SDL_initialized &= ~SDL_INIT_TIMER; 204 } 205 #endif 206 } 207 208 Uint32 SDL_WasInit(Uint32 flags) 209 { 210 if ( ! flags ) { 211 flags = SDL_INIT_EVERYTHING; 212 } 213 return (SDL_initialized&flags); 214 } 215 216 void SDL_Quit(void) 217 { 218 /* Quit all subsystems */ 219 #ifdef DEBUG_BUILD 220 printf("[SDL_Quit] : Enter! Calling QuitSubSystem()\n"); fflush(stdout); 221 #endif 222 SDL_QuitSubSystem(SDL_INIT_EVERYTHING); 223 224 #ifdef CHECK_LEAKS 225 #ifdef DEBUG_BUILD 226 printf("[SDL_Quit] : CHECK_LEAKS\n"); fflush(stdout); 227 #endif 228 229 /* Print the number of surfaces not freed */ 230 if ( surfaces_allocated != 0 ) { 231 fprintf(stderr, "SDL Warning: %d SDL surfaces extant\n", 232 surfaces_allocated); 233 } 234 #endif 235 #ifdef DEBUG_BUILD 236 printf("[SDL_Quit] : SDL_UninstallParachute()\n"); fflush(stdout); 237 #endif 238 239 /* Uninstall any parachute signal handlers */ 240 SDL_UninstallParachute(); 241 242 #if !SDL_THREADS_DISABLED && SDL_THREAD_PTH 243 pth_kill(); 244 #endif 245 #ifdef DEBUG_BUILD 246 printf("[SDL_Quit] : Returning!\n"); fflush(stdout); 247 #endif 248 249 } 250 251 /* Return the library version number */ 252 const SDL_version * SDL_Linked_Version(void) 253 { 254 return(&version); 255 } 256 257 #if defined(__OS2__) 258 /* Building for OS/2 */ 259 #ifdef __WATCOMC__ 260 261 #define INCL_DOSERRORS 262 #define INCL_DOSEXCEPTIONS 263 #include <os2.h> 264 265 /* Exception handler to prevent the Audio thread hanging, making a zombie process! */ 266 ULONG _System SDL_Main_ExceptionHandler(PEXCEPTIONREPORTRECORD pERepRec, 267 PEXCEPTIONREGISTRATIONRECORD pERegRec, 268 PCONTEXTRECORD pCtxRec, 269 PVOID p) 270 { 271 if (pERepRec->fHandlerFlags & EH_EXIT_UNWIND) 272 return XCPT_CONTINUE_SEARCH; 273 if (pERepRec->fHandlerFlags & EH_UNWINDING) 274 return XCPT_CONTINUE_SEARCH; 275 if (pERepRec->fHandlerFlags & EH_NESTED_CALL) 276 return XCPT_CONTINUE_SEARCH; 277 278 /* Do cleanup at every fatal exception! */ 279 if (((pERepRec->ExceptionNum & XCPT_SEVERITY_CODE) == XCPT_FATAL_EXCEPTION) && 280 (pERepRec->ExceptionNum != XCPT_BREAKPOINT) && 281 (pERepRec->ExceptionNum != XCPT_SINGLE_STEP) 282 ) 283 { 284 if (SDL_initialized & SDL_INIT_AUDIO) 285 { 286 /* This removes the zombie audio thread in case of emergency. */ 287 #ifdef DEBUG_BUILD 288 printf("[SDL_Main_ExceptionHandler] : Calling SDL_CloseAudio()!\n"); 289 #endif 290 SDL_CloseAudio(); 291 } 292 } 293 return (XCPT_CONTINUE_SEARCH); 294 } 295 296 297 EXCEPTIONREGISTRATIONRECORD SDL_Main_xcpthand = {0, SDL_Main_ExceptionHandler}; 298 299 /* The main DLL entry for DLL Initialization and Uninitialization: */ 300 unsigned _System LibMain(unsigned hmod, unsigned termination) 301 { 302 if (termination) 303 { 304 #ifdef DEBUG_BUILD 305 /* printf("[SDL DLL Unintialization] : Removing exception handler\n"); */ 306 #endif 307 DosUnsetExceptionHandler(&SDL_Main_xcpthand); 308 return 1; 309 } else 310 { 311 #ifdef DEBUG_BUILD 312 /* Make stdout and stderr unbuffered! */ 313 setbuf(stdout, NULL); 314 setbuf(stderr, NULL); 315 #endif 316 /* Fire up exception handler */ 317 #ifdef DEBUG_BUILD 318 /* printf("[SDL DLL Initialization] : Setting exception handler\n"); */ 319 #endif 320 /* Set exception handler */ 321 DosSetExceptionHandler(&SDL_Main_xcpthand); 322 323 return 1; 324 } 325 } 326 #endif /* __WATCOMC__ */ 327 328 #elif defined(__WIN32__) && !defined(__SYMBIAN32__) 329 330 #if !defined(HAVE_LIBC) || (defined(__WATCOMC__) && defined(BUILD_DLL)) 331 /* Need to include DllMain() on Watcom C for some reason.. */ 332 #define WIN32_LEAN_AND_MEAN 333 #include <windows.h> 334 335 BOOL APIENTRY _DllMainCRTStartup( HANDLE hModule, 336 DWORD ul_reason_for_call, 337 LPVOID lpReserved ) 338 { 339 switch (ul_reason_for_call) { 340 case DLL_PROCESS_ATTACH: 341 case DLL_THREAD_ATTACH: 342 case DLL_THREAD_DETACH: 343 case DLL_PROCESS_DETACH: 344 break; 345 } 346 return TRUE; 347 } 348 #endif /* building DLL with Watcom C */ 349 350 #endif /* OS/2 elif __WIN32__ */ 351