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