From f1e7d7c0ea8ebfa4b081525ad174eea0f4be4356 Mon Sep 17 00:00:00 2001
From: Camilla Berglund
Date: Tue, 23 Nov 2010 17:45:23 +0100
Subject: [PATCH] Added error callback.
---
include/GL/glfw3.h | 2 ++
readme.html | 1 +
src/cocoa/cocoa_window.m | 10 +++---
src/enable.c | 4 +--
src/error.c | 30 ++++++++++++++--
src/fullscreen.c | 6 ++--
src/gamma.c | 6 ++--
src/glext.c | 12 +++----
src/input.c | 24 ++++++-------
src/internal.h | 3 +-
src/joystick.c | 6 ++--
src/time.c | 4 +--
src/win32/win32_window.c | 28 +++++++--------
src/window.c | 76 ++++++++++++++++++++--------------------
src/x11/x11_init.c | 23 ++++++------
src/x11/x11_window.c | 36 ++++++++-----------
tests/version.c | 15 ++++----
17 files changed, 154 insertions(+), 132 deletions(-)
diff --git a/include/GL/glfw3.h b/include/GL/glfw3.h
index d645e9fa..d28802f7 100644
--- a/include/GL/glfw3.h
+++ b/include/GL/glfw3.h
@@ -392,6 +392,7 @@ typedef struct
} GLFWgammaramp;
/* Function pointer types */
+typedef void (* GLFWerrorfun)(int,const char*);
typedef void (* GLFWwindowsizefun)(GLFWwindow,int,int);
typedef int (* GLFWwindowclosefun)(GLFWwindow);
typedef void (* GLFWwindowrefreshfun)(GLFWwindow);
@@ -417,6 +418,7 @@ GLFWAPI const char* glfwGetVersionString(void);
/* Error handling */
GLFWAPI int glfwGetError(void);
GLFWAPI const char* glfwErrorString(int error);
+GLFWAPI void glfwSetErrorCallback(GLFWerrorfun cbfun);
/* Video mode functions */
GLFWAPI int glfwGetVideoModes(GLFWvidmode* list, int maxcount);
diff --git a/readme.html b/readme.html
index 03df9905..90a7247c 100644
--- a/readme.html
+++ b/readme.html
@@ -265,6 +265,7 @@ version of GLFW.
Added glfwIsWindow
function for verifying that a given window handle is (still) valid
Added glfwMakeWindowCurrent
function for making the context of the specified window current
Added glfwGetError
and glfwErrorString
error reporting functions and a number of error tokens
+ Added glfwSetErrorCallback
function and GLFWerrorfun
type for receiving more specific and/or nested errors
Added glfwSetWindowUserPointer
and glfwGetWindowUserPointer
functions for per-window user pointers
Added glfwGetVersionString
function for determining which code paths were enabled at compile time
Added glfwGetWindowPos
function for querying the position of the specified window
diff --git a/src/cocoa/cocoa_window.m b/src/cocoa/cocoa_window.m
index 2b389e4d..08c11fbc 100644
--- a/src/cocoa/cocoa_window.m
+++ b/src/cocoa/cocoa_window.m
@@ -475,7 +475,7 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window,
// Fail if OpenGL 3.0 or above was requested
if (wndconfig->glMajor > 2)
{
- _glfwSetError(GLFW_VERSION_UNAVAILABLE);
+ _glfwSetError(GLFW_VERSION_UNAVAILABLE, "Cocoa/NSOpenGL: Mac OS X does not support OpenGL version 3.0 or above");
return GL_FALSE;
}
@@ -486,7 +486,7 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window,
_glfwLibrary.NS.delegate = [[GLFWApplicationDelegate alloc] init];
if (_glfwLibrary.NS.delegate == nil)
{
- _glfwSetError(GLFW_PLATFORM_ERROR);
+ _glfwSetError(GLFW_PLATFORM_ERROR, "Cocoa/NSOpenGL: Failed to create application delegate");
return GL_FALSE;
}
@@ -496,7 +496,7 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window,
window->NS.delegate = [[GLFWWindowDelegate alloc] initWithGlfwWindow:window];
if (window->NS.delegate == nil)
{
- _glfwSetError(GLFW_PLATFORM_ERROR);
+ _glfwSetError(GLFW_PLATFORM_ERROR, "Cocoa/NSOpenGL: Failed to create window delegate");
return GL_FALSE;
}
@@ -627,7 +627,7 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window,
[[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
if (window->NSGL.pixelFormat == nil)
{
- _glfwSetError(GLFW_PLATFORM_ERROR);
+ _glfwSetError(GLFW_PLATFORM_ERROR, "Cocoa/NSOpenGL: Failed to create pixel format");
return GL_FALSE;
}
@@ -641,7 +641,7 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window,
shareContext:share];
if (window->NSGL.context == nil)
{
- _glfwSetError(GLFW_PLATFORM_ERROR);
+ _glfwSetError(GLFW_PLATFORM_ERROR, "Cocoa/NSOpenGL: Failed to create OpenGL context");
return GL_FALSE;
}
diff --git a/src/enable.c b/src/enable.c
index 60789290..bb3b8b38 100644
--- a/src/enable.c
+++ b/src/enable.c
@@ -185,7 +185,7 @@ GLFWAPI void glfwEnable(GLFWwindow window, int token)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
@@ -220,7 +220,7 @@ GLFWAPI void glfwDisable(GLFWwindow window, int token)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
diff --git a/src/error.c b/src/error.c
index 9eb80071..956f4d07 100644
--- a/src/error.c
+++ b/src/error.c
@@ -45,9 +45,17 @@ static int _glfwError = GLFW_NO_ERROR;
// Sets the current error value
//========================================================================
-void _glfwSetError(int error)
+void _glfwSetError(int error, const char* description)
{
- _glfwError = error;
+ if (_glfwLibrary.errorCallback)
+ {
+ if (!description)
+ description = glfwErrorString(error);
+
+ _glfwLibrary.errorCallback(error, description);
+ }
+ else
+ _glfwError = error;
}
@@ -99,3 +107,21 @@ GLFWAPI const char* glfwErrorString(int error)
}
}
+
+//========================================================================
+// Sets the callback function for GLFW errors
+//========================================================================
+
+GLFWAPI void glfwSetErrorCallback(GLFWerrorfun cbfun)
+{
+ if (!_glfwInitialized)
+ {
+ // TODO: Uhm... Hmm...
+
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
+ return;
+ }
+
+ _glfwLibrary.errorCallback = cbfun;
+}
+
diff --git a/src/fullscreen.c b/src/fullscreen.c
index 8b706a9d..a4c599c8 100644
--- a/src/fullscreen.c
+++ b/src/fullscreen.c
@@ -106,7 +106,7 @@ GLFWAPI int glfwGetVideoModes(GLFWvidmode* list, int maxcount)
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return 0;
}
@@ -132,13 +132,13 @@ GLFWAPI void glfwGetDesktopMode(GLFWvidmode* mode)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
if (mode == NULL)
{
- _glfwSetError(GLFW_INVALID_VALUE);
+ _glfwSetError(GLFW_INVALID_VALUE, "glfwGetDesktopMode: Parameter 'mode' cannot be NULL");
return;
}
diff --git a/src/gamma.c b/src/gamma.c
index b2416a98..42d6b776 100644
--- a/src/gamma.c
+++ b/src/gamma.c
@@ -48,7 +48,7 @@ GLFWAPI void glfwSetGammaFormula(float gamma, float blacklevel, float gain)
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
@@ -89,7 +89,7 @@ GLFWAPI void glfwGetGammaRamp(GLFWgammaramp* ramp)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
@@ -105,7 +105,7 @@ GLFWAPI void glfwSetGammaRamp(const GLFWgammaramp* ramp)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
diff --git a/src/glext.c b/src/glext.c
index 50369274..9ae29249 100644
--- a/src/glext.c
+++ b/src/glext.c
@@ -139,14 +139,14 @@ GLFWAPI int glfwExtensionSupported(const char* extension)
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return GL_FALSE;
}
window = _glfwLibrary.currentWindow;
if (!window)
{
- _glfwSetError(GLFW_NO_CURRENT_WINDOW);
+ _glfwSetError(GLFW_NO_CURRENT_WINDOW, NULL);
return GL_FALSE;
}
@@ -199,13 +199,13 @@ GLFWAPI void* glfwGetProcAddress(const char* procname)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return NULL;
}
if (!_glfwLibrary.currentWindow)
{
- _glfwSetError(GLFW_NO_CURRENT_WINDOW);
+ _glfwSetError(GLFW_NO_CURRENT_WINDOW, NULL);
return NULL;
}
@@ -223,14 +223,14 @@ GLFWAPI void glfwGetGLVersion(int* major, int* minor, int* rev)
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
window = _glfwLibrary.currentWindow;
if (!window)
{
- _glfwSetError(GLFW_NO_CURRENT_WINDOW);
+ _glfwSetError(GLFW_NO_CURRENT_WINDOW, NULL);
return;
}
diff --git a/src/input.c b/src/input.c
index 8a61fbef..f9f7c9e0 100644
--- a/src/input.c
+++ b/src/input.c
@@ -43,7 +43,7 @@ GLFWAPI int glfwGetKey(GLFWwindow window, int key)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return GLFW_RELEASE;
}
@@ -51,7 +51,7 @@ GLFWAPI int glfwGetKey(GLFWwindow window, int key)
if (key < 0 || key > GLFW_KEY_LAST)
{
// TODO: Decide whether key is a value or enum
- _glfwSetError(GLFW_INVALID_VALUE);
+ _glfwSetError(GLFW_INVALID_VALUE, "glfwGetKey: The specified key is invalid");
return GLFW_RELEASE;
}
@@ -74,14 +74,14 @@ GLFWAPI int glfwGetMouseButton(GLFWwindow window, int button)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return GLFW_RELEASE;
}
// Is it a valid mouse button?
if (button < 0 || button > GLFW_MOUSE_BUTTON_LAST)
{
- _glfwSetError(GLFW_INVALID_ENUM);
+ _glfwSetError(GLFW_INVALID_ENUM, "glfwGetMouseButton: The specified mouse button is invalid");
return GLFW_RELEASE;
}
@@ -104,7 +104,7 @@ GLFWAPI void glfwGetMousePos(GLFWwindow window, int* xpos, int* ypos)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
@@ -126,7 +126,7 @@ GLFWAPI void glfwSetMousePos(GLFWwindow window, int xpos, int ypos)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
@@ -155,7 +155,7 @@ GLFWAPI void glfwGetScrollOffset(GLFWwindow window, int* x, int* y)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
@@ -175,7 +175,7 @@ GLFWAPI void glfwSetKeyCallback(GLFWkeyfun cbfun)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
@@ -191,7 +191,7 @@ GLFWAPI void glfwSetCharCallback(GLFWcharfun cbfun)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
@@ -207,7 +207,7 @@ GLFWAPI void glfwSetMouseButtonCallback(GLFWmousebuttonfun cbfun)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
@@ -223,7 +223,7 @@ GLFWAPI void glfwSetMousePosCallback(GLFWmouseposfun cbfun)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
@@ -250,7 +250,7 @@ GLFWAPI void glfwSetScrollCallback(GLFWscrollfun cbfun)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
diff --git a/src/internal.h b/src/internal.h
index b85748d2..07c75bb4 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -216,6 +216,7 @@ struct _GLFWlibrary
_GLFWwindow* activeWindow;
_GLFWwindow* cursorLockWindow;
+ GLFWerrorfun errorCallback;
GLFWwindowsizefun windowSizeCallback;
GLFWwindowclosefun windowCloseCallback;
GLFWwindowrefreshfun windowRefreshCallback;
@@ -313,7 +314,7 @@ void* _glfwPlatformGetProcAddress(const char* procname);
void _glfwSplitBPP(int bpp, int* red, int* green, int* blue);
// Error handling
-void _glfwSetError(int error);
+void _glfwSetError(int error, const char* description);
// Window management (window.c)
void _glfwClearWindowHints(void);
diff --git a/src/joystick.c b/src/joystick.c
index 410b4ebb..a64d3198 100644
--- a/src/joystick.c
+++ b/src/joystick.c
@@ -43,7 +43,7 @@ GLFWAPI int glfwGetJoystickParam(int joy, int param)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return 0;
}
@@ -61,7 +61,7 @@ GLFWAPI int glfwGetJoystickPos(int joy, float* pos, int numaxes)
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return 0;
}
@@ -85,7 +85,7 @@ GLFWAPI int glfwGetJoystickButtons(int joy,
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return 0;
}
diff --git a/src/time.c b/src/time.c
index e47a18ea..8d1adbc2 100644
--- a/src/time.c
+++ b/src/time.c
@@ -43,7 +43,7 @@ GLFWAPI double glfwGetTime(void)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return 0.0;
}
@@ -59,7 +59,7 @@ GLFWAPI void glfwSetTime(double time)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
diff --git a/src/win32/win32_window.c b/src/win32/win32_window.c
index 565bcd66..e9c2626f 100644
--- a/src/win32/win32_window.c
+++ b/src/win32/win32_window.c
@@ -184,14 +184,14 @@ static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found)
if (!count)
{
- _glfwSetError(GLFW_OPENGL_UNAVAILABLE);
+ _glfwSetError(GLFW_OPENGL_UNAVAILABLE, "Win32/WGL: No pixel formats found");
return NULL;
}
result = (_GLFWfbconfig*) malloc(sizeof(_GLFWfbconfig) * count);
if (!result)
{
- _glfwSetError(GLFW_OUT_OF_MEMORY);
+ _glfwSetError(GLFW_OUT_OF_MEMORY, "Win32/WGL: Failed to allocate _GLFWfbconfig array");
return NULL;
}
@@ -324,13 +324,13 @@ static GLboolean createContext(_GLFWwindow* window,
if (!_glfw_DescribePixelFormat(window->WGL.DC, pixelFormat, sizeof(pfd), &pfd))
{
- _glfwSetError(GLFW_OPENGL_UNAVAILABLE);
+ _glfwSetError(GLFW_OPENGL_UNAVAILABLE, "Win32/WGL: Failed to retrieve PFD for selected pixel format");
return GL_FALSE;
}
if (!_glfw_SetPixelFormat(window->WGL.DC, pixelFormat, &pfd))
{
- _glfwSetError(GLFW_OPENGL_UNAVAILABLE);
+ _glfwSetError(GLFW_OPENGL_UNAVAILABLE, "Win32/WGL: Failed to set selected pixel format");
return GL_FALSE;
}
@@ -368,14 +368,14 @@ static GLboolean createContext(_GLFWwindow* window,
if (!window->WGL.has_WGL_ARB_create_context_profile)
{
- _glfwSetError(GLFW_VERSION_UNAVAILABLE);
+ _glfwSetError(GLFW_VERSION_UNAVAILABLE, "Win32/WGL: OpenGL profile requested but WGL_ARB_create_context_profile is unavailable");
return GL_FALSE;
}
if (wndconfig->glProfile == GLFW_OPENGL_ES2_PROFILE &&
!window->WGL.has_WGL_EXT_create_context_es2_profile)
{
- _glfwSetError(GLFW_VERSION_UNAVAILABLE);
+ _glfwSetError(GLFW_VERSION_UNAVAILABLE, "Win32/WGL: OpenGL ES 2.x profile requested but WGL_EXT_create_context_es2_profile is unavailable");
return GL_FALSE;
}
@@ -397,7 +397,7 @@ static GLboolean createContext(_GLFWwindow* window,
attribs);
if (!window->WGL.context)
{
- _glfwSetError(GLFW_VERSION_UNAVAILABLE);
+ _glfwSetError(GLFW_VERSION_UNAVAILABLE, "Win32/WGL: Failed to create OpenGL context");
return GL_FALSE;
}
}
@@ -406,7 +406,7 @@ static GLboolean createContext(_GLFWwindow* window,
window->WGL.context = wglCreateContext(window->WGL.DC);
if (!window->WGL.context)
{
- _glfwSetError(GLFW_PLATFORM_ERROR);
+ _glfwSetError(GLFW_PLATFORM_ERROR, "Win32/WGL: Failed to create OpenGL context");
return GL_FALSE;
}
@@ -414,7 +414,7 @@ static GLboolean createContext(_GLFWwindow* window,
{
if (!wglShareLists(share, window->WGL.context))
{
- _glfwSetError(GLFW_PLATFORM_ERROR);
+ _glfwSetError(GLFW_PLATFORM_ERROR, "Win32/WGL: Failed to enable sharing with specified OpenGL context");
return GL_FALSE;
}
}
@@ -1113,7 +1113,7 @@ static ATOM registerWindowClass(void)
classAtom = RegisterClass(&wc);
if (!classAtom)
{
- _glfwSetError(GLFW_PLATFORM_ERROR);
+ _glfwSetError(GLFW_PLATFORM_ERROR, "Win32/WGL: Failed to register window class");
return 0;
}
@@ -1227,14 +1227,14 @@ static int createWindow(_GLFWwindow* window,
if (!window->Win32.handle)
{
- _glfwSetError(GLFW_PLATFORM_ERROR);
+ _glfwSetError(GLFW_PLATFORM_ERROR, "Win32/WGL: Failed to create window");
return GL_FALSE;
}
window->WGL.DC = GetDC(window->Win32.handle);
if (!window->WGL.DC)
{
- _glfwSetError(GLFW_PLATFORM_ERROR);
+ _glfwSetError(GLFW_PLATFORM_ERROR, "Win32/WGL: Failed to retrieve DC for window");
return GL_FALSE;
}
@@ -1352,7 +1352,7 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window,
{
if (!window->WGL.has_WGL_ARB_create_context)
{
- _glfwSetError(GLFW_VERSION_UNAVAILABLE);
+ _glfwSetError(GLFW_VERSION_UNAVAILABLE, "Win32/WGL: A forward compatible or debug OpenGL context requested but WGL_ARB_create_context is unavailable");
return GL_FALSE;
}
@@ -1363,7 +1363,7 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window,
{
if (!window->WGL.has_WGL_ARB_create_context_profile)
{
- _glfwSetError(GLFW_VERSION_UNAVAILABLE);
+ _glfwSetError(GLFW_VERSION_UNAVAILABLE, "Win32/WGL: OpenGL profile requested but WGL_ARB_create_context_profile is unavailable");
return GL_FALSE;
}
diff --git a/src/window.c b/src/window.c
index 5e57a1ac..ce260b32 100644
--- a/src/window.c
+++ b/src/window.c
@@ -437,14 +437,14 @@ GLFWAPI GLFWwindow glfwOpenWindow(int width, int height,
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return NULL;
}
window = (_GLFWwindow*) malloc(sizeof(_GLFWwindow));
if (!window)
{
- _glfwSetError(GLFW_OUT_OF_MEMORY);
+ _glfwSetError(GLFW_OUT_OF_MEMORY, "glfwOpenWindow: Failed to allocate window structure");
return NULL;
}
@@ -487,21 +487,21 @@ GLFWAPI GLFWwindow glfwOpenWindow(int width, int height,
{
// OpenGL 1.x series ended with version 1.5
glfwCloseWindow(window);
- _glfwSetError(GLFW_INVALID_VALUE);
+ _glfwSetError(GLFW_INVALID_VALUE, "glfwOpenWindow: Invalid OpenGL version requested");
return GL_FALSE;
}
else if (wndconfig.glMajor == 2 && wndconfig.glMinor > 1)
{
// OpenGL 2.x series ended with version 2.1
glfwCloseWindow(window);
- _glfwSetError(GLFW_INVALID_VALUE);
+ _glfwSetError(GLFW_INVALID_VALUE, "glfwOpenWindow: Invalid OpenGL version requested");
return GL_FALSE;
}
else if (wndconfig.glMajor == 3 && wndconfig.glMinor > 3)
{
// OpenGL 3.x series ended with version 3.3
glfwCloseWindow(window);
- _glfwSetError(GLFW_INVALID_VALUE);
+ _glfwSetError(GLFW_INVALID_VALUE, "glfwOpenWindow: Invalid OpenGL version requested");
return GL_FALSE;
}
else
@@ -519,7 +519,7 @@ GLFWAPI GLFWwindow glfwOpenWindow(int width, int height,
// everything 2.x and let the driver report invalid versions
glfwCloseWindow(window);
- _glfwSetError(GLFW_INVALID_VALUE);
+ _glfwSetError(GLFW_INVALID_VALUE, "glfwOpenWindow: Invalid OpenGL ES 2.x version requested");
return GL_FALSE;
}
}
@@ -531,7 +531,7 @@ GLFWAPI GLFWwindow glfwOpenWindow(int width, int height,
// and above
glfwCloseWindow(window);
- _glfwSetError(GLFW_INVALID_VALUE);
+ _glfwSetError(GLFW_INVALID_VALUE, "glfwOpenWindow: Context profiles only exist for OpenGL version 3.2 and above");
return GL_FALSE;
}
}
@@ -540,7 +540,7 @@ GLFWAPI GLFWwindow glfwOpenWindow(int width, int height,
{
// Forward-compatible contexts are only defined for OpenGL version 3.0 and above
glfwCloseWindow(window);
- _glfwSetError(GLFW_INVALID_VALUE);
+ _glfwSetError(GLFW_INVALID_VALUE, "glfwOpenWindow: Forward compatibility only exist for OpenGL version 3.0 and above");
return GL_FALSE;
}
@@ -548,7 +548,7 @@ GLFWAPI GLFWwindow glfwOpenWindow(int width, int height,
{
// Invalid window mode
glfwCloseWindow(window);
- _glfwSetError(GLFW_INVALID_ENUM);
+ _glfwSetError(GLFW_INVALID_ENUM, "glfwOpenWindow: Invalid enum for 'mode' parameter");
return GL_FALSE;
}
@@ -601,7 +601,7 @@ GLFWAPI GLFWwindow glfwOpenWindow(int width, int height,
// The desired OpenGL version is greater than the actual version
// This only happens if the machine lacks {GLX|WGL}_ARB_create_context
glfwCloseWindow(window);
- _glfwSetError(GLFW_VERSION_UNAVAILABLE);
+ _glfwSetError(GLFW_VERSION_UNAVAILABLE, "glfwOpenWindow: The requested OpenGL version is not available");
return GL_FALSE;
}
@@ -611,7 +611,7 @@ GLFWAPI GLFWwindow glfwOpenWindow(int width, int height,
if (!window->GetStringi)
{
glfwCloseWindow(window);
- _glfwSetError(GLFW_PLATFORM_ERROR);
+ _glfwSetError(GLFW_PLATFORM_ERROR, "glfwOpenWindow: Entry point retrieval is broken; see the build documentation for your platform");
return GL_FALSE;
}
}
@@ -637,7 +637,7 @@ GLFWAPI void glfwMakeWindowCurrent(GLFWwindow window)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
@@ -659,7 +659,7 @@ GLFWAPI int glfwIsWindow(GLFWwindow window)
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return GL_FALSE;
}
@@ -684,7 +684,7 @@ GLFWAPI GLFWwindow glfwGetCurrentWindow(void)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return GL_FALSE;
}
@@ -700,7 +700,7 @@ GLFWAPI void glfwOpenWindowHint(int target, int hint)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
@@ -780,7 +780,7 @@ GLFWAPI void glfwCloseWindow(GLFWwindow window)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
@@ -820,7 +820,7 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow window, const char* title)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
@@ -836,7 +836,7 @@ GLFWAPI void glfwGetWindowSize(GLFWwindow window, int* width, int* height)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
@@ -856,7 +856,7 @@ GLFWAPI void glfwSetWindowSize(GLFWwindow window, int width, int height)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
@@ -889,7 +889,7 @@ GLFWAPI void glfwGetWindowPos(GLFWwindow window, int* x, int* y)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
@@ -909,7 +909,7 @@ GLFWAPI void glfwSetWindowPos(GLFWwindow window, int x, int y)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
@@ -931,7 +931,7 @@ GLFWAPI void glfwIconifyWindow(GLFWwindow window)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
@@ -950,7 +950,7 @@ GLFWAPI void glfwRestoreWindow(GLFWwindow window)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
@@ -973,13 +973,13 @@ GLFWAPI void glfwSwapBuffers(void)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
if (!_glfwLibrary.currentWindow)
{
- _glfwSetError(GLFW_NO_CURRENT_WINDOW);
+ _glfwSetError(GLFW_NO_CURRENT_WINDOW, NULL);
return;
}
@@ -996,13 +996,13 @@ GLFWAPI void glfwSwapInterval(int interval)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
if (!_glfwLibrary.currentWindow)
{
- _glfwSetError(GLFW_NO_CURRENT_WINDOW);
+ _glfwSetError(GLFW_NO_CURRENT_WINDOW, NULL);
return;
}
@@ -1018,7 +1018,7 @@ GLFWAPI int glfwGetWindowParam(GLFWwindow window, int param)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return 0;
}
@@ -1071,7 +1071,7 @@ GLFWAPI int glfwGetWindowParam(GLFWwindow window, int param)
case GLFW_OPENGL_PROFILE:
return window->glProfile;
default:
- _glfwSetError(GLFW_INVALID_ENUM);
+ _glfwSetError(GLFW_INVALID_ENUM, "glfwGetWindowParam: Invalid enum value for 'param' parameter");
return 0;
}
}
@@ -1085,7 +1085,7 @@ GLFWAPI void glfwSetWindowUserPointer(GLFWwindow window, void* pointer)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
@@ -1101,7 +1101,7 @@ GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow window)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return NULL;
}
@@ -1117,7 +1117,7 @@ GLFWAPI void glfwSetWindowSizeCallback(GLFWwindowsizefun cbfun)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
@@ -1142,7 +1142,7 @@ GLFWAPI void glfwSetWindowCloseCallback(GLFWwindowclosefun cbfun)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
@@ -1158,7 +1158,7 @@ GLFWAPI void glfwSetWindowRefreshCallback(GLFWwindowrefreshfun cbfun)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
@@ -1174,7 +1174,7 @@ GLFWAPI void glfwSetWindowFocusCallback(GLFWwindowfocusfun cbfun)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
@@ -1190,7 +1190,7 @@ GLFWAPI void glfwSetWindowIconifyCallback(GLFWwindowiconifyfun cbfun)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
@@ -1206,7 +1206,7 @@ GLFWAPI void glfwPollEvents(void)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
@@ -1226,7 +1226,7 @@ GLFWAPI void glfwWaitEvents(void)
{
if (!_glfwInitialized)
{
- _glfwSetError(GLFW_NOT_INITIALIZED);
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return;
}
diff --git a/src/x11/x11_init.c b/src/x11/x11_init.c
index ac5c3054..38c31584 100644
--- a/src/x11/x11_init.c
+++ b/src/x11/x11_init.c
@@ -71,12 +71,11 @@ static GLboolean initDisplay(void)
_glfwLibrary.X11.display = XOpenDisplay(0);
if (!_glfwLibrary.X11.display)
{
- fprintf(stderr, "Failed to open X display\n");
- _glfwSetError(GLFW_OPENGL_UNAVAILABLE);
+ _glfwSetError(GLFW_OPENGL_UNAVAILABLE, "X11/GLX: Failed to open X display");
return GL_FALSE;
}
- // As the API currently doesn't understand multiple display devices, we hardcode
+ // As the API currently doesn't understand multiple display devices, we hard-code
// this choice and hope for the best
_glfwLibrary.X11.screen = DefaultScreen(_glfwLibrary.X11.display);
_glfwLibrary.X11.root = RootWindow(_glfwLibrary.X11.display,
@@ -99,11 +98,15 @@ static GLboolean initDisplay(void)
&_glfwLibrary.X11.RandR.eventBase,
&_glfwLibrary.X11.RandR.errorBase);
- if (!XRRQueryVersion(_glfwLibrary.X11.display,
- &_glfwLibrary.X11.RandR.majorVersion,
- &_glfwLibrary.X11.RandR.minorVersion))
+ if (_glfwLibrary.X11.RandR.available)
{
- fprintf(stderr, "Unable to query RandR version number\n");
+ if (!XRRQueryVersion(_glfwLibrary.X11.display,
+ &_glfwLibrary.X11.RandR.majorVersion,
+ &_glfwLibrary.X11.RandR.minorVersion))
+ {
+ _glfwSetError(GLFW_PLATFORM_ERROR, "X11/GLX: Failed to query RandR version");
+ return GL_FALSE;
+ }
}
#else
_glfwLibrary.X11.RandR.available = GL_FALSE;
@@ -112,8 +115,7 @@ static GLboolean initDisplay(void)
// Check if GLX is supported on this display
if (!glXQueryExtension(_glfwLibrary.X11.display, NULL, NULL))
{
- fprintf(stderr, "GLX not supported\n");
- _glfwSetError(GLFW_OPENGL_UNAVAILABLE);
+ _glfwSetError(GLFW_OPENGL_UNAVAILABLE, "X11/GLX: GLX supported not found");
return GL_FALSE;
}
@@ -121,8 +123,7 @@ static GLboolean initDisplay(void)
&_glfwLibrary.X11.glxMajor,
&_glfwLibrary.X11.glxMinor))
{
- fprintf(stderr, "Unable to query GLX version\n");
- _glfwSetError(GLFW_OPENGL_UNAVAILABLE);
+ _glfwSetError(GLFW_OPENGL_UNAVAILABLE, "X11/GLX: Failed to query GLX version");
return GL_FALSE;
}
diff --git a/src/x11/x11_window.c b/src/x11/x11_window.c
index a1528835..981acaef 100644
--- a/src/x11/x11_window.c
+++ b/src/x11/x11_window.c
@@ -387,8 +387,7 @@ static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found)
{
if (!window->GLX.has_GLX_SGIX_fbconfig)
{
- fprintf(stderr, "GLXFBConfigs are not supported by the X server\n");
- _glfwSetError(GLFW_OPENGL_UNAVAILABLE);
+ _glfwSetError(GLFW_OPENGL_UNAVAILABLE, "X11/GLX: GLXFBConfig support not found");
return NULL;
}
}
@@ -401,8 +400,7 @@ static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found)
&count);
if (!count)
{
- fprintf(stderr, "No GLXFBConfigs returned\n");
- _glfwSetError(GLFW_OPENGL_UNAVAILABLE);
+ _glfwSetError(GLFW_OPENGL_UNAVAILABLE, "X11/GLX: No GLXFBConfigs returned");
return NULL;
}
}
@@ -411,8 +409,7 @@ static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found)
fbconfigs = glXGetFBConfigs(_glfwLibrary.X11.display, _glfwLibrary.X11.screen, &count);
if (!count)
{
- fprintf(stderr, "No GLXFBConfigs returned\n");
- _glfwSetError(GLFW_OPENGL_UNAVAILABLE);
+ _glfwSetError(GLFW_OPENGL_UNAVAILABLE, "X11/GLX: No GLXFBConfigs returned");
return NULL;
}
}
@@ -420,7 +417,7 @@ static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found)
result = (_GLFWfbconfig*) malloc(sizeof(_GLFWfbconfig) * count);
if (!result)
{
- _glfwSetError(GLFW_OUT_OF_MEMORY);
+ _glfwSetError(GLFW_OUT_OF_MEMORY, "X11/GLX: Failed to allocate _GLFWfbconfig array");
return NULL;
}
@@ -521,8 +518,7 @@ static int createContext(_GLFWwindow* window,
if (fbconfig == NULL)
{
- fprintf(stderr, "Unable to retrieve the selected GLXFBConfig\n");
- _glfwSetError(GLFW_PLATFORM_ERROR);
+ _glfwSetError(GLFW_PLATFORM_ERROR, "X11/GLX: Failed to retrieve the selected GLXFBConfig");
return GL_FALSE;
}
}
@@ -543,8 +539,7 @@ static int createContext(_GLFWwindow* window,
{
XFree(fbconfig);
- fprintf(stderr, "Unable to retrieve visual for GLXFBconfig\n");
- _glfwSetError(GLFW_PLATFORM_ERROR);
+ _glfwSetError(GLFW_PLATFORM_ERROR, "X11/GLX: Failed to retrieve visual for GLXFBConfig");
return GL_FALSE;
}
@@ -579,18 +574,14 @@ static int createContext(_GLFWwindow* window,
if (!window->GLX.has_GLX_ARB_create_context_profile)
{
- fprintf(stderr, "OpenGL profile requested but GLX_ARB_create_context_profile "
- "is unavailable\n");
- _glfwSetError(GLFW_VERSION_UNAVAILABLE);
+ _glfwSetError(GLFW_VERSION_UNAVAILABLE, "X11/GLX: An OpenGL profile requested but GLX_ARB_create_context_profile is unavailable");
return GL_FALSE;
}
if (wndconfig->glProfile == GLFW_OPENGL_ES2_PROFILE &&
!window->GLX.has_GLX_EXT_create_context_es2_profile)
{
- fprintf(stderr, "OpenGL ES2 profile requested but "
- "GLX_EXT_create_context_es2_profile is unavailable\n");
- _glfwSetError(GLFW_VERSION_UNAVAILABLE);
+ _glfwSetError(GLFW_VERSION_UNAVAILABLE, "X11/GLX: OpenGL ES 2.x profile requested but GLX_EXT_create_context_es2_profile is unavailable");
return GL_FALSE;
}
@@ -647,9 +638,9 @@ static int createContext(_GLFWwindow* window,
if (window->GLX.context == NULL)
{
- fprintf(stderr, "Unable to create OpenGL context\n");
// TODO: Handle all the various error codes here
- _glfwSetError(GLFW_PLATFORM_ERROR);
+
+ _glfwSetError(GLFW_PLATFORM_ERROR, "X11/GLX: Failed to create OpenGL context");
return GL_FALSE;
}
@@ -790,7 +781,8 @@ static GLboolean createWindow(_GLFWwindow* window,
if (!window->X11.handle)
{
// TODO: Handle all the various error codes here
- _glfwSetError(GLFW_PLATFORM_ERROR);
+
+ _glfwSetError(GLFW_PLATFORM_ERROR, "X11/GLX: Failed to create window");
return GL_FALSE;
}
}
@@ -851,7 +843,7 @@ static GLboolean createWindow(_GLFWwindow* window,
XWMHints* hints = XAllocWMHints();
if (!hints)
{
- _glfwSetError(GLFW_OUT_OF_MEMORY);
+ _glfwSetError(GLFW_OUT_OF_MEMORY, "X11/GLX: Failed to allocate WM hints");
return GL_FALSE;
}
@@ -867,7 +859,7 @@ static GLboolean createWindow(_GLFWwindow* window,
XSizeHints* hints = XAllocSizeHints();
if (!hints)
{
- _glfwSetError(GLFW_OUT_OF_MEMORY);
+ _glfwSetError(GLFW_OUT_OF_MEMORY, "X11/GLX: Failed to allocate size hints");
return GL_FALSE;
}
diff --git a/tests/version.c b/tests/version.c
index 5ed9ae05..af0c33a6 100644
--- a/tests/version.c
+++ b/tests/version.c
@@ -48,6 +48,11 @@ static void usage(void)
printf("available profiles: core compat es2\n");
}
+static void error_callback(int error, const char* description)
+{
+ fprintf(stderr, "Error: %s in %s\n", glfwErrorString(error), description);
+}
+
static const char* get_glfw_profile_name(int profile)
{
if (profile == GLFW_OPENGL_COMPAT_PROFILE)
@@ -82,10 +87,7 @@ static void list_extensions(int major, int minor)
{
PFNGLGETSTRINGIPROC glGetStringi = (PFNGLGETSTRINGIPROC) glfwGetProcAddress("glGetStringi");
if (!glGetStringi)
- {
- fprintf(stderr, "Failed to retrieve glGetStringi entry point: %s\n", glfwErrorString(glfwGetError()));
exit(EXIT_FAILURE);
- }
glGetIntegerv(GL_NUM_EXTENSIONS, &count);
@@ -166,6 +168,8 @@ int main(int argc, char** argv)
exit(EXIT_FAILURE);
}
+ glfwSetErrorCallback(error_callback);
+
if (major != 1 || minor != 0)
{
glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, major);
@@ -186,12 +190,7 @@ int main(int argc, char** argv)
window = glfwOpenWindow(0, 0, GLFW_WINDOWED, "Version", NULL);
if (!window)
- {
- glfwTerminate();
-
- fprintf(stderr, "Failed to open GLFW window: %s\n", glfwErrorString(glfwGetError()));
exit(EXIT_FAILURE);
- }
// Report GLFW version