Henri Verbeet : ddraw: Window proc replacement depends on DDSCL_EXCLUSIVE, not DDSCL_FULLSCREEN.

Alexandre Julliard julliard at winehq.org
Wed Nov 10 11:09:40 CST 2010


Module: wine
Branch: master
Commit: 6fcb33f59f8449d836bf7eb58acd48172bf9ad4f
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=6fcb33f59f8449d836bf7eb58acd48172bf9ad4f

Author: Henri Verbeet <hverbeet at codeweavers.com>
Date:   Wed Nov 10 10:53:01 2010 +0100

ddraw: Window proc replacement depends on DDSCL_EXCLUSIVE, not DDSCL_FULLSCREEN.

---

 dlls/ddraw/ddraw.c     |   27 +++++++++++++++++----------
 dlls/ddraw/tests/d3d.c |   34 ++++++++++++++++++++++++++++++++++
 2 files changed, 51 insertions(+), 10 deletions(-)

diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index 512fd8e..e155482 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -641,12 +641,15 @@ static HRESULT WINAPI ddraw7_SetCooperativeLevel(IDirectDraw7 *iface, HWND hwnd,
         TRACE("(%p) SetCooperativeLevel needs at least SetFocusWindow or Exclusive or Normal mode\n", This);
         LeaveCriticalSection(&ddraw_cs);
         return DDERR_INVALIDPARAMS;
-     }
+    }
+
+    if ((This->cooperative_level & DDSCL_EXCLUSIVE)
+            && (hwnd != window || !(cooplevel & DDSCL_EXCLUSIVE)))
+        IWineD3DDevice_ReleaseFocusWindow(This->wineD3DDevice);
 
     /* Do we switch from fullscreen to non-fullscreen ? */
     if (!(cooplevel & DDSCL_FULLSCREEN) && (This->cooperative_level & DDSCL_FULLSCREEN))
     {
-        IWineD3DDevice_ReleaseFocusWindow(This->wineD3DDevice);
         IWineD3DDevice_RestoreFullscreenWindow(This->wineD3DDevice, This->dest_window);
     }
 
@@ -656,21 +659,25 @@ static HRESULT WINAPI ddraw7_SetCooperativeLevel(IDirectDraw7 *iface, HWND hwnd,
         if (cooplevel & DDSCL_FULLSCREEN)
         {
             WINED3DDISPLAYMODE display_mode;
-            HRESULT hr;
 
             IWineD3D_GetAdapterDisplayMode(This->wineD3D, WINED3DADAPTER_DEFAULT, &display_mode);
             IWineD3DDevice_SetupFullscreenWindow(This->wineD3DDevice, hwnd, display_mode.Width, display_mode.Height);
-            hr = IWineD3DDevice_AcquireFocusWindow(This->wineD3DDevice, hwnd);
-            if (FAILED(hr))
-            {
-                ERR("Failed to acquire focus window, hr %#x.\n", hr);
-                LeaveCriticalSection(&ddraw_cs);
-                return hr;
-            }
         }
         This->dest_window = hwnd;
     }
 
+    if ((cooplevel & DDSCL_EXCLUSIVE)
+            && (hwnd != window || !(This->cooperative_level & DDSCL_EXCLUSIVE)))
+    {
+        HRESULT hr = IWineD3DDevice_AcquireFocusWindow(This->wineD3DDevice, hwnd);
+        if (FAILED(hr))
+        {
+            ERR("Failed to acquire focus window, hr %#x.\n", hr);
+            LeaveCriticalSection(&ddraw_cs);
+            return hr;
+        }
+    }
+
     if(cooplevel & DDSCL_CREATEDEVICEWINDOW)
     {
         /* Don't create a device window if a focus window is set */
diff --git a/dlls/ddraw/tests/d3d.c b/dlls/ddraw/tests/d3d.c
index 9066e4e..82fdedf 100644
--- a/dlls/ddraw/tests/d3d.c
+++ b/dlls/ddraw/tests/d3d.c
@@ -3281,6 +3281,7 @@ static void test_wndproc(void)
         0,
     };
 
+    /* DDSCL_EXCLUSIVE replaces the window's window proc. */
     hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
     if (FAILED(hr))
     {
@@ -3323,6 +3324,39 @@ static void test_wndproc(void)
     ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
             (LONG_PTR)test_proc, proc);
 
+    /* DDSCL_NORMAL doesn't. */
+    hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
+    if (FAILED(hr))
+    {
+        skip("Failed to create IDirectDraw7 object (%#x), skipping tests.\n", hr);
+        return;
+    }
+
+    proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
+    ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
+            (LONG_PTR)test_proc, proc);
+
+    hr = IDirectDraw7_SetCooperativeLevel(ddraw7, window, DDSCL_NORMAL | DDSCL_FULLSCREEN);
+    ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
+    if (FAILED(hr))
+    {
+        IDirectDraw7_Release(ddraw7);
+        goto done;
+    }
+
+    proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
+    ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
+            (LONG_PTR)test_proc, proc);
+
+    ref = IDirectDraw7_Release(ddraw7);
+    ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
+
+    proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
+    ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
+            (LONG_PTR)test_proc, proc);
+
+    /* The original window proc is only restored by ddraw if the current
+     * window proc matches the one ddraw set. */
     hr = pDirectDrawCreateEx(NULL, (void **)&ddraw7, &IID_IDirectDraw7, NULL);
     if (FAILED(hr))
     {




More information about the wine-cvs mailing list