Added pluggable memory allocator and threading stub.
diff --git a/include/GL/glfw3.h b/include/GL/glfw3.h
index 9d5ae7b..ee622b2 100644
--- a/include/GL/glfw3.h
+++ b/include/GL/glfw3.h
@@ -463,6 +463,8 @@
typedef void (* GLFWscrollfun)(GLFWwindow,int,int);
typedef void (* GLFWkeyfun)(GLFWwindow,int,int);
typedef void (* GLFWcharfun)(GLFWwindow,int);
+typedef void* (* GLFWmallocfun)(size_t);
+typedef void (* GLFWfreefun)(void*);
/* The video mode structure used by glfwGetVideoModes */
typedef struct
@@ -482,6 +484,18 @@
unsigned short blue[GLFW_GAMMA_RAMP_SIZE];
} GLFWgammaramp;
+/* Custom memory allocator interface */
+typedef struct
+{
+ GLFWmallocfun malloc;
+ GLFWfreefun free;
+} GLFWallocator;
+
+/* Custom threading model interface */
+typedef struct
+{
+} GLFWthreadmodel;
+
/*************************************************************************
* Prototypes
@@ -489,6 +503,7 @@
/* Initialization, termination and version querying */
GLFWAPI int glfwInit(void);
+GLFWAPI int glfwInitWithModels(GLFWthreadmodel* threading, GLFWallocator* allocator);
GLFWAPI void glfwTerminate(void);
GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev);
GLFWAPI const char* glfwGetVersionString(void);
diff --git a/readme.html b/readme.html
index c373a4b..6d54174 100644
--- a/readme.html
+++ b/readme.html
@@ -272,6 +272,7 @@
<li>Added <code>glfwSetWindowFocusCallback</code> function and <code>GLFWwindowfocusfun</code> type for receiving window focus events</li>
<li>Added <code>glfwSetWindowIconifyCallback</code> function and <code>GLFWwindowiconifyfun</code> type for receiving window iconification events</li>
<li>Added <code>glfwGetCurrentWindow</code> function for retrieving the window whose OpenGL context is current</li>
+ <li>Added <code>glfwInitWithModels</code> function and <code>GLFWallocator</code> and <code>GLFWthreadmodel</code> types for pluggable memory allocation and threading models</li>
<li>Added <code>GLFW_OPENGL_ES2_PROFILE</code> profile for creating OpenGL ES 2.0 contexts using the <code>GLX_EXT_create_context_es2_profile</code> and <code>WGL_EXT_create_context_es2_profile</code> extensions</li>
<li>Added <code>windows</code> simple multi-window test program</li>
<li>Added <code>sharing</code> simple OpenGL object sharing test program</li>
diff --git a/src/init.c b/src/init.c
index 99f0fd9..d83c19e 100644
--- a/src/init.c
+++ b/src/init.c
@@ -46,6 +46,30 @@
//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+//========================================================================
+// Allocate memory using the allocator
+//========================================================================
+
+void* _glfwMalloc(size_t size)
+{
+ return _glfwLibrary.allocator.malloc(size);
+}
+
+
+//========================================================================
+// Free memory using the allocator
+//========================================================================
+
+void _glfwFree(void* ptr)
+{
+ _glfwLibrary.allocator.free(ptr);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
////// GLFW public API //////
//////////////////////////////////////////////////////////////////////////
@@ -55,11 +79,42 @@
GLFWAPI int glfwInit(void)
{
+ return glfwInitWithModels(NULL, NULL);
+}
+
+
+//========================================================================
+// Initialize various GLFW state using custom model interfaces
+//========================================================================
+
+GLFWAPI int glfwInitWithModels(GLFWthreadmodel* threading, GLFWallocator* allocator)
+{
if (_glfwInitialized)
return GL_TRUE;
memset(&_glfwLibrary, 0, sizeof(_glfwLibrary));
+ if (threading)
+ _glfwLibrary.threading = *threading;
+
+ if (allocator)
+ {
+ // Verify that the specified model is complete
+ if (!allocator->malloc || !allocator->free)
+ {
+ _glfwSetError(GLFW_INVALID_VALUE, NULL);
+ return GL_FALSE;
+ }
+
+ _glfwLibrary.allocator = *allocator;
+ }
+ else
+ {
+ // Use the libc malloc and free
+ _glfwLibrary.allocator.malloc = malloc;
+ _glfwLibrary.allocator.free = free;
+ }
+
// Not all window hints are cleared to zero, so this needs to be here
// despite the memset above
_glfwClearWindowHints();
diff --git a/src/internal.h b/src/internal.h
index b0465e1..a9fbe16 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -228,6 +228,9 @@
GLFWkeyfun keyCallback;
GLFWcharfun charCallback;
+ GLFWthreadmodel threading;
+ GLFWallocator allocator;
+
GLFWgammaramp currentRamp;
GLFWgammaramp originalRamp;
int originalRampSize;
@@ -310,6 +313,10 @@
// Prototypes for platform independent internal functions
//========================================================================
+// Memory management (init.c)
+void* _glfwMalloc(size_t size);
+void _glfwFree(void* ptr);
+
// Fullscren management (fullscreen.c)
void _glfwSplitBPP(int bpp, int* red, int* green, int* blue);
diff --git a/src/win32/win32_window.c b/src/win32/win32_window.c
index 98c4daf..2def3a8 100644
--- a/src/win32/win32_window.c
+++ b/src/win32/win32_window.c
@@ -188,7 +188,7 @@
return NULL;
}
- result = (_GLFWfbconfig*) malloc(sizeof(_GLFWfbconfig) * count);
+ result = (_GLFWfbconfig*) _glfwMalloc(sizeof(_GLFWfbconfig) * count);
if (!result)
{
_glfwSetError(GLFW_OUT_OF_MEMORY, "Win32/WGL: Failed to allocate _GLFWfbconfig array");
@@ -1182,13 +1182,13 @@
closest = _glfwChooseFBConfig(fbconfig, fbconfigs, fbcount);
if (!closest)
{
- free(fbconfigs);
+ _glfwFree(fbconfigs);
return 0;
}
pixelFormat = (int) closest->platformID;
- free(fbconfigs);
+ _glfwFree(fbconfigs);
fbconfigs = NULL;
closest = NULL;
diff --git a/src/window.c b/src/window.c
index 8e16ad2..de497f7 100644
--- a/src/window.c
+++ b/src/window.c
@@ -360,7 +360,7 @@
return NULL;
}
- window = (_GLFWwindow*) malloc(sizeof(_GLFWwindow));
+ window = (_GLFWwindow*) _glfwMalloc(sizeof(_GLFWwindow));
if (!window)
{
_glfwSetError(GLFW_OUT_OF_MEMORY, "glfwOpenWindow: Failed to allocate window structure");
@@ -692,7 +692,7 @@
*prev = window->next;
}
- free(window);
+ _glfwFree(window);
}
diff --git a/src/x11/x11_fullscreen.c b/src/x11/x11_fullscreen.c
index 40b85f9..c154fe3 100644
--- a/src/x11/x11_fullscreen.c
+++ b/src/x11/x11_fullscreen.c
@@ -356,7 +356,7 @@
return 0;
}
- rgbarray = (int*) malloc(sizeof(int) * viscount);
+ rgbarray = (int*) _glfwMalloc(sizeof(int) * viscount);
rgbcount = 0;
// Build RGB array
@@ -400,7 +400,7 @@
sc = XRRGetScreenInfo(_glfwLibrary.X11.display, _glfwLibrary.X11.root);
sizelist = XRRConfigSizes(sc, &sizecount);
- resarray = (struct _glfwResolution*) malloc(sizeof(struct _glfwResolution) * sizecount);
+ resarray = (struct _glfwResolution*) _glfwMalloc(sizeof(struct _glfwResolution) * sizecount);
for (k = 0; k < sizecount; k++)
{
@@ -417,7 +417,7 @@
#if defined(_GLFW_HAS_XF86VIDMODE)
XF86VidModeGetAllModeLines(_glfwLibrary.X11.display, screen, &modecount, &modelist);
- resarray = (struct _glfwResolution*) malloc(sizeof(struct _glfwResolution) * modecount);
+ resarray = (struct _glfwResolution*) _glfwMalloc(sizeof(struct _glfwResolution) * modecount);
for (k = 0; k < modecount; k++)
{
@@ -446,7 +446,7 @@
if (!resarray)
{
rescount = 1;
- resarray = (struct _glfwResolution*) malloc(sizeof(struct _glfwResolution) * rescount);
+ resarray = (struct _glfwResolution*) _glfwMalloc(sizeof(struct _glfwResolution) * rescount);
resarray[0].width = DisplayWidth(_glfwLibrary.X11.display, screen);
resarray[0].height = DisplayHeight(_glfwLibrary.X11.display, screen);
@@ -470,8 +470,8 @@
// Free visuals list
XFree(vislist);
- free(resarray);
- free(rgbarray);
+ _glfwFree(resarray);
+ _glfwFree(rgbarray);
return count;
}
diff --git a/src/x11/x11_window.c b/src/x11/x11_window.c
index abafe39..3ecb15a 100644
--- a/src/x11/x11_window.c
+++ b/src/x11/x11_window.c
@@ -304,7 +304,7 @@
}
}
- result = (_GLFWfbconfig*) malloc(sizeof(_GLFWfbconfig) * count);
+ result = (_GLFWfbconfig*) _glfwMalloc(sizeof(_GLFWfbconfig) * count);
if (!result)
{
_glfwSetError(GLFW_OUT_OF_MEMORY, "X11/GLX: Failed to allocate _GLFWfbconfig array");
@@ -1341,12 +1341,12 @@
result = _glfwChooseFBConfig(fbconfig, fbconfigs, fbcount);
if (!result)
{
- free(fbconfigs);
+ _glfwFree(fbconfigs);
return GL_FALSE;
}
closest = *result;
- free(fbconfigs);
+ _glfwFree(fbconfigs);
}
if (!createContext(window, wndconfig, (GLXFBConfigID) closest.platformID))