From d83119a87464ea57cfdee6d37fed2bbab7f84ec1 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Sun, 22 Jul 2012 15:24:35 +0200 Subject: [PATCH 01/35] Added explicit access to native handles. --- include/GL/glfw3native.h | 97 ++++++++++++++++++++++++++++++++++++++++ readme.html | 1 + src/CMakeLists.txt | 8 ++-- src/cocoa_native.m | 74 ++++++++++++++++++++++++++++++ src/win32_native.c | 74 ++++++++++++++++++++++++++++++ src/x11_native.c | 84 ++++++++++++++++++++++++++++++++++ 6 files changed, 335 insertions(+), 3 deletions(-) create mode 100644 include/GL/glfw3native.h create mode 100644 src/cocoa_native.m create mode 100644 src/win32_native.c create mode 100644 src/x11_native.c diff --git a/include/GL/glfw3native.h b/include/GL/glfw3native.h new file mode 100644 index 00000000..b8b01f9a --- /dev/null +++ b/include/GL/glfw3native.h @@ -0,0 +1,97 @@ +/************************************************************************* + * GLFW - An OpenGL library + * API version: 3.0 + * WWW: http://www.glfw.org/ + *------------------------------------------------------------------------ + * Copyright (c) 2002-2006 Marcus Geelnard + * Copyright (c) 2006-2010 Camilla Berglund + * + * 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. + * + *************************************************************************/ + +#ifndef __glfw3_platform_h__ +#define __glfw3_platform_h__ + +#ifdef __cplusplus +extern "C" { +#endif + + +/************************************************************************* + * System headers and types + *************************************************************************/ + +#if defined(GLFW_EXPOSE_NATIVE_WIN32_WGL) + + /* We are building for Win32 and WGL */ + #include + +#elif defined(GLFW_EXPOSE_NATIVE_COCOA_NSGL) + + /* We are building for Cocoa and NSOpenGL */ + #if defined(__OBJC__) + #import + #else + typedef void* id; + #endif + +#elif defined(GLFW_EXPOSE_NATIVE_X11_GLX) + + /* We are building for X11 and GLX */ + #include + +#else + + #error "No platform specified" + +#endif + + +/************************************************************************* + * Functions + *************************************************************************/ + +#if defined(GLFW_EXPOSE_NATIVE_WIN32_WGL) + +GLFWAPI HWND glfwGetWin32Window(GLFWwindow window); +GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow window); + +#elif defined(GLFW_EXPOSE_NATIVE_COCOA_NSGL) + +GLFWAPI id glfwGetCocoaWindow(GLFWwindow window); +GLFWAPI id glfwGetNSGLContext(GLFWwindow window); + +#elif defined(GLFW_EXPOSE_NATIVE_X11_GLX) + +GLFWAPI Display* glfwGetX11Display(void); + +GLFWAPI Window glfwGetX11Window(GLFWwindow window); +GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow window); + +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* __glfw3_platform_h__ */ + diff --git a/readme.html b/readme.html index b854a59c..e0e7056e 100644 --- a/readme.html +++ b/readme.html @@ -287,6 +287,7 @@ version of GLFW.

  • Added windows simple multi-window test program
  • Added sharing simple OpenGL object sharing test program
  • Added modes video mode enumeration and setting test program
  • +
  • Added glfw3native.h header and platform-specific functions for explicit access to native display, window and context handles
  • Added a parameter to glfwOpenWindow for specifying a context the new window's context will share objects with
  • Added initial window title parameter to glfwOpenWindow
  • Added glfwSetGamma, glfwSetGammaRamp and glfwGetGammaRamp functions and GLFWgammaramp type for monitor gamma ramp control
  • diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index add05982..25a80e3a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -11,7 +11,7 @@ if (_GLFW_COCOA_NSGL) set(glfw_HEADERS ${common_HEADERS} cocoa_platform.h) set(glfw_SOURCES ${common_SOURCES} cocoa_clipboard.m cocoa_fullscreen.m cocoa_gamma.c cocoa_init.m cocoa_input.m cocoa_joystick.m - cocoa_opengl.m cocoa_time.c cocoa_window.m) + cocoa_native.m cocoa_opengl.m cocoa_time.c cocoa_window.m) # For some reason, CMake doesn't know about .m set_source_files_properties(${glfw_SOURCES} PROPERTIES LANGUAGE C) @@ -19,12 +19,14 @@ elseif (_GLFW_WIN32_WGL) set(glfw_HEADERS ${common_HEADERS} win32_platform.h) set(glfw_SOURCES ${common_SOURCES} win32_clipboard.c win32_fullscreen.c win32_gamma.c win32_init.c win32_input.c win32_joystick.c - win32_opengl.c win32_time.c win32_window.c win32_dllmain.c) + win32_native.c win32_opengl.c win32_time.c win32_window.c + win32_dllmain.c) elseif (_GLFW_X11_GLX) set(glfw_HEADERS ${common_HEADERS} x11_platform.h) set(glfw_SOURCES ${common_SOURCES} x11_clipboard.c x11_fullscreen.c x11_gamma.c x11_init.c x11_input.c x11_joystick.c - x11_keysym2unicode.c x11_opengl.c x11_time.c x11_window.c) + x11_keysym2unicode.c x11_native.c x11_opengl.c x11_time.c + x11_window.c) endif() add_library(glfw ${glfw_SOURCES} ${glfw_HEADERS}) diff --git a/src/cocoa_native.m b/src/cocoa_native.m new file mode 100644 index 00000000..2b90bc24 --- /dev/null +++ b/src/cocoa_native.m @@ -0,0 +1,74 @@ +//======================================================================== +// GLFW - An OpenGL library +// Platform: Cocoa/NSOpenGL +// API version: 3.0 +// WWW: http://www.glfw.org/ +//------------------------------------------------------------------------ +// Copyright (c) 2010 Camilla Berglund +// +// 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 "internal.h" + +#define GLFW_EXPOSE_NATIVE_COCOA_NSGL +#include "../include/GL/glfw3native.h" + + +////////////////////////////////////////////////////////////////////////// +////// GLFW native API ////// +////////////////////////////////////////////////////////////////////////// + +//======================================================================== +// Returns the X11 handle of the specified window +//======================================================================== + +GLFWAPI id glfwGetCocoaWindow(GLFWwindow window) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + + if (!_glfwInitialized) + { + _glfwSetError(GLFW_NOT_INITIALIZED, NULL); + return 0; + } + + return window->NS.object; +} + + +//======================================================================== +// Return the GLX context of the specified window +//======================================================================== + +GLFWAPI id glfwGetNSGLContext(GLFWwindow window) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + + if (!_glfwInitialized) + { + _glfwSetError(GLFW_NOT_INITIALIZED, NULL); + return NULL; + } + + return window->NSGL.context; +} + diff --git a/src/win32_native.c b/src/win32_native.c new file mode 100644 index 00000000..80cc5730 --- /dev/null +++ b/src/win32_native.c @@ -0,0 +1,74 @@ +//======================================================================== +// GLFW - An OpenGL library +// Platform: Win32/WGL +// API version: 3.0 +// WWW: http://www.glfw.org/ +//------------------------------------------------------------------------ +// Copyright (c) 2010 Camilla Berglund +// +// 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 "internal.h" + +#define GLFW_EXPOSE_NATIVE_WIN32_WGL +#include "../include/GL/glfw3native.h" + + +////////////////////////////////////////////////////////////////////////// +////// GLFW native API ////// +////////////////////////////////////////////////////////////////////////// + +//======================================================================== +// Returns the Win32 handle of the specified window +//======================================================================== + +GLFWAPI HWND glfwGetWin32Window(GLFWwindow handle) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + + if (!_glfwInitialized) + { + _glfwSetError(GLFW_NOT_INITIALIZED, NULL); + return NULL; + } + + return window->Win32.handle; +} + + +//======================================================================== +// Return the WGL context of the specified window +//======================================================================== + +GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow handle) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + + if (!_glfwInitialized) + { + _glfwSetError(GLFW_NOT_INITIALIZED, NULL); + return NULL; + } + + return window->WGL.context; +} + diff --git a/src/x11_native.c b/src/x11_native.c new file mode 100644 index 00000000..22f30112 --- /dev/null +++ b/src/x11_native.c @@ -0,0 +1,84 @@ +//======================================================================== +// GLFW - An OpenGL library +// Platform: Win32/WGL +// API version: 3.0 +// WWW: http://www.glfw.org/ +//------------------------------------------------------------------------ +// Copyright (c) 2010 Camilla Berglund +// +// 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 "internal.h" + +#define GLFW_EXPOSE_NATIVE_X11_GLX +#include "../include/GL/glfw3native.h" + + +////////////////////////////////////////////////////////////////////////// +////// GLFW native API ////// +////////////////////////////////////////////////////////////////////////// + +//======================================================================== +// Returns the X11 display +//======================================================================== + +GLFWAPI Display* glfwGetX11Display(void) +{ + return _glfwLibrary.X11.display; +} + + +//======================================================================== +// Returns the X11 handle of the specified window +//======================================================================== + +GLFWAPI Window glfwGetX11Window(GLFWwindow handle) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + + if (!_glfwInitialized) + { + _glfwSetError(GLFW_NOT_INITIALIZED, NULL); + return 0; + } + + return window->X11.handle; +} + + +//======================================================================== +// Return the GLX context of the specified window +//======================================================================== + +GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow handle) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + + if (!_glfwInitialized) + { + _glfwSetError(GLFW_NOT_INITIALIZED, NULL); + return NULL; + } + + return window->GLX.context; +} + From df6d4bc58a810854e877d1dc0bed1f196c0d6fe3 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Sun, 22 Jul 2012 15:42:18 +0200 Subject: [PATCH 02/35] Added glfw3native.h to installation. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b80ac24e..7fbdd950 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -242,7 +242,7 @@ configure_file(${GLFW_SOURCE_DIR}/src/config.h.in # The src directory's CMakeLists.txt file installs the library #-------------------------------------------------------------------- install(DIRECTORY include/GL DESTINATION include - FILES_MATCHING PATTERN glfw3.h) + FILES_MATCHING PATTERN glfw3.h PATTERN glfw3native.h) install(FILES COPYING.txt readme.html DESTINATION share/doc/glfw-${GLFW_VERSION_FULL}) From dd298ab908cd29180eb5a9e65cdce9486531bfeb Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Mon, 23 Jul 2012 00:48:30 +0200 Subject: [PATCH 03/35] Fixed copypaste errors. --- src/cocoa_native.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cocoa_native.m b/src/cocoa_native.m index 2b90bc24..be8aac4b 100644 --- a/src/cocoa_native.m +++ b/src/cocoa_native.m @@ -41,7 +41,7 @@ // Returns the X11 handle of the specified window //======================================================================== -GLFWAPI id glfwGetCocoaWindow(GLFWwindow window) +GLFWAPI id glfwGetCocoaWindow(GLFWwindow handle) { _GLFWwindow* window = (_GLFWwindow*) handle; @@ -59,7 +59,7 @@ GLFWAPI id glfwGetCocoaWindow(GLFWwindow window) // Return the GLX context of the specified window //======================================================================== -GLFWAPI id glfwGetNSGLContext(GLFWwindow window) +GLFWAPI id glfwGetNSGLContext(GLFWwindow handle) { _GLFWwindow* window = (_GLFWwindow*) handle; From 52ebc0db852ea5c31be6d9c9504403c6468d57ef Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Mon, 23 Jul 2012 00:50:52 +0200 Subject: [PATCH 04/35] Fixed use of wrong point type. --- src/cocoa_window.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 3523806a..fd57040e 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -1163,7 +1163,7 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, int x, int y) { if (window->mode == GLFW_FULLSCREEN) { - NSPoint globalPoint = NSMakePoint(x, y); + CGPoint globalPoint = CGMakePoint(x, y); CGDisplayMoveCursorToPoint(CGMainDisplayID(), globalPoint); } else From b28298f3294853d372bb7ba7cd30c7ba9d65fd7d Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Sun, 29 Jul 2012 14:07:01 +0200 Subject: [PATCH 05/35] Fixed call to CGPointMake. --- src/cocoa_window.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cocoa_window.m b/src/cocoa_window.m index fd57040e..d00fbbff 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -1163,7 +1163,7 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, int x, int y) { if (window->mode == GLFW_FULLSCREEN) { - CGPoint globalPoint = CGMakePoint(x, y); + CGPoint globalPoint = CGPointMake(x, y); CGDisplayMoveCursorToPoint(CGMainDisplayID(), globalPoint); } else From 93ec9fa90171ce7bdcd52ea0dc7ade981ed1d113 Mon Sep 17 00:00:00 2001 From: John Bartholomew Date: Mon, 30 Jul 2012 00:14:09 +0100 Subject: [PATCH 06/35] Changed library output name to "glfw3", and pkg-config name to libglfw3. Since the headers are already named differently, this allows side-by-side installation of GLFW 2.x and GLFW 3.x. --- CMakeLists.txt | 6 +++--- src/CMakeLists.txt | 1 + src/{libglfw.pc.in => libglfw3.pc.in} | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) rename src/{libglfw.pc.in => libglfw3.pc.in} (92%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7fbdd950..f082c3d7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -251,10 +251,10 @@ install(FILES COPYING.txt readme.html # Create and install pkg-config file on supported platforms #-------------------------------------------------------------------- if (_GLFW_X11_GLX OR _GLFW_COCOA_NSGL) - configure_file(${GLFW_SOURCE_DIR}/src/libglfw.pc.in - ${GLFW_BINARY_DIR}/src/libglfw.pc @ONLY) + configure_file(${GLFW_SOURCE_DIR}/src/libglfw3.pc.in + ${GLFW_BINARY_DIR}/src/libglfw3.pc @ONLY) - install(FILES ${GLFW_BINARY_DIR}/src/libglfw.pc + install(FILES ${GLFW_BINARY_DIR}/src/libglfw3.pc DESTINATION lib/pkgconfig) endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 25a80e3a..78cd1c07 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -30,6 +30,7 @@ elseif (_GLFW_X11_GLX) endif() add_library(glfw ${glfw_SOURCES} ${glfw_HEADERS}) +set_target_properties(glfw PROPERTIES OUTPUT_NAME "glfw3") if (BUILD_SHARED_LIBS) diff --git a/src/libglfw.pc.in b/src/libglfw3.pc.in similarity index 92% rename from src/libglfw.pc.in rename to src/libglfw3.pc.in index be6275aa..775819ed 100644 --- a/src/libglfw.pc.in +++ b/src/libglfw3.pc.in @@ -8,6 +8,6 @@ Description: A portable library for OpenGL, window and input Version: @GLFW_VERSION_FULL@ URL: http://www.glfw.org/ Requires.private: @GLFW_PKG_DEPS@ -Libs: -L${libdir} -lglfw +Libs: -L${libdir} -lglfw3 Libs.private: @GLFW_PKG_LIBS@ Cflags: -I${includedir} From 0f0e42b975742c0918e0813b7a24247c197ed758 Mon Sep 17 00:00:00 2001 From: John Bartholomew Date: Mon, 30 Jul 2012 01:04:08 +0100 Subject: [PATCH 07/35] Use SOVERSION for shared libraries on Unix-like systems. --- CMakeLists.txt | 10 ++++++++++ src/CMakeLists.txt | 7 ++++++- src/libglfw3.pc.in | 2 +- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f082c3d7..d49a2aea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -215,6 +215,16 @@ endif() #-------------------------------------------------------------------- set(GLFW_LIBRARIES ${glfw_LIBRARIES} CACHE STRING "Dependencies of GLFW") +#-------------------------------------------------------------------- +# Choose library output name +#-------------------------------------------------------------------- +if (BUILD_SHARED_LIBS AND UNIX) + # On Unix-like systems, shared libraries can use the soname system. + set(GLFW_LIB_NAME glfw) +else() + set(GLFW_LIB_NAME glfw3) +endif() + #-------------------------------------------------------------------- # Add subdirectories #-------------------------------------------------------------------- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 78cd1c07..926ef668 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -30,9 +30,14 @@ elseif (_GLFW_X11_GLX) endif() add_library(glfw ${glfw_SOURCES} ${glfw_HEADERS}) -set_target_properties(glfw PROPERTIES OUTPUT_NAME "glfw3") +set_target_properties(glfw PROPERTIES OUTPUT_NAME "${GLFW_LIB_NAME}") if (BUILD_SHARED_LIBS) + # Include version information in the output + set_target_properties(glfw PROPERTIES VERSION ${GLFW_VERSION}) + if (UNIX) + set_target_properties(glfw PROPERTIES SOVERSION ${GLFW_VERSION_MAJOR}) + endif() if (_GLFW_WIN32_WGL) # The GLFW DLL needs a special compile-time macro and import library name diff --git a/src/libglfw3.pc.in b/src/libglfw3.pc.in index 775819ed..175c902d 100644 --- a/src/libglfw3.pc.in +++ b/src/libglfw3.pc.in @@ -8,6 +8,6 @@ Description: A portable library for OpenGL, window and input Version: @GLFW_VERSION_FULL@ URL: http://www.glfw.org/ Requires.private: @GLFW_PKG_DEPS@ -Libs: -L${libdir} -lglfw3 +Libs: -L${libdir} -l@GLFW_LIB_NAME@ Libs.private: @GLFW_PKG_LIBS@ Cflags: -I${includedir} From a8686ce0b5072e96d1b8f84032fd517e69c682b8 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Mon, 30 Jul 2012 20:11:19 +0200 Subject: [PATCH 08/35] Added credit. --- readme.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/readme.html b/readme.html index e0e7056e..10fa433b 100644 --- a/readme.html +++ b/readme.html @@ -848,6 +848,9 @@ their skills. Special thanks go out to:

  • Keith Bauer, for his invaluable help with porting and maintaining GLFW on Mac OS X, and for his many ideas
  • +
  • John Bartholomew, for adding proper version number and soname to the + shared library build
  • +
  • Lambert Clara, for a bug fix for the modes test
  • Jarrod Davis, for the Delphi port of GLFW
  • From 6c37c84d91d37925b14b9dadb988b02255533cc3 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Mon, 30 Jul 2012 20:15:34 +0200 Subject: [PATCH 09/35] Reduced the number of conditional blocks. --- src/x11_window.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/x11_window.c b/src/x11_window.c index 84b6f7d6..e5c548de 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -1139,20 +1139,14 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window) void _glfwPlatformRefreshWindowParams(void) { -#if defined(_GLFW_HAS_XRANDR) - XRRScreenConfiguration* sc; -#endif /*_GLFW_HAS_XRANDR*/ -#if defined(_GLFW_HAS_XF86VIDMODE) - XF86VidModeModeLine modeline; - int dotclock; - float pixels_per_second, pixels_per_frame; -#endif /*_GLFW_HAS_XF86VIDMODE*/ _GLFWwindow* window = _glfwLibrary.currentWindow; // Retrieve refresh rate if possible if (_glfwLibrary.X11.RandR.available) { #if defined(_GLFW_HAS_XRANDR) + XRRScreenConfiguration* sc; + sc = XRRGetScreenInfo(_glfwLibrary.X11.display, _glfwLibrary.X11.root); window->refreshRate = XRRConfigCurrentRate(sc); XRRFreeScreenConfigInfo(sc); @@ -1161,6 +1155,10 @@ void _glfwPlatformRefreshWindowParams(void) else if (_glfwLibrary.X11.VidMode.available) { #if defined(_GLFW_HAS_XF86VIDMODE) + XF86VidModeModeLine modeline; + int dotclock; + float pixels_per_second, pixels_per_frame; + // Use the XF86VidMode extension to get current video mode XF86VidModeGetModeLine(_glfwLibrary.X11.display, _glfwLibrary.X11.screen, From fc74a5533e656b35d75f58f84760bf8e9f48a016 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Tue, 31 Jul 2012 22:48:28 +0200 Subject: [PATCH 10/35] Moved WGL context logic into OpenGL module. --- src/win32_opengl.c | 582 +++++++++++++++++++++++++++++++++++++++++++ src/win32_platform.h | 6 + src/win32_window.c | 569 +----------------------------------------- 3 files changed, 594 insertions(+), 563 deletions(-) diff --git a/src/win32_opengl.c b/src/win32_opengl.c index 5e94d7da..cc795e53 100644 --- a/src/win32_opengl.c +++ b/src/win32_opengl.c @@ -31,6 +31,588 @@ #include "internal.h" +//======================================================================== +// Initialize WGL-specific extensions +// This function is called once before initial context creation, i.e. before +// any WGL extensions could be present. This is done in order to have both +// extension variable clearing and loading in the same place, hopefully +// decreasing the possibility of forgetting to add one without the other. +//======================================================================== + +static void initWGLExtensions(_GLFWwindow* window) +{ + // This needs to include every function pointer loaded below + window->WGL.SwapIntervalEXT = NULL; + window->WGL.GetPixelFormatAttribivARB = NULL; + window->WGL.GetExtensionsStringARB = NULL; + window->WGL.GetExtensionsStringEXT = NULL; + window->WGL.CreateContextAttribsARB = NULL; + + // This needs to include every extension used below except for + // WGL_ARB_extensions_string and WGL_EXT_extensions_string + window->WGL.ARB_multisample = GL_FALSE; + window->WGL.ARB_create_context = GL_FALSE; + window->WGL.ARB_create_context_profile = GL_FALSE; + window->WGL.EXT_create_context_es2_profile = GL_FALSE; + window->WGL.ARB_create_context_robustness = GL_FALSE; + window->WGL.EXT_swap_control = GL_FALSE; + window->WGL.ARB_pixel_format = GL_FALSE; + + window->WGL.GetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC) + wglGetProcAddress("wglGetExtensionsStringEXT"); + if (!window->WGL.GetExtensionsStringEXT) + { + window->WGL.GetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC) + wglGetProcAddress("wglGetExtensionsStringARB"); + if (!window->WGL.GetExtensionsStringARB) + return; + } + + if (_glfwPlatformExtensionSupported("WGL_ARB_multisample")) + window->WGL.ARB_multisample = GL_TRUE; + + if (_glfwPlatformExtensionSupported("WGL_ARB_create_context")) + { + window->WGL.CreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC) + wglGetProcAddress("wglCreateContextAttribsARB"); + + if (window->WGL.CreateContextAttribsARB) + window->WGL.ARB_create_context = GL_TRUE; + } + + if (window->WGL.ARB_create_context) + { + if (_glfwPlatformExtensionSupported("WGL_ARB_create_context_profile")) + window->WGL.ARB_create_context_profile = GL_TRUE; + } + + if (window->WGL.ARB_create_context && + window->WGL.ARB_create_context_profile) + { + if (_glfwPlatformExtensionSupported("WGL_EXT_create_context_es2_profile")) + window->WGL.EXT_create_context_es2_profile = GL_TRUE; + } + + if (window->WGL.ARB_create_context) + { + if (_glfwPlatformExtensionSupported("WGL_ARB_create_context_robustness")) + window->WGL.ARB_create_context_robustness = GL_TRUE; + } + + if (_glfwPlatformExtensionSupported("WGL_EXT_swap_control")) + { + window->WGL.SwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) + wglGetProcAddress("wglSwapIntervalEXT"); + + if (window->WGL.SwapIntervalEXT) + window->WGL.EXT_swap_control = GL_TRUE; + } + + if (_glfwPlatformExtensionSupported("WGL_ARB_pixel_format")) + { + window->WGL.GetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC) + wglGetProcAddress("wglGetPixelFormatAttribivARB"); + + if (window->WGL.GetPixelFormatAttribivARB) + window->WGL.ARB_pixel_format = GL_TRUE; + } +} + + +//======================================================================== +// Returns the specified attribute of the specified pixel format +// NOTE: Do not call this unless we have found WGL_ARB_pixel_format +//======================================================================== + +static int getPixelFormatAttrib(_GLFWwindow* window, int pixelFormat, int attrib) +{ + int value = 0; + + if (!window->WGL.GetPixelFormatAttribivARB(window->WGL.DC, + pixelFormat, + 0, 1, &attrib, &value)) + { + // NOTE: We should probably handle this error somehow + return 0; + } + + return value; +} + + +//======================================================================== +// Return a list of available and usable framebuffer configs +//======================================================================== + +static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found) +{ + _GLFWfbconfig* fbconfigs; + PIXELFORMATDESCRIPTOR pfd; + int i, available; + + *found = 0; + + if (window->WGL.ARB_pixel_format) + { + available = getPixelFormatAttrib(window, + 1, + WGL_NUMBER_PIXEL_FORMATS_ARB); + } + else + { + available = DescribePixelFormat(window->WGL.DC, + 1, + sizeof(PIXELFORMATDESCRIPTOR), + NULL); + } + + if (!available) + { + _glfwSetError(GLFW_OPENGL_UNAVAILABLE, "Win32/WGL: No pixel formats found"); + return NULL; + } + + fbconfigs = (_GLFWfbconfig*) malloc(sizeof(_GLFWfbconfig) * available); + if (!fbconfigs) + { + _glfwSetError(GLFW_OUT_OF_MEMORY, + "Win32/WGL: Failed to allocate _GLFWfbconfig array"); + return NULL; + } + + for (i = 1; i <= available; i++) + { + _GLFWfbconfig* f = fbconfigs + *found; + + if (window->WGL.ARB_pixel_format) + { + // Get pixel format attributes through WGL_ARB_pixel_format + if (!getPixelFormatAttrib(window, i, WGL_SUPPORT_OPENGL_ARB) || + !getPixelFormatAttrib(window, i, WGL_DRAW_TO_WINDOW_ARB) || + !getPixelFormatAttrib(window, i, WGL_DOUBLE_BUFFER_ARB)) + { + continue; + } + + if (getPixelFormatAttrib(window, i, WGL_PIXEL_TYPE_ARB) != + WGL_TYPE_RGBA_ARB) + { + continue; + } + + if (getPixelFormatAttrib(window, i, WGL_ACCELERATION_ARB) == + WGL_NO_ACCELERATION_ARB) + { + continue; + } + + f->redBits = getPixelFormatAttrib(window, i, WGL_RED_BITS_ARB); + f->greenBits = getPixelFormatAttrib(window, i, WGL_GREEN_BITS_ARB); + f->blueBits = getPixelFormatAttrib(window, i, WGL_BLUE_BITS_ARB); + f->alphaBits = getPixelFormatAttrib(window, i, WGL_ALPHA_BITS_ARB); + + f->depthBits = getPixelFormatAttrib(window, i, WGL_DEPTH_BITS_ARB); + f->stencilBits = getPixelFormatAttrib(window, i, WGL_STENCIL_BITS_ARB); + + f->accumRedBits = getPixelFormatAttrib(window, i, WGL_ACCUM_RED_BITS_ARB); + f->accumGreenBits = getPixelFormatAttrib(window, i, WGL_ACCUM_GREEN_BITS_ARB); + f->accumBlueBits = getPixelFormatAttrib(window, i, WGL_ACCUM_BLUE_BITS_ARB); + f->accumAlphaBits = getPixelFormatAttrib(window, i, WGL_ACCUM_ALPHA_BITS_ARB); + + f->auxBuffers = getPixelFormatAttrib(window, i, WGL_AUX_BUFFERS_ARB); + f->stereo = getPixelFormatAttrib(window, i, WGL_STEREO_ARB); + + if (window->WGL.ARB_multisample) + f->samples = getPixelFormatAttrib(window, i, WGL_SAMPLES_ARB); + else + f->samples = 0; + } + else + { + // Get pixel format attributes through old-fashioned PFDs + + if (!DescribePixelFormat(window->WGL.DC, + i, + sizeof(PIXELFORMATDESCRIPTOR), + &pfd)) + { + continue; + } + + if (!(pfd.dwFlags & PFD_DRAW_TO_WINDOW) || + !(pfd.dwFlags & PFD_SUPPORT_OPENGL) || + !(pfd.dwFlags & PFD_DOUBLEBUFFER)) + { + continue; + } + + if (!(pfd.dwFlags & PFD_GENERIC_ACCELERATED) && + (pfd.dwFlags & PFD_GENERIC_FORMAT)) + { + continue; + } + + if (pfd.iPixelType != PFD_TYPE_RGBA) + continue; + + f->redBits = pfd.cRedBits; + f->greenBits = pfd.cGreenBits; + f->blueBits = pfd.cBlueBits; + f->alphaBits = pfd.cAlphaBits; + + f->depthBits = pfd.cDepthBits; + f->stencilBits = pfd.cStencilBits; + + f->accumRedBits = pfd.cAccumRedBits; + f->accumGreenBits = pfd.cAccumGreenBits; + f->accumBlueBits = pfd.cAccumBlueBits; + f->accumAlphaBits = pfd.cAccumAlphaBits; + + f->auxBuffers = pfd.cAuxBuffers; + f->stereo = (pfd.dwFlags & PFD_STEREO) ? GL_TRUE : GL_FALSE; + + // PFD pixel formats do not support FSAA + f->samples = 0; + } + + f->platformID = i; + + (*found)++; + } + + if (*found == 0) + { + free(fbconfigs); + return NULL; + } + + return fbconfigs; +} + + +//======================================================================== +// Read back framebuffer parameters from the context +//======================================================================== + +static void refreshContextParams(_GLFWwindow* window, int pixelFormat) +{ + PIXELFORMATDESCRIPTOR pfd; + + if (window->WGL.ARB_pixel_format) + { + if (getPixelFormatAttrib(window, pixelFormat, WGL_ACCELERATION_ARB) != + WGL_NO_ACCELERATION_ARB) + { + window->accelerated = GL_TRUE; + } + else + window->accelerated = GL_FALSE; + + window->redBits = + getPixelFormatAttrib(window, pixelFormat, WGL_RED_BITS_ARB); + window->greenBits = + getPixelFormatAttrib(window, pixelFormat, WGL_GREEN_BITS_ARB); + window->blueBits = + getPixelFormatAttrib(window, pixelFormat, WGL_BLUE_BITS_ARB); + + window->alphaBits = + getPixelFormatAttrib(window, pixelFormat, WGL_ALPHA_BITS_ARB); + window->depthBits = + getPixelFormatAttrib(window, pixelFormat, WGL_DEPTH_BITS_ARB); + window->stencilBits = + getPixelFormatAttrib(window, pixelFormat, WGL_STENCIL_BITS_ARB); + + window->accumRedBits = + getPixelFormatAttrib(window, pixelFormat, WGL_ACCUM_RED_BITS_ARB); + window->accumGreenBits = + getPixelFormatAttrib(window, pixelFormat, WGL_ACCUM_GREEN_BITS_ARB); + window->accumBlueBits = + getPixelFormatAttrib(window, pixelFormat, WGL_ACCUM_BLUE_BITS_ARB); + window->accumAlphaBits = + getPixelFormatAttrib(window, pixelFormat, WGL_ACCUM_ALPHA_BITS_ARB); + + window->auxBuffers = + getPixelFormatAttrib(window, pixelFormat, WGL_AUX_BUFFERS_ARB); + window->stereo = + getPixelFormatAttrib(window, pixelFormat, WGL_STEREO_ARB) ? GL_TRUE : GL_FALSE; + + if (window->WGL.ARB_multisample) + { + window->samples = getPixelFormatAttrib(window, pixelFormat, WGL_SAMPLES_ARB); + + // We force 1 to zero here because all the other APIs say zero when + // they really mean 1 + if (window->samples == 1) + window->samples = 0; + } + else + window->samples = 0; + } + else + { + DescribePixelFormat(window->WGL.DC, pixelFormat, + sizeof(PIXELFORMATDESCRIPTOR), &pfd); + + // Is current OpenGL context accelerated? + window->accelerated = (pfd.dwFlags & PFD_GENERIC_ACCELERATED) || + !(pfd.dwFlags & PFD_GENERIC_FORMAT) ? 1 : 0; + + // "Standard" window parameters + window->redBits = pfd.cRedBits; + window->greenBits = pfd.cGreenBits; + window->blueBits = pfd.cBlueBits; + window->alphaBits = pfd.cAlphaBits; + window->depthBits = pfd.cDepthBits; + window->stencilBits = pfd.cStencilBits; + window->accumRedBits = pfd.cAccumRedBits; + window->accumGreenBits = pfd.cAccumGreenBits; + window->accumBlueBits = pfd.cAccumBlueBits; + window->accumAlphaBits = pfd.cAccumAlphaBits; + window->auxBuffers = pfd.cAuxBuffers; + window->stereo = (pfd.dwFlags & PFD_STEREO) ? GL_TRUE : GL_FALSE; + + // If we don't have WGL_ARB_pixel_format then we can't have created a + // multisampling context, so it's safe to hardcode zero here + window->samples = 0; + } +} + + +//======================================================================== +// Creates an OpenGL context on the specified device context +//======================================================================== + +static GLboolean createContext(_GLFWwindow* window, + const _GLFWwndconfig* wndconfig, + int pixelFormat) +{ + PIXELFORMATDESCRIPTOR pfd; + int i = 0, attribs[40]; + HGLRC share = NULL; + + if (wndconfig->share) + share = wndconfig->share->WGL.context; + + if (!DescribePixelFormat(window->WGL.DC, pixelFormat, sizeof(pfd), &pfd)) + { + _glfwSetError(GLFW_OPENGL_UNAVAILABLE, + "Win32/WGL: Failed to retrieve PFD for selected pixel format"); + return GL_FALSE; + } + + if (!SetPixelFormat(window->WGL.DC, pixelFormat, &pfd)) + { + _glfwSetError(GLFW_OPENGL_UNAVAILABLE, + "Win32/WGL: Failed to set selected pixel format"); + return GL_FALSE; + } + + if (window->WGL.ARB_create_context) + { + // Use the newer wglCreateContextAttribsARB creation method + + if (wndconfig->glMajor != 1 || wndconfig->glMinor != 0) + { + // Request an explicitly versioned context + + attribs[i++] = WGL_CONTEXT_MAJOR_VERSION_ARB; + attribs[i++] = wndconfig->glMajor; + attribs[i++] = WGL_CONTEXT_MINOR_VERSION_ARB; + attribs[i++] = wndconfig->glMinor; + } + + if (wndconfig->glForward || wndconfig->glDebug || wndconfig->glRobustness) + { + int flags = 0; + + if (wndconfig->glForward) + flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; + + if (wndconfig->glDebug) + flags |= WGL_CONTEXT_DEBUG_BIT_ARB; + + if (wndconfig->glRobustness) + flags |= WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB; + + attribs[i++] = WGL_CONTEXT_FLAGS_ARB; + attribs[i++] = flags; + } + + if (wndconfig->glProfile) + { + int flags = 0; + + if (!window->WGL.ARB_create_context_profile) + { + _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.EXT_create_context_es2_profile) + { + _glfwSetError(GLFW_VERSION_UNAVAILABLE, + "Win32/WGL: OpenGL ES 2.x profile requested but " + "WGL_EXT_create_context_es2_profile is unavailable"); + return GL_FALSE; + } + + if (wndconfig->glProfile == GLFW_OPENGL_CORE_PROFILE) + flags = WGL_CONTEXT_CORE_PROFILE_BIT_ARB; + else if (wndconfig->glProfile == GLFW_OPENGL_COMPAT_PROFILE) + flags = WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; + else if (wndconfig->glProfile == GLFW_OPENGL_ES2_PROFILE) + flags = WGL_CONTEXT_ES2_PROFILE_BIT_EXT; + + attribs[i++] = WGL_CONTEXT_PROFILE_MASK_ARB; + attribs[i++] = flags; + } + + if (wndconfig->glRobustness) + { + int strategy; + + if (!window->WGL.ARB_create_context_robustness) + { + _glfwSetError(GLFW_VERSION_UNAVAILABLE, + "Win32/WGL: An OpenGL robustness strategy was " + "requested but WGL_ARB_create_context_robustness " + "is unavailable"); + return GL_FALSE; + } + + if (wndconfig->glRobustness == GLFW_OPENGL_NO_RESET_NOTIFICATION) + strategy = WGL_NO_RESET_NOTIFICATION_ARB; + else if (wndconfig->glRobustness == GLFW_OPENGL_LOSE_CONTEXT_ON_RESET) + strategy = WGL_LOSE_CONTEXT_ON_RESET_ARB; + + attribs[i++] = WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB; + attribs[i++] = strategy; + } + + attribs[i++] = 0; + + window->WGL.context = window->WGL.CreateContextAttribsARB(window->WGL.DC, + share, + attribs); + if (!window->WGL.context) + { + _glfwSetError(GLFW_VERSION_UNAVAILABLE, + "Win32/WGL: Failed to create OpenGL context"); + return GL_FALSE; + } + } + else + { + window->WGL.context = wglCreateContext(window->WGL.DC); + if (!window->WGL.context) + { + _glfwSetError(GLFW_PLATFORM_ERROR, + "Win32/WGL: Failed to create OpenGL context"); + return GL_FALSE; + } + + if (share) + { + if (!wglShareLists(share, window->WGL.context)) + { + _glfwSetError(GLFW_PLATFORM_ERROR, + "Win32/WGL: Failed to enable sharing with " + "specified OpenGL context"); + return GL_FALSE; + } + } + } + + glfwMakeContextCurrent(window); + initWGLExtensions(window); + refreshContextParams(window, pixelFormat); + + return GL_TRUE; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +//======================================================================== +// Prepare for creation of the OpenGL context +//======================================================================== + +int _glfwCreateContext(_GLFWwindow* window, + const _GLFWwndconfig* wndconfig, + const _GLFWfbconfig* fbconfig) +{ + _GLFWfbconfig closest; + + window->WGL.DC = GetDC(window->Win32.handle); + if (!window->WGL.DC) + { + _glfwSetError(GLFW_PLATFORM_ERROR, + "Win32/WGL: Failed to retrieve DC for window"); + return GL_FALSE; + } + + // Choose the best available fbconfig + { + unsigned int fbcount; + _GLFWfbconfig* fbconfigs; + const _GLFWfbconfig* result; + + fbconfigs = getFBConfigs(window, &fbcount); + if (!fbconfigs) + { + _glfwSetError(GLFW_PLATFORM_ERROR, + "Win32/WGL: No usable pixel formats found"); + return GL_FALSE; + } + + result = _glfwChooseFBConfig(fbconfig, fbconfigs, fbcount); + if (!result) + { + _glfwSetError(GLFW_PLATFORM_ERROR, + "Win32/WGL: No pixel format matched the criteria"); + + free(fbconfigs); + return GL_FALSE; + } + + closest = *result; + free(fbconfigs); + } + + return createContext(window, wndconfig, (int) closest.platformID); +} + + +//======================================================================== +// Destroy the OpenGL context +//======================================================================== + +void _glfwDestroyContext(_GLFWwindow* window) +{ + // This is duplicated from glfwCloseWindow + // TODO: Stop duplicating code + if (window == _glfwLibrary.currentWindow) + glfwMakeContextCurrent(NULL); + + if (window->WGL.context) + { + wglDeleteContext(window->WGL.context); + window->WGL.context = NULL; + } + + if (window->WGL.DC) + { + ReleaseDC(window->Win32.handle, window->WGL.DC); + window->WGL.DC = NULL; + } +} + + ////////////////////////////////////////////////////////////////////////// ////// GLFW platform API ////// ////////////////////////////////////////////////////////////////////////// diff --git a/src/win32_platform.h b/src/win32_platform.h index eeadbf22..79bbbb94 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -232,6 +232,12 @@ char* _glfwCreateUTF8FromWideString(const WCHAR* source); // Time void _glfwInitTimer(void); +// OpenGL support +int _glfwCreateContext(_GLFWwindow* window, + const _GLFWwndconfig* wndconfig, + const _GLFWfbconfig* fbconfig); +void _glfwDestroyContext(_GLFWwindow* window); + // Fullscreen support void _glfwSetVideoMode(int* width, int* height, int* bpp, int* refreshRate, diff --git a/src/win32_window.c b/src/win32_window.c index 935767ce..484c81b4 100755 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -122,329 +122,6 @@ static void setForegroundWindow(HWND hWnd) } -//======================================================================== -// Returns the specified attribute of the specified pixel format -// NOTE: Do not call this unless we have found WGL_ARB_pixel_format -//======================================================================== - -static int getPixelFormatAttrib(_GLFWwindow* window, int pixelFormat, int attrib) -{ - int value = 0; - - if (!window->WGL.GetPixelFormatAttribivARB(window->WGL.DC, - pixelFormat, - 0, 1, &attrib, &value)) - { - // NOTE: We should probably handle this error somehow - return 0; - } - - return value; -} - - -//======================================================================== -// Return a list of available and usable framebuffer configs -//======================================================================== - -static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found) -{ - _GLFWfbconfig* fbconfigs; - PIXELFORMATDESCRIPTOR pfd; - int i, available; - - *found = 0; - - if (window->WGL.ARB_pixel_format) - { - available = getPixelFormatAttrib(window, - 1, - WGL_NUMBER_PIXEL_FORMATS_ARB); - } - else - { - available = DescribePixelFormat(window->WGL.DC, - 1, - sizeof(PIXELFORMATDESCRIPTOR), - NULL); - } - - if (!available) - { - _glfwSetError(GLFW_OPENGL_UNAVAILABLE, "Win32/WGL: No pixel formats found"); - return NULL; - } - - fbconfigs = (_GLFWfbconfig*) malloc(sizeof(_GLFWfbconfig) * available); - if (!fbconfigs) - { - _glfwSetError(GLFW_OUT_OF_MEMORY, - "Win32/WGL: Failed to allocate _GLFWfbconfig array"); - return NULL; - } - - for (i = 1; i <= available; i++) - { - _GLFWfbconfig* f = fbconfigs + *found; - - if (window->WGL.ARB_pixel_format) - { - // Get pixel format attributes through WGL_ARB_pixel_format - if (!getPixelFormatAttrib(window, i, WGL_SUPPORT_OPENGL_ARB) || - !getPixelFormatAttrib(window, i, WGL_DRAW_TO_WINDOW_ARB) || - !getPixelFormatAttrib(window, i, WGL_DOUBLE_BUFFER_ARB)) - { - continue; - } - - if (getPixelFormatAttrib(window, i, WGL_PIXEL_TYPE_ARB) != - WGL_TYPE_RGBA_ARB) - { - continue; - } - - if (getPixelFormatAttrib(window, i, WGL_ACCELERATION_ARB) == - WGL_NO_ACCELERATION_ARB) - { - continue; - } - - f->redBits = getPixelFormatAttrib(window, i, WGL_RED_BITS_ARB); - f->greenBits = getPixelFormatAttrib(window, i, WGL_GREEN_BITS_ARB); - f->blueBits = getPixelFormatAttrib(window, i, WGL_BLUE_BITS_ARB); - f->alphaBits = getPixelFormatAttrib(window, i, WGL_ALPHA_BITS_ARB); - - f->depthBits = getPixelFormatAttrib(window, i, WGL_DEPTH_BITS_ARB); - f->stencilBits = getPixelFormatAttrib(window, i, WGL_STENCIL_BITS_ARB); - - f->accumRedBits = getPixelFormatAttrib(window, i, WGL_ACCUM_RED_BITS_ARB); - f->accumGreenBits = getPixelFormatAttrib(window, i, WGL_ACCUM_GREEN_BITS_ARB); - f->accumBlueBits = getPixelFormatAttrib(window, i, WGL_ACCUM_BLUE_BITS_ARB); - f->accumAlphaBits = getPixelFormatAttrib(window, i, WGL_ACCUM_ALPHA_BITS_ARB); - - f->auxBuffers = getPixelFormatAttrib(window, i, WGL_AUX_BUFFERS_ARB); - f->stereo = getPixelFormatAttrib(window, i, WGL_STEREO_ARB); - - if (window->WGL.ARB_multisample) - f->samples = getPixelFormatAttrib(window, i, WGL_SAMPLES_ARB); - else - f->samples = 0; - } - else - { - // Get pixel format attributes through old-fashioned PFDs - - if (!DescribePixelFormat(window->WGL.DC, - i, - sizeof(PIXELFORMATDESCRIPTOR), - &pfd)) - { - continue; - } - - if (!(pfd.dwFlags & PFD_DRAW_TO_WINDOW) || - !(pfd.dwFlags & PFD_SUPPORT_OPENGL) || - !(pfd.dwFlags & PFD_DOUBLEBUFFER)) - { - continue; - } - - if (!(pfd.dwFlags & PFD_GENERIC_ACCELERATED) && - (pfd.dwFlags & PFD_GENERIC_FORMAT)) - { - continue; - } - - if (pfd.iPixelType != PFD_TYPE_RGBA) - continue; - - f->redBits = pfd.cRedBits; - f->greenBits = pfd.cGreenBits; - f->blueBits = pfd.cBlueBits; - f->alphaBits = pfd.cAlphaBits; - - f->depthBits = pfd.cDepthBits; - f->stencilBits = pfd.cStencilBits; - - f->accumRedBits = pfd.cAccumRedBits; - f->accumGreenBits = pfd.cAccumGreenBits; - f->accumBlueBits = pfd.cAccumBlueBits; - f->accumAlphaBits = pfd.cAccumAlphaBits; - - f->auxBuffers = pfd.cAuxBuffers; - f->stereo = (pfd.dwFlags & PFD_STEREO) ? GL_TRUE : GL_FALSE; - - // PFD pixel formats do not support FSAA - f->samples = 0; - } - - f->platformID = i; - - (*found)++; - } - - if (*found == 0) - { - free(fbconfigs); - return NULL; - } - - return fbconfigs; -} - - -//======================================================================== -// Creates an OpenGL context on the specified device context -//======================================================================== - -static GLboolean createContext(_GLFWwindow* window, - const _GLFWwndconfig* wndconfig, - int pixelFormat) -{ - PIXELFORMATDESCRIPTOR pfd; - int i = 0, attribs[40]; - HGLRC share = NULL; - - if (wndconfig->share) - share = wndconfig->share->WGL.context; - - if (!DescribePixelFormat(window->WGL.DC, pixelFormat, sizeof(pfd), &pfd)) - { - _glfwSetError(GLFW_OPENGL_UNAVAILABLE, - "Win32/WGL: Failed to retrieve PFD for selected pixel format"); - return GL_FALSE; - } - - if (!SetPixelFormat(window->WGL.DC, pixelFormat, &pfd)) - { - _glfwSetError(GLFW_OPENGL_UNAVAILABLE, - "Win32/WGL: Failed to set selected pixel format"); - return GL_FALSE; - } - - if (window->WGL.ARB_create_context) - { - // Use the newer wglCreateContextAttribsARB creation method - - if (wndconfig->glMajor != 1 || wndconfig->glMinor != 0) - { - // Request an explicitly versioned context - - attribs[i++] = WGL_CONTEXT_MAJOR_VERSION_ARB; - attribs[i++] = wndconfig->glMajor; - attribs[i++] = WGL_CONTEXT_MINOR_VERSION_ARB; - attribs[i++] = wndconfig->glMinor; - } - - if (wndconfig->glForward || wndconfig->glDebug || wndconfig->glRobustness) - { - int flags = 0; - - if (wndconfig->glForward) - flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; - - if (wndconfig->glDebug) - flags |= WGL_CONTEXT_DEBUG_BIT_ARB; - - if (wndconfig->glRobustness) - flags |= WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB; - - attribs[i++] = WGL_CONTEXT_FLAGS_ARB; - attribs[i++] = flags; - } - - if (wndconfig->glProfile) - { - int flags = 0; - - if (!window->WGL.ARB_create_context_profile) - { - _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.EXT_create_context_es2_profile) - { - _glfwSetError(GLFW_VERSION_UNAVAILABLE, - "Win32/WGL: OpenGL ES 2.x profile requested but " - "WGL_EXT_create_context_es2_profile is unavailable"); - return GL_FALSE; - } - - if (wndconfig->glProfile == GLFW_OPENGL_CORE_PROFILE) - flags = WGL_CONTEXT_CORE_PROFILE_BIT_ARB; - else if (wndconfig->glProfile == GLFW_OPENGL_COMPAT_PROFILE) - flags = WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; - else if (wndconfig->glProfile == GLFW_OPENGL_ES2_PROFILE) - flags = WGL_CONTEXT_ES2_PROFILE_BIT_EXT; - - attribs[i++] = WGL_CONTEXT_PROFILE_MASK_ARB; - attribs[i++] = flags; - } - - if (wndconfig->glRobustness) - { - int strategy; - - if (!window->WGL.ARB_create_context_robustness) - { - _glfwSetError(GLFW_VERSION_UNAVAILABLE, - "Win32/WGL: An OpenGL robustness strategy was " - "requested but WGL_ARB_create_context_robustness " - "is unavailable"); - return GL_FALSE; - } - - if (wndconfig->glRobustness == GLFW_OPENGL_NO_RESET_NOTIFICATION) - strategy = WGL_NO_RESET_NOTIFICATION_ARB; - else if (wndconfig->glRobustness == GLFW_OPENGL_LOSE_CONTEXT_ON_RESET) - strategy = WGL_LOSE_CONTEXT_ON_RESET_ARB; - - attribs[i++] = WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB; - attribs[i++] = strategy; - } - - attribs[i++] = 0; - - window->WGL.context = window->WGL.CreateContextAttribsARB(window->WGL.DC, - share, - attribs); - if (!window->WGL.context) - { - _glfwSetError(GLFW_VERSION_UNAVAILABLE, - "Win32/WGL: Failed to create OpenGL context"); - return GL_FALSE; - } - } - else - { - window->WGL.context = wglCreateContext(window->WGL.DC); - if (!window->WGL.context) - { - _glfwSetError(GLFW_PLATFORM_ERROR, - "Win32/WGL: Failed to create OpenGL context"); - return GL_FALSE; - } - - if (share) - { - if (!wglShareLists(share, window->WGL.context)) - { - _glfwSetError(GLFW_PLATFORM_ERROR, - "Win32/WGL: Failed to enable sharing with " - "specified OpenGL context"); - return GL_FALSE; - } - } - } - - return GL_TRUE; -} - - //======================================================================== // Hide mouse cursor //======================================================================== @@ -1104,94 +781,6 @@ static void getFullWindowSize(_GLFWwindow* window, } -//======================================================================== -// Initialize WGL-specific extensions -// This function is called once before initial context creation, i.e. before -// any WGL extensions could be present. This is done in order to have both -// extension variable clearing and loading in the same place, hopefully -// decreasing the possibility of forgetting to add one without the other. -//======================================================================== - -static void initWGLExtensions(_GLFWwindow* window) -{ - // This needs to include every function pointer loaded below - window->WGL.SwapIntervalEXT = NULL; - window->WGL.GetPixelFormatAttribivARB = NULL; - window->WGL.GetExtensionsStringARB = NULL; - window->WGL.GetExtensionsStringEXT = NULL; - window->WGL.CreateContextAttribsARB = NULL; - - // This needs to include every extension used below except for - // WGL_ARB_extensions_string and WGL_EXT_extensions_string - window->WGL.ARB_multisample = GL_FALSE; - window->WGL.ARB_create_context = GL_FALSE; - window->WGL.ARB_create_context_profile = GL_FALSE; - window->WGL.EXT_create_context_es2_profile = GL_FALSE; - window->WGL.ARB_create_context_robustness = GL_FALSE; - window->WGL.EXT_swap_control = GL_FALSE; - window->WGL.ARB_pixel_format = GL_FALSE; - - window->WGL.GetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC) - wglGetProcAddress("wglGetExtensionsStringEXT"); - if (!window->WGL.GetExtensionsStringEXT) - { - window->WGL.GetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC) - wglGetProcAddress("wglGetExtensionsStringARB"); - if (!window->WGL.GetExtensionsStringARB) - return; - } - - if (_glfwPlatformExtensionSupported("WGL_ARB_multisample")) - window->WGL.ARB_multisample = GL_TRUE; - - if (_glfwPlatformExtensionSupported("WGL_ARB_create_context")) - { - window->WGL.CreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC) - wglGetProcAddress("wglCreateContextAttribsARB"); - - if (window->WGL.CreateContextAttribsARB) - window->WGL.ARB_create_context = GL_TRUE; - } - - if (window->WGL.ARB_create_context) - { - if (_glfwPlatformExtensionSupported("WGL_ARB_create_context_profile")) - window->WGL.ARB_create_context_profile = GL_TRUE; - } - - if (window->WGL.ARB_create_context && - window->WGL.ARB_create_context_profile) - { - if (_glfwPlatformExtensionSupported("WGL_EXT_create_context_es2_profile")) - window->WGL.EXT_create_context_es2_profile = GL_TRUE; - } - - if (window->WGL.ARB_create_context) - { - if (_glfwPlatformExtensionSupported("WGL_ARB_create_context_robustness")) - window->WGL.ARB_create_context_robustness = GL_TRUE; - } - - if (_glfwPlatformExtensionSupported("WGL_EXT_swap_control")) - { - window->WGL.SwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) - wglGetProcAddress("wglSwapIntervalEXT"); - - if (window->WGL.SwapIntervalEXT) - window->WGL.EXT_swap_control = GL_TRUE; - } - - if (_glfwPlatformExtensionSupported("WGL_ARB_pixel_format")) - { - window->WGL.GetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC) - wglGetProcAddress("wglGetPixelFormatAttribivARB"); - - if (window->WGL.GetPixelFormatAttribivARB) - window->WGL.ARB_pixel_format = GL_TRUE; - } -} - - //======================================================================== // Registers the GLFW window class //======================================================================== @@ -1232,38 +821,6 @@ static ATOM registerWindowClass(void) } -//======================================================================== -// Returns the closest matching pixel format, or zero on error -//======================================================================== - -static int choosePixelFormat(_GLFWwindow* window, const _GLFWfbconfig* fbconfig) -{ - unsigned int fbcount; - int pixelFormat; - _GLFWfbconfig* fbconfigs; - const _GLFWfbconfig* closest; - - fbconfigs = getFBConfigs(window, &fbcount); - if (!fbconfigs) - return 0; - - closest = _glfwChooseFBConfig(fbconfig, fbconfigs, fbcount); - if (!closest) - { - free(fbconfigs); - return 0; - } - - pixelFormat = (int) closest->platformID; - - free(fbconfigs); - fbconfigs = NULL; - closest = NULL; - - return pixelFormat; -} - - //======================================================================== // Creates the GLFW window and rendering context //======================================================================== @@ -1273,7 +830,7 @@ static int createWindow(_GLFWwindow* window, const _GLFWfbconfig* fbconfig) { DWORD dwStyle, dwExStyle; - int pixelFormat, fullWidth, fullHeight; + int fullWidth, fullHeight; RECT wa; POINT pos; WCHAR* wideTitle; @@ -1353,31 +910,15 @@ static int createWindow(_GLFWwindow* window, free(wideTitle); - window->WGL.DC = GetDC(window->Win32.handle); - if (!window->WGL.DC) - { - _glfwSetError(GLFW_PLATFORM_ERROR, - "Win32/WGL: Failed to retrieve DC for window"); - return GL_FALSE; - } - - pixelFormat = choosePixelFormat(window, fbconfig); - if (!pixelFormat) - return GL_FALSE; - - if (!createContext(window, wndconfig, pixelFormat)) - return GL_FALSE; - - glfwMakeContextCurrent(window); - - initWGLExtensions(window); - // Initialize cursor position data GetCursorPos(&pos); ScreenToClient(window->Win32.handle, &pos); window->Win32.oldCursorX = window->cursorPosX = pos.x; window->Win32.oldCursorY = window->cursorPosY = pos.y; + if (!_glfwCreateContext(window, wndconfig, fbconfig)) + return GL_FALSE; + return GL_TRUE; } @@ -1388,28 +929,13 @@ static int createWindow(_GLFWwindow* window, static void destroyWindow(_GLFWwindow* window) { - // This is duplicated from glfwCloseWindow - // TODO: Stop duplicating code - if (window == _glfwLibrary.currentWindow) - glfwMakeContextCurrent(NULL); + _glfwDestroyContext(window); // This is duplicated from glfwCloseWindow // TODO: Stop duplicating code if (window == _glfwLibrary.activeWindow) _glfwLibrary.activeWindow = NULL; - if (window->WGL.context) - { - wglDeleteContext(window->WGL.context); - window->WGL.context = NULL; - } - - if (window->WGL.DC) - { - ReleaseDC(window->Win32.handle, window->WGL.DC); - window->WGL.DC = NULL; - } - if (window->Win32.handle) { DestroyWindow(window->Win32.handle); @@ -1669,93 +1195,10 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window) void _glfwPlatformRefreshWindowParams(void) { - PIXELFORMATDESCRIPTOR pfd; DEVMODE dm; - int pixelFormat; - _GLFWwindow* window = _glfwLibrary.currentWindow; - // Obtain a detailed description of current pixel format - pixelFormat = GetPixelFormat(window->WGL.DC); - - if (window->WGL.ARB_pixel_format) - { - if (getPixelFormatAttrib(window, pixelFormat, WGL_ACCELERATION_ARB) != - WGL_NO_ACCELERATION_ARB) - { - window->accelerated = GL_TRUE; - } - else - window->accelerated = GL_FALSE; - - window->redBits = - getPixelFormatAttrib(window, pixelFormat, WGL_RED_BITS_ARB); - window->greenBits = - getPixelFormatAttrib(window, pixelFormat, WGL_GREEN_BITS_ARB); - window->blueBits = - getPixelFormatAttrib(window, pixelFormat, WGL_BLUE_BITS_ARB); - - window->alphaBits = - getPixelFormatAttrib(window, pixelFormat, WGL_ALPHA_BITS_ARB); - window->depthBits = - getPixelFormatAttrib(window, pixelFormat, WGL_DEPTH_BITS_ARB); - window->stencilBits = - getPixelFormatAttrib(window, pixelFormat, WGL_STENCIL_BITS_ARB); - - window->accumRedBits = - getPixelFormatAttrib(window, pixelFormat, WGL_ACCUM_RED_BITS_ARB); - window->accumGreenBits = - getPixelFormatAttrib(window, pixelFormat, WGL_ACCUM_GREEN_BITS_ARB); - window->accumBlueBits = - getPixelFormatAttrib(window, pixelFormat, WGL_ACCUM_BLUE_BITS_ARB); - window->accumAlphaBits = - getPixelFormatAttrib(window, pixelFormat, WGL_ACCUM_ALPHA_BITS_ARB); - - window->auxBuffers = - getPixelFormatAttrib(window, pixelFormat, WGL_AUX_BUFFERS_ARB); - window->stereo = - getPixelFormatAttrib(window, pixelFormat, WGL_STEREO_ARB) ? GL_TRUE : GL_FALSE; - - if (window->WGL.ARB_multisample) - { - window->samples = getPixelFormatAttrib(window, pixelFormat, WGL_SAMPLES_ARB); - - // We force 1 to zero here because all the other APIs say zero when - // they really mean 1 - if (window->samples == 1) - window->samples = 0; - } - else - window->samples = 0; - } - else - { - DescribePixelFormat(window->WGL.DC, pixelFormat, - sizeof(PIXELFORMATDESCRIPTOR), &pfd); - - // Is current OpenGL context accelerated? - window->accelerated = (pfd.dwFlags & PFD_GENERIC_ACCELERATED) || - !(pfd.dwFlags & PFD_GENERIC_FORMAT) ? 1 : 0; - - // "Standard" window parameters - window->redBits = pfd.cRedBits; - window->greenBits = pfd.cGreenBits; - window->blueBits = pfd.cBlueBits; - window->alphaBits = pfd.cAlphaBits; - window->depthBits = pfd.cDepthBits; - window->stencilBits = pfd.cStencilBits; - window->accumRedBits = pfd.cAccumRedBits; - window->accumGreenBits = pfd.cAccumGreenBits; - window->accumBlueBits = pfd.cAccumBlueBits; - window->accumAlphaBits = pfd.cAccumAlphaBits; - window->auxBuffers = pfd.cAuxBuffers; - window->stereo = (pfd.dwFlags & PFD_STEREO) ? GL_TRUE : GL_FALSE; - - // If we don't have WGL_ARB_pixel_format then we can't have created a - // multisampling context, so it's safe to hardcode zero here - window->samples = 0; - } - + ZeroMemory(&dm, sizeof(DEVMODE)); dm.dmSize = sizeof(DEVMODE); if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm)) From 669c40f102c0107152efbba9fd2bec5976011911 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Tue, 31 Jul 2012 23:07:18 +0200 Subject: [PATCH 11/35] Fixed debug context being a hard constraint on WGL. --- src/win32_window.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/win32_window.c b/src/win32_window.c index 484c81b4..fff50ea2 100755 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -998,14 +998,19 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window, recreateContext = GL_TRUE; } - if (wndconfig->glForward || wndconfig->glDebug) + if (wndconfig->glDebug) + { + if (window->WGL.ARB_create_context) + recreateContext = GL_TRUE; + } + + if (wndconfig->glForward) { if (!window->WGL.ARB_create_context) { _glfwSetError(GLFW_VERSION_UNAVAILABLE, - "Win32/WGL: A forward compatible or debug OpenGL " - "context requested but WGL_ARB_create_context is " - "unavailable"); + "Win32/WGL: A forward compatible OpenGL context " + "requested but WGL_ARB_create_context is unavailable"); return GL_FALSE; } From 6c86149bad13a5fe43683ff8af8737de8065934f Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Tue, 31 Jul 2012 23:14:31 +0200 Subject: [PATCH 12/35] Improved output of OpenGL bitmasks. --- tests/glfwinfo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/glfwinfo.c b/tests/glfwinfo.c index 45cb8616..746d606f 100644 --- a/tests/glfwinfo.c +++ b/tests/glfwinfo.c @@ -249,7 +249,7 @@ int main(int argc, char** argv) if (major >= 3) { glGetIntegerv(GL_CONTEXT_FLAGS, &flags); - printf("OpenGL context flags:"); + printf("OpenGL context flags (0x%08x):", flags); if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT) puts(" forward-compatible"); @@ -263,7 +263,7 @@ int main(int argc, char** argv) if (major > 3 || (major == 3 && minor >= 2)) { glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask); - printf("OpenGL profile mask: %s (0x%08x)\n", get_profile_name(mask), mask); + printf("OpenGL profile mask (0x%08x): %s\n", mask, get_profile_name(mask)); printf("OpenGL profile parsed by GLFW: %s\n", get_glfw_profile_name(glfwGetWindowParam(window, GLFW_OPENGL_PROFILE))); From b00064902daa9a324a2cd66ff8925b2d36ca019a Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Tue, 31 Jul 2012 23:51:27 +0200 Subject: [PATCH 13/35] Made flag parsing output more consistent. --- tests/glfwinfo.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/tests/glfwinfo.c b/tests/glfwinfo.c index 746d606f..13c9eec2 100644 --- a/tests/glfwinfo.c +++ b/tests/glfwinfo.c @@ -252,12 +252,18 @@ int main(int argc, char** argv) printf("OpenGL context flags (0x%08x):", flags); if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT) - puts(" forward-compatible"); - else - puts(" none"); + printf(" forward-compatible"); + if (flags & 0) + printf(" debug"); + putchar('\n'); - printf("OpenGL forward-compatible flag parsed by GLFW: %s\n", - glfwGetWindowParam(window, GLFW_OPENGL_FORWARD_COMPAT) ? "true" : "false"); + printf("OpenGL flags parsed by GLFW:"); + + if (glfwGetWindowParam(window, GLFW_OPENGL_FORWARD_COMPAT)) + printf(" forward-compatible"); + if (glfwGetWindowParam(window, GLFW_OPENGL_DEBUG_CONTEXT)) + printf(" debug"); + putchar('\n'); } if (major > 3 || (major == 3 && minor >= 2)) From 302037d5b40a2b486acde7643f18d6dffdbadefa Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Tue, 31 Jul 2012 23:52:23 +0200 Subject: [PATCH 14/35] Added stub debug context detection. --- src/cocoa_window.m | 4 ---- src/opengl.c | 2 ++ 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/cocoa_window.m b/src/cocoa_window.m index d00fbbff..9f20398a 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -1104,10 +1104,6 @@ void _glfwPlatformRefreshWindowParams(void) forAttribute:NSOpenGLPFASamples forVirtualScreen:0]; window->samples = value; - - // These this is forced to false as long as Mac OS X lacks support for - // requesting debug contexts - window->glDebug = GL_FALSE; } diff --git a/src/opengl.c b/src/opengl.c index 67b5e728..64e12e97 100644 --- a/src/opengl.c +++ b/src/opengl.c @@ -366,6 +366,8 @@ GLboolean _glfwIsValidContext(_GLFWwindow* window, _GLFWwndconfig* wndconfig) if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT) window->glForward = GL_TRUE; + if (flags & 0) + window->glDebug = GL_TRUE; } } From 98d02ebb1d94458e33267daee7141850dcb4ed22 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Wed, 1 Aug 2012 00:51:49 +0200 Subject: [PATCH 15/35] Updated MinGW cross-compilation documentation. --- CMake/README.txt | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/CMake/README.txt b/CMake/README.txt index 96ac1905..9dbaee26 100644 --- a/CMake/README.txt +++ b/CMake/README.txt @@ -1,17 +1,16 @@ -This directory contains a collection of toolchain definitions for cross -compilation, currently limited to compiling Win32 binaries on Linux. - -The toolchain file naming scheme is as follows: - - host-system-compiler.cmake +This directory contains a collection of toolchain definitions for +cross-compiling for Windows using MinGW on various other systems. To use these files you add a special parameter when configuring the source tree: cmake -DCMAKE_TOOLCHAIN_FILE= . -For example, to use the Debian GNU/Linux MinGW package, run CMake like this: +The exact file to use depends on the prefix used by the MinGW binaries on your +system. You can usually see this in the /usr directory, i.e. the Ubuntu +MinGW-w64 packages have /usr/x86_64-w64-mingw32 for the 64-bit compilers, so the +correct invocation would be: - cmake -DCMAKE_TOOLCHAIN_FILE=CMake/i586-mingw32msvc.cmake . + cmake -DCMAKE_TOOLCHAIN_FILE=CMake/x86_64-w64-mingw32.cmake . For more details see this article: From d1617bdd789a0bb882652e9a0f7d748cdf85371f Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Wed, 1 Aug 2012 01:46:06 +0200 Subject: [PATCH 16/35] Made flag parsing output even more consistent. --- tests/glfwinfo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/glfwinfo.c b/tests/glfwinfo.c index 13c9eec2..bbbedce0 100644 --- a/tests/glfwinfo.c +++ b/tests/glfwinfo.c @@ -257,7 +257,7 @@ int main(int argc, char** argv) printf(" debug"); putchar('\n'); - printf("OpenGL flags parsed by GLFW:"); + printf("OpenGL context flags parsed by GLFW:"); if (glfwGetWindowParam(window, GLFW_OPENGL_FORWARD_COMPAT)) printf(" forward-compatible"); @@ -271,7 +271,7 @@ int main(int argc, char** argv) glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask); printf("OpenGL profile mask (0x%08x): %s\n", mask, get_profile_name(mask)); - printf("OpenGL profile parsed by GLFW: %s\n", + printf("OpenGL profile mask parsed by GLFW: %s\n", get_glfw_profile_name(glfwGetWindowParam(window, GLFW_OPENGL_PROFILE))); } From 3a72f33541466c0d0b00a4c33e70c981e87fa9fe Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Thu, 2 Aug 2012 01:13:05 +0200 Subject: [PATCH 17/35] Removed GLFW_ACCELERATED window parameter. --- include/GL/glfw3.h | 1 - readme.html | 1 + src/cocoa_window.m | 5 ----- src/internal.h | 1 - src/win32_opengl.c | 12 ------------ src/window.c | 2 -- src/x11_opengl.c | 4 ---- tests/defaults.c | 1 - 8 files changed, 1 insertion(+), 26 deletions(-) diff --git a/include/GL/glfw3.h b/include/GL/glfw3.h index 28e38bd1..693e55f3 100644 --- a/include/GL/glfw3.h +++ b/include/GL/glfw3.h @@ -390,7 +390,6 @@ extern "C" { /* glfwGetWindowParam tokens */ #define GLFW_ACTIVE 0x00020001 #define GLFW_ICONIFIED 0x00020002 -#define GLFW_ACCELERATED 0x00020003 #define GLFW_OPENGL_REVISION 0x00020004 /* The following constants are used for both glfwGetWindowParam diff --git a/readme.html b/readme.html index 10fa433b..e5fa8c9d 100644 --- a/readme.html +++ b/readme.html @@ -318,6 +318,7 @@ version of GLFW.

  • Removed GLFW_OPENED window parameter
  • Removed nonsensical key actions for Unicode character input
  • Removed GLFWCALL and GLFWAPIENTRY macros for stdcall calling convention
  • +
  • Removed GLFW_ACCELERATED window parameter
  • Bugfix: The default OpenGL version in the glfwinfo test was set to 1.1
  • Bugfix: The OpenGL profile and forward-compatibility window parameters were not saved after context creation
  • Bugfix: The FSAA test did not check for the availability of GL_ARB_multisample
  • diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 9f20398a..e0b146b9 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -1047,11 +1047,6 @@ void _glfwPlatformRefreshWindowParams(void) // Since GLFW doesn't understand screens, we use virtual screen zero - [window->NSGL.pixelFormat getValues:&value - forAttribute:NSOpenGLPFAAccelerated - forVirtualScreen:0]; - window->accelerated = value; - [window->NSGL.pixelFormat getValues:&value forAttribute:NSOpenGLPFAAlphaSize forVirtualScreen:0]; diff --git a/src/internal.h b/src/internal.h index 700b6c06..f0bc6cb0 100644 --- a/src/internal.h +++ b/src/internal.h @@ -211,7 +211,6 @@ struct _GLFWwindow int samples; // OpenGL extensions and context attributes - GLboolean accelerated; // GL_TRUE if OpenGL context is "accelerated" int glMajor, glMinor, glRevision; GLboolean glForward, glDebug; int glProfile; diff --git a/src/win32_opengl.c b/src/win32_opengl.c index cc795e53..1bb26bfc 100644 --- a/src/win32_opengl.c +++ b/src/win32_opengl.c @@ -300,14 +300,6 @@ static void refreshContextParams(_GLFWwindow* window, int pixelFormat) if (window->WGL.ARB_pixel_format) { - if (getPixelFormatAttrib(window, pixelFormat, WGL_ACCELERATION_ARB) != - WGL_NO_ACCELERATION_ARB) - { - window->accelerated = GL_TRUE; - } - else - window->accelerated = GL_FALSE; - window->redBits = getPixelFormatAttrib(window, pixelFormat, WGL_RED_BITS_ARB); window->greenBits = @@ -353,10 +345,6 @@ static void refreshContextParams(_GLFWwindow* window, int pixelFormat) DescribePixelFormat(window->WGL.DC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd); - // Is current OpenGL context accelerated? - window->accelerated = (pfd.dwFlags & PFD_GENERIC_ACCELERATED) || - !(pfd.dwFlags & PFD_GENERIC_FORMAT) ? 1 : 0; - // "Standard" window parameters window->redBits = pfd.cRedBits; window->greenBits = pfd.cGreenBits; diff --git a/src/window.c b/src/window.c index f8939e37..119ce7de 100644 --- a/src/window.c +++ b/src/window.c @@ -682,8 +682,6 @@ GLFWAPI int glfwGetWindowParam(GLFWwindow handle, int param) return window == _glfwLibrary.activeWindow; case GLFW_ICONIFIED: return window->iconified; - case GLFW_ACCELERATED: - return window->accelerated; case GLFW_RED_BITS: return window->redBits; case GLFW_GREEN_BITS: diff --git a/src/x11_opengl.c b/src/x11_opengl.c index edcd69b6..048b794f 100644 --- a/src/x11_opengl.c +++ b/src/x11_opengl.c @@ -233,10 +233,6 @@ static void refreshContextParams(_GLFWwindow* window, GLXFBConfigID fbconfigID) abort(); } - // There is no clear definition of an "accelerated" context on X11/GLX, and - // true sounds better than false, so we hardcode true here - window->accelerated = GL_TRUE; - window->redBits = getFBConfigAttrib(window, *fbconfig, GLX_RED_SIZE); window->greenBits = getFBConfigAttrib(window, *fbconfig, GLX_GREEN_SIZE); window->blueBits = getFBConfigAttrib(window, *fbconfig, GLX_BLUE_SIZE); diff --git a/tests/defaults.c b/tests/defaults.c index d7c5a02c..16c62723 100644 --- a/tests/defaults.c +++ b/tests/defaults.c @@ -42,7 +42,6 @@ typedef struct static Param parameters[] = { - { GLFW_ACCELERATED, "accelerated" }, { GLFW_RED_BITS, "red bits" }, { GLFW_GREEN_BITS, "green bits" }, { GLFW_BLUE_BITS, "blue bits" }, From 053737e6607bb529731aae4720011247c84a2f6c Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Thu, 2 Aug 2012 01:18:35 +0200 Subject: [PATCH 18/35] Use OpenGL to get default framebuffer properties. --- src/cocoa_window.m | 57 ---------------------------------- src/internal.h | 25 +++++++-------- src/opengl.c | 37 +++++++++++++++++++--- src/win32_opengl.c | 77 ---------------------------------------------- src/window.c | 1 + src/x11_opengl.c | 64 -------------------------------------- 6 files changed, 47 insertions(+), 214 deletions(-) diff --git a/src/cocoa_window.m b/src/cocoa_window.m index e0b146b9..6e4d4270 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -1042,63 +1042,6 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window) void _glfwPlatformRefreshWindowParams(void) { - GLint value; - _GLFWwindow* window = _glfwLibrary.currentWindow; - - // Since GLFW doesn't understand screens, we use virtual screen zero - - [window->NSGL.pixelFormat getValues:&value - forAttribute:NSOpenGLPFAAlphaSize - forVirtualScreen:0]; - window->alphaBits = value; - - [window->NSGL.pixelFormat getValues:&value - forAttribute:NSOpenGLPFAColorSize - forVirtualScreen:0]; - - // It seems that the color size includes the size of the alpha channel so - // we subtract it before splitting - _glfwSplitBPP(value - window->alphaBits, - &window->redBits, - &window->greenBits, - &window->blueBits); - - [window->NSGL.pixelFormat getValues:&value - forAttribute:NSOpenGLPFADepthSize - forVirtualScreen:0]; - window->depthBits = value; - - [window->NSGL.pixelFormat getValues:&value - forAttribute:NSOpenGLPFAStencilSize - forVirtualScreen:0]; - window->stencilBits = value; - - [window->NSGL.pixelFormat getValues:&value - forAttribute:NSOpenGLPFAAccumSize - forVirtualScreen:0]; - - _glfwSplitBPP(value, - &window->accumRedBits, - &window->accumGreenBits, - &window->accumBlueBits); - - // TODO: Figure out what to set this value to - window->accumAlphaBits = 0; - - [window->NSGL.pixelFormat getValues:&value - forAttribute:NSOpenGLPFAAuxBuffers - forVirtualScreen:0]; - window->auxBuffers = value; - - [window->NSGL.pixelFormat getValues:&value - forAttribute:NSOpenGLPFAStereo - forVirtualScreen:0]; - window->stereo = value; - - [window->NSGL.pixelFormat getValues:&value - forAttribute:NSOpenGLPFASamples - forVirtualScreen:0]; - window->samples = value; } diff --git a/src/internal.h b/src/internal.h index f0bc6cb0..620459e9 100644 --- a/src/internal.h +++ b/src/internal.h @@ -196,19 +196,19 @@ struct _GLFWwindow char key[GLFW_KEY_LAST + 1]; // Framebuffer attributes - int redBits; - int greenBits; - int blueBits; - int alphaBits; - int depthBits; - int stencilBits; - int accumRedBits; - int accumGreenBits; - int accumBlueBits; - int accumAlphaBits; - int auxBuffers; + GLint redBits; + GLint greenBits; + GLint blueBits; + GLint alphaBits; + GLint depthBits; + GLint stencilBits; + GLint accumRedBits; + GLint accumGreenBits; + GLint accumBlueBits; + GLint accumAlphaBits; + GLint auxBuffers; GLboolean stereo; - int samples; + GLint samples; // OpenGL extensions and context attributes int glMajor, glMinor, glRevision; @@ -363,6 +363,7 @@ int _glfwStringInExtensionString(const char* string, const GLubyte* extensions); const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired, const _GLFWfbconfig* alternatives, unsigned int count); +void _glfwRefreshContextParams(void); GLboolean _glfwIsValidContextConfig(_GLFWwndconfig* wndconfig); GLboolean _glfwIsValidContext(_GLFWwindow* window, _GLFWwndconfig* wndconfig); diff --git a/src/opengl.c b/src/opengl.c index 64e12e97..ed68c499 100644 --- a/src/opengl.c +++ b/src/opengl.c @@ -347,12 +347,13 @@ GLboolean _glfwIsValidContextConfig(_GLFWwndconfig* wndconfig) //======================================================================== -// Checks whether the specified context fulfils the requirements -// It blames glfwOpenWindow because that's the only caller +// Reads back context properties //======================================================================== -GLboolean _glfwIsValidContext(_GLFWwindow* window, _GLFWwndconfig* wndconfig) +void _glfwRefreshContextParams(void) { + _GLFWwindow* window = _glfwLibrary.currentWindow; + parseGLVersion(&window->glMajor, &window->glMinor, &window->glRevision); // Read back forward-compatibility flag @@ -387,8 +388,36 @@ GLboolean _glfwIsValidContext(_GLFWwindow* window, _GLFWwndconfig* wndconfig) } } - window->glRobustness = wndconfig->glRobustness; + glGetIntegerv(GL_RED_BITS, &window->redBits); + glGetIntegerv(GL_GREEN_BITS, &window->greenBits); + glGetIntegerv(GL_BLUE_BITS, &window->blueBits); + glGetIntegerv(GL_ALPHA_BITS, &window->alphaBits); + glGetIntegerv(GL_DEPTH_BITS, &window->depthBits); + glGetIntegerv(GL_STENCIL_BITS, &window->stencilBits); + + glGetIntegerv(GL_ACCUM_RED_BITS, &window->accumRedBits); + glGetIntegerv(GL_ACCUM_GREEN_BITS, &window->accumGreenBits); + glGetIntegerv(GL_ACCUM_BLUE_BITS, &window->accumBlueBits); + glGetIntegerv(GL_ACCUM_ALPHA_BITS, &window->accumAlphaBits); + + glGetIntegerv(GL_AUX_BUFFERS, &window->auxBuffers); + glGetBooleanv(GL_STEREO, &window->stereo); + + if (_glfwPlatformExtensionSupported("GL_ARB_multisample")) + glGetIntegerv(GL_SAMPLES_ARB, &window->samples); + else + window->samples = 0; +} + + +//======================================================================== +// Checks whether the specified context fulfils the requirements +// It blames glfwOpenWindow because that's the only caller +//======================================================================== + +GLboolean _glfwIsValidContext(_GLFWwindow* window, _GLFWwndconfig* wndconfig) +{ if (window->glMajor < wndconfig->glMajor || (window->glMajor == wndconfig->glMajor && window->glMinor < wndconfig->glMinor)) diff --git a/src/win32_opengl.c b/src/win32_opengl.c index 1bb26bfc..11a45346 100644 --- a/src/win32_opengl.c +++ b/src/win32_opengl.c @@ -290,82 +290,6 @@ static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found) } -//======================================================================== -// Read back framebuffer parameters from the context -//======================================================================== - -static void refreshContextParams(_GLFWwindow* window, int pixelFormat) -{ - PIXELFORMATDESCRIPTOR pfd; - - if (window->WGL.ARB_pixel_format) - { - window->redBits = - getPixelFormatAttrib(window, pixelFormat, WGL_RED_BITS_ARB); - window->greenBits = - getPixelFormatAttrib(window, pixelFormat, WGL_GREEN_BITS_ARB); - window->blueBits = - getPixelFormatAttrib(window, pixelFormat, WGL_BLUE_BITS_ARB); - - window->alphaBits = - getPixelFormatAttrib(window, pixelFormat, WGL_ALPHA_BITS_ARB); - window->depthBits = - getPixelFormatAttrib(window, pixelFormat, WGL_DEPTH_BITS_ARB); - window->stencilBits = - getPixelFormatAttrib(window, pixelFormat, WGL_STENCIL_BITS_ARB); - - window->accumRedBits = - getPixelFormatAttrib(window, pixelFormat, WGL_ACCUM_RED_BITS_ARB); - window->accumGreenBits = - getPixelFormatAttrib(window, pixelFormat, WGL_ACCUM_GREEN_BITS_ARB); - window->accumBlueBits = - getPixelFormatAttrib(window, pixelFormat, WGL_ACCUM_BLUE_BITS_ARB); - window->accumAlphaBits = - getPixelFormatAttrib(window, pixelFormat, WGL_ACCUM_ALPHA_BITS_ARB); - - window->auxBuffers = - getPixelFormatAttrib(window, pixelFormat, WGL_AUX_BUFFERS_ARB); - window->stereo = - getPixelFormatAttrib(window, pixelFormat, WGL_STEREO_ARB) ? GL_TRUE : GL_FALSE; - - if (window->WGL.ARB_multisample) - { - window->samples = getPixelFormatAttrib(window, pixelFormat, WGL_SAMPLES_ARB); - - // We force 1 to zero here because all the other APIs say zero when - // they really mean 1 - if (window->samples == 1) - window->samples = 0; - } - else - window->samples = 0; - } - else - { - DescribePixelFormat(window->WGL.DC, pixelFormat, - sizeof(PIXELFORMATDESCRIPTOR), &pfd); - - // "Standard" window parameters - window->redBits = pfd.cRedBits; - window->greenBits = pfd.cGreenBits; - window->blueBits = pfd.cBlueBits; - window->alphaBits = pfd.cAlphaBits; - window->depthBits = pfd.cDepthBits; - window->stencilBits = pfd.cStencilBits; - window->accumRedBits = pfd.cAccumRedBits; - window->accumGreenBits = pfd.cAccumGreenBits; - window->accumBlueBits = pfd.cAccumBlueBits; - window->accumAlphaBits = pfd.cAccumAlphaBits; - window->auxBuffers = pfd.cAuxBuffers; - window->stereo = (pfd.dwFlags & PFD_STEREO) ? GL_TRUE : GL_FALSE; - - // If we don't have WGL_ARB_pixel_format then we can't have created a - // multisampling context, so it's safe to hardcode zero here - window->samples = 0; - } -} - - //======================================================================== // Creates an OpenGL context on the specified device context //======================================================================== @@ -516,7 +440,6 @@ static GLboolean createContext(_GLFWwindow* window, glfwMakeContextCurrent(window); initWGLExtensions(window); - refreshContextParams(window, pixelFormat); return GL_TRUE; } diff --git a/src/window.c b/src/window.c index 119ce7de..919434ec 100644 --- a/src/window.c +++ b/src/window.c @@ -320,6 +320,7 @@ GLFWAPI GLFWwindow glfwOpenWindow(int width, int height, // Cache the actual (as opposed to desired) window parameters glfwMakeContextCurrent(window); + _glfwRefreshContextParams(); _glfwPlatformRefreshWindowParams(); if (!_glfwIsValidContext(window, &wndconfig)) diff --git a/src/x11_opengl.c b/src/x11_opengl.c index 048b794f..017d660d 100644 --- a/src/x11_opengl.c +++ b/src/x11_opengl.c @@ -197,68 +197,6 @@ static int errorHandler(Display *display, XErrorEvent* event) } -//======================================================================== -// Read back framebuffer parameters from the context -//======================================================================== - -static void refreshContextParams(_GLFWwindow* window, GLXFBConfigID fbconfigID) -{ - int dummy; - GLXFBConfig* fbconfig; - - int attribs[] = { GLX_FBCONFIG_ID, fbconfigID, None }; - - if (_glfwLibrary.GLX.SGIX_fbconfig) - { - fbconfig = _glfwLibrary.GLX.ChooseFBConfigSGIX(_glfwLibrary.X11.display, - _glfwLibrary.X11.screen, - attribs, - &dummy); - } - else - { - fbconfig = glXChooseFBConfig(_glfwLibrary.X11.display, - _glfwLibrary.X11.screen, - attribs, - &dummy); - } - - if (fbconfig == NULL) - { - // This should never ever happen - // TODO: Flag this as an error and propagate up - _glfwSetError(GLFW_PLATFORM_ERROR, "X11/GLX: Cannot find known " - "GLXFBConfig by ID. This cannot " - "happen. Have a nice day.\n"); - abort(); - } - - window->redBits = getFBConfigAttrib(window, *fbconfig, GLX_RED_SIZE); - window->greenBits = getFBConfigAttrib(window, *fbconfig, GLX_GREEN_SIZE); - window->blueBits = getFBConfigAttrib(window, *fbconfig, GLX_BLUE_SIZE); - - window->alphaBits = getFBConfigAttrib(window, *fbconfig, GLX_ALPHA_SIZE); - window->depthBits = getFBConfigAttrib(window, *fbconfig, GLX_DEPTH_SIZE); - window->stencilBits = getFBConfigAttrib(window, *fbconfig, GLX_STENCIL_SIZE); - - window->accumRedBits = getFBConfigAttrib(window, *fbconfig, GLX_ACCUM_RED_SIZE); - window->accumGreenBits = getFBConfigAttrib(window, *fbconfig, GLX_ACCUM_GREEN_SIZE); - window->accumBlueBits = getFBConfigAttrib(window, *fbconfig, GLX_ACCUM_BLUE_SIZE); - window->accumAlphaBits = getFBConfigAttrib(window, *fbconfig, GLX_ACCUM_ALPHA_SIZE); - - window->auxBuffers = getFBConfigAttrib(window, *fbconfig, GLX_AUX_BUFFERS); - window->stereo = getFBConfigAttrib(window, *fbconfig, GLX_STEREO) ? GL_TRUE : GL_FALSE; - - // Get FSAA buffer sample count - if (_glfwLibrary.GLX.ARB_multisample) - window->samples = getFBConfigAttrib(window, *fbconfig, GLX_SAMPLES); - else - window->samples = 0; - - XFree(fbconfig); -} - - //======================================================================== // Create the actual OpenGL context //======================================================================== @@ -463,8 +401,6 @@ static int createContext(_GLFWwindow* window, return GL_FALSE; } - refreshContextParams(window, fbconfigID); - return GL_TRUE; } From f274b329d1f838f42dae1f1f108f82c4a9b82483 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Thu, 2 Aug 2012 14:16:07 +0200 Subject: [PATCH 19/35] Fixed check for GL_ARB_multisample. --- src/opengl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opengl.c b/src/opengl.c index ed68c499..d06bdb1e 100644 --- a/src/opengl.c +++ b/src/opengl.c @@ -404,7 +404,7 @@ void _glfwRefreshContextParams(void) glGetIntegerv(GL_AUX_BUFFERS, &window->auxBuffers); glGetBooleanv(GL_STEREO, &window->stereo); - if (_glfwPlatformExtensionSupported("GL_ARB_multisample")) + if (glfwExtensionSupported("GL_ARB_multisample")) glGetIntegerv(GL_SAMPLES_ARB, &window->samples); else window->samples = 0; From 59896c327aab2654c516ac4bda05066db47f3d09 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Thu, 2 Aug 2012 14:42:24 +0200 Subject: [PATCH 20/35] Context property fixes. --- src/internal.h | 4 ++-- src/opengl.c | 55 ++++++++++++++++++++++++++++++++------------------ src/window.c | 12 ++++++++--- 3 files changed, 46 insertions(+), 25 deletions(-) diff --git a/src/internal.h b/src/internal.h index 620459e9..fc036bc0 100644 --- a/src/internal.h +++ b/src/internal.h @@ -363,9 +363,9 @@ int _glfwStringInExtensionString(const char* string, const GLubyte* extensions); const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired, const _GLFWfbconfig* alternatives, unsigned int count); -void _glfwRefreshContextParams(void); +GLboolean _glfwRefreshContextParams(void); GLboolean _glfwIsValidContextConfig(_GLFWwndconfig* wndconfig); -GLboolean _glfwIsValidContext(_GLFWwindow* window, _GLFWwndconfig* wndconfig); +GLboolean _glfwIsValidContext(_GLFWwndconfig* wndconfig); #endif // _internal_h_ diff --git a/src/opengl.c b/src/opengl.c index d06bdb1e..273d2c58 100644 --- a/src/opengl.c +++ b/src/opengl.c @@ -38,7 +38,7 @@ // Parses the OpenGL version string and extracts the version number //======================================================================== -static void parseGLVersion(int* major, int* minor, int* rev) +static GLboolean parseGLVersion(int* major, int* minor, int* rev) { GLuint _major, _minor = 0, _rev = 0; const GLubyte* version; @@ -47,7 +47,10 @@ static void parseGLVersion(int* major, int* minor, int* rev) version = glGetString(GL_VERSION); if (!version) + { + _glfwSetError(GLFW_PLATFORM_ERROR, "Failed to retrieve version string"); return; + } if (strncmp((const char*) version, glesPrefix, strlen(glesPrefix)) == 0) { @@ -81,6 +84,8 @@ static void parseGLVersion(int* major, int* minor, int* rev) *major = _major; *minor = _minor; *rev = _rev; + + return GL_TRUE; } @@ -348,13 +353,34 @@ GLboolean _glfwIsValidContextConfig(_GLFWwndconfig* wndconfig) //======================================================================== // Reads back context properties +// It blames glfwOpenWindow because that's the only caller //======================================================================== -void _glfwRefreshContextParams(void) +GLboolean _glfwRefreshContextParams(void) { _GLFWwindow* window = _glfwLibrary.currentWindow; - parseGLVersion(&window->glMajor, &window->glMinor, &window->glRevision); + if (!parseGLVersion(&window->glMajor, + &window->glMinor, + &window->glRevision)) + { + return GL_FALSE; + } + + if (window->glMajor > 2) + { + // OpenGL 3.0+ uses a different function for extension string retrieval + // We cache it here instead of in glfwExtensionSupported mostly to alert + // users as early as possible that their build may be broken + + window->GetStringi = (PFNGLGETSTRINGIPROC) glfwGetProcAddress("glGetStringi"); + if (!window->GetStringi) + { + _glfwSetError(GLFW_PLATFORM_ERROR, + "glfwOpenWindow: Entry point retrieval is broken"); + return GL_FALSE; + } + } // Read back forward-compatibility flag { @@ -408,16 +434,20 @@ void _glfwRefreshContextParams(void) glGetIntegerv(GL_SAMPLES_ARB, &window->samples); else window->samples = 0; + + return GL_TRUE; } //======================================================================== -// Checks whether the specified context fulfils the requirements +// Checks whether the current context fulfils the specified requirements // It blames glfwOpenWindow because that's the only caller //======================================================================== -GLboolean _glfwIsValidContext(_GLFWwindow* window, _GLFWwndconfig* wndconfig) +GLboolean _glfwIsValidContext(_GLFWwndconfig* wndconfig) { + _GLFWwindow* window = _glfwLibrary.currentWindow; + if (window->glMajor < wndconfig->glMajor || (window->glMajor == wndconfig->glMajor && window->glMinor < wndconfig->glMinor)) @@ -434,21 +464,6 @@ GLboolean _glfwIsValidContext(_GLFWwindow* window, _GLFWwndconfig* wndconfig) return GL_FALSE; } - if (window->glMajor > 2) - { - // OpenGL 3.0+ uses a different function for extension string retrieval - // We cache it here instead of in glfwExtensionSupported mostly to alert - // users as early as possible that their build may be broken - - window->GetStringi = (PFNGLGETSTRINGIPROC) glfwGetProcAddress("glGetStringi"); - if (!window->GetStringi) - { - _glfwSetError(GLFW_PLATFORM_ERROR, - "glfwOpenWindow: Entry point retrieval is broken"); - return GL_FALSE; - } - } - return GL_TRUE; } diff --git a/src/window.c b/src/window.c index 919434ec..2e77fa15 100644 --- a/src/window.c +++ b/src/window.c @@ -319,11 +319,17 @@ GLFWAPI GLFWwindow glfwOpenWindow(int width, int height, } // Cache the actual (as opposed to desired) window parameters - glfwMakeContextCurrent(window); - _glfwRefreshContextParams(); _glfwPlatformRefreshWindowParams(); - if (!_glfwIsValidContext(window, &wndconfig)) + glfwMakeContextCurrent(window); + + if (!_glfwRefreshContextParams()) + { + glfwCloseWindow(window); + return GL_FALSE; + } + + if (!_glfwIsValidContext(&wndconfig)) { glfwCloseWindow(window); return GL_FALSE; From 208377d08efd14ec9d4af043b8c840111d909f00 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Thu, 2 Aug 2012 14:48:06 +0200 Subject: [PATCH 21/35] Imported version parsing from EGL branch. --- src/opengl.c | 50 +++++++++++++++++++++----------------------------- 1 file changed, 21 insertions(+), 29 deletions(-) diff --git a/src/opengl.c b/src/opengl.c index 273d2c58..8c28fec9 100644 --- a/src/opengl.c +++ b/src/opengl.c @@ -30,6 +30,7 @@ #include "internal.h" +#include #include #include @@ -40,47 +41,38 @@ static GLboolean parseGLVersion(int* major, int* minor, int* rev) { - GLuint _major, _minor = 0, _rev = 0; - const GLubyte* version; - const GLubyte* ptr; - const char* glesPrefix = "OpenGL ES "; + int i, _major, _minor = 0, _rev = 0; + const char* version; + const char* prefixes[] = + { + "OpenGL ES ", + NULL + }; - version = glGetString(GL_VERSION); + version = (const char*) glGetString(GL_VERSION); if (!version) { _glfwSetError(GLFW_PLATFORM_ERROR, "Failed to retrieve version string"); - return; + return GL_FALSE; } - if (strncmp((const char*) version, glesPrefix, strlen(glesPrefix)) == 0) + for (i = 0; prefixes[i]; i++) { - // The version string on OpenGL ES has a prefix before the version - // number, so we skip past it and then continue as normal + const size_t length = strlen(prefixes[i]); - version += strlen(glesPrefix); - } - - // Parse version from string - - ptr = version; - for (_major = 0; *ptr >= '0' && *ptr <= '9'; ptr++) - _major = 10 * _major + (*ptr - '0'); - - if (*ptr == '.') - { - ptr++; - for (_minor = 0; *ptr >= '0' && *ptr <= '9'; ptr++) - _minor = 10 * _minor + (*ptr - '0'); - - if (*ptr == '.') + if (strncmp(version, prefixes[i], length) == 0) { - ptr++; - for (_rev = 0; *ptr >= '0' && *ptr <= '9'; ptr++) - _rev = 10 * _rev + (*ptr - '0'); + version += length; + break; } } - // Store result + if (!sscanf(version, "%d.%d.%d", &_major, &_minor, &_rev)) + { + _glfwSetError(GLFW_PLATFORM_ERROR, "No version found in version string"); + return GL_FALSE; + } + *major = _major; *minor = _minor; *rev = _rev; From ba941b2fc8255c044465edd672a0e4486bdbda6d Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Thu, 2 Aug 2012 15:13:57 +0200 Subject: [PATCH 22/35] Added formatting to error string. --- src/error.c | 26 ++++++++++++++++++++++++-- src/internal.h | 2 +- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/error.c b/src/error.c index 062fb76a..a1af3917 100644 --- a/src/error.c +++ b/src/error.c @@ -29,6 +29,9 @@ #include "internal.h" +#include +#include + ////////////////////////////////////////////////////////////////////////// ////// GLFW internal API ////// @@ -49,11 +52,30 @@ static GLFWerrorfun _glfwErrorCallback = NULL; // This function may be called without GLFW having been initialized //======================================================================== -void _glfwSetError(int error, const char* description) +void _glfwSetError(int error, const char* format, ...) { if (_glfwErrorCallback) { - if (!description) + char buffer[16384]; + const char* description; + + // We would use vasprintf here if msvcrt supported it + + if (format) + { + int count; + va_list vl; + + va_start(vl, format); + count = vsnprintf(buffer, sizeof(buffer), format, vl); + va_end(vl); + + if (count < 0) + buffer[sizeof(buffer) - 1] = '\0'; + + description = buffer; + } + else description = glfwErrorString(error); _glfwErrorCallback(error, description); diff --git a/src/internal.h b/src/internal.h index fc036bc0..4e18c93c 100644 --- a/src/internal.h +++ b/src/internal.h @@ -338,7 +338,7 @@ void _glfwPlatformCopyContext(_GLFWwindow* src, _GLFWwindow* dst, unsigned long void _glfwSplitBPP(int bpp, int* red, int* green, int* blue); // Error handling (error.c) -void _glfwSetError(int error, const char* description); +void _glfwSetError(int error, const char* format, ...); // Window management (window.c) void _glfwSetDefaultWindowHints(void); From bfc746a8474f3bc40e9d1a1c332831eb9ac82706 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Thu, 2 Aug 2012 15:14:38 +0200 Subject: [PATCH 23/35] Error message grammar fix. --- src/x11_opengl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/x11_opengl.c b/src/x11_opengl.c index 017d660d..3549e573 100644 --- a/src/x11_opengl.c +++ b/src/x11_opengl.c @@ -445,7 +445,7 @@ int _glfwInitOpenGL(void) // Check if GLX is supported on this display if (!glXQueryExtension(_glfwLibrary.X11.display, NULL, NULL)) { - _glfwSetError(GLFW_OPENGL_UNAVAILABLE, "X11/GLX: GLX supported not found"); + _glfwSetError(GLFW_OPENGL_UNAVAILABLE, "X11/GLX: GLX support not found"); return GL_FALSE; } From ee3304c09a1c5ffb39a7ce627d9bc0801e68c710 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Thu, 2 Aug 2012 15:29:13 +0200 Subject: [PATCH 24/35] Removed check for invalid user, added error setting. --- src/opengl.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/opengl.c b/src/opengl.c index 8c28fec9..7c324acb 100644 --- a/src/opengl.c +++ b/src/opengl.c @@ -589,7 +589,6 @@ GLFWAPI int glfwExtensionSupported(const char* extension) { const GLubyte* extensions; _GLFWwindow* window; - GLubyte* where; GLint count; int i; @@ -606,10 +605,11 @@ GLFWAPI int glfwExtensionSupported(const char* extension) return GL_FALSE; } - // Extension names should not have spaces - where = (GLubyte*) strchr(extension, ' '); - if (where || *extension == '\0') + if (extension == NULL || *extension == '\0') + { + _glfwSetError(GLFW_INVALID_VALUE, NULL); return GL_FALSE; + } if (window->glMajor < 3) { From 1bad573c108330f8527f97154c59288455712f72 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Thu, 2 Aug 2012 15:31:08 +0200 Subject: [PATCH 25/35] Tightened scope of some local variables. --- src/opengl.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/opengl.c b/src/opengl.c index 7c324acb..812d1c53 100644 --- a/src/opengl.c +++ b/src/opengl.c @@ -589,8 +589,6 @@ GLFWAPI int glfwExtensionSupported(const char* extension) { const GLubyte* extensions; _GLFWwindow* window; - GLint count; - int i; if (!_glfwInitialized) { @@ -624,6 +622,9 @@ GLFWAPI int glfwExtensionSupported(const char* extension) } else { + int i; + GLint count; + // Check if extension is in the modern OpenGL extensions string list glGetIntegerv(GL_NUM_EXTENSIONS, &count); From a916997c864b1f55e05881ef714670c3155f9c3c Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Thu, 2 Aug 2012 15:32:39 +0200 Subject: [PATCH 26/35] Simplified call to platform-specific extension check. --- src/opengl.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/opengl.c b/src/opengl.c index 812d1c53..01609d86 100644 --- a/src/opengl.c +++ b/src/opengl.c @@ -639,11 +639,8 @@ GLFWAPI int glfwExtensionSupported(const char* extension) } } - // Additional platform specific extension checking (e.g. WGL) - if (_glfwPlatformExtensionSupported(extension)) - return GL_TRUE; - - return GL_FALSE; + // Check if extension is in the platform-specific string + return _glfwPlatformExtensionSupported(extension); } From 957ecdc9a09fee81fc2aeb2723d15efa7a87a90e Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Thu, 2 Aug 2012 15:36:15 +0200 Subject: [PATCH 27/35] Renamed no current context error to match function. --- include/GL/glfw3.h | 2 +- src/error.c | 4 ++-- src/opengl.c | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/GL/glfw3.h b/include/GL/glfw3.h index 693e55f3..fd792e80 100644 --- a/include/GL/glfw3.h +++ b/include/GL/glfw3.h @@ -448,7 +448,7 @@ extern "C" { /* glfwGetError/glfwErrorString tokens */ #define GLFW_NO_ERROR 0 #define GLFW_NOT_INITIALIZED 0x00070001 -#define GLFW_NO_CURRENT_WINDOW 0x00070002 +#define GLFW_NO_CURRENT_CONTEXT 0x00070002 #define GLFW_INVALID_ENUM 0x00070003 #define GLFW_INVALID_VALUE 0x00070004 #define GLFW_OUT_OF_MEMORY 0x00070005 diff --git a/src/error.c b/src/error.c index a1af3917..c7926e9c 100644 --- a/src/error.c +++ b/src/error.c @@ -115,8 +115,8 @@ GLFWAPI const char* glfwErrorString(int error) return "No error"; case GLFW_NOT_INITIALIZED: return "The GLFW library is not initialized"; - case GLFW_NO_CURRENT_WINDOW: - return "There is no current GLFW window"; + case GLFW_NO_CURRENT_CONTEXT: + return "There is no current OpenGL context"; case GLFW_INVALID_ENUM: return "Invalid argument for enum parameter"; case GLFW_INVALID_VALUE: diff --git a/src/opengl.c b/src/opengl.c index 01609d86..59166bfa 100644 --- a/src/opengl.c +++ b/src/opengl.c @@ -551,7 +551,7 @@ GLFWAPI void glfwSwapBuffers(void) if (!_glfwLibrary.currentWindow) { - _glfwSetError(GLFW_NO_CURRENT_WINDOW, NULL); + _glfwSetError(GLFW_NO_CURRENT_CONTEXT, NULL); return; } @@ -573,7 +573,7 @@ GLFWAPI void glfwSwapInterval(int interval) if (!_glfwLibrary.currentWindow) { - _glfwSetError(GLFW_NO_CURRENT_WINDOW, NULL); + _glfwSetError(GLFW_NO_CURRENT_CONTEXT, NULL); return; } @@ -599,7 +599,7 @@ GLFWAPI int glfwExtensionSupported(const char* extension) window = _glfwLibrary.currentWindow; if (!window) { - _glfwSetError(GLFW_NO_CURRENT_WINDOW, NULL); + _glfwSetError(GLFW_NO_CURRENT_CONTEXT, NULL); return GL_FALSE; } @@ -659,7 +659,7 @@ GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname) if (!_glfwLibrary.currentWindow) { - _glfwSetError(GLFW_NO_CURRENT_WINDOW, NULL); + _glfwSetError(GLFW_NO_CURRENT_CONTEXT, NULL); return NULL; } From 287e94cd6be1a796441688062f52bb2742651d16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arturo=20J=2E=20Pe=CC=81rez?= Date: Thu, 2 Aug 2012 17:45:52 +0200 Subject: [PATCH 28/35] Behavior differences under Lion and Snow Leopard in updateTrackingAreas. super call added. According to documentation (NSView Class Reference -> Instance Methods -> updateTrackingAreas): You should override this method to remove out of date tracking areas and add recomputed tracking areas; your implementation should call super. --- src/cocoa_window.m | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 6e4d4270..74f187b0 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -425,6 +425,7 @@ static int convertMacKeyCode(unsigned int macKeyCode) userInfo:nil]; [self addTrackingArea:trackingArea]; + [super updateTrackingAreas]; } - (void)keyDown:(NSEvent *)event From 871e1a70d78b52f7b96d9f2165e41aea9689832d Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Thu, 2 Aug 2012 18:03:43 +0200 Subject: [PATCH 29/35] Made video mode retrieval dynamic. --- include/GL/glfw3.h | 2 +- readme.html | 1 + src/cocoa_fullscreen.m | 18 ++-- src/fullscreen.c | 39 ++++----- src/init.c | 3 + src/internal.h | 5 +- src/win32_fullscreen.c | 119 ++++++++++++++------------- src/x11_fullscreen.c | 181 +++++++++++++++++++++-------------------- tests/modes.c | 26 +----- 9 files changed, 201 insertions(+), 193 deletions(-) diff --git a/include/GL/glfw3.h b/include/GL/glfw3.h index fd792e80..19759cb9 100644 --- a/include/GL/glfw3.h +++ b/include/GL/glfw3.h @@ -520,7 +520,7 @@ GLFWAPI const char* glfwErrorString(int error); GLFWAPI void glfwSetErrorCallback(GLFWerrorfun cbfun); /* Video mode functions */ -GLFWAPI int glfwGetVideoModes(GLFWvidmode* list, int maxcount); +GLFWAPI GLFWvidmode* glfwGetVideoModes(int* count); GLFWAPI void glfwGetDesktopMode(GLFWvidmode* mode); /* Gamma ramp functions */ diff --git a/readme.html b/readme.html index e5fa8c9d..ad62d559 100644 --- a/readme.html +++ b/readme.html @@ -294,6 +294,7 @@ version of GLFW.

  • Changed buffer bit depth parameters of glfwOpenWindow to window hints
  • Changed glfwOpenWindow and glfwSetWindowTitle to use UTF-8 encoded strings
  • Changed glfwGetProcAddress to return a (generic) function pointer
  • +
  • Changed glfwGetVideoModes to return a dynamic, unlimited number of video modes
  • Renamed glfw.h to glfw3.h to avoid conflicts with 2.x series
  • Renamed GLFW_WINDOW token to GLFW_WINDOWED
  • Renamed GLFW_WINDOW_NO_RESIZE to GLFW_WINDOW_RESIZABLE
  • diff --git a/src/cocoa_fullscreen.m b/src/cocoa_fullscreen.m index 147913fb..e02cb2f2 100644 --- a/src/cocoa_fullscreen.m +++ b/src/cocoa_fullscreen.m @@ -197,25 +197,31 @@ void _glfwRestoreVideoMode(void) // Get a list of available video modes //======================================================================== -int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount) +GLFWvidmode* _glfwPlatformGetVideoModes(int* found) { - CGDisplayModeRef mode; CFArrayRef modes; CFIndex count, i; - int stored = 0; + GLFWvidmode* result; modes = CGDisplayCopyAllDisplayModes(CGMainDisplayID(), NULL); count = CFArrayGetCount(modes); - for (i = 0; i < count && stored < maxcount; i++) + result = (GLFWvidmode*) malloc(sizeof(GLFWvidmode) * count); + + for (i = 0; i < count; i++) { + CGDisplayModeRef mode; + mode = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i); if (modeIsGood(mode)) - list[stored++] = vidmodeFromCGDisplayMode(mode); + { + result[*found] vidmodeFromCGDisplayMode(mode); + (*found)++; + } } CFRelease(modes); - return stored; + return result; } diff --git a/src/fullscreen.c b/src/fullscreen.c index 631f6193..d613ab7e 100644 --- a/src/fullscreen.c +++ b/src/fullscreen.c @@ -68,6 +68,16 @@ static int compareVideoModes(const void* firstPtr, const void* secondPtr) ////// GLFW internal API ////// ////////////////////////////////////////////////////////////////////////// +//======================================================================== +// Lexical comparison of GLFW video modes +//======================================================================== + +int _glfwCompareVideoModes(const GLFWvidmode* first, const GLFWvidmode* second) +{ + return compareVideoModes(first, second); +} + + //======================================================================== // Convert BPP to RGB bits based on "best guess" //======================================================================== @@ -100,36 +110,27 @@ void _glfwSplitBPP(int bpp, int* red, int* green, int* blue) // Get a list of available video modes //======================================================================== -GLFWAPI int glfwGetVideoModes(GLFWvidmode* list, int maxcount) +GLFWAPI GLFWvidmode* glfwGetVideoModes(int* count) { - int count; - if (!_glfwInitialized) { _glfwSetError(GLFW_NOT_INITIALIZED, NULL); - return 0; + return NULL; } - if (maxcount <= 0) + if (count == NULL) { - _glfwSetError(GLFW_INVALID_VALUE, - "glfwGetVideoModes: Parameter 'maxcount' must be " - "greater than zero"); - return 0; + _glfwSetError(GLFW_INVALID_VALUE, NULL); + return NULL; } - if (list == NULL) - { - _glfwSetError(GLFW_INVALID_VALUE, - "glfwGetVideoModes: Parameter 'list' cannot be NULL"); - return 0; - } + free(_glfwLibrary.modes); - count = _glfwPlatformGetVideoModes(list, maxcount); - if (count > 0) - qsort(list, count, sizeof(GLFWvidmode), compareVideoModes); + _glfwLibrary.modes = _glfwPlatformGetVideoModes(count); + if (_glfwLibrary.modes) + qsort(_glfwLibrary.modes, *count, sizeof(GLFWvidmode), compareVideoModes); - return count; + return _glfwLibrary.modes; } diff --git a/src/init.c b/src/init.c index 336cfe25..eab5869f 100644 --- a/src/init.c +++ b/src/init.c @@ -84,6 +84,9 @@ GLFWAPI void glfwTerminate(void) if (!_glfwPlatformTerminate()) return; + if (_glfwLibrary.modes) + free(_glfwLibrary.modes); + _glfwInitialized = GL_FALSE; } diff --git a/src/internal.h b/src/internal.h index 4e18c93c..99d74b86 100644 --- a/src/internal.h +++ b/src/internal.h @@ -251,6 +251,8 @@ struct _GLFWlibrary int originalRampSize; GLboolean rampChanged; + GLFWvidmode* modes; + // This is defined in the current port's platform.h _GLFW_PLATFORM_LIBRARY_WINDOW_STATE; _GLFW_PLATFORM_LIBRARY_OPENGL_STATE; @@ -287,7 +289,7 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, int x, int y); void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode); // Fullscreen -int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount); +GLFWvidmode* _glfwPlatformGetVideoModes(int* count); void _glfwPlatformGetDesktopMode(GLFWvidmode* mode); // Gamma ramp @@ -335,6 +337,7 @@ void _glfwPlatformCopyContext(_GLFWwindow* src, _GLFWwindow* dst, unsigned long //======================================================================== // Fullscren management (fullscreen.c) +int _glfwCompareVideoModes(const GLFWvidmode* first, const GLFWvidmode* second); void _glfwSplitBPP(int bpp, int* red, int* green, int* blue); // Error handling (error.c) diff --git a/src/win32_fullscreen.c b/src/win32_fullscreen.c index de3d898b..c04e5ff1 100644 --- a/src/win32_fullscreen.c +++ b/src/win32_fullscreen.c @@ -182,71 +182,78 @@ void _glfwRestoreVideoMode(void) // Get a list of available video modes //======================================================================== -int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount) +GLFWvidmode* _glfwPlatformGetVideoModes(int* found) { - int count, success, mode, i, j; - int m1, m2, bpp, r, g, b; - DEVMODE dm; + int dmIndex = 0, count = 0; + GLFWvidmode* result = NULL; - // Loop through all video modes and extract all the UNIQUE modes - count = 0; - mode = 0; + *found = 0; - do + for (;;) { - // Get video mode properties + int i; + GLFWvidmode mode; + DEVMODE dm; + + ZeroMemory(&dm, sizeof(DEVMODE)); dm.dmSize = sizeof(DEVMODE); - success = EnumDisplaySettings(NULL, mode, &dm); - // Is it a valid mode? (only list depths >= 15 bpp) - if (success && dm.dmBitsPerPel >= 15) + if (!EnumDisplaySettings(NULL, dmIndex, &dm)) + break; + + dmIndex++; + + if (dm.dmBitsPerPel < 15) { - // Convert to RGB, and back to bpp ("mask out" alpha bits etc) - _glfwSplitBPP(dm.dmBitsPerPel, &r, &g, &b); - bpp = r + g + b; - - // Mode "code" for this mode - m1 = (bpp << 25) | (dm.dmPelsWidth * dm.dmPelsHeight); - - // Insert mode in list (sorted), and avoid duplicates - for (i = 0; i < count; i++) - { - // Mode "code" for already listed mode - bpp = list[i].redBits + list[i].greenBits + list[i].blueBits; - m2 = (bpp << 25) | (list[i].width * list[i].height); - if (m1 <= m2) - break; - } - - // New entry at the end of the list? - if (i >= count) - { - list[count].width = dm.dmPelsWidth; - list[count].height = dm.dmPelsHeight; - list[count].redBits = r; - list[count].greenBits = g; - list[count].blueBits = b; - count ++; - } - // Insert new entry in the list? - else if (m1 < m2) - { - for (j = count; j > i; j--) - list[j] = list[j - 1]; - - list[i].width = dm.dmPelsWidth; - list[i].height = dm.dmPelsHeight; - list[i].redBits = r; - list[i].greenBits = g; - list[i].blueBits = b; - count++; - } + // Skip modes with less than 15 BPP + continue; } - mode++; - } - while (success && (count < maxcount)); - return count; + mode.width = dm.dmPelsWidth; + mode.height = dm.dmPelsHeight; + _glfwSplitBPP(dm.dmBitsPerPel, + &mode.redBits, + &mode.greenBits, + &mode.blueBits); + + for (i = 0; i < *found; i++) + { + if (_glfwCompareVideoModes(result + i, &mode) == 0) + break; + } + + if (i < *found) + { + // This is a duplicate, so skip it + continue; + } + + if (*found == count) + { + void* larger; + + if (count) + count *= 2; + else + count = 128; + + larger = realloc(result, count * sizeof(GLFWvidmode)); + if (!larger) + { + free(result); + + _glfwSetError(GLFW_OUT_OF_MEMORY, NULL); + return NULL; + } + + result = (GLFWvidmode*) larger; + } + + result[*found] = mode; + (*found)++; + } + + return result; } diff --git a/src/x11_fullscreen.c b/src/x11_fullscreen.c index 7ad11ec5..34beae6a 100644 --- a/src/x11_fullscreen.c +++ b/src/x11_fullscreen.c @@ -32,6 +32,7 @@ #include #include +#include ////////////////////////////////////////////////////////////////////////// @@ -325,92 +326,94 @@ void _glfwRestoreVideoMode(void) ////// GLFW platform API ////// ////////////////////////////////////////////////////////////////////////// -struct _glfwResolution +typedef struct { int width; int height; -}; +} _GLFWvidsize; + //======================================================================== // List available video modes //======================================================================== -int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount) +GLFWvidmode* _glfwPlatformGetVideoModes(int* found) { - int count, k, l, r, g, b, rgba, gl; - int depth; - XVisualInfo* vislist; + XVisualInfo* visuals; XVisualInfo dummy; - int viscount, rgbcount, rescount; - int* rgbarray; - struct _glfwResolution* resarray; + int i, j, visualCount, sizeCount, rgbCount; + int* rgbs; + _GLFWvidsize* sizes; + GLFWvidmode* result; - // Get list of visuals - vislist = XGetVisualInfo(_glfwLibrary.X11.display, 0, &dummy, &viscount); - if (vislist == NULL) + visuals = XGetVisualInfo(_glfwLibrary.X11.display, 0, &dummy, &visualCount); + if (visuals == NULL) { _glfwSetError(GLFW_PLATFORM_ERROR, "X11/GLX: Failed to retrieve the available visuals"); return 0; } - rgbarray = (int*) malloc(sizeof(int) * viscount); - rgbcount = 0; + // Build array of available RGB channel depths - // Build RGB array - for (k = 0; k < viscount; k++) + rgbs = (int*) malloc(sizeof(int) * visualCount); + rgbCount = 0; + + for (i = 0; i < visualCount; i++) { - // Does the visual support OpenGL & true color? - glXGetConfig(_glfwLibrary.X11.display, &vislist[k], GLX_USE_GL, &gl); - glXGetConfig(_glfwLibrary.X11.display, &vislist[k], GLX_RGBA, &rgba); - if (gl && rgba) + int gl, rgba, rgb, r, g, b; + + glXGetConfig(_glfwLibrary.X11.display, &visuals[i], GLX_USE_GL, &gl); + glXGetConfig(_glfwLibrary.X11.display, &visuals[i], GLX_RGBA, &rgba); + + if (!gl || !rgba) { - // Get color depth for this visual - depth = vislist[k].depth; - - // Convert to RGB - _glfwSplitBPP(depth, &r, &g, &b); - depth = (r << 16) | (g << 8) | b; - - // Is this mode unique? - for (l = 0; l < rgbcount; l++) - { - if (depth == rgbarray[l]) - break; - } - - if (l >= rgbcount) - { - rgbarray[rgbcount] = depth; - rgbcount++; - } + // The visual lacks OpenGL or true color, so skip it + continue; } + + // Convert to RGB channel depths and encode + _glfwSplitBPP(visuals[i].depth, &r, &g, &b); + rgb = (r << 16) | (g << 8) | b; + + for (j = 0; j < rgbCount; j++) + { + if (rgbs[j] == rgb) + break; + } + + if (j < rgbCount) + { + // This channel depth is a duplicate, so skip it + continue; + } + + rgbs[rgbCount] = rgb; + rgbCount++; } - XFree(vislist); + XFree(visuals); - rescount = 0; - resarray = NULL; + sizeCount = 0; + sizes = NULL; - // Build resolution array + // Build array of available resolutions if (_glfwLibrary.X11.RandR.available) { #if defined(_GLFW_HAS_XRANDR) XRRScreenConfiguration* sc; - XRRScreenSize* sizelist; - int sizecount; + XRRScreenSize* rrSizes; sc = XRRGetScreenInfo(_glfwLibrary.X11.display, _glfwLibrary.X11.root); - sizelist = XRRConfigSizes(sc, &sizecount); + rrSizes = XRRConfigSizes(sc, &sizeCount); - resarray = (struct _glfwResolution*) malloc(sizeof(struct _glfwResolution) * sizecount); + sizes = (_GLFWvidsize*) malloc(sizeof(_GLFWvidsize) * sizeCount); - for (k = 0; k < sizecount; k++) + for (i = 0; i < sizeCount; i++) { - resarray[rescount].width = sizelist[k].width; - resarray[rescount].height = sizelist[k].height; - rescount++; + sizes[i].width = rrSizes[i].width; + sizes[i].height = rrSizes[i].height; } XRRFreeScreenConfigInfo(sc); @@ -419,69 +422,75 @@ int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount) else if (_glfwLibrary.X11.VidMode.available) { #if defined(_GLFW_HAS_XF86VIDMODE) - XF86VidModeModeInfo** modelist; - int modecount, width, height; + XF86VidModeModeInfo** modes; + int modeCount; XF86VidModeGetAllModeLines(_glfwLibrary.X11.display, _glfwLibrary.X11.screen, - &modecount, &modelist); + &modeCount, &modes); - resarray = (struct _glfwResolution*) malloc(sizeof(struct _glfwResolution) * modecount); + sizes = (_GLFWvidsize*) malloc(sizeof(_GLFWvidsize) * modeCount); - for (k = 0; k < modecount; k++) + for (i = 0; i < modeCount; i++) { - width = modelist[k]->hdisplay; - height = modelist[k]->vdisplay; + _GLFWvidsize size; + size.width = modes[i]->hdisplay; + size.height = modes[i]->vdisplay; - // Is this mode unique? - for (l = 0; l < rescount; l++) + for (j = 0; j < sizeCount; j++) { - if (width == resarray[l].width && height == resarray[l].height) + if (memcmp(sizes + j, &size, sizeof(_GLFWvidsize)) == 0) break; } - if (l >= rescount) + if (j < sizeCount) { - resarray[rescount].width = width; - resarray[rescount].height = height; - rescount++; + // This size is a duplicate, so skip it + continue; } + + sizes[sizeCount] = size; + sizeCount++; } - XFree(modelist); + XFree(modes); #endif /*_GLFW_HAS_XF86VIDMODE*/ } - if (!resarray) + if (!sizeCount) { - rescount = 1; - resarray = (struct _glfwResolution*) malloc(sizeof(struct _glfwResolution) * rescount); + sizeCount = 1; + sizes = (_GLFWvidsize*) malloc(sizeof(_GLFWvidsize)); - resarray[0].width = DisplayWidth(_glfwLibrary.X11.display, - _glfwLibrary.X11.screen); - resarray[0].height = DisplayHeight(_glfwLibrary.X11.display, - _glfwLibrary.X11.screen); + sizes[0].width = DisplayWidth(_glfwLibrary.X11.display, + _glfwLibrary.X11.screen); + sizes[0].height = DisplayHeight(_glfwLibrary.X11.display, + _glfwLibrary.X11.screen); } - // Build permutations of colors and resolutions - count = 0; - for (k = 0; k < rgbcount && count < maxcount; k++) + // Build all permutations of channel depths and resolutions + + result = (GLFWvidmode*) malloc(sizeof(GLFWvidmode) * rgbCount * sizeCount); + *found = 0; + + for (i = 0; i < rgbCount; i++) { - for (l = 0; l < rescount && count < maxcount; l++) + for (j = 0; j < sizeCount; j++) { - list[count].width = resarray[l].width; - list[count].height = resarray[l].height; - list[count].redBits = (rgbarray[k] >> 16) & 255; - list[count].greenBits = (rgbarray[k] >> 8) & 255; - list[count].blueBits = rgbarray[k] & 255; - count++; + result[*found].width = sizes[j].width; + result[*found].height = sizes[j].height; + result[*found].redBits = (rgbs[i] >> 16) & 255; + result[*found].greenBits = (rgbs[i] >> 8) & 255; + result[*found].blueBits = rgbs[i] & 255; + + (*found)++; } } - free(resarray); - free(rgbarray); + free(sizes); + free(rgbs); - return count; + return result; } diff --git a/tests/modes.c b/tests/modes.c index 3a384003..0f2452c7 100644 --- a/tests/modes.c +++ b/tests/modes.c @@ -90,29 +90,11 @@ static void key_callback(GLFWwindow dummy, int key, int action) } } -static GLFWvidmode* get_video_modes(size_t* found) -{ - size_t count = 0; - GLFWvidmode* modes = NULL; - - for (;;) - { - count += 256; - modes = realloc(modes, sizeof(GLFWvidmode) * count); - - *found = glfwGetVideoModes(modes, count); - if (*found < count) - break; - } - - return modes; -} - static void list_modes(void) { size_t count, i; GLFWvidmode desktop_mode; - GLFWvidmode* modes = get_video_modes(&count); + GLFWvidmode* modes = glfwGetVideoModes(&count); glfwGetDesktopMode(&desktop_mode); printf("Desktop mode: %s\n", format_mode(&desktop_mode)); @@ -128,15 +110,13 @@ static void list_modes(void) putchar('\n'); } - - free(modes); } static void test_modes(void) { int width, height; size_t i, count; - GLFWvidmode* modes = get_video_modes(&count); + GLFWvidmode* modes = glfwGetVideoModes(&count); glfwSetWindowSizeCallback(window_size_callback); glfwSetWindowCloseCallback(window_close_callback); @@ -207,8 +187,6 @@ static void test_modes(void) glfwPollEvents(); window = NULL; } - - free(modes); } int main(int argc, char** argv) From 88fd170e646c0b548ba65d9591da1ca2dc1993e9 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Thu, 2 Aug 2012 18:22:11 +0200 Subject: [PATCH 30/35] Fixed type errors in modes test. --- tests/modes.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/modes.c b/tests/modes.c index 0f2452c7..6d262ef3 100644 --- a/tests/modes.c +++ b/tests/modes.c @@ -92,7 +92,7 @@ static void key_callback(GLFWwindow dummy, int key, int action) static void list_modes(void) { - size_t count, i; + int count, i; GLFWvidmode desktop_mode; GLFWvidmode* modes = glfwGetVideoModes(&count); @@ -114,8 +114,7 @@ static void list_modes(void) static void test_modes(void) { - int width, height; - size_t i, count; + int i, count, width, height; GLFWvidmode* modes = glfwGetVideoModes(&count); glfwSetWindowSizeCallback(window_size_callback); From b03e62f6ace5ab1d2e2d6bb9c6085288044aa8c2 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Thu, 2 Aug 2012 18:54:10 +0200 Subject: [PATCH 31/35] Made X11 resolution enumeration a separate function. --- src/x11_fullscreen.c | 180 ++++++++++++++++++++++++------------------- 1 file changed, 100 insertions(+), 80 deletions(-) diff --git a/src/x11_fullscreen.c b/src/x11_fullscreen.c index 34beae6a..8c4138d3 100644 --- a/src/x11_fullscreen.c +++ b/src/x11_fullscreen.c @@ -35,6 +35,104 @@ #include +//------------------------------------------------------------------------ +// Display resolution +//------------------------------------------------------------------------ + +typedef struct +{ + int width; + int height; +} _GLFWvidsize; + + +//======================================================================== +// List available resolutions +//======================================================================== + +static _GLFWvidsize* getResolutions(int* found) +{ + int i, j; + _GLFWvidsize* result = NULL; + + *found = 0; + + // Build array of available resolutions + + if (_glfwLibrary.X11.RandR.available) + { +#if defined(_GLFW_HAS_XRANDR) + XRRScreenConfiguration* sc; + XRRScreenSize* sizes; + + sc = XRRGetScreenInfo(_glfwLibrary.X11.display, _glfwLibrary.X11.root); + sizes = XRRConfigSizes(sc, found); + + result = (_GLFWvidsize*) malloc(sizeof(_GLFWvidsize) * *found); + + for (i = 0; i < *found; i++) + { + result[i].width = sizes[i].width; + result[i].height = sizes[i].height; + } + + XRRFreeScreenConfigInfo(sc); +#endif /*_GLFW_HAS_XRANDR*/ + } + else if (_glfwLibrary.X11.VidMode.available) + { +#if defined(_GLFW_HAS_XF86VIDMODE) + XF86VidModeModeInfo** modes; + int modeCount; + + XF86VidModeGetAllModeLines(_glfwLibrary.X11.display, + _glfwLibrary.X11.screen, + &modeCount, &modes); + + result = (_GLFWvidsize*) malloc(sizeof(_GLFWvidsize) * modeCount); + + for (i = 0; i < modeCount; i++) + { + _GLFWvidsize size; + size.width = modes[i]->hdisplay; + size.height = modes[i]->vdisplay; + + for (j = 0; j < *found; j++) + { + if (memcmp(result + j, &size, sizeof(_GLFWvidsize)) == 0) + break; + } + + if (j < *found) + { + // This size is a duplicate, so skip it + continue; + } + + result[*found] = size; + (*found)++; + } + + XFree(modes); +#endif /*_GLFW_HAS_XF86VIDMODE*/ + } + + if (result == NULL) + { + *found = 1; + result = (_GLFWvidsize*) malloc(sizeof(_GLFWvidsize)); + + result[0].width = DisplayWidth(_glfwLibrary.X11.display, + _glfwLibrary.X11.screen); + result[0].height = DisplayHeight(_glfwLibrary.X11.display, + _glfwLibrary.X11.screen); + } + + return result; +} + + + ////////////////////////////////////////////////////////////////////////// ////// GLFW internal API ////// ////////////////////////////////////////////////////////////////////////// @@ -326,12 +424,6 @@ void _glfwRestoreVideoMode(void) ////// GLFW platform API ////// ////////////////////////////////////////////////////////////////////////// -typedef struct -{ - int width; - int height; -} _GLFWvidsize; - //======================================================================== // List available video modes @@ -394,82 +486,10 @@ GLFWvidmode* _glfwPlatformGetVideoModes(int* found) XFree(visuals); - sizeCount = 0; - sizes = NULL; - - // Build array of available resolutions - - if (_glfwLibrary.X11.RandR.available) - { -#if defined(_GLFW_HAS_XRANDR) - XRRScreenConfiguration* sc; - XRRScreenSize* rrSizes; - - sc = XRRGetScreenInfo(_glfwLibrary.X11.display, _glfwLibrary.X11.root); - rrSizes = XRRConfigSizes(sc, &sizeCount); - - sizes = (_GLFWvidsize*) malloc(sizeof(_GLFWvidsize) * sizeCount); - - for (i = 0; i < sizeCount; i++) - { - sizes[i].width = rrSizes[i].width; - sizes[i].height = rrSizes[i].height; - } - - XRRFreeScreenConfigInfo(sc); -#endif /*_GLFW_HAS_XRANDR*/ - } - else if (_glfwLibrary.X11.VidMode.available) - { -#if defined(_GLFW_HAS_XF86VIDMODE) - XF86VidModeModeInfo** modes; - int modeCount; - - XF86VidModeGetAllModeLines(_glfwLibrary.X11.display, - _glfwLibrary.X11.screen, - &modeCount, &modes); - - sizes = (_GLFWvidsize*) malloc(sizeof(_GLFWvidsize) * modeCount); - - for (i = 0; i < modeCount; i++) - { - _GLFWvidsize size; - size.width = modes[i]->hdisplay; - size.height = modes[i]->vdisplay; - - for (j = 0; j < sizeCount; j++) - { - if (memcmp(sizes + j, &size, sizeof(_GLFWvidsize)) == 0) - break; - } - - if (j < sizeCount) - { - // This size is a duplicate, so skip it - continue; - } - - sizes[sizeCount] = size; - sizeCount++; - } - - XFree(modes); -#endif /*_GLFW_HAS_XF86VIDMODE*/ - } - - if (!sizeCount) - { - sizeCount = 1; - sizes = (_GLFWvidsize*) malloc(sizeof(_GLFWvidsize)); - - sizes[0].width = DisplayWidth(_glfwLibrary.X11.display, - _glfwLibrary.X11.screen); - sizes[0].height = DisplayHeight(_glfwLibrary.X11.display, - _glfwLibrary.X11.screen); - } - // Build all permutations of channel depths and resolutions + sizes = getResolutions(&sizeCount); + result = (GLFWvidmode*) malloc(sizeof(GLFWvidmode) * rgbCount * sizeCount); *found = 0; From ae586e65d80adf88b09c5b7b7605381514e19624 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Thu, 2 Aug 2012 19:14:58 +0200 Subject: [PATCH 32/35] Fixed typo. --- src/cocoa_fullscreen.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cocoa_fullscreen.m b/src/cocoa_fullscreen.m index e02cb2f2..bf58a930 100644 --- a/src/cocoa_fullscreen.m +++ b/src/cocoa_fullscreen.m @@ -215,7 +215,7 @@ GLFWvidmode* _glfwPlatformGetVideoModes(int* found) mode = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i); if (modeIsGood(mode)) { - result[*found] vidmodeFromCGDisplayMode(mode); + result[*found] = vidmodeFromCGDisplayMode(mode); (*found)++; } } From 5f5b463766a05e33ab93311682f302bd91318fda Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Thu, 2 Aug 2012 19:24:12 +0200 Subject: [PATCH 33/35] Added credit. --- readme.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/readme.html b/readme.html index ad62d559..12f73f3c 100644 --- a/readme.html +++ b/readme.html @@ -920,6 +920,9 @@ their skills. Special thanks go out to:

    Much of the Windows code of GLFW was originally based on Jeff's code +
  • Arturo J. PĂ©rez, for a bug fix for cursor tracking on Mac OS X 10.6 Snow + Leopard
  • +
  • Douglas C. Schmidt and Irfan Pyarali, for their excellent article Strategies for Implementing POSIX Condition Variables on Win32
  • From 4b9e616cf8dd2b9f020038df14be3c7b0722d37c Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Thu, 2 Aug 2012 19:26:00 +0200 Subject: [PATCH 34/35] Fixed indexing bug in Cocoa video mode enumeration. --- src/cocoa_fullscreen.m | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cocoa_fullscreen.m b/src/cocoa_fullscreen.m index bf58a930..9382993b 100644 --- a/src/cocoa_fullscreen.m +++ b/src/cocoa_fullscreen.m @@ -207,6 +207,7 @@ GLFWvidmode* _glfwPlatformGetVideoModes(int* found) count = CFArrayGetCount(modes); result = (GLFWvidmode*) malloc(sizeof(GLFWvidmode) * count); + *found = 0; for (i = 0; i < count; i++) { From 3c912cbc3c754874fe3e3eeb7e78f3dae1cb328d Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Thu, 2 Aug 2012 21:25:00 +0200 Subject: [PATCH 35/35] Replaced declaration of wchar_t with stddef.h header. --- include/GL/glfw3.h | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/include/GL/glfw3.h b/include/GL/glfw3.h index 19759cb9..7a47f86e 100644 --- a/include/GL/glfw3.h +++ b/include/GL/glfw3.h @@ -71,7 +71,6 @@ extern "C" { */ #if __MINGW64__ #define WINAPI -#include #endif /* The following three defines are here solely to make some Windows-based @@ -110,11 +109,10 @@ extern "C" { #define GLFW_CALLBACK_DEFINED #endif /* CALLBACK */ -/* Microsoft Visual C++, Borland C++ and Pelles C needs wchar_t */ -#if defined(_WIN32) && (defined(_MSC_VER) || defined(__BORLANDC__) || defined(__POCC__)) && !defined(_WCHAR_T_DEFINED) - typedef unsigned short wchar_t; - #define _WCHAR_T_DEFINED -#endif /* _WCHAR_T_DEFINED */ +/* Most variants on Windows need wchar_t */ +#if defined(_WIN32) + #include +#endif /* ---------------- GLFW related system specific defines ----------------- */