diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 32e407b9..6496854e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,33 +8,33 @@ add_definitions(-D_GLFW_USE_CONFIG_H) set(common_HEADERS "${GLFW_BINARY_DIR}/src/glfw_config.h" internal.h "${GLFW_SOURCE_DIR}/include/GLFW/glfw3.h" "${GLFW_SOURCE_DIR}/include/GLFW/glfw3native.h") -set(common_SOURCES clipboard.c context.c gamma.c init.c input.c joystick.c +set(common_SOURCES clipboard.c context.c init.c input.c joystick.c monitor.c time.c window.c) if (_GLFW_COCOA) set(glfw_HEADERS ${common_HEADERS} cocoa_platform.h iokit_joystick.h posix_tls.h) - set(glfw_SOURCES ${common_SOURCES} cocoa_clipboard.m cocoa_gamma.c - cocoa_init.m cocoa_monitor.m cocoa_window.m - iokit_joystick.m mach_time.c posix_tls.c) + set(glfw_SOURCES ${common_SOURCES} cocoa_clipboard.m cocoa_init.m + cocoa_monitor.m cocoa_window.m iokit_joystick.m mach_time.c + posix_tls.c) elseif (_GLFW_WIN32) set(glfw_HEADERS ${common_HEADERS} win32_platform.h win32_tls.h winmm_joystick.h) - set(glfw_SOURCES ${common_SOURCES} win32_clipboard.c win32_gamma.c - win32_init.c win32_monitor.c win32_time.c win32_tls.c - win32_window.c winmm_joystick.c) + set(glfw_SOURCES ${common_SOURCES} win32_clipboard.c win32_init.c + win32_monitor.c win32_time.c win32_tls.c win32_window.c + winmm_joystick.c) elseif (_GLFW_X11) set(glfw_HEADERS ${common_HEADERS} x11_platform.h xkb_unicode.h linux_joystick.h posix_time.h posix_tls.h) - set(glfw_SOURCES ${common_SOURCES} x11_clipboard.c x11_gamma.c x11_init.c - x11_monitor.c x11_window.c xkb_unicode.c - linux_joystick.c posix_time.c posix_tls.c) + set(glfw_SOURCES ${common_SOURCES} x11_clipboard.c x11_init.c x11_monitor.c + x11_window.c xkb_unicode.c linux_joystick.c posix_time.c + posix_tls.c) elseif (_GLFW_WAYLAND) set(glfw_HEADERS ${common_HEADERS} wl_platform.h linux_joystick.h posix_time.h posix_tls.h xkb_unicode.h) - set(glfw_SOURCES ${common_SOURCES} wl_clipboard.c wl_gamma.c wl_init.c - wl_monitor.c wl_window.c linux_joystick.c posix_time.c - posix_tls.c xkb_unicode.c) + set(glfw_SOURCES ${common_SOURCES} wl_clipboard.c wl_init.c wl_monitor.c + wl_window.c linux_joystick.c posix_time.c posix_tls.c + xkb_unicode.c) endif() if (_GLFW_EGL) diff --git a/src/cocoa_gamma.c b/src/cocoa_gamma.c deleted file mode 100644 index 85fb50ad..00000000 --- a/src/cocoa_gamma.c +++ /dev/null @@ -1,84 +0,0 @@ -//======================================================================== -// GLFW 3.1 OS X - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2010 Camilla Berglund -// -// 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 -#include -#include - -#include - - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - -void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) -{ - uint32_t i, size = CGDisplayGammaTableCapacity(monitor->ns.displayID); - CGGammaValue* values = calloc(size * 3, sizeof(CGGammaValue)); - - CGGetDisplayTransferByTable(monitor->ns.displayID, - size, - values, - values + size, - values + size * 2, - &size); - - _glfwAllocGammaArrays(ramp, size); - - for (i = 0; i < size; i++) - { - ramp->red[i] = (unsigned short) (values[i] * 65535); - ramp->green[i] = (unsigned short) (values[i + size] * 65535); - ramp->blue[i] = (unsigned short) (values[i + size * 2] * 65535); - } - - free(values); -} - -void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) -{ - int i; - CGGammaValue* values = calloc(ramp->size * 3, sizeof(CGGammaValue)); - - for (i = 0; i < ramp->size; i++) - { - values[i] = ramp->red[i] / 65535.f; - values[i + ramp->size] = ramp->green[i] / 65535.f; - values[i + ramp->size * 2] = ramp->blue[i] / 65535.f; - } - - CGSetDisplayTransferByTable(monitor->ns.displayID, - ramp->size, - values, - values + ramp->size, - values + ramp->size * 2); - - free(values); -} - diff --git a/src/cocoa_monitor.m b/src/cocoa_monitor.m index 3b4b1ed1..abf66654 100644 --- a/src/cocoa_monitor.m +++ b/src/cocoa_monitor.m @@ -27,6 +27,7 @@ #include "internal.h" +#include #include #include @@ -34,6 +35,7 @@ #include #include #include +#include // Get the name of the specified display @@ -356,6 +358,51 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode *mode) CVDisplayLinkRelease(link); } +void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) +{ + uint32_t i, size = CGDisplayGammaTableCapacity(monitor->ns.displayID); + CGGammaValue* values = calloc(size * 3, sizeof(CGGammaValue)); + + CGGetDisplayTransferByTable(monitor->ns.displayID, + size, + values, + values + size, + values + size * 2, + &size); + + _glfwAllocGammaArrays(ramp, size); + + for (i = 0; i < size; i++) + { + ramp->red[i] = (unsigned short) (values[i] * 65535); + ramp->green[i] = (unsigned short) (values[i + size] * 65535); + ramp->blue[i] = (unsigned short) (values[i + size * 2] * 65535); + } + + free(values); +} + +void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) +{ + int i; + CGGammaValue* values = calloc(ramp->size * 3, sizeof(CGGammaValue)); + + for (i = 0; i < ramp->size; i++) + { + values[i] = ramp->red[i] / 65535.f; + values[i + ramp->size] = ramp->green[i] / 65535.f; + values[i + ramp->size * 2] = ramp->blue[i] / 65535.f; + } + + CGSetDisplayTransferByTable(monitor->ns.displayID, + ramp->size, + values, + values + ramp->size, + values + ramp->size * 2); + + free(values); +} + ////////////////////////////////////////////////////////////////////////// ////// GLFW native API ////// diff --git a/src/gamma.c b/src/gamma.c deleted file mode 100644 index 945e886b..00000000 --- a/src/gamma.c +++ /dev/null @@ -1,122 +0,0 @@ -//======================================================================== -// GLFW 3.1 - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2010 Camilla Berglund -// -// 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 -#include -#include - - -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -void _glfwAllocGammaArrays(GLFWgammaramp* ramp, unsigned int size) -{ - ramp->red = calloc(size, sizeof(unsigned short)); - ramp->green = calloc(size, sizeof(unsigned short)); - ramp->blue = calloc(size, sizeof(unsigned short)); - ramp->size = size; -} - -void _glfwFreeGammaArrays(GLFWgammaramp* ramp) -{ - free(ramp->red); - free(ramp->green); - free(ramp->blue); - - memset(ramp, 0, sizeof(GLFWgammaramp)); -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW public API ////// -////////////////////////////////////////////////////////////////////////// - -GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma) -{ - int i; - unsigned short values[256]; - GLFWgammaramp ramp; - - _GLFW_REQUIRE_INIT(); - - if (gamma <= 0.f) - { - _glfwInputError(GLFW_INVALID_VALUE, - "Gamma value must be greater than zero"); - return; - } - - for (i = 0; i < 256; i++) - { - double value; - - // Calculate intensity - value = i / 255.0; - // Apply gamma curve - value = pow(value, 1.0 / gamma) * 65535.0 + 0.5; - - // Clamp to value range - if (value > 65535.0) - value = 65535.0; - - values[i] = (unsigned short) value; - } - - ramp.red = values; - ramp.green = values; - ramp.blue = values; - ramp.size = 256; - - glfwSetGammaRamp(handle, &ramp); -} - -GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle) -{ - _GLFWmonitor* monitor = (_GLFWmonitor*) handle; - - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - - _glfwFreeGammaArrays(&monitor->currentRamp); - _glfwPlatformGetGammaRamp(monitor, &monitor->currentRamp); - - return &monitor->currentRamp; -} - -GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp) -{ - _GLFWmonitor* monitor = (_GLFWmonitor*) handle; - - _GLFW_REQUIRE_INIT(); - - if (!monitor->originalRamp.size) - _glfwPlatformGetGammaRamp(monitor, &monitor->originalRamp); - - _glfwPlatformSetGammaRamp(monitor, ramp); -} - diff --git a/src/monitor.c b/src/monitor.c index eccbd433..ad353532 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -27,6 +27,7 @@ #include "internal.h" +#include #include #include #include @@ -184,6 +185,23 @@ void _glfwFreeMonitor(_GLFWmonitor* monitor) free(monitor); } +void _glfwAllocGammaArrays(GLFWgammaramp* ramp, unsigned int size) +{ + ramp->red = calloc(size, sizeof(unsigned short)); + ramp->green = calloc(size, sizeof(unsigned short)); + ramp->blue = calloc(size, sizeof(unsigned short)); + ramp->size = size; +} + +void _glfwFreeGammaArrays(GLFWgammaramp* ramp) +{ + free(ramp->red); + free(ramp->green); + free(ramp->blue); + + memset(ramp, 0, sizeof(GLFWgammaramp)); +} + void _glfwFreeMonitors(_GLFWmonitor** monitors, int count) { int i; @@ -359,3 +377,66 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* handle) return &monitor->currentMode; } +GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma) +{ + int i; + unsigned short values[256]; + GLFWgammaramp ramp; + + _GLFW_REQUIRE_INIT(); + + if (gamma <= 0.f) + { + _glfwInputError(GLFW_INVALID_VALUE, + "Gamma value must be greater than zero"); + return; + } + + for (i = 0; i < 256; i++) + { + double value; + + // Calculate intensity + value = i / 255.0; + // Apply gamma curve + value = pow(value, 1.0 / gamma) * 65535.0 + 0.5; + + // Clamp to value range + if (value > 65535.0) + value = 65535.0; + + values[i] = (unsigned short) value; + } + + ramp.red = values; + ramp.green = values; + ramp.blue = values; + ramp.size = 256; + + glfwSetGammaRamp(handle, &ramp); +} + +GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle) +{ + _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + + _glfwFreeGammaArrays(&monitor->currentRamp); + _glfwPlatformGetGammaRamp(monitor, &monitor->currentRamp); + + return &monitor->currentRamp; +} + +GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp) +{ + _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + + _GLFW_REQUIRE_INIT(); + + if (!monitor->originalRamp.size) + _glfwPlatformGetGammaRamp(monitor, &monitor->originalRamp); + + _glfwPlatformSetGammaRamp(monitor, ramp); +} + diff --git a/src/win32_gamma.c b/src/win32_gamma.c deleted file mode 100644 index 7fbad62e..00000000 --- a/src/win32_gamma.c +++ /dev/null @@ -1,82 +0,0 @@ -//======================================================================== -// GLFW 3.1 Win32 - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2010 Camilla Berglund -// -// 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 - - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - -void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) -{ - HDC dc; - WORD values[768]; - DISPLAY_DEVICEW display; - - ZeroMemory(&display, sizeof(DISPLAY_DEVICEW)); - display.cb = sizeof(DISPLAY_DEVICEW); - EnumDisplayDevicesW(monitor->win32.name, 0, &display, 0); - - dc = CreateDCW(L"DISPLAY", display.DeviceString, NULL, NULL); - GetDeviceGammaRamp(dc, values); - DeleteDC(dc); - - _glfwAllocGammaArrays(ramp, 256); - - memcpy(ramp->red, values + 0, 256 * sizeof(unsigned short)); - memcpy(ramp->green, values + 256, 256 * sizeof(unsigned short)); - memcpy(ramp->blue, values + 512, 256 * sizeof(unsigned short)); -} - -void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) -{ - HDC dc; - WORD values[768]; - DISPLAY_DEVICE display; - - if (ramp->size != 256) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Win32: Gamma ramp size must be 256"); - return; - } - - memcpy(values + 0, ramp->red, 256 * sizeof(unsigned short)); - memcpy(values + 256, ramp->green, 256 * sizeof(unsigned short)); - memcpy(values + 512, ramp->blue, 256 * sizeof(unsigned short)); - - ZeroMemory(&display, sizeof(DISPLAY_DEVICEW)); - display.cb = sizeof(DISPLAY_DEVICEW); - EnumDisplayDevicesW(monitor->win32.name, 0, &display, 0); - - dc = CreateDCW(L"DISPLAY", display.DeviceString, NULL, NULL); - SetDeviceGammaRamp(dc, values); - DeleteDC(dc); -} - diff --git a/src/win32_monitor.c b/src/win32_monitor.c index aa9ad272..ec16da52 100644 --- a/src/win32_monitor.c +++ b/src/win32_monitor.c @@ -286,6 +286,53 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) &mode->blueBits); } +void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) +{ + HDC dc; + WORD values[768]; + DISPLAY_DEVICEW display; + + ZeroMemory(&display, sizeof(DISPLAY_DEVICEW)); + display.cb = sizeof(DISPLAY_DEVICEW); + EnumDisplayDevicesW(monitor->win32.name, 0, &display, 0); + + dc = CreateDCW(L"DISPLAY", display.DeviceString, NULL, NULL); + GetDeviceGammaRamp(dc, values); + DeleteDC(dc); + + _glfwAllocGammaArrays(ramp, 256); + + memcpy(ramp->red, values + 0, 256 * sizeof(unsigned short)); + memcpy(ramp->green, values + 256, 256 * sizeof(unsigned short)); + memcpy(ramp->blue, values + 512, 256 * sizeof(unsigned short)); +} + +void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) +{ + HDC dc; + WORD values[768]; + DISPLAY_DEVICE display; + + if (ramp->size != 256) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Win32: Gamma ramp size must be 256"); + return; + } + + memcpy(values + 0, ramp->red, 256 * sizeof(unsigned short)); + memcpy(values + 256, ramp->green, 256 * sizeof(unsigned short)); + memcpy(values + 512, ramp->blue, 256 * sizeof(unsigned short)); + + ZeroMemory(&display, sizeof(DISPLAY_DEVICEW)); + display.cb = sizeof(DISPLAY_DEVICEW); + EnumDisplayDevicesW(monitor->win32.name, 0, &display, 0); + + dc = CreateDCW(L"DISPLAY", display.DeviceString, NULL, NULL); + SetDeviceGammaRamp(dc, values); + DeleteDC(dc); +} + ////////////////////////////////////////////////////////////////////////// ////// GLFW native API ////// diff --git a/src/wl_gamma.c b/src/wl_gamma.c deleted file mode 100644 index 803e3c50..00000000 --- a/src/wl_gamma.c +++ /dev/null @@ -1,47 +0,0 @@ -//======================================================================== -// GLFW 3.1 Wayland - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2014 Jonas Ã…dahl -// -// 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 - - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - -void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) -{ - // TODO - fprintf(stderr, "_glfwPlatformGetGammaRamp not implemented yet\n"); -} - -void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) -{ - // TODO - fprintf(stderr, "_glfwPlatformSetGammaRamp not implemented yet\n"); -} - diff --git a/src/wl_monitor.c b/src/wl_monitor.c index 0f66c7ba..fbcefd38 100644 --- a/src/wl_monitor.c +++ b/src/wl_monitor.c @@ -236,3 +236,15 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) } } +void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) +{ + // TODO + fprintf(stderr, "_glfwPlatformGetGammaRamp not implemented yet\n"); +} + +void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) +{ + // TODO + fprintf(stderr, "_glfwPlatformSetGammaRamp not implemented yet\n"); +} + diff --git a/src/x11_gamma.c b/src/x11_gamma.c deleted file mode 100644 index 315e0221..00000000 --- a/src/x11_gamma.c +++ /dev/null @@ -1,118 +0,0 @@ -//======================================================================== -// GLFW 3.1 X11 - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2010 Camilla Berglund -// -// 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 -#include - - -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -// Detect gamma ramp support -// -void _glfwInitGammaRamp(void) -{ - if (_glfw.x11.randr.available) - { - XRRScreenResources* sr = XRRGetScreenResources(_glfw.x11.display, - _glfw.x11.root); - - if (!sr->ncrtc || !XRRGetCrtcGammaSize(_glfw.x11.display, sr->crtcs[0])) - { - // This is either a headless system or an older Nvidia binary driver - // with broken gamma support - // Flag it as useless and fall back to Xf86VidMode, if available - _glfwInputError(GLFW_PLATFORM_ERROR, - "X11: RandR gamma ramp support seems broken"); - _glfw.x11.randr.gammaBroken = GL_TRUE; - } - - XRRFreeScreenResources(sr); - } -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - -void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) -{ - if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken) - { - const size_t size = XRRGetCrtcGammaSize(_glfw.x11.display, - monitor->x11.crtc); - XRRCrtcGamma* gamma = XRRGetCrtcGamma(_glfw.x11.display, - monitor->x11.crtc); - - _glfwAllocGammaArrays(ramp, size); - - memcpy(ramp->red, gamma->red, size * sizeof(unsigned short)); - memcpy(ramp->green, gamma->green, size * sizeof(unsigned short)); - memcpy(ramp->blue, gamma->blue, size * sizeof(unsigned short)); - - XRRFreeGamma(gamma); - } - else if (_glfw.x11.vidmode.available) - { - int size; - XF86VidModeGetGammaRampSize(_glfw.x11.display, _glfw.x11.screen, &size); - - _glfwAllocGammaArrays(ramp, size); - - XF86VidModeGetGammaRamp(_glfw.x11.display, - _glfw.x11.screen, - ramp->size, ramp->red, ramp->green, ramp->blue); - } -} - -void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) -{ - if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken) - { - XRRCrtcGamma* gamma = XRRAllocGamma(ramp->size); - - memcpy(gamma->red, ramp->red, ramp->size * sizeof(unsigned short)); - memcpy(gamma->green, ramp->green, ramp->size * sizeof(unsigned short)); - memcpy(gamma->blue, ramp->blue, ramp->size * sizeof(unsigned short)); - - XRRSetCrtcGamma(_glfw.x11.display, monitor->x11.crtc, gamma); - XRRFreeGamma(gamma); - } - else if (_glfw.x11.vidmode.available) - { - XF86VidModeSetGammaRamp(_glfw.x11.display, - _glfw.x11.screen, - ramp->size, - (unsigned short*) ramp->red, - (unsigned short*) ramp->green, - (unsigned short*) ramp->blue); - } -} - diff --git a/src/x11_monitor.c b/src/x11_monitor.c index 479a4e11..60b31d4a 100644 --- a/src/x11_monitor.c +++ b/src/x11_monitor.c @@ -95,6 +95,29 @@ static GLFWvidmode vidmodeFromModeInfo(const XRRModeInfo* mi, ////// GLFW internal API ////// ////////////////////////////////////////////////////////////////////////// +// Detect gamma ramp support +// +void _glfwInitGammaRamp(void) +{ + if (_glfw.x11.randr.available) + { + XRRScreenResources* sr = XRRGetScreenResources(_glfw.x11.display, + _glfw.x11.root); + + if (!sr->ncrtc || !XRRGetCrtcGammaSize(_glfw.x11.display, sr->crtcs[0])) + { + // This is either a headless system or an older Nvidia binary driver + // with broken gamma support + // Flag it as useless and fall back to Xf86VidMode, if available + _glfwInputError(GLFW_PLATFORM_ERROR, + "X11: RandR gamma ramp support seems broken"); + _glfw.x11.randr.gammaBroken = GL_TRUE; + } + + XRRFreeScreenResources(sr); + } +} + // Set the current video mode for the specified monitor // GLboolean _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired) @@ -413,6 +436,60 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) } } +void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) +{ + if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken) + { + const size_t size = XRRGetCrtcGammaSize(_glfw.x11.display, + monitor->x11.crtc); + XRRCrtcGamma* gamma = XRRGetCrtcGamma(_glfw.x11.display, + monitor->x11.crtc); + + _glfwAllocGammaArrays(ramp, size); + + memcpy(ramp->red, gamma->red, size * sizeof(unsigned short)); + memcpy(ramp->green, gamma->green, size * sizeof(unsigned short)); + memcpy(ramp->blue, gamma->blue, size * sizeof(unsigned short)); + + XRRFreeGamma(gamma); + } + else if (_glfw.x11.vidmode.available) + { + int size; + XF86VidModeGetGammaRampSize(_glfw.x11.display, _glfw.x11.screen, &size); + + _glfwAllocGammaArrays(ramp, size); + + XF86VidModeGetGammaRamp(_glfw.x11.display, + _glfw.x11.screen, + ramp->size, ramp->red, ramp->green, ramp->blue); + } +} + +void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) +{ + if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken) + { + XRRCrtcGamma* gamma = XRRAllocGamma(ramp->size); + + memcpy(gamma->red, ramp->red, ramp->size * sizeof(unsigned short)); + memcpy(gamma->green, ramp->green, ramp->size * sizeof(unsigned short)); + memcpy(gamma->blue, ramp->blue, ramp->size * sizeof(unsigned short)); + + XRRSetCrtcGamma(_glfw.x11.display, monitor->x11.crtc, gamma); + XRRFreeGamma(gamma); + } + else if (_glfw.x11.vidmode.available) + { + XF86VidModeSetGammaRamp(_glfw.x11.display, + _glfw.x11.screen, + ramp->size, + (unsigned short*) ramp->red, + (unsigned short*) ramp->green, + (unsigned short*) ramp->blue); + } +} + ////////////////////////////////////////////////////////////////////////// ////// GLFW native API //////