Henri Verbeet : ddraw: Implement IDirectDrawImpl_GetSurfaceFromDC().

Alexandre Julliard julliard at winehq.org
Wed Mar 17 12:19:05 CDT 2010


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

Author: Henri Verbeet <hverbeet at codeweavers.com>
Date:   Tue Mar 16 19:02:21 2010 +0100

ddraw: Implement IDirectDrawImpl_GetSurfaceFromDC().

This is a pretty naive implementation, should that become a performance
problem it's easy enough to speed up with a search tree of some kind.

---

 dlls/ddraw/ddraw.c          |   21 +++++++++++++++++----
 dlls/ddraw/tests/dsurface.c |   31 +++++++++++++++++++++++++++++++
 dlls/wined3d/device.c       |   25 ++++++++++++++++++++++++-
 include/wine/wined3d.idl    |    4 ++++
 4 files changed, 76 insertions(+), 5 deletions(-)

diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index 527f448..4d5701f 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -1514,11 +1514,24 @@ IDirectDrawImpl_GetSurfaceFromDC(IDirectDraw7 *iface,
                                  IDirectDrawSurface7 **Surface)
 {
     IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
-    FIXME("(%p)->(%p,%p): Stub!\n", This, hdc, Surface);
+    IWineD3DSurface *wined3d_surface;
+    HRESULT hr;
+
+    TRACE("iface %p, dc %p, surface %p.\n", iface, hdc, Surface);
+
+    if (!Surface) return E_INVALIDARG;
 
-    /* Implementation idea if needed: Loop through all surfaces and compare
-     * their hdc with hdc. Implement it in WineD3D! */
-    return DDERR_NOTFOUND;
+    hr = IWineD3DDevice_GetSurfaceFromDC(This->wineD3DDevice, hdc, &wined3d_surface);
+    if (FAILED(hr))
+    {
+        TRACE("No surface found for dc %p.\n", hdc);
+        *Surface = NULL;
+        return DDERR_NOTFOUND;
+    }
+
+    IWineD3DSurface_GetParent(wined3d_surface, (IUnknown **)Surface);
+    TRACE("Returning surface %p.\n", Surface);
+    return DD_OK;
 }
 
 /*****************************************************************************
diff --git a/dlls/ddraw/tests/dsurface.c b/dlls/ddraw/tests/dsurface.c
index d53d6a0..f323ef0 100644
--- a/dlls/ddraw/tests/dsurface.c
+++ b/dlls/ddraw/tests/dsurface.c
@@ -3008,10 +3008,12 @@ static void GetDCTest(void)
     IDirectDrawSurface2 *surf2;
     IDirectDrawSurface4 *surf4;
     IDirectDrawSurface7 *surf7;
+    IDirectDrawSurface7 *tmp7;
     HRESULT hr;
     IDirectDraw2 *dd2;
     IDirectDraw4 *dd4;
     IDirectDraw7 *dd7;
+    HDC dc;
 
     memset(&ddsd, 0, sizeof(ddsd));
     ddsd.dwSize = sizeof(ddsd);
@@ -3064,6 +3066,35 @@ static void GetDCTest(void)
     ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed: 0x%08x\n", hr);
     dctest_surf((IDirectDrawSurface *) surf7, 2);
 
+    hr = IDirectDrawSurface7_GetDC(surf7, &dc);
+    ok(SUCCEEDED(hr), "GetDC failed, hr %#x.\n", hr);
+
+    hr = IDirectDraw7_GetSurfaceFromDC(dd7, dc, NULL);
+    ok(hr == E_INVALIDARG, "Expected hr E_INVALIDARG, got %#x.\n", hr);
+
+    hr = IDirectDraw7_GetSurfaceFromDC(dd7, dc, &tmp7);
+    ok(SUCCEEDED(hr), "GetSurfaceFromDC failed, hr %#x.\n", hr);
+    ok(tmp7 == surf7, "Expected surface %p, got %p.\n\n", surf7, tmp7);
+    IDirectDrawSurface7_Release(tmp7);
+
+    hr = IDirectDrawSurface7_ReleaseDC(surf7, dc);
+    ok(SUCCEEDED(hr), "ReleaseDC failed, hr %#x.\n", hr);
+
+    dc = CreateCompatibleDC(NULL);
+    ok(!!dc, "CreateCompatibleDC failed.\n");
+
+    tmp7 = (IDirectDrawSurface7 *)0xdeadbeef;
+    hr = IDirectDraw7_GetSurfaceFromDC(dd7, dc, &tmp7);
+    ok(hr == DDERR_NOTFOUND, "GetSurfaceFromDC failed, hr %#x.\n", hr);
+    ok(!tmp7, "Expected surface NULL, got %p.\n", tmp7);
+
+    ok(DeleteDC(dc), "DeleteDC failed.\n");
+
+    tmp7 = (IDirectDrawSurface7 *)0xdeadbeef;
+    hr = IDirectDraw7_GetSurfaceFromDC(dd7, NULL, (IDirectDrawSurface7 **)&tmp7);
+    ok(hr == DDERR_NOTFOUND, "GetSurfaceFromDC failed, hr %#x.\n", hr);
+    ok(!tmp7, "Expected surface NULL, got %p.\n", tmp7);
+
     IDirectDrawSurface7_Release(surf7);
     IDirectDraw7_Release(dd7);
 }
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 5f4d2f8..0968bfc 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -6870,6 +6870,28 @@ static HRESULT WINAPI IWineD3DDeviceImpl_EnumResources(IWineD3DDevice *iface, D3
     return WINED3D_OK;
 }
 
+static HRESULT WINAPI IWineD3DDeviceImpl_GetSurfaceFromDC(IWineD3DDevice *iface, HDC dc, IWineD3DSurface **surface)
+{
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
+    IWineD3DResourceImpl *resource;
+
+    LIST_FOR_EACH_ENTRY(resource, &This->resources, IWineD3DResourceImpl, resource.resource_list_entry)
+    {
+        WINED3DRESOURCETYPE type = IWineD3DResource_GetType((IWineD3DResource *)resource);
+        if (type == WINED3DRTYPE_SURFACE)
+        {
+            if (((IWineD3DSurfaceImpl *)resource)->hDC == dc)
+            {
+                TRACE("Found surface %p for dc %p.\n", resource, dc);
+                *surface = (IWineD3DSurface *)resource;
+                return WINED3D_OK;
+            }
+        }
+    }
+
+    return WINED3DERR_INVALIDCALL;
+}
+
 /**********************************************************
  * IWineD3DDevice VTbl follows
  **********************************************************/
@@ -7018,7 +7040,8 @@ static const IWineD3DDeviceVtbl IWineD3DDevice_Vtbl =
     IWineD3DDeviceImpl_UpdateSurface,
     IWineD3DDeviceImpl_GetFrontBufferData,
     /*** object tracking ***/
-    IWineD3DDeviceImpl_EnumResources
+    IWineD3DDeviceImpl_EnumResources,
+    IWineD3DDeviceImpl_GetSurfaceFromDC,
 };
 
 HRESULT device_init(IWineD3DDeviceImpl *device, IWineD3DImpl *wined3d,
diff --git a/include/wine/wined3d.idl b/include/wine/wined3d.idl
index ac4ee89..b8467d8 100644
--- a/include/wine/wined3d.idl
+++ b/include/wine/wined3d.idl
@@ -3456,6 +3456,10 @@ interface IWineD3DDevice : IWineD3DBase
         [in] D3DCB_ENUMRESOURCES callback,
         [in] void *data
     );
+    HRESULT GetSurfaceFromDC(
+        [in] HDC dc,
+        [out] IWineD3DSurface **surface
+    );
 }
 
 IWineD3D *WineDirect3DCreate(UINT dxVersion, IUnknown *parent);




More information about the wine-cvs mailing list