mirror of
https://github.com/glfw/glfw.git
synced 2024-11-26 03:52:01 +00:00
Merged fullscreen and monitor modules.
This commit is contained in:
parent
c87829ea61
commit
55419bda67
@ -3,13 +3,13 @@ include_directories(${GLFW_SOURCE_DIR}/src
|
|||||||
${glfw_INCLUDE_DIRS})
|
${glfw_INCLUDE_DIRS})
|
||||||
|
|
||||||
set(common_HEADERS ${GLFW_SOURCE_DIR}/include/GL/glfw3.h internal.h)
|
set(common_HEADERS ${GLFW_SOURCE_DIR}/include/GL/glfw3.h internal.h)
|
||||||
set(common_SOURCES clipboard.c fullscreen.c gamma.c init.c input.c
|
set(common_SOURCES clipboard.c gamma.c init.c input.c joystick.c monitor.c
|
||||||
joystick.c monitor.c opengl.c time.c window.c)
|
opengl.c time.c window.c)
|
||||||
|
|
||||||
if (_GLFW_COCOA_NSGL)
|
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_gamma.c
|
||||||
cocoa_gamma.c cocoa_init.m cocoa_input.m cocoa_joystick.m
|
cocoa_init.m cocoa_input.m cocoa_joystick.m cocoa_monitor.m
|
||||||
cocoa_opengl.m cocoa_time.c cocoa_window.m)
|
cocoa_opengl.m cocoa_time.c cocoa_window.m)
|
||||||
|
|
||||||
if (GLFW_NATIVE_API)
|
if (GLFW_NATIVE_API)
|
||||||
@ -20,20 +20,18 @@ if (_GLFW_COCOA_NSGL)
|
|||||||
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_fullscreen.c
|
set(glfw_SOURCES ${common_SOURCES} win32_clipboard.c win32_gamma.c
|
||||||
win32_gamma.c win32_init.c win32_input.c win32_joystick.c
|
win32_init.c win32_input.c win32_joystick.c win32_monitor.c
|
||||||
win32_monitor.c win32_opengl.c win32_time.c win32_window.c
|
win32_opengl.c win32_time.c win32_window.c win32_dllmain.c)
|
||||||
win32_dllmain.c)
|
|
||||||
|
|
||||||
if (GLFW_NATIVE_API)
|
if (GLFW_NATIVE_API)
|
||||||
list(APPEND glfw_SOURCES win32_native.c)
|
list(APPEND glfw_SOURCES win32_native.c)
|
||||||
endif()
|
endif()
|
||||||
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_gamma.c x11_init.c
|
||||||
x11_gamma.c x11_init.c x11_input.c x11_joystick.c
|
x11_input.c x11_joystick.c x11_keysym2unicode.c
|
||||||
x11_keysym2unicode.c x11_monitor.c x11_opengl.c x11_time.c
|
x11_monitor.c x11_opengl.c x11_time.c x11_window.c)
|
||||||
x11_window.c)
|
|
||||||
|
|
||||||
if (GLFW_NATIVE_API)
|
if (GLFW_NATIVE_API)
|
||||||
list(APPEND glfw_SOURCES x11_native.c)
|
list(APPEND glfw_SOURCES x11_native.c)
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
@ -30,6 +30,167 @@
|
|||||||
|
|
||||||
#include "internal.h"
|
#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 //////
|
////// GLFW platform API //////
|
||||||
@ -54,3 +215,50 @@ void _glfwPlatformDestroyMonitor(_GLFWmonitor* monitor)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//========================================================================
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
172
src/fullscreen.c
172
src/fullscreen.c
@ -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);
|
|
||||||
}
|
|
||||||
|
|
129
src/monitor.c
129
src/monitor.c
@ -32,6 +32,40 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
@ -151,6 +185,40 @@ void _glfwDestroyMonitors(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//========================================================================
|
||||||
|
// 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 //////
|
////// GLFW public API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
@ -281,3 +349,64 @@ GLFWAPI void glfwSetMonitorCallback(GLFWmonitorfun cbfun)
|
|||||||
_glfwLibrary.monitorCallback= cbfun;
|
_glfwLibrary.monitorCallback= cbfun;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//========================================================================
|
||||||
|
// 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);
|
|
||||||
}
|
|
||||||
|
|
@ -32,6 +32,8 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
|
||||||
// These constants are missing on MinGW
|
// These constants are missing on MinGW
|
||||||
#ifndef EDS_ROTATEDMODE
|
#ifndef EDS_ROTATEDMODE
|
||||||
@ -42,6 +44,146 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
//========================================================================
|
||||||
|
// 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 //////
|
////// GLFW platform API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
@ -164,3 +306,104 @@ void _glfwPlatformDestroyMonitor(_GLFWmonitor* monitor)
|
|||||||
free(monitor->Win32.name);
|
free(monitor->Win32.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//========================================================================
|
||||||
|
// 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);
|
|
||||||
}
|
|
||||||
|
|
@ -30,10 +30,396 @@
|
|||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.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 //////
|
////// GLFW platform API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
@ -113,3 +499,109 @@ void _glfwPlatformDestroyMonitor(_GLFWmonitor* monitor)
|
|||||||
#endif /*_GLFW_HAS_XRANDR*/
|
#endif /*_GLFW_HAS_XRANDR*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//========================================================================
|
||||||
|
// 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
Block a user