Regarding dirty rectangles:<br> Documentation for `ForceUpdate` states that "The system might update any region that is larger than the specified rectangle, including possibly the entire window". While native seems to use a sort of dirty-rectangle approach, for this MR, I am simply dirtying the entire surface. If someday someone did want to more-closely match the behavior of native, much can be learned from the rectangles passed to the update callbacks.
From: Jeff Smith whydoubt@gmail.com
--- dlls/d3drm/tests/d3drm.c | 940 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 940 insertions(+)
diff --git a/dlls/d3drm/tests/d3drm.c b/dlls/d3drm/tests/d3drm.c index 5d478f24b1a..b9367f67d34 100644 --- a/dlls/d3drm/tests/d3drm.c +++ b/dlls/d3drm/tests/d3drm.c @@ -6833,6 +6833,25 @@ static D3DCOLOR get_surface_color(IDirectDrawSurface *surface, UINT x, UINT y) return color; }
+static HRESULT set_surface_color(IDirectDrawSurface *surface, UINT x, UINT y, D3DCOLOR color) +{ + RECT rect = { x, y, x + 1, y + 1 }; + DDSURFACEDESC surface_desc; + HRESULT hr; + + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + + hr = IDirectDrawSurface_Lock(surface, &rect, &surface_desc, DDLOCK_WRITEONLY | DDLOCK_WAIT, NULL); + if (FAILED(hr)) + return hr; + + *((DWORD *)surface_desc.lpSurface) = color; + + hr = IDirectDrawSurface_Unlock(surface, NULL); + return hr; +} + static IDirect3DDevice2 *create_device2_without_ds(IDirectDraw2 *ddraw, HWND window) { IDirectDrawSurface *surface; @@ -8230,6 +8249,921 @@ static void test_wrap_qi(void)
IDirect3DRM_Release(d3drm1); } + +struct update_rect_context +{ + int rect_count; + D3DRECT rect; +}; + +static void CDECL update_cb_modify_rect(IDirect3DRMDevice *device, void *arg, int rect_count, D3DRECT *update_rects) +{ + if (rect_count > 0) + update_rects[0].x1 = 999999; +} +static void CDECL update_cb_get_rect(IDirect3DRMDevice *device, void *arg, int rect_count, D3DRECT *update_rects) +{ + struct update_rect_context *ctx = arg; + ctx->rect_count = rect_count; + if (rect_count > 0) + ctx->rect = update_rects[0]; +} + +static void test_update_1(void) +{ + IDirect3DRM *d3drm1 = NULL; + IDirect3DRMDevice *device1 = NULL; + IDirect3DRMFrame *scene = NULL, *camera = NULL; + IDirect3DRMViewport *viewport = NULL; + IDirectDrawClipper *clipper = NULL; + GUID driver = IID_IDirect3DRGBDevice; + DWORD dev_width = 600, dev_height = 400; + RECT vrect = { 1, 1, 480, 360 }; + struct update_rect_context ctx; + HWND window; + HRESULT hr; + + window = create_window(); + + /* Set up device */ + hr = DirectDrawCreateClipper(0, &clipper, NULL); + ok(hr == DD_OK, "Cannot get IDirectDrawClipper interface, hr %#lx.\n", hr); + hr = IDirectDrawClipper_SetHWnd(clipper, 0, window); + ok(hr == DD_OK, "Cannot set HWnd to Clipper, hr %#lx.\n", hr); + hr = Direct3DRMCreate(&d3drm1); + ok(SUCCEEDED(hr), "Cannot create IDirect3DRM instance, hr %#lx.\n", hr); + hr = IDirect3DRM_CreateDeviceFromClipper(d3drm1, clipper, &driver, dev_width, dev_height, &device1); + ok(hr == D3DRM_OK, "Cannot create IDirect3DRMDevice interface, hr %#lx.\n", hr); + + /* Set up viewport */ + hr = IDirect3DRM_CreateFrame(d3drm1, NULL, &scene); + ok(hr == D3DRM_OK, "Cannot create root scene, hr %#lx.\n", hr); + hr = IDirect3DRM_CreateFrame(d3drm1, scene, &camera); + ok(hr == D3DRM_OK, "Cannot create camera, hr %#lx.\n", hr); + hr = IDirect3DRM_CreateViewport(d3drm1, device1, camera, + vrect.left, vrect.top, vrect.right - vrect.left, vrect.bottom - vrect.top, &viewport); + ok(hr == D3DRM_OK, "Cannot create viewport, hr %#lx\n", hr); + + /* Callbacks receive no rectangles if the viewport hasn't been notified of updates */ + ctx.rect.x1 = ctx.rect.y1 = ctx.rect.x2 = ctx.rect.y2 = ~0; + ctx.rect_count = -1; + hr = IDirect3DRMDevice_AddUpdateCallback(device1, update_cb_get_rect, &ctx); + todo_wine ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); + hr = IDirect3DRMDevice_Update(device1); + ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice, hr %#lx.\n", hr); + hr = IDirect3DRMDevice_DeleteUpdateCallback(device1, update_cb_get_rect, &ctx); + todo_wine ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); + todo_wine ok(ctx.rect_count == 0, "Got unexpected rect count %d, expected 0.\n", ctx.rect_count); + ok(ctx.rect.x1 == ~0 && ctx.rect.y1 == ~0 && ctx.rect.x2 == ~0 && ctx.rect.y2 == ~0, + "Got unexpected rect %s.\n", wine_dbgstr_rect((RECT *)&ctx.rect)); + + /* Area cannot extend beyond viewport */ + hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left - 1, vrect.top, vrect.right - 1, vrect.bottom); + todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left, vrect.top - 1, vrect.right, vrect.bottom - 1); + todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left + 1, vrect.top, vrect.right + 1, vrect.bottom); + todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left, vrect.top + 1, vrect.right, vrect.bottom + 1); + todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + /* Point 1 cannot be left of or above Point 2 */ + hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left + 1, vrect.top, vrect.left, vrect.top + 1); + todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left, vrect.top + 1, vrect.left + 1, vrect.top); + todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left + 1, vrect.top + 1, vrect.left, vrect.top); + todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + /* Anything else is allowed, including a single point */ + hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left, vrect.top, vrect.left, vrect.top); + todo_wine ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); + hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left, vrect.top, vrect.left + 1, vrect.top + 1); + todo_wine ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); + hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left, vrect.top, vrect.right, vrect.bottom); + todo_wine ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); + /* Update just to flush force updates */ + hr = IDirect3DRMDevice_Update(device1); + ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice, hr %#lx.\n", hr); + + /* Callbacks will receive (at least) one rectangle following a force update */ + ctx.rect.x1 = ctx.rect.y1 = ctx.rect.x2 = ctx.rect.y2 = ~0; + ctx.rect_count = -1; + hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left, vrect.top, vrect.right, vrect.bottom); + todo_wine ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); + hr = IDirect3DRMDevice_AddUpdateCallback(device1, update_cb_modify_rect, NULL); + todo_wine ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); + hr = IDirect3DRMDevice_AddUpdateCallback(device1, update_cb_get_rect, &ctx); + todo_wine ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); + hr = IDirect3DRMDevice_Update(device1); + ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice, hr %#lx.\n", hr); + hr = IDirect3DRMDevice_DeleteUpdateCallback(device1, update_cb_modify_rect, NULL); + todo_wine ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); + hr = IDirect3DRMDevice_DeleteUpdateCallback(device1, update_cb_get_rect, &ctx); + todo_wine ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); + todo_wine ok(ctx.rect_count == 1, "Got unexpected rect count %d, expected 1.\n", ctx.rect_count); + todo_wine + ok(ctx.rect.x1 == 999999 && ctx.rect.y1 <= vrect.top && + ctx.rect.x2 >= vrect.right && ctx.rect.y2 >= vrect.bottom, + "Got unexpected rect %s.\n", wine_dbgstr_rect((RECT *)&ctx.rect)); + + /* Callbacks will receive (at least) one rectangle following a viewport clear */ + ctx.rect.x1 = ctx.rect.y1 = ctx.rect.x2 = ctx.rect.y2 = ~0; + ctx.rect_count = -1; + hr = IDirect3DRMViewport_Clear(viewport); + ok(hr == D3DRM_OK, "Cannot clear viewport, hr %#lx.\n", hr); + hr = IDirect3DRMDevice_AddUpdateCallback(device1, update_cb_get_rect, &ctx); + todo_wine ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); + hr = IDirect3DRMDevice_Update(device1); + ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice, hr %#lx.\n", hr); + hr = IDirect3DRMDevice_DeleteUpdateCallback(device1, update_cb_get_rect, &ctx); + todo_wine ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); + todo_wine ok(ctx.rect_count == 1, "Got unexpected rect count %d, expected 1.\n", ctx.rect_count); + todo_wine + ok(ctx.rect.x1 <= vrect.left && ctx.rect.y1 <= vrect.top && + ctx.rect.x2 >= vrect.right && ctx.rect.y2 >= vrect.bottom, + "Got unexpected rect %s.\n", wine_dbgstr_rect((RECT *)&ctx.rect)); + + IDirect3DRMViewport_Release(viewport); + IDirect3DRMFrame_Release(camera); + IDirect3DRMFrame_Release(scene); + + IDirect3DRMDevice_Release(device1); + IDirect3DRM_Release(d3drm1); + IDirectDrawClipper_Release(clipper); + DestroyWindow(window); +} + +static void test_update_2(void) +{ + IDirect3DRM *d3drm1 = NULL; + IDirect3DRM2 *d3drm2 = NULL; + IDirect3DRMDevice *device1 = NULL; + IDirect3DRMDevice2 *device2 = NULL; + IDirect3DRMFrame *scene1 = NULL, *camera1 = NULL; + IDirect3DRMFrame2 *scene = NULL, *camera = NULL; + IDirect3DRMViewport *viewport = NULL; + IDirectDrawClipper *clipper = NULL; + GUID driver = IID_IDirect3DRGBDevice; + DWORD dev_width = 600, dev_height = 400; + RECT vrect = { 1, 1, 480, 360 }; + struct update_rect_context ctx; + HWND window; + HRESULT hr; + + window = create_window(); + + /* Set up device */ + hr = DirectDrawCreateClipper(0, &clipper, NULL); + ok(hr == DD_OK, "Cannot get IDirectDrawClipper interface, hr %#lx.\n", hr); + hr = IDirectDrawClipper_SetHWnd(clipper, 0, window); + ok(hr == DD_OK, "Cannot set HWnd to Clipper, hr %#lx.\n", hr); + hr = Direct3DRMCreate(&d3drm1); + ok(SUCCEEDED(hr), "Cannot create IDirect3DRM instance, hr %#lx.\n", hr); + hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM2, (void **)&d3drm2); + ok(hr == D3DRM_OK, "Cannot get IDirect3DRM3 interface, hr %#lx.\n", hr); + hr = IDirect3DRM2_CreateDeviceFromClipper(d3drm2, clipper, &driver, dev_width, dev_height, &device2); + ok(hr == D3DRM_OK, "Cannot create IDirect3DRMDevice interface, hr %#lx.\n", hr); + hr = IDirect3DRMDevice2_QueryInterface(device2, &IID_IDirect3DRMDevice, (void **)&device1); + ok(hr == D3DRM_OK, "Cannot get IDirect3DRMDevice interface, hr %#lx.\n", hr); + + /* Set up viewport */ + hr = IDirect3DRM2_CreateFrame(d3drm2, NULL, &scene); + ok(hr == D3DRM_OK, "Cannot create root scene, hr %#lx.\n", hr); + hr = IDirect3DRMFrame2_QueryInterface(scene, &IID_IDirect3DRMFrame, (void **)&scene1); + ok(hr == D3DRM_OK, "Cannot get IDirect3DRMFrame interface, hr %#lx.\n", hr); + hr = IDirect3DRM2_CreateFrame(d3drm2, scene1, &camera); + ok(hr == D3DRM_OK, "Cannot create camera, hr %#lx.\n", hr); + hr = IDirect3DRMFrame2_QueryInterface(camera, &IID_IDirect3DRMFrame, (void **)&camera1); + ok(hr == D3DRM_OK, "Cannot get IDirect3DRMFrame interface, hr %#lx.\n", hr); + hr = IDirect3DRM2_CreateViewport(d3drm2, device1, camera1, + vrect.left, vrect.top, vrect.right - vrect.left, vrect.bottom - vrect.top, &viewport); + ok(hr == D3DRM_OK, "Cannot create viewport, hr %#lx\n", hr); + + /* Callbacks receive no rectangles if the viewport hasn't been notified of updates */ + ctx.rect.x1 = ctx.rect.y1 = ctx.rect.x2 = ctx.rect.y2 = ~0; + ctx.rect_count = -1; + hr = IDirect3DRMDevice2_AddUpdateCallback(device2, update_cb_get_rect, &ctx); + todo_wine ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); + hr = IDirect3DRMDevice2_Update(device2); + ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice2, hr %#lx.\n", hr); + hr = IDirect3DRMDevice2_DeleteUpdateCallback(device2, update_cb_get_rect, &ctx); + todo_wine ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); + todo_wine ok(ctx.rect_count == 0, "Got unexpected rect count %d, expected 0.\n", ctx.rect_count); + ok(ctx.rect.x1 == ~0 && ctx.rect.y1 == ~0 && ctx.rect.x2 == ~0 && ctx.rect.y2 == ~0, + "Got unexpected rect %s.\n", wine_dbgstr_rect((RECT *)&ctx.rect)); + + /* Area cannot extend beyond viewport */ + hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left - 1, vrect.top, vrect.right - 1, vrect.bottom); + todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left, vrect.top - 1, vrect.right, vrect.bottom - 1); + todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left + 1, vrect.top, vrect.right + 1, vrect.bottom); + todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left, vrect.top + 1, vrect.right, vrect.bottom + 1); + todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + /* Point 1 cannot be left of or above Point 2 */ + hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left + 1, vrect.top, vrect.left, vrect.top + 1); + todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left, vrect.top + 1, vrect.left + 1, vrect.top); + todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left + 1, vrect.top + 1, vrect.left, vrect.top); + todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + /* Anything else is allowed, including a single point */ + hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left, vrect.top, vrect.left, vrect.top); + todo_wine ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); + hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left, vrect.top, vrect.left + 1, vrect.top + 1); + todo_wine ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); + hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left, vrect.top, vrect.right, vrect.bottom); + todo_wine ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); + /* Update just to flush force updates */ + hr = IDirect3DRMDevice2_Update(device2); + ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice2, hr %#lx.\n", hr); + + /* Callbacks will receive (at least) one rectangle following a force update */ + ctx.rect.x1 = ctx.rect.y1 = ctx.rect.x2 = ctx.rect.y2 = ~0; + ctx.rect_count = -1; + hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left, vrect.top, vrect.right, vrect.bottom); + todo_wine ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); + hr = IDirect3DRMDevice2_AddUpdateCallback(device2, update_cb_modify_rect, NULL); + todo_wine ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); + hr = IDirect3DRMDevice2_AddUpdateCallback(device2, update_cb_get_rect, &ctx); + todo_wine ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); + hr = IDirect3DRMDevice2_Update(device2); + ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice2, hr %#lx.\n", hr); + hr = IDirect3DRMDevice2_DeleteUpdateCallback(device2, update_cb_modify_rect, NULL); + todo_wine ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); + hr = IDirect3DRMDevice2_DeleteUpdateCallback(device2, update_cb_get_rect, &ctx); + todo_wine ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); + todo_wine ok(ctx.rect_count == 1, "Got unexpected rect count %d, expected 1.\n", ctx.rect_count); + todo_wine + ok(ctx.rect.x1 == 999999 && ctx.rect.y1 <= vrect.top && + ctx.rect.x2 >= vrect.right && ctx.rect.y2 >= vrect.bottom, + "Got unexpected rect %s.\n", wine_dbgstr_rect((RECT *)&ctx.rect)); + + /* Callbacks will receive (at least) one rectangle following a viewport clear */ + ctx.rect.x1 = ctx.rect.y1 = ctx.rect.x2 = ctx.rect.y2 = ~0; + ctx.rect_count = -1; + hr = IDirect3DRMViewport_Clear(viewport); + ok(hr == D3DRM_OK, "Cannot clear viewport, hr %#lx.\n", hr); + hr = IDirect3DRMDevice2_AddUpdateCallback(device2, update_cb_get_rect, &ctx); + todo_wine ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); + hr = IDirect3DRMDevice2_Update(device2); + ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice2, hr %#lx.\n", hr); + hr = IDirect3DRMDevice2_DeleteUpdateCallback(device2, update_cb_get_rect, &ctx); + todo_wine ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); + todo_wine ok(ctx.rect_count == 1, "Got unexpected rect count %d, expected 1.\n", ctx.rect_count); + todo_wine + ok(ctx.rect.x1 <= vrect.left && ctx.rect.y1 <= vrect.top && + ctx.rect.x2 >= vrect.right && ctx.rect.y2 >= vrect.bottom, + "Got unexpected rect %s.\n", wine_dbgstr_rect((RECT *)&ctx.rect)); + + IDirect3DRMViewport_Release(viewport); + IDirect3DRMFrame_Release(camera1); + IDirect3DRMFrame2_Release(camera); + IDirect3DRMFrame_Release(scene1); + IDirect3DRMFrame2_Release(scene); + + IDirect3DRMDevice_Release(device1); + IDirect3DRMDevice2_Release(device2); + IDirect3DRM2_Release(d3drm2); + IDirect3DRM_Release(d3drm1); + IDirectDrawClipper_Release(clipper); + DestroyWindow(window); +} + +static void test_update_3(void) +{ + IDirect3DRM *d3drm1 = NULL; + IDirect3DRM3 *d3drm3 = NULL; + IDirect3DRMDevice3 *device3 = NULL; + IDirect3DRMFrame3 *scene = NULL, *camera = NULL; + IDirect3DRMViewport2 *viewport = NULL; + IDirectDrawClipper *clipper = NULL; + GUID driver = IID_IDirect3DRGBDevice; + DWORD dev_width = 600, dev_height = 400; + RECT vrect = { 1, 1, 480, 360 }; + struct update_rect_context ctx; + HWND window; + HRESULT hr; + + window = create_window(); + + /* Set up device */ + hr = DirectDrawCreateClipper(0, &clipper, NULL); + ok(hr == DD_OK, "Cannot get IDirectDrawClipper interface, hr %#lx.\n", hr); + hr = IDirectDrawClipper_SetHWnd(clipper, 0, window); + ok(hr == DD_OK, "Cannot set HWnd to Clipper, hr %#lx.\n", hr); + hr = Direct3DRMCreate(&d3drm1); + ok(SUCCEEDED(hr), "Cannot create IDirect3DRM instance, hr %#lx.\n", hr); + hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3); + ok(hr == D3DRM_OK, "Cannot get IDirect3DRM3 interface, hr %#lx.\n", hr); + hr = IDirect3DRM3_CreateDeviceFromClipper(d3drm3, clipper, &driver, dev_width, dev_height, &device3); + ok(hr == D3DRM_OK, "Cannot create IDirect3DRMDevice3 interface, hr %#lx.\n", hr); + + /* Set up viewport */ + hr = IDirect3DRM3_CreateFrame(d3drm3, NULL, &scene); + ok(hr == D3DRM_OK, "Cannot create root scene, hr %#lx.\n", hr); + hr = IDirect3DRM3_CreateFrame(d3drm3, scene, &camera); + ok(hr == D3DRM_OK, "Cannot create camera, hr %#lx.\n", hr); + hr = IDirect3DRM3_CreateViewport(d3drm3, device3, camera, + vrect.left, vrect.top, vrect.right - vrect.left, vrect.bottom - vrect.top, &viewport); + ok(hr == D3DRM_OK, "Cannot create viewport, hr %#lx\n", hr); + + /* Callbacks receive no rectangles if the viewport hasn't been notified of updates */ + ctx.rect.x1 = ctx.rect.y1 = ctx.rect.x2 = ctx.rect.y2 = ~0; + ctx.rect_count = -1; + hr = IDirect3DRMDevice3_AddUpdateCallback(device3, update_cb_get_rect, &ctx); + todo_wine ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); + hr = IDirect3DRMDevice3_Update(device3); + ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice3, hr %#lx.\n", hr); + hr = IDirect3DRMDevice3_DeleteUpdateCallback(device3, update_cb_get_rect, &ctx); + todo_wine ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); + todo_wine ok(ctx.rect_count == 0, "Got unexpected rect count %d, expected 0.\n", ctx.rect_count); + ok(ctx.rect.x1 == ~0 && ctx.rect.y1 == ~0 && ctx.rect.x2 == ~0 && ctx.rect.y2 == ~0, + "Got unexpected rect %s.\n", wine_dbgstr_rect((RECT *)&ctx.rect)); + + /* Area cannot extend beyond viewport */ + hr = IDirect3DRMViewport2_ForceUpdate(viewport, vrect.left - 1, vrect.top, vrect.right - 1, vrect.bottom); + todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + hr = IDirect3DRMViewport2_ForceUpdate(viewport, vrect.left, vrect.top - 1, vrect.right, vrect.bottom - 1); + todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + hr = IDirect3DRMViewport2_ForceUpdate(viewport, vrect.left + 1, vrect.top, vrect.right + 1, vrect.bottom); + todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + hr = IDirect3DRMViewport2_ForceUpdate(viewport, vrect.left, vrect.top + 1, vrect.right, vrect.bottom + 1); + todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + /* Point 1 cannot be left of or above Point 2 */ + hr = IDirect3DRMViewport2_ForceUpdate(viewport, vrect.left + 1, vrect.top, vrect.left, vrect.top + 1); + todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + hr = IDirect3DRMViewport2_ForceUpdate(viewport, vrect.left, vrect.top + 1, vrect.left + 1, vrect.top); + todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + hr = IDirect3DRMViewport2_ForceUpdate(viewport, vrect.left + 1, vrect.top + 1, vrect.left, vrect.top); + todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + /* Anything else is allowed, including a single point */ + hr = IDirect3DRMViewport2_ForceUpdate(viewport, vrect.left, vrect.top, vrect.left, vrect.top); + todo_wine ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); + hr = IDirect3DRMViewport2_ForceUpdate(viewport, vrect.left, vrect.top, vrect.left + 1, vrect.top + 1); + todo_wine ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); + hr = IDirect3DRMViewport2_ForceUpdate(viewport, vrect.left, vrect.top, vrect.right, vrect.bottom); + todo_wine ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); + /* Update just to flush force updates */ + hr = IDirect3DRMDevice3_Update(device3); + ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice3, hr %#lx.\n", hr); + + /* Callbacks will receive (at least) one rectangle following a force update */ + ctx.rect.x1 = ctx.rect.y1 = ctx.rect.x2 = ctx.rect.y2 = ~0; + ctx.rect_count = -1; + hr = IDirect3DRMViewport2_ForceUpdate(viewport, vrect.left, vrect.top, vrect.right, vrect.bottom); + todo_wine ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); + hr = IDirect3DRMDevice3_AddUpdateCallback(device3, update_cb_modify_rect, NULL); + todo_wine ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); + hr = IDirect3DRMDevice3_AddUpdateCallback(device3, update_cb_get_rect, &ctx); + todo_wine ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); + hr = IDirect3DRMDevice3_Update(device3); + ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice3, hr %#lx.\n", hr); + hr = IDirect3DRMDevice3_DeleteUpdateCallback(device3, update_cb_modify_rect, NULL); + todo_wine ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); + hr = IDirect3DRMDevice3_DeleteUpdateCallback(device3, update_cb_get_rect, &ctx); + todo_wine ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); + todo_wine ok(ctx.rect_count == 1, "Got unexpected rect count %d, expected 1.\n", ctx.rect_count); + todo_wine + ok(ctx.rect.x1 == 999999 && ctx.rect.y1 <= vrect.top && + ctx.rect.x2 >= vrect.right && ctx.rect.y2 >= vrect.bottom, + "Got unexpected rect %s.\n", wine_dbgstr_rect((RECT *)&ctx.rect)); + + /* Callbacks will receive (at least) one rectangle following a viewport clear */ + ctx.rect.x1 = ctx.rect.y1 = ctx.rect.x2 = ctx.rect.y2 = ~0; + ctx.rect_count = -1; + hr = IDirect3DRMViewport2_Clear(viewport, D3DRMCLEAR_ALL); + ok(hr == D3DRM_OK, "Cannot clear viewport, hr %#lx.\n", hr); + hr = IDirect3DRMDevice3_AddUpdateCallback(device3, update_cb_get_rect, &ctx); + todo_wine ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); + hr = IDirect3DRMDevice3_Update(device3); + ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice3, hr %#lx.\n", hr); + hr = IDirect3DRMDevice3_DeleteUpdateCallback(device3, update_cb_get_rect, &ctx); + todo_wine ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); + todo_wine ok(ctx.rect_count == 1, "Got unexpected rect count %d, expected 1.\n", ctx.rect_count); + todo_wine + ok(ctx.rect.x1 <= vrect.left && ctx.rect.y1 <= vrect.top && + ctx.rect.x2 >= vrect.right && ctx.rect.y2 >= vrect.bottom, + "Got unexpected rect %s.\n", wine_dbgstr_rect((RECT *)&ctx.rect)); + + IDirect3DRMViewport2_Release(viewport); + IDirect3DRMFrame3_Release(camera); + IDirect3DRMFrame3_Release(scene); + + IDirect3DRMDevice3_Release(device3); + IDirect3DRM3_Release(d3drm3); + IDirect3DRM_Release(d3drm1); + IDirectDrawClipper_Release(clipper); + DestroyWindow(window); +} + +struct update_surface_context +{ + IDirectDrawSurface *surface; + UINT x; + UINT y; + D3DCOLOR color; +}; + +static void CDECL update_cb_surf_color(IDirect3DRMDevice *device, void *arg, int rect_count, D3DRECT *update_rects) +{ + struct update_surface_context *ctx = arg; + ctx->color = get_surface_color(ctx->surface, ctx->x, ctx->y); +} + +static void test_update_surfaces_1(void) +{ + IDirect3DRM *d3drm1 = NULL; + IDirect3DRMDevice *device1 = NULL; + IDirect3DRMFrame *scene = NULL, *camera = NULL; + IDirect3DRMViewport *viewport = NULL; + IDirect3DDevice *d3ddevice1 = NULL; + IDirectDrawClipper *clipper = NULL; + IDirectDrawSurface *surface = NULL, *d3drm_primary = NULL; + IDirectDrawSurface7 *surface7 = NULL; + IDirectDraw *ddraw = NULL; + IUnknown *unknown = NULL; + GUID driver = IID_IDirect3DRGBDevice; + DWORD dev_width = 600, dev_height = 400; + RECT vrect = { 1, 1, 480, 360 }; + POINT client_pos = { 0, 0 }; + struct update_surface_context ctx; + D3DCOLOR ret_color = 0; + DWORD clip_list_size; + RGNDATA *clip_list; + HWND window; + HRESULT hr; + + window = create_window(); + + /* Set up device */ + hr = DirectDrawCreateClipper(0, &clipper, NULL); + ok(hr == DD_OK, "Cannot get IDirectDrawClipper interface, hr %#lx.\n", hr); + hr = IDirectDrawClipper_SetHWnd(clipper, 0, window); + ok(hr == DD_OK, "Cannot set HWnd to Clipper, hr %#lx.\n", hr); + hr = Direct3DRMCreate(&d3drm1); + ok(SUCCEEDED(hr), "Cannot create IDirect3DRM instance, hr %#lx.\n", hr); + hr = IDirect3DRM_CreateDeviceFromClipper(d3drm1, clipper, &driver, dev_width, dev_height, &device1); + ok(hr == D3DRM_OK, "Cannot create IDirect3DRMDevice interface, hr %#lx.\n", hr); + + /* Obtain render target */ + hr = IDirect3DRMDevice_GetDirect3DDevice(device1, &d3ddevice1); + ok(hr == D3DRM_OK, "Cannot get IDirect3DDevice interface, hr %#lx.\n", hr); + hr = IDirect3DDevice_QueryInterface(d3ddevice1, &IID_IDirectDrawSurface, (void **)&surface); + ok(hr == DD_OK, "Cannot get surface to the render target, hr %#lx.\n", hr); + + /* Obtain primary surface */ + hr = IDirectDrawSurface_QueryInterface(surface, &IID_IDirectDrawSurface7, (void **)&surface7); + ok(hr == DD_OK, "Cannot get IDirectDrawSurface7 interface, hr %#lx.\n", hr); + IDirectDrawSurface7_GetDDInterface(surface7, (void **)&unknown); + hr = IUnknown_QueryInterface(unknown, &IID_IDirectDraw, (void **)&ddraw); + ok(hr == DD_OK, "Cannot get IDirectDraw interface, hr %#lx.\n", hr); + IUnknown_Release(unknown); + hr = IDirectDraw_EnumSurfaces(ddraw, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST, + NULL, &d3drm_primary, surface_callback); + ok(hr == DD_OK, "Cannot enumerate surfaces, hr %#lx.\n", hr); + ok(d3drm_primary != NULL, "No primary surface was enumerated.\n"); + + /* Set color of a pixel on primary surface and on render target */ + ClientToScreen(window, &client_pos); + hr = set_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y, 0x00123456); + if (FAILED(hr)) + { + win_skip("Cannot lock/unlock primary surface, hr %#lx, skipping tests\n", hr); + goto cleanup; + } + ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); + if (!compare_color(ret_color, 0x00123456, 1)) + { + win_skip("Cannot set color of pixel on primary surface, color 0x%08lx, skipping tests\n", ret_color); + goto cleanup; + } + hr = set_surface_color(surface, 320, 240, 0x000000ff); + ret_color = get_surface_color(surface, 320, 240); + ok(compare_color(ret_color, 0x000000ff, 1), "Got unexpected color 0x%08lx.\n", ret_color); + + /* Set up viewport */ + hr = IDirect3DRM_CreateFrame(d3drm1, NULL, &scene); + ok(hr == D3DRM_OK, "Cannot create root scene, hr %#lx.\n", hr); + hr = IDirect3DRM_CreateFrame(d3drm1, scene, &camera); + ok(hr == D3DRM_OK, "Cannot create camera, hr %#lx.\n", hr); + hr = IDirect3DRM_CreateViewport(d3drm1, device1, camera, + vrect.left, vrect.top, vrect.right - vrect.left, vrect.bottom - vrect.top, &viewport); + ok(hr == D3DRM_OK, "Cannot create viewport, hr %#lx\n", hr); + + /* Update leaves primary surface unmodified if the viewport hasn't been notified */ + hr = IDirect3DRMDevice_Update(device1); + ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice, hr %#lx.\n", hr); + ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); + ok(compare_color(ret_color, 0x00123456, 1), "Got unexpected color 0x%08lx.\n", ret_color); + + /* Update modifies primary surface following a force update */ + hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left, vrect.top, vrect.right, vrect.bottom); + todo_wine ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); + hr = IDirect3DRMDevice_Update(device1); + ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice, hr %#lx.\n", hr); + ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); + todo_wine ok(compare_color(ret_color, 0x000000ff, 1), "Got unexpected color 0x%08lx.\n", ret_color); + + /* Update modifies primary surface following a viewport clear */ + clip_list_size = 0; + hr = IDirectDrawClipper_GetClipList(clipper, NULL, NULL, &clip_list_size); + ok(hr == DD_OK, "Cannot get clip list size, hr %#lx.\n", hr); + clip_list = malloc(clip_list_size); + hr = IDirectDrawClipper_GetClipList(clipper, NULL, clip_list, &clip_list_size); + ok(hr == DD_OK, "Cannot get clip list, hr %#lx.\n", hr); + ctx.surface = d3drm_primary; + ctx.x = 320 + client_pos.x; + ctx.y = 240 + client_pos.y; + ctx.color = 0xdeadbeef; + hr = IDirect3DRMFrame_SetSceneBackgroundRGB(scene, 1.0f, 0.5f, 0.0f); + ok(hr == D3DRM_OK, "Cannot set background color, hr %#lx\n", hr); + hr = IDirect3DRMViewport_Clear(viewport); + ok(hr == D3DRM_OK, "Cannot clear viewport, hr %#lx.\n", hr); + ret_color = get_surface_color(surface, 320, 240); + ok(compare_color(ret_color, 0x00ff7f00, 1), "Got unexpected color 0x%08lx.\n", ret_color); + ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); + todo_wine ok(compare_color(ret_color, 0x000000ff, 1), "Got unexpected color 0x%08lx.\n", ret_color); + hr = IDirect3DRMDevice_AddUpdateCallback(device1, update_cb_surf_color, &ctx); + todo_wine ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); + hr = IDirect3DRMDevice_Update(device1); + ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice, hr %#lx.\n", hr); + hr = IDirect3DRMDevice_DeleteUpdateCallback(device1, update_cb_surf_color, &ctx); + todo_wine ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); + ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); + todo_wine ok(compare_color(ret_color, 0x00ff7f00, 1), "Got unexpected color 0x%08lx.\n", ret_color); + todo_wine ok(compare_color(ctx.color, 0x00ff7f00, 1), "Got unexpected color 0x%08lx.\n", ctx.color); + + /* Draw at the window handle location, regardless of clipper alterations */ + clip_list->rdh.rcBound.left += 10; + clip_list->rdh.rcBound.top += 20; + ((RECT *)&clip_list->Buffer[0])->left += 10; + ((RECT *)&clip_list->Buffer[0])->top += 20; + hr = IDirectDrawClipper_SetHWnd(clipper, 0, NULL); + ok(hr == DD_OK, "Cannot set NULL HWnd to Clipper, hr %#lx\n", hr); + hr = IDirectDrawClipper_SetClipList(clipper, clip_list, 0); + ok(hr == DD_OK, "Cannot set clip list, hr %#lx.\n", hr); + free(clip_list); + set_surface_color(surface, 320, 240, 0x0000ff00); + hr = IDirect3DRMViewport_ForceUpdate(viewport, 320, 240, 321, 241); + todo_wine ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); + hr = IDirect3DRMDevice_Update(device1); + ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice, hr %#lx.\n", hr); + ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); + todo_wine ok(compare_color(ret_color, 0x0000ff00, 1), "Got unexpected color 0x%08lx.\n", ret_color); + + IDirect3DRMViewport_Release(viewport); + IDirect3DRMFrame_Release(camera); + IDirect3DRMFrame_Release(scene); + +cleanup: + IDirectDrawSurface_Release(d3drm_primary); + IDirectDraw_Release(ddraw); + IDirectDrawSurface7_Release(surface7); + IDirectDrawSurface_Release(surface); + IDirect3DDevice_Release(d3ddevice1); + + IDirect3DRMDevice_Release(device1); + IDirect3DRM_Release(d3drm1); + IDirectDrawClipper_Release(clipper); + DestroyWindow(window); +} + +static void test_update_surfaces_2(void) +{ + IDirect3DRM *d3drm1 = NULL; + IDirect3DRM2 *d3drm2 = NULL; + IDirect3DRMDevice *device1 = NULL; + IDirect3DRMDevice2 *device2 = NULL; + IDirect3DRMFrame *scene1 = NULL, *camera1 = NULL; + IDirect3DRMFrame2 *scene = NULL, *camera = NULL; + IDirect3DRMViewport *viewport = NULL; + IDirect3DDevice2 *d3ddevice2 = NULL; + IDirectDrawClipper *clipper = NULL; + IDirectDrawSurface *surface = NULL, *d3drm_primary = NULL; + IDirectDrawSurface7 *surface7 = NULL; + IDirectDraw *ddraw = NULL; + IUnknown *unknown = NULL; + GUID driver = IID_IDirect3DRGBDevice; + DWORD dev_width = 600, dev_height = 400; + RECT vrect = { 1, 1, 480, 360 }; + POINT client_pos = { 0, 0 }; + struct update_surface_context ctx; + D3DCOLOR ret_color = 0; + DWORD clip_list_size; + RGNDATA *clip_list; + HWND window; + HRESULT hr; + + window = create_window(); + + /* Set up device */ + hr = DirectDrawCreateClipper(0, &clipper, NULL); + ok(hr == DD_OK, "Cannot get IDirectDrawClipper interface, hr %#lx.\n", hr); + hr = IDirectDrawClipper_SetHWnd(clipper, 0, window); + ok(hr == DD_OK, "Cannot set HWnd to Clipper, hr %#lx.\n", hr); + hr = Direct3DRMCreate(&d3drm1); + ok(SUCCEEDED(hr), "Cannot create IDirect3DRM instance, hr %#lx.\n", hr); + hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM2, (void **)&d3drm2); + ok(hr == D3DRM_OK, "Cannot get IDirect3DRM3 interface, hr %#lx.\n", hr); + hr = IDirect3DRM2_CreateDeviceFromClipper(d3drm2, clipper, &driver, dev_width, dev_height, &device2); + ok(hr == D3DRM_OK, "Cannot create IDirect3DRMDevice interface, hr %#lx.\n", hr); + hr = IDirect3DRMDevice2_QueryInterface(device2, &IID_IDirect3DRMDevice, (void **)&device1); + ok(hr == D3DRM_OK, "Cannot get IDirect3DRMDevice interface, hr %#lx.\n", hr); + + /* Obtain render target */ + hr = IDirect3DRMDevice2_GetDirect3DDevice2(device2, &d3ddevice2); + ok(hr == D3DRM_OK, "Cannot get IDirect3DDevice interface, hr %#lx.\n", hr); + hr = IDirect3DDevice2_GetRenderTarget(d3ddevice2, &surface); + ok(hr == DD_OK, "Cannot get surface to the render target, hr %#lx.\n", hr); + + /* Obtain primary surface */ + hr = IDirectDrawSurface_QueryInterface(surface, &IID_IDirectDrawSurface7, (void **)&surface7); + ok(hr == DD_OK, "Cannot get IDirectDrawSurface7 interface, hr %#lx.\n", hr); + IDirectDrawSurface7_GetDDInterface(surface7, (void **)&unknown); + hr = IUnknown_QueryInterface(unknown, &IID_IDirectDraw, (void **)&ddraw); + ok(hr == DD_OK, "Cannot get IDirectDraw interface, hr %#lx.\n", hr); + IUnknown_Release(unknown); + hr = IDirectDraw_EnumSurfaces(ddraw, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST, + NULL, &d3drm_primary, surface_callback); + ok(hr == DD_OK, "Cannot enumerate surfaces, hr %#lx.\n", hr); + ok(d3drm_primary != NULL, "No primary surface was enumerated.\n"); + + /* Set color of a pixel on primary surface and on render target */ + ClientToScreen(window, &client_pos); + hr = set_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y, 0x00123456); + if (FAILED(hr)) + { + win_skip("Cannot lock/unlock primary surface, hr %#lx, skipping tests\n", hr); + goto cleanup; + } + ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); + if (!compare_color(ret_color, 0x00123456, 1)) + { + win_skip("Cannot set color of pixel on primary surface, color 0x%08lx, skipping tests\n", ret_color); + goto cleanup; + } + hr = set_surface_color(surface, 320, 240, 0x000000ff); + ret_color = get_surface_color(surface, 320, 240); + ok(compare_color(ret_color, 0x000000ff, 1), "Got unexpected color 0x%08lx.\n", ret_color); + + /* Set up viewport */ + hr = IDirect3DRM2_CreateFrame(d3drm2, NULL, &scene); + ok(hr == D3DRM_OK, "Cannot create root scene, hr %#lx.\n", hr); + hr = IDirect3DRMFrame2_QueryInterface(scene, &IID_IDirect3DRMFrame, (void **)&scene1); + ok(hr == D3DRM_OK, "Cannot get IDirect3DRMFrame interface, hr %#lx.\n", hr); + hr = IDirect3DRM2_CreateFrame(d3drm2, scene1, &camera); + ok(hr == D3DRM_OK, "Cannot create camera, hr %#lx.\n", hr); + hr = IDirect3DRMFrame2_QueryInterface(camera, &IID_IDirect3DRMFrame, (void **)&camera1); + ok(hr == D3DRM_OK, "Cannot get IDirect3DRMFrame interface, hr %#lx.\n", hr); + hr = IDirect3DRM_CreateViewport(d3drm2, device1, camera1, + vrect.left, vrect.top, vrect.right - vrect.left, vrect.bottom - vrect.top, &viewport); + ok(hr == D3DRM_OK, "Cannot create viewport, hr %#lx\n", hr); + + /* Update leaves primary surface unmodified if the viewport hasn't been notified */ + hr = IDirect3DRMDevice_Update(device2); + ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice2, hr %#lx.\n", hr); + ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); + ok(compare_color(ret_color, 0x00123456, 1), "Got unexpected color 0x%08lx.\n", ret_color); + + /* Update modifies primary surface following a force update */ + hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left, vrect.top, vrect.right, vrect.bottom); + todo_wine ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); + hr = IDirect3DRMDevice_Update(device2); + ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice2, hr %#lx.\n", hr); + ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); + todo_wine ok(compare_color(ret_color, 0x000000ff, 1), "Got unexpected color 0x%08lx.\n", ret_color); + + /* Update modifies primary surface following a viewport clear */ + ctx.surface = d3drm_primary; + ctx.x = 320 + client_pos.x; + ctx.y = 240 + client_pos.y; + ctx.color = 0xdeadbeef; + hr = IDirect3DRMFrame_SetSceneBackgroundRGB(scene, 1.0f, 0.5f, 0.0f); + ok(hr == D3DRM_OK, "Cannot set background color, hr %#lx\n", hr); + hr = IDirect3DRMViewport_Clear(viewport); + ok(hr == D3DRM_OK, "Cannot clear viewport, hr %#lx.\n", hr); + ret_color = get_surface_color(surface, 320, 240); + ok(compare_color(ret_color, 0x00ff7f00, 1), "Got unexpected color 0x%08lx.\n", ret_color); + ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); + todo_wine ok(compare_color(ret_color, 0x000000ff, 1), "Got unexpected color 0x%08lx.\n", ret_color); + hr = IDirect3DRMDevice2_AddUpdateCallback(device2, update_cb_surf_color, &ctx); + todo_wine ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); + hr = IDirect3DRMDevice2_Update(device2); + ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice2, hr %#lx.\n", hr); + hr = IDirect3DRMDevice2_DeleteUpdateCallback(device2, update_cb_surf_color, &ctx); + todo_wine ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); + ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); + todo_wine ok(compare_color(ret_color, 0x00ff7f00, 1), "Got unexpected color 0x%08lx.\n", ret_color); + todo_wine ok(compare_color(ctx.color, 0x00ff7f00, 1), "Got unexpected color 0x%08lx.\n", ctx.color); + + /* Draw at the window handle location, regardless of clipper alterations */ + clip_list_size = 0; + hr = IDirectDrawClipper_GetClipList(clipper, NULL, NULL, &clip_list_size); + ok(hr == DD_OK, "Cannot get clip list size, hr %#lx.\n", hr); + clip_list = malloc(clip_list_size); + hr = IDirectDrawClipper_GetClipList(clipper, NULL, clip_list, &clip_list_size); + ok(hr == DD_OK, "Cannot get clip list, hr %#lx.\n", hr); + clip_list->rdh.rcBound.left += 10; + clip_list->rdh.rcBound.top += 20; + ((RECT *)&clip_list->Buffer[0])->left += 10; + ((RECT *)&clip_list->Buffer[0])->top += 20; + hr = IDirectDrawClipper_SetHWnd(clipper, 0, NULL); + ok(hr == DD_OK, "Cannot set NULL HWnd to Clipper, hr %#lx\n", hr); + hr = IDirectDrawClipper_SetClipList(clipper, clip_list, 0); + ok(hr == DD_OK, "Cannot set clip list, hr %#lx.\n", hr); + free(clip_list); + set_surface_color(surface, 320, 240, 0x0000ff00); + hr = IDirect3DRMViewport_ForceUpdate(viewport, 320, 240, 321, 241); + todo_wine ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); + hr = IDirect3DRMDevice2_Update(device2); + ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice2, hr %#lx.\n", hr); + ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); + todo_wine ok(compare_color(ret_color, 0x0000ff00, 1), "Got unexpected color 0x%08lx.\n", ret_color); + + IDirect3DRMViewport_Release(viewport); + IDirect3DRMFrame_Release(camera1); + IDirect3DRMFrame2_Release(camera); + IDirect3DRMFrame_Release(scene1); + IDirect3DRMFrame2_Release(scene); + +cleanup: + IDirectDrawSurface_Release(d3drm_primary); + IDirectDraw_Release(ddraw); + IDirectDrawSurface7_Release(surface7); + IDirectDrawSurface_Release(surface); + IDirect3DDevice2_Release(d3ddevice2); + + IDirect3DRMDevice_Release(device2); + IDirect3DRMDevice_Release(device1); + IDirect3DRM_Release(d3drm2); + IDirect3DRM_Release(d3drm1); + IDirectDrawClipper_Release(clipper); + DestroyWindow(window); +} + +static void test_update_surfaces_3(void) +{ + IDirect3DRM *d3drm1 = NULL; + IDirect3DRM3 *d3drm3 = NULL; + IDirect3DRMDevice3 *device3 = NULL; + IDirect3DRMFrame3 *scene = NULL, *camera = NULL; + IDirect3DRMViewport2 *viewport = NULL; + IDirect3DDevice2 *d3ddevice2 = NULL; + IDirectDrawClipper *clipper = NULL; + IDirectDrawSurface *surface = NULL, *d3drm_primary = NULL; + IDirectDrawSurface7 *surface7 = NULL; + IDirectDraw *ddraw = NULL; + IUnknown *unknown = NULL; + GUID driver = IID_IDirect3DRGBDevice; + DWORD dev_width = 600, dev_height = 400; + RECT vrect = { 1, 1, 480, 360 }; + POINT client_pos = { 0, 0 }; + struct update_surface_context ctx; + D3DCOLOR ret_color = 0; + DWORD clip_list_size; + RGNDATA *clip_list; + HWND window; + HRESULT hr; + + window = create_window(); + + /* Set up device */ + hr = DirectDrawCreateClipper(0, &clipper, NULL); + ok(hr == DD_OK, "Cannot get IDirectDrawClipper interface, hr %#lx.\n", hr); + hr = IDirectDrawClipper_SetHWnd(clipper, 0, window); + ok(hr == DD_OK, "Cannot set HWnd to Clipper, hr %#lx.\n", hr); + hr = Direct3DRMCreate(&d3drm1); + ok(SUCCEEDED(hr), "Cannot create IDirect3DRM instance, hr %#lx.\n", hr); + hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3); + ok(hr == D3DRM_OK, "Cannot get IDirect3DRM3 interface, hr %#lx.\n", hr); + hr = IDirect3DRM3_CreateDeviceFromClipper(d3drm3, clipper, &driver, dev_width, dev_height, &device3); + ok(hr == D3DRM_OK, "Cannot create IDirect3DRMDevice interface, hr %#lx.\n", hr); + + /* Obtain render target */ + hr = IDirect3DRMDevice3_GetDirect3DDevice2(device3, &d3ddevice2); + ok(hr == D3DRM_OK, "Cannot get IDirect3DDevice interface, hr %#lx.\n", hr); + hr = IDirect3DDevice2_GetRenderTarget(d3ddevice2, &surface); + ok(hr == DD_OK, "Cannot get surface to the render target, hr %#lx.\n", hr); + + /* Obtain primary surface */ + hr = IDirectDrawSurface_QueryInterface(surface, &IID_IDirectDrawSurface7, (void **)&surface7); + ok(hr == DD_OK, "Cannot get IDirectDrawSurface7 interface, hr %#lx.\n", hr); + IDirectDrawSurface7_GetDDInterface(surface7, (void **)&unknown); + hr = IUnknown_QueryInterface(unknown, &IID_IDirectDraw, (void **)&ddraw); + ok(hr == DD_OK, "Cannot get IDirectDraw interface, hr %#lx.\n", hr); + IUnknown_Release(unknown); + hr = IDirectDraw_EnumSurfaces(ddraw, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST, + NULL, &d3drm_primary, surface_callback); + ok(hr == DD_OK, "Cannot enumerate surfaces, hr %#lx.\n", hr); + ok(d3drm_primary != NULL, "No primary surface was enumerated.\n"); + + /* Set color of a pixel on primary surface and on render target */ + ClientToScreen(window, &client_pos); + hr = set_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y, 0x00123456); + if (FAILED(hr)) + { + win_skip("Cannot lock/unlock primary surface, hr %#lx, skipping tests\n", hr); + goto cleanup; + } + ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); + if (!compare_color(ret_color, 0x00123456, 1)) + { + win_skip("Cannot set color of pixel on primary surface, color 0x%08lx, skipping tests\n", ret_color); + goto cleanup; + } + hr = set_surface_color(surface, 320, 240, 0x000000ff); + ret_color = get_surface_color(surface, 320, 240); + ok(compare_color(ret_color, 0x000000ff, 1), "Got unexpected color 0x%08lx.\n", ret_color); + + /* Set up viewport */ + hr = IDirect3DRM3_CreateFrame(d3drm3, NULL, &scene); + ok(hr == D3DRM_OK, "Cannot create root scene, hr %#lx.\n", hr); + hr = IDirect3DRM3_CreateFrame(d3drm3, scene, &camera); + ok(hr == D3DRM_OK, "Cannot create camera, hr %#lx.\n", hr); + hr = IDirect3DRM3_CreateViewport(d3drm3, device3, camera, + vrect.left, vrect.top, vrect.right - vrect.left, vrect.bottom - vrect.top, &viewport); + ok(hr == D3DRM_OK, "Cannot create viewport, hr %#lx\n", hr); + + /* Update leaves primary surface unmodified if the viewport hasn't been notified */ + hr = IDirect3DRMDevice3_Update(device3); + ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice3, hr %#lx.\n", hr); + ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); + ok(compare_color(ret_color, 0x00123456, 1), "Got unexpected color 0x%08lx.\n", ret_color); + + /* Update modifies primary surface following a force update */ + hr = IDirect3DRMViewport2_ForceUpdate(viewport, vrect.left, vrect.top, vrect.right, vrect.bottom); + todo_wine ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); + hr = IDirect3DRMDevice3_Update(device3); + ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice3, hr %#lx.\n", hr); + ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); + todo_wine ok(compare_color(ret_color, 0x000000ff, 1), "Got unexpected color 0x%08lx.\n", ret_color); + + /* Update modifies primary surface following a viewport clear */ + ctx.surface = d3drm_primary; + ctx.x = 320 + client_pos.x; + ctx.y = 240 + client_pos.y; + ctx.color = 0xdeadbeef; + hr = IDirect3DRMFrame3_SetSceneBackgroundRGB(scene, 1.0f, 0.5f, 0.0f); + ok(hr == D3DRM_OK, "Cannot set background color, hr %#lx\n", hr); + hr = IDirect3DRMViewport2_Clear(viewport, D3DRMCLEAR_ALL); + ok(hr == D3DRM_OK, "Cannot clear viewport, hr %#lx.\n", hr); + ret_color = get_surface_color(surface, 320, 240); + ok(compare_color(ret_color, 0x00ff7f00, 1), "Got unexpected color 0x%08lx.\n", ret_color); + ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); + todo_wine ok(compare_color(ret_color, 0x000000ff, 1), "Got unexpected color 0x%08lx.\n", ret_color); + hr = IDirect3DRMDevice3_AddUpdateCallback(device3, update_cb_surf_color, &ctx); + todo_wine ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); + hr = IDirect3DRMDevice3_Update(device3); + ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice3, hr %#lx.\n", hr); + hr = IDirect3DRMDevice3_DeleteUpdateCallback(device3, update_cb_surf_color, &ctx); + todo_wine ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); + ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); + todo_wine ok(compare_color(ret_color, 0x00ff7f00, 1), "Got unexpected color 0x%08lx.\n", ret_color); + todo_wine ok(compare_color(ctx.color, 0x00ff7f00, 1), "Got unexpected color 0x%08lx.\n", ctx.color); + + /* Draw at the window handle location, regardless of clipper alterations */ + clip_list_size = 0; + hr = IDirectDrawClipper_GetClipList(clipper, NULL, NULL, &clip_list_size); + ok(hr == DD_OK, "Cannot get clip list size, hr %#lx.\n", hr); + clip_list = malloc(clip_list_size); + hr = IDirectDrawClipper_GetClipList(clipper, NULL, clip_list, &clip_list_size); + ok(hr == DD_OK, "Cannot get clip list, hr %#lx.\n", hr); + clip_list->rdh.rcBound.left += 10; + clip_list->rdh.rcBound.top += 20; + ((RECT *)&clip_list->Buffer[0])->left += 10; + ((RECT *)&clip_list->Buffer[0])->top += 20; + hr = IDirectDrawClipper_SetHWnd(clipper, 0, NULL); + ok(hr == DD_OK, "Cannot set NULL HWnd to Clipper, hr %#lx\n", hr); + hr = IDirectDrawClipper_SetClipList(clipper, clip_list, 0); + ok(hr == DD_OK, "Cannot set clip list, hr %#lx.\n", hr); + free(clip_list); + set_surface_color(surface, 320, 240, 0x0000ff00); + hr = IDirect3DRMViewport2_ForceUpdate(viewport, 320, 240, 321, 241); + todo_wine ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); + hr = IDirect3DRMDevice3_Update(device3); + ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice3, hr %#lx.\n", hr); + ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); + todo_wine ok(compare_color(ret_color, 0x0000ff00, 1), "Got unexpected color 0x%08lx.\n", ret_color); + + IDirect3DRMViewport2_Release(viewport); + IDirect3DRMFrame3_Release(camera); + IDirect3DRMFrame3_Release(scene); + +cleanup: + IDirectDrawSurface_Release(d3drm_primary); + IDirectDraw_Release(ddraw); + IDirectDrawSurface7_Release(surface7); + IDirectDrawSurface_Release(surface); + IDirect3DDevice2_Release(d3ddevice2); + + IDirect3DRMDevice3_Release(device3); + IDirect3DRM3_Release(d3drm3); + IDirect3DRM_Release(d3drm1); + IDirectDrawClipper_Release(clipper); + DestroyWindow(window); +} + START_TEST(d3drm) { test_MeshBuilder(); @@ -8271,4 +9205,10 @@ START_TEST(d3drm) test_animation_qi(); test_wrap(); test_wrap_qi(); + test_update_1(); + test_update_2(); + test_update_3(); + test_update_surfaces_1(); + test_update_surfaces_2(); + test_update_surfaces_3(); }
From: Jeff Smith whydoubt@gmail.com
--- dlls/d3drm/tests/d3drm.c | 78 ++++++++++++++++++++-------------------- dlls/d3drm/viewport.c | 24 ++++++++++--- 2 files changed, 59 insertions(+), 43 deletions(-)
diff --git a/dlls/d3drm/tests/d3drm.c b/dlls/d3drm/tests/d3drm.c index b9367f67d34..7b60efa1965 100644 --- a/dlls/d3drm/tests/d3drm.c +++ b/dlls/d3drm/tests/d3drm.c @@ -8319,27 +8319,27 @@ static void test_update_1(void)
/* Area cannot extend beyond viewport */ hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left - 1, vrect.top, vrect.right - 1, vrect.bottom); - todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left, vrect.top - 1, vrect.right, vrect.bottom - 1); - todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left + 1, vrect.top, vrect.right + 1, vrect.bottom); - todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left, vrect.top + 1, vrect.right, vrect.bottom + 1); - todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); /* Point 1 cannot be left of or above Point 2 */ hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left + 1, vrect.top, vrect.left, vrect.top + 1); - todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left, vrect.top + 1, vrect.left + 1, vrect.top); - todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left + 1, vrect.top + 1, vrect.left, vrect.top); - todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); /* Anything else is allowed, including a single point */ hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left, vrect.top, vrect.left, vrect.top); - todo_wine ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left, vrect.top, vrect.left + 1, vrect.top + 1); - todo_wine ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left, vrect.top, vrect.right, vrect.bottom); - todo_wine ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); /* Update just to flush force updates */ hr = IDirect3DRMDevice_Update(device1); ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice, hr %#lx.\n", hr); @@ -8348,7 +8348,7 @@ static void test_update_1(void) ctx.rect.x1 = ctx.rect.y1 = ctx.rect.x2 = ctx.rect.y2 = ~0; ctx.rect_count = -1; hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left, vrect.top, vrect.right, vrect.bottom); - todo_wine ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); hr = IDirect3DRMDevice_AddUpdateCallback(device1, update_cb_modify_rect, NULL); todo_wine ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); hr = IDirect3DRMDevice_AddUpdateCallback(device1, update_cb_get_rect, &ctx); @@ -8453,27 +8453,27 @@ static void test_update_2(void)
/* Area cannot extend beyond viewport */ hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left - 1, vrect.top, vrect.right - 1, vrect.bottom); - todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left, vrect.top - 1, vrect.right, vrect.bottom - 1); - todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left + 1, vrect.top, vrect.right + 1, vrect.bottom); - todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left, vrect.top + 1, vrect.right, vrect.bottom + 1); - todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); /* Point 1 cannot be left of or above Point 2 */ hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left + 1, vrect.top, vrect.left, vrect.top + 1); - todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left, vrect.top + 1, vrect.left + 1, vrect.top); - todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left + 1, vrect.top + 1, vrect.left, vrect.top); - todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); /* Anything else is allowed, including a single point */ hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left, vrect.top, vrect.left, vrect.top); - todo_wine ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left, vrect.top, vrect.left + 1, vrect.top + 1); - todo_wine ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left, vrect.top, vrect.right, vrect.bottom); - todo_wine ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); /* Update just to flush force updates */ hr = IDirect3DRMDevice2_Update(device2); ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice2, hr %#lx.\n", hr); @@ -8482,7 +8482,7 @@ static void test_update_2(void) ctx.rect.x1 = ctx.rect.y1 = ctx.rect.x2 = ctx.rect.y2 = ~0; ctx.rect_count = -1; hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left, vrect.top, vrect.right, vrect.bottom); - todo_wine ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); hr = IDirect3DRMDevice2_AddUpdateCallback(device2, update_cb_modify_rect, NULL); todo_wine ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); hr = IDirect3DRMDevice2_AddUpdateCallback(device2, update_cb_get_rect, &ctx); @@ -8583,27 +8583,27 @@ static void test_update_3(void)
/* Area cannot extend beyond viewport */ hr = IDirect3DRMViewport2_ForceUpdate(viewport, vrect.left - 1, vrect.top, vrect.right - 1, vrect.bottom); - todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); hr = IDirect3DRMViewport2_ForceUpdate(viewport, vrect.left, vrect.top - 1, vrect.right, vrect.bottom - 1); - todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); hr = IDirect3DRMViewport2_ForceUpdate(viewport, vrect.left + 1, vrect.top, vrect.right + 1, vrect.bottom); - todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); hr = IDirect3DRMViewport2_ForceUpdate(viewport, vrect.left, vrect.top + 1, vrect.right, vrect.bottom + 1); - todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); /* Point 1 cannot be left of or above Point 2 */ hr = IDirect3DRMViewport2_ForceUpdate(viewport, vrect.left + 1, vrect.top, vrect.left, vrect.top + 1); - todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); hr = IDirect3DRMViewport2_ForceUpdate(viewport, vrect.left, vrect.top + 1, vrect.left + 1, vrect.top); - todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); hr = IDirect3DRMViewport2_ForceUpdate(viewport, vrect.left + 1, vrect.top + 1, vrect.left, vrect.top); - todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); + ok(hr == D3DRMERR_BADVALUE, "Expected bad value from force update, hr %#lx.\n", hr); /* Anything else is allowed, including a single point */ hr = IDirect3DRMViewport2_ForceUpdate(viewport, vrect.left, vrect.top, vrect.left, vrect.top); - todo_wine ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); hr = IDirect3DRMViewport2_ForceUpdate(viewport, vrect.left, vrect.top, vrect.left + 1, vrect.top + 1); - todo_wine ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); hr = IDirect3DRMViewport2_ForceUpdate(viewport, vrect.left, vrect.top, vrect.right, vrect.bottom); - todo_wine ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); /* Update just to flush force updates */ hr = IDirect3DRMDevice3_Update(device3); ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice3, hr %#lx.\n", hr); @@ -8612,7 +8612,7 @@ static void test_update_3(void) ctx.rect.x1 = ctx.rect.y1 = ctx.rect.x2 = ctx.rect.y2 = ~0; ctx.rect_count = -1; hr = IDirect3DRMViewport2_ForceUpdate(viewport, vrect.left, vrect.top, vrect.right, vrect.bottom); - todo_wine ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); hr = IDirect3DRMDevice3_AddUpdateCallback(device3, update_cb_modify_rect, NULL); todo_wine ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); hr = IDirect3DRMDevice3_AddUpdateCallback(device3, update_cb_get_rect, &ctx); @@ -8759,7 +8759,7 @@ static void test_update_surfaces_1(void)
/* Update modifies primary surface following a force update */ hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left, vrect.top, vrect.right, vrect.bottom); - todo_wine ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); hr = IDirect3DRMDevice_Update(device1); ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice, hr %#lx.\n", hr); ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); @@ -8806,7 +8806,7 @@ static void test_update_surfaces_1(void) free(clip_list); set_surface_color(surface, 320, 240, 0x0000ff00); hr = IDirect3DRMViewport_ForceUpdate(viewport, 320, 240, 321, 241); - todo_wine ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); hr = IDirect3DRMDevice_Update(device1); ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice, hr %#lx.\n", hr); ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); @@ -8928,7 +8928,7 @@ static void test_update_surfaces_2(void)
/* Update modifies primary surface following a force update */ hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left, vrect.top, vrect.right, vrect.bottom); - todo_wine ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); hr = IDirect3DRMDevice_Update(device2); ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice2, hr %#lx.\n", hr); ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); @@ -8975,7 +8975,7 @@ static void test_update_surfaces_2(void) free(clip_list); set_surface_color(surface, 320, 240, 0x0000ff00); hr = IDirect3DRMViewport_ForceUpdate(viewport, 320, 240, 321, 241); - todo_wine ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); hr = IDirect3DRMDevice2_Update(device2); ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice2, hr %#lx.\n", hr); ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); @@ -9093,7 +9093,7 @@ static void test_update_surfaces_3(void)
/* Update modifies primary surface following a force update */ hr = IDirect3DRMViewport2_ForceUpdate(viewport, vrect.left, vrect.top, vrect.right, vrect.bottom); - todo_wine ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); hr = IDirect3DRMDevice3_Update(device3); ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice3, hr %#lx.\n", hr); ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); @@ -9140,7 +9140,7 @@ static void test_update_surfaces_3(void) free(clip_list); set_surface_color(surface, 320, 240, 0x0000ff00); hr = IDirect3DRMViewport2_ForceUpdate(viewport, 320, 240, 321, 241); - todo_wine ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); hr = IDirect3DRMDevice3_Update(device3); ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice3, hr %#lx.\n", hr); ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); diff --git a/dlls/d3drm/viewport.c b/dlls/d3drm/viewport.c index 821eb1ff12c..528cae24001 100644 --- a/dlls/d3drm/viewport.c +++ b/dlls/d3drm/viewport.c @@ -677,17 +677,33 @@ static HRESULT WINAPI d3drm_viewport1_Configure(IDirect3DRMViewport *iface, static HRESULT WINAPI d3drm_viewport2_ForceUpdate(IDirect3DRMViewport2* iface, DWORD x1, DWORD y1, DWORD x2, DWORD y2) { - FIXME("iface %p, x1 %lu, y1 %lu, x2 %lu, y2 %lu stub!\n", iface, x1, y1, x2, y2); + struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport2(iface); + D3DVIEWPORT vp = { sizeof(vp) }; + HRESULT hr;
- return E_NOTIMPL; + TRACE("iface %p, x1 %lu, y1 %lu, x2 %lu, y2 %lu.\n", iface, x1, y1, x2, y2); + + if (!viewport->d3d_viewport) + return D3DRMERR_BADOBJECT; + + if (FAILED(hr = IDirect3DViewport_GetViewport(viewport->d3d_viewport, &vp))) + return hr; + + if (x1 > x2 || y1 > y2 || x1 < vp.dwX || y1 < vp.dwY || + x2 > (vp.dwX + vp.dwWidth) || y2 > (vp.dwY + vp.dwHeight)) + return D3DRMERR_BADVALUE; + + return D3DRM_OK; }
static HRESULT WINAPI d3drm_viewport1_ForceUpdate(IDirect3DRMViewport *iface, DWORD x1, DWORD y1, DWORD x2, DWORD y2) { - FIXME("iface %p, x1 %lu, y1 %lu, x2 %lu, y2 %lu stub!\n", iface, x1, y1, x2, y2); + struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport(iface);
- return E_NOTIMPL; + TRACE("iface %p, x1 %lu, y1 %lu, x2 %lu, y2 %lu.\n", iface, x1, y1, x2, y2); + + return d3drm_viewport2_ForceUpdate(&viewport->IDirect3DRMViewport2_iface, x1, y1, x2, y2); }
static HRESULT WINAPI d3drm_viewport2_SetPlane(IDirect3DRMViewport2 *iface,
From: Jeff Smith whydoubt@gmail.com
--- dlls/d3drm/Makefile.in | 2 +- dlls/d3drm/d3drm_private.h | 3 ++- dlls/d3drm/device.c | 45 ++++++++++++++++++++++++++++++-------- dlls/d3drm/tests/d3drm.c | 24 ++++++++++---------- dlls/d3drm/viewport.c | 4 ++++ 5 files changed, 55 insertions(+), 23 deletions(-)
diff --git a/dlls/d3drm/Makefile.in b/dlls/d3drm/Makefile.in index e5381b4919c..482302e60f4 100644 --- a/dlls/d3drm/Makefile.in +++ b/dlls/d3drm/Makefile.in @@ -1,6 +1,6 @@ MODULE = d3drm.dll IMPORTLIB = d3drm -IMPORTS = d3dxof ddraw +IMPORTS = d3dxof ddraw user32
EXTRADLLFLAGS = -Wb,--prefer-native
diff --git a/dlls/d3drm/d3drm_private.h b/dlls/d3drm/d3drm_private.h index e07efa1c799..8f434831b37 100644 --- a/dlls/d3drm/d3drm_private.h +++ b/dlls/d3drm/d3drm_private.h @@ -127,13 +127,14 @@ struct d3drm_device IDirect3DRM *d3drm; IDirectDraw *ddraw; IDirectDrawSurface *primary_surface, *render_target; - IDirectDrawClipper *clipper; IDirect3DDevice *device; BOOL dither; D3DRMRENDERQUALITY quality; DWORD rendermode; DWORD height; DWORD width; + HWND window; + BOOL needs_update; };
struct d3drm_face diff --git a/dlls/d3drm/device.c b/dlls/d3drm/device.c index 1a433746224..e6c327a4ade 100644 --- a/dlls/d3drm/device.c +++ b/dlls/d3drm/device.c @@ -51,7 +51,6 @@ void d3drm_device_destroy(struct d3drm_device *device) { TRACE("Releasing primary surface and attached clipper.\n"); IDirectDrawSurface_Release(device->primary_surface); - IDirectDrawClipper_Release(device->clipper); } if (device->ddraw) { @@ -110,8 +109,7 @@ HRESULT d3drm_device_create_surfaces_from_clipper(struct d3drm_device *object, I }
object->primary_surface = primary_surface; - object->clipper = clipper; - IDirectDrawClipper_AddRef(clipper); + object->window = window; *surface = render_target;
return D3DRM_OK; @@ -219,6 +217,8 @@ HRESULT d3drm_device_init(struct d3drm_device *device, UINT version, IDirectDraw device->width = desc.dwWidth; device->height = desc.dwHeight;
+ device->needs_update = FALSE; + return hr; }
@@ -712,23 +712,50 @@ static HRESULT WINAPI d3drm_device1_InitFromClipper(IDirect3DRMDevice *iface,
static HRESULT WINAPI d3drm_device3_Update(IDirect3DRMDevice3 *iface) { - FIXME("iface %p stub!\n", iface); + struct d3drm_device *device = impl_from_IDirect3DRMDevice3(iface); + HRESULT hr = D3DRM_OK;
- return D3DRM_OK; + TRACE("iface %p.\n", iface); + + if (device->needs_update) + { + if (device->primary_surface) + { + RECT rt_rect = { 0, 0, device->width, device->height }; + RECT ps_rect = rt_rect; + + ClientToScreen(device->window, (POINT *)&ps_rect.left); + ClientToScreen(device->window, (POINT *)&ps_rect.right); + + TRACE("primary surface rect %s, render target rect %s\n", + wine_dbgstr_rect(&ps_rect), wine_dbgstr_rect(&rt_rect)); + + hr = IDirectDrawSurface_Blt(device->primary_surface, &ps_rect, + device->render_target, &rt_rect, DDBLT_WAIT, NULL); + } + + device->needs_update = FALSE; + } + + return hr; }
static HRESULT WINAPI d3drm_device2_Update(IDirect3DRMDevice2 *iface) { - FIXME("iface %p stub!\n", iface); + struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
- return D3DRM_OK; + TRACE("iface %p.\n", iface); + + return d3drm_device3_Update(&device->IDirect3DRMDevice3_iface); }
static HRESULT WINAPI d3drm_device1_Update(IDirect3DRMDevice *iface) { - FIXME("iface %p stub!\n", iface); + struct d3drm_device *device = impl_from_IDirect3DRMDevice(iface);
- return D3DRM_OK; + TRACE("iface %p.\n", iface); + + return d3drm_device3_Update(&device->IDirect3DRMDevice3_iface); }
static HRESULT WINAPI d3drm_device3_AddUpdateCallback(IDirect3DRMDevice3 *iface, diff --git a/dlls/d3drm/tests/d3drm.c b/dlls/d3drm/tests/d3drm.c index 7b60efa1965..cf1ff2e5295 100644 --- a/dlls/d3drm/tests/d3drm.c +++ b/dlls/d3drm/tests/d3drm.c @@ -8763,7 +8763,7 @@ static void test_update_surfaces_1(void) hr = IDirect3DRMDevice_Update(device1); ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice, hr %#lx.\n", hr); ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); - todo_wine ok(compare_color(ret_color, 0x000000ff, 1), "Got unexpected color 0x%08lx.\n", ret_color); + ok(compare_color(ret_color, 0x000000ff, 1), "Got unexpected color 0x%08lx.\n", ret_color);
/* Update modifies primary surface following a viewport clear */ clip_list_size = 0; @@ -8783,7 +8783,7 @@ static void test_update_surfaces_1(void) ret_color = get_surface_color(surface, 320, 240); ok(compare_color(ret_color, 0x00ff7f00, 1), "Got unexpected color 0x%08lx.\n", ret_color); ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); - todo_wine ok(compare_color(ret_color, 0x000000ff, 1), "Got unexpected color 0x%08lx.\n", ret_color); + ok(compare_color(ret_color, 0x000000ff, 1), "Got unexpected color 0x%08lx.\n", ret_color); hr = IDirect3DRMDevice_AddUpdateCallback(device1, update_cb_surf_color, &ctx); todo_wine ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); hr = IDirect3DRMDevice_Update(device1); @@ -8791,7 +8791,7 @@ static void test_update_surfaces_1(void) hr = IDirect3DRMDevice_DeleteUpdateCallback(device1, update_cb_surf_color, &ctx); todo_wine ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); - todo_wine ok(compare_color(ret_color, 0x00ff7f00, 1), "Got unexpected color 0x%08lx.\n", ret_color); + ok(compare_color(ret_color, 0x00ff7f00, 1), "Got unexpected color 0x%08lx.\n", ret_color); todo_wine ok(compare_color(ctx.color, 0x00ff7f00, 1), "Got unexpected color 0x%08lx.\n", ctx.color);
/* Draw at the window handle location, regardless of clipper alterations */ @@ -8810,7 +8810,7 @@ static void test_update_surfaces_1(void) hr = IDirect3DRMDevice_Update(device1); ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice, hr %#lx.\n", hr); ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); - todo_wine ok(compare_color(ret_color, 0x0000ff00, 1), "Got unexpected color 0x%08lx.\n", ret_color); + ok(compare_color(ret_color, 0x0000ff00, 1), "Got unexpected color 0x%08lx.\n", ret_color);
IDirect3DRMViewport_Release(viewport); IDirect3DRMFrame_Release(camera); @@ -8932,7 +8932,7 @@ static void test_update_surfaces_2(void) hr = IDirect3DRMDevice_Update(device2); ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice2, hr %#lx.\n", hr); ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); - todo_wine ok(compare_color(ret_color, 0x000000ff, 1), "Got unexpected color 0x%08lx.\n", ret_color); + ok(compare_color(ret_color, 0x000000ff, 1), "Got unexpected color 0x%08lx.\n", ret_color);
/* Update modifies primary surface following a viewport clear */ ctx.surface = d3drm_primary; @@ -8946,7 +8946,7 @@ static void test_update_surfaces_2(void) ret_color = get_surface_color(surface, 320, 240); ok(compare_color(ret_color, 0x00ff7f00, 1), "Got unexpected color 0x%08lx.\n", ret_color); ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); - todo_wine ok(compare_color(ret_color, 0x000000ff, 1), "Got unexpected color 0x%08lx.\n", ret_color); + ok(compare_color(ret_color, 0x000000ff, 1), "Got unexpected color 0x%08lx.\n", ret_color); hr = IDirect3DRMDevice2_AddUpdateCallback(device2, update_cb_surf_color, &ctx); todo_wine ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); hr = IDirect3DRMDevice2_Update(device2); @@ -8954,7 +8954,7 @@ static void test_update_surfaces_2(void) hr = IDirect3DRMDevice2_DeleteUpdateCallback(device2, update_cb_surf_color, &ctx); todo_wine ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); - todo_wine ok(compare_color(ret_color, 0x00ff7f00, 1), "Got unexpected color 0x%08lx.\n", ret_color); + ok(compare_color(ret_color, 0x00ff7f00, 1), "Got unexpected color 0x%08lx.\n", ret_color); todo_wine ok(compare_color(ctx.color, 0x00ff7f00, 1), "Got unexpected color 0x%08lx.\n", ctx.color);
/* Draw at the window handle location, regardless of clipper alterations */ @@ -8979,7 +8979,7 @@ static void test_update_surfaces_2(void) hr = IDirect3DRMDevice2_Update(device2); ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice2, hr %#lx.\n", hr); ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); - todo_wine ok(compare_color(ret_color, 0x0000ff00, 1), "Got unexpected color 0x%08lx.\n", ret_color); + ok(compare_color(ret_color, 0x0000ff00, 1), "Got unexpected color 0x%08lx.\n", ret_color);
IDirect3DRMViewport_Release(viewport); IDirect3DRMFrame_Release(camera1); @@ -9097,7 +9097,7 @@ static void test_update_surfaces_3(void) hr = IDirect3DRMDevice3_Update(device3); ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice3, hr %#lx.\n", hr); ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); - todo_wine ok(compare_color(ret_color, 0x000000ff, 1), "Got unexpected color 0x%08lx.\n", ret_color); + ok(compare_color(ret_color, 0x000000ff, 1), "Got unexpected color 0x%08lx.\n", ret_color);
/* Update modifies primary surface following a viewport clear */ ctx.surface = d3drm_primary; @@ -9111,7 +9111,7 @@ static void test_update_surfaces_3(void) ret_color = get_surface_color(surface, 320, 240); ok(compare_color(ret_color, 0x00ff7f00, 1), "Got unexpected color 0x%08lx.\n", ret_color); ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); - todo_wine ok(compare_color(ret_color, 0x000000ff, 1), "Got unexpected color 0x%08lx.\n", ret_color); + ok(compare_color(ret_color, 0x000000ff, 1), "Got unexpected color 0x%08lx.\n", ret_color); hr = IDirect3DRMDevice3_AddUpdateCallback(device3, update_cb_surf_color, &ctx); todo_wine ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); hr = IDirect3DRMDevice3_Update(device3); @@ -9119,7 +9119,7 @@ static void test_update_surfaces_3(void) hr = IDirect3DRMDevice3_DeleteUpdateCallback(device3, update_cb_surf_color, &ctx); todo_wine ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); - todo_wine ok(compare_color(ret_color, 0x00ff7f00, 1), "Got unexpected color 0x%08lx.\n", ret_color); + ok(compare_color(ret_color, 0x00ff7f00, 1), "Got unexpected color 0x%08lx.\n", ret_color); todo_wine ok(compare_color(ctx.color, 0x00ff7f00, 1), "Got unexpected color 0x%08lx.\n", ctx.color);
/* Draw at the window handle location, regardless of clipper alterations */ @@ -9144,7 +9144,7 @@ static void test_update_surfaces_3(void) hr = IDirect3DRMDevice3_Update(device3); ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice3, hr %#lx.\n", hr); ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); - todo_wine ok(compare_color(ret_color, 0x0000ff00, 1), "Got unexpected color 0x%08lx.\n", ret_color); + ok(compare_color(ret_color, 0x0000ff00, 1), "Got unexpected color 0x%08lx.\n", ret_color);
IDirect3DRMViewport2_Release(viewport); IDirect3DRMFrame3_Release(camera); diff --git a/dlls/d3drm/viewport.c b/dlls/d3drm/viewport.c index 528cae24001..7ba7b0c61b5 100644 --- a/dlls/d3drm/viewport.c +++ b/dlls/d3drm/viewport.c @@ -458,6 +458,8 @@ static HRESULT WINAPI d3drm_viewport2_Clear(IDirect3DRMViewport2 *iface, DWORD f if (FAILED(hr = IDirect3DViewport_Clear(viewport->d3d_viewport, 1, &clear_rect, clear_flags))) return hr;
+ viewport->device->needs_update = TRUE; + return D3DRM_OK; }
@@ -693,6 +695,8 @@ static HRESULT WINAPI d3drm_viewport2_ForceUpdate(IDirect3DRMViewport2* iface, x2 > (vp.dwX + vp.dwWidth) || y2 > (vp.dwY + vp.dwHeight)) return D3DRMERR_BADVALUE;
+ viewport->device->needs_update = TRUE; + return D3DRM_OK; }
From: Jeff Smith whydoubt@gmail.com
--- dlls/d3drm/d3drm_private.h | 1 + dlls/d3drm/device.c | 97 +++++++++++++++++++++++++++++++++----- dlls/d3drm/tests/d3drm.c | 90 +++++++++++++++++------------------ 3 files changed, 127 insertions(+), 61 deletions(-)
diff --git a/dlls/d3drm/d3drm_private.h b/dlls/d3drm/d3drm_private.h index 8f434831b37..507ecdac49b 100644 --- a/dlls/d3drm/d3drm_private.h +++ b/dlls/d3drm/d3drm_private.h @@ -135,6 +135,7 @@ struct d3drm_device DWORD width; HWND window; BOOL needs_update; + struct list update_callbacks; };
struct d3drm_face diff --git a/dlls/d3drm/device.c b/dlls/d3drm/device.c index e6c327a4ade..67836c7bcd8 100644 --- a/dlls/d3drm/device.c +++ b/dlls/d3drm/device.c @@ -218,6 +218,7 @@ HRESULT d3drm_device_init(struct d3drm_device *device, UINT version, IDirectDraw device->height = desc.dwHeight;
device->needs_update = FALSE; + list_init(&device->update_callbacks);
return hr; } @@ -710,18 +711,27 @@ static HRESULT WINAPI d3drm_device1_InitFromClipper(IDirect3DRMDevice *iface, clipper, guid, width, height); }
+struct update_callback +{ + struct list entry; + D3DRMUPDATECALLBACK cb; + void *ctx; +}; + static HRESULT WINAPI d3drm_device3_Update(IDirect3DRMDevice3 *iface) { struct d3drm_device *device = impl_from_IDirect3DRMDevice3(iface); + struct update_callback *callback; HRESULT hr = D3DRM_OK;
TRACE("iface %p.\n", iface);
if (device->needs_update) { + RECT rt_rect = { 0, 0, device->width, device->height }; + if (device->primary_surface) { - RECT rt_rect = { 0, 0, device->width, device->height }; RECT ps_rect = rt_rect;
ClientToScreen(device->window, (POINT *)&ps_rect.left); @@ -734,8 +744,20 @@ static HRESULT WINAPI d3drm_device3_Update(IDirect3DRMDevice3 *iface) device->render_target, &rt_rect, DDBLT_WAIT, NULL); }
+ LIST_FOR_EACH_ENTRY(callback, &device->update_callbacks, struct update_callback, entry) + { + callback->cb(&device->IDirect3DRMDevice_iface, callback->ctx, 1, (D3DRECT *)&rt_rect); + } + device->needs_update = FALSE; } + else + { + LIST_FOR_EACH_ENTRY(callback, &device->update_callbacks, struct update_callback, entry) + { + callback->cb(&device->IDirect3DRMDevice_iface, callback->ctx, 0, NULL); + } + }
return hr; } @@ -758,52 +780,101 @@ static HRESULT WINAPI d3drm_device1_Update(IDirect3DRMDevice *iface) return d3drm_device3_Update(&device->IDirect3DRMDevice3_iface); }
+HRESULT d3drm_device_add_update_callback(struct d3drm_device *device, D3DRMUPDATECALLBACK cb, void *ctx) +{ + struct update_callback *callback; + + if (!cb) + return D3DRMERR_BADVALUE; + + if (!(callback = malloc(sizeof(*callback)))) + return E_OUTOFMEMORY; + + callback->cb = cb; + callback->ctx = ctx; + + list_add_tail(&device->update_callbacks, &callback->entry); + return D3DRM_OK; +} + +HRESULT d3drm_device_delete_update_callback(struct d3drm_device *device, D3DRMUPDATECALLBACK cb, void *ctx) +{ + struct update_callback *callback; + + if (!cb) + return D3DRMERR_BADVALUE; + + LIST_FOR_EACH_ENTRY(callback, &device->update_callbacks, struct update_callback, entry) + { + if (callback->cb == cb && callback->ctx == ctx) + { + list_remove(&callback->entry); + free(callback); + break; + } + } + + return D3DRM_OK; +} + static HRESULT WINAPI d3drm_device3_AddUpdateCallback(IDirect3DRMDevice3 *iface, D3DRMUPDATECALLBACK cb, void *ctx) { - FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx); + struct d3drm_device *device = impl_from_IDirect3DRMDevice3(iface);
- return E_NOTIMPL; + TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx); + + return d3drm_device_add_update_callback(device, cb, ctx); }
static HRESULT WINAPI d3drm_device2_AddUpdateCallback(IDirect3DRMDevice2 *iface, D3DRMUPDATECALLBACK cb, void *ctx) { - FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx); + struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
- return E_NOTIMPL; + TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx); + + return d3drm_device_add_update_callback(device, cb, ctx); }
static HRESULT WINAPI d3drm_device1_AddUpdateCallback(IDirect3DRMDevice *iface, D3DRMUPDATECALLBACK cb, void *ctx) { - FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx); + struct d3drm_device *device = impl_from_IDirect3DRMDevice(iface);
- return E_NOTIMPL; + TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx); + + return d3drm_device_add_update_callback(device, cb, ctx); }
static HRESULT WINAPI d3drm_device3_DeleteUpdateCallback(IDirect3DRMDevice3 *iface, D3DRMUPDATECALLBACK cb, void *ctx) { - FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx); + struct d3drm_device *device = impl_from_IDirect3DRMDevice3(iface);
- return E_NOTIMPL; + TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx); + + return d3drm_device_delete_update_callback(device, cb, ctx); }
static HRESULT WINAPI d3drm_device2_DeleteUpdateCallback(IDirect3DRMDevice2 *iface, D3DRMUPDATECALLBACK cb, void *ctx) { - FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx); + struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
- return E_NOTIMPL; + TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx); + + return d3drm_device_delete_update_callback(device, cb, ctx); }
static HRESULT WINAPI d3drm_device1_DeleteUpdateCallback(IDirect3DRMDevice *iface, D3DRMUPDATECALLBACK cb, void *ctx) { - FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx); + struct d3drm_device *device = impl_from_IDirect3DRMDevice(iface);
- return E_NOTIMPL; + TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx); + + return d3drm_device_delete_update_callback(device, cb, ctx); }
static HRESULT WINAPI d3drm_device3_SetBufferCount(IDirect3DRMDevice3 *iface, DWORD count) diff --git a/dlls/d3drm/tests/d3drm.c b/dlls/d3drm/tests/d3drm.c index cf1ff2e5295..ae1fe93690c 100644 --- a/dlls/d3drm/tests/d3drm.c +++ b/dlls/d3drm/tests/d3drm.c @@ -8308,12 +8308,12 @@ static void test_update_1(void) ctx.rect.x1 = ctx.rect.y1 = ctx.rect.x2 = ctx.rect.y2 = ~0; ctx.rect_count = -1; hr = IDirect3DRMDevice_AddUpdateCallback(device1, update_cb_get_rect, &ctx); - todo_wine ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); hr = IDirect3DRMDevice_Update(device1); ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice, hr %#lx.\n", hr); hr = IDirect3DRMDevice_DeleteUpdateCallback(device1, update_cb_get_rect, &ctx); - todo_wine ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); - todo_wine ok(ctx.rect_count == 0, "Got unexpected rect count %d, expected 0.\n", ctx.rect_count); + ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); + ok(ctx.rect_count == 0, "Got unexpected rect count %d, expected 0.\n", ctx.rect_count); ok(ctx.rect.x1 == ~0 && ctx.rect.y1 == ~0 && ctx.rect.x2 == ~0 && ctx.rect.y2 == ~0, "Got unexpected rect %s.\n", wine_dbgstr_rect((RECT *)&ctx.rect));
@@ -8350,17 +8350,16 @@ static void test_update_1(void) hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left, vrect.top, vrect.right, vrect.bottom); ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); hr = IDirect3DRMDevice_AddUpdateCallback(device1, update_cb_modify_rect, NULL); - todo_wine ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); hr = IDirect3DRMDevice_AddUpdateCallback(device1, update_cb_get_rect, &ctx); - todo_wine ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); hr = IDirect3DRMDevice_Update(device1); ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice, hr %#lx.\n", hr); hr = IDirect3DRMDevice_DeleteUpdateCallback(device1, update_cb_modify_rect, NULL); - todo_wine ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); hr = IDirect3DRMDevice_DeleteUpdateCallback(device1, update_cb_get_rect, &ctx); - todo_wine ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); - todo_wine ok(ctx.rect_count == 1, "Got unexpected rect count %d, expected 1.\n", ctx.rect_count); - todo_wine + ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); + ok(ctx.rect_count == 1, "Got unexpected rect count %d, expected 1.\n", ctx.rect_count); ok(ctx.rect.x1 == 999999 && ctx.rect.y1 <= vrect.top && ctx.rect.x2 >= vrect.right && ctx.rect.y2 >= vrect.bottom, "Got unexpected rect %s.\n", wine_dbgstr_rect((RECT *)&ctx.rect)); @@ -8371,13 +8370,12 @@ static void test_update_1(void) hr = IDirect3DRMViewport_Clear(viewport); ok(hr == D3DRM_OK, "Cannot clear viewport, hr %#lx.\n", hr); hr = IDirect3DRMDevice_AddUpdateCallback(device1, update_cb_get_rect, &ctx); - todo_wine ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); hr = IDirect3DRMDevice_Update(device1); ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice, hr %#lx.\n", hr); hr = IDirect3DRMDevice_DeleteUpdateCallback(device1, update_cb_get_rect, &ctx); - todo_wine ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); - todo_wine ok(ctx.rect_count == 1, "Got unexpected rect count %d, expected 1.\n", ctx.rect_count); - todo_wine + ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); + ok(ctx.rect_count == 1, "Got unexpected rect count %d, expected 1.\n", ctx.rect_count); ok(ctx.rect.x1 <= vrect.left && ctx.rect.y1 <= vrect.top && ctx.rect.x2 >= vrect.right && ctx.rect.y2 >= vrect.bottom, "Got unexpected rect %s.\n", wine_dbgstr_rect((RECT *)&ctx.rect)); @@ -8442,12 +8440,12 @@ static void test_update_2(void) ctx.rect.x1 = ctx.rect.y1 = ctx.rect.x2 = ctx.rect.y2 = ~0; ctx.rect_count = -1; hr = IDirect3DRMDevice2_AddUpdateCallback(device2, update_cb_get_rect, &ctx); - todo_wine ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); hr = IDirect3DRMDevice2_Update(device2); ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice2, hr %#lx.\n", hr); hr = IDirect3DRMDevice2_DeleteUpdateCallback(device2, update_cb_get_rect, &ctx); - todo_wine ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); - todo_wine ok(ctx.rect_count == 0, "Got unexpected rect count %d, expected 0.\n", ctx.rect_count); + ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); + ok(ctx.rect_count == 0, "Got unexpected rect count %d, expected 0.\n", ctx.rect_count); ok(ctx.rect.x1 == ~0 && ctx.rect.y1 == ~0 && ctx.rect.x2 == ~0 && ctx.rect.y2 == ~0, "Got unexpected rect %s.\n", wine_dbgstr_rect((RECT *)&ctx.rect));
@@ -8484,17 +8482,16 @@ static void test_update_2(void) hr = IDirect3DRMViewport_ForceUpdate(viewport, vrect.left, vrect.top, vrect.right, vrect.bottom); ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); hr = IDirect3DRMDevice2_AddUpdateCallback(device2, update_cb_modify_rect, NULL); - todo_wine ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); hr = IDirect3DRMDevice2_AddUpdateCallback(device2, update_cb_get_rect, &ctx); - todo_wine ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); hr = IDirect3DRMDevice2_Update(device2); ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice2, hr %#lx.\n", hr); hr = IDirect3DRMDevice2_DeleteUpdateCallback(device2, update_cb_modify_rect, NULL); - todo_wine ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); hr = IDirect3DRMDevice2_DeleteUpdateCallback(device2, update_cb_get_rect, &ctx); - todo_wine ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); - todo_wine ok(ctx.rect_count == 1, "Got unexpected rect count %d, expected 1.\n", ctx.rect_count); - todo_wine + ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); + ok(ctx.rect_count == 1, "Got unexpected rect count %d, expected 1.\n", ctx.rect_count); ok(ctx.rect.x1 == 999999 && ctx.rect.y1 <= vrect.top && ctx.rect.x2 >= vrect.right && ctx.rect.y2 >= vrect.bottom, "Got unexpected rect %s.\n", wine_dbgstr_rect((RECT *)&ctx.rect)); @@ -8505,13 +8502,12 @@ static void test_update_2(void) hr = IDirect3DRMViewport_Clear(viewport); ok(hr == D3DRM_OK, "Cannot clear viewport, hr %#lx.\n", hr); hr = IDirect3DRMDevice2_AddUpdateCallback(device2, update_cb_get_rect, &ctx); - todo_wine ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); hr = IDirect3DRMDevice2_Update(device2); ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice2, hr %#lx.\n", hr); hr = IDirect3DRMDevice2_DeleteUpdateCallback(device2, update_cb_get_rect, &ctx); - todo_wine ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); - todo_wine ok(ctx.rect_count == 1, "Got unexpected rect count %d, expected 1.\n", ctx.rect_count); - todo_wine + ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); + ok(ctx.rect_count == 1, "Got unexpected rect count %d, expected 1.\n", ctx.rect_count); ok(ctx.rect.x1 <= vrect.left && ctx.rect.y1 <= vrect.top && ctx.rect.x2 >= vrect.right && ctx.rect.y2 >= vrect.bottom, "Got unexpected rect %s.\n", wine_dbgstr_rect((RECT *)&ctx.rect)); @@ -8572,12 +8568,12 @@ static void test_update_3(void) ctx.rect.x1 = ctx.rect.y1 = ctx.rect.x2 = ctx.rect.y2 = ~0; ctx.rect_count = -1; hr = IDirect3DRMDevice3_AddUpdateCallback(device3, update_cb_get_rect, &ctx); - todo_wine ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); hr = IDirect3DRMDevice3_Update(device3); ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice3, hr %#lx.\n", hr); hr = IDirect3DRMDevice3_DeleteUpdateCallback(device3, update_cb_get_rect, &ctx); - todo_wine ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); - todo_wine ok(ctx.rect_count == 0, "Got unexpected rect count %d, expected 0.\n", ctx.rect_count); + ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); + ok(ctx.rect_count == 0, "Got unexpected rect count %d, expected 0.\n", ctx.rect_count); ok(ctx.rect.x1 == ~0 && ctx.rect.y1 == ~0 && ctx.rect.x2 == ~0 && ctx.rect.y2 == ~0, "Got unexpected rect %s.\n", wine_dbgstr_rect((RECT *)&ctx.rect));
@@ -8614,17 +8610,16 @@ static void test_update_3(void) hr = IDirect3DRMViewport2_ForceUpdate(viewport, vrect.left, vrect.top, vrect.right, vrect.bottom); ok(hr == D3DRM_OK, "Cannot force update of viewport, hr %#lx.\n", hr); hr = IDirect3DRMDevice3_AddUpdateCallback(device3, update_cb_modify_rect, NULL); - todo_wine ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); hr = IDirect3DRMDevice3_AddUpdateCallback(device3, update_cb_get_rect, &ctx); - todo_wine ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); hr = IDirect3DRMDevice3_Update(device3); ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice3, hr %#lx.\n", hr); hr = IDirect3DRMDevice3_DeleteUpdateCallback(device3, update_cb_modify_rect, NULL); - todo_wine ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); hr = IDirect3DRMDevice3_DeleteUpdateCallback(device3, update_cb_get_rect, &ctx); - todo_wine ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); - todo_wine ok(ctx.rect_count == 1, "Got unexpected rect count %d, expected 1.\n", ctx.rect_count); - todo_wine + ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); + ok(ctx.rect_count == 1, "Got unexpected rect count %d, expected 1.\n", ctx.rect_count); ok(ctx.rect.x1 == 999999 && ctx.rect.y1 <= vrect.top && ctx.rect.x2 >= vrect.right && ctx.rect.y2 >= vrect.bottom, "Got unexpected rect %s.\n", wine_dbgstr_rect((RECT *)&ctx.rect)); @@ -8635,13 +8630,12 @@ static void test_update_3(void) hr = IDirect3DRMViewport2_Clear(viewport, D3DRMCLEAR_ALL); ok(hr == D3DRM_OK, "Cannot clear viewport, hr %#lx.\n", hr); hr = IDirect3DRMDevice3_AddUpdateCallback(device3, update_cb_get_rect, &ctx); - todo_wine ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); hr = IDirect3DRMDevice3_Update(device3); ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice3, hr %#lx.\n", hr); hr = IDirect3DRMDevice3_DeleteUpdateCallback(device3, update_cb_get_rect, &ctx); - todo_wine ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); - todo_wine ok(ctx.rect_count == 1, "Got unexpected rect count %d, expected 1.\n", ctx.rect_count); - todo_wine + ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); + ok(ctx.rect_count == 1, "Got unexpected rect count %d, expected 1.\n", ctx.rect_count); ok(ctx.rect.x1 <= vrect.left && ctx.rect.y1 <= vrect.top && ctx.rect.x2 >= vrect.right && ctx.rect.y2 >= vrect.bottom, "Got unexpected rect %s.\n", wine_dbgstr_rect((RECT *)&ctx.rect)); @@ -8785,14 +8779,14 @@ static void test_update_surfaces_1(void) ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); ok(compare_color(ret_color, 0x000000ff, 1), "Got unexpected color 0x%08lx.\n", ret_color); hr = IDirect3DRMDevice_AddUpdateCallback(device1, update_cb_surf_color, &ctx); - todo_wine ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); hr = IDirect3DRMDevice_Update(device1); ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice, hr %#lx.\n", hr); hr = IDirect3DRMDevice_DeleteUpdateCallback(device1, update_cb_surf_color, &ctx); - todo_wine ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); ok(compare_color(ret_color, 0x00ff7f00, 1), "Got unexpected color 0x%08lx.\n", ret_color); - todo_wine ok(compare_color(ctx.color, 0x00ff7f00, 1), "Got unexpected color 0x%08lx.\n", ctx.color); + ok(compare_color(ctx.color, 0x00ff7f00, 1), "Got unexpected color 0x%08lx.\n", ctx.color);
/* Draw at the window handle location, regardless of clipper alterations */ clip_list->rdh.rcBound.left += 10; @@ -8948,14 +8942,14 @@ static void test_update_surfaces_2(void) ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); ok(compare_color(ret_color, 0x000000ff, 1), "Got unexpected color 0x%08lx.\n", ret_color); hr = IDirect3DRMDevice2_AddUpdateCallback(device2, update_cb_surf_color, &ctx); - todo_wine ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); hr = IDirect3DRMDevice2_Update(device2); ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice2, hr %#lx.\n", hr); hr = IDirect3DRMDevice2_DeleteUpdateCallback(device2, update_cb_surf_color, &ctx); - todo_wine ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); ok(compare_color(ret_color, 0x00ff7f00, 1), "Got unexpected color 0x%08lx.\n", ret_color); - todo_wine ok(compare_color(ctx.color, 0x00ff7f00, 1), "Got unexpected color 0x%08lx.\n", ctx.color); + ok(compare_color(ctx.color, 0x00ff7f00, 1), "Got unexpected color 0x%08lx.\n", ctx.color);
/* Draw at the window handle location, regardless of clipper alterations */ clip_list_size = 0; @@ -9113,14 +9107,14 @@ static void test_update_surfaces_3(void) ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); ok(compare_color(ret_color, 0x000000ff, 1), "Got unexpected color 0x%08lx.\n", ret_color); hr = IDirect3DRMDevice3_AddUpdateCallback(device3, update_cb_surf_color, &ctx); - todo_wine ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot add update callback, hr %#lx.\n", hr); hr = IDirect3DRMDevice3_Update(device3); ok(hr == D3DRM_OK, "Cannot update Direct3DRMDevice3, hr %#lx.\n", hr); hr = IDirect3DRMDevice3_DeleteUpdateCallback(device3, update_cb_surf_color, &ctx); - todo_wine ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); + ok(hr == D3DRM_OK, "Cannot delete update callback, hr %#lx.\n", hr); ret_color = get_surface_color(d3drm_primary, 320 + client_pos.x, 240 + client_pos.y); ok(compare_color(ret_color, 0x00ff7f00, 1), "Got unexpected color 0x%08lx.\n", ret_color); - todo_wine ok(compare_color(ctx.color, 0x00ff7f00, 1), "Got unexpected color 0x%08lx.\n", ctx.color); + ok(compare_color(ctx.color, 0x00ff7f00, 1), "Got unexpected color 0x%08lx.\n", ctx.color);
/* Draw at the window handle location, regardless of clipper alterations */ clip_list_size = 0;
@stefan @alesliehughes