From: Jeff Smith whydoubt@gmail.com
--- dlls/d3drm/d3drm_private.h | 1 + dlls/d3drm/device.c | 97 +++++++++++++++++++++++++++++++++----- dlls/d3drm/tests/d3drm.c | 66 ++++++++++++-------------- 3 files changed, 116 insertions(+), 48 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 16285de552c..e268713522f 100644 --- a/dlls/d3drm/tests/d3drm.c +++ b/dlls/d3drm/tests/d3drm.c @@ -8306,22 +8306,22 @@ static void test_update_1(void)
/* A NULL callback is not allowed */ hr = IDirect3DRMDevice_AddUpdateCallback(device1, NULL, NULL); - todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from add update callback, hr %#lx.\n", hr); + ok(hr == D3DRMERR_BADVALUE, "Expected bad value from add update callback, hr %#lx.\n", hr); hr = IDirect3DRMDevice_DeleteUpdateCallback(device1, NULL, NULL); - todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected bad value from delete update callback, hr %#lx.\n", hr); + ok(hr == D3DRMERR_BADVALUE, "Expected bad value from delete update callback, 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 = LONG_MIN; 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_DeleteUpdateCallback(device1, update_cb_get_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_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 == LONG_MIN && ctx.rect.y1 == LONG_MIN && ctx.rect.x2 == LONG_MIN && ctx.rect.y2 == LONG_MIN, "Got unexpected rect %s.\n", wine_dbgstr_rect((RECT *)&ctx.rect));
@@ -8358,17 +8358,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)); @@ -8379,13 +8378,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_3(void) ctx.rect.x1 = ctx.rect.y1 = ctx.rect.x2 = ctx.rect.y2 = LONG_MIN; 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 == LONG_MIN && ctx.rect.y1 == LONG_MIN && ctx.rect.x2 == LONG_MIN && ctx.rect.y2 == LONG_MIN, "Got unexpected rect %s.\n", wine_dbgstr_rect((RECT *)&ctx.rect));
@@ -8484,17 +8482,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)); @@ -8505,13 +8502,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)); @@ -8655,14 +8651,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; @@ -8810,14 +8806,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;