From ebcf5196fc150b6ed4bf4891d3f5b0ebe08d625c Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Fri, 10 Feb 2017 13:58:58 +0100 Subject: [PATCH] ddraw: Implement GetSurfaceFromDC(). Many thanks to Dmitry Timoshkov for helping figure this out. Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- dlls/ddraw/ddraw.spec | 2 +- dlls/ddraw/main.c | 34 ++++++++++++++++++++++++++++++++ dlls/ddraw/tests/ddraw4.c | 39 ++++++++++++++++++++++++++++++++++++- dlls/ddraw/tests/ddraw7.c | 41 +++++++++++++++++++++++++++++++++++++-- 4 files changed, 112 insertions(+), 4 deletions(-) diff --git a/dlls/ddraw/ddraw.spec b/dlls/ddraw/ddraw.spec index 75750910e48..a6cf1411703 100644 --- a/dlls/ddraw/ddraw.spec +++ b/dlls/ddraw/ddraw.spec @@ -15,7 +15,7 @@ @ stdcall -private DllRegisterServer() @ stdcall -private DllUnregisterServer() @ stub GetNextMipMap -@ stub GetSurfaceFromDC +@ stdcall GetSurfaceFromDC(ptr ptr ptr) @ stub HeapVidMemAllocAligned @ stub InternalLock @ stub InternalUnlock diff --git a/dlls/ddraw/main.c b/dlls/ddraw/main.c index 4c94dd12f56..4caa9235ff2 100644 --- a/dlls/ddraw/main.c +++ b/dlls/ddraw/main.c @@ -200,6 +200,40 @@ void *ddraw_get_object(struct ddraw_handle_table *t, DWORD handle, enum ddraw_ha return entry->object; } +HRESULT WINAPI GetSurfaceFromDC(HDC dc, IDirectDrawSurface4 **surface, HDC *device_dc) +{ + struct ddraw *ddraw; + + TRACE("dc %p, surface %p, device_dc %p.\n", dc, surface, device_dc); + + if (!surface) + return E_INVALIDARG; + + if (!device_dc) + { + *surface = NULL; + + return E_INVALIDARG; + } + + wined3d_mutex_lock(); + LIST_FOR_EACH_ENTRY(ddraw, &global_ddraw_list, struct ddraw, ddraw_list_entry) + { + if (FAILED(IDirectDraw4_GetSurfaceFromDC(&ddraw->IDirectDraw4_iface, dc, surface))) + continue; + + *device_dc = NULL; /* FIXME */ + wined3d_mutex_unlock(); + return DD_OK; + } + wined3d_mutex_unlock(); + + *surface = NULL; + *device_dc = NULL; + + return DDERR_NOTFOUND; +} + /*********************************************************************** * * Helper function for DirectDrawCreate and friends diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c index d5b43f45fc9..830da89bba2 100644 --- a/dlls/ddraw/tests/ddraw4.c +++ b/dlls/ddraw/tests/ddraw4.c @@ -24,6 +24,8 @@ #include #include "d3d.h" +HRESULT WINAPI GetSurfaceFromDC(HDC dc, struct IDirectDrawSurface **surface, HDC *device_dc); + static BOOL is_ddraw64 = sizeof(DWORD) != sizeof(DWORD *); static DEVMODEW registry_mode; @@ -12778,10 +12780,11 @@ static void test_get_surface_from_dc(void) IDirectDrawSurface4 *surface; DDSURFACEDESC2 surface_desc; IDirectDraw4 *ddraw; + HDC dc, device_dc; ULONG refcount; HWND window; HRESULT hr; - HDC dc; + DWORD ret; window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, 0, 0); @@ -12810,6 +12813,33 @@ static void test_get_surface_from_dc(void) hr = IDirectDrawSurface4_GetDC(surface, &dc); ok(SUCCEEDED(hr), "Failed to get DC, hr %#x.\n", hr); + tmp = (void *)0xdeadbeef; + device_dc = (void *)0xdeadbeef; + hr = GetSurfaceFromDC(NULL, &tmp, &device_dc); + ok(hr == DDERR_NOTFOUND, "Got unexpected hr %#x.\n", hr); + ok(!tmp, "Got unexpected surface %p.\n", tmp); + ok(!device_dc, "Got unexpected device_dc %p.\n", device_dc); + + device_dc = (void *)0xdeadbeef; + hr = GetSurfaceFromDC(dc, NULL, &device_dc); + ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); + ok(device_dc == (void *)0xdeadbeef, "Got unexpected device_dc %p.\n", device_dc); + + tmp = (void *)0xdeadbeef; + hr = GetSurfaceFromDC(dc, &tmp, NULL); + ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); + ok(!tmp, "Got unexpected surface %p.\n", tmp); + + hr = GetSurfaceFromDC(dc, &tmp, &device_dc); + ok(SUCCEEDED(hr), "GetSurfaceFromDC failed, hr %#x.\n", hr); + ok(tmp == surface1, "Got unexpected surface %p, expected %p.\n", tmp, surface1); + IDirectDrawSurface_Release(tmp); + + ret = GetObjectType(device_dc); + todo_wine ok(ret == OBJ_DC, "Got unexpected object type %#x.\n", ret); + ret = GetDeviceCaps(device_dc, TECHNOLOGY); + todo_wine ok(ret == DT_RASDISPLAY, "Got unexpected technology %#x.\n", ret); + hr = IDirectDraw4_GetSurfaceFromDC(ddraw, dc, NULL); ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); @@ -12830,6 +12860,13 @@ static void test_get_surface_from_dc(void) dc = CreateCompatibleDC(NULL); ok(!!dc, "CreateCompatibleDC failed.\n"); + tmp = (void *)0xdeadbeef; + device_dc = (void *)0xdeadbeef; + hr = GetSurfaceFromDC(dc, &tmp, &device_dc); + ok(hr == DDERR_NOTFOUND, "Got unexpected hr %#x.\n", hr); + ok(!tmp, "Got unexpected surface %p.\n", tmp); + ok(!device_dc, "Got unexpected device_dc %p.\n", device_dc); + tmp = (void *)0xdeadbeef; hr = IDirectDraw4_GetSurfaceFromDC(ddraw, dc, (IDirectDrawSurface4 **)&tmp); ok(hr == DDERR_NOTFOUND, "Got unexpected hr %#x.\n", hr); diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index 70aff8f1d42..31e76403f9c 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -24,6 +24,8 @@ #include #include "d3d.h" +HRESULT WINAPI GetSurfaceFromDC(HDC dc, struct IDirectDrawSurface **surface, HDC *device_dc); + static HRESULT (WINAPI *pDirectDrawCreateEx)(GUID *guid, void **ddraw, REFIID iid, IUnknown *outer_unknown); static BOOL is_ddraw64 = sizeof(DWORD) != sizeof(DWORD *); static DEVMODEW registry_mode; @@ -12447,14 +12449,15 @@ static void test_surface_desc_size(void) static void test_get_surface_from_dc(void) { + IDirectDrawSurface *surface1, *tmp1; IDirectDrawSurface7 *surface, *tmp; - IDirectDrawSurface *surface1; DDSURFACEDESC2 surface_desc; IDirectDraw7 *ddraw; + HDC dc, device_dc; ULONG refcount; HWND window; HRESULT hr; - HDC dc; + DWORD ret; window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, 0, 0); @@ -12483,6 +12486,33 @@ static void test_get_surface_from_dc(void) hr = IDirectDrawSurface7_GetDC(surface, &dc); ok(SUCCEEDED(hr), "Failed to get DC, hr %#x.\n", hr); + tmp1 = (void *)0xdeadbeef; + device_dc = (void *)0xdeadbeef; + hr = GetSurfaceFromDC(NULL, &tmp1, &device_dc); + ok(hr == DDERR_NOTFOUND, "Got unexpected hr %#x.\n", hr); + ok(!tmp1, "Got unexpected surface %p.\n", tmp1); + ok(!device_dc, "Got unexpected device_dc %p.\n", device_dc); + + device_dc = (void *)0xdeadbeef; + hr = GetSurfaceFromDC(dc, NULL, &device_dc); + ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); + ok(device_dc == (void *)0xdeadbeef, "Got unexpected device_dc %p.\n", device_dc); + + tmp1 = (void *)0xdeadbeef; + hr = GetSurfaceFromDC(dc, &tmp1, NULL); + ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); + ok(!tmp1, "Got unexpected surface %p.\n", tmp1); + + hr = GetSurfaceFromDC(dc, &tmp1, &device_dc); + ok(SUCCEEDED(hr), "GetSurfaceFromDC failed, hr %#x.\n", hr); + ok(tmp1 == surface1, "Got unexpected surface %p, expected %p.\n", tmp1, surface1); + IDirectDrawSurface_Release(tmp1); + + ret = GetObjectType(device_dc); + todo_wine ok(ret == OBJ_DC, "Got unexpected object type %#x.\n", ret); + ret = GetDeviceCaps(device_dc, TECHNOLOGY); + todo_wine ok(ret == DT_RASDISPLAY, "Got unexpected technology %#x.\n", ret); + hr = IDirectDraw7_GetSurfaceFromDC(ddraw, dc, NULL); ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); @@ -12503,6 +12533,13 @@ static void test_get_surface_from_dc(void) dc = CreateCompatibleDC(NULL); ok(!!dc, "CreateCompatibleDC failed.\n"); + tmp1 = (void *)0xdeadbeef; + device_dc = (void *)0xdeadbeef; + hr = GetSurfaceFromDC(dc, &tmp1, &device_dc); + ok(hr == DDERR_NOTFOUND, "Got unexpected hr %#x.\n", hr); + ok(!tmp1, "Got unexpected surface %p.\n", tmp1); + ok(!device_dc, "Got unexpected device_dc %p.\n", device_dc); + tmp = (void *)0xdeadbeef; hr = IDirectDraw7_GetSurfaceFromDC(ddraw, dc, &tmp); ok(hr == DDERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);