From 62b06b3339801083e955422e22be7f2d3c2ced12 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Tue, 24 Jan 2017 01:37:29 +0100
Subject: [PATCH] dxgi: Implement setting and querying the gamma value of an
 output.

---
 dlls/dxgi/Makefile.in    |  2 +-
 dlls/dxgi/output.c       | 17 +++++++++++++++--
 dlls/dxgi/tests/device.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 61 insertions(+), 3 deletions(-)

diff --git a/dlls/dxgi/Makefile.in b/dlls/dxgi/Makefile.in
index ce76b8e..1a0c908 100644
--- a/dlls/dxgi/Makefile.in
+++ b/dlls/dxgi/Makefile.in
@@ -1,6 +1,6 @@
 MODULE    = dxgi.dll
 IMPORTLIB = dxgi
-IMPORTS   = dxguid uuid wined3d user32
+IMPORTS   = dxguid uuid wined3d user32 gdi32
 
 C_SRCS = \
 	adapter.c \
diff --git a/dlls/dxgi/output.c b/dlls/dxgi/output.c
index 2b168fb..31bdf9a 100644
--- a/dlls/dxgi/output.c
+++ b/dlls/dxgi/output.c
@@ -293,9 +293,22 @@ static void STDMETHODCALLTYPE dxgi_output_ReleaseOwnership(IDXGIOutput4 *iface)
 static HRESULT STDMETHODCALLTYPE dxgi_output_GetGammaControlCapabilities(IDXGIOutput4 *iface,
         DXGI_GAMMA_CONTROL_CAPABILITIES *gamma_caps)
 {
-    FIXME("iface %p, gamma_caps %p stub!\n", iface, gamma_caps);
+    int i;
 
-    return E_NOTIMPL;
+    TRACE("iface %p, gamma_caps %p.\n", iface, gamma_caps);
+
+    if (!gamma_caps)
+        return E_INVALIDARG;
+
+    gamma_caps->ScaleAndOffsetSupported = FALSE;
+    gamma_caps->MaxConvertedValue = 1.0;
+    gamma_caps->MinConvertedValue = 0.0;
+    gamma_caps->NumGammaControlPoints = 256;
+
+    for (i = 0; i < 256; i++)
+        gamma_caps->ControlPointPositions[i] = i / 255.0f;
+
+    return S_OK;
 }
 
 static HRESULT STDMETHODCALLTYPE dxgi_output_SetGammaControl(IDXGIOutput4 *iface,
diff --git a/dlls/dxgi/tests/device.c b/dlls/dxgi/tests/device.c
index 58c3bba..acf0f85 100644
--- a/dlls/dxgi/tests/device.c
+++ b/dlls/dxgi/tests/device.c
@@ -1852,11 +1852,13 @@ static void test_swapchain_fullscreen_state(IDXGISwapChain *swapchain,
 static void test_set_fullscreen(void)
 {
     struct swapchain_fullscreen_state initial_state;
+    DXGI_GAMMA_CONTROL_CAPABILITIES caps;
     DXGI_SWAP_CHAIN_DESC swapchain_desc;
     IDXGISwapChain *swapchain;
     IDXGIFactory *factory;
     IDXGIAdapter *adapter;
     IDXGIDevice *device;
+    IDXGIOutput *output;
     ULONG refcount;
     HRESULT hr;
 
@@ -1872,6 +1874,17 @@ static void test_set_fullscreen(void)
     hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory);
     ok(SUCCEEDED(hr), "GetParent failed, hr %#x.\n", hr);
 
+    hr = IDXGIAdapter_EnumOutputs(adapter, 0, &output);
+    if (SUCCEEDED(hr))
+    {
+        hr = IDXGIOutput_GetGammaControlCapabilities(output, &caps);
+        todo_wine ok(hr == DXGI_ERROR_INVALID_CALL, "Expected DXGI_ERROR_INVALID_CALL, got %#x.\n", hr);
+
+        IDXGIOutput_Release(output);
+    }
+    else
+        skip("Failed to get output, skipping gamma test.\n");
+
     swapchain_desc.BufferDesc.Width = 800;
     swapchain_desc.BufferDesc.Height = 600;
     swapchain_desc.BufferDesc.RefreshRate.Numerator = 60;
@@ -1902,6 +1915,38 @@ static void test_set_fullscreen(void)
         skip("Could not change fullscreen state.\n");
         goto done;
     }
+
+    hr = IDXGISwapChain_GetContainingOutput(swapchain, &output);
+    if (SUCCEEDED(hr))
+    {
+        DXGI_GAMMA_CONTROL gamma;
+        int i;
+
+        memset(&caps, 0, sizeof(caps));
+        hr = IDXGIOutput_GetGammaControlCapabilities(output, &caps);
+        ok(hr == S_OK, "Expected S_OK, got %#x.\n", hr);
+
+        ok(caps.MaxConvertedValue > caps.MinConvertedValue,
+           "Expected max gamma value (%f) to be bigger than the min value (%f).\n",
+           caps.MaxConvertedValue, caps.MinConvertedValue);
+
+        for (i = 1; i < caps.NumGammaControlPoints; i++)
+        {
+            ok(caps.ControlPointPositions[i] > caps.ControlPointPositions[i-1],
+               "Expected control point positions to be strictly monotonically increasing (%f > %f).\n",
+               caps.ControlPointPositions[i], caps.ControlPointPositions[i-1]);
+        }
+
+        hr = IDXGIOutput_GetGammaControl(output, &gamma);
+        ok(hr == S_OK, "Expected S_OK, got %#x.\n", hr);
+        hr = IDXGIOutput_SetGammaControl(output, &gamma);
+        ok(hr == S_OK, "Expected S_OK, got %#x.\n", hr);
+
+        IDXGIOutput_Release(output);
+    }
+    else
+        skip("Failed to get output, skipping gamma test.\n");
+
     hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL);
     ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
     refcount = IDXGISwapChain_Release(swapchain);
-- 
1.9.1