Merge commit '26c8cc348eacea01237cd64e1a68d0df8141e848'
This commit is contained in:
280
deps/glfw/src/init.c
vendored
280
deps/glfw/src/init.c
vendored
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 - www.glfw.org
|
||||
// GLFW 3.4 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
|
||||
@ -24,8 +24,6 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// Please use C89 style variable declarations in this file because VS 2010
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@ -48,15 +46,49 @@ _GLFWlibrary _glfw = { GLFW_FALSE };
|
||||
//
|
||||
static _GLFWerror _glfwMainThreadError;
|
||||
static GLFWerrorfun _glfwErrorCallback;
|
||||
static GLFWallocator _glfwInitAllocator;
|
||||
static _GLFWinitconfig _glfwInitHints =
|
||||
{
|
||||
GLFW_TRUE, // hat buttons
|
||||
.hatButtons = GLFW_TRUE,
|
||||
.angleType = GLFW_ANGLE_PLATFORM_TYPE_NONE,
|
||||
.platformID = GLFW_ANY_PLATFORM,
|
||||
.vulkanLoader = NULL,
|
||||
.ns =
|
||||
{
|
||||
GLFW_TRUE, // macOS menu bar
|
||||
GLFW_TRUE // macOS bundle chdir
|
||||
}
|
||||
.menubar = GLFW_TRUE,
|
||||
.chdir = GLFW_TRUE
|
||||
},
|
||||
.x11 =
|
||||
{
|
||||
.xcbVulkanSurface = GLFW_TRUE,
|
||||
},
|
||||
.wl =
|
||||
{
|
||||
.libdecorMode = GLFW_WAYLAND_PREFER_LIBDECOR
|
||||
},
|
||||
};
|
||||
|
||||
// The allocation function used when no custom allocator is set
|
||||
//
|
||||
static void* defaultAllocate(size_t size, void* user)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
// The deallocation function used when no custom allocator is set
|
||||
//
|
||||
static void defaultDeallocate(void* block, void* user)
|
||||
{
|
||||
free(block);
|
||||
}
|
||||
|
||||
// The reallocation function used when no custom allocator is set
|
||||
//
|
||||
static void* defaultReallocate(void* block, size_t size, void* user)
|
||||
{
|
||||
return realloc(block, size);
|
||||
}
|
||||
|
||||
// Terminate the library
|
||||
//
|
||||
static void terminate(void)
|
||||
@ -75,20 +107,21 @@ static void terminate(void)
|
||||
{
|
||||
_GLFWmonitor* monitor = _glfw.monitors[i];
|
||||
if (monitor->originalRamp.size)
|
||||
_glfwPlatformSetGammaRamp(monitor, &monitor->originalRamp);
|
||||
_glfw.platform.setGammaRamp(monitor, &monitor->originalRamp);
|
||||
_glfwFreeMonitor(monitor);
|
||||
}
|
||||
|
||||
free(_glfw.monitors);
|
||||
_glfw_free(_glfw.monitors);
|
||||
_glfw.monitors = NULL;
|
||||
_glfw.monitorCount = 0;
|
||||
|
||||
free(_glfw.mappings);
|
||||
_glfw_free(_glfw.mappings);
|
||||
_glfw.mappings = NULL;
|
||||
_glfw.mappingCount = 0;
|
||||
|
||||
_glfwTerminateVulkan();
|
||||
_glfwPlatformTerminate();
|
||||
_glfw.platform.terminateJoysticks();
|
||||
_glfw.platform.terminate();
|
||||
|
||||
_glfw.initialized = GLFW_FALSE;
|
||||
|
||||
@ -96,7 +129,7 @@ static void terminate(void)
|
||||
{
|
||||
_GLFWerror* error = _glfw.errorListHead;
|
||||
_glfw.errorListHead = error->next;
|
||||
free(error);
|
||||
_glfw_free(error);
|
||||
}
|
||||
|
||||
_glfwPlatformDestroyTls(&_glfw.contextSlot);
|
||||
@ -111,36 +144,159 @@ static void terminate(void)
|
||||
////// GLFW internal API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Encode a Unicode code point to a UTF-8 stream
|
||||
// Based on cutef8 by Jeff Bezanson (Public Domain)
|
||||
//
|
||||
size_t _glfwEncodeUTF8(char* s, uint32_t codepoint)
|
||||
{
|
||||
size_t count = 0;
|
||||
|
||||
if (codepoint < 0x80)
|
||||
s[count++] = (char) codepoint;
|
||||
else if (codepoint < 0x800)
|
||||
{
|
||||
s[count++] = (codepoint >> 6) | 0xc0;
|
||||
s[count++] = (codepoint & 0x3f) | 0x80;
|
||||
}
|
||||
else if (codepoint < 0x10000)
|
||||
{
|
||||
s[count++] = (codepoint >> 12) | 0xe0;
|
||||
s[count++] = ((codepoint >> 6) & 0x3f) | 0x80;
|
||||
s[count++] = (codepoint & 0x3f) | 0x80;
|
||||
}
|
||||
else if (codepoint < 0x110000)
|
||||
{
|
||||
s[count++] = (codepoint >> 18) | 0xf0;
|
||||
s[count++] = ((codepoint >> 12) & 0x3f) | 0x80;
|
||||
s[count++] = ((codepoint >> 6) & 0x3f) | 0x80;
|
||||
s[count++] = (codepoint & 0x3f) | 0x80;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
// Splits and translates a text/uri-list into separate file paths
|
||||
// NOTE: This function destroys the provided string
|
||||
//
|
||||
char** _glfwParseUriList(char* text, int* count)
|
||||
{
|
||||
const char* prefix = "file://";
|
||||
char** paths = NULL;
|
||||
char* line;
|
||||
|
||||
*count = 0;
|
||||
|
||||
while ((line = strtok(text, "\r\n")))
|
||||
{
|
||||
char* path;
|
||||
|
||||
text = NULL;
|
||||
|
||||
if (line[0] == '#')
|
||||
continue;
|
||||
|
||||
if (strncmp(line, prefix, strlen(prefix)) == 0)
|
||||
{
|
||||
line += strlen(prefix);
|
||||
// TODO: Validate hostname
|
||||
while (*line != '/')
|
||||
line++;
|
||||
}
|
||||
|
||||
(*count)++;
|
||||
|
||||
path = _glfw_calloc(strlen(line) + 1, 1);
|
||||
paths = _glfw_realloc(paths, *count * sizeof(char*));
|
||||
paths[*count - 1] = path;
|
||||
|
||||
while (*line)
|
||||
{
|
||||
if (line[0] == '%' && line[1] && line[2])
|
||||
{
|
||||
const char digits[3] = { line[1], line[2], '\0' };
|
||||
*path = (char) strtol(digits, NULL, 16);
|
||||
line += 2;
|
||||
}
|
||||
else
|
||||
*path = *line;
|
||||
|
||||
path++;
|
||||
line++;
|
||||
}
|
||||
}
|
||||
|
||||
return paths;
|
||||
}
|
||||
|
||||
char* _glfw_strdup(const char* source)
|
||||
{
|
||||
const size_t length = strlen(source);
|
||||
char* result = calloc(length + 1, 1);
|
||||
char* result = _glfw_calloc(length + 1, 1);
|
||||
strcpy(result, source);
|
||||
return result;
|
||||
}
|
||||
|
||||
float _glfw_fminf(float a, float b)
|
||||
int _glfw_min(int a, int b)
|
||||
{
|
||||
if (a != a)
|
||||
return b;
|
||||
else if (b != b)
|
||||
return a;
|
||||
else if (a < b)
|
||||
return a;
|
||||
else
|
||||
return b;
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
float _glfw_fmaxf(float a, float b)
|
||||
int _glfw_max(int a, int b)
|
||||
{
|
||||
if (a != a)
|
||||
return b;
|
||||
else if (b != b)
|
||||
return a;
|
||||
else if (a > b)
|
||||
return a;
|
||||
return a > b ? a : b;
|
||||
}
|
||||
|
||||
void* _glfw_calloc(size_t count, size_t size)
|
||||
{
|
||||
if (count && size)
|
||||
{
|
||||
void* block;
|
||||
|
||||
if (count > SIZE_MAX / size)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_VALUE, "Allocation size overflow");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
block = _glfw.allocator.allocate(count * size, _glfw.allocator.user);
|
||||
if (block)
|
||||
return memset(block, 0, count * size);
|
||||
else
|
||||
{
|
||||
_glfwInputError(GLFW_OUT_OF_MEMORY, NULL);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
return b;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void* _glfw_realloc(void* block, size_t size)
|
||||
{
|
||||
if (block && size)
|
||||
{
|
||||
void* resized = _glfw.allocator.reallocate(block, size, _glfw.allocator.user);
|
||||
if (resized)
|
||||
return resized;
|
||||
else
|
||||
{
|
||||
_glfwInputError(GLFW_OUT_OF_MEMORY, NULL);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else if (block)
|
||||
{
|
||||
_glfw_free(block);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
return _glfw_calloc(1, size);
|
||||
}
|
||||
|
||||
void _glfw_free(void* block)
|
||||
{
|
||||
if (block)
|
||||
_glfw.allocator.deallocate(block, _glfw.allocator.user);
|
||||
}
|
||||
|
||||
|
||||
@ -187,6 +343,14 @@ void _glfwInputError(int code, const char* format, ...)
|
||||
strcpy(description, "The requested format is unavailable");
|
||||
else if (code == GLFW_NO_WINDOW_CONTEXT)
|
||||
strcpy(description, "The specified window has no context");
|
||||
else if (code == GLFW_CURSOR_UNAVAILABLE)
|
||||
strcpy(description, "The specified cursor shape is unavailable");
|
||||
else if (code == GLFW_FEATURE_UNAVAILABLE)
|
||||
strcpy(description, "The requested feature cannot be implemented for this platform");
|
||||
else if (code == GLFW_FEATURE_UNIMPLEMENTED)
|
||||
strcpy(description, "The requested feature has not yet been implemented for this platform");
|
||||
else if (code == GLFW_PLATFORM_UNAVAILABLE)
|
||||
strcpy(description, "The requested platform is unavailable");
|
||||
else
|
||||
strcpy(description, "ERROR: UNKNOWN GLFW ERROR");
|
||||
}
|
||||
@ -196,7 +360,7 @@ void _glfwInputError(int code, const char* format, ...)
|
||||
error = _glfwPlatformGetTls(&_glfw.errorSlot);
|
||||
if (!error)
|
||||
{
|
||||
error = calloc(1, sizeof(_GLFWerror));
|
||||
error = _glfw_calloc(1, sizeof(_GLFWerror));
|
||||
_glfwPlatformSetTls(&_glfw.errorSlot, error);
|
||||
_glfwPlatformLockMutex(&_glfw.errorLock);
|
||||
error->next = _glfw.errorListHead;
|
||||
@ -227,7 +391,18 @@ GLFWAPI int glfwInit(void)
|
||||
memset(&_glfw, 0, sizeof(_glfw));
|
||||
_glfw.hints.init = _glfwInitHints;
|
||||
|
||||
if (!_glfwPlatformInit())
|
||||
_glfw.allocator = _glfwInitAllocator;
|
||||
if (!_glfw.allocator.allocate)
|
||||
{
|
||||
_glfw.allocator.allocate = defaultAllocate;
|
||||
_glfw.allocator.reallocate = defaultReallocate;
|
||||
_glfw.allocator.deallocate = defaultDeallocate;
|
||||
}
|
||||
|
||||
if (!_glfwSelectPlatform(_glfw.hints.init.platformID, &_glfw.platform))
|
||||
return GLFW_FALSE;
|
||||
|
||||
if (!_glfw.platform.init())
|
||||
{
|
||||
terminate();
|
||||
return GLFW_FALSE;
|
||||
@ -245,9 +420,11 @@ GLFWAPI int glfwInit(void)
|
||||
|
||||
_glfwInitGamepadMappings();
|
||||
|
||||
_glfw.initialized = GLFW_TRUE;
|
||||
_glfwPlatformInitTimer();
|
||||
_glfw.timer.offset = _glfwPlatformGetTimerValue();
|
||||
|
||||
_glfw.initialized = GLFW_TRUE;
|
||||
|
||||
glfwDefaultWindowHints();
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
@ -267,18 +444,48 @@ GLFWAPI void glfwInitHint(int hint, int value)
|
||||
case GLFW_JOYSTICK_HAT_BUTTONS:
|
||||
_glfwInitHints.hatButtons = value;
|
||||
return;
|
||||
case GLFW_ANGLE_PLATFORM_TYPE:
|
||||
_glfwInitHints.angleType = value;
|
||||
return;
|
||||
case GLFW_PLATFORM:
|
||||
_glfwInitHints.platformID = value;
|
||||
return;
|
||||
case GLFW_COCOA_CHDIR_RESOURCES:
|
||||
_glfwInitHints.ns.chdir = value;
|
||||
return;
|
||||
case GLFW_COCOA_MENUBAR:
|
||||
_glfwInitHints.ns.menubar = value;
|
||||
return;
|
||||
case GLFW_X11_XCB_VULKAN_SURFACE:
|
||||
_glfwInitHints.x11.xcbVulkanSurface = value;
|
||||
return;
|
||||
case GLFW_WAYLAND_LIBDECOR:
|
||||
_glfwInitHints.wl.libdecorMode = value;
|
||||
return;
|
||||
}
|
||||
|
||||
_glfwInputError(GLFW_INVALID_ENUM,
|
||||
"Invalid init hint 0x%08X", hint);
|
||||
}
|
||||
|
||||
GLFWAPI void glfwInitAllocator(const GLFWallocator* allocator)
|
||||
{
|
||||
if (allocator)
|
||||
{
|
||||
if (allocator->allocate && allocator->reallocate && allocator->deallocate)
|
||||
_glfwInitAllocator = *allocator;
|
||||
else
|
||||
_glfwInputError(GLFW_INVALID_VALUE, "Missing function in allocator");
|
||||
}
|
||||
else
|
||||
memset(&_glfwInitAllocator, 0, sizeof(GLFWallocator));
|
||||
}
|
||||
|
||||
GLFWAPI void glfwInitVulkanLoader(PFN_vkGetInstanceProcAddr loader)
|
||||
{
|
||||
_glfwInitHints.vulkanLoader = loader;
|
||||
}
|
||||
|
||||
GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev)
|
||||
{
|
||||
if (major != NULL)
|
||||
@ -289,11 +496,6 @@ GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev)
|
||||
*rev = GLFW_VERSION_REVISION;
|
||||
}
|
||||
|
||||
GLFWAPI const char* glfwGetVersionString(void)
|
||||
{
|
||||
return _glfwPlatformGetVersionString();
|
||||
}
|
||||
|
||||
GLFWAPI int glfwGetError(const char** description)
|
||||
{
|
||||
_GLFWerror* error;
|
||||
@ -320,7 +522,7 @@ GLFWAPI int glfwGetError(const char** description)
|
||||
|
||||
GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun)
|
||||
{
|
||||
_GLFW_SWAP_POINTERS(_glfwErrorCallback, cbfun);
|
||||
_GLFW_SWAP(GLFWerrorfun, _glfwErrorCallback, cbfun);
|
||||
return cbfun;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user