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