mirror of
https://github.com/glfw/glfw.git
synced 2024-11-26 03:52:01 +00:00
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:
commit
854e634fec
@ -1,17 +1,16 @@
|
|||||||
This directory contains a collection of toolchain definitions for cross
|
This directory contains a collection of toolchain definitions for
|
||||||
compilation, currently limited to compiling Win32 binaries on Linux.
|
cross-compiling for Windows using MinGW on various other systems.
|
||||||
|
|
||||||
The toolchain file naming scheme is as follows:
|
|
||||||
|
|
||||||
host-system-compiler.cmake
|
|
||||||
|
|
||||||
To use these files you add a special parameter when configuring the source tree:
|
To use these files you add a special parameter when configuring the source tree:
|
||||||
|
|
||||||
cmake -DCMAKE_TOOLCHAIN_FILE=<toolchain-file> .
|
cmake -DCMAKE_TOOLCHAIN_FILE=<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:
|
For more details see this article:
|
||||||
|
|
||||||
|
@ -215,6 +215,16 @@ endif()
|
|||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
set(GLFW_LIBRARIES ${glfw_LIBRARIES} CACHE STRING "Dependencies of GLFW")
|
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
|
# 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
|
# The src directory's CMakeLists.txt file installs the library
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
install(DIRECTORY include/GL DESTINATION include
|
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
|
install(FILES COPYING.txt readme.html
|
||||||
DESTINATION share/doc/glfw-${GLFW_VERSION_FULL})
|
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
|
# Create and install pkg-config file on supported platforms
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
if (_GLFW_X11_GLX OR _GLFW_COCOA_NSGL)
|
if (_GLFW_X11_GLX OR _GLFW_COCOA_NSGL)
|
||||||
configure_file(${GLFW_SOURCE_DIR}/src/libglfw.pc.in
|
configure_file(${GLFW_SOURCE_DIR}/src/libglfw3.pc.in
|
||||||
${GLFW_BINARY_DIR}/src/libglfw.pc @ONLY)
|
${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)
|
DESTINATION lib/pkgconfig)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -71,7 +71,6 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
#if __MINGW64__
|
#if __MINGW64__
|
||||||
#define WINAPI
|
#define WINAPI
|
||||||
#include <stddef.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The following three defines are here solely to make some Windows-based
|
/* The following three defines are here solely to make some Windows-based
|
||||||
@ -110,11 +109,10 @@ extern "C" {
|
|||||||
#define GLFW_CALLBACK_DEFINED
|
#define GLFW_CALLBACK_DEFINED
|
||||||
#endif /* CALLBACK */
|
#endif /* CALLBACK */
|
||||||
|
|
||||||
/* Microsoft Visual C++, Borland C++ and Pelles C <GL*glu.h> needs wchar_t */
|
/* Most <GL/glu.h> variants on Windows need wchar_t */
|
||||||
#if defined(_WIN32) && (defined(_MSC_VER) || defined(__BORLANDC__) || defined(__POCC__)) && !defined(_WCHAR_T_DEFINED)
|
#if defined(_WIN32)
|
||||||
typedef unsigned short wchar_t;
|
#include <stddef.h>
|
||||||
#define _WCHAR_T_DEFINED
|
#endif
|
||||||
#endif /* _WCHAR_T_DEFINED */
|
|
||||||
|
|
||||||
|
|
||||||
/* ---------------- GLFW related system specific defines ----------------- */
|
/* ---------------- GLFW related system specific defines ----------------- */
|
||||||
@ -390,7 +388,6 @@ extern "C" {
|
|||||||
/* glfwGetWindowParam tokens */
|
/* glfwGetWindowParam tokens */
|
||||||
#define GLFW_ACTIVE 0x00020001
|
#define GLFW_ACTIVE 0x00020001
|
||||||
#define GLFW_ICONIFIED 0x00020002
|
#define GLFW_ICONIFIED 0x00020002
|
||||||
#define GLFW_ACCELERATED 0x00020003
|
|
||||||
#define GLFW_OPENGL_REVISION 0x00020004
|
#define GLFW_OPENGL_REVISION 0x00020004
|
||||||
|
|
||||||
/* The following constants are used for both glfwGetWindowParam
|
/* The following constants are used for both glfwGetWindowParam
|
||||||
@ -449,7 +446,7 @@ extern "C" {
|
|||||||
/* glfwGetError/glfwErrorString tokens */
|
/* glfwGetError/glfwErrorString tokens */
|
||||||
#define GLFW_NO_ERROR 0
|
#define GLFW_NO_ERROR 0
|
||||||
#define GLFW_NOT_INITIALIZED 0x00070001
|
#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_ENUM 0x00070003
|
||||||
#define GLFW_INVALID_VALUE 0x00070004
|
#define GLFW_INVALID_VALUE 0x00070004
|
||||||
#define GLFW_OUT_OF_MEMORY 0x00070005
|
#define GLFW_OUT_OF_MEMORY 0x00070005
|
||||||
@ -546,7 +543,7 @@ GLFWAPI const char* glfwGetMonitorString(GLFWmonitor monitor, int param);
|
|||||||
GLFWAPI GLFWmonitor glfwGetNextMonitor(GLFWmonitor iterator);
|
GLFWAPI GLFWmonitor glfwGetNextMonitor(GLFWmonitor iterator);
|
||||||
|
|
||||||
/* Video mode functions */
|
/* Video mode functions */
|
||||||
GLFWAPI int glfwGetVideoModes(GLFWmonitor monitor, GLFWvidmode* list, int maxcount);
|
GLFWAPI GLFWvidmode* glfwGetVideoModes(GLFWmonitor monitor, int* count);
|
||||||
GLFWAPI void glfwGetDesktopMode(GLFWvidmode* mode);
|
GLFWAPI void glfwGetDesktopMode(GLFWvidmode* mode);
|
||||||
|
|
||||||
/* Gamma ramp functions */
|
/* Gamma ramp functions */
|
||||||
|
97
include/GL/glfw3native.h
Normal file
97
include/GL/glfw3native.h
Normal file
@ -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 <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.
|
||||||
|
*
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
#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 <windows.h>
|
||||||
|
|
||||||
|
#elif defined(GLFW_EXPOSE_NATIVE_COCOA_NSGL)
|
||||||
|
|
||||||
|
/* We are building for Cocoa and NSOpenGL */
|
||||||
|
#if defined(__OBJC__)
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#else
|
||||||
|
typedef void* id;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined(GLFW_EXPOSE_NATIVE_X11_GLX)
|
||||||
|
|
||||||
|
/* We are building for X11 and GLX */
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
|
||||||
|
#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__ */
|
||||||
|
|
@ -287,12 +287,14 @@ version of GLFW.</p>
|
|||||||
<li>Added <code>windows</code> simple multi-window test program</li>
|
<li>Added <code>windows</code> simple multi-window test program</li>
|
||||||
<li>Added <code>sharing</code> simple OpenGL object sharing test program</li>
|
<li>Added <code>sharing</code> simple OpenGL object sharing test program</li>
|
||||||
<li>Added <code>modes</code> video mode enumeration and setting test program</li>
|
<li>Added <code>modes</code> video mode enumeration and setting test program</li>
|
||||||
|
<li>Added <code>glfw3native.h</code> header and platform-specific functions for explicit access to native display, window and context handles</li>
|
||||||
<li>Added a parameter to <code>glfwOpenWindow</code> for specifying a context the new window's context will share objects with</li>
|
<li>Added a parameter to <code>glfwOpenWindow</code> for specifying a context the new window's context will share objects with</li>
|
||||||
<li>Added initial window title parameter to <code>glfwOpenWindow</code></li>
|
<li>Added initial window title parameter to <code>glfwOpenWindow</code></li>
|
||||||
<li>Added <code>glfwSetGamma</code>, <code>glfwSetGammaRamp</code> and <code>glfwGetGammaRamp</code> functions and <code>GLFWgammaramp</code> type for monitor gamma ramp control</li>
|
<li>Added <code>glfwSetGamma</code>, <code>glfwSetGammaRamp</code> and <code>glfwGetGammaRamp</code> functions and <code>GLFWgammaramp</code> type for monitor gamma ramp control</li>
|
||||||
<li>Changed buffer bit depth parameters of <code>glfwOpenWindow</code> to window hints</li>
|
<li>Changed buffer bit depth parameters of <code>glfwOpenWindow</code> to window hints</li>
|
||||||
<li>Changed <code>glfwOpenWindow</code> and <code>glfwSetWindowTitle</code> to use UTF-8 encoded strings</li>
|
<li>Changed <code>glfwOpenWindow</code> and <code>glfwSetWindowTitle</code> to use UTF-8 encoded strings</li>
|
||||||
<li>Changed <code>glfwGetProcAddress</code> to return a (generic) function pointer</li>
|
<li>Changed <code>glfwGetProcAddress</code> to return a (generic) function pointer</li>
|
||||||
|
<li>Changed <code>glfwGetVideoModes</code> to return a dynamic, unlimited number of video modes</li>
|
||||||
<li>Renamed <code>glfw.h</code> to <code>glfw3.h</code> to avoid conflicts with 2.x series</li>
|
<li>Renamed <code>glfw.h</code> to <code>glfw3.h</code> to avoid conflicts with 2.x series</li>
|
||||||
<li>Renamed <code>GLFW_WINDOW</code> token to <code>GLFW_WINDOWED</code></li>
|
<li>Renamed <code>GLFW_WINDOW</code> token to <code>GLFW_WINDOWED</code></li>
|
||||||
<li>Renamed <code>GLFW_WINDOW_NO_RESIZE</code> to <code>GLFW_WINDOW_RESIZABLE</code></li>
|
<li>Renamed <code>GLFW_WINDOW_NO_RESIZE</code> to <code>GLFW_WINDOW_RESIZABLE</code></li>
|
||||||
@ -317,6 +319,7 @@ version of GLFW.</p>
|
|||||||
<li>Removed <code>GLFW_OPENED</code> window parameter</li>
|
<li>Removed <code>GLFW_OPENED</code> window parameter</li>
|
||||||
<li>Removed nonsensical key actions for Unicode character input</li>
|
<li>Removed nonsensical key actions for Unicode character input</li>
|
||||||
<li>Removed <code>GLFWCALL</code> and <code>GLFWAPIENTRY</code> macros for stdcall calling convention</li>
|
<li>Removed <code>GLFWCALL</code> and <code>GLFWAPIENTRY</code> macros for stdcall calling convention</li>
|
||||||
|
<li>Removed <code>GLFW_ACCELERATED</code> window parameter</li>
|
||||||
<li>Bugfix: The default OpenGL version in the <code>glfwinfo</code> test was set to 1.1</li>
|
<li>Bugfix: The default OpenGL version in the <code>glfwinfo</code> test was set to 1.1</li>
|
||||||
<li>Bugfix: The OpenGL profile and forward-compatibility window parameters were not saved after context creation</li>
|
<li>Bugfix: The OpenGL profile and forward-compatibility window parameters were not saved after context creation</li>
|
||||||
<li>Bugfix: The FSAA test did not check for the availability of <code>GL_ARB_multisample</code></li>
|
<li>Bugfix: The FSAA test did not check for the availability of <code>GL_ARB_multisample</code></li>
|
||||||
@ -847,6 +850,9 @@ their skills. Special thanks go out to:</p>
|
|||||||
<li>Keith Bauer, for his invaluable help with porting and maintaining GLFW on
|
<li>Keith Bauer, for his invaluable help with porting and maintaining GLFW on
|
||||||
Mac OS X, and for his many ideas</li>
|
Mac OS X, and for his many ideas</li>
|
||||||
|
|
||||||
|
<li>John Bartholomew, for adding proper version number and soname to the
|
||||||
|
shared library build</li>
|
||||||
|
|
||||||
<li>Lambert Clara, for a bug fix for the modes test</li>
|
<li>Lambert Clara, for a bug fix for the modes test</li>
|
||||||
|
|
||||||
<li>Jarrod Davis, for the Delphi port of GLFW</li>
|
<li>Jarrod Davis, for the Delphi port of GLFW</li>
|
||||||
@ -917,6 +923,9 @@ their skills. Special thanks go out to:</p>
|
|||||||
Much of the Windows code of GLFW was originally based on Jeff's
|
Much of the Windows code of GLFW was originally based on Jeff's
|
||||||
code</li>
|
code</li>
|
||||||
|
|
||||||
|
<li>Arturo J. Pérez, for a bug fix for cursor tracking on Mac OS X 10.6 Snow
|
||||||
|
Leopard</li>
|
||||||
|
|
||||||
<li>Douglas C. Schmidt and Irfan Pyarali, for their excellent article
|
<li>Douglas C. Schmidt and Irfan Pyarali, for their excellent article
|
||||||
<a href="http://www.cs.wustl.edu/~schmidt/win32-cv-1.html">Strategies for Implementing POSIX Condition Variables on Win32</a></li>
|
<a href="http://www.cs.wustl.edu/~schmidt/win32-cv-1.html">Strategies for Implementing POSIX Condition Variables on Win32</a></li>
|
||||||
|
|
||||||
|
@ -11,27 +11,33 @@ if (_GLFW_COCOA_NSGL)
|
|||||||
set(glfw_HEADERS ${common_HEADERS} cocoa_platform.h)
|
set(glfw_HEADERS ${common_HEADERS} cocoa_platform.h)
|
||||||
set(glfw_SOURCES ${common_SOURCES} cocoa_clipboard.m cocoa_fullscreen.m
|
set(glfw_SOURCES ${common_SOURCES} cocoa_clipboard.m cocoa_fullscreen.m
|
||||||
cocoa_gamma.c cocoa_init.m cocoa_input.m cocoa_joystick.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
|
# For some reason, CMake doesn't know about .m
|
||||||
set_source_files_properties(${glfw_SOURCES} PROPERTIES LANGUAGE C)
|
set_source_files_properties(${glfw_SOURCES} PROPERTIES LANGUAGE C)
|
||||||
elseif (_GLFW_WIN32_WGL)
|
elseif (_GLFW_WIN32_WGL)
|
||||||
set(glfw_HEADERS ${common_HEADERS} win32_platform.h)
|
set(glfw_HEADERS ${common_HEADERS} win32_platform.h)
|
||||||
set(glfw_SOURCES ${common_SOURCES} win32_clipboard.c win32_dllmain.c
|
set(glfw_SOURCES ${common_SOURCES} win32_clipboard.c win32_fullscreen.c
|
||||||
win32_fullscreen.c win32_gamma.c win32_init.c win32_input.c
|
win32_gamma.c win32_init.c win32_input.c win32_joystick.c
|
||||||
win32_joystick.c win32_monitor.c win32_opengl.c
|
win32_monitor.c win32_native.c win32_opengl.c win32_time.c
|
||||||
win32_time.c win32_window.c)
|
win32_window.c win32_dllmain.c)
|
||||||
elseif (_GLFW_X11_GLX)
|
elseif (_GLFW_X11_GLX)
|
||||||
set(glfw_HEADERS ${common_HEADERS} x11_platform.h)
|
set(glfw_HEADERS ${common_HEADERS} x11_platform.h)
|
||||||
set(glfw_SOURCES ${common_SOURCES} x11_clipboard.c x11_fullscreen.c
|
set(glfw_SOURCES ${common_SOURCES} x11_clipboard.c x11_fullscreen.c
|
||||||
x11_gamma.c x11_init.c x11_input.c x11_joystick.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_keysym2unicode.c x11_monitor.c x11_native.c
|
||||||
x11_window.c)
|
x11_opengl.c x11_time.c x11_window.c)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_library(glfw ${glfw_SOURCES} ${glfw_HEADERS})
|
add_library(glfw ${glfw_SOURCES} ${glfw_HEADERS})
|
||||||
|
set_target_properties(glfw PROPERTIES OUTPUT_NAME "${GLFW_LIB_NAME}")
|
||||||
|
|
||||||
if (BUILD_SHARED_LIBS)
|
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)
|
if (_GLFW_WIN32_WGL)
|
||||||
# The GLFW DLL needs a special compile-time macro and import library name
|
# The GLFW DLL needs a special compile-time macro and import library name
|
||||||
|
@ -197,25 +197,32 @@ void _glfwRestoreVideoMode(void)
|
|||||||
// Get a list of available video modes
|
// Get a list of available video modes
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount)
|
GLFWvidmode* _glfwPlatformGetVideoModes(int* found)
|
||||||
{
|
{
|
||||||
CGDisplayModeRef mode;
|
|
||||||
CFArrayRef modes;
|
CFArrayRef modes;
|
||||||
CFIndex count, i;
|
CFIndex count, i;
|
||||||
int stored = 0;
|
GLFWvidmode* result;
|
||||||
|
|
||||||
modes = CGDisplayCopyAllDisplayModes(CGMainDisplayID(), NULL);
|
modes = CGDisplayCopyAllDisplayModes(CGMainDisplayID(), NULL);
|
||||||
count = CFArrayGetCount(modes);
|
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);
|
mode = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
|
||||||
if (modeIsGood(mode))
|
if (modeIsGood(mode))
|
||||||
list[stored++] = vidmodeFromCGDisplayMode(mode);
|
{
|
||||||
|
result[*found] = vidmodeFromCGDisplayMode(mode);
|
||||||
|
(*found)++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CFRelease(modes);
|
CFRelease(modes);
|
||||||
return stored;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
74
src/cocoa_native.m
Normal file
74
src/cocoa_native.m
Normal 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;
|
||||||
|
}
|
||||||
|
|
@ -425,6 +425,7 @@ static int convertMacKeyCode(unsigned int macKeyCode)
|
|||||||
userInfo:nil];
|
userInfo:nil];
|
||||||
|
|
||||||
[self addTrackingArea:trackingArea];
|
[self addTrackingArea:trackingArea];
|
||||||
|
[super updateTrackingAreas];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)keyDown:(NSEvent *)event
|
- (void)keyDown:(NSEvent *)event
|
||||||
@ -1042,72 +1043,6 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window)
|
|||||||
|
|
||||||
void _glfwPlatformRefreshWindowParams(void)
|
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)
|
if (window->mode == GLFW_FULLSCREEN)
|
||||||
{
|
{
|
||||||
NSPoint globalPoint = NSMakePoint(x, y);
|
CGPoint globalPoint = CGPointMake(x, y);
|
||||||
CGDisplayMoveCursorToPoint(CGMainDisplayID(), globalPoint);
|
CGDisplayMoveCursorToPoint(CGMainDisplayID(), globalPoint);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
30
src/error.c
30
src/error.c
@ -29,6 +29,9 @@
|
|||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW internal API //////
|
////// GLFW internal API //////
|
||||||
@ -49,11 +52,30 @@ static GLFWerrorfun _glfwErrorCallback = NULL;
|
|||||||
// This function may be called without GLFW having been initialized
|
// 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 (_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);
|
description = glfwErrorString(error);
|
||||||
|
|
||||||
_glfwErrorCallback(error, description);
|
_glfwErrorCallback(error, description);
|
||||||
@ -93,8 +115,8 @@ GLFWAPI const char* glfwErrorString(int error)
|
|||||||
return "No error";
|
return "No error";
|
||||||
case GLFW_NOT_INITIALIZED:
|
case GLFW_NOT_INITIALIZED:
|
||||||
return "The GLFW library is not initialized";
|
return "The GLFW library is not initialized";
|
||||||
case GLFW_NO_CURRENT_WINDOW:
|
case GLFW_NO_CURRENT_CONTEXT:
|
||||||
return "There is no current GLFW window";
|
return "There is no current OpenGL context";
|
||||||
case GLFW_INVALID_ENUM:
|
case GLFW_INVALID_ENUM:
|
||||||
return "Invalid argument for enum parameter";
|
return "Invalid argument for enum parameter";
|
||||||
case GLFW_INVALID_VALUE:
|
case GLFW_INVALID_VALUE:
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
// Lexical comparison function for GLFW video modes, used by qsort
|
// 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;
|
int firstBPP, secondBPP, firstSize, secondSize;
|
||||||
GLFWvidmode* first = (GLFWvidmode*) firstPtr;
|
GLFWvidmode* first = (GLFWvidmode*) firstPtr;
|
||||||
@ -68,6 +68,16 @@ int _glfwCompareVideoModes(const void* firstPtr, const void* secondPtr)
|
|||||||
////// GLFW internal API //////
|
////// 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"
|
// 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
|
// 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;
|
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
|
||||||
|
|
||||||
if (!_glfwInitialized)
|
if (!_glfwInitialized)
|
||||||
{
|
{
|
||||||
_glfwSetError(GLFW_NOT_INITIALIZED, NULL);
|
_glfwSetError(GLFW_NOT_INITIALIZED, NULL);
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (monitor == NULL)
|
if (monitor == NULL)
|
||||||
@ -118,26 +127,19 @@ GLFWAPI int glfwGetVideoModes(GLFWmonitor handle, GLFWvidmode* list, int maxcoun
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (maxcount <= 0)
|
if (count == NULL)
|
||||||
{
|
{
|
||||||
_glfwSetError(GLFW_INVALID_VALUE,
|
_glfwSetError(GLFW_INVALID_VALUE, NULL);
|
||||||
"glfwGetVideoModes: Parameter 'maxcount' must be "
|
return NULL;
|
||||||
"greater than zero");
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (list == NULL)
|
free(monitor->modes);
|
||||||
{
|
|
||||||
_glfwSetError(GLFW_INVALID_VALUE,
|
|
||||||
"glfwGetVideoModes: Parameter 'list' cannot be NULL");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
count = _glfwPlatformGetVideoModes(monitor, list, maxcount);
|
monitor->modes = _glfwPlatformGetVideoModes(monitor, count);
|
||||||
if (count > 0)
|
if (monitor->modes)
|
||||||
qsort(list, count, sizeof(GLFWvidmode), _glfwCompareVideoModes);
|
qsort(monitor->modes, *count, sizeof(GLFWvidmode), compareVideoModes);
|
||||||
|
|
||||||
return count;
|
return monitor->modes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -197,22 +197,21 @@ struct _GLFWwindow
|
|||||||
char key[GLFW_KEY_LAST + 1];
|
char key[GLFW_KEY_LAST + 1];
|
||||||
|
|
||||||
// Framebuffer attributes
|
// Framebuffer attributes
|
||||||
int redBits;
|
GLint redBits;
|
||||||
int greenBits;
|
GLint greenBits;
|
||||||
int blueBits;
|
GLint blueBits;
|
||||||
int alphaBits;
|
GLint alphaBits;
|
||||||
int depthBits;
|
GLint depthBits;
|
||||||
int stencilBits;
|
GLint stencilBits;
|
||||||
int accumRedBits;
|
GLint accumRedBits;
|
||||||
int accumGreenBits;
|
GLint accumGreenBits;
|
||||||
int accumBlueBits;
|
GLint accumBlueBits;
|
||||||
int accumAlphaBits;
|
GLint accumAlphaBits;
|
||||||
int auxBuffers;
|
GLint auxBuffers;
|
||||||
GLboolean stereo;
|
GLboolean stereo;
|
||||||
int samples;
|
GLint samples;
|
||||||
|
|
||||||
// OpenGL extensions and context attributes
|
// OpenGL extensions and context attributes
|
||||||
GLboolean accelerated; // GL_TRUE if OpenGL context is "accelerated"
|
|
||||||
int glMajor, glMinor, glRevision;
|
int glMajor, glMinor, glRevision;
|
||||||
GLboolean glForward, glDebug;
|
GLboolean glForward, glDebug;
|
||||||
int glProfile;
|
int glProfile;
|
||||||
@ -242,6 +241,8 @@ struct _GLFWmonitor
|
|||||||
int screenX;
|
int screenX;
|
||||||
int screenY;
|
int screenY;
|
||||||
|
|
||||||
|
GLFWvidmode* modes;
|
||||||
|
|
||||||
// These are defined in the current port's platform.h
|
// These are defined in the current port's platform.h
|
||||||
_GLFW_PLATFORM_MONITOR_STATE;
|
_GLFW_PLATFORM_MONITOR_STATE;
|
||||||
};
|
};
|
||||||
@ -313,7 +314,7 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, int x, int y);
|
|||||||
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode);
|
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode);
|
||||||
|
|
||||||
// Fullscreen
|
// Fullscreen
|
||||||
int _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, GLFWvidmode* list, int maxcount);
|
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count);
|
||||||
void _glfwPlatformGetDesktopMode(GLFWvidmode* mode);
|
void _glfwPlatformGetDesktopMode(GLFWvidmode* mode);
|
||||||
|
|
||||||
// Gamma ramp
|
// Gamma ramp
|
||||||
@ -361,11 +362,11 @@ void _glfwPlatformCopyContext(_GLFWwindow* src, _GLFWwindow* dst, unsigned long
|
|||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
// Fullscren management (fullscreen.c)
|
// Fullscren management (fullscreen.c)
|
||||||
|
int _glfwCompareVideoModes(const GLFWvidmode* first, const GLFWvidmode* second);
|
||||||
void _glfwSplitBPP(int bpp, int* red, int* green, int* blue);
|
void _glfwSplitBPP(int bpp, int* red, int* green, int* blue);
|
||||||
int _glfwCompareVideoModes(const void* firstPtr, const void* secondPtr);
|
|
||||||
|
|
||||||
// Error handling (error.c)
|
// Error handling (error.c)
|
||||||
void _glfwSetError(int error, const char* description);
|
void _glfwSetError(int error, const char* format, ...);
|
||||||
|
|
||||||
// Window management (window.c)
|
// Window management (window.c)
|
||||||
void _glfwSetDefaultWindowHints(void);
|
void _glfwSetDefaultWindowHints(void);
|
||||||
@ -390,8 +391,9 @@ int _glfwStringInExtensionString(const char* string, const GLubyte* extensions);
|
|||||||
const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
|
const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
|
||||||
const _GLFWfbconfig* alternatives,
|
const _GLFWfbconfig* alternatives,
|
||||||
unsigned int count);
|
unsigned int count);
|
||||||
|
GLboolean _glfwRefreshContextParams(void);
|
||||||
GLboolean _glfwIsValidContextConfig(_GLFWwndconfig* wndconfig);
|
GLboolean _glfwIsValidContextConfig(_GLFWwndconfig* wndconfig);
|
||||||
GLboolean _glfwIsValidContext(_GLFWwindow* window, _GLFWwndconfig* wndconfig);
|
GLboolean _glfwIsValidContext(_GLFWwndconfig* wndconfig);
|
||||||
|
|
||||||
// Monitor management (monitor.c)
|
// Monitor management (monitor.c)
|
||||||
void _glfwInitMonitors(void);
|
void _glfwInitMonitors(void);
|
||||||
|
@ -8,6 +8,6 @@ Description: A portable library for OpenGL, window and input
|
|||||||
Version: @GLFW_VERSION_FULL@
|
Version: @GLFW_VERSION_FULL@
|
||||||
URL: http://www.glfw.org/
|
URL: http://www.glfw.org/
|
||||||
Requires.private: @GLFW_PKG_DEPS@
|
Requires.private: @GLFW_PKG_DEPS@
|
||||||
Libs: -L${libdir} -lglfw
|
Libs: -L${libdir} -l@GLFW_LIB_NAME@
|
||||||
Libs.private: @GLFW_PKG_LIBS@
|
Libs.private: @GLFW_PKG_LIBS@
|
||||||
Cflags: -I${includedir}
|
Cflags: -I${includedir}
|
162
src/opengl.c
162
src/opengl.c
@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
@ -38,49 +39,45 @@
|
|||||||
// Parses the OpenGL version string and extracts the version number
|
// 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;
|
int i, _major, _minor = 0, _rev = 0;
|
||||||
const GLubyte* version;
|
const char* version;
|
||||||
const GLubyte* ptr;
|
const char* prefixes[] =
|
||||||
const char* glesPrefix = "OpenGL ES ";
|
|
||||||
|
|
||||||
version = glGetString(GL_VERSION);
|
|
||||||
if (!version)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (strncmp((const char*) version, glesPrefix, strlen(glesPrefix)) == 0)
|
|
||||||
{
|
{
|
||||||
// The version string on OpenGL ES has a prefix before the version
|
"OpenGL ES ",
|
||||||
// number, so we skip past it and then continue as normal
|
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
|
for (i = 0; prefixes[i]; i++)
|
||||||
|
|
||||||
ptr = version;
|
|
||||||
for (_major = 0; *ptr >= '0' && *ptr <= '9'; ptr++)
|
|
||||||
_major = 10 * _major + (*ptr - '0');
|
|
||||||
|
|
||||||
if (*ptr == '.')
|
|
||||||
{
|
{
|
||||||
ptr++;
|
const size_t length = strlen(prefixes[i]);
|
||||||
for (_minor = 0; *ptr >= '0' && *ptr <= '9'; ptr++)
|
|
||||||
_minor = 10 * _minor + (*ptr - '0');
|
|
||||||
|
|
||||||
if (*ptr == '.')
|
if (strncmp(version, prefixes[i], length) == 0)
|
||||||
{
|
{
|
||||||
ptr++;
|
version += length;
|
||||||
for (_rev = 0; *ptr >= '0' && *ptr <= '9'; ptr++)
|
break;
|
||||||
_rev = 10 * _rev + (*ptr - '0');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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;
|
*major = _major;
|
||||||
*minor = _minor;
|
*minor = _minor;
|
||||||
*rev = _rev;
|
*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
|
// 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
|
// Read back forward-compatibility flag
|
||||||
{
|
{
|
||||||
@ -366,6 +385,8 @@ GLboolean _glfwIsValidContext(_GLFWwindow* window, _GLFWwndconfig* wndconfig)
|
|||||||
|
|
||||||
if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)
|
if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)
|
||||||
window->glForward = GL_TRUE;
|
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 ||
|
if (window->glMajor < wndconfig->glMajor ||
|
||||||
(window->glMajor == wndconfig->glMajor &&
|
(window->glMajor == wndconfig->glMajor &&
|
||||||
@ -403,21 +456,6 @@ GLboolean _glfwIsValidContext(_GLFWwindow* window, _GLFWwndconfig* wndconfig)
|
|||||||
return GL_FALSE;
|
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;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -513,7 +551,7 @@ GLFWAPI void glfwSwapBuffers(void)
|
|||||||
|
|
||||||
if (!_glfwLibrary.currentWindow)
|
if (!_glfwLibrary.currentWindow)
|
||||||
{
|
{
|
||||||
_glfwSetError(GLFW_NO_CURRENT_WINDOW, NULL);
|
_glfwSetError(GLFW_NO_CURRENT_CONTEXT, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -535,7 +573,7 @@ GLFWAPI void glfwSwapInterval(int interval)
|
|||||||
|
|
||||||
if (!_glfwLibrary.currentWindow)
|
if (!_glfwLibrary.currentWindow)
|
||||||
{
|
{
|
||||||
_glfwSetError(GLFW_NO_CURRENT_WINDOW, NULL);
|
_glfwSetError(GLFW_NO_CURRENT_CONTEXT, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -551,9 +589,6 @@ GLFWAPI int glfwExtensionSupported(const char* extension)
|
|||||||
{
|
{
|
||||||
const GLubyte* extensions;
|
const GLubyte* extensions;
|
||||||
_GLFWwindow* window;
|
_GLFWwindow* window;
|
||||||
GLubyte* where;
|
|
||||||
GLint count;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!_glfwInitialized)
|
if (!_glfwInitialized)
|
||||||
{
|
{
|
||||||
@ -564,14 +599,15 @@ GLFWAPI int glfwExtensionSupported(const char* extension)
|
|||||||
window = _glfwLibrary.currentWindow;
|
window = _glfwLibrary.currentWindow;
|
||||||
if (!window)
|
if (!window)
|
||||||
{
|
{
|
||||||
_glfwSetError(GLFW_NO_CURRENT_WINDOW, NULL);
|
_glfwSetError(GLFW_NO_CURRENT_CONTEXT, NULL);
|
||||||
return GL_FALSE;
|
return GL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extension names should not have spaces
|
if (extension == NULL || *extension == '\0')
|
||||||
where = (GLubyte*) strchr(extension, ' ');
|
{
|
||||||
if (where || *extension == '\0')
|
_glfwSetError(GLFW_INVALID_VALUE, NULL);
|
||||||
return GL_FALSE;
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (window->glMajor < 3)
|
if (window->glMajor < 3)
|
||||||
{
|
{
|
||||||
@ -586,6 +622,9 @@ GLFWAPI int glfwExtensionSupported(const char* extension)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
GLint count;
|
||||||
|
|
||||||
// Check if extension is in the modern OpenGL extensions string list
|
// Check if extension is in the modern OpenGL extensions string list
|
||||||
|
|
||||||
glGetIntegerv(GL_NUM_EXTENSIONS, &count);
|
glGetIntegerv(GL_NUM_EXTENSIONS, &count);
|
||||||
@ -600,11 +639,8 @@ GLFWAPI int glfwExtensionSupported(const char* extension)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Additional platform specific extension checking (e.g. WGL)
|
// Check if extension is in the platform-specific string
|
||||||
if (_glfwPlatformExtensionSupported(extension))
|
return _glfwPlatformExtensionSupported(extension);
|
||||||
return GL_TRUE;
|
|
||||||
|
|
||||||
return GL_FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -623,7 +659,7 @@ GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname)
|
|||||||
|
|
||||||
if (!_glfwLibrary.currentWindow)
|
if (!_glfwLibrary.currentWindow)
|
||||||
{
|
{
|
||||||
_glfwSetError(GLFW_NO_CURRENT_WINDOW, NULL);
|
_glfwSetError(GLFW_NO_CURRENT_CONTEXT, NULL);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,52 +182,87 @@ void _glfwRestoreVideoMode(void)
|
|||||||
// Get a list of available video modes
|
// 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 deviceModeIndex = 0, count = 0;
|
||||||
int modeCount = 0;
|
GLFWvidmode* result = NULL;
|
||||||
|
WCHAR* deviceName;
|
||||||
|
|
||||||
WCHAR* deviceName = _glfwCreateWideStringFromUTF8(monitor->Win32.name);
|
deviceName = _glfwCreateWideStringFromUTF8(monitor->Win32.name);
|
||||||
if (!deviceName)
|
if (!deviceName)
|
||||||
return 0;
|
{
|
||||||
|
_glfwSetError(GLFW_PLATFORM_ERROR, "Win32: Failed to convert device name");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*found = 0;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
GLFWvidmode mode;
|
GLFWvidmode mode;
|
||||||
DEVMODE deviceMode;
|
DEVMODE dm;
|
||||||
|
|
||||||
ZeroMemory(&deviceMode, sizeof(DEVMODE));
|
ZeroMemory(&dm, sizeof(DEVMODE));
|
||||||
deviceMode.dmSize = sizeof(DEVMODE);
|
dm.dmSize = sizeof(DEVMODE);
|
||||||
|
|
||||||
if (!EnumDisplaySettings(deviceName, deviceModeIndex, &deviceMode))
|
if (!EnumDisplaySettings(deviceName, deviceModeIndex, &dm))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
deviceModeIndex++;
|
deviceModeIndex++;
|
||||||
if (deviceMode.dmBitsPerPel < 15)
|
|
||||||
|
if (dm.dmBitsPerPel < 15)
|
||||||
|
{
|
||||||
|
// Skip modes with less than 15 BPP
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
mode.height = deviceMode.dmPelsHeight;
|
mode.width = dm.dmPelsWidth;
|
||||||
mode.width = deviceMode.dmPelsWidth;
|
mode.height = dm.dmPelsHeight;
|
||||||
_glfwSplitBPP(deviceMode.dmBitsPerPel,
|
_glfwSplitBPP(dm.dmBitsPerPel,
|
||||||
&mode.redBits,
|
&mode.redBits,
|
||||||
&mode.greenBits,
|
&mode.greenBits,
|
||||||
&mode.blueBits);
|
&mode.blueBits);
|
||||||
|
|
||||||
// Skip duplicate modes
|
for (i = 0; i < *found; i++)
|
||||||
if (bsearch(&mode, list, modeCount, sizeof(GLFWvidmode), _glfwCompareVideoModes))
|
{
|
||||||
|
if (_glfwCompareVideoModes(result + i, &mode) == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < *found)
|
||||||
|
{
|
||||||
|
// This is a duplicate, so skip it
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
list[modeCount] = mode;
|
if (*found == count)
|
||||||
modeCount++;
|
{
|
||||||
|
void* larger;
|
||||||
|
|
||||||
qsort(list, modeCount, sizeof(GLFWvidmode), _glfwCompareVideoModes);
|
if (count)
|
||||||
|
count *= 2;
|
||||||
|
else
|
||||||
|
count = 128;
|
||||||
|
|
||||||
if (modeCount >= maxcount)
|
larger = realloc(result, count * sizeof(GLFWvidmode));
|
||||||
break;
|
if (!larger)
|
||||||
|
{
|
||||||
|
free(result);
|
||||||
|
|
||||||
|
_glfwSetError(GLFW_OUT_OF_MEMORY, NULL);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = (GLFWvidmode*) larger;
|
||||||
|
}
|
||||||
|
|
||||||
|
result[*found] = mode;
|
||||||
|
(*found)++;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(deviceName);
|
free(deviceName);
|
||||||
return modeCount;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
74
src/win32_native.c
Normal file
74
src/win32_native.c
Normal 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;
|
||||||
|
}
|
||||||
|
|
@ -31,6 +31,499 @@
|
|||||||
#include "internal.h"
|
#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 //////
|
////// GLFW platform API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -248,6 +248,12 @@ void _glfwInitTimer(void);
|
|||||||
_GLFWmonitor* _glfwCreateMonitors(void);
|
_GLFWmonitor* _glfwCreateMonitors(void);
|
||||||
_GLFWmonitor* _glfwDestroyMonitor(_GLFWmonitor* monitor);
|
_GLFWmonitor* _glfwDestroyMonitor(_GLFWmonitor* monitor);
|
||||||
|
|
||||||
|
// OpenGL support
|
||||||
|
int _glfwCreateContext(_GLFWwindow* window,
|
||||||
|
const _GLFWwndconfig* wndconfig,
|
||||||
|
const _GLFWfbconfig* fbconfig);
|
||||||
|
void _glfwDestroyContext(_GLFWwindow* window);
|
||||||
|
|
||||||
// Fullscreen support
|
// Fullscreen support
|
||||||
void _glfwSetVideoMode(int* width, int* height,
|
void _glfwSetVideoMode(int* width, int* height,
|
||||||
int* bpp, int* refreshRate,
|
int* bpp, int* refreshRate,
|
||||||
|
@ -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
|
// 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
|
// 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
|
// Creates the GLFW window and rendering context
|
||||||
//========================================================================
|
//========================================================================
|
||||||
@ -1282,7 +839,7 @@ static int createWindow(_GLFWwindow* window,
|
|||||||
const _GLFWfbconfig* fbconfig)
|
const _GLFWfbconfig* fbconfig)
|
||||||
{
|
{
|
||||||
DWORD dwStyle, dwExStyle;
|
DWORD dwStyle, dwExStyle;
|
||||||
int pixelFormat, fullWidth, fullHeight;
|
int fullWidth, fullHeight;
|
||||||
RECT wa;
|
RECT wa;
|
||||||
POINT pos;
|
POINT pos;
|
||||||
WCHAR* wideTitle;
|
WCHAR* wideTitle;
|
||||||
@ -1362,31 +919,15 @@ static int createWindow(_GLFWwindow* window,
|
|||||||
|
|
||||||
free(wideTitle);
|
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
|
// Initialize cursor position data
|
||||||
GetCursorPos(&pos);
|
GetCursorPos(&pos);
|
||||||
ScreenToClient(window->Win32.handle, &pos);
|
ScreenToClient(window->Win32.handle, &pos);
|
||||||
window->Win32.oldCursorX = window->cursorPosX = pos.x;
|
window->Win32.oldCursorX = window->cursorPosX = pos.x;
|
||||||
window->Win32.oldCursorY = window->cursorPosY = pos.y;
|
window->Win32.oldCursorY = window->cursorPosY = pos.y;
|
||||||
|
|
||||||
|
if (!_glfwCreateContext(window, wndconfig, fbconfig))
|
||||||
|
return GL_FALSE;
|
||||||
|
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1397,28 +938,13 @@ static int createWindow(_GLFWwindow* window,
|
|||||||
|
|
||||||
static void destroyWindow(_GLFWwindow* window)
|
static void destroyWindow(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
// This is duplicated from glfwCloseWindow
|
_glfwDestroyContext(window);
|
||||||
// TODO: Stop duplicating code
|
|
||||||
if (window == _glfwLibrary.currentWindow)
|
|
||||||
glfwMakeContextCurrent(NULL);
|
|
||||||
|
|
||||||
// This is duplicated from glfwCloseWindow
|
// This is duplicated from glfwCloseWindow
|
||||||
// TODO: Stop duplicating code
|
// TODO: Stop duplicating code
|
||||||
if (window == _glfwLibrary.activeWindow)
|
if (window == _glfwLibrary.activeWindow)
|
||||||
_glfwLibrary.activeWindow = NULL;
|
_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)
|
if (window->Win32.handle)
|
||||||
{
|
{
|
||||||
DestroyWindow(window->Win32.handle);
|
DestroyWindow(window->Win32.handle);
|
||||||
@ -1481,14 +1007,19 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window,
|
|||||||
recreateContext = GL_TRUE;
|
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)
|
if (!window->WGL.ARB_create_context)
|
||||||
{
|
{
|
||||||
_glfwSetError(GLFW_VERSION_UNAVAILABLE,
|
_glfwSetError(GLFW_VERSION_UNAVAILABLE,
|
||||||
"Win32/WGL: A forward compatible or debug OpenGL "
|
"Win32/WGL: A forward compatible OpenGL context "
|
||||||
"context requested but WGL_ARB_create_context is "
|
"requested but WGL_ARB_create_context is unavailable");
|
||||||
"unavailable");
|
|
||||||
return GL_FALSE;
|
return GL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1678,93 +1209,10 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window)
|
|||||||
|
|
||||||
void _glfwPlatformRefreshWindowParams(void)
|
void _glfwPlatformRefreshWindowParams(void)
|
||||||
{
|
{
|
||||||
PIXELFORMATDESCRIPTOR pfd;
|
|
||||||
DEVMODE dm;
|
DEVMODE dm;
|
||||||
int pixelFormat;
|
|
||||||
|
|
||||||
_GLFWwindow* window = _glfwLibrary.currentWindow;
|
_GLFWwindow* window = _glfwLibrary.currentWindow;
|
||||||
|
|
||||||
// Obtain a detailed description of current pixel format
|
ZeroMemory(&dm, sizeof(DEVMODE));
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
dm.dmSize = sizeof(DEVMODE);
|
dm.dmSize = sizeof(DEVMODE);
|
||||||
|
|
||||||
if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm))
|
if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm))
|
||||||
|
13
src/window.c
13
src/window.c
@ -319,10 +319,17 @@ GLFWAPI GLFWwindow glfwOpenWindow(int width, int height,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Cache the actual (as opposed to desired) window parameters
|
// Cache the actual (as opposed to desired) window parameters
|
||||||
glfwMakeContextCurrent(window);
|
|
||||||
_glfwPlatformRefreshWindowParams();
|
_glfwPlatformRefreshWindowParams();
|
||||||
|
|
||||||
if (!_glfwIsValidContext(window, &wndconfig))
|
glfwMakeContextCurrent(window);
|
||||||
|
|
||||||
|
if (!_glfwRefreshContextParams())
|
||||||
|
{
|
||||||
|
glfwCloseWindow(window);
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_glfwIsValidContext(&wndconfig))
|
||||||
{
|
{
|
||||||
glfwCloseWindow(window);
|
glfwCloseWindow(window);
|
||||||
return GL_FALSE;
|
return GL_FALSE;
|
||||||
@ -682,8 +689,6 @@ GLFWAPI int glfwGetWindowParam(GLFWwindow handle, int param)
|
|||||||
return window == _glfwLibrary.activeWindow;
|
return window == _glfwLibrary.activeWindow;
|
||||||
case GLFW_ICONIFIED:
|
case GLFW_ICONIFIED:
|
||||||
return window->iconified;
|
return window->iconified;
|
||||||
case GLFW_ACCELERATED:
|
|
||||||
return window->accelerated;
|
|
||||||
case GLFW_RED_BITS:
|
case GLFW_RED_BITS:
|
||||||
return window->redBits;
|
return window->redBits;
|
||||||
case GLFW_GREEN_BITS:
|
case GLFW_GREEN_BITS:
|
||||||
|
@ -32,6 +32,105 @@
|
|||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdlib.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 //////
|
////// 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
|
// 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;
|
XVisualInfo* visuals;
|
||||||
int depth;
|
|
||||||
XVisualInfo* vislist;
|
|
||||||
XVisualInfo dummy;
|
XVisualInfo dummy;
|
||||||
int viscount, rgbcount, rescount;
|
int i, j, visualCount, sizeCount, rgbCount;
|
||||||
int* rgbarray;
|
int* rgbs;
|
||||||
struct _glfwResolution* resarray;
|
_GLFWvidsize* sizes;
|
||||||
|
GLFWvidmode* result;
|
||||||
|
|
||||||
// Get list of visuals
|
visuals = XGetVisualInfo(_glfwLibrary.X11.display, 0, &dummy, &visualCount);
|
||||||
vislist = XGetVisualInfo(_glfwLibrary.X11.display, 0, &dummy, &viscount);
|
if (visuals == NULL)
|
||||||
if (vislist == NULL)
|
|
||||||
{
|
{
|
||||||
_glfwSetError(GLFW_PLATFORM_ERROR,
|
_glfwSetError(GLFW_PLATFORM_ERROR,
|
||||||
"X11/GLX: Failed to retrieve the available visuals");
|
"X11/GLX: Failed to retrieve the available visuals");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
rgbarray = (int*) malloc(sizeof(int) * viscount);
|
// Build array of available RGB channel depths
|
||||||
rgbcount = 0;
|
|
||||||
|
|
||||||
// Build RGB array
|
rgbs = (int*) malloc(sizeof(int) * visualCount);
|
||||||
for (k = 0; k < viscount; k++)
|
rgbCount = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < visualCount; i++)
|
||||||
{
|
{
|
||||||
// Does the visual support OpenGL & true color?
|
int gl, rgba, rgb, r, g, b;
|
||||||
glXGetConfig(_glfwLibrary.X11.display, &vislist[k], GLX_USE_GL, &gl);
|
|
||||||
glXGetConfig(_glfwLibrary.X11.display, &vislist[k], GLX_RGBA, &rgba);
|
glXGetConfig(_glfwLibrary.X11.display, &visuals[i], GLX_USE_GL, &gl);
|
||||||
if (gl && rgba)
|
glXGetConfig(_glfwLibrary.X11.display, &visuals[i], GLX_RGBA, &rgba);
|
||||||
|
|
||||||
|
if (!gl || !rgba)
|
||||||
{
|
{
|
||||||
// Get color depth for this visual
|
// The visual lacks OpenGL or true color, so skip it
|
||||||
depth = vislist[k].depth;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Convert to RGB
|
// Convert to RGB channel depths and encode
|
||||||
_glfwSplitBPP(depth, &r, &g, &b);
|
_glfwSplitBPP(visuals[i].depth, &r, &g, &b);
|
||||||
depth = (r << 16) | (g << 8) | b;
|
rgb = (r << 16) | (g << 8) | b;
|
||||||
|
|
||||||
// Is this mode unique?
|
for (j = 0; j < rgbCount; j++)
|
||||||
for (l = 0; l < rgbcount; l++)
|
{
|
||||||
{
|
if (rgbs[j] == rgb)
|
||||||
if (depth == rgbarray[l])
|
break;
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (l >= rgbcount)
|
if (j < rgbCount)
|
||||||
{
|
{
|
||||||
rgbarray[rgbcount] = depth;
|
// This channel depth is a duplicate, so skip it
|
||||||
rgbcount++;
|
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;
|
return result;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -78,6 +78,7 @@ _GLFWmonitor* _glfwDestroyMonitor(_GLFWmonitor* monitor)
|
|||||||
XRRFreeOutputInfo(monitor->X11.output);
|
XRRFreeOutputInfo(monitor->X11.output);
|
||||||
#endif /*_GLFW_HAS_XRANDR*/
|
#endif /*_GLFW_HAS_XRANDR*/
|
||||||
|
|
||||||
|
free(monitor->modes);
|
||||||
free(monitor->name);
|
free(monitor->name);
|
||||||
free(monitor);
|
free(monitor);
|
||||||
|
|
||||||
|
84
src/x11_native.c
Normal file
84
src/x11_native.c
Normal 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;
|
||||||
|
}
|
||||||
|
|
@ -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
|
// Create the actual OpenGL context
|
||||||
//========================================================================
|
//========================================================================
|
||||||
@ -467,8 +401,6 @@ static int createContext(_GLFWwindow* window,
|
|||||||
return GL_FALSE;
|
return GL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
refreshContextParams(window, fbconfigID);
|
|
||||||
|
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -513,7 +445,7 @@ int _glfwInitOpenGL(void)
|
|||||||
// Check if GLX is supported on this display
|
// Check if GLX is supported on this display
|
||||||
if (!glXQueryExtension(_glfwLibrary.X11.display, NULL, NULL))
|
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;
|
return GL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1140,20 +1140,14 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window)
|
|||||||
|
|
||||||
void _glfwPlatformRefreshWindowParams(void)
|
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;
|
_GLFWwindow* window = _glfwLibrary.currentWindow;
|
||||||
|
|
||||||
// Retrieve refresh rate if possible
|
// Retrieve refresh rate if possible
|
||||||
if (_glfwLibrary.X11.RandR.available)
|
if (_glfwLibrary.X11.RandR.available)
|
||||||
{
|
{
|
||||||
#if defined(_GLFW_HAS_XRANDR)
|
#if defined(_GLFW_HAS_XRANDR)
|
||||||
|
XRRScreenConfiguration* sc;
|
||||||
|
|
||||||
sc = XRRGetScreenInfo(_glfwLibrary.X11.display, _glfwLibrary.X11.root);
|
sc = XRRGetScreenInfo(_glfwLibrary.X11.display, _glfwLibrary.X11.root);
|
||||||
window->refreshRate = XRRConfigCurrentRate(sc);
|
window->refreshRate = XRRConfigCurrentRate(sc);
|
||||||
XRRFreeScreenConfigInfo(sc);
|
XRRFreeScreenConfigInfo(sc);
|
||||||
@ -1162,6 +1156,10 @@ void _glfwPlatformRefreshWindowParams(void)
|
|||||||
else if (_glfwLibrary.X11.VidMode.available)
|
else if (_glfwLibrary.X11.VidMode.available)
|
||||||
{
|
{
|
||||||
#if defined(_GLFW_HAS_XF86VIDMODE)
|
#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
|
// Use the XF86VidMode extension to get current video mode
|
||||||
XF86VidModeGetModeLine(_glfwLibrary.X11.display,
|
XF86VidModeGetModeLine(_glfwLibrary.X11.display,
|
||||||
_glfwLibrary.X11.screen,
|
_glfwLibrary.X11.screen,
|
||||||
|
@ -42,7 +42,6 @@ typedef struct
|
|||||||
|
|
||||||
static Param parameters[] =
|
static Param parameters[] =
|
||||||
{
|
{
|
||||||
{ GLFW_ACCELERATED, "accelerated" },
|
|
||||||
{ GLFW_RED_BITS, "red bits" },
|
{ GLFW_RED_BITS, "red bits" },
|
||||||
{ GLFW_GREEN_BITS, "green bits" },
|
{ GLFW_GREEN_BITS, "green bits" },
|
||||||
{ GLFW_BLUE_BITS, "blue bits" },
|
{ GLFW_BLUE_BITS, "blue bits" },
|
||||||
|
@ -249,23 +249,29 @@ int main(int argc, char** argv)
|
|||||||
if (major >= 3)
|
if (major >= 3)
|
||||||
{
|
{
|
||||||
glGetIntegerv(GL_CONTEXT_FLAGS, &flags);
|
glGetIntegerv(GL_CONTEXT_FLAGS, &flags);
|
||||||
printf("OpenGL context flags:");
|
printf("OpenGL context flags (0x%08x):", flags);
|
||||||
|
|
||||||
if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)
|
if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)
|
||||||
puts(" forward-compatible");
|
printf(" forward-compatible");
|
||||||
else
|
if (flags & 0)
|
||||||
puts(" none");
|
printf(" debug");
|
||||||
|
putchar('\n');
|
||||||
|
|
||||||
printf("OpenGL forward-compatible flag parsed by GLFW: %s\n",
|
printf("OpenGL context flags parsed by GLFW:");
|
||||||
glfwGetWindowParam(window, GLFW_OPENGL_FORWARD_COMPAT) ? "true" : "false");
|
|
||||||
|
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))
|
if (major > 3 || (major == 3 && minor >= 2))
|
||||||
{
|
{
|
||||||
glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask);
|
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)));
|
get_glfw_profile_name(glfwGetWindowParam(window, GLFW_OPENGL_PROFILE)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
static void list_modes(GLFWmonitor monitor)
|
||||||
{
|
{
|
||||||
size_t count, i;
|
int count, i;
|
||||||
GLFWvidmode desktop_mode;
|
GLFWvidmode desktop_mode;
|
||||||
|
GLFWvidmode* modes = glfwGetVideoModes(monitor, &count);
|
||||||
|
|
||||||
glfwGetDesktopMode(&desktop_mode);
|
glfwGetDesktopMode(&desktop_mode);
|
||||||
printf("Desktop mode: %s\n", format_mode(&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",
|
printf("Monitor %s (%ix%i mm):\n",
|
||||||
glfwGetMonitorString(monitor, GLFW_MONITOR_NAME),
|
glfwGetMonitorString(monitor, GLFW_MONITOR_NAME),
|
||||||
glfwGetMonitorParam(monitor, GLFW_MONITOR_PHYSICAL_WIDTH),
|
glfwGetMonitorParam(monitor, GLFW_MONITOR_PHYSICAL_WIDTH),
|
||||||
@ -132,15 +113,12 @@ static void list_modes(GLFWmonitor monitor)
|
|||||||
|
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
free(modes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_modes(GLFWmonitor monitor)
|
static void test_modes(GLFWmonitor monitor)
|
||||||
{
|
{
|
||||||
int width, height;
|
int i, count, width, height;
|
||||||
size_t i, count;
|
GLFWvidmode* modes = glfwGetVideoModes(monitor, &count);
|
||||||
GLFWvidmode* modes = get_video_modes(monitor, &count);
|
|
||||||
|
|
||||||
glfwSetWindowSizeCallback(window_size_callback);
|
glfwSetWindowSizeCallback(window_size_callback);
|
||||||
glfwSetWindowCloseCallback(window_close_callback);
|
glfwSetWindowCloseCallback(window_close_callback);
|
||||||
@ -214,8 +192,6 @@ static void test_modes(GLFWmonitor monitor)
|
|||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
window = NULL;
|
window = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(modes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
|
Loading…
Reference in New Issue
Block a user