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