src/SDL.c
author Ryan C. Gordon <icculus@icculus.org>
Sat, 01 Apr 2017 00:46:15 -0400
changeset 10954 b2804f1267bb
parent 10925 4de9d54bbc87
child 10955 82bec2d58a45
permissions -rw-r--r--
Intentionally breaking buildbot to test email server change.
     1 sdfsdf
     2 /*
     3   Simple DirectMedia Layer
     4   Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
     5 
     6   This software is provided 'as-is', without any express or implied
     7   warranty.  In no event will the authors be held liable for any damages
     8   arising from the use of this software.
     9 
    10   Permission is granted to anyone to use this software for any purpose,
    11   including commercial applications, and to alter it and redistribute it
    12   freely, subject to the following restrictions:
    13 
    14   1. The origin of this software must not be misrepresented; you must not
    15      claim that you wrote the original software. If you use this software
    16      in a product, an acknowledgment in the product documentation would be
    17      appreciated but is not required.
    18   2. Altered source versions must be plainly marked as such, and must not be
    19      misrepresented as being the original software.
    20   3. This notice may not be removed or altered from any source distribution.
    21 */
    22 #include "./SDL_internal.h"
    23 
    24 #if defined(__WIN32__)
    25 #include "core/windows/SDL_windows.h"
    26 #endif
    27 
    28 /* Initialization code for SDL */
    29 
    30 #include "SDL.h"
    31 #include "SDL_bits.h"
    32 #include "SDL_revision.h"
    33 #include "SDL_assert_c.h"
    34 #include "events/SDL_events_c.h"
    35 #include "haptic/SDL_haptic_c.h"
    36 #include "joystick/SDL_joystick_c.h"
    37 
    38 /* Initialization/Cleanup routines */
    39 #if !SDL_TIMERS_DISABLED
    40 # include "timer/SDL_timer_c.h"
    41 #endif
    42 #if SDL_VIDEO_DRIVER_WINDOWS
    43 extern int SDL_HelperWindowCreate(void);
    44 extern int SDL_HelperWindowDestroy(void);
    45 #endif
    46 
    47 
    48 /* The initialized subsystems */
    49 #ifdef SDL_MAIN_NEEDED
    50 static SDL_bool SDL_MainIsReady = SDL_FALSE;
    51 #else
    52 static SDL_bool SDL_MainIsReady = SDL_TRUE;
    53 #endif
    54 static SDL_bool SDL_bInMainQuit = SDL_FALSE;
    55 static Uint8 SDL_SubsystemRefCount[ 32 ];
    56 
    57 /* Private helper to increment a subsystem's ref counter. */
    58 static void
    59 SDL_PrivateSubsystemRefCountIncr(Uint32 subsystem)
    60 {
    61     int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
    62     SDL_assert(SDL_SubsystemRefCount[subsystem_index] < 255);
    63     ++SDL_SubsystemRefCount[subsystem_index];
    64 }
    65 
    66 /* Private helper to decrement a subsystem's ref counter. */
    67 static void
    68 SDL_PrivateSubsystemRefCountDecr(Uint32 subsystem)
    69 {
    70     int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
    71     if (SDL_SubsystemRefCount[subsystem_index] > 0) {
    72         --SDL_SubsystemRefCount[subsystem_index];
    73     }
    74 }
    75 
    76 /* Private helper to check if a system needs init. */
    77 static SDL_bool
    78 SDL_PrivateShouldInitSubsystem(Uint32 subsystem)
    79 {
    80     int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
    81     SDL_assert(SDL_SubsystemRefCount[subsystem_index] < 255);
    82     return (SDL_SubsystemRefCount[subsystem_index] == 0) ? SDL_TRUE : SDL_FALSE;
    83 }
    84 
    85 /* Private helper to check if a system needs to be quit. */
    86 static SDL_bool
    87 SDL_PrivateShouldQuitSubsystem(Uint32 subsystem) {
    88     int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
    89     if (SDL_SubsystemRefCount[subsystem_index] == 0) {
    90       return SDL_FALSE;
    91     }
    92 
    93     /* If we're in SDL_Quit, we shut down every subsystem, even if refcount
    94      * isn't zero.
    95      */
    96     return (SDL_SubsystemRefCount[subsystem_index] == 1 || SDL_bInMainQuit) ? SDL_TRUE : SDL_FALSE;
    97 }
    98 
    99 void
   100 SDL_SetMainReady(void)
   101 {
   102     SDL_MainIsReady = SDL_TRUE;
   103 }
   104 
   105 int
   106 SDL_InitSubSystem(Uint32 flags)
   107 {
   108     if (!SDL_MainIsReady) {
   109         SDL_SetError("Application didn't initialize properly, did you include SDL_main.h in the file containing your main() function?");
   110         return -1;
   111     }
   112 
   113     /* Clear the error message */
   114     SDL_ClearError();
   115 
   116     if ((flags & SDL_INIT_GAMECONTROLLER)) {
   117         /* game controller implies joystick */
   118         flags |= SDL_INIT_JOYSTICK;
   119     }
   120 
   121     if ((flags & (SDL_INIT_VIDEO|SDL_INIT_JOYSTICK))) {
   122         /* video or joystick implies events */
   123         flags |= SDL_INIT_EVENTS;
   124     }
   125 
   126 #if SDL_VIDEO_DRIVER_WINDOWS
   127 	if ((flags & (SDL_INIT_HAPTIC|SDL_INIT_JOYSTICK))) {
   128 		if (SDL_HelperWindowCreate() < 0) {
   129 			return -1;
   130 		}
   131 	}
   132 #endif
   133 
   134 #if !SDL_TIMERS_DISABLED
   135     SDL_TicksInit();
   136 #endif
   137 
   138     /* Initialize the event subsystem */
   139     if ((flags & SDL_INIT_EVENTS)) {
   140 #if !SDL_EVENTS_DISABLED
   141         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_EVENTS)) {
   142             if (SDL_StartEventLoop() < 0) {
   143                 return (-1);
   144             }
   145             SDL_QuitInit();
   146         }
   147         SDL_PrivateSubsystemRefCountIncr(SDL_INIT_EVENTS);
   148 #else
   149         return SDL_SetError("SDL not built with events support");
   150 #endif
   151     }
   152 
   153     /* Initialize the timer subsystem */
   154     if ((flags & SDL_INIT_TIMER)){
   155 #if !SDL_TIMERS_DISABLED
   156         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_TIMER)) {
   157             if (SDL_TimerInit() < 0) {
   158                 return (-1);
   159             }
   160         }
   161         SDL_PrivateSubsystemRefCountIncr(SDL_INIT_TIMER);
   162 #else
   163         return SDL_SetError("SDL not built with timer support");
   164 #endif
   165     }
   166 
   167     /* Initialize the video subsystem */
   168     if ((flags & SDL_INIT_VIDEO)){
   169 #if !SDL_VIDEO_DISABLED
   170         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_VIDEO)) {
   171             if (SDL_VideoInit(NULL) < 0) {
   172                 return (-1);
   173             }
   174         }
   175         SDL_PrivateSubsystemRefCountIncr(SDL_INIT_VIDEO);
   176 #else
   177         return SDL_SetError("SDL not built with video support");
   178 #endif
   179     }
   180 
   181     /* Initialize the audio subsystem */
   182     if ((flags & SDL_INIT_AUDIO)){
   183 #if !SDL_AUDIO_DISABLED
   184         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_AUDIO)) {
   185             if (SDL_AudioInit(NULL) < 0) {
   186                 return (-1);
   187             }
   188         }
   189         SDL_PrivateSubsystemRefCountIncr(SDL_INIT_AUDIO);
   190 #else
   191         return SDL_SetError("SDL not built with audio support");
   192 #endif
   193     }
   194 
   195     /* Initialize the joystick subsystem */
   196     if ((flags & SDL_INIT_JOYSTICK)){
   197 #if !SDL_JOYSTICK_DISABLED
   198         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_JOYSTICK)) {
   199            if (SDL_JoystickInit() < 0) {
   200                return (-1);
   201            }
   202         }
   203         SDL_PrivateSubsystemRefCountIncr(SDL_INIT_JOYSTICK);
   204 #else
   205         return SDL_SetError("SDL not built with joystick support");
   206 #endif
   207     }
   208 
   209     if ((flags & SDL_INIT_GAMECONTROLLER)){
   210 #if !SDL_JOYSTICK_DISABLED
   211         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_GAMECONTROLLER)) {
   212             if (SDL_GameControllerInit() < 0) {
   213                 return (-1);
   214             }
   215         }
   216         SDL_PrivateSubsystemRefCountIncr(SDL_INIT_GAMECONTROLLER);
   217 #else
   218         return SDL_SetError("SDL not built with joystick support");
   219 #endif
   220     }
   221 
   222     /* Initialize the haptic subsystem */
   223     if ((flags & SDL_INIT_HAPTIC)){
   224 #if !SDL_HAPTIC_DISABLED
   225         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_HAPTIC)) {
   226             if (SDL_HapticInit() < 0) {
   227                 return (-1);
   228             }
   229         }
   230         SDL_PrivateSubsystemRefCountIncr(SDL_INIT_HAPTIC);
   231 #else
   232         return SDL_SetError("SDL not built with haptic (force feedback) support");
   233 #endif
   234     }
   235 
   236     return (0);
   237 }
   238 
   239 int
   240 SDL_Init(Uint32 flags)
   241 {
   242     return SDL_InitSubSystem(flags);
   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 #if !SDL_TIMERS_DISABLED
   358     SDL_TicksQuit();
   359 #endif
   360 
   361     SDL_ClearHints();
   362     SDL_AssertionsQuit();
   363     SDL_LogResetPriorities();
   364 
   365     /* Now that every subsystem has been quit, we reset the subsystem refcount
   366      * and the list of initialized subsystems.
   367      */
   368     SDL_memset( SDL_SubsystemRefCount, 0x0, sizeof(SDL_SubsystemRefCount) );
   369 
   370     SDL_bInMainQuit = SDL_FALSE;
   371 }
   372 
   373 /* Get the library version number */
   374 void
   375 SDL_GetVersion(SDL_version * ver)
   376 {
   377     SDL_VERSION(ver);
   378 }
   379 
   380 /* Get the library source revision */
   381 const char *
   382 SDL_GetRevision(void)
   383 {
   384     return SDL_REVISION;
   385 }
   386 
   387 /* Get the library source revision number */
   388 int
   389 SDL_GetRevisionNumber(void)
   390 {
   391     return SDL_REVISION_NUMBER;
   392 }
   393 
   394 /* Get the name of the platform */
   395 const char *
   396 SDL_GetPlatform()
   397 {
   398 #if __AIX__
   399     return "AIX";
   400 #elif __ANDROID__
   401     return "Android";
   402 #elif __BSDI__
   403     return "BSDI";
   404 #elif __DREAMCAST__
   405     return "Dreamcast";
   406 #elif __EMSCRIPTEN__
   407     return "Emscripten";
   408 #elif __FREEBSD__
   409     return "FreeBSD";
   410 #elif __HAIKU__
   411     return "Haiku";
   412 #elif __HPUX__
   413     return "HP-UX";
   414 #elif __IRIX__
   415     return "Irix";
   416 #elif __LINUX__
   417     return "Linux";
   418 #elif __MINT__
   419     return "Atari MiNT";
   420 #elif __MACOS__
   421     return "MacOS Classic";
   422 #elif __MACOSX__
   423     return "Mac OS X";
   424 #elif __NACL__
   425     return "NaCl";
   426 #elif __NETBSD__
   427     return "NetBSD";
   428 #elif __OPENBSD__
   429     return "OpenBSD";
   430 #elif __OS2__
   431     return "OS/2";
   432 #elif __OSF__
   433     return "OSF/1";
   434 #elif __QNXNTO__
   435     return "QNX Neutrino";
   436 #elif __RISCOS__
   437     return "RISC OS";
   438 #elif __SOLARIS__
   439     return "Solaris";
   440 #elif __WIN32__
   441     return "Windows";
   442 #elif __WINRT__
   443     return "WinRT";
   444 #elif __TVOS__
   445     return "tvOS";
   446 #elif __IPHONEOS__
   447     return "iOS";
   448 #elif __PSP__
   449     return "PlayStation Portable";
   450 #else
   451     return "Unknown (see SDL_platform.h)";
   452 #endif
   453 }
   454 
   455 #if defined(__WIN32__)
   456 
   457 #if !defined(HAVE_LIBC) || (defined(__WATCOMC__) && defined(BUILD_DLL))
   458 /* Need to include DllMain() on Watcom C for some reason.. */
   459 
   460 BOOL APIENTRY
   461 _DllMainCRTStartup(HANDLE hModule,
   462                    DWORD ul_reason_for_call, LPVOID lpReserved)
   463 {
   464     switch (ul_reason_for_call) {
   465     case DLL_PROCESS_ATTACH:
   466     case DLL_THREAD_ATTACH:
   467     case DLL_THREAD_DETACH:
   468     case DLL_PROCESS_DETACH:
   469         break;
   470     }
   471     return TRUE;
   472 }
   473 #endif /* building DLL with Watcom C */
   474 
   475 #endif /* __WIN32__ */
   476 
   477 /* vi: set sts=4 ts=4 sw=4 expandtab: */