From 716160a2f199982dced092fbd13849d841fe4fdb Mon Sep 17 00:00:00 2001
From: Aaryaman Vasishta <jem456.vasishta@gmail.com>
Date: Thu, 2 Jul 2015 01:09:42 +0530
Subject: d3drm: Implement IDirect3DRM::CreateDeviceFromClipper
Reply-To: wine-devel <wine-devel@winehq.org>

---
 dlls/d3drm/d3drm.c       | 57 +++++++++++++++++++++++++++++++++++++++++++++---
 dlls/d3drm/tests/d3drm.c |  8 +++----
 2 files changed, 58 insertions(+), 7 deletions(-)

diff --git a/dlls/d3drm/d3drm.c b/dlls/d3drm/d3drm.c
index 8ad85dc..299cdb3 100644
--- a/dlls/d3drm/d3drm.c
+++ b/dlls/d3drm/d3drm.c
@@ -258,10 +258,62 @@ static HRESULT WINAPI d3drm1_CreateDeviceFromClipper(IDirect3DRM *iface,
         IDirectDrawClipper *clipper, GUID *guid, int width, int height,
         IDirect3DRMDevice **device)
 {
-    FIXME("iface %p, clipper %p, guid %s, width %d, height %d, device %p.\n",
+    struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
+    IDirectDraw *ddraw;
+    IDirectDrawSurface *surface, *primary_surface;
+    DDSURFACEDESC surface_desc;
+    HWND window;
+    HRESULT hr;
+
+    TRACE("iface %p, clipper %p, guid %s, width %d, height %d, device %p.\n",
             iface, clipper, debugstr_guid(guid), width, height, device);
 
-    return Direct3DRMDevice_create(&IID_IDirect3DRMDevice, (IUnknown **)device);
+    if (!clipper || !width || !height)
+        return D3DRMERR_BADVALUE;
+
+    hr = DirectDrawCreate(NULL, &ddraw, NULL);
+    if (FAILED(hr))
+        return hr;
+
+    hr = IDirectDrawClipper_GetHWnd(clipper, &window);
+    if (FAILED(hr))
+        return hr;
+
+    hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
+    if (FAILED(hr))
+        return hr;
+
+    hr = Direct3DRMDevice_create(&IID_IDirect3DRMDevice, (IUnknown **)device);
+    if (FAILED(hr))
+        return hr;
+
+    memset(&surface_desc, 0, sizeof(surface_desc));
+    surface_desc.dwSize = sizeof(surface_desc);
+    surface_desc.dwFlags = DDSD_CAPS;
+    surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
+    hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &primary_surface, NULL);
+    if (FAILED(hr))
+        return hr;
+    hr = IDirectDrawSurface_SetClipper(primary_surface, clipper);
+    if (FAILED(hr))
+        return hr;
+    set_primary_surface((void **)device, 1, clipper, primary_surface);
+
+    memset(&surface_desc, 0, sizeof(surface_desc));
+    surface_desc.dwSize = sizeof(surface_desc);
+    surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
+    surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
+    surface_desc.dwWidth = width;
+    surface_desc.dwHeight = height;
+
+    hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &surface, NULL);
+    if (FAILED(hr))
+        return hr;
+
+    hr = init_device(&d3drm->IDirect3DRM_iface, guid, ddraw, surface, TRUE, NULL, width, height, (void **)device);
+    IDirectDrawSurface_Release(surface);
+
+    return hr;
 }
 
 static HRESULT WINAPI d3drm1_CreateTextureFromSurface(IDirect3DRM *iface,
@@ -628,7 +680,6 @@ static HRESULT WINAPI d3drm2_CreateDeviceFromClipper(IDirect3DRM2 *iface,
 
     return D3DRM_OK;
 }
-
 static HRESULT WINAPI d3drm2_CreateTextureFromSurface(IDirect3DRM2 *iface,
         IDirectDrawSurface *surface, IDirect3DRMTexture2 **texture)
 {
diff --git a/dlls/d3drm/tests/d3drm.c b/dlls/d3drm/tests/d3drm.c
index 6130e8e..29bc36c 100644
--- a/dlls/d3drm/tests/d3drm.c
+++ b/dlls/d3drm/tests/d3drm.c
@@ -1993,18 +1993,18 @@ static void test_create_device_from_clipper1(void)
     cref1 = get_refcount((IUnknown *)clipper);
 
     hr = IDirect3DRM_CreateDeviceFromClipper(d3drm1, clipper, &driver, 0, 0, &device1);
-    todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr);
+    ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr);
 
     /* If NULL is passed for clipper, CreateDeviceFromClipper returns D3DRMERR_BADVALUE */
     hr = IDirect3DRM_CreateDeviceFromClipper(d3drm1, NULL, &driver, 0, 0, &device1);
-    todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr);
+    ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr);
 
     hr = IDirect3DRM_CreateDeviceFromClipper(d3drm1, clipper, &driver, 300, 200, &device1);
     ok(hr == D3DRM_OK, "Cannot create IDirect3DRMDevice interface (hr = %x).\n", hr);
     ref2 = get_refcount((IUnknown *)d3drm1);
-    todo_wine ok(ref2 > ref1, "expected ref2 > ref1, got ref1 = %u , ref2 = %u.\n", ref1, ref2);
+    ok(ref2 > ref1, "expected ref2 > ref1, got ref1 = %u , ref2 = %u.\n", ref1, ref2);
     cref2 = get_refcount((IUnknown *)clipper);
-    todo_wine ok(cref2 > cref1, "expected cref2 > cref1, got cref1 = %u , cref2 = %u.\n", cref1, cref2);
+    ok(cref2 > cref1, "expected cref2 > cref1, got cref1 = %u , cref2 = %u.\n", cref1, cref2);
 
     /* Fetch immediate mode device in order to access render target */
     hr = IDirect3DRMDevice_GetDirect3DDevice(device1, &d3ddevice1);
-- 
2.3.2 (Apple Git-55)

