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