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: diff --git a/CMakeLists.txt b/CMakeLists.txt index b80ac24e..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 #-------------------------------------------------------------------- @@ -242,7 +252,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}) @@ -251,10 +261,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/include/GL/glfw3.h b/include/GL/glfw3.h index b7ea88c5..6811d9b5 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 ----------------- */ @@ -390,7 +388,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 @@ -449,7 +446,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 @@ -546,7 +543,7 @@ GLFWAPI const char* glfwGetMonitorString(GLFWmonitor monitor, int param); GLFWAPI GLFWmonitor glfwGetNextMonitor(GLFWmonitor iterator); /* Video mode functions */ -GLFWAPI int glfwGetVideoModes(GLFWmonitor monitor, GLFWvidmode* list, int maxcount); +GLFWAPI GLFWvidmode* glfwGetVideoModes(GLFWmonitor monitor, int* count); GLFWAPI void glfwGetDesktopMode(GLFWvidmode* mode); /* Gamma ramp functions */ 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 789ac5ff..f399f752 100644 --- a/readme.html +++ b/readme.html @@ -287,12 +287,14 @@ 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
  • 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
  • @@ -317,6 +319,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
  • @@ -847,6 +850,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
  • @@ -917,6 +923,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
  • diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ee9241a7..7822c56b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -11,27 +11,33 @@ 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) elseif (_GLFW_WIN32_WGL) set(glfw_HEADERS ${common_HEADERS} win32_platform.h) - set(glfw_SOURCES ${common_SOURCES} win32_clipboard.c win32_dllmain.c - win32_fullscreen.c win32_gamma.c win32_init.c win32_input.c - win32_joystick.c win32_monitor.c win32_opengl.c - win32_time.c win32_window.c) + set(glfw_SOURCES ${common_SOURCES} win32_clipboard.c win32_fullscreen.c + win32_gamma.c win32_init.c win32_input.c win32_joystick.c + win32_monitor.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_monitor.c x11_opengl.c x11_time.c - x11_window.c) + x11_keysym2unicode.c x11_monitor.c x11_native.c + x11_opengl.c x11_time.c x11_window.c) endif() add_library(glfw ${glfw_SOURCES} ${glfw_HEADERS}) +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/cocoa_fullscreen.m b/src/cocoa_fullscreen.m index 147913fb..9382993b 100644 --- a/src/cocoa_fullscreen.m +++ b/src/cocoa_fullscreen.m @@ -197,25 +197,32 @@ 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); + *found = 0; + + 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/cocoa_native.m b/src/cocoa_native.m new file mode 100644 index 00000000..be8aac4b --- /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 handle) +{ + _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 handle) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + + if (!_glfwInitialized) + { + _glfwSetError(GLFW_NOT_INITIALIZED, NULL); + return NULL; + } + + return window->NSGL.context; +} + diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 3523806a..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 @@ -1042,72 +1043,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:NSOpenGLPFAAccelerated - forVirtualScreen:0]; - window->accelerated = value; - - [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; - - // These this is forced to false as long as Mac OS X lacks support for - // requesting debug contexts - window->glDebug = GL_FALSE; } @@ -1163,7 +1098,7 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, int x, int y) { if (window->mode == GLFW_FULLSCREEN) { - NSPoint globalPoint = NSMakePoint(x, y); + CGPoint globalPoint = CGPointMake(x, y); CGDisplayMoveCursorToPoint(CGMainDisplayID(), globalPoint); } else diff --git a/src/error.c b/src/error.c index 062fb76a..c7926e9c 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); @@ -93,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/fullscreen.c b/src/fullscreen.c index 011e1924..08ac9572 100644 --- a/src/fullscreen.c +++ b/src/fullscreen.c @@ -37,7 +37,7 @@ // Lexical comparison function for GLFW video modes, used by qsort //======================================================================== -int _glfwCompareVideoModes(const void* firstPtr, const void* secondPtr) +int compareVideoModes(const void* firstPtr, const void* secondPtr) { int firstBPP, secondBPP, firstSize, secondSize; GLFWvidmode* first = (GLFWvidmode*) firstPtr; @@ -68,6 +68,16 @@ int _glfwCompareVideoModes(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,15 +110,14 @@ void _glfwSplitBPP(int bpp, int* red, int* green, int* blue) // Get a list of available video modes //======================================================================== -GLFWAPI int glfwGetVideoModes(GLFWmonitor handle, GLFWvidmode* list, int maxcount) +GLFWAPI GLFWvidmode* glfwGetVideoModes(GLFWmonitor handle, int* count) { - int count; _GLFWmonitor* monitor = (_GLFWmonitor*) handle; if (!_glfwInitialized) { _glfwSetError(GLFW_NOT_INITIALIZED, NULL); - return 0; + return NULL; } if (monitor == NULL) @@ -118,26 +127,19 @@ GLFWAPI int glfwGetVideoModes(GLFWmonitor handle, GLFWvidmode* list, int maxcoun return 0; } - 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(monitor->modes); - count = _glfwPlatformGetVideoModes(monitor, list, maxcount); - if (count > 0) - qsort(list, count, sizeof(GLFWvidmode), _glfwCompareVideoModes); + monitor->modes = _glfwPlatformGetVideoModes(monitor, count); + if (monitor->modes) + qsort(monitor->modes, *count, sizeof(GLFWvidmode), compareVideoModes); - return count; + return monitor->modes; } diff --git a/src/internal.h b/src/internal.h index ccb7f402..66f413ba 100755 --- a/src/internal.h +++ b/src/internal.h @@ -197,22 +197,21 @@ 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 - GLboolean accelerated; // GL_TRUE if OpenGL context is "accelerated" int glMajor, glMinor, glRevision; GLboolean glForward, glDebug; int glProfile; @@ -242,6 +241,8 @@ struct _GLFWmonitor int screenX; int screenY; + GLFWvidmode* modes; + // These are defined in the current port's platform.h _GLFW_PLATFORM_MONITOR_STATE; }; @@ -313,7 +314,7 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, int x, int y); void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode); // Fullscreen -int _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, GLFWvidmode* list, int maxcount); +GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count); void _glfwPlatformGetDesktopMode(GLFWvidmode* mode); // Gamma ramp @@ -361,11 +362,11 @@ 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); -int _glfwCompareVideoModes(const void* firstPtr, const void* secondPtr); // 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); @@ -390,8 +391,9 @@ int _glfwStringInExtensionString(const char* string, const GLubyte* extensions); const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired, const _GLFWfbconfig* alternatives, unsigned int count); +GLboolean _glfwRefreshContextParams(void); GLboolean _glfwIsValidContextConfig(_GLFWwndconfig* wndconfig); -GLboolean _glfwIsValidContext(_GLFWwindow* window, _GLFWwndconfig* wndconfig); +GLboolean _glfwIsValidContext(_GLFWwndconfig* wndconfig); // Monitor management (monitor.c) void _glfwInitMonitors(void); diff --git a/src/libglfw.pc.in b/src/libglfw3.pc.in similarity index 89% rename from src/libglfw.pc.in rename to src/libglfw3.pc.in index be6275aa..175c902d 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} -l@GLFW_LIB_NAME@ Libs.private: @GLFW_PKG_LIBS@ Cflags: -I${includedir} diff --git a/src/opengl.c b/src/opengl.c index 67b5e728..59166bfa 100644 --- a/src/opengl.c +++ b/src/opengl.c @@ -30,6 +30,7 @@ #include "internal.h" +#include #include #include @@ -38,49 +39,45 @@ // 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; - const GLubyte* ptr; - const char* glesPrefix = "OpenGL ES "; - - version = glGetString(GL_VERSION); - if (!version) - return; - - if (strncmp((const char*) version, glesPrefix, strlen(glesPrefix)) == 0) + int i, _major, _minor = 0, _rev = 0; + const char* version; + const char* prefixes[] = { - // The version string on OpenGL ES has a prefix before the version - // number, so we skip past it and then continue as normal + "OpenGL ES ", + NULL + }; - version += strlen(glesPrefix); + version = (const char*) glGetString(GL_VERSION); + if (!version) + { + _glfwSetError(GLFW_PLATFORM_ERROR, "Failed to retrieve version string"); + return GL_FALSE; } - // Parse version from string - - ptr = version; - for (_major = 0; *ptr >= '0' && *ptr <= '9'; ptr++) - _major = 10 * _major + (*ptr - '0'); - - if (*ptr == '.') + for (i = 0; prefixes[i]; i++) { - ptr++; - for (_minor = 0; *ptr >= '0' && *ptr <= '9'; ptr++) - _minor = 10 * _minor + (*ptr - '0'); + const size_t length = strlen(prefixes[i]); - 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; + + return GL_TRUE; } @@ -347,13 +344,35 @@ GLboolean _glfwIsValidContextConfig(_GLFWwndconfig* wndconfig) //======================================================================== -// Checks whether the specified context fulfils the requirements +// Reads back context properties // It blames glfwOpenWindow because that's the only caller //======================================================================== -GLboolean _glfwIsValidContext(_GLFWwindow* window, _GLFWwndconfig* wndconfig) +GLboolean _glfwRefreshContextParams(void) { - parseGLVersion(&window->glMajor, &window->glMinor, &window->glRevision); + _GLFWwindow* window = _glfwLibrary.currentWindow; + + 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 { @@ -366,6 +385,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; } } @@ -385,7 +406,39 @@ 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 (glfwExtensionSupported("GL_ARB_multisample")) + glGetIntegerv(GL_SAMPLES_ARB, &window->samples); + else + window->samples = 0; + + return GL_TRUE; +} + + +//======================================================================== +// Checks whether the current context fulfils the specified requirements +// It blames glfwOpenWindow because that's the only caller +//======================================================================== + +GLboolean _glfwIsValidContext(_GLFWwndconfig* wndconfig) +{ + _GLFWwindow* window = _glfwLibrary.currentWindow; if (window->glMajor < wndconfig->glMajor || (window->glMajor == wndconfig->glMajor && @@ -403,21 +456,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; } @@ -513,7 +551,7 @@ GLFWAPI void glfwSwapBuffers(void) if (!_glfwLibrary.currentWindow) { - _glfwSetError(GLFW_NO_CURRENT_WINDOW, NULL); + _glfwSetError(GLFW_NO_CURRENT_CONTEXT, NULL); return; } @@ -535,7 +573,7 @@ GLFWAPI void glfwSwapInterval(int interval) if (!_glfwLibrary.currentWindow) { - _glfwSetError(GLFW_NO_CURRENT_WINDOW, NULL); + _glfwSetError(GLFW_NO_CURRENT_CONTEXT, NULL); return; } @@ -551,9 +589,6 @@ GLFWAPI int glfwExtensionSupported(const char* extension) { const GLubyte* extensions; _GLFWwindow* window; - GLubyte* where; - GLint count; - int i; if (!_glfwInitialized) { @@ -564,14 +599,15 @@ 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; } - // 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) { @@ -586,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); @@ -600,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); } @@ -623,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; } diff --git a/src/win32_fullscreen.c b/src/win32_fullscreen.c index d33b4eaa..b6edb549 100644 --- a/src/win32_fullscreen.c +++ b/src/win32_fullscreen.c @@ -182,52 +182,87 @@ void _glfwRestoreVideoMode(void) // Get a list of available video modes //======================================================================== -int _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, GLFWvidmode* list, int maxcount) +GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found) { - DWORD deviceModeIndex = 0; - int modeCount = 0; + int deviceModeIndex = 0, count = 0; + GLFWvidmode* result = NULL; + WCHAR* deviceName; - WCHAR* deviceName = _glfwCreateWideStringFromUTF8(monitor->Win32.name); + deviceName = _glfwCreateWideStringFromUTF8(monitor->Win32.name); if (!deviceName) - return 0; + { + _glfwSetError(GLFW_PLATFORM_ERROR, "Win32: Failed to convert device name"); + return NULL; + } + + *found = 0; for (;;) { + int i; GLFWvidmode mode; - DEVMODE deviceMode; + DEVMODE dm; - ZeroMemory(&deviceMode, sizeof(DEVMODE)); - deviceMode.dmSize = sizeof(DEVMODE); + ZeroMemory(&dm, sizeof(DEVMODE)); + dm.dmSize = sizeof(DEVMODE); - if (!EnumDisplaySettings(deviceName, deviceModeIndex, &deviceMode)) - break; + if (!EnumDisplaySettings(deviceName, deviceModeIndex, &dm)) + break; deviceModeIndex++; - if (deviceMode.dmBitsPerPel < 15) + + if (dm.dmBitsPerPel < 15) + { + // Skip modes with less than 15 BPP continue; + } - mode.height = deviceMode.dmPelsHeight; - mode.width = deviceMode.dmPelsWidth; - _glfwSplitBPP(deviceMode.dmBitsPerPel, - &mode.redBits, - &mode.greenBits, - &mode.blueBits); + mode.width = dm.dmPelsWidth; + mode.height = dm.dmPelsHeight; + _glfwSplitBPP(dm.dmBitsPerPel, + &mode.redBits, + &mode.greenBits, + &mode.blueBits); - // Skip duplicate modes - if (bsearch(&mode, list, modeCount, sizeof(GLFWvidmode), _glfwCompareVideoModes)) + for (i = 0; i < *found; i++) + { + if (_glfwCompareVideoModes(result + i, &mode) == 0) + break; + } + + if (i < *found) + { + // This is a duplicate, so skip it continue; + } - list[modeCount] = mode; - modeCount++; + if (*found == count) + { + void* larger; - qsort(list, modeCount, sizeof(GLFWvidmode), _glfwCompareVideoModes); + if (count) + count *= 2; + else + count = 128; - if (modeCount >= maxcount) - break; + 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)++; } free(deviceName); - return modeCount; + return result; } 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/win32_opengl.c b/src/win32_opengl.c index 5e94d7da..11a45346 100644 --- a/src/win32_opengl.c +++ b/src/win32_opengl.c @@ -31,6 +31,499 @@ #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; +} + + +//======================================================================== +// 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); + + 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 714a735e..c0c2e157 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -248,6 +248,12 @@ void _glfwInitTimer(void); _GLFWmonitor* _glfwCreateMonitors(void); _GLFWmonitor* _glfwDestroyMonitor(_GLFWmonitor* monitor); +// 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 dd14a77f..85846bdd 100755 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -121,329 +121,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 //======================================================================== @@ -1113,94 +790,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 //======================================================================== @@ -1241,38 +830,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 //======================================================================== @@ -1282,7 +839,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; @@ -1362,31 +919,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; } @@ -1397,28 +938,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); @@ -1481,14 +1007,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; } @@ -1678,93 +1209,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)) diff --git a/src/window.c b/src/window.c index f8939e37..2e77fa15 100644 --- a/src/window.c +++ b/src/window.c @@ -319,10 +319,17 @@ GLFWAPI GLFWwindow glfwOpenWindow(int width, int height, } // Cache the actual (as opposed to desired) window parameters - glfwMakeContextCurrent(window); _glfwPlatformRefreshWindowParams(); - if (!_glfwIsValidContext(window, &wndconfig)) + glfwMakeContextCurrent(window); + + if (!_glfwRefreshContextParams()) + { + glfwCloseWindow(window); + return GL_FALSE; + } + + if (!_glfwIsValidContext(&wndconfig)) { glfwCloseWindow(window); return GL_FALSE; @@ -682,8 +689,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_fullscreen.c b/src/x11_fullscreen.c index 2ff8a731..cc0736af 100644 --- a/src/x11_fullscreen.c +++ b/src/x11_fullscreen.c @@ -32,6 +32,105 @@ #include #include +#include + + +//------------------------------------------------------------------------ +// Display resolution +//------------------------------------------------------------------------ + +typedef struct +{ + int width; + int height; +} _GLFWvidsize; + + +//======================================================================== +// List available resolutions +//======================================================================== + +static _GLFWvidsize* getResolutions(_GLFWmonitor* monitor, 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; +} + ////////////////////////////////////////////////////////////////////////// @@ -325,192 +424,92 @@ void _glfwRestoreVideoMode(void) ////// GLFW platform API ////// ////////////////////////////////////////////////////////////////////////// -struct _glfwResolution -{ - int width; - int height; -}; - -int _glfwCompareResolution(const void* left, const void* right) -{ - int result = 0; - const struct _glfwResolution* leftResolution = left; - const struct _glfwResolution* rightResolution = right; - - result = leftResolution->height - rightResolution->height; - if (result == 0) - { - result = leftResolution->width - rightResolution->width; - } - - return result; -} - //======================================================================== // List available video modes //======================================================================== -int _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, GLFWvidmode* list, int maxcount) +GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, 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; + // The visual lacks OpenGL or true color, so skip it + continue; + } - // Convert to RGB - _glfwSplitBPP(depth, &r, &g, &b); - depth = (r << 16) | (g << 8) | b; + // Convert to RGB channel depths and encode + _glfwSplitBPP(visuals[i].depth, &r, &g, &b); + rgb = (r << 16) | (g << 8) | b; - // Is this mode unique? - for (l = 0; l < rgbcount; l++) - { - if (depth == rgbarray[l]) - break; - } + for (j = 0; j < rgbCount; j++) + { + if (rgbs[j] == rgb) + break; + } - if (l >= rgbcount) - { - rgbarray[rgbcount] = depth; - rgbcount++; - } + if (j < rgbCount) + { + // This channel depth is a duplicate, so skip it + continue; + } + + rgbs[rgbCount] = rgb; + rgbCount++; + } + + XFree(visuals); + + // Build all permutations of channel depths and resolutions + + sizes = getResolutions(monitor, &sizeCount); + + result = (GLFWvidmode*) malloc(sizeof(GLFWvidmode) * rgbCount * sizeCount); + *found = 0; + + for (i = 0; i < rgbCount; i++) + { + for (j = 0; j < sizeCount; j++) + { + 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)++; } } - XFree(vislist); + free(sizes); + free(rgbs); - rescount = 0; - resarray = NULL; - - // Build resolution array - - if (_glfwLibrary.X11.RandR.available) - { -#if defined(_GLFW_HAS_XRANDR) - XRRScreenResources* resource; - unsigned int a; - resource = XRRGetScreenResources(_glfwLibrary.X11.display, _glfwLibrary.X11.root); - - resarray = (struct _glfwResolution*) malloc(sizeof(struct _glfwResolution) * monitor->X11.output->nmode); - - for (k = 0; k < monitor->X11.output->nmode; k++) - { - for (a = 0; a < resource->nmode; a++) - { - if (resource->modes[a].id != monitor->X11.output->modes[k]) - { - continue; - } - - struct _glfwResolution res = { - resource->modes[a].width, - resource->modes[a].height - }; - - if (!bsearch(&res, resarray, rescount, sizeof(struct _glfwResolution), _glfwCompareResolution)) - { - resarray[rescount].width = resource->modes[a].width; - resarray[rescount].height = resource->modes[a].height; - rescount++; - qsort(resarray, rescount, sizeof(struct _glfwResolution), _glfwCompareResolution); - } - } - } - - XRRFreeScreenResources(resource); -#endif /*_GLFW_HAS_XRANDR*/ - } - else if (_glfwLibrary.X11.VidMode.available) - { -#if defined(_GLFW_HAS_XF86VIDMODE) - XF86VidModeModeInfo** modelist; - int modecount, width, height; - - XF86VidModeGetAllModeLines(_glfwLibrary.X11.display, - _glfwLibrary.X11.screen, - &modecount, &modelist); - - resarray = (struct _glfwResolution*) malloc(sizeof(struct _glfwResolution) * modecount); - - for (k = 0; k < modecount; k++) - { - width = modelist[k]->hdisplay; - height = modelist[k]->vdisplay; - - // Is this mode unique? - for (l = 0; l < rescount; l++) - { - if (width == resarray[l].width && height == resarray[l].height) - break; - } - - if (l >= rescount) - { - resarray[rescount].width = width; - resarray[rescount].height = height; - rescount++; - } - } - - XFree(modelist); -#endif /*_GLFW_HAS_XF86VIDMODE*/ - } - - if (!resarray) - { - rescount = 1; - resarray = (struct _glfwResolution*) malloc(sizeof(struct _glfwResolution) * rescount); - - resarray[0].width = DisplayWidth(_glfwLibrary.X11.display, - _glfwLibrary.X11.screen); - resarray[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++) - { - for (l = 0; l < rescount && count < maxcount; l++) - { - 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++; - } - } - - free(resarray); - free(rgbarray); - - return count; + return result; } diff --git a/src/x11_monitor.c b/src/x11_monitor.c index e1b7b67e..e36bbdc5 100644 --- a/src/x11_monitor.c +++ b/src/x11_monitor.c @@ -78,6 +78,7 @@ _GLFWmonitor* _glfwDestroyMonitor(_GLFWmonitor* monitor) XRRFreeOutputInfo(monitor->X11.output); #endif /*_GLFW_HAS_XRANDR*/ + free(monitor->modes); free(monitor->name); free(monitor); 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; +} + diff --git a/src/x11_opengl.c b/src/x11_opengl.c index edcd69b6..3549e573 100644 --- a/src/x11_opengl.c +++ b/src/x11_opengl.c @@ -197,72 +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(); - } - - // 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); - - 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 //======================================================================== @@ -467,8 +401,6 @@ static int createContext(_GLFWwindow* window, return GL_FALSE; } - refreshContextParams(window, fbconfigID); - return GL_TRUE; } @@ -513,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; } diff --git a/src/x11_window.c b/src/x11_window.c index 5cc7f6f4..1bf2da76 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -1140,20 +1140,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); @@ -1162,6 +1156,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, 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" }, diff --git a/tests/glfwinfo.c b/tests/glfwinfo.c index 45cb8616..bbbedce0 100644 --- a/tests/glfwinfo.c +++ b/tests/glfwinfo.c @@ -249,23 +249,29 @@ 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"); - 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 context 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)) { 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", + printf("OpenGL profile mask parsed by GLFW: %s\n", get_glfw_profile_name(glfwGetWindowParam(window, GLFW_OPENGL_PROFILE))); } diff --git a/tests/modes.c b/tests/modes.c index 07c07f2a..93206620 100755 --- a/tests/modes.c +++ b/tests/modes.c @@ -90,34 +90,15 @@ static void key_callback(GLFWwindow dummy, int key, int action) } } -static GLFWvidmode* get_video_modes(GLFWmonitor monitor, size_t* found) -{ - size_t count = 0; - GLFWvidmode* modes = NULL; - - for (;;) - { - count += 256; - modes = realloc(modes, sizeof(GLFWvidmode) * count); - - *found = glfwGetVideoModes(monitor, modes, count); - if (*found < count) - break; - } - - return modes; -} - static void list_modes(GLFWmonitor monitor) { - size_t count, i; + int count, i; GLFWvidmode desktop_mode; + GLFWvidmode* modes = glfwGetVideoModes(monitor, &count); glfwGetDesktopMode(&desktop_mode); printf("Desktop mode: %s\n", format_mode(&desktop_mode)); - GLFWvidmode* modes = get_video_modes(monitor, &count); - printf("Monitor %s (%ix%i mm):\n", glfwGetMonitorString(monitor, GLFW_MONITOR_NAME), glfwGetMonitorParam(monitor, GLFW_MONITOR_PHYSICAL_WIDTH), @@ -132,15 +113,12 @@ static void list_modes(GLFWmonitor monitor) putchar('\n'); } - - free(modes); } static void test_modes(GLFWmonitor monitor) { - int width, height; - size_t i, count; - GLFWvidmode* modes = get_video_modes(monitor, &count); + int i, count, width, height; + GLFWvidmode* modes = glfwGetVideoModes(monitor, &count); glfwSetWindowSizeCallback(window_size_callback); glfwSetWindowCloseCallback(window_close_callback); @@ -214,8 +192,6 @@ static void test_modes(GLFWmonitor monitor) glfwPollEvents(); window = NULL; } - - free(modes); } int main(int argc, char** argv)