mirror of
https://github.com/glfw/glfw.git
synced 2024-11-10 00:51:47 +00:00
Add pluggable heap allocator
This adds the glfwInitAllocator function for specifying a custom memory allocator to use instead of the C runtime library. The allocator is a struct of type GLFWallocator with fields corresponding to malloc, realloc and free, while the internal API corresponds to calloc, realloc and free. Heap allocation calls are filtered before reaching the user-provided functions, so deallocation of NULL and allocations of zero bytes are not passed on, reallocating NULL is transformed into an allocation and reallocating to size zero is transformed into deallocation. The clearing of a new block to zero is performed by the internal calloc-like function. Closes #544. Fixes #1628. Closes #1947.
This commit is contained in:
parent
4e557437f2
commit
22b586b3d8
@ -116,6 +116,9 @@ information on what to include when reporting a bug.
|
||||
|
||||
## Changelog
|
||||
|
||||
- Added `glfwInitAllocator` for setting a custom memory allocator (#544,#1628,#1947)
|
||||
- Added `GLFWallocator` struct and `GLFWallocatefun`, `GLFWreallocatefun` and
|
||||
`GLFWdeallocatefun` types (#544,#1628,#1947)
|
||||
- Added `GLFW_RESIZE_NWSE_CURSOR`, `GLFW_RESIZE_NESW_CURSOR`,
|
||||
`GLFW_RESIZE_ALL_CURSOR` and `GLFW_NOT_ALLOWED_CURSOR` cursor shapes (#427)
|
||||
- Added `GLFW_RESIZE_EW_CURSOR` alias for `GLFW_HRESIZE_CURSOR` (#427)
|
||||
|
@ -33,6 +33,7 @@ successfully initialized, and only from the main thread.
|
||||
- @ref glfwGetError
|
||||
- @ref glfwSetErrorCallback
|
||||
- @ref glfwInitHint
|
||||
- @ref glfwInitAllocator
|
||||
- @ref glfwInit
|
||||
- @ref glfwTerminate
|
||||
|
||||
@ -143,6 +144,64 @@ Initialization hint | Default value | Supported v
|
||||
@ref GLFW_X11_XCB_VULKAN_SURFACE | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||
|
||||
|
||||
@subsection init_allocator Custom heap memory allocator
|
||||
|
||||
The heap memory allocator can be customized before initialization with @ref
|
||||
glfwInitAllocator.
|
||||
|
||||
@code
|
||||
GLFWallocator allocator;
|
||||
allocator.allocate = my_malloc;
|
||||
allocator.reallocate = my_realloc;
|
||||
allocator.deallocate = my_free;
|
||||
allocator.user = NULL;
|
||||
|
||||
glfwInitAllocator(&allocator);
|
||||
@endcode
|
||||
|
||||
The allocator will be picked up at the beginning of initialization and will be
|
||||
used until GLFW has been fully terminated. Any allocator set after
|
||||
initialization will be picked up only at the next initialization.
|
||||
|
||||
The allocator will only be used for allocations that would have been made with
|
||||
the C standard library. Memory allocations that must be made with platform
|
||||
specific APIs will still use those.
|
||||
|
||||
The allocation function must have a signature matching @ref GLFWallocatefun. It receives
|
||||
the desired size, in bytes, and the user pointer passed to @ref glfwInitAllocator and
|
||||
returns the address to the allocated memory block.
|
||||
|
||||
@code
|
||||
void* my_malloc(size_t size, void* user)
|
||||
{
|
||||
...
|
||||
}
|
||||
@endcode
|
||||
|
||||
The reallocation function must have a function signature matching @ref GLFWreallocatefun.
|
||||
It receives the memory block to be reallocated, the new desired size, in bytes, and the user
|
||||
pointer passed to @ref glfwInitAllocator and returns the address to the resized memory
|
||||
block.
|
||||
|
||||
@code
|
||||
void* my_realloc(void* block, size_t size, void* user)
|
||||
{
|
||||
...
|
||||
}
|
||||
@endcode
|
||||
|
||||
The deallocation function must have a function signature matching @ref GLFWdeallocatefun.
|
||||
It receives the memory block to be deallocated and the user pointer passed to @ref
|
||||
glfwInitAllocator.
|
||||
|
||||
@code
|
||||
void my_free(void* block, void* user)
|
||||
{
|
||||
...
|
||||
}
|
||||
@endcode
|
||||
|
||||
|
||||
@subsection intro_init_terminate Terminating GLFW
|
||||
|
||||
Before your application exits, you should terminate the GLFW library if it has
|
||||
|
@ -44,6 +44,16 @@ requesting a specific rendering backend when using
|
||||
contexts.
|
||||
|
||||
|
||||
@subsubsection features_34_init_allocator Support for custom memory allocator
|
||||
|
||||
GLFW now supports plugging a custom memory allocator at initialization with @ref
|
||||
glfwInitAllocator. The allocator is a struct of type @ref GLFWallocator with
|
||||
function pointers corresponding to the standard library functions `malloc`,
|
||||
`realloc` and `free`.
|
||||
|
||||
For more information see @ref init_allocator.
|
||||
|
||||
|
||||
@subsubsection features_34_win32_keymenu Support for keyboard access to Windows window menu
|
||||
|
||||
GLFW now provides the
|
||||
@ -118,7 +128,18 @@ then GLFW will fail to initialize.
|
||||
@subsection symbols_34 New symbols in version 3.4
|
||||
|
||||
@subsubsection functions_34 New functions in version 3.4
|
||||
|
||||
- @ref glfwInitAllocator
|
||||
|
||||
|
||||
@subsubsection types_34 New types in version 3.4
|
||||
|
||||
- @ref GLFWallocator
|
||||
- @ref GLFWallocatefun
|
||||
- @ref GLFWreallocatefun
|
||||
- @ref GLFWdeallocatefun
|
||||
|
||||
|
||||
@subsubsection constants_34 New constants in version 3.4
|
||||
|
||||
- @ref GLFW_POINTING_HAND_CURSOR
|
||||
|
@ -1330,6 +1330,131 @@ typedef struct GLFWwindow GLFWwindow;
|
||||
*/
|
||||
typedef struct GLFWcursor GLFWcursor;
|
||||
|
||||
/*! @brief The function pointer type for memory allocation callbacks.
|
||||
*
|
||||
* This is the function pointer type for memory allocation callbacks. A memory
|
||||
* allocation callback function has the following signature:
|
||||
* @code
|
||||
* void* function_name(size_t size, void* user)
|
||||
* @endcode
|
||||
*
|
||||
* This function must return either a memory block at least `size` bytes long,
|
||||
* or `NULL` if allocation failed. Note that not all parts of GLFW handle allocation
|
||||
* failures gracefully yet.
|
||||
*
|
||||
* This function may be called during @ref glfwInit but before the library is
|
||||
* flagged as initialized, as well as during @ref glfwTerminate after the
|
||||
* library is no longer flagged as initialized.
|
||||
*
|
||||
* Any memory allocated by this function will be deallocated during library
|
||||
* termination or earlier.
|
||||
*
|
||||
* The size will always be greater than zero. Allocations of size zero are filtered out
|
||||
* before reaching the custom allocator.
|
||||
*
|
||||
* @param[in] size The minimum size, in bytes, of the memory block.
|
||||
* @param[in] user The user-defined pointer from the allocator.
|
||||
* @return The address of the newly allocated memory block, or `NULL` if an
|
||||
* error occurred.
|
||||
*
|
||||
* @pointer_lifetime The returned memory block must be valid at least until it
|
||||
* is deallocated.
|
||||
*
|
||||
* @reentrancy This function should not call any GLFW function.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread that calls GLFW functions.
|
||||
*
|
||||
* @sa @ref init_allocator
|
||||
* @sa @ref GLFWallocator
|
||||
*
|
||||
* @since Added in version 3.4.
|
||||
*
|
||||
* @ingroup init
|
||||
*/
|
||||
typedef void* (* GLFWallocatefun)(size_t size, void* user);
|
||||
|
||||
/*! @brief The function pointer type for memory reallocation callbacks.
|
||||
*
|
||||
* This is the function pointer type for memory reallocation callbacks.
|
||||
* A memory reallocation callback function has the following signature:
|
||||
* @code
|
||||
* void* function_name(void* block, size_t size, void* user)
|
||||
* @endcode
|
||||
*
|
||||
* This function must return a memory block at least `size` bytes long, or
|
||||
* `NULL` if allocation failed. Note that not all parts of GLFW handle allocation
|
||||
* failures gracefully yet.
|
||||
*
|
||||
* This function may be called during @ref glfwInit but before the library is
|
||||
* flagged as initialized, as well as during @ref glfwTerminate after the
|
||||
* library is no longer flagged as initialized.
|
||||
*
|
||||
* Any memory allocated by this function will be deallocated during library
|
||||
* termination or earlier.
|
||||
*
|
||||
* The block address will never be `NULL` and the size will always be greater than zero.
|
||||
* Reallocations of a block to size zero are converted into deallocations. Reallocations
|
||||
* of `NULL` to a non-zero size are converted into regular allocations.
|
||||
*
|
||||
* @param[in] block The address of the memory block to reallocate.
|
||||
* @param[in] size The new minimum size, in bytes, of the memory block.
|
||||
* @param[in] user The user-defined pointer from the allocator.
|
||||
* @return The address of the newly allocated or resized memory block, or
|
||||
* `NULL` if an error occurred.
|
||||
*
|
||||
* @pointer_lifetime The returned memory block must be valid at least until it
|
||||
* is deallocated.
|
||||
*
|
||||
* @reentrancy This function should not call any GLFW function.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread that calls GLFW functions.
|
||||
*
|
||||
* @sa @ref init_allocator
|
||||
* @sa @ref GLFWallocator
|
||||
*
|
||||
* @since Added in version 3.4.
|
||||
*
|
||||
* @ingroup init
|
||||
*/
|
||||
typedef void* (* GLFWreallocatefun)(void* block, size_t size, void* user);
|
||||
|
||||
/*! @brief The function pointer type for memory deallocation callbacks.
|
||||
*
|
||||
* This is the function pointer type for memory deallocation callbacks.
|
||||
* A memory deallocation callback function has the following signature:
|
||||
* @code
|
||||
* void function_name(void* block, void* user)
|
||||
* @endcode
|
||||
*
|
||||
* This function may deallocate the specified memory block. This memory block
|
||||
* will have been allocated with the same allocator.
|
||||
*
|
||||
* This function may be called during @ref glfwInit but before the library is
|
||||
* flagged as initialized, as well as during @ref glfwTerminate after the
|
||||
* library is no longer flagged as initialized.
|
||||
*
|
||||
* The block address will never be `NULL`. Deallocations of `NULL` are filtered out
|
||||
* before reaching the custom allocator.
|
||||
*
|
||||
* @param[in] block The address of the memory block to deallocate.
|
||||
* @param[in] user The user-defined pointer from the allocator.
|
||||
*
|
||||
* @pointer_lifetime The specified memory block will not be accessed by GLFW
|
||||
* after this function is called.
|
||||
*
|
||||
* @reentrancy This function should not call any GLFW function.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread that calls GLFW functions.
|
||||
*
|
||||
* @sa @ref init_allocator
|
||||
* @sa @ref GLFWallocator
|
||||
*
|
||||
* @since Added in version 3.4.
|
||||
*
|
||||
* @ingroup init
|
||||
*/
|
||||
typedef void (* GLFWdeallocatefun)(void* block, void* user);
|
||||
|
||||
/*! @brief The function pointer type for error callbacks.
|
||||
*
|
||||
* This is the function pointer type for error callbacks. An error callback
|
||||
@ -1887,6 +2012,23 @@ typedef struct GLFWgamepadstate
|
||||
float axes[6];
|
||||
} GLFWgamepadstate;
|
||||
|
||||
/*! @brief
|
||||
*
|
||||
* @sa @ref init_allocator
|
||||
* @sa @ref glfwInitAllocator
|
||||
*
|
||||
* @since Added in version 3.4.
|
||||
*
|
||||
* @ingroup init
|
||||
*/
|
||||
typedef struct GLFWallocator
|
||||
{
|
||||
GLFWallocatefun allocate;
|
||||
GLFWreallocatefun reallocate;
|
||||
GLFWdeallocatefun deallocate;
|
||||
void* user;
|
||||
} GLFWallocator;
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* GLFW API functions
|
||||
@ -1930,6 +2072,8 @@ typedef struct GLFWgamepadstate
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
* @sa @ref intro_init
|
||||
* @sa @ref glfwInitHint
|
||||
* @sa @ref glfwInitAllocator
|
||||
* @sa @ref glfwTerminate
|
||||
*
|
||||
* @since Added in version 1.0.
|
||||
@ -2004,6 +2148,33 @@ GLFWAPI void glfwTerminate(void);
|
||||
*/
|
||||
GLFWAPI void glfwInitHint(int hint, int value);
|
||||
|
||||
/*! @brief Sets the init allocator to the desired value.
|
||||
*
|
||||
* To use the default allocator, call this function with a `NULL` argument.
|
||||
*
|
||||
* If you specify an allocator struct, every member must be a valid function
|
||||
* pointer. If any member is `NULL`, this function emits @ref
|
||||
* GLFW_INVALID_VALUE and the init allocator is unchanged.
|
||||
*
|
||||
* @param[in] allocator The allocator to use at the next initialization, or
|
||||
* `NULL` to use the default one.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_INVALID_VALUE.
|
||||
*
|
||||
* @pointer_lifetime The specified allocator is copied before this function
|
||||
* returns.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
* @sa @ref init_allocator
|
||||
* @sa @ref glfwInit
|
||||
*
|
||||
* @since Added in version 3.4.
|
||||
*
|
||||
* @ingroup init
|
||||
*/
|
||||
GLFWAPI void glfwInitAllocator(const GLFWallocator* allocator);
|
||||
|
||||
/*! @brief Retrieves the version of the GLFW library.
|
||||
*
|
||||
* This function retrieves the major, minor and revision numbers of the GLFW
|
||||
|
@ -602,7 +602,7 @@ void _glfwPlatformTerminate(void)
|
||||
if (_glfw.ns.keyUpMonitor)
|
||||
[NSEvent removeMonitor:_glfw.ns.keyUpMonitor];
|
||||
|
||||
free(_glfw.ns.clipboardString);
|
||||
_glfw_free(_glfw.ns.clipboardString);
|
||||
|
||||
_glfwTerminateNSGL();
|
||||
|
||||
|
@ -102,15 +102,15 @@ static void closeJoystick(_GLFWjoystick* js)
|
||||
return;
|
||||
|
||||
for (i = 0; i < CFArrayGetCount(js->ns.axes); i++)
|
||||
free((void*) CFArrayGetValueAtIndex(js->ns.axes, i));
|
||||
_glfw_free((void*) CFArrayGetValueAtIndex(js->ns.axes, i));
|
||||
CFRelease(js->ns.axes);
|
||||
|
||||
for (i = 0; i < CFArrayGetCount(js->ns.buttons); i++)
|
||||
free((void*) CFArrayGetValueAtIndex(js->ns.buttons, i));
|
||||
_glfw_free((void*) CFArrayGetValueAtIndex(js->ns.buttons, i));
|
||||
CFRelease(js->ns.buttons);
|
||||
|
||||
for (i = 0; i < CFArrayGetCount(js->ns.hats); i++)
|
||||
free((void*) CFArrayGetValueAtIndex(js->ns.hats, i));
|
||||
_glfw_free((void*) CFArrayGetValueAtIndex(js->ns.hats, i));
|
||||
CFRelease(js->ns.hats);
|
||||
|
||||
_glfwFreeJoystick(js);
|
||||
@ -251,7 +251,7 @@ static void matchCallback(void* context,
|
||||
|
||||
if (target)
|
||||
{
|
||||
_GLFWjoyelementNS* element = calloc(1, sizeof(_GLFWjoyelementNS));
|
||||
_GLFWjoyelementNS* element = _glfw_calloc(1, sizeof(_GLFWjoyelementNS));
|
||||
element->native = native;
|
||||
element->usage = usage;
|
||||
element->index = (int) CFArrayGetCount(target);
|
||||
|
@ -120,7 +120,7 @@ static char* getMonitorName(CGDirectDisplayID displayID, NSScreen* screen)
|
||||
const CFIndex size =
|
||||
CFStringGetMaximumSizeForEncoding(CFStringGetLength(nameRef),
|
||||
kCFStringEncodingUTF8);
|
||||
char* name = calloc(size + 1, 1);
|
||||
char* name = _glfw_calloc(size + 1, 1);
|
||||
CFStringGetCString(nameRef, name, size, kCFStringEncodingUTF8);
|
||||
|
||||
CFRelease(info);
|
||||
@ -301,7 +301,7 @@ void _glfwPollMonitorsNS(void)
|
||||
{
|
||||
uint32_t displayCount;
|
||||
CGGetOnlineDisplayList(0, NULL, &displayCount);
|
||||
CGDirectDisplayID* displays = calloc(displayCount, sizeof(CGDirectDisplayID));
|
||||
CGDirectDisplayID* displays = _glfw_calloc(displayCount, sizeof(CGDirectDisplayID));
|
||||
CGGetOnlineDisplayList(displayCount, displays, &displayCount);
|
||||
|
||||
for (int i = 0; i < _glfw.monitorCount; i++)
|
||||
@ -311,7 +311,7 @@ void _glfwPollMonitorsNS(void)
|
||||
uint32_t disconnectedCount = _glfw.monitorCount;
|
||||
if (disconnectedCount)
|
||||
{
|
||||
disconnected = calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*));
|
||||
disconnected = _glfw_calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*));
|
||||
memcpy(disconnected,
|
||||
_glfw.monitors,
|
||||
_glfw.monitorCount * sizeof(_GLFWmonitor*));
|
||||
@ -363,7 +363,7 @@ void _glfwPollMonitorsNS(void)
|
||||
monitor->ns.unitNumber = unitNumber;
|
||||
monitor->ns.screen = screen;
|
||||
|
||||
free(name);
|
||||
_glfw_free(name);
|
||||
|
||||
CGDisplayModeRef mode = CGDisplayCopyDisplayMode(displays[i]);
|
||||
if (CGDisplayModeGetRefreshRate(mode) == 0.0)
|
||||
@ -379,8 +379,8 @@ void _glfwPollMonitorsNS(void)
|
||||
_glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
|
||||
}
|
||||
|
||||
free(disconnected);
|
||||
free(displays);
|
||||
_glfw_free(disconnected);
|
||||
_glfw_free(displays);
|
||||
}
|
||||
|
||||
// Change the current video mode
|
||||
@ -521,7 +521,7 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
|
||||
|
||||
CFArrayRef modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL);
|
||||
const CFIndex found = CFArrayGetCount(modes);
|
||||
GLFWvidmode* result = calloc(found, sizeof(GLFWvidmode));
|
||||
GLFWvidmode* result = _glfw_calloc(found, sizeof(GLFWvidmode));
|
||||
|
||||
for (CFIndex i = 0; i < found; i++)
|
||||
{
|
||||
@ -569,7 +569,7 @@ GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||
@autoreleasepool {
|
||||
|
||||
uint32_t size = CGDisplayGammaTableCapacity(monitor->ns.displayID);
|
||||
CGGammaValue* values = calloc(size * 3, sizeof(CGGammaValue));
|
||||
CGGammaValue* values = _glfw_calloc(size * 3, sizeof(CGGammaValue));
|
||||
|
||||
CGGetDisplayTransferByTable(monitor->ns.displayID,
|
||||
size,
|
||||
@ -587,7 +587,7 @@ GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||
ramp->blue[i] = (unsigned short) (values[i + size * 2] * 65535);
|
||||
}
|
||||
|
||||
free(values);
|
||||
_glfw_free(values);
|
||||
return GLFW_TRUE;
|
||||
|
||||
} // autoreleasepool
|
||||
@ -597,7 +597,7 @@ void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
||||
{
|
||||
@autoreleasepool {
|
||||
|
||||
CGGammaValue* values = calloc(ramp->size * 3, sizeof(CGGammaValue));
|
||||
CGGammaValue* values = _glfw_calloc(ramp->size * 3, sizeof(CGGammaValue));
|
||||
|
||||
for (unsigned int i = 0; i < ramp->size; i++)
|
||||
{
|
||||
@ -612,7 +612,7 @@ void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
||||
values + ramp->size,
|
||||
values + ramp->size * 2);
|
||||
|
||||
free(values);
|
||||
_glfw_free(values);
|
||||
|
||||
} // autoreleasepool
|
||||
}
|
||||
|
@ -646,7 +646,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
||||
const NSUInteger count = [urls count];
|
||||
if (count)
|
||||
{
|
||||
char** paths = calloc(count, sizeof(char*));
|
||||
char** paths = _glfw_calloc(count, sizeof(char*));
|
||||
|
||||
for (NSUInteger i = 0; i < count; i++)
|
||||
paths[i] = _glfw_strdup([urls[i] fileSystemRepresentation]);
|
||||
@ -654,8 +654,8 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
||||
_glfwInputDrop(window, (int) count, (const char**) paths);
|
||||
|
||||
for (NSUInteger i = 0; i < count; i++)
|
||||
free(paths[i]);
|
||||
free(paths);
|
||||
_glfw_free(paths[i]);
|
||||
_glfw_free(paths);
|
||||
}
|
||||
|
||||
return YES;
|
||||
@ -1747,7 +1747,7 @@ const char* _glfwPlatformGetClipboardString(void)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
free(_glfw.ns.clipboardString);
|
||||
_glfw_free(_glfw.ns.clipboardString);
|
||||
_glfw.ns.clipboardString = _glfw_strdup([object UTF8String]);
|
||||
|
||||
return _glfw.ns.clipboardString;
|
||||
@ -1775,7 +1775,7 @@ EGLenum _glfwPlatformGetEGLPlatform(EGLint** attribs)
|
||||
|
||||
if (type)
|
||||
{
|
||||
*attribs = calloc(3, sizeof(EGLint));
|
||||
*attribs = _glfw_calloc(3, sizeof(EGLint));
|
||||
(*attribs)[0] = EGL_PLATFORM_ANGLE_TYPE_ANGLE;
|
||||
(*attribs)[1] = type;
|
||||
(*attribs)[2] = EGL_NONE;
|
||||
|
@ -103,10 +103,10 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
nativeConfigs = calloc(nativeCount, sizeof(EGLConfig));
|
||||
nativeConfigs = _glfw_calloc(nativeCount, sizeof(EGLConfig));
|
||||
eglGetConfigs(_glfw.egl.display, nativeConfigs, nativeCount, &nativeCount);
|
||||
|
||||
usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig));
|
||||
usableConfigs = _glfw_calloc(nativeCount, sizeof(_GLFWfbconfig));
|
||||
usableCount = 0;
|
||||
|
||||
for (i = 0; i < nativeCount; i++)
|
||||
@ -183,8 +183,8 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
|
||||
if (closest)
|
||||
*result = (EGLConfig) closest->handle;
|
||||
|
||||
free(nativeConfigs);
|
||||
free(usableConfigs);
|
||||
_glfw_free(nativeConfigs);
|
||||
_glfw_free(usableConfigs);
|
||||
|
||||
return closest != NULL;
|
||||
}
|
||||
@ -440,7 +440,7 @@ GLFWbool _glfwInitEGL(void)
|
||||
else
|
||||
_glfw.egl.display = eglGetDisplay(_glfwPlatformGetEGLNativeDisplay());
|
||||
|
||||
free(attribs);
|
||||
_glfw_free(attribs);
|
||||
|
||||
if (_glfw.egl.display == EGL_NO_DISPLAY)
|
||||
{
|
||||
|
@ -73,7 +73,7 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired,
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig));
|
||||
usableConfigs = _glfw_calloc(nativeCount, sizeof(_GLFWfbconfig));
|
||||
usableCount = 0;
|
||||
|
||||
for (i = 0; i < nativeCount; i++)
|
||||
@ -138,7 +138,7 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired,
|
||||
*result = (GLXFBConfig) closest->handle;
|
||||
|
||||
XFree(nativeConfigs);
|
||||
free(usableConfigs);
|
||||
_glfw_free(usableConfigs);
|
||||
|
||||
return closest != NULL;
|
||||
}
|
||||
|
106
src/init.c
106
src/init.c
@ -49,6 +49,7 @@ _GLFWlibrary _glfw = { GLFW_FALSE };
|
||||
//
|
||||
static _GLFWerror _glfwMainThreadError;
|
||||
static GLFWerrorfun _glfwErrorCallback;
|
||||
static GLFWallocator _glfwInitAllocator;
|
||||
static _GLFWinitconfig _glfwInitHints =
|
||||
{
|
||||
GLFW_TRUE, // hat buttons
|
||||
@ -62,6 +63,27 @@ static _GLFWinitconfig _glfwInitHints =
|
||||
},
|
||||
};
|
||||
|
||||
// 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)
|
||||
@ -84,11 +106,11 @@ static void terminate(void)
|
||||
_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;
|
||||
|
||||
@ -102,7 +124,7 @@ static void terminate(void)
|
||||
{
|
||||
_GLFWerror* error = _glfw.errorListHead;
|
||||
_glfw.errorListHead = error->next;
|
||||
free(error);
|
||||
_glfw_free(error);
|
||||
}
|
||||
|
||||
_glfwPlatformDestroyTls(&_glfw.contextSlot);
|
||||
@ -120,7 +142,7 @@ static void terminate(void)
|
||||
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;
|
||||
}
|
||||
@ -149,6 +171,59 @@ float _glfw_fmaxf(float a, float b)
|
||||
return 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 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);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW event API //////
|
||||
@ -208,7 +283,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;
|
||||
@ -239,6 +314,14 @@ GLFWAPI int glfwInit(void)
|
||||
memset(&_glfw, 0, sizeof(_glfw));
|
||||
_glfw.hints.init = _glfwInitHints;
|
||||
|
||||
_glfw.allocator = _glfwInitAllocator;
|
||||
if (!_glfw.allocator.allocate)
|
||||
{
|
||||
_glfw.allocator.allocate = defaultAllocate;
|
||||
_glfw.allocator.reallocate = defaultReallocate;
|
||||
_glfw.allocator.deallocate = defaultDeallocate;
|
||||
}
|
||||
|
||||
if (!_glfwPlatformInit())
|
||||
{
|
||||
terminate();
|
||||
@ -297,6 +380,19 @@ GLFWAPI void glfwInitHint(int hint, int value)
|
||||
"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 glfwGetVersion(int* major, int* minor, int* rev)
|
||||
{
|
||||
if (major != NULL)
|
||||
|
22
src/input.c
22
src/input.c
@ -419,7 +419,7 @@ void _glfwInitGamepadMappings(void)
|
||||
{
|
||||
size_t i;
|
||||
const size_t count = sizeof(_glfwDefaultMappings) / sizeof(char*);
|
||||
_glfw.mappings = calloc(count, sizeof(_GLFWmapping));
|
||||
_glfw.mappings = _glfw_calloc(count, sizeof(_GLFWmapping));
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
@ -450,9 +450,9 @@ _GLFWjoystick* _glfwAllocJoystick(const char* name,
|
||||
|
||||
js = _glfw.joysticks + jid;
|
||||
js->present = GLFW_TRUE;
|
||||
js->axes = calloc(axisCount, sizeof(float));
|
||||
js->buttons = calloc(buttonCount + (size_t) hatCount * 4, 1);
|
||||
js->hats = calloc(hatCount, 1);
|
||||
js->axes = _glfw_calloc(axisCount, sizeof(float));
|
||||
js->buttons = _glfw_calloc(buttonCount + (size_t) hatCount * 4, 1);
|
||||
js->hats = _glfw_calloc(hatCount, 1);
|
||||
js->axisCount = axisCount;
|
||||
js->buttonCount = buttonCount;
|
||||
js->hatCount = hatCount;
|
||||
@ -468,9 +468,9 @@ _GLFWjoystick* _glfwAllocJoystick(const char* name,
|
||||
//
|
||||
void _glfwFreeJoystick(_GLFWjoystick* js)
|
||||
{
|
||||
free(js->axes);
|
||||
free(js->buttons);
|
||||
free(js->hats);
|
||||
_glfw_free(js->axes);
|
||||
_glfw_free(js->buttons);
|
||||
_glfw_free(js->hats);
|
||||
memset(js, 0, sizeof(_GLFWjoystick));
|
||||
}
|
||||
|
||||
@ -754,7 +754,7 @@ GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot)
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
|
||||
cursor = calloc(1, sizeof(_GLFWcursor));
|
||||
cursor = _glfw_calloc(1, sizeof(_GLFWcursor));
|
||||
cursor->next = _glfw.cursorListHead;
|
||||
_glfw.cursorListHead = cursor;
|
||||
|
||||
@ -788,7 +788,7 @@ GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cursor = calloc(1, sizeof(_GLFWcursor));
|
||||
cursor = _glfw_calloc(1, sizeof(_GLFWcursor));
|
||||
cursor->next = _glfw.cursorListHead;
|
||||
_glfw.cursorListHead = cursor;
|
||||
|
||||
@ -833,7 +833,7 @@ GLFWAPI void glfwDestroyCursor(GLFWcursor* handle)
|
||||
*prev = cursor->next;
|
||||
}
|
||||
|
||||
free(cursor);
|
||||
_glfw_free(cursor);
|
||||
}
|
||||
|
||||
GLFWAPI void glfwSetCursor(GLFWwindow* windowHandle, GLFWcursor* cursorHandle)
|
||||
@ -1191,7 +1191,7 @@ GLFWAPI int glfwUpdateGamepadMappings(const char* string)
|
||||
{
|
||||
_glfw.mappingCount++;
|
||||
_glfw.mappings =
|
||||
realloc(_glfw.mappings,
|
||||
_glfw_realloc(_glfw.mappings,
|
||||
sizeof(_GLFWmapping) * _glfw.mappingCount);
|
||||
_glfw.mappings[_glfw.mappingCount - 1] = mapping;
|
||||
}
|
||||
|
@ -527,6 +527,7 @@ struct _GLFWmutex
|
||||
struct _GLFWlibrary
|
||||
{
|
||||
GLFWbool initialized;
|
||||
GLFWallocator allocator;
|
||||
|
||||
struct {
|
||||
_GLFWinitconfig init;
|
||||
@ -798,3 +799,7 @@ char* _glfw_strdup(const char* source);
|
||||
float _glfw_fminf(float a, float b);
|
||||
float _glfw_fmaxf(float a, float b);
|
||||
|
||||
void* _glfw_calloc(size_t count, size_t size);
|
||||
void* _glfw_realloc(void* pointer, size_t size);
|
||||
void _glfw_free(void* pointer);
|
||||
|
||||
|
@ -80,7 +80,7 @@ static GLFWbool refreshVideoModes(_GLFWmonitor* monitor)
|
||||
|
||||
qsort(modes, modeCount, sizeof(GLFWvidmode), compareVideoModes);
|
||||
|
||||
free(monitor->modes);
|
||||
_glfw_free(monitor->modes);
|
||||
monitor->modes = modes;
|
||||
monitor->modeCount = modeCount;
|
||||
|
||||
@ -100,7 +100,8 @@ void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement)
|
||||
{
|
||||
_glfw.monitorCount++;
|
||||
_glfw.monitors =
|
||||
realloc(_glfw.monitors, sizeof(_GLFWmonitor*) * _glfw.monitorCount);
|
||||
_glfw_realloc(_glfw.monitors,
|
||||
sizeof(_GLFWmonitor*) * _glfw.monitorCount);
|
||||
|
||||
if (placement == _GLFW_INSERT_FIRST)
|
||||
{
|
||||
@ -166,7 +167,7 @@ void _glfwInputMonitorWindow(_GLFWmonitor* monitor, _GLFWwindow* window)
|
||||
//
|
||||
_GLFWmonitor* _glfwAllocMonitor(const char* name, int widthMM, int heightMM)
|
||||
{
|
||||
_GLFWmonitor* monitor = calloc(1, sizeof(_GLFWmonitor));
|
||||
_GLFWmonitor* monitor = _glfw_calloc(1, sizeof(_GLFWmonitor));
|
||||
monitor->widthMM = widthMM;
|
||||
monitor->heightMM = heightMM;
|
||||
|
||||
@ -187,17 +188,17 @@ void _glfwFreeMonitor(_GLFWmonitor* monitor)
|
||||
_glfwFreeGammaArrays(&monitor->originalRamp);
|
||||
_glfwFreeGammaArrays(&monitor->currentRamp);
|
||||
|
||||
free(monitor->modes);
|
||||
free(monitor);
|
||||
_glfw_free(monitor->modes);
|
||||
_glfw_free(monitor);
|
||||
}
|
||||
|
||||
// Allocates red, green and blue value arrays of the specified size
|
||||
//
|
||||
void _glfwAllocGammaArrays(GLFWgammaramp* ramp, unsigned int size)
|
||||
{
|
||||
ramp->red = calloc(size, sizeof(unsigned short));
|
||||
ramp->green = calloc(size, sizeof(unsigned short));
|
||||
ramp->blue = calloc(size, sizeof(unsigned short));
|
||||
ramp->red = _glfw_calloc(size, sizeof(unsigned short));
|
||||
ramp->green = _glfw_calloc(size, sizeof(unsigned short));
|
||||
ramp->blue = _glfw_calloc(size, sizeof(unsigned short));
|
||||
ramp->size = size;
|
||||
}
|
||||
|
||||
@ -205,9 +206,9 @@ void _glfwAllocGammaArrays(GLFWgammaramp* ramp, unsigned int size)
|
||||
//
|
||||
void _glfwFreeGammaArrays(GLFWgammaramp* ramp)
|
||||
{
|
||||
free(ramp->red);
|
||||
free(ramp->green);
|
||||
free(ramp->blue);
|
||||
_glfw_free(ramp->red);
|
||||
_glfw_free(ramp->green);
|
||||
_glfw_free(ramp->blue);
|
||||
|
||||
memset(ramp, 0, sizeof(GLFWgammaramp));
|
||||
}
|
||||
@ -472,7 +473,7 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
|
||||
if (!original)
|
||||
return;
|
||||
|
||||
values = calloc(original->size, sizeof(unsigned short));
|
||||
values = _glfw_calloc(original->size, sizeof(unsigned short));
|
||||
|
||||
for (i = 0; i < original->size; i++)
|
||||
{
|
||||
@ -494,7 +495,7 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
|
||||
ramp.size = original->size;
|
||||
|
||||
glfwSetGammaRamp(handle, &ramp);
|
||||
free(values);
|
||||
_glfw_free(values);
|
||||
}
|
||||
|
||||
GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle)
|
||||
|
@ -46,7 +46,7 @@ int _glfwPlatformInit(void)
|
||||
|
||||
void _glfwPlatformTerminate(void)
|
||||
{
|
||||
free(_glfw.null.clipboardString);
|
||||
_glfw_free(_glfw.null.clipboardString);
|
||||
_glfwTerminateOSMesa();
|
||||
}
|
||||
|
||||
|
@ -105,7 +105,7 @@ void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor,
|
||||
|
||||
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
|
||||
{
|
||||
GLFWvidmode* mode = calloc(1, sizeof(GLFWvidmode));
|
||||
GLFWvidmode* mode = _glfw_calloc(1, sizeof(GLFWvidmode));
|
||||
*mode = getVideoMode();
|
||||
*found = 1;
|
||||
return mode;
|
||||
|
@ -513,7 +513,7 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
|
||||
void _glfwPlatformSetClipboardString(const char* string)
|
||||
{
|
||||
char* copy = _glfw_strdup(string);
|
||||
free(_glfw.null.clipboardString);
|
||||
_glfw_free(_glfw.null.clipboardString);
|
||||
_glfw.null.clipboardString = copy;
|
||||
}
|
||||
|
||||
|
@ -46,10 +46,10 @@ static void makeContextCurrentOSMesa(_GLFWwindow* window)
|
||||
(width != window->context.osmesa.width) ||
|
||||
(height != window->context.osmesa.height))
|
||||
{
|
||||
free(window->context.osmesa.buffer);
|
||||
_glfw_free(window->context.osmesa.buffer);
|
||||
|
||||
// Allocate the new buffer (width * height * 8-bit RGBA)
|
||||
window->context.osmesa.buffer = calloc(4, (size_t) width * height);
|
||||
window->context.osmesa.buffer = _glfw_calloc(4, (size_t) width * height);
|
||||
window->context.osmesa.width = width;
|
||||
window->context.osmesa.height = height;
|
||||
}
|
||||
@ -83,7 +83,7 @@ static void destroyContextOSMesa(_GLFWwindow* window)
|
||||
|
||||
if (window->context.osmesa.buffer)
|
||||
{
|
||||
free(window->context.osmesa.buffer);
|
||||
_glfw_free(window->context.osmesa.buffer);
|
||||
window->context.osmesa.width = 0;
|
||||
window->context.osmesa.height = 0;
|
||||
}
|
||||
|
@ -108,7 +108,7 @@ GLFWbool _glfwInitVulkan(int mode)
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
ep = calloc(count, sizeof(VkExtensionProperties));
|
||||
ep = _glfw_calloc(count, sizeof(VkExtensionProperties));
|
||||
|
||||
err = vkEnumerateInstanceExtensionProperties(NULL, &count, ep);
|
||||
if (err)
|
||||
@ -117,7 +117,7 @@ GLFWbool _glfwInitVulkan(int mode)
|
||||
"Vulkan: Failed to query instance extensions: %s",
|
||||
_glfwGetVulkanResultString(err));
|
||||
|
||||
free(ep);
|
||||
_glfw_free(ep);
|
||||
_glfwTerminateVulkan();
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
@ -145,7 +145,7 @@ GLFWbool _glfwInitVulkan(int mode)
|
||||
#endif
|
||||
}
|
||||
|
||||
free(ep);
|
||||
_glfw_free(ep);
|
||||
|
||||
_glfw.vk.available = GLFW_TRUE;
|
||||
|
||||
|
@ -30,7 +30,6 @@
|
||||
#include "internal.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <malloc.h>
|
||||
#include <assert.h>
|
||||
|
||||
// Return the value corresponding to the specified attribute
|
||||
@ -130,7 +129,7 @@ static int choosePixelFormat(_GLFWwindow* window,
|
||||
NULL);
|
||||
}
|
||||
|
||||
usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig));
|
||||
usableConfigs = _glfw_calloc(nativeCount, sizeof(_GLFWfbconfig));
|
||||
|
||||
for (i = 0; i < nativeCount; i++)
|
||||
{
|
||||
@ -149,7 +148,7 @@ static int choosePixelFormat(_GLFWwindow* window,
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to retrieve pixel format attributes");
|
||||
|
||||
free(usableConfigs);
|
||||
_glfw_free(usableConfigs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -221,7 +220,7 @@ static int choosePixelFormat(_GLFWwindow* window,
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to describe pixel format");
|
||||
|
||||
free(usableConfigs);
|
||||
_glfw_free(usableConfigs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -271,7 +270,7 @@ static int choosePixelFormat(_GLFWwindow* window,
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"WGL: The driver does not appear to support OpenGL");
|
||||
|
||||
free(usableConfigs);
|
||||
_glfw_free(usableConfigs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -281,12 +280,12 @@ static int choosePixelFormat(_GLFWwindow* window,
|
||||
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||
"WGL: Failed to find a suitable pixel format");
|
||||
|
||||
free(usableConfigs);
|
||||
_glfw_free(usableConfigs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pixelFormat = (int) closest->handle;
|
||||
free(usableConfigs);
|
||||
_glfw_free(usableConfigs);
|
||||
|
||||
return pixelFormat;
|
||||
}
|
||||
|
@ -30,7 +30,6 @@
|
||||
#include "internal.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <malloc.h>
|
||||
|
||||
static const GUID _glfw_GUID_DEVINTERFACE_HID =
|
||||
{0x4d1e55b2,0xf16f,0x11cf,{0x88,0xcb,0x00,0x11,0x11,0x00,0x00,0x30}};
|
||||
@ -405,13 +404,13 @@ WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
target = calloc(count, sizeof(WCHAR));
|
||||
target = _glfw_calloc(count, sizeof(WCHAR));
|
||||
|
||||
if (!MultiByteToWideChar(CP_UTF8, 0, source, -1, target, count))
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"Win32: Failed to convert string from UTF-8");
|
||||
free(target);
|
||||
_glfw_free(target);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -433,13 +432,13 @@ char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
target = calloc(size, 1);
|
||||
target = _glfw_calloc(size, 1);
|
||||
|
||||
if (!WideCharToMultiByte(CP_UTF8, 0, source, -1, target, size, NULL, NULL))
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"Win32: Failed to convert string to UTF-8");
|
||||
free(target);
|
||||
_glfw_free(target);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -593,8 +592,8 @@ void _glfwPlatformTerminate(void)
|
||||
|
||||
_glfwUnregisterWindowClassWin32();
|
||||
|
||||
free(_glfw.win32.clipboardString);
|
||||
free(_glfw.win32.rawInput);
|
||||
_glfw_free(_glfw.win32.clipboardString);
|
||||
_glfw_free(_glfw.win32.rawInput);
|
||||
|
||||
_glfwTerminateWGL();
|
||||
_glfwTerminateEGL();
|
||||
|
@ -199,11 +199,11 @@ static GLFWbool supportsXInput(const GUID* guid)
|
||||
if (GetRawInputDeviceList(NULL, &count, sizeof(RAWINPUTDEVICELIST)) != 0)
|
||||
return GLFW_FALSE;
|
||||
|
||||
ridl = calloc(count, sizeof(RAWINPUTDEVICELIST));
|
||||
ridl = _glfw_calloc(count, sizeof(RAWINPUTDEVICELIST));
|
||||
|
||||
if (GetRawInputDeviceList(ridl, &count, sizeof(RAWINPUTDEVICELIST)) == (UINT) -1)
|
||||
{
|
||||
free(ridl);
|
||||
_glfw_free(ridl);
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
@ -248,7 +248,7 @@ static GLFWbool supportsXInput(const GUID* guid)
|
||||
}
|
||||
}
|
||||
|
||||
free(ridl);
|
||||
_glfw_free(ridl);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -262,7 +262,7 @@ static void closeJoystick(_GLFWjoystick* js)
|
||||
IDirectInputDevice8_Release(js->win32.device);
|
||||
}
|
||||
|
||||
free(js->win32.objects);
|
||||
_glfw_free(js->win32.objects);
|
||||
|
||||
_glfwFreeJoystick(js);
|
||||
_glfwInputJoystick(js, GLFW_DISCONNECTED);
|
||||
@ -416,7 +416,7 @@ static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user)
|
||||
|
||||
memset(&data, 0, sizeof(data));
|
||||
data.device = device;
|
||||
data.objects = calloc(dc.dwAxes + (size_t) dc.dwButtons + dc.dwPOVs,
|
||||
data.objects = _glfw_calloc(dc.dwAxes + (size_t) dc.dwButtons + dc.dwPOVs,
|
||||
sizeof(_GLFWjoyobjectWin32));
|
||||
|
||||
if (FAILED(IDirectInputDevice8_EnumObjects(device,
|
||||
@ -428,7 +428,7 @@ static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user)
|
||||
"Win32: Failed to enumerate device objects");
|
||||
|
||||
IDirectInputDevice8_Release(device);
|
||||
free(data.objects);
|
||||
_glfw_free(data.objects);
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
|
||||
@ -445,7 +445,7 @@ static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user)
|
||||
"Win32: Failed to convert joystick name to UTF-8");
|
||||
|
||||
IDirectInputDevice8_Release(device);
|
||||
free(data.objects);
|
||||
_glfw_free(data.objects);
|
||||
return DIENUM_STOP;
|
||||
}
|
||||
|
||||
@ -473,7 +473,7 @@ static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user)
|
||||
if (!js)
|
||||
{
|
||||
IDirectInputDevice8_Release(device);
|
||||
free(data.objects);
|
||||
_glfw_free(data.objects);
|
||||
return DIENUM_STOP;
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <malloc.h>
|
||||
#include <wchar.h>
|
||||
|
||||
|
||||
@ -96,7 +95,7 @@ static _GLFWmonitor* createMonitor(DISPLAY_DEVICEW* adapter,
|
||||
DeleteDC(dc);
|
||||
|
||||
monitor = _glfwAllocMonitor(name, widthMM, heightMM);
|
||||
free(name);
|
||||
_glfw_free(name);
|
||||
|
||||
if (adapter->StateFlags & DISPLAY_DEVICE_MODESPRUNED)
|
||||
monitor->win32.modesPruned = GLFW_TRUE;
|
||||
@ -145,7 +144,7 @@ void _glfwPollMonitorsWin32(void)
|
||||
disconnectedCount = _glfw.monitorCount;
|
||||
if (disconnectedCount)
|
||||
{
|
||||
disconnected = calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*));
|
||||
disconnected = _glfw_calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*));
|
||||
memcpy(disconnected,
|
||||
_glfw.monitors,
|
||||
_glfw.monitorCount * sizeof(_GLFWmonitor*));
|
||||
@ -197,7 +196,7 @@ void _glfwPollMonitorsWin32(void)
|
||||
monitor = createMonitor(&adapter, &display);
|
||||
if (!monitor)
|
||||
{
|
||||
free(disconnected);
|
||||
_glfw_free(disconnected);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -227,7 +226,7 @@ void _glfwPollMonitorsWin32(void)
|
||||
monitor = createMonitor(&adapter, NULL);
|
||||
if (!monitor)
|
||||
{
|
||||
free(disconnected);
|
||||
_glfw_free(disconnected);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -241,7 +240,7 @@ void _glfwPollMonitorsWin32(void)
|
||||
_glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
|
||||
}
|
||||
|
||||
free(disconnected);
|
||||
_glfw_free(disconnected);
|
||||
}
|
||||
|
||||
// Change the current video mode
|
||||
@ -442,7 +441,7 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
|
||||
if (*count == size)
|
||||
{
|
||||
size += 128;
|
||||
result = (GLFWvidmode*) realloc(result, size * sizeof(GLFWvidmode));
|
||||
result = (GLFWvidmode*) _glfw_realloc(result, size * sizeof(GLFWvidmode));
|
||||
}
|
||||
|
||||
(*count)++;
|
||||
@ -452,7 +451,7 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
|
||||
if (!*count)
|
||||
{
|
||||
// HACK: Report the current mode if no valid modes were found
|
||||
result = calloc(1, sizeof(GLFWvidmode));
|
||||
result = _glfw_calloc(1, sizeof(GLFWvidmode));
|
||||
_glfwPlatformGetVideoMode(monitor, result);
|
||||
*count = 1;
|
||||
}
|
||||
|
@ -31,7 +31,6 @@
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
#include <windowsx.h>
|
||||
#include <shellapi.h>
|
||||
@ -884,8 +883,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
GetRawInputData(ri, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER));
|
||||
if (size > (UINT) _glfw.win32.rawInputSize)
|
||||
{
|
||||
free(_glfw.win32.rawInput);
|
||||
_glfw.win32.rawInput = calloc(size, 1);
|
||||
_glfw_free(_glfw.win32.rawInput);
|
||||
_glfw.win32.rawInput = _glfw_calloc(size, 1);
|
||||
_glfw.win32.rawInputSize = size;
|
||||
}
|
||||
|
||||
@ -1185,7 +1184,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
int i;
|
||||
|
||||
const int count = DragQueryFileW(drop, 0xffffffff, NULL, 0);
|
||||
char** paths = calloc(count, sizeof(char*));
|
||||
char** paths = _glfw_calloc(count, sizeof(char*));
|
||||
|
||||
// Move the mouse to the position of the drop
|
||||
DragQueryPoint(drop, &pt);
|
||||
@ -1194,19 +1193,19 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
const UINT length = DragQueryFileW(drop, i, NULL, 0);
|
||||
WCHAR* buffer = calloc((size_t) length + 1, sizeof(WCHAR));
|
||||
WCHAR* buffer = _glfw_calloc((size_t) length + 1, sizeof(WCHAR));
|
||||
|
||||
DragQueryFileW(drop, i, buffer, length + 1);
|
||||
paths[i] = _glfwCreateUTF8FromWideStringWin32(buffer);
|
||||
|
||||
free(buffer);
|
||||
_glfw_free(buffer);
|
||||
}
|
||||
|
||||
_glfwInputDrop(window, count, (const char**) paths);
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
free(paths[i]);
|
||||
free(paths);
|
||||
_glfw_free(paths[i]);
|
||||
_glfw_free(paths);
|
||||
|
||||
DragFinish(drop);
|
||||
return 0;
|
||||
@ -1269,7 +1268,7 @@ static int createNativeWindow(_GLFWwindow* window,
|
||||
GetModuleHandleW(NULL),
|
||||
(LPVOID) wndconfig);
|
||||
|
||||
free(wideTitle);
|
||||
_glfw_free(wideTitle);
|
||||
|
||||
if (!window->win32.handle)
|
||||
{
|
||||
@ -1469,7 +1468,7 @@ void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
|
||||
return;
|
||||
|
||||
SetWindowTextW(window->win32.handle, wideTitle);
|
||||
free(wideTitle);
|
||||
_glfw_free(wideTitle);
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
|
||||
@ -2270,7 +2269,7 @@ const char* _glfwPlatformGetClipboardString(void)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
free(_glfw.win32.clipboardString);
|
||||
_glfw_free(_glfw.win32.clipboardString);
|
||||
_glfw.win32.clipboardString = _glfwCreateUTF8FromWideStringWin32(buffer);
|
||||
|
||||
GlobalUnlock(object);
|
||||
@ -2309,7 +2308,7 @@ EGLenum _glfwPlatformGetEGLPlatform(EGLint** attribs)
|
||||
|
||||
if (type)
|
||||
{
|
||||
*attribs = calloc(3, sizeof(EGLint));
|
||||
*attribs = _glfw_calloc(3, sizeof(EGLint));
|
||||
(*attribs)[0] = EGL_PLATFORM_ANGLE_TYPE_ANGLE;
|
||||
(*attribs)[1] = type;
|
||||
(*attribs)[2] = EGL_NONE;
|
||||
|
@ -186,7 +186,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
|
||||
if (!_glfwIsValidContextConfig(&ctxconfig))
|
||||
return NULL;
|
||||
|
||||
window = calloc(1, sizeof(_GLFWwindow));
|
||||
window = _glfw_calloc(1, sizeof(_GLFWwindow));
|
||||
window->next = _glfw.windowListHead;
|
||||
_glfw.windowListHead = window;
|
||||
|
||||
@ -480,7 +480,7 @@ GLFWAPI void glfwDestroyWindow(GLFWwindow* handle)
|
||||
*prev = window->next;
|
||||
}
|
||||
|
||||
free(window);
|
||||
_glfw_free(window);
|
||||
}
|
||||
|
||||
GLFWAPI int glfwWindowShouldClose(GLFWwindow* handle)
|
||||
|
@ -1273,7 +1273,7 @@ int _glfwPlatformInit(void)
|
||||
wl_data_device_manager_get_data_device(_glfw.wl.dataDeviceManager,
|
||||
_glfw.wl.seat);
|
||||
wl_data_device_add_listener(_glfw.wl.dataDevice, &dataDeviceListener, NULL);
|
||||
_glfw.wl.clipboardString = malloc(4096);
|
||||
_glfw.wl.clipboardString = _glfw_calloc(4096, 1);
|
||||
if (!_glfw.wl.clipboardString)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
@ -1369,9 +1369,9 @@ void _glfwPlatformTerminate(void)
|
||||
close(_glfw.wl.cursorTimerfd);
|
||||
|
||||
if (_glfw.wl.clipboardString)
|
||||
free(_glfw.wl.clipboardString);
|
||||
_glfw_free(_glfw.wl.clipboardString);
|
||||
if (_glfw.wl.clipboardSendString)
|
||||
free(_glfw.wl.clipboardSendString);
|
||||
_glfw_free(_glfw.wl.clipboardSendString);
|
||||
}
|
||||
|
||||
const char* _glfwPlatformGetVersionString(void)
|
||||
|
@ -77,7 +77,7 @@ static void outputHandleMode(void* data,
|
||||
|
||||
monitor->modeCount++;
|
||||
monitor->modes =
|
||||
realloc(monitor->modes, monitor->modeCount * sizeof(GLFWvidmode));
|
||||
_glfw_realloc(monitor->modes, monitor->modeCount * sizeof(GLFWvidmode));
|
||||
monitor->modes[monitor->modeCount - 1] = mode;
|
||||
|
||||
if (flags & WL_OUTPUT_MODE_CURRENT)
|
||||
|
@ -112,12 +112,12 @@ static int createAnonymousFile(off_t size)
|
||||
return -1;
|
||||
}
|
||||
|
||||
name = calloc(strlen(path) + sizeof(template), 1);
|
||||
name = _glfw_calloc(strlen(path) + sizeof(template), 1);
|
||||
strcpy(name, path);
|
||||
strcat(name, template);
|
||||
|
||||
fd = createTmpfileCloexec(name);
|
||||
free(name);
|
||||
_glfw_free(name);
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
}
|
||||
@ -382,7 +382,7 @@ static void surfaceHandleEnter(void *data,
|
||||
{
|
||||
++window->wl.monitorsSize;
|
||||
window->wl.monitors =
|
||||
realloc(window->wl.monitors,
|
||||
_glfw_realloc(window->wl.monitors,
|
||||
window->wl.monitorsSize * sizeof(_GLFWmonitor*));
|
||||
}
|
||||
|
||||
@ -837,7 +837,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
|
||||
window->wl.currentCursor = NULL;
|
||||
|
||||
window->wl.monitors = calloc(1, sizeof(_GLFWmonitor*));
|
||||
window->wl.monitors = _glfw_calloc(1, sizeof(_GLFWmonitor*));
|
||||
window->wl.monitorsCount = 0;
|
||||
window->wl.monitorsSize = 1;
|
||||
|
||||
@ -882,14 +882,14 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
||||
if (window->wl.surface)
|
||||
wl_surface_destroy(window->wl.surface);
|
||||
|
||||
free(window->wl.title);
|
||||
free(window->wl.monitors);
|
||||
_glfw_free(window->wl.title);
|
||||
_glfw_free(window->wl.monitors);
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
|
||||
{
|
||||
if (window->wl.title)
|
||||
free(window->wl.title);
|
||||
_glfw_free(window->wl.title);
|
||||
window->wl.title = _glfw_strdup(title);
|
||||
if (window->wl.xdg.toplevel)
|
||||
xdg_toplevel_set_title(window->wl.xdg.toplevel, title);
|
||||
@ -1608,11 +1608,11 @@ void _glfwPlatformSetClipboardString(const char* string)
|
||||
|
||||
if (_glfw.wl.clipboardSendString)
|
||||
{
|
||||
free(_glfw.wl.clipboardSendString);
|
||||
_glfw_free(_glfw.wl.clipboardSendString);
|
||||
_glfw.wl.clipboardSendString = NULL;
|
||||
}
|
||||
|
||||
_glfw.wl.clipboardSendString = strdup(string);
|
||||
_glfw.wl.clipboardSendString = _glfw_strdup(string);
|
||||
if (!_glfw.wl.clipboardSendString)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
@ -1626,7 +1626,7 @@ void _glfwPlatformSetClipboardString(const char* string)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Impossible to create clipboard source");
|
||||
free(_glfw.wl.clipboardSendString);
|
||||
_glfw_free(_glfw.wl.clipboardSendString);
|
||||
return;
|
||||
}
|
||||
wl_data_source_add_listener(_glfw.wl.dataSource,
|
||||
@ -1642,7 +1642,7 @@ static GLFWbool growClipboardString(void)
|
||||
{
|
||||
char* clipboard = _glfw.wl.clipboardString;
|
||||
|
||||
clipboard = realloc(clipboard, _glfw.wl.clipboardSize * 2);
|
||||
clipboard = _glfw_realloc(clipboard, _glfw.wl.clipboardSize * 2);
|
||||
if (!clipboard)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
|
@ -1407,8 +1407,8 @@ void _glfwPlatformTerminate(void)
|
||||
_glfw.x11.hiddenCursorHandle = (Cursor) 0;
|
||||
}
|
||||
|
||||
free(_glfw.x11.primarySelectionString);
|
||||
free(_glfw.x11.clipboardString);
|
||||
_glfw_free(_glfw.x11.primarySelectionString);
|
||||
_glfw_free(_glfw.x11.clipboardString);
|
||||
|
||||
XUnregisterIMInstantiateCallback(_glfw.x11.display,
|
||||
NULL, NULL, NULL,
|
||||
|
@ -116,7 +116,7 @@ void _glfwPollMonitorsX11(void)
|
||||
disconnectedCount = _glfw.monitorCount;
|
||||
if (disconnectedCount)
|
||||
{
|
||||
disconnected = calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*));
|
||||
disconnected = _glfw_calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*));
|
||||
memcpy(disconnected,
|
||||
_glfw.monitors,
|
||||
_glfw.monitorCount * sizeof(_GLFWmonitor*));
|
||||
@ -209,7 +209,7 @@ void _glfwPollMonitorsX11(void)
|
||||
_glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
|
||||
}
|
||||
|
||||
free(disconnected);
|
||||
_glfw_free(disconnected);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -450,7 +450,7 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
|
||||
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||
XRROutputInfo* oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output);
|
||||
|
||||
result = calloc(oi->nmode, sizeof(GLFWvidmode));
|
||||
result = _glfw_calloc(oi->nmode, sizeof(GLFWvidmode));
|
||||
|
||||
for (int i = 0; i < oi->nmode; i++)
|
||||
{
|
||||
@ -482,7 +482,7 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
|
||||
else
|
||||
{
|
||||
*count = 1;
|
||||
result = calloc(1, sizeof(GLFWvidmode));
|
||||
result = _glfw_calloc(1, sizeof(GLFWvidmode));
|
||||
_glfwPlatformGetVideoMode(monitor, result);
|
||||
}
|
||||
|
||||
|
@ -406,8 +406,8 @@ static char** parseUriList(char* text, int* count)
|
||||
|
||||
(*count)++;
|
||||
|
||||
char* path = calloc(strlen(line) + 1, 1);
|
||||
paths = realloc(paths, *count * sizeof(char*));
|
||||
char* path = _glfw_calloc(strlen(line) + 1, 1);
|
||||
paths = _glfw_realloc(paths, *count * sizeof(char*));
|
||||
paths[*count - 1] = path;
|
||||
|
||||
while (*line)
|
||||
@ -493,7 +493,7 @@ static char* convertLatin1toUTF8(const char* source)
|
||||
for (sp = source; *sp; sp++)
|
||||
size += (*sp & 0x80) ? 2 : 1;
|
||||
|
||||
char* target = calloc(size, 1);
|
||||
char* target = _glfw_calloc(size, 1);
|
||||
char* tp = target;
|
||||
|
||||
for (sp = source; *sp; sp++)
|
||||
@ -924,12 +924,12 @@ static void handleSelectionClear(XEvent* event)
|
||||
{
|
||||
if (event->xselectionclear.selection == _glfw.x11.PRIMARY)
|
||||
{
|
||||
free(_glfw.x11.primarySelectionString);
|
||||
_glfw_free(_glfw.x11.primarySelectionString);
|
||||
_glfw.x11.primarySelectionString = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
free(_glfw.x11.clipboardString);
|
||||
_glfw_free(_glfw.x11.clipboardString);
|
||||
_glfw.x11.clipboardString = NULL;
|
||||
}
|
||||
}
|
||||
@ -968,7 +968,7 @@ static const char* getSelectionString(Atom selection)
|
||||
return *selectionString;
|
||||
}
|
||||
|
||||
free(*selectionString);
|
||||
_glfw_free(*selectionString);
|
||||
*selectionString = NULL;
|
||||
|
||||
for (size_t i = 0; i < targetCount; i++)
|
||||
@ -1047,7 +1047,7 @@ static const char* getSelectionString(Atom selection)
|
||||
if (itemCount)
|
||||
{
|
||||
size += itemCount;
|
||||
string = realloc(string, size);
|
||||
string = _glfw_realloc(string, size);
|
||||
string[size - itemCount - 1] = '\0';
|
||||
strcat(string, data);
|
||||
}
|
||||
@ -1057,7 +1057,7 @@ static const char* getSelectionString(Atom selection)
|
||||
if (targets[i] == XA_STRING)
|
||||
{
|
||||
*selectionString = convertLatin1toUTF8(string);
|
||||
free(string);
|
||||
_glfw_free(string);
|
||||
}
|
||||
else
|
||||
*selectionString = string;
|
||||
@ -1293,7 +1293,7 @@ static void processEvent(XEvent *event)
|
||||
|
||||
if (status == XBufferOverflow)
|
||||
{
|
||||
chars = calloc(count + 1, 1);
|
||||
chars = _glfw_calloc(count + 1, 1);
|
||||
count = Xutf8LookupString(window->x11.ic,
|
||||
&event->xkey,
|
||||
chars, count,
|
||||
@ -1309,7 +1309,7 @@ static void processEvent(XEvent *event)
|
||||
}
|
||||
|
||||
if (chars != buffer)
|
||||
free(chars);
|
||||
_glfw_free(chars);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1724,8 +1724,8 @@ static void processEvent(XEvent *event)
|
||||
_glfwInputDrop(window, count, (const char**) paths);
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
free(paths[i]);
|
||||
free(paths);
|
||||
_glfw_free(paths[i]);
|
||||
_glfw_free(paths);
|
||||
}
|
||||
|
||||
if (data)
|
||||
@ -2108,7 +2108,7 @@ void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
|
||||
for (i = 0; i < count; i++)
|
||||
longCount += 2 + images[i].width * images[i].height;
|
||||
|
||||
long* icon = calloc(longCount, sizeof(long));
|
||||
long* icon = _glfw_calloc(longCount, sizeof(long));
|
||||
long* target = icon;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
@ -2132,7 +2132,7 @@ void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
|
||||
(unsigned char*) icon,
|
||||
longCount);
|
||||
|
||||
free(icon);
|
||||
_glfw_free(icon);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -3045,7 +3045,7 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
|
||||
void _glfwPlatformSetClipboardString(const char* string)
|
||||
{
|
||||
char* copy = _glfw_strdup(string);
|
||||
free(_glfw.x11.clipboardString);
|
||||
_glfw_free(_glfw.x11.clipboardString);
|
||||
_glfw.x11.clipboardString = copy;
|
||||
|
||||
XSetSelectionOwner(_glfw.x11.display,
|
||||
@ -3086,7 +3086,7 @@ EGLenum _glfwPlatformGetEGLPlatform(EGLint** attribs)
|
||||
|
||||
if (type)
|
||||
{
|
||||
*attribs = calloc(5, sizeof(EGLint));
|
||||
*attribs = _glfw_calloc(5, sizeof(EGLint));
|
||||
(*attribs)[0] = EGL_PLATFORM_ANGLE_TYPE_ANGLE;
|
||||
(*attribs)[1] = type;
|
||||
(*attribs)[2] = EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE;
|
||||
@ -3286,7 +3286,7 @@ GLFWAPI void glfwSetX11SelectionString(const char* string)
|
||||
{
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
free(_glfw.x11.primarySelectionString);
|
||||
_glfw_free(_glfw.x11.primarySelectionString);
|
||||
_glfw.x11.primarySelectionString = _glfw_strdup(string);
|
||||
|
||||
XSetSelectionOwner(_glfw.x11.display,
|
||||
|
@ -21,6 +21,7 @@ set(GETOPT "${GLFW_SOURCE_DIR}/deps/getopt.h"
|
||||
set(TINYCTHREAD "${GLFW_SOURCE_DIR}/deps/tinycthread.h"
|
||||
"${GLFW_SOURCE_DIR}/deps/tinycthread.c")
|
||||
|
||||
add_executable(allocator allocator.c ${GLAD_GL})
|
||||
add_executable(clipboard clipboard.c ${GETOPT} ${GLAD_GL})
|
||||
add_executable(events events.c ${GETOPT} ${GLAD_GL})
|
||||
add_executable(msaa msaa.c ${GETOPT} ${GLAD_GL})
|
||||
@ -51,8 +52,8 @@ endif()
|
||||
|
||||
set(GUI_ONLY_BINARIES empty gamma icon inputlag joysticks tearing threads
|
||||
timeout title triangle-vulkan window)
|
||||
set(CONSOLE_BINARIES clipboard events msaa glfwinfo iconify monitors reopen
|
||||
cursor)
|
||||
set(CONSOLE_BINARIES allocator clipboard events msaa glfwinfo iconify monitors
|
||||
reopen cursor)
|
||||
|
||||
set_target_properties(${GUI_ONLY_BINARIES} ${CONSOLE_BINARIES} PROPERTIES
|
||||
C_STANDARD 99
|
||||
|
141
tests/allocator.c
Normal file
141
tests/allocator.c
Normal file
@ -0,0 +1,141 @@
|
||||
//========================================================================
|
||||
// Custom heap allocator test
|
||||
// Copyright (c) Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include <glad/gl.h>
|
||||
#define GLFW_INCLUDE_NONE
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define CALL(x) (function_name = #x, x)
|
||||
static const char* function_name = NULL;
|
||||
|
||||
struct allocator_stats
|
||||
{
|
||||
size_t total;
|
||||
size_t current;
|
||||
size_t maximum;
|
||||
};
|
||||
|
||||
static void error_callback(int error, const char* description)
|
||||
{
|
||||
fprintf(stderr, "Error: %s\n", description);
|
||||
}
|
||||
|
||||
static void* allocate(size_t size, void* user)
|
||||
{
|
||||
struct allocator_stats* stats = user;
|
||||
assert(size > 0);
|
||||
|
||||
stats->total += size;
|
||||
stats->current += size;
|
||||
if (stats->current > stats->maximum)
|
||||
stats->maximum = stats->current;
|
||||
|
||||
printf("%s: allocate %zu bytes (current %zu maximum %zu total %zu)\n",
|
||||
function_name, size, stats->current, stats->maximum, stats->total);
|
||||
|
||||
size_t* real_block = malloc(size + sizeof(size_t));
|
||||
assert(real_block != NULL);
|
||||
*real_block = size;
|
||||
return real_block + 1;
|
||||
}
|
||||
|
||||
static void deallocate(void* block, void* user)
|
||||
{
|
||||
struct allocator_stats* stats = user;
|
||||
assert(block != NULL);
|
||||
|
||||
size_t* real_block = (size_t*) block - 1;
|
||||
stats->current -= *real_block;
|
||||
|
||||
printf("%s: deallocate %zu bytes (current %zu maximum %zu total %zu)\n",
|
||||
function_name, *real_block, stats->current, stats->maximum, stats->total);
|
||||
|
||||
free(real_block);
|
||||
}
|
||||
|
||||
static void* reallocate(void* block, size_t size, void* user)
|
||||
{
|
||||
struct allocator_stats* stats = user;
|
||||
assert(block != NULL);
|
||||
assert(size > 0);
|
||||
|
||||
size_t* real_block = (size_t*) block - 1;
|
||||
stats->total += size;
|
||||
stats->current += size - *real_block;
|
||||
if (stats->current > stats->maximum)
|
||||
stats->maximum = stats->current;
|
||||
|
||||
printf("%s: reallocate %zu bytes to %zu bytes (current %zu maximum %zu total %zu)\n",
|
||||
function_name, *real_block, size, stats->current, stats->maximum, stats->total);
|
||||
|
||||
real_block = realloc(real_block, size + sizeof(size_t));
|
||||
assert(real_block != NULL);
|
||||
*real_block = size;
|
||||
return real_block + 1;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
struct allocator_stats stats = {0};
|
||||
const GLFWallocator allocator =
|
||||
{
|
||||
.allocate = allocate,
|
||||
.deallocate = deallocate,
|
||||
.reallocate = reallocate,
|
||||
.user = &stats
|
||||
};
|
||||
|
||||
glfwSetErrorCallback(error_callback);
|
||||
glfwInitAllocator(&allocator);
|
||||
|
||||
if (!CALL(glfwInit)())
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
GLFWwindow* window = CALL(glfwCreateWindow)(400, 400, "Custom allocator test", NULL, NULL);
|
||||
if (!window)
|
||||
{
|
||||
glfwTerminate();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
CALL(glfwMakeContextCurrent)(window);
|
||||
gladLoadGL(glfwGetProcAddress);
|
||||
CALL(glfwSwapInterval)(1);
|
||||
|
||||
while (!CALL(glfwWindowShouldClose)(window))
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
CALL(glfwSwapBuffers)(window);
|
||||
CALL(glfwWaitEvents)();
|
||||
}
|
||||
|
||||
CALL(glfwTerminate)();
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user