parent
c87829ea61
commit
55419bda67
9 changed files with 1082 additions and 1239 deletions
@ -1,243 +0,0 @@ |
|||||||
//======================================================================== |
|
||||||
// GLFW - An OpenGL library |
|
||||||
// Platform: Cocoa |
|
||||||
// API Version: 3.0 |
|
||||||
// WWW: http://www.glfw.org/ |
|
||||||
//------------------------------------------------------------------------ |
|
||||||
// Copyright (c) 2009-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" |
|
||||||
|
|
||||||
#include <stdlib.h> |
|
||||||
#include <limits.h> |
|
||||||
|
|
||||||
|
|
||||||
//======================================================================== |
|
||||||
// Check whether the display mode should be included in enumeration |
|
||||||
//======================================================================== |
|
||||||
|
|
||||||
static GLboolean modeIsGood(CGDisplayModeRef mode) |
|
||||||
{ |
|
||||||
uint32_t flags = CGDisplayModeGetIOFlags(mode); |
|
||||||
if (!(flags & kDisplayModeValidFlag) || !(flags & kDisplayModeSafeFlag)) |
|
||||||
return GL_FALSE; |
|
||||||
|
|
||||||
if (flags & kDisplayModeInterlacedFlag) |
|
||||||
return GL_FALSE; |
|
||||||
|
|
||||||
if (flags & kDisplayModeTelevisionFlag) |
|
||||||
return GL_FALSE; |
|
||||||
|
|
||||||
if (flags & kDisplayModeStretchedFlag) |
|
||||||
return GL_FALSE; |
|
||||||
|
|
||||||
CFStringRef format = CGDisplayModeCopyPixelEncoding(mode); |
|
||||||
if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) && |
|
||||||
CFStringCompare(format, CFSTR(IO32BitDirectPixels), 0)) |
|
||||||
{ |
|
||||||
CFRelease(format); |
|
||||||
return GL_FALSE; |
|
||||||
} |
|
||||||
|
|
||||||
CFRelease(format); |
|
||||||
return GL_TRUE; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
//======================================================================== |
|
||||||
// Convert Core Graphics display mode to GLFW video mode |
|
||||||
//======================================================================== |
|
||||||
|
|
||||||
static GLFWvidmode vidmodeFromCGDisplayMode(CGDisplayModeRef mode) |
|
||||||
{ |
|
||||||
GLFWvidmode result; |
|
||||||
result.width = CGDisplayModeGetWidth(mode); |
|
||||||
result.height = CGDisplayModeGetHeight(mode); |
|
||||||
|
|
||||||
CFStringRef format = CGDisplayModeCopyPixelEncoding(mode); |
|
||||||
|
|
||||||
if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) == 0) |
|
||||||
{ |
|
||||||
result.redBits = 5; |
|
||||||
result.greenBits = 5; |
|
||||||
result.blueBits = 5; |
|
||||||
} |
|
||||||
else |
|
||||||
{ |
|
||||||
result.redBits = 8; |
|
||||||
result.greenBits = 8; |
|
||||||
result.blueBits = 8; |
|
||||||
} |
|
||||||
|
|
||||||
CFRelease(format); |
|
||||||
return result; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////// |
|
||||||
////// GLFW internal API ////// |
|
||||||
////////////////////////////////////////////////////////////////////////// |
|
||||||
|
|
||||||
//======================================================================== |
|
||||||
// Change the current video mode |
|
||||||
//======================================================================== |
|
||||||
|
|
||||||
GLboolean _glfwSetVideoMode(int* width, int* height, int* bpp, int* refreshRate) |
|
||||||
{ |
|
||||||
CGDisplayModeRef bestMode = NULL; |
|
||||||
CFArrayRef modes; |
|
||||||
CFIndex count, i; |
|
||||||
unsigned int leastSizeDiff = UINT_MAX; |
|
||||||
double leastRateDiff = DBL_MAX; |
|
||||||
|
|
||||||
modes = CGDisplayCopyAllDisplayModes(CGMainDisplayID(), NULL); |
|
||||||
count = CFArrayGetCount(modes); |
|
||||||
|
|
||||||
for (i = 0; i < count; i++) |
|
||||||
{ |
|
||||||
CGDisplayModeRef mode = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i); |
|
||||||
if (!modeIsGood(mode)) |
|
||||||
continue; |
|
||||||
|
|
||||||
int modeBPP; |
|
||||||
|
|
||||||
// Identify display mode pixel encoding |
|
||||||
{ |
|
||||||
CFStringRef format = CGDisplayModeCopyPixelEncoding(mode); |
|
||||||
|
|
||||||
if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) == 0) |
|
||||||
modeBPP = 16; |
|
||||||
else |
|
||||||
modeBPP = 32; |
|
||||||
|
|
||||||
CFRelease(format); |
|
||||||
} |
|
||||||
|
|
||||||
int modeWidth = (int) CGDisplayModeGetWidth(mode); |
|
||||||
int modeHeight = (int) CGDisplayModeGetHeight(mode); |
|
||||||
|
|
||||||
unsigned int sizeDiff = (abs(modeBPP - *bpp) << 25) | |
|
||||||
((modeWidth - *width) * (modeWidth - *width) + |
|
||||||
(modeHeight - *height) * (modeHeight - *height)); |
|
||||||
|
|
||||||
double rateDiff; |
|
||||||
|
|
||||||
if (*refreshRate > 0) |
|
||||||
rateDiff = fabs(CGDisplayModeGetRefreshRate(mode) - *refreshRate); |
|
||||||
else |
|
||||||
{ |
|
||||||
// If no refresh rate was specified, then they're all the same |
|
||||||
rateDiff = 0; |
|
||||||
} |
|
||||||
|
|
||||||
if ((sizeDiff < leastSizeDiff) || |
|
||||||
(sizeDiff == leastSizeDiff && (rateDiff < leastRateDiff))) |
|
||||||
{ |
|
||||||
bestMode = mode; |
|
||||||
|
|
||||||
leastSizeDiff = sizeDiff; |
|
||||||
leastRateDiff = rateDiff; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
if (!bestMode) |
|
||||||
{ |
|
||||||
CFRelease(modes); |
|
||||||
return GL_FALSE; |
|
||||||
} |
|
||||||
|
|
||||||
_glfwLibrary.NS.previousMode = CGDisplayCopyDisplayMode(CGMainDisplayID()); |
|
||||||
|
|
||||||
CGDisplayCapture(CGMainDisplayID()); |
|
||||||
CGDisplaySetDisplayMode(CGMainDisplayID(), bestMode, NULL); |
|
||||||
|
|
||||||
CFRelease(modes); |
|
||||||
return GL_TRUE; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
//======================================================================== |
|
||||||
// Restore the previously saved (original) video mode |
|
||||||
//======================================================================== |
|
||||||
|
|
||||||
void _glfwRestoreVideoMode(void) |
|
||||||
{ |
|
||||||
CGDisplaySetDisplayMode(CGMainDisplayID(), |
|
||||||
_glfwLibrary.NS.previousMode, |
|
||||||
NULL); |
|
||||||
|
|
||||||
CGDisplayRelease(CGMainDisplayID()); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////// |
|
||||||
////// GLFW platform API ////// |
|
||||||
////////////////////////////////////////////////////////////////////////// |
|
||||||
|
|
||||||
//======================================================================== |
|
||||||
// Get a list of available video modes |
|
||||||
//======================================================================== |
|
||||||
|
|
||||||
GLFWvidmode* _glfwPlatformGetVideoModes(int* found) |
|
||||||
{ |
|
||||||
CFArrayRef modes; |
|
||||||
CFIndex count, i; |
|
||||||
GLFWvidmode* result; |
|
||||||
|
|
||||||
modes = CGDisplayCopyAllDisplayModes(CGMainDisplayID(), NULL); |
|
||||||
count = CFArrayGetCount(modes); |
|
||||||
|
|
||||||
result = (GLFWvidmode*) malloc(sizeof(GLFWvidmode) * count); |
|
||||||
*found = 0; |
|
||||||
|
|
||||||
for (i = 0; i < count; i++) |
|
||||||
{ |
|
||||||
CGDisplayModeRef mode; |
|
||||||
|
|
||||||
mode = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i); |
|
||||||
if (modeIsGood(mode)) |
|
||||||
{ |
|
||||||
result[*found] = vidmodeFromCGDisplayMode(mode); |
|
||||||
(*found)++; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
CFRelease(modes); |
|
||||||
return result; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
//======================================================================== |
|
||||||
// Get the current video mode for the specified monitor |
|
||||||
//======================================================================== |
|
||||||
|
|
||||||
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode *mode) |
|
||||||
{ |
|
||||||
CGDisplayModeRef displayMode; |
|
||||||
|
|
||||||
displayMode = CGDisplayCopyDisplayMode(CGMainDisplayID()); |
|
||||||
*mode = vidmodeFromCGDisplayMode(displayMode); |
|
||||||
CGDisplayModeRelease(displayMode); |
|
||||||
} |
|
||||||
|
|
@ -1,172 +0,0 @@ |
|||||||
//========================================================================
|
|
||||||
// GLFW - An OpenGL library
|
|
||||||
// Platform: Any
|
|
||||||
// API version: 3.0
|
|
||||||
// WWW: http://www.glfw.org/
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
|
||||||
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
|
||||||
// Copyright (c) 2012 Torsten Walluhn <tw@mad-cad.net>
|
|
||||||
//
|
|
||||||
// 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" |
|
||||||
|
|
||||||
#include <stdlib.h> |
|
||||||
#if _WIN32 |
|
||||||
#include <malloc.h> |
|
||||||
#endif |
|
||||||
|
|
||||||
|
|
||||||
//========================================================================
|
|
||||||
// Lexical comparison function for GLFW video modes, used by qsort
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
int compareVideoModes(const void* firstPtr, const void* secondPtr) |
|
||||||
{ |
|
||||||
int firstBPP, secondBPP, firstSize, secondSize; |
|
||||||
GLFWvidmode* first = (GLFWvidmode*) firstPtr; |
|
||||||
GLFWvidmode* second = (GLFWvidmode*) secondPtr; |
|
||||||
|
|
||||||
// First sort on color bits per pixel
|
|
||||||
|
|
||||||
firstBPP = first->redBits + |
|
||||||
first->greenBits + |
|
||||||
first->blueBits; |
|
||||||
secondBPP = second->redBits + |
|
||||||
second->greenBits + |
|
||||||
second->blueBits; |
|
||||||
|
|
||||||
if (firstBPP != secondBPP) |
|
||||||
return firstBPP - secondBPP; |
|
||||||
|
|
||||||
// Then sort on screen area, in pixels
|
|
||||||
|
|
||||||
firstSize = first->width * first->height; |
|
||||||
secondSize = second->width * second->height; |
|
||||||
|
|
||||||
return firstSize - secondSize; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
////// 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"
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
void _glfwSplitBPP(int bpp, int* red, int* green, int* blue) |
|
||||||
{ |
|
||||||
int delta; |
|
||||||
|
|
||||||
// We assume that by 32 the user really meant 24
|
|
||||||
if (bpp == 32) |
|
||||||
bpp = 24; |
|
||||||
|
|
||||||
// Convert "bits per pixel" to red, green & blue sizes
|
|
||||||
|
|
||||||
*red = *green = *blue = bpp / 3; |
|
||||||
delta = bpp - (*red * 3); |
|
||||||
if (delta >= 1) |
|
||||||
*green = *green + 1; |
|
||||||
|
|
||||||
if (delta == 2) |
|
||||||
*red = *red + 1; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
////// GLFW public API //////
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//========================================================================
|
|
||||||
// Get a list of available video modes
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
GLFWAPI GLFWvidmode* glfwGetVideoModes(GLFWmonitor handle, int* count) |
|
||||||
{ |
|
||||||
_GLFWmonitor* monitor = (_GLFWmonitor*) handle; |
|
||||||
|
|
||||||
if (!_glfwInitialized) |
|
||||||
{ |
|
||||||
_glfwSetError(GLFW_NOT_INITIALIZED, NULL); |
|
||||||
return NULL; |
|
||||||
} |
|
||||||
|
|
||||||
if (monitor == NULL) |
|
||||||
{ |
|
||||||
_glfwSetError(GLFW_INVALID_VALUE, |
|
||||||
"glfwGetVideoModes: Invalid monitor handle"); |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
if (count == NULL) |
|
||||||
{ |
|
||||||
_glfwSetError(GLFW_INVALID_VALUE, NULL); |
|
||||||
return NULL; |
|
||||||
} |
|
||||||
|
|
||||||
free(monitor->modes); |
|
||||||
|
|
||||||
monitor->modes = _glfwPlatformGetVideoModes(monitor, count); |
|
||||||
if (monitor->modes) |
|
||||||
qsort(monitor->modes, *count, sizeof(GLFWvidmode), compareVideoModes); |
|
||||||
|
|
||||||
return monitor->modes; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
//========================================================================
|
|
||||||
// Get the current video mode for the specified monitor
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
GLFWAPI void glfwGetVideoMode(GLFWmonitor handle, GLFWvidmode* mode) |
|
||||||
{ |
|
||||||
_GLFWmonitor* monitor = (_GLFWmonitor*) handle; |
|
||||||
|
|
||||||
if (!_glfwInitialized) |
|
||||||
{ |
|
||||||
_glfwSetError(GLFW_NOT_INITIALIZED, NULL); |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
if (mode == NULL) |
|
||||||
{ |
|
||||||
_glfwSetError(GLFW_INVALID_VALUE, NULL); |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
_glfwPlatformGetVideoMode(monitor, mode); |
|
||||||
} |
|
||||||
|
|
@ -1,281 +0,0 @@ |
|||||||
//========================================================================
|
|
||||||
// GLFW - An OpenGL library
|
|
||||||
// Platform: Win32
|
|
||||||
// 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.
|
|
||||||
//
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
#include "internal.h" |
|
||||||
|
|
||||||
#include <stdlib.h> |
|
||||||
#include <limits.h> |
|
||||||
#include <malloc.h> |
|
||||||
|
|
||||||
|
|
||||||
//========================================================================
|
|
||||||
// Return closest video mode by dimensions, refresh rate and bits per pixel
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
static GLboolean getClosestVideoMode(int* width, int* height, |
|
||||||
int* bpp, int* refreshRate, |
|
||||||
GLboolean exactBPP) |
|
||||||
{ |
|
||||||
int mode, bestWidth, bestHeight, bestBPP, bestRate; |
|
||||||
unsigned int sizeDiff, rateDiff, leastSizeDiff, leastRateDiff; |
|
||||||
GLboolean foundMode = GL_FALSE; |
|
||||||
DEVMODE dm; |
|
||||||
|
|
||||||
leastSizeDiff = leastRateDiff = UINT_MAX; |
|
||||||
|
|
||||||
for (mode = 0; ; mode++) |
|
||||||
{ |
|
||||||
dm.dmSize = sizeof(DEVMODE); |
|
||||||
if (!EnumDisplaySettings(NULL, mode, &dm)) |
|
||||||
break; |
|
||||||
|
|
||||||
if (exactBPP && dm.dmBitsPerPel != *bpp) |
|
||||||
continue; |
|
||||||
|
|
||||||
sizeDiff = (abs(dm.dmBitsPerPel - *bpp) << 25) | |
|
||||||
((dm.dmPelsWidth - *width) * |
|
||||||
(dm.dmPelsWidth - *width) + |
|
||||||
(dm.dmPelsHeight - *height) * |
|
||||||
(dm.dmPelsHeight - *height)); |
|
||||||
|
|
||||||
if (*refreshRate > 0) |
|
||||||
{ |
|
||||||
rateDiff = (dm.dmDisplayFrequency - *refreshRate) * |
|
||||||
(dm.dmDisplayFrequency - *refreshRate); |
|
||||||
} |
|
||||||
else |
|
||||||
{ |
|
||||||
// If no refresh rate was specified, then they're all the same
|
|
||||||
rateDiff = 0; |
|
||||||
} |
|
||||||
|
|
||||||
// We match first BPP, then screen area and last refresh rate
|
|
||||||
|
|
||||||
if ((sizeDiff < leastSizeDiff) || |
|
||||||
(sizeDiff == leastSizeDiff && (rateDiff < leastRateDiff))) |
|
||||||
{ |
|
||||||
bestWidth = dm.dmPelsWidth; |
|
||||||
bestHeight = dm.dmPelsHeight; |
|
||||||
bestBPP = dm.dmBitsPerPel; |
|
||||||
bestRate = dm.dmDisplayFrequency; |
|
||||||
|
|
||||||
leastSizeDiff = sizeDiff; |
|
||||||
leastRateDiff = rateDiff; |
|
||||||
|
|
||||||
foundMode = GL_TRUE; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
if (!foundMode) |
|
||||||
return GL_FALSE; |
|
||||||
|
|
||||||
*width = bestWidth; |
|
||||||
*height = bestHeight; |
|
||||||
*bpp = bestBPP; |
|
||||||
|
|
||||||
// Only save the found refresh rate if the client requested a specific
|
|
||||||
// rate; otherwise keep it at zero to let Windows select the best rate
|
|
||||||
if (*refreshRate > 0) |
|
||||||
*refreshRate = bestRate; |
|
||||||
|
|
||||||
return GL_TRUE; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
////// GLFW internal API //////
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//========================================================================
|
|
||||||
// Change the current video mode
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
void _glfwSetVideoMode(int* width, int* height, |
|
||||||
int* bpp, int* refreshRate, |
|
||||||
GLboolean exactBPP) |
|
||||||
{ |
|
||||||
DEVMODE dm; |
|
||||||
int closestWidth, closestHeight, closestBPP, closestRate; |
|
||||||
|
|
||||||
closestWidth = *width; |
|
||||||
closestHeight = *height; |
|
||||||
closestBPP = *bpp; |
|
||||||
closestRate = *refreshRate; |
|
||||||
|
|
||||||
if (getClosestVideoMode(&closestWidth, &closestHeight, |
|
||||||
&closestBPP, &closestRate, GL_FALSE)) |
|
||||||
{ |
|
||||||
dm.dmSize = sizeof(DEVMODE); |
|
||||||
dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL; |
|
||||||
dm.dmPelsWidth = closestWidth; |
|
||||||
dm.dmPelsHeight = closestHeight; |
|
||||||
dm.dmBitsPerPel = closestBPP; |
|
||||||
|
|
||||||
if (*refreshRate > 0) |
|
||||||
{ |
|
||||||
dm.dmFields |= DM_DISPLAYFREQUENCY; |
|
||||||
dm.dmDisplayFrequency = closestRate; |
|
||||||
} |
|
||||||
|
|
||||||
if (ChangeDisplaySettings(&dm, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL) |
|
||||||
{ |
|
||||||
*width = closestWidth; |
|
||||||
*height = closestHeight; |
|
||||||
*bpp = closestBPP; |
|
||||||
*refreshRate = closestRate; |
|
||||||
} |
|
||||||
} |
|
||||||
else |
|
||||||
{ |
|
||||||
dm.dmSize = sizeof(DEVMODE); |
|
||||||
EnumDisplaySettings(NULL, ENUM_REGISTRY_SETTINGS, &dm); |
|
||||||
|
|
||||||
*width = dm.dmPelsWidth; |
|
||||||
*height = dm.dmPelsHeight; |
|
||||||
*bpp = dm.dmBitsPerPel; |
|
||||||
*refreshRate = dm.dmDisplayFrequency; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
//========================================================================
|
|
||||||
// Restore the previously saved (original) video mode
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
void _glfwRestoreVideoMode(void) |
|
||||||
{ |
|
||||||
ChangeDisplaySettings(NULL, CDS_FULLSCREEN); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
////// GLFW platform API //////
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//========================================================================
|
|
||||||
// Get a list of available video modes
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found) |
|
||||||
{ |
|
||||||
int modeIndex = 0, count = 0; |
|
||||||
GLFWvidmode* result = NULL; |
|
||||||
|
|
||||||
*found = 0; |
|
||||||
|
|
||||||
for (;;) |
|
||||||
{ |
|
||||||
int i; |
|
||||||
GLFWvidmode mode; |
|
||||||
DEVMODE dm; |
|
||||||
|
|
||||||
ZeroMemory(&dm, sizeof(DEVMODE)); |
|
||||||
dm.dmSize = sizeof(DEVMODE); |
|
||||||
|
|
||||||
if (!EnumDisplaySettings(monitor->Win32.name, modeIndex, &dm)) |
|
||||||
break; |
|
||||||
|
|
||||||
modeIndex++; |
|
||||||
|
|
||||||
if (dm.dmBitsPerPel < 15) |
|
||||||
{ |
|
||||||
// Skip modes with less than 15 BPP
|
|
||||||
continue; |
|
||||||
} |
|
||||||
|
|
||||||
mode.width = dm.dmPelsWidth; |
|
||||||
mode.height = dm.dmPelsHeight; |
|
||||||
_glfwSplitBPP(dm.dmBitsPerPel, |
|
||||||
&mode.redBits, |
|
||||||
&mode.greenBits, |
|
||||||
&mode.blueBits); |
|
||||||
|
|
||||||
for (i = 0; i < *found; i++) |
|
||||||
{ |
|
||||||
if (_glfwCompareVideoModes(result + i, &mode) == 0) |
|
||||||
break; |
|
||||||
} |
|
||||||
|
|
||||||
if (i < *found) |
|
||||||
{ |
|
||||||
// This is a duplicate, so skip it
|
|
||||||
continue; |
|
||||||
} |
|
||||||
|
|
||||||
if (*found == count) |
|
||||||
{ |
|
||||||
void* larger; |
|
||||||
|
|
||||||
if (count) |
|
||||||
count *= 2; |
|
||||||
else |
|
||||||
count = 128; |
|
||||||
|
|
||||||
larger = realloc(result, count * sizeof(GLFWvidmode)); |
|
||||||
if (!larger) |
|
||||||
{ |
|
||||||
free(result); |
|
||||||
|
|
||||||
_glfwSetError(GLFW_OUT_OF_MEMORY, NULL); |
|
||||||
return NULL; |
|
||||||
} |
|
||||||
|
|
||||||
result = (GLFWvidmode*) larger; |
|
||||||
} |
|
||||||
|
|
||||||
result[*found] = mode; |
|
||||||
(*found)++; |
|
||||||
} |
|
||||||
|
|
||||||
return result; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
//========================================================================
|
|
||||||
// Get the current video mode for the specified monitor
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) |
|
||||||
{ |
|
||||||
DEVMODE dm; |
|
||||||
|
|
||||||
ZeroMemory(&dm, sizeof(DEVMODE)); |
|
||||||
dm.dmSize = sizeof(DEVMODE); |
|
||||||
|
|
||||||
EnumDisplaySettings(monitor->Win32.name, ENUM_REGISTRY_SETTINGS, &dm); |
|
||||||
|
|
||||||
mode->width = dm.dmPelsWidth; |
|
||||||
mode->height = dm.dmPelsHeight; |
|
||||||
_glfwSplitBPP(dm.dmBitsPerPel, |
|
||||||
&mode->redBits, |
|
||||||
&mode->greenBits, |
|
||||||
&mode->blueBits); |
|
||||||
} |
|
||||||
|
|
@ -1,531 +0,0 @@ |
|||||||
//========================================================================
|
|
||||||
// GLFW - An OpenGL library
|
|
||||||
// Platform: X11
|
|
||||||
// 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.
|
|
||||||
//
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
#include "internal.h" |
|
||||||
|
|
||||||
#include <limits.h> |
|
||||||
#include <stdlib.h> |
|
||||||
#include <string.h> |
|
||||||
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
// Display resolution
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
|
|
||||||
typedef struct |
|
||||||
{ |
|
||||||
int width; |
|
||||||
int height; |
|
||||||
} _GLFWvidsize; |
|
||||||
|
|
||||||
|
|
||||||
//========================================================================
|
|
||||||
// List available resolutions
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
static _GLFWvidsize* getResolutions(_GLFWmonitor* monitor, int* found) |
|
||||||
{ |
|
||||||
int i, j; |
|
||||||
_GLFWvidsize* result = NULL; |
|
||||||
|
|
||||||
*found = 0; |
|
||||||
|
|
||||||
// Build array of available resolutions
|
|
||||||
|
|
||||||
if (_glfwLibrary.X11.RandR.available) |
|
||||||
{ |
|
||||||
#if defined(_GLFW_HAS_XRANDR) |
|
||||||
XRRScreenConfiguration* sc; |
|
||||||
XRRScreenSize* sizes; |
|
||||||
|
|
||||||
sc = XRRGetScreenInfo(_glfwLibrary.X11.display, _glfwLibrary.X11.root); |
|
||||||
sizes = XRRConfigSizes(sc, found); |
|
||||||
|
|
||||||
result = (_GLFWvidsize*) malloc(sizeof(_GLFWvidsize) * *found); |
|
||||||
|
|
||||||
for (i = 0; i < *found; i++) |
|
||||||
{ |
|
||||||
result[i].width = sizes[i].width; |
|
||||||
result[i].height = sizes[i].height; |
|
||||||
} |
|
||||||
|
|
||||||
XRRFreeScreenConfigInfo(sc); |
|
||||||
#endif /*_GLFW_HAS_XRANDR*/ |
|
||||||
} |
|
||||||
else if (_glfwLibrary.X11.VidMode.available) |
|
||||||
{ |
|
||||||
#if defined(_GLFW_HAS_XF86VIDMODE) |
|
||||||
XF86VidModeModeInfo** modes; |
|
||||||
int modeCount; |
|
||||||
|
|
||||||
XF86VidModeGetAllModeLines(_glfwLibrary.X11.display, |
|
||||||
_glfwLibrary.X11.screen, |
|
||||||
&modeCount, &modes); |
|
||||||
|
|
||||||
result = (_GLFWvidsize*) malloc(sizeof(_GLFWvidsize) * modeCount); |
|
||||||
|
|
||||||
for (i = 0; i < modeCount; i++) |
|
||||||
{ |
|
||||||
_GLFWvidsize size; |
|
||||||
size.width = modes[i]->hdisplay; |
|
||||||
size.height = modes[i]->vdisplay; |
|
||||||
|
|
||||||
for (j = 0; j < *found; j++) |
|
||||||
{ |
|
||||||
if (memcmp(result + j, &size, sizeof(_GLFWvidsize)) == 0) |
|
||||||
break; |
|
||||||
} |
|
||||||
|
|
||||||
if (j < *found) |
|
||||||
{ |
|
||||||
// This size is a duplicate, so skip it
|
|
||||||
continue; |
|
||||||
} |
|
||||||
|
|
||||||
result[*found] = size; |
|
||||||
(*found)++; |
|
||||||
} |
|
||||||
|
|
||||||
XFree(modes); |
|
||||||
#endif /*_GLFW_HAS_XF86VIDMODE*/ |
|
||||||
} |
|
||||||
|
|
||||||
if (result == NULL) |
|
||||||
{ |
|
||||||
*found = 1; |
|
||||||
result = (_GLFWvidsize*) malloc(sizeof(_GLFWvidsize)); |
|
||||||
|
|
||||||
result[0].width = DisplayWidth(_glfwLibrary.X11.display, |
|
||||||
_glfwLibrary.X11.screen); |
|
||||||
result[0].height = DisplayHeight(_glfwLibrary.X11.display, |
|
||||||
_glfwLibrary.X11.screen); |
|
||||||
} |
|
||||||
|
|
||||||
return result; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
////// GLFW internal API //////
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//========================================================================
|
|
||||||
// Finds the video mode closest in size to the specified desired size
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
int _glfwGetClosestVideoMode(int* width, int* height, int* rate) |
|
||||||
{ |
|
||||||
int i, match, bestmatch; |
|
||||||
|
|
||||||
if (_glfwLibrary.X11.RandR.available) |
|
||||||
{ |
|
||||||
#if defined(_GLFW_HAS_XRANDR) |
|
||||||
int sizecount, bestsize; |
|
||||||
int ratecount, bestrate; |
|
||||||
short* ratelist; |
|
||||||
XRRScreenConfiguration* sc; |
|
||||||
XRRScreenSize* sizelist; |
|
||||||
|
|
||||||
sc = XRRGetScreenInfo(_glfwLibrary.X11.display, _glfwLibrary.X11.root); |
|
||||||
|
|
||||||
sizelist = XRRConfigSizes(sc, &sizecount); |
|
||||||
|
|
||||||
// Find the best matching mode
|
|
||||||
bestsize = -1; |
|
||||||
bestmatch = INT_MAX; |
|
||||||
for (i = 0; i < sizecount; i++) |
|
||||||
{ |
|
||||||
match = (*width - sizelist[i].width) * |
|
||||||
(*width - sizelist[i].width) + |
|
||||||
(*height - sizelist[i].height) * |
|
||||||
(*height - sizelist[i].height); |
|
||||||
if (match < bestmatch) |
|
||||||
{ |
|
||||||
bestmatch = match; |
|
||||||
bestsize = i; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
if (bestsize != -1) |
|
||||||
{ |
|
||||||
// Report width & height of best matching mode
|
|
||||||
*width = sizelist[bestsize].width; |
|
||||||
*height = sizelist[bestsize].height; |
|
||||||
|
|
||||||
if (*rate > 0) |
|
||||||
{ |
|
||||||
ratelist = XRRConfigRates(sc, bestsize, &ratecount); |
|
||||||
|
|
||||||
bestrate = -1; |
|
||||||
bestmatch = INT_MAX; |
|
||||||
for (i = 0; i < ratecount; i++) |
|
||||||
{ |
|
||||||
match = abs(ratelist[i] - *rate); |
|
||||||
if (match < bestmatch) |
|
||||||
{ |
|
||||||
bestmatch = match; |
|
||||||
bestrate = ratelist[i]; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
if (bestrate != -1) |
|
||||||
*rate = bestrate; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
XRRFreeScreenConfigInfo(sc); |
|
||||||
|
|
||||||
if (bestsize != -1) |
|
||||||
return bestsize; |
|
||||||
#endif /*_GLFW_HAS_XRANDR*/ |
|
||||||
} |
|
||||||
else if (_glfwLibrary.X11.VidMode.available) |
|
||||||
{ |
|
||||||
#if defined(_GLFW_HAS_XF86VIDMODE) |
|
||||||
XF86VidModeModeInfo** modelist; |
|
||||||
int bestmode, modecount; |
|
||||||
|
|
||||||
// Get a list of all available display modes
|
|
||||||
XF86VidModeGetAllModeLines(_glfwLibrary.X11.display, |
|
||||||
_glfwLibrary.X11.screen, |
|
||||||
&modecount, &modelist); |
|
||||||
|
|
||||||
// Find the best matching mode
|
|
||||||
bestmode = -1; |
|
||||||
bestmatch = INT_MAX; |
|
||||||
for (i = 0; i < modecount; i++) |
|
||||||
{ |
|
||||||
match = (*width - modelist[i]->hdisplay) * |
|
||||||
(*width - modelist[i]->hdisplay) + |
|
||||||
(*height - modelist[i]->vdisplay) * |
|
||||||
(*height - modelist[i]->vdisplay); |
|
||||||
if (match < bestmatch) |
|
||||||
{ |
|
||||||
bestmatch = match; |
|
||||||
bestmode = i; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
if (bestmode != -1) |
|
||||||
{ |
|
||||||
// Report width & height of best matching mode
|
|
||||||
*width = modelist[bestmode]->hdisplay; |
|
||||||
*height = modelist[bestmode]->vdisplay; |
|
||||||
} |
|
||||||
|
|
||||||
XFree(modelist); |
|
||||||
|
|
||||||
if (bestmode != -1) |
|
||||||
return bestmode; |
|
||||||
#endif /*_GLFW_HAS_XF86VIDMODE*/ |
|
||||||
} |
|
||||||
|
|
||||||
// Default: Simply use the screen resolution
|
|
||||||
*width = DisplayWidth(_glfwLibrary.X11.display, _glfwLibrary.X11.screen); |
|
||||||
*height = DisplayHeight(_glfwLibrary.X11.display, _glfwLibrary.X11.screen); |
|
||||||
|
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
//========================================================================
|
|
||||||
// Change the current video mode
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
void _glfwSetVideoModeMODE(int mode, int rate) |
|
||||||
{ |
|
||||||
if (_glfwLibrary.X11.RandR.available) |
|
||||||
{ |
|
||||||
#if defined(_GLFW_HAS_XRANDR) |
|
||||||
XRRScreenConfiguration* sc; |
|
||||||
Window root; |
|
||||||
|
|
||||||
root = _glfwLibrary.X11.root; |
|
||||||
sc = XRRGetScreenInfo(_glfwLibrary.X11.display, root); |
|
||||||
|
|
||||||
// Remember old size and flag that we have changed the mode
|
|
||||||
if (!_glfwLibrary.X11.FS.modeChanged) |
|
||||||
{ |
|
||||||
_glfwLibrary.X11.FS.oldSizeID = XRRConfigCurrentConfiguration(sc, &_glfwLibrary.X11.FS.oldRotation); |
|
||||||
_glfwLibrary.X11.FS.oldWidth = DisplayWidth(_glfwLibrary.X11.display, |
|
||||||
_glfwLibrary.X11.screen); |
|
||||||
_glfwLibrary.X11.FS.oldHeight = DisplayHeight(_glfwLibrary.X11.display, |
|
||||||
_glfwLibrary.X11.screen); |
|
||||||
|
|
||||||
_glfwLibrary.X11.FS.modeChanged = GL_TRUE; |
|
||||||
} |
|
||||||
|
|
||||||
if (rate > 0) |
|
||||||
{ |
|
||||||
// Set desired configuration
|
|
||||||
XRRSetScreenConfigAndRate(_glfwLibrary.X11.display, |
|
||||||
sc, |
|
||||||
root, |
|
||||||
mode, |
|
||||||
RR_Rotate_0, |
|
||||||
(short) rate, |
|
||||||
CurrentTime); |
|
||||||
} |
|
||||||
else |
|
||||||
{ |
|
||||||
// Set desired configuration
|
|
||||||
XRRSetScreenConfig(_glfwLibrary.X11.display, |
|
||||||
sc, |
|
||||||
root, |
|
||||||
mode, |
|
||||||
RR_Rotate_0, |
|
||||||
CurrentTime); |
|
||||||
} |
|
||||||
|
|
||||||
XRRFreeScreenConfigInfo(sc); |
|
||||||
#endif /*_GLFW_HAS_XRANDR*/ |
|
||||||
} |
|
||||||
else if (_glfwLibrary.X11.VidMode.available) |
|
||||||
{ |
|
||||||
#if defined(_GLFW_HAS_XF86VIDMODE) |
|
||||||
XF86VidModeModeInfo **modelist; |
|
||||||
int modecount; |
|
||||||
|
|
||||||
// Get a list of all available display modes
|
|
||||||
XF86VidModeGetAllModeLines(_glfwLibrary.X11.display, |
|
||||||
_glfwLibrary.X11.screen, |
|
||||||
&modecount, &modelist); |
|
||||||
|
|
||||||
// Unlock mode switch if necessary
|
|
||||||
if (_glfwLibrary.X11.FS.modeChanged) |
|
||||||
{ |
|
||||||
XF86VidModeLockModeSwitch(_glfwLibrary.X11.display, |
|
||||||
_glfwLibrary.X11.screen, |
|
||||||
0); |
|
||||||
} |
|
||||||
|
|
||||||
// Change the video mode to the desired mode
|
|
||||||
XF86VidModeSwitchToMode(_glfwLibrary.X11.display, |
|
||||||
_glfwLibrary.X11.screen, |
|
||||||
modelist[mode]); |
|
||||||
|
|
||||||
// Set viewport to upper left corner (where our window will be)
|
|
||||||
XF86VidModeSetViewPort(_glfwLibrary.X11.display, |
|
||||||
_glfwLibrary.X11.screen, |
|
||||||
0, 0); |
|
||||||
|
|
||||||
// Lock mode switch
|
|
||||||
XF86VidModeLockModeSwitch(_glfwLibrary.X11.display, |
|
||||||
_glfwLibrary.X11.screen, |
|
||||||
1); |
|
||||||
|
|
||||||
// Remember old mode and flag that we have changed the mode
|
|
||||||
if (!_glfwLibrary.X11.FS.modeChanged) |
|
||||||
{ |
|
||||||
_glfwLibrary.X11.FS.oldMode = *modelist[0]; |
|
||||||
_glfwLibrary.X11.FS.modeChanged = GL_TRUE; |
|
||||||
} |
|
||||||
|
|
||||||
XFree(modelist); |
|
||||||
#endif /*_GLFW_HAS_XF86VIDMODE*/ |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
//========================================================================
|
|
||||||
// Change the current video mode
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
void _glfwSetVideoMode(int* width, int* height, int* rate) |
|
||||||
{ |
|
||||||
int bestmode; |
|
||||||
|
|
||||||
// Find a best match mode
|
|
||||||
bestmode = _glfwGetClosestVideoMode(width, height, rate); |
|
||||||
|
|
||||||
// Change mode
|
|
||||||
_glfwSetVideoModeMODE(bestmode, *rate); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
//========================================================================
|
|
||||||
// Restore the previously saved (original) video mode
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
void _glfwRestoreVideoMode(void) |
|
||||||
{ |
|
||||||
if (_glfwLibrary.X11.FS.modeChanged) |
|
||||||
{ |
|
||||||
if (_glfwLibrary.X11.RandR.available) |
|
||||||
{ |
|
||||||
#if defined(_GLFW_HAS_XRANDR) |
|
||||||
XRRScreenConfiguration* sc; |
|
||||||
|
|
||||||
if (_glfwLibrary.X11.RandR.available) |
|
||||||
{ |
|
||||||
sc = XRRGetScreenInfo(_glfwLibrary.X11.display, |
|
||||||
_glfwLibrary.X11.root); |
|
||||||
|
|
||||||
XRRSetScreenConfig(_glfwLibrary.X11.display, |
|
||||||
sc, |
|
||||||
_glfwLibrary.X11.root, |
|
||||||
_glfwLibrary.X11.FS.oldSizeID, |
|
||||||
_glfwLibrary.X11.FS.oldRotation, |
|
||||||
CurrentTime); |
|
||||||
|
|
||||||
XRRFreeScreenConfigInfo(sc); |
|
||||||
} |
|
||||||
#endif /*_GLFW_HAS_XRANDR*/ |
|
||||||
} |
|
||||||
else if (_glfwLibrary.X11.VidMode.available) |
|
||||||
{ |
|
||||||
#if defined(_GLFW_HAS_XF86VIDMODE) |
|
||||||
// Unlock mode switch
|
|
||||||
XF86VidModeLockModeSwitch(_glfwLibrary.X11.display, |
|
||||||
_glfwLibrary.X11.screen, |
|
||||||
0); |
|
||||||
|
|
||||||
// Change the video mode back to the old mode
|
|
||||||
XF86VidModeSwitchToMode(_glfwLibrary.X11.display, |
|
||||||
_glfwLibrary.X11.screen, |
|
||||||
&_glfwLibrary.X11.FS.oldMode); |
|
||||||
#endif /*_GLFW_HAS_XF86VIDMODE*/ |
|
||||||
} |
|
||||||
|
|
||||||
_glfwLibrary.X11.FS.modeChanged = GL_FALSE; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
////// GLFW platform API //////
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//========================================================================
|
|
||||||
// List available video modes
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found) |
|
||||||
{ |
|
||||||
XVisualInfo* visuals; |
|
||||||
XVisualInfo dummy; |
|
||||||
int i, j, visualCount, sizeCount, rgbCount; |
|
||||||
int* rgbs; |
|
||||||
_GLFWvidsize* sizes; |
|
||||||
GLFWvidmode* result; |
|
||||||
|
|
||||||
visuals = XGetVisualInfo(_glfwLibrary.X11.display, 0, &dummy, &visualCount); |
|
||||||
if (visuals == NULL) |
|
||||||
{ |
|
||||||
_glfwSetError(GLFW_PLATFORM_ERROR, |
|
||||||
"X11: Failed to retrieve the available visuals"); |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
// Build array of available RGB channel depths
|
|
||||||
|
|
||||||
rgbs = (int*) malloc(sizeof(int) * visualCount); |
|
||||||
rgbCount = 0; |
|
||||||
|
|
||||||
for (i = 0; i < visualCount; i++) |
|
||||||
{ |
|
||||||
int gl, rgba, rgb, r, g, b; |
|
||||||
|
|
||||||
glXGetConfig(_glfwLibrary.X11.display, &visuals[i], GLX_USE_GL, &gl); |
|
||||||
glXGetConfig(_glfwLibrary.X11.display, &visuals[i], GLX_RGBA, &rgba); |
|
||||||
|
|
||||||
if (!gl || !rgba) |
|
||||||
{ |
|
||||||
// The visual lacks OpenGL or true color, so skip it
|
|
||||||
continue; |
|
||||||
} |
|
||||||
|
|
||||||
// Convert to RGB channel depths and encode
|
|
||||||
_glfwSplitBPP(visuals[i].depth, &r, &g, &b); |
|
||||||
rgb = (r << 16) | (g << 8) | b; |
|
||||||
|
|
||||||
for (j = 0; j < rgbCount; j++) |
|
||||||
{ |
|
||||||
if (rgbs[j] == rgb) |
|
||||||
break; |
|
||||||
} |
|
||||||
|
|
||||||
if (j < rgbCount) |
|
||||||
{ |
|
||||||
// This channel depth is a duplicate, so skip it
|
|
||||||
continue; |
|
||||||
} |
|
||||||
|
|
||||||
rgbs[rgbCount] = rgb; |
|
||||||
rgbCount++; |
|
||||||
} |
|
||||||
|
|
||||||
XFree(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)++; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
free(sizes); |
|
||||||
free(rgbs); |
|
||||||
|
|
||||||
return result; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
//========================================================================
|
|
||||||
// Get the current video mode for the specified monitor
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) |
|
||||||
{ |
|
||||||
_glfwSplitBPP(DefaultDepth(_glfwLibrary.X11.display, |
|
||||||
_glfwLibrary.X11.screen), |
|
||||||
&mode->redBits, &mode->greenBits, &mode->blueBits); |
|
||||||
|
|
||||||
mode->width = DisplayWidth(_glfwLibrary.X11.display, |
|
||||||
_glfwLibrary.X11.screen); |
|
||||||
mode->height = DisplayHeight(_glfwLibrary.X11.display, |
|
||||||
_glfwLibrary.X11.screen); |
|
||||||
} |
|
||||||
|
|
Loading…
Reference in New Issue