src/SDL.c
author Ryan C. Gordon
Wed, 23 Nov 2005 07:29:56 +0000
changeset 1190 173c063d4f55
parent 769 b8d311d90021
child 1312 c9b51268668f
permissions -rw-r--r--
OS/2 port!

This was mostly, if not entirely, written by "Doodle" and "Caetano":
doodle@scenergy.dfmk.hu
daniel@caetano.eng.br

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