medfall

A super great game engine
Log | Files | Refs

init.cc (8802B)


      1 //========================================================================
      2 // GLFW 3.3 - www.glfw.org
      3 //------------------------------------------------------------------------
      4 // Copyright (c) 2002-2006 Marcus Geelnard
      5 // Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
      6 //
      7 // This software is provided 'as-is', without any express or implied
      8 // warranty. In no event will the authors be held liable for any damages
      9 // arising from the use of this software.
     10 //
     11 // Permission is granted to anyone to use this software for any purpose,
     12 // including commercial applications, and to alter it and redistribute it
     13 // freely, subject to the following restrictions:
     14 //
     15 // 1. The origin of this software must not be misrepresented; you must not
     16 //    claim that you wrote the original software. If you use this software
     17 //    in a product, an acknowledgment in the product documentation would
     18 //    be appreciated but is not required.
     19 //
     20 // 2. Altered source versions must be plainly marked as such, and must not
     21 //    be misrepresented as being the original software.
     22 //
     23 // 3. This notice may not be removed or altered from any source
     24 //    distribution.
     25 //
     26 //========================================================================
     27 
     28 #include "internal.h"
     29 #include "mappings.h"
     30 
     31 #include <string.h>
     32 #include <stdlib.h>
     33 #include <stdio.h>
     34 #include <stdarg.h>
     35 #include <assert.h>
     36 
     37 
     38 // The global variables below comprise all global data in GLFW.
     39 // Any other global variable is a bug.
     40 
     41 // Global state shared between compilation units of GLFW
     42 //
     43 _GLFWlibrary _glfw = { GLFW_FALSE };
     44 
     45 // These are outside of _glfw so they can be used before initialization and
     46 // after termination
     47 //
     48 static _GLFWerror _glfwMainThreadError;
     49 static GLFWerrorfun _glfwErrorCallback;
     50 static _GLFWinitconfig _glfwInitHints =
     51 {
     52     GLFW_TRUE,      // hat buttons
     53     {
     54         GLFW_TRUE,  // macOS menu bar
     55         GLFW_TRUE   // macOS bundle chdir
     56     },
     57     {
     58         "",         // X11 WM_CLASS name
     59         ""          // X11 WM_CLASS class
     60     }
     61 };
     62 
     63 // Returns a generic string representation of the specified error
     64 //
     65 static const char* getErrorString(int code)
     66 {
     67     switch (code)
     68     {
     69         case GLFW_NOT_INITIALIZED:
     70             return "The GLFW library is not initialized";
     71         case GLFW_NO_CURRENT_CONTEXT:
     72             return "There is no current context";
     73         case GLFW_INVALID_ENUM:
     74             return "Invalid argument for enum parameter";
     75         case GLFW_INVALID_VALUE:
     76             return "Invalid value for parameter";
     77         case GLFW_OUT_OF_MEMORY:
     78             return "Out of memory";
     79         case GLFW_API_UNAVAILABLE:
     80             return "The requested API is unavailable";
     81         case GLFW_VERSION_UNAVAILABLE:
     82             return "The requested API version is unavailable";
     83         case GLFW_PLATFORM_ERROR:
     84             return "An undocumented platform-specific error occurred";
     85         case GLFW_FORMAT_UNAVAILABLE:
     86             return "The requested format is unavailable";
     87         case GLFW_NO_WINDOW_CONTEXT:
     88             return "The specified window has no context";
     89         default:
     90             return "ERROR: UNKNOWN GLFW ERROR";
     91     }
     92 }
     93 
     94 // Terminate the library
     95 //
     96 static void terminate(void)
     97 {
     98     int i;
     99 
    100     memset(&_glfw.callbacks, 0, sizeof(_glfw.callbacks));
    101 
    102     while (_glfw.windowListHead)
    103         glfwDestroyWindow((GLFWwindow*) _glfw.windowListHead);
    104 
    105     while (_glfw.cursorListHead)
    106         glfwDestroyCursor((GLFWcursor*) _glfw.cursorListHead);
    107 
    108     for (i = 0;  i < _glfw.monitorCount;  i++)
    109     {
    110         _GLFWmonitor* monitor = _glfw.monitors[i];
    111         if (monitor->originalRamp.size)
    112             _glfwPlatformSetGammaRamp(monitor, &monitor->originalRamp);
    113         _glfwFreeMonitor(monitor);
    114     }
    115 
    116     free(_glfw.monitors);
    117     _glfw.monitors = NULL;
    118     _glfw.monitorCount = 0;
    119 
    120     free(_glfw.mappings);
    121     _glfw.mappings = NULL;
    122     _glfw.mappingCount = 0;
    123 
    124     _glfwTerminateVulkan();
    125     _glfwPlatformTerminate();
    126 
    127     _glfw.initialized = GLFW_FALSE;
    128 
    129     while (_glfw.errorListHead)
    130     {
    131         _GLFWerror* error = _glfw.errorListHead;
    132         _glfw.errorListHead = error->next;
    133         free(error);
    134     }
    135 
    136     _glfwPlatformDestroyTls(&_glfw.contextSlot);
    137     _glfwPlatformDestroyTls(&_glfw.errorSlot);
    138     _glfwPlatformDestroyMutex(&_glfw.errorLock);
    139 
    140     memset(&_glfw, 0, sizeof(_glfw));
    141 }
    142 
    143 
    144 //////////////////////////////////////////////////////////////////////////
    145 //////                         GLFW event API                       //////
    146 //////////////////////////////////////////////////////////////////////////
    147 
    148 void _glfwInputError(int code, const char* format, ...)
    149 {
    150     _GLFWerror* error;
    151     char description[_GLFW_MESSAGE_SIZE];
    152 
    153     if (format)
    154     {
    155         int count;
    156         va_list vl;
    157 
    158         va_start(vl, format);
    159         count = vsnprintf(description, sizeof(description), format, vl);
    160         va_end(vl);
    161 
    162         if (count < 0)
    163             description[sizeof(description) - 1] = '\0';
    164     }
    165     else
    166         strcpy(description, getErrorString(code));
    167 
    168     if (_glfw.initialized)
    169     {
    170         error = _glfwPlatformGetTls(&_glfw.errorSlot);
    171         if (!error)
    172         {
    173             error = calloc(1, sizeof(_GLFWerror));
    174             _glfwPlatformSetTls(&_glfw.errorSlot, error);
    175             _glfwPlatformLockMutex(&_glfw.errorLock);
    176             error->next = _glfw.errorListHead;
    177             _glfw.errorListHead = error;
    178             _glfwPlatformUnlockMutex(&_glfw.errorLock);
    179         }
    180     }
    181     else
    182         error = &_glfwMainThreadError;
    183 
    184     error->code = code;
    185     strcpy(error->description, description);
    186 
    187     if (_glfwErrorCallback)
    188         _glfwErrorCallback(code, description);
    189 }
    190 
    191 
    192 //////////////////////////////////////////////////////////////////////////
    193 //////                        GLFW public API                       //////
    194 //////////////////////////////////////////////////////////////////////////
    195 
    196 GLFWAPI int glfwInit(void)
    197 {
    198     if (_glfw.initialized)
    199         return GLFW_TRUE;
    200 
    201     memset(&_glfw, 0, sizeof(_glfw));
    202     _glfw.hints.init = _glfwInitHints;
    203 
    204     if (!_glfwPlatformInit())
    205     {
    206         terminate();
    207         return GLFW_FALSE;
    208     }
    209 
    210     if (!_glfwPlatformCreateMutex(&_glfw.errorLock))
    211         return GLFW_FALSE;
    212     if (!_glfwPlatformCreateTls(&_glfw.errorSlot))
    213         return GLFW_FALSE;
    214     if (!_glfwPlatformCreateTls(&_glfw.contextSlot))
    215         return GLFW_FALSE;
    216 
    217     _glfwPlatformSetTls(&_glfw.errorSlot, &_glfwMainThreadError);
    218 
    219     _glfw.initialized = GLFW_TRUE;
    220     _glfw.timer.offset = _glfwPlatformGetTimerValue();
    221 
    222     glfwDefaultWindowHints();
    223     glfwUpdateGamepadMappings(_glfwDefaultMappings);
    224 
    225     return GLFW_TRUE;
    226 }
    227 
    228 GLFWAPI void glfwTerminate(void)
    229 {
    230     if (!_glfw.initialized)
    231         return;
    232 
    233     terminate();
    234 }
    235 
    236 GLFWAPI void glfwInitHint(int hint, int value)
    237 {
    238     switch (hint)
    239     {
    240         case GLFW_JOYSTICK_HAT_BUTTONS:
    241             _glfwInitHints.hatButtons = value;
    242             return;
    243         case GLFW_COCOA_CHDIR_RESOURCES:
    244             _glfwInitHints.ns.chdir = value;
    245             return;
    246         case GLFW_COCOA_MENUBAR:
    247             _glfwInitHints.ns.menubar = value;
    248             return;
    249     }
    250 
    251     _glfwInputError(GLFW_INVALID_ENUM,
    252                     "Invalid integer type init hint 0x%08X", hint);
    253 }
    254 
    255 GLFWAPI void glfwInitHintString(int hint, const char* value)
    256 {
    257     assert(value != NULL);
    258 
    259     switch (hint)
    260     {
    261         case GLFW_X11_WM_CLASS_NAME:
    262             strncpy(_glfwInitHints.x11.className, value,
    263                     sizeof(_glfwInitHints.x11.className) - 1);
    264             break;
    265         case GLFW_X11_WM_CLASS_CLASS:
    266             strncpy(_glfwInitHints.x11.classClass, value,
    267                     sizeof(_glfwInitHints.x11.classClass) - 1);
    268             break;
    269     }
    270 
    271     _glfwInputError(GLFW_INVALID_ENUM,
    272                     "Invalid string type init hint 0x%08X", hint);
    273 }
    274 
    275 GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev)
    276 {
    277     if (major != NULL)
    278         *major = GLFW_VERSION_MAJOR;
    279     if (minor != NULL)
    280         *minor = GLFW_VERSION_MINOR;
    281     if (rev != NULL)
    282         *rev = GLFW_VERSION_REVISION;
    283 }
    284 
    285 GLFWAPI const char* glfwGetVersionString(void)
    286 {
    287     return _glfwPlatformGetVersionString();
    288 }
    289 
    290 GLFWAPI int glfwGetError(const char** description)
    291 {
    292     _GLFWerror* error;
    293     int code = GLFW_NO_ERROR;
    294 
    295     if (description)
    296         *description = NULL;
    297 
    298     if (_glfw.initialized)
    299         error = _glfwPlatformGetTls(&_glfw.errorSlot);
    300     else
    301         error = &_glfwMainThreadError;
    302 
    303     if (error)
    304     {
    305         code = error->code;
    306         error->code = GLFW_NO_ERROR;
    307         if (description && code)
    308             *description = error->description;
    309     }
    310 
    311     return code;
    312 }
    313 
    314 GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun)
    315 {
    316     _GLFW_SWAP_POINTERS(_glfwErrorCallback, cbfun);
    317     return cbfun;
    318 }
    319