Module: wine Branch: master Commit: 4e48ae2629cc641f3a02862b9477daae02a1c85b URL: http://source.winehq.org/git/wine.git/?a=commit;h=4e48ae2629cc641f3a02862b94...
Author: Henri Verbeet hverbeet@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);