diff --git a/dlls/d3drm/d3drm.c b/dlls/d3drm/d3drm.c index 2b4e87c1ece..ae08fdfae25 100644 --- a/dlls/d3drm/d3drm.c +++ b/dlls/d3drm/d3drm.c @@ -110,6 +110,19 @@ static HRESULT d3drm_create_mesh_builder_object(void **object, IDirect3DRM *d3dr return hr; } +static HRESULT d3drm_create_frame_object(void **object, IDirect3DRM *d3drm) +{ + struct d3drm_frame *frame; + HRESULT hr; + + if (FAILED(hr = d3drm_frame_create(&frame, NULL, d3drm))) + return hr; + + *object = &frame->IDirect3DRMFrame_iface; + + return hr; +} + struct d3drm { IDirect3DRM IDirect3DRM_iface; @@ -1257,6 +1270,7 @@ static HRESULT WINAPI d3drm3_CreateObject(IDirect3DRM3 *iface, {&CLSID_CDirect3DRMViewport, d3drm_create_viewport_object}, {&CLSID_CDirect3DRMFace, d3drm_create_face_object}, {&CLSID_CDirect3DRMMeshBuilder, d3drm_create_mesh_builder_object}, + {&CLSID_CDirect3DRMFrame, d3drm_create_frame_object}, }; TRACE("iface %p, clsid %s, outer %p, iid %s, out %p.\n", diff --git a/dlls/d3drm/frame.c b/dlls/d3drm/frame.c index 99b8ce08f72..eda2c04594c 100644 --- a/dlls/d3drm/frame.c +++ b/dlls/d3drm/frame.c @@ -533,6 +533,7 @@ static ULONG WINAPI d3drm_frame3_Release(IDirect3DRMFrame3 *iface) if (!refcount) { + d3drm_object_cleanup((IDirect3DRMObject *)&frame->IDirect3DRMFrame_iface, &frame->obj); for (i = 0; i < frame->nb_children; ++i) { IDirect3DRMFrame3_Release(frame->children[i]); @@ -548,6 +549,7 @@ static ULONG WINAPI d3drm_frame3_Release(IDirect3DRMFrame3 *iface) IDirect3DRMLight_Release(frame->lights[i]); } HeapFree(GetProcessHeap(), 0, frame->lights); + IDirect3DRM_Release(frame->d3drm); HeapFree(GetProcessHeap(), 0, frame); } @@ -599,49 +601,61 @@ static HRESULT WINAPI d3drm_frame1_Clone(IDirect3DRMFrame *iface, static HRESULT WINAPI d3drm_frame3_AddDestroyCallback(IDirect3DRMFrame3 *iface, D3DRMOBJECTCALLBACK cb, void *ctx) { - FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame3(iface); - return E_NOTIMPL; + TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx); + + return d3drm_object_add_destroy_callback(&frame->obj, cb, ctx); } static HRESULT WINAPI d3drm_frame2_AddDestroyCallback(IDirect3DRMFrame2 *iface, D3DRMOBJECTCALLBACK cb, void *ctx) { - FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame2(iface); - return E_NOTIMPL; + TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx); + + return IDirect3DRMFrame3_AddDestroyCallback(&frame->IDirect3DRMFrame3_iface, cb, ctx); } static HRESULT WINAPI d3drm_frame1_AddDestroyCallback(IDirect3DRMFrame *iface, D3DRMOBJECTCALLBACK cb, void *ctx) { - FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame(iface); - return E_NOTIMPL; + TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx); + + return IDirect3DRMFrame3_AddDestroyCallback(&frame->IDirect3DRMFrame3_iface, cb, ctx); } static HRESULT WINAPI d3drm_frame3_DeleteDestroyCallback(IDirect3DRMFrame3 *iface, D3DRMOBJECTCALLBACK cb, void *ctx) { - FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame3(iface); - return E_NOTIMPL; + TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx); + + return d3drm_object_delete_destroy_callback(&frame->obj, cb, ctx); } static HRESULT WINAPI d3drm_frame2_DeleteDestroyCallback(IDirect3DRMFrame2 *iface, D3DRMOBJECTCALLBACK cb, void *ctx) { - FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame2(iface); - return E_NOTIMPL; + TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx); + + return IDirect3DRMFrame3_DeleteDestroyCallback(&frame->IDirect3DRMFrame3_iface, cb, ctx); } static HRESULT WINAPI d3drm_frame1_DeleteDestroyCallback(IDirect3DRMFrame *iface, D3DRMOBJECTCALLBACK cb, void *ctx) { - FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame(iface); - return E_NOTIMPL; + TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx); + + return IDirect3DRMFrame3_DeleteDestroyCallback(&frame->IDirect3DRMFrame3_iface, cb, ctx); } static HRESULT WINAPI d3drm_frame3_SetAppData(IDirect3DRMFrame3 *iface, DWORD data) @@ -2959,6 +2973,8 @@ HRESULT d3drm_frame_create(struct d3drm_frame **frame, IUnknown *parent_frame, I IDirect3DRMFrame3_AddChild(p, &object->IDirect3DRMFrame3_iface); } + IDirect3DRM_AddRef(object->d3drm); + *frame = object; return hr; diff --git a/dlls/d3drm/tests/d3drm.c b/dlls/d3drm/tests/d3drm.c index d5c1bcd0a22..971e95c39cd 100644 --- a/dlls/d3drm/tests/d3drm.c +++ b/dlls/d3drm/tests/d3drm.c @@ -907,15 +907,19 @@ static void test_Frame(void) IDirect3DRMLight *light1; IDirect3DRMLight *light_tmp; IDirect3DRMLightArray *light_array; + ULONG ref, ref2; D3DCOLOR color; DWORD count; hr = Direct3DRMCreate(&d3drm); ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr); + ref = get_refcount((IUnknown *)d3drm); hr = IDirect3DRM_CreateFrame(d3drm, NULL, &pFrameC); ok(hr == D3DRM_OK, "Cannot get IDirect3DRMFrame interface (hr = %x)\n", hr); CHECK_REFCOUNT(pFrameC, 1); + ref2 = get_refcount((IUnknown *)d3drm); + ok(ref2 > ref, "Expected d3drm object to be referenced.\n"); test_class_name((IDirect3DRMObject *)pFrameC, "Frame"); @@ -1396,6 +1400,9 @@ static void test_object(void) { &CLSID_CDirect3DRMMeshBuilder, &IID_IDirect3DRMMeshBuilder }, { &CLSID_CDirect3DRMMeshBuilder, &IID_IDirect3DRMMeshBuilder2 }, { &CLSID_CDirect3DRMMeshBuilder, &IID_IDirect3DRMMeshBuilder3 }, + { &CLSID_CDirect3DRMFrame, &IID_IDirect3DRMFrame }, + { &CLSID_CDirect3DRMFrame, &IID_IDirect3DRMFrame2 }, + { &CLSID_CDirect3DRMFrame, &IID_IDirect3DRMFrame3 }, }; IDirect3DRM *d3drm1; IDirect3DRM2 *d3drm2; @@ -1419,7 +1426,8 @@ static void test_object(void) for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i) { - BOOL takes_ref = IsEqualGUID(tests[i].clsid, &CLSID_CDirect3DRMMeshBuilder); + BOOL takes_ref = IsEqualGUID(tests[i].clsid, &CLSID_CDirect3DRMMeshBuilder) || + IsEqualGUID(tests[i].clsid, &CLSID_CDirect3DRMFrame); unknown = (IUnknown *)0xdeadbeef; hr = IDirect3DRM_CreateObject(d3drm1, NULL, NULL, tests[i].iid, (void **)&unknown); @@ -1439,7 +1447,7 @@ static void test_object(void) { ref2 = get_refcount((IUnknown *)d3drm1); if (takes_ref) - ok(ref2 == ref1 + 1, "Test %u: expected ref2 == ref1 + 1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2); + ok(ref2 > ref1, "Test %u: expected ref2 > ref1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2); else ok(ref2 == ref1, "Test %u: expected ref2 == ref1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2); @@ -1462,7 +1470,7 @@ static void test_object(void) ok(SUCCEEDED(hr), "Test %u: expected hr == D3DRM_OK, got %#x.\n", i, hr); ref2 = get_refcount((IUnknown *)d3drm1); if (takes_ref) - ok(ref2 == ref1 + 1, "Test %u: expected ref2 == ref1 + 1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2); + ok(ref2 > ref1, "Test %u: expected ref2 > ref1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2); else ok(ref2 == ref1, "Test %u: expected ref2 == ref1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2); ref3 = get_refcount((IUnknown *)d3drm2); @@ -1481,7 +1489,7 @@ static void test_object(void) ok(SUCCEEDED(hr), "Test %u: expected hr == D3DRM_OK, got %#x.\n", i, hr); ref2 = get_refcount((IUnknown *)d3drm1); if (takes_ref) - ok(ref2 == ref1 + 1, "Test %u: expected ref2 == ref1 + 1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2); + ok(ref2 > ref1, "Test %u: expected ref2 > ref1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2); else ok(ref2 == ref1, "Test %u: expected ref2 == ref1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2); ref3 = get_refcount((IUnknown *)d3drm2); @@ -2019,8 +2027,7 @@ static void test_Viewport(void) IDirect3DRMDevice3_Release(device3); IDirect3DRMDevice_Release(device1); ref4 = get_refcount((IUnknown *)d3drm1); - todo_wine ok(ref4 > initial_ref1, "Expected ref4 > initial_ref1, got initial_ref1 = %u, ref4 = %u.\n", initial_ref1, - ref4); + ok(ref4 > initial_ref1, "Expected ref4 > initial_ref1, got initial_ref1 = %u, ref4 = %u.\n", initial_ref1, ref4); ref4 = get_refcount((IUnknown *)d3drm2); ok(ref4 == initial_ref2, "Expected ref4 == initial_ref2, got initial_ref2 = %u, ref4 = %u.\n", initial_ref2, ref4); ref4 = get_refcount((IUnknown *)d3drm3); @@ -2032,8 +2039,7 @@ static void test_Viewport(void) IDirect3DRMFrame3_Release(frame3); ref4 = get_refcount((IUnknown *)d3drm1); - todo_wine ok(ref4 > initial_ref1, "Expected ref4 > initial_ref1, got initial_ref1 = %u, ref4 = %u.\n", initial_ref1, - ref4); + ok(ref4 > initial_ref1, "Expected ref4 > initial_ref1, got initial_ref1 = %u, ref4 = %u.\n", initial_ref1, ref4); ref4 = get_refcount((IUnknown *)d3drm2); ok(ref4 == initial_ref2, "Expected ref4 == initial_ref2, got initial_ref2 = %u, ref4 = %u.\n", initial_ref2, ref4); ref4 = get_refcount((IUnknown *)d3drm3);