From 64e8c4698047a079d4a538d1774f194529570453 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Wed, 3 Jun 2015 22:57:21 +0200
Subject: [PATCH] winex11.drv: Allow changing the opengl pixel format on the
 desktop window.

This patch is not 100% correct because the old behavior was more similar to
windows. However, Direct3D supports using the desktop window to create a
context and since Wine translates Direct3D to OpenGL, using the desktop
window will fail because of this limitation. Unless someone comes up with
a more correct solution or finds an application that breaks because of this,
it seems to be a suitable workaround as it fixes multiple applications.
---
 dlls/d3d10_1/tests/d3d10_1.c | 16 +++++++++++++---
 dlls/d3d11/tests/d3d11.c     | 22 +++++++++++++++++-----
 dlls/d3d9/tests/device.c     | 16 ++++++++++++++++
 dlls/winex11.drv/opengl.c    |  5 ++++-
 4 files changed, 50 insertions(+), 9 deletions(-)

diff --git a/dlls/d3d10_1/tests/d3d10_1.c b/dlls/d3d10_1/tests/d3d10_1.c
index 7c2b3ba..5d111d9 100644
--- a/dlls/d3d10_1/tests/d3d10_1.c
+++ b/dlls/d3d10_1/tests/d3d10_1.c
@@ -252,9 +252,19 @@ static void test_create_device(void)
     swapchain_desc.OutputWindow = NULL;
     hr = D3D10CreateDeviceAndSwapChain1(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, 0,
             supported_feature_level, D3D10_1_SDK_VERSION, &swapchain_desc, &swapchain, &device);
-    ok(hr == DXGI_ERROR_INVALID_CALL, "D3D10CreateDeviceAndSwapChain1 returned %#x.\n", hr);
-    ok(!swapchain, "Got unexpected swapchain pointer %p.\n", swapchain);
-    ok(!device, "Got unexpected device pointer %p.\n", device);
+    todo_wine ok(hr == DXGI_ERROR_INVALID_CALL, "D3D10CreateDeviceAndSwapChain1 returned %#x.\n", hr);
+    if (SUCCEEDED(hr))
+    {
+        refcount = IDXGISwapChain_Release(swapchain);
+        ok(!refcount, "Swapchain has %u references left.\n", refcount);
+        refcount = ID3D10Device1_Release(device);
+        ok(!refcount, "Device has %u references left.\n", refcount);
+    }
+    else
+    {
+        ok(!swapchain, "Got unexpected swapchain pointer %p.\n", swapchain);
+        ok(!device, "Got unexpected device pointer %p.\n", device);
+    }
 
     swapchain = (IDXGISwapChain *)0xdeadbeef;
     device = (ID3D10Device1 *)0xdeadbeef;
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c
index 5a36bc2..1c07775 100644
--- a/dlls/d3d11/tests/d3d11.c
+++ b/dlls/d3d11/tests/d3d11.c
@@ -1705,11 +1705,23 @@ static void test_create_device(void)
     swapchain_desc.OutputWindow = NULL;
     hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, NULL, 0, D3D11_SDK_VERSION,
             &swapchain_desc, &swapchain, &device, &feature_level, &immediate_context);
-    ok(hr == DXGI_ERROR_INVALID_CALL, "D3D11CreateDeviceAndSwapChain returned %#x.\n", hr);
-    ok(!swapchain, "Got unexpected swapchain pointer %p.\n", swapchain);
-    ok(!device, "Got unexpected device pointer %p.\n", device);
-    ok(!feature_level, "Got unexpected feature level %#x.\n", feature_level);
-    ok(!immediate_context, "Got unexpected immediate context pointer %p.\n", immediate_context);
+    todo_wine ok(hr == DXGI_ERROR_INVALID_CALL, "D3D11CreateDeviceAndSwapChain returned %#x.\n", hr);
+    if (SUCCEEDED(hr))
+    {
+        refcount = IDXGISwapChain_Release(swapchain);
+        ok(!refcount, "Swapchain has %u references left.\n", refcount);
+        refcount = ID3D11DeviceContext_Release(immediate_context);
+        ok(!refcount, "Immediate context has %u references left.\n", refcount);
+        refcount = ID3D11Device_Release(device);
+        ok(!refcount, "Device has %u references left.\n", refcount);
+    }
+    else
+    {
+        ok(!swapchain, "Got unexpected swapchain pointer %p.\n", swapchain);
+        ok(!device, "Got unexpected device pointer %p.\n", device);
+        ok(!feature_level, "Got unexpected feature level %#x.\n", feature_level);
+        ok(!immediate_context, "Got unexpected immediate context pointer %p.\n", immediate_context);
+    }
 
     swapchain = (IDXGISwapChain *)0xdeadbeef;
     device = (ID3D11Device *)0xdeadbeef;
diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c
index 6084fd2..3480de0 100644
--- a/dlls/d3d9/tests/device.c
+++ b/dlls/d3d9/tests/device.c
@@ -12418,6 +12418,21 @@ static void test_stretch_rect(void)
     DestroyWindow(window);
 }
 
+static void test_desktop_window(void)
+{
+    IDirect3DDevice9 *device = NULL;
+    IDirect3D9 *d3d;
+
+    d3d = Direct3DCreate9(D3D_SDK_VERSION);
+    ok(!!d3d, "Failed to create a D3D object.\n");
+
+    device = create_device(d3d, GetDesktopWindow(), NULL);
+    ok(!!device, "Failed to created device on desktop window.\n");
+
+    if (device) IDirect3DDevice9_Release(device);
+    IDirect3D9_Release(d3d);
+}
+
 START_TEST(device)
 {
     WNDCLASSA wc = {0};
@@ -12538,6 +12553,7 @@ START_TEST(device)
     test_format_unknown();
     test_destroyed_window();
     test_lockable_backbuffer();
+    test_desktop_window();
     test_clip_planes_limits();
     test_swapchain_multisample_reset();
     test_stretch_rect();
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c
index 01b92e3..0b5abb5 100644
--- a/dlls/winex11.drv/opengl.c
+++ b/dlls/winex11.drv/opengl.c
@@ -1455,12 +1455,15 @@ static BOOL set_pixel_format(HDC hdc, int format, BOOL allow_change)
 
     TRACE("(%p,%d)\n", hdc, format);
 
-    if (!hwnd || hwnd == GetDesktopWindow())
+    if (!hwnd)
     {
         WARN( "not a valid window DC %p/%p\n", hdc, hwnd );
         return FALSE;
     }
 
+    if (hwnd == GetDesktopWindow())
+        FIXME("Using desktop window for OpenGL is not supported on windows\n");
+
     fmt = get_pixel_format(gdi_display, format, FALSE /* Offscreen */);
     if (!fmt)
     {
-- 
2.7.4

