diff --git a/CMake/README.txt b/CMake/README.txt
index 96ac1905b..9dbaee266 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 b80ac24ee..d49a2aea6 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 b7ea88c52..6811d9b57 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 000000000..b8b01f9ab
--- /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 789ac5ff5..f399f7529 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 ee9241a7e..7822c56b5 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 147913fbe..9382993b8 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 000000000..be8aac4bd
--- /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 3523806ab..74f187b04 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 062fb76ae..c7926e9cc 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 011e19242..08ac95723 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 ccb7f402d..66f413ba1 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 be6275aa7..175c902db 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 67b5e728b..59166bfa4 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 d33b4eaaf..b6edb549e 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 000000000..80cc5730d
--- /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 5e94d7da6..11a453460 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 714a735e1..c0c2e1573 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 dd14a77f8..85846bdda 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 f8939e37c..2e77fa159 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 2ff8a7317..cc0736af2 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 e1b7b67ed..e36bbdc53 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 000000000..22f301124
--- /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 edcd69b61..3549e5738 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 5cc7f6f4c..1bf2da763 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 d7c5a02c4..16c627236 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 45cb86161..bbbedce02 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 07c07f2a1..932066203 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)