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