Merge branch 'master' into multi-monitor

Conflicts:
	src/cocoa_window.m
	src/init.c
	tests/iconify.c
	tests/reopen.c
This commit is contained in:
Camilla Berglund
2012-12-30 22:18:15 +01:00
32 changed files with 434 additions and 402 deletions
+1 -3
View File
@@ -118,7 +118,7 @@ int _glfwPlatformInit(void)
// Close window, if open, and shut down GLFW
//========================================================================
int _glfwPlatformTerminate(void)
void _glfwPlatformTerminate(void)
{
// TODO: Probably other cleanup
@@ -142,8 +142,6 @@ int _glfwPlatformTerminate(void)
_glfwTerminateJoysticks();
_glfwTerminateOpenGL();
return GL_TRUE;
}
+4
View File
@@ -120,5 +120,9 @@ void _glfwRestoreVideoMode(void);
// OpenGL support
int _glfwInitOpenGL(void);
void _glfwTerminateOpenGL(void);
int _glfwCreateContext(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig,
const _GLFWfbconfig* fbconfig);
void _glfwDestroyContext(_GLFWwindow* window);
#endif // _cocoa_platform_h_
+2 -166
View File
@@ -711,166 +711,6 @@ static GLboolean createWindow(_GLFWwindow* window,
}
//========================================================================
// Create the OpenGL context
//========================================================================
static GLboolean createContext(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig,
const _GLFWfbconfig* fbconfig)
{
unsigned int attributeCount = 0;
// Mac OS X needs non-zero color size, so set resonable values
int colorBits = fbconfig->redBits + fbconfig->greenBits + fbconfig->blueBits;
if (colorBits == 0)
colorBits = 24;
else if (colorBits < 15)
colorBits = 15;
if (wndconfig->clientAPI == GLFW_OPENGL_ES_API)
{
_glfwSetError(GLFW_VERSION_UNAVAILABLE,
"NSOpenGL: This API does not support OpenGL ES");
return GL_FALSE;
}
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
// Fail if any OpenGL version above 2.1 other than 3.2 was requested
if (wndconfig->glMajor > 3 ||
(wndconfig->glMajor == 3 && wndconfig->glMinor != 2))
{
_glfwSetError(GLFW_VERSION_UNAVAILABLE,
"NSOpenGL: The targeted version of Mac OS X does not "
"support any OpenGL version above 2.1 except 3.2");
return GL_FALSE;
}
if (wndconfig->glMajor > 2)
{
if (!wndconfig->glForward)
{
_glfwSetError(GLFW_VERSION_UNAVAILABLE,
"NSOpenGL: The targeted version of Mac OS X only "
"supports OpenGL 3.2 contexts if they are "
"forward-compatible");
return GL_FALSE;
}
if (wndconfig->glProfile != GLFW_OPENGL_CORE_PROFILE)
{
_glfwSetError(GLFW_VERSION_UNAVAILABLE,
"NSOpenGL: The targeted version of Mac OS X only "
"supports OpenGL 3.2 contexts if they use the "
"core profile");
return GL_FALSE;
}
}
#else
// Fail if OpenGL 3.0 or above was requested
if (wndconfig->glMajor > 2)
{
_glfwSetError(GLFW_VERSION_UNAVAILABLE,
"NSOpenGL: The targeted version of Mac OS X does not "
"support OpenGL version 3.0 or above");
return GL_FALSE;
}
#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
// Fail if a robustness strategy was requested
if (wndconfig->glRobustness)
{
_glfwSetError(GLFW_VERSION_UNAVAILABLE,
"NSOpenGL: Mac OS X does not support OpenGL robustness "
"strategies");
return GL_FALSE;
}
#define ADD_ATTR(x) { attributes[attributeCount++] = x; }
#define ADD_ATTR2(x, y) { ADD_ATTR(x); ADD_ATTR(y); }
// Arbitrary array size here
NSOpenGLPixelFormatAttribute attributes[40];
ADD_ATTR(NSOpenGLPFADoubleBuffer);
if (wndconfig->monitor)
{
ADD_ATTR(NSOpenGLPFANoRecovery);
ADD_ATTR2(NSOpenGLPFAScreenMask,
CGDisplayIDToOpenGLDisplayMask(CGMainDisplayID()));
}
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
if (wndconfig->glMajor > 2)
ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core);
#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
ADD_ATTR2(NSOpenGLPFAColorSize, colorBits);
if (fbconfig->alphaBits > 0)
ADD_ATTR2(NSOpenGLPFAAlphaSize, fbconfig->alphaBits);
if (fbconfig->depthBits > 0)
ADD_ATTR2(NSOpenGLPFADepthSize, fbconfig->depthBits);
if (fbconfig->stencilBits > 0)
ADD_ATTR2(NSOpenGLPFAStencilSize, fbconfig->stencilBits);
int accumBits = fbconfig->accumRedBits + fbconfig->accumGreenBits +
fbconfig->accumBlueBits + fbconfig->accumAlphaBits;
if (accumBits > 0)
ADD_ATTR2(NSOpenGLPFAAccumSize, accumBits);
if (fbconfig->auxBuffers > 0)
ADD_ATTR2(NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers);
if (fbconfig->stereo)
ADD_ATTR(NSOpenGLPFAStereo);
if (fbconfig->samples > 0)
{
ADD_ATTR2(NSOpenGLPFASampleBuffers, 1);
ADD_ATTR2(NSOpenGLPFASamples, fbconfig->samples);
}
// NOTE: All NSOpenGLPixelFormats on the relevant cards support sRGB
// frambuffer, so there's no need (and no way) to request it
ADD_ATTR(0);
#undef ADD_ATTR
#undef ADD_ATTR2
window->NSGL.pixelFormat =
[[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
if (window->NSGL.pixelFormat == nil)
{
_glfwSetError(GLFW_PLATFORM_ERROR,
"NSOpenGL: Failed to create OpenGL pixel format");
return GL_FALSE;
}
NSOpenGLContext* share = NULL;
if (wndconfig->share)
share = wndconfig->share->NSGL.context;
window->NSGL.context =
[[NSOpenGLContext alloc] initWithFormat:window->NSGL.pixelFormat
shareContext:share];
if (window->NSGL.context == nil)
{
_glfwSetError(GLFW_PLATFORM_ERROR,
"NSOpenGL: Failed to create OpenGL context");
return GL_FALSE;
}
return GL_TRUE;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
@@ -923,7 +763,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
if (!createWindow(window, wndconfig))
return GL_FALSE;
if (!createContext(window, wndconfig, fbconfig))
if (!_glfwCreateContext(window, wndconfig, fbconfig))
return GL_FALSE;
[window->NSGL.context setView:[window->NS.object contentView]];
@@ -968,11 +808,7 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
_glfwRestoreVideoMode();
}
[window->NSGL.pixelFormat release];
window->NSGL.pixelFormat = nil;
[window->NSGL.context release];
window->NSGL.context = nil;
_glfwDestroyContext(window);
[window->NS.object setDelegate:nil];
[window->NS.delegate release];
+64 -27
View File
@@ -38,6 +38,11 @@
void (*glXGetProcAddressEXT(const GLubyte* procName))();
#ifndef GLXBadProfileARB
#define GLXBadProfileARB 13
#endif
//========================================================================
// Thread local storage attribute macro
//========================================================================
@@ -48,6 +53,12 @@ void (*glXGetProcAddressEXT(const GLubyte* procName))();
#endif
//========================================================================
// The X error code as provided to the X error handler
//========================================================================
static unsigned long _glfwErrorCode = Success;
//========================================================================
// The per-thread current context/window pointer
//========================================================================
@@ -207,18 +218,48 @@ static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found)
//========================================================================
// Error handler for BadMatch errors when requesting context with
// unavailable OpenGL versions using the GLX_ARB_create_context extension
// Error handler used when creating a context with the GLX_ARB_create_context
// extension set
//========================================================================
static int errorHandler(Display *display, XErrorEvent* event)
{
_glfwErrorCode = event->error_code;
return 0;
}
//========================================================================
// Create the actual OpenGL context
// Create the OpenGL context using legacy API
//========================================================================
static void createLegacyContext(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig,
GLXFBConfig fbconfig,
GLXContext share)
{
if (_glfwLibrary.GLX.SGIX_fbconfig)
{
window->GLX.context =
_glfwLibrary.GLX.CreateContextWithConfigSGIX(_glfwLibrary.X11.display,
fbconfig,
GLX_RGBA_TYPE,
share,
True);
}
else
{
window->GLX.context = glXCreateNewContext(_glfwLibrary.X11.display,
fbconfig,
GLX_RGBA_TYPE,
share,
True);
}
}
//========================================================================
// Create the OpenGL context
//========================================================================
#define setGLXattrib(attribName, attribValue) \
@@ -386,6 +427,7 @@ static int createContext(_GLFWwindow* window,
// it because glXCreateContextAttribsARB generates a BadMatch error if
// the requested OpenGL version is unavailable (instead of a civilized
// response like returning NULL)
_glfwErrorCode = Success;
XSetErrorHandler(errorHandler);
window->GLX.context =
@@ -397,36 +439,29 @@ static int createContext(_GLFWwindow* window,
// We are done, so unset the error handler again (see above)
XSetErrorHandler(NULL);
if (window->GLX.context == NULL)
{
// HACK: This is a fallback for the broken Mesa implementation of
// GLX_ARB_create_context_profile, which fails default 1.0 context
// creation with a GLXBadProfileARB error in violation of the spec
if (_glfwErrorCode == _glfwLibrary.GLX.errorBase + GLXBadProfileARB &&
wndconfig->clientAPI == GLFW_OPENGL_API &&
wndconfig->glProfile == GLFW_OPENGL_NO_PROFILE &&
wndconfig->glForward == GL_FALSE)
{
createLegacyContext(window, wndconfig, *fbconfig, share);
}
}
}
else
{
if (_glfwLibrary.GLX.SGIX_fbconfig)
{
window->GLX.context =
_glfwLibrary.GLX.CreateContextWithConfigSGIX(_glfwLibrary.X11.display,
*fbconfig,
GLX_RGBA_TYPE,
share,
True);
}
else
{
window->GLX.context = glXCreateNewContext(_glfwLibrary.X11.display,
*fbconfig,
GLX_RGBA_TYPE,
share,
True);
}
}
createLegacyContext(window, wndconfig, *fbconfig, share);
XFree(fbconfig);
if (window->GLX.context == NULL)
{
// TODO: Handle all the various error codes here
_glfwSetError(GLFW_PLATFORM_ERROR,
"GLX: Failed to create context");
_glfwSetError(GLFW_PLATFORM_ERROR, "GLX: Failed to create context");
return GL_FALSE;
}
@@ -472,7 +507,9 @@ int _glfwInitOpenGL(void)
#endif
// Check if GLX is supported on this display
if (!glXQueryExtension(_glfwLibrary.X11.display, NULL, NULL))
if (!glXQueryExtension(_glfwLibrary.X11.display,
&_glfwLibrary.GLX.errorBase,
&_glfwLibrary.GLX.eventBase))
{
_glfwSetError(GLFW_API_UNAVAILABLE, "GLX: GLX support not found");
return GL_FALSE;
+2
View File
@@ -90,6 +90,8 @@ typedef struct _GLFWlibraryGLX
{
// Server-side GLX version
int majorVersion, minorVersion;
int eventBase;
int errorBase;
// GLX extensions
PFNGLXSWAPINTERVALSGIPROC SwapIntervalSGI;
+36 -62
View File
@@ -50,15 +50,6 @@ GLboolean _glfwInitialized = GL_FALSE;
_GLFWlibrary _glfwLibrary;
//------------------------------------------------------------------------
// The current GLFW error code
// This is outside of _glfwLibrary so it can be initialized and usable
// before glfwInit is called, which lets that function report errors
// TODO: Make this thread-local
//------------------------------------------------------------------------
static int _glfwError = GLFW_NO_ERROR;
//------------------------------------------------------------------------
// The current error callback
// This is outside of _glfwLibrary so it can be initialized and usable
@@ -67,6 +58,40 @@ static int _glfwError = GLFW_NO_ERROR;
static GLFWerrorfun _glfwErrorCallback = NULL;
//========================================================================
// Returns a generic string representation of the specified error
//========================================================================
static const char* getErrorString(int error)
{
switch (error)
{
case GLFW_NO_ERROR:
return "No error";
case GLFW_NOT_INITIALIZED:
return "The GLFW library is not initialized";
case GLFW_NO_CURRENT_CONTEXT:
return "There is no current context";
case GLFW_INVALID_ENUM:
return "Invalid argument for enum parameter";
case GLFW_INVALID_VALUE:
return "Invalid value for parameter";
case GLFW_OUT_OF_MEMORY:
return "Out of memory";
case GLFW_API_UNAVAILABLE:
return "The requested client API is unavailable";
case GLFW_VERSION_UNAVAILABLE:
return "The requested client API version is unavailable";
case GLFW_PLATFORM_ERROR:
return "A platform-specific error occurred";
case GLFW_FORMAT_UNAVAILABLE:
return "The requested format is unavailable";
}
return "ERROR: UNKNOWN ERROR TOKEN PASSED TO glfwErrorString";
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
@@ -97,12 +122,10 @@ void _glfwSetError(int error, const char* format, ...)
description = buffer;
}
else
description = glfwErrorString(error);
description = getErrorString(error);
_glfwErrorCallback(error, description);
}
else
_glfwError = error;
}
@@ -158,8 +181,7 @@ GLFWAPI void glfwTerminate(void)
_glfwDestroyMonitors();
if (!_glfwPlatformTerminate())
return;
_glfwPlatformTerminate();
_glfwInitialized = GL_FALSE;
}
@@ -194,54 +216,6 @@ GLFWAPI const char* glfwGetVersionString(void)
}
//========================================================================
// Returns the current error value
// This function may be called without GLFW having been initialized
//========================================================================
GLFWAPI int glfwGetError(void)
{
int error = _glfwError;
_glfwError = GLFW_NO_ERROR;
return error;
}
//========================================================================
// Returns a string representation of the specified error value
// This function may be called without GLFW having been initialized
//========================================================================
GLFWAPI const char* glfwErrorString(int error)
{
switch (error)
{
case GLFW_NO_ERROR:
return "No error";
case GLFW_NOT_INITIALIZED:
return "The GLFW library is not initialized";
case GLFW_NO_CURRENT_CONTEXT:
return "There is no current context";
case GLFW_INVALID_ENUM:
return "Invalid argument for enum parameter";
case GLFW_INVALID_VALUE:
return "Invalid value for parameter";
case GLFW_OUT_OF_MEMORY:
return "Out of memory";
case GLFW_API_UNAVAILABLE:
return "The requested client API is unavailable";
case GLFW_VERSION_UNAVAILABLE:
return "The requested client API version is unavailable";
case GLFW_PLATFORM_ERROR:
return "A platform-specific error occurred";
case GLFW_FORMAT_UNAVAILABLE:
return "The requested format is unavailable";
}
return "ERROR: UNKNOWN ERROR TOKEN PASSED TO glfwErrorString";
}
//========================================================================
// Sets the callback function for GLFW errors
// This function may be called without GLFW having been initialized
+1 -3
View File
@@ -289,12 +289,10 @@ extern _GLFWlibrary _glfwLibrary;
// Platform init and version
int _glfwPlatformInit(void);
int _glfwPlatformTerminate(void);
void _glfwPlatformTerminate(void);
const char* _glfwPlatformGetVersionString(void);
// Input mode support
void _glfwPlatformEnableSystemKeys(_GLFWwindow* window);
void _glfwPlatformDisableSystemKeys(_GLFWwindow* window);
void _glfwPlatformSetCursorPos(_GLFWwindow* window, int x, int y);
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode);
+179 -1
View File
@@ -39,7 +39,7 @@ static pthread_key_t _glfwCurrentTLS;
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
//========================================================================
@@ -69,6 +69,184 @@ void _glfwTerminateOpenGL(void)
}
//========================================================================
// Create the OpenGL context
//========================================================================
int _glfwCreateContext(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig,
const _GLFWfbconfig* fbconfig)
{
unsigned int attributeCount = 0;
// Mac OS X needs non-zero color size, so set resonable values
int colorBits = fbconfig->redBits + fbconfig->greenBits + fbconfig->blueBits;
if (colorBits == 0)
colorBits = 24;
else if (colorBits < 15)
colorBits = 15;
if (wndconfig->clientAPI == GLFW_OPENGL_ES_API)
{
_glfwSetError(GLFW_VERSION_UNAVAILABLE,
"NSOpenGL: This API does not support OpenGL ES");
return GL_FALSE;
}
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
// Fail if any OpenGL version above 2.1 other than 3.2 was requested
if (wndconfig->glMajor > 3 ||
(wndconfig->glMajor == 3 && wndconfig->glMinor != 2))
{
_glfwSetError(GLFW_VERSION_UNAVAILABLE,
"NSOpenGL: The targeted version of Mac OS X does not "
"support any OpenGL version above 2.1 except 3.2");
return GL_FALSE;
}
if (wndconfig->glMajor > 2)
{
if (!wndconfig->glForward)
{
_glfwSetError(GLFW_VERSION_UNAVAILABLE,
"NSOpenGL: The targeted version of Mac OS X only "
"supports OpenGL 3.2 contexts if they are "
"forward-compatible");
return GL_FALSE;
}
if (wndconfig->glProfile != GLFW_OPENGL_CORE_PROFILE)
{
_glfwSetError(GLFW_VERSION_UNAVAILABLE,
"NSOpenGL: The targeted version of Mac OS X only "
"supports OpenGL 3.2 contexts if they use the "
"core profile");
return GL_FALSE;
}
}
#else
// Fail if OpenGL 3.0 or above was requested
if (wndconfig->glMajor > 2)
{
_glfwSetError(GLFW_VERSION_UNAVAILABLE,
"NSOpenGL: The targeted version of Mac OS X does not "
"support OpenGL version 3.0 or above");
return GL_FALSE;
}
#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
// Fail if a robustness strategy was requested
if (wndconfig->glRobustness)
{
_glfwSetError(GLFW_VERSION_UNAVAILABLE,
"NSOpenGL: Mac OS X does not support OpenGL robustness "
"strategies");
return GL_FALSE;
}
#define ADD_ATTR(x) { attributes[attributeCount++] = x; }
#define ADD_ATTR2(x, y) { ADD_ATTR(x); ADD_ATTR(y); }
// Arbitrary array size here
NSOpenGLPixelFormatAttribute attributes[40];
ADD_ATTR(NSOpenGLPFADoubleBuffer);
if (wndconfig->mode == GLFW_FULLSCREEN)
{
ADD_ATTR(NSOpenGLPFANoRecovery);
ADD_ATTR2(NSOpenGLPFAScreenMask,
CGDisplayIDToOpenGLDisplayMask(CGMainDisplayID()));
}
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
if (wndconfig->glMajor > 2)
ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core);
#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
ADD_ATTR2(NSOpenGLPFAColorSize, colorBits);
if (fbconfig->alphaBits > 0)
ADD_ATTR2(NSOpenGLPFAAlphaSize, fbconfig->alphaBits);
if (fbconfig->depthBits > 0)
ADD_ATTR2(NSOpenGLPFADepthSize, fbconfig->depthBits);
if (fbconfig->stencilBits > 0)
ADD_ATTR2(NSOpenGLPFAStencilSize, fbconfig->stencilBits);
int accumBits = fbconfig->accumRedBits + fbconfig->accumGreenBits +
fbconfig->accumBlueBits + fbconfig->accumAlphaBits;
if (accumBits > 0)
ADD_ATTR2(NSOpenGLPFAAccumSize, accumBits);
if (fbconfig->auxBuffers > 0)
ADD_ATTR2(NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers);
if (fbconfig->stereo)
ADD_ATTR(NSOpenGLPFAStereo);
if (fbconfig->samples > 0)
{
ADD_ATTR2(NSOpenGLPFASampleBuffers, 1);
ADD_ATTR2(NSOpenGLPFASamples, fbconfig->samples);
}
// NOTE: All NSOpenGLPixelFormats on the relevant cards support sRGB
// frambuffer, so there's no need (and no way) to request it
ADD_ATTR(0);
#undef ADD_ATTR
#undef ADD_ATTR2
window->NSGL.pixelFormat =
[[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
if (window->NSGL.pixelFormat == nil)
{
_glfwSetError(GLFW_PLATFORM_ERROR,
"NSOpenGL: Failed to create OpenGL pixel format");
return GL_FALSE;
}
NSOpenGLContext* share = NULL;
if (wndconfig->share)
share = wndconfig->share->NSGL.context;
window->NSGL.context =
[[NSOpenGLContext alloc] initWithFormat:window->NSGL.pixelFormat
shareContext:share];
if (window->NSGL.context == nil)
{
_glfwSetError(GLFW_PLATFORM_ERROR,
"NSOpenGL: Failed to create OpenGL context");
return GL_FALSE;
}
return GL_TRUE;
}
//========================================================================
// Destroy the OpenGL context
//========================================================================
void _glfwDestroyContext(_GLFWwindow* window)
{
[window->NSGL.pixelFormat release];
window->NSGL.pixelFormat = nil;
[window->NSGL.context release];
window->NSGL.context = nil;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
//========================================================================
// Make the OpenGL context associated with the specified window current
//========================================================================
+1 -3
View File
@@ -200,7 +200,7 @@ int _glfwPlatformInit(void)
// Close window and shut down library
//========================================================================
int _glfwPlatformTerminate(void)
void _glfwPlatformTerminate(void)
{
// Restore the original gamma ramp
if (_glfwLibrary.rampChanged)
@@ -220,8 +220,6 @@ int _glfwPlatformTerminate(void)
SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0,
UIntToPtr(_glfwLibrary.Win32.foregroundLockTimeout),
SPIF_SENDCHANGE);
return GL_TRUE;
}
+1 -3
View File
@@ -662,7 +662,7 @@ int _glfwPlatformInit(void)
// Close window and shut down library
//========================================================================
int _glfwPlatformTerminate(void)
void _glfwPlatformTerminate(void)
{
if (_glfwLibrary.X11.cursor)
{
@@ -681,8 +681,6 @@ int _glfwPlatformTerminate(void)
// Free clipboard memory
if (_glfwLibrary.X11.selection.string)
free(_glfwLibrary.X11.selection.string);
return GL_TRUE;
}