1/* 2 SDL - Simple DirectMedia Layer 3 Copyright (C) 1997-2006 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@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 38extern int SDL_JoystickInit(void); 39extern void SDL_JoystickQuit(void); 40#endif 41#if !SDL_CDROM_DISABLED 42extern int SDL_CDROMInit(void); 43extern void SDL_CDROMQuit(void); 44#endif 45#if !SDL_TIMERS_DISABLED 46extern void SDL_StartTicks(void); 47extern int SDL_TimerInit(void); 48extern void SDL_TimerQuit(void); 49#endif 50 51/* The current SDL version */ 52static SDL_version version = 53 { SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL }; 54 55/* The initialized subsystems */ 56static Uint32 SDL_initialized = 0; 57#if !SDL_TIMERS_DISABLED 58static Uint32 ticks_started = 0; 59#endif 60 61#ifdef CHECK_LEAKS 62int surfaces_allocated = 0; 63#endif 64 65int SDL_InitSubSystem(Uint32 flags) 66{ 67#if !SDL_VIDEO_DISABLED 68 /* Initialize the video/event subsystem */ 69 if ( (flags & SDL_INIT_VIDEO) && !(SDL_initialized & SDL_INIT_VIDEO) ) { 70 if ( SDL_VideoInit(SDL_getenv("SDL_VIDEODRIVER"), 71 (flags&SDL_INIT_EVENTTHREAD)) < 0 ) { 72 return(-1); 73 } 74 SDL_initialized |= SDL_INIT_VIDEO; 75 } 76#else 77 if ( flags & SDL_INIT_VIDEO ) { 78 SDL_SetError("SDL not built with video support"); 79 return(-1); 80 } 81#endif 82 83#if !SDL_AUDIO_DISABLED 84 /* Initialize the audio subsystem */ 85 if ( (flags & SDL_INIT_AUDIO) && !(SDL_initialized & SDL_INIT_AUDIO) ) { 86 if ( SDL_AudioInit(SDL_getenv("SDL_AUDIODRIVER")) < 0 ) { 87 return(-1); 88 } 89 SDL_initialized |= SDL_INIT_AUDIO; 90 } 91#else 92 if ( flags & SDL_INIT_AUDIO ) { 93 SDL_SetError("SDL not built with audio support"); 94 return(-1); 95 } 96#endif 97 98#if !SDL_TIMERS_DISABLED 99 /* Initialize the timer subsystem */ 100 if ( ! ticks_started ) { 101 SDL_StartTicks(); 102 ticks_started = 1; 103 } 104 if ( (flags & SDL_INIT_TIMER) && !(SDL_initialized & SDL_INIT_TIMER) ) { 105 if ( SDL_TimerInit() < 0 ) { 106 return(-1); 107 } 108 SDL_initialized |= SDL_INIT_TIMER; 109 } 110#else 111 if ( flags & SDL_INIT_TIMER ) { 112 SDL_SetError("SDL not built with timer 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 150int 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 173void 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_TIMERS_DISABLED 189 if ( (flags & SDL_initialized & SDL_INIT_TIMER) ) { 190 SDL_TimerQuit(); 191 SDL_initialized &= ~SDL_INIT_TIMER; 192 } 193#endif 194#if !SDL_AUDIO_DISABLED 195 if ( (flags & SDL_initialized & SDL_INIT_AUDIO) ) { 196 SDL_AudioQuit(); 197 SDL_initialized &= ~SDL_INIT_AUDIO; 198 } 199#endif 200#if !SDL_VIDEO_DISABLED 201 if ( (flags & SDL_initialized & SDL_INIT_VIDEO) ) { 202 SDL_VideoQuit(); 203 SDL_initialized &= ~SDL_INIT_VIDEO; 204 } 205#endif 206} 207 208Uint32 SDL_WasInit(Uint32 flags) 209{ 210 if ( ! flags ) { 211 flags = SDL_INIT_EVERYTHING; 212 } 213 return (SDL_initialized&flags); 214} 215 216void 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 */ 252const 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! */ 266ULONG _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 297EXCEPTIONREGISTRATIONRECORD SDL_Main_xcpthand = {0, SDL_Main_ExceptionHandler}; 298 299/* The main DLL entry for DLL Initialization and Uninitialization: */ 300unsigned _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 335BOOL 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