src/SDL.c
author Ryan C. Gordon <icculus@icculus.org>
Sun, 31 Mar 2013 12:48:50 -0400
changeset 7037 3fedf1f25b94
parent 7011 82bbfbbc720e
child 7110 2a98852fd58d
permissions -rw-r--r--
Make SDL_SetError and friends unconditionally return -1.

This lets us change things like this...

if (Failed) {
SDL_SetError("We failed");
return -1;
}

...into this...

if (Failed) {
return SDL_SetError("We failed");
}


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