Merge branch 'master' into multi-monitor

Conflicts:
	include/GL/glfw3.h
	src/CMakeLists.txt
	src/fullscreen.c
	src/internal.h
	src/win32_fullscreen.c
	src/win32_platform.h
	src/x11_fullscreen.c
	tests/modes.c
This commit is contained in:
Camilla Berglund
2012-08-03 02:57:33 +02:00
28 changed files with 1330 additions and 1078 deletions
+13 -7
View File
@@ -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
+13 -6
View File
@@ -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;
}
+74
View File
@@ -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 <elmindreda@elmindreda.org>
//
// 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;
}
+2 -67
View File
@@ -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
+26 -4
View File
@@ -29,6 +29,9 @@
#include "internal.h"
#include <stdio.h>
#include <stdarg.h>
//////////////////////////////////////////////////////////////////////////
////// 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:
+21 -19
View File
@@ -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;
}
+19 -17
View File
@@ -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);
+1 -1
View File
@@ -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}
+99 -63
View File
@@ -30,6 +30,7 @@
#include "internal.h"
#include <stdio.h>
#include <string.h>
#include <limits.h>
@@ -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;
}
+60 -25
View File
@@ -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;
}
+74
View File
@@ -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 <elmindreda@elmindreda.org>
//
// 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;
}
+493
View File
@@ -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 //////
//////////////////////////////////////////////////////////////////////////
+6
View File
@@ -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,
+15 -567
View File
@@ -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))
+9 -4
View File
@@ -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:
+162 -163
View File
@@ -32,6 +32,105 @@
#include <limits.h>
#include <stdlib.h>
#include <string.h>
//------------------------------------------------------------------------
// 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;
}
+1
View File
@@ -78,6 +78,7 @@ _GLFWmonitor* _glfwDestroyMonitor(_GLFWmonitor* monitor)
XRRFreeOutputInfo(monitor->X11.output);
#endif /*_GLFW_HAS_XRANDR*/
free(monitor->modes);
free(monitor->name);
free(monitor);
+84
View File
@@ -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 <elmindreda@elmindreda.org>
//
// 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;
}
+1 -69
View File
@@ -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;
}
+6 -8
View File
@@ -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,