[PATCH 1/2] d3drm: Implement IDirect3DRMFrameX_GetParent and update tests. (try 2)
Christian Costa
titan.costa at gmail.com
Thu Apr 19 13:31:22 CDT 2012
Try 2: Store the parent as pointer on frame implementation rather than an IDirect3DRMFrame3 interface.
---
dlls/d3drm/frame.c | 79 ++++++++++++++++++++++++++++++++++++++--------
dlls/d3drm/tests/d3drm.c | 42 +++++++++++++-----------
2 files changed, 88 insertions(+), 33 deletions(-)
diff --git a/dlls/d3drm/frame.c b/dlls/d3drm/frame.c
index 55fa08b..e872f45 100644
--- a/dlls/d3drm/frame.c
+++ b/dlls/d3drm/frame.c
@@ -30,14 +30,17 @@
WINE_DEFAULT_DEBUG_CHANNEL(d3drm);
-typedef struct {
+typedef struct IDirect3DRMFrameImpl IDirect3DRMFrameImpl;
+
+struct IDirect3DRMFrameImpl {
IDirect3DRMFrame2 IDirect3DRMFrame2_iface;
IDirect3DRMFrame3 IDirect3DRMFrame3_iface;
LONG ref;
+ IDirect3DRMFrameImpl* parent;
ULONG nb_children;
ULONG children_capacity;
IDirect3DRMFrame3** children;
-} IDirect3DRMFrameImpl;
+};
static inline IDirect3DRMFrameImpl *impl_from_IDirect3DRMFrame2(IDirect3DRMFrame2 *iface)
{
@@ -50,6 +53,7 @@ static inline IDirect3DRMFrameImpl *impl_from_IDirect3DRMFrame3(IDirect3DRMFrame
}
static inline IDirect3DRMFrameImpl *unsafe_impl_from_IDirect3DRMFrame2(IDirect3DRMFrame2 *iface);
+static inline IDirect3DRMFrameImpl *unsafe_impl_from_IDirect3DRMFrame3(IDirect3DRMFrame3 *iface);
/*** IUnknown methods ***/
static HRESULT WINAPI IDirect3DRMFrame2Impl_QueryInterface(IDirect3DRMFrame2* iface,
@@ -327,9 +331,22 @@ static HRESULT WINAPI IDirect3DRMFrame2Impl_GetParent(IDirect3DRMFrame2* iface,
{
IDirect3DRMFrameImpl *This = impl_from_IDirect3DRMFrame2(iface);
- FIXME("(%p/%p)->(%p): stub\n", iface, This, frame);
+ TRACE("(%p/%p)->(%p)\n", iface, This, frame);
- return E_NOTIMPL;
+ if (!frame)
+ return D3DRMERR_BADVALUE;
+
+ if (This->parent)
+ {
+ *frame = (LPDIRECT3DRMFRAME)&This->parent->IDirect3DRMFrame2_iface;
+ IDirect3DRMFrame_AddRef(*frame);
+ }
+ else
+ {
+ *frame = NULL;
+ }
+
+ return D3DRM_OK;
}
static HRESULT WINAPI IDirect3DRMFrame2Impl_GetPosition(IDirect3DRMFrame2* iface,
@@ -1059,22 +1076,33 @@ static HRESULT WINAPI IDirect3DRMFrame3Impl_AddChild(IDirect3DRMFrame3* iface,
LPDIRECT3DRMFRAME3 child)
{
IDirect3DRMFrameImpl *This = impl_from_IDirect3DRMFrame3(iface);
- ULONG i;
- IDirect3DRMFrame3** children;
+ IDirect3DRMFrameImpl *child_obj = unsafe_impl_from_IDirect3DRMFrame3(child);
TRACE("(%p/%p)->(%p)\n", iface, This, child);
- if (!child)
+ if (!child_obj)
return D3DRMERR_BADOBJECT;
- /* Check if already existing and return gracefully without increasing ref count */
- for (i = 0; i < This->nb_children; i++)
- if (This->children[i] == child)
+ if (child_obj->parent)
+ {
+ IDirect3DRMFrame3* parent = &child_obj->parent->IDirect3DRMFrame3_iface;
+
+ if (parent == iface)
+ {
+ /* Passed frame is already a child so return success */
return D3DRM_OK;
+ }
+ else
+ {
+ /* Remove parent and continue */
+ IDirect3DRMFrame3_DeleteChild(parent, child);
+ }
+ }
if ((This->nb_children + 1) > This->children_capacity)
{
ULONG new_capacity;
+ IDirect3DRMFrame3** children;
if (!This->children_capacity)
{
@@ -1096,6 +1124,7 @@ static HRESULT WINAPI IDirect3DRMFrame3Impl_AddChild(IDirect3DRMFrame3* iface,
This->children[This->nb_children++] = child;
IDirect3DRMFrame3_AddRef(child);
+ child_obj->parent = This;
return D3DRM_OK;
}
@@ -1218,9 +1247,22 @@ static HRESULT WINAPI IDirect3DRMFrame3Impl_GetParent(IDirect3DRMFrame3* iface,
{
IDirect3DRMFrameImpl *This = impl_from_IDirect3DRMFrame3(iface);
- FIXME("(%p/%p)->(%p): stub\n", iface, This, frame);
+ TRACE("(%p/%p)->(%p)\n", iface, This, frame);
- return E_NOTIMPL;
+ if (!frame)
+ return D3DRMERR_BADVALUE;
+
+ if (This->parent)
+ {
+ *frame = &This->parent->IDirect3DRMFrame3_iface;
+ IDirect3DRMFrame_AddRef(*frame);
+ }
+ else
+ {
+ *frame = NULL;
+ }
+
+ return D3DRM_OK;
}
static HRESULT WINAPI IDirect3DRMFrame3Impl_GetPosition(IDirect3DRMFrame3* iface,
@@ -1364,11 +1406,12 @@ static HRESULT WINAPI IDirect3DRMFrame3Impl_DeleteChild(IDirect3DRMFrame3* iface
LPDIRECT3DRMFRAME3 frame)
{
IDirect3DRMFrameImpl *This = impl_from_IDirect3DRMFrame3(iface);
+ IDirect3DRMFrameImpl *frame_obj = unsafe_impl_from_IDirect3DRMFrame3(frame);
ULONG i;
TRACE("(%p/%p)->(%p)\n", iface, This, frame);
- if (!frame)
+ if (!frame_obj)
return D3DRMERR_BADOBJECT;
/* Check if child exists */
@@ -1381,6 +1424,7 @@ static HRESULT WINAPI IDirect3DRMFrame3Impl_DeleteChild(IDirect3DRMFrame3* iface
memmove(This->children + i, This->children + i + 1, sizeof(IDirect3DRMFrame3*) * (This->nb_children - 1 - i));
IDirect3DRMFrame3_Release(frame);
+ frame_obj->parent = NULL;
This->nb_children--;
return D3DRM_OK;
@@ -2010,6 +2054,15 @@ static inline IDirect3DRMFrameImpl *unsafe_impl_from_IDirect3DRMFrame2(IDirect3D
return impl_from_IDirect3DRMFrame2(iface);
}
+static inline IDirect3DRMFrameImpl *unsafe_impl_from_IDirect3DRMFrame3(IDirect3DRMFrame3 *iface)
+{
+ if (!iface)
+ return NULL;
+ assert(iface->lpVtbl == &Direct3DRMFrame3_Vtbl);
+
+ return impl_from_IDirect3DRMFrame3(iface);
+}
+
HRESULT Direct3DRMFrame_create(REFIID riid, IUnknown** ppObj)
{
IDirect3DRMFrameImpl* object;
diff --git a/dlls/d3drm/tests/d3drm.c b/dlls/d3drm/tests/d3drm.c
index 91e1c76..ddd152a 100644
--- a/dlls/d3drm/tests/d3drm.c
+++ b/dlls/d3drm/tests/d3drm.c
@@ -416,10 +416,12 @@ static void test_Frame(void)
ok(hr == D3DRM_OK, "Cannot get IDirect3DRMFrame interface (hr = %x)\n", hr);
CHECK_REFCOUNT(pFrameC, 1);
+ hr = IDirect3DRMFrame_GetParent(pFrameC, NULL);
+ ok(hr == D3DRMERR_BADVALUE, "Should fail and return D3DRM_BADVALUE (hr = %x)\n", hr);
pFrameTmp = (void*)0xdeadbeef;
hr = IDirect3DRMFrame_GetParent(pFrameC, &pFrameTmp);
- todo_wine ok(hr == D3DRM_OK, "Cannot get parent frame (hr = %x)\n", hr);
- todo_wine ok(pFrameTmp == NULL, "pFrameTmp = %p\n", pFrameTmp);
+ ok(hr == D3DRM_OK, "Cannot get parent frame (hr = %x)\n", hr);
+ ok(pFrameTmp == NULL, "pFrameTmp = %p\n", pFrameTmp);
CHECK_REFCOUNT(pFrameC, 1);
pArray = NULL;
@@ -441,7 +443,7 @@ static void test_Frame(void)
/* GetParent with NULL pointer */
hr = IDirect3DRMFrame_GetParent(pFrameP1, NULL);
- todo_wine ok(hr == D3DRMERR_BADVALUE, "Should have returned D3DRMERR_BADVALUE (hr = %x)\n", hr);
+ ok(hr == D3DRMERR_BADVALUE, "Should have returned D3DRMERR_BADVALUE (hr = %x)\n", hr);
CHECK_REFCOUNT(pFrameP1, 1);
/* [Add/Delete]Child with NULL pointer */
@@ -456,8 +458,8 @@ static void test_Frame(void)
/* Add child to first parent */
pFrameTmp = (void*)0xdeadbeef;
hr = IDirect3DRMFrame_GetParent(pFrameP1, &pFrameTmp);
- todo_wine ok(hr == D3DRM_OK, "Cannot get parent frame (hr = %x)\n", hr);
- todo_wine ok(pFrameTmp == NULL, "pFrameTmp = %p\n", pFrameTmp);
+ ok(hr == D3DRM_OK, "Cannot get parent frame (hr = %x)\n", hr);
+ ok(pFrameTmp == NULL, "pFrameTmp = %p\n", pFrameTmp);
hr = IDirect3DRMFrame_AddChild(pFrameP1, pFrameC);
ok(hr == D3DRM_OK, "Cannot add child frame (hr = %x)\n", hr);
@@ -480,9 +482,9 @@ static void test_Frame(void)
pFrameTmp = (void*)0xdeadbeef;
hr = IDirect3DRMFrame_GetParent(pFrameC, &pFrameTmp);
- todo_wine ok(hr == D3DRM_OK, "Cannot get parent frame (hr = %x)\n", hr);
- todo_wine ok(pFrameTmp == pFrameP1, "pFrameTmp = %p\n", pFrameTmp);
- todo_wine CHECK_REFCOUNT(pFrameP1, 2);
+ ok(hr == D3DRM_OK, "Cannot get parent frame (hr = %x)\n", hr);
+ ok(pFrameTmp == pFrameP1, "pFrameTmp = %p\n", pFrameTmp);
+ CHECK_REFCOUNT(pFrameP1, 2);
/* Add child to second parent */
hr = IDirect3DRM_CreateFrame(pD3DRM, NULL, &pFrameP2);
@@ -490,7 +492,7 @@ static void test_Frame(void)
hr = IDirect3DRMFrame_AddChild(pFrameP2, pFrameC);
ok(hr == D3DRM_OK, "Cannot add child frame (hr = %x)\n", hr);
- todo_wine CHECK_REFCOUNT(pFrameC, 2);
+ CHECK_REFCOUNT(pFrameC, 2);
pArray = NULL;
hr = IDirect3DRMFrame_GetChildren(pFrameP2, &pArray);
@@ -521,15 +523,15 @@ static void test_Frame(void)
pFrameTmp = (void*)0xdeadbeef;
hr = IDirect3DRMFrame_GetParent(pFrameC, &pFrameTmp);
- todo_wine ok(hr == D3DRM_OK, "Cannot get parent frame (hr = %x)\n", hr);
- todo_wine ok(pFrameTmp == pFrameP2, "pFrameTmp = %p\n", pFrameTmp);
- todo_wine CHECK_REFCOUNT(pFrameP2, 2);
- todo_wine CHECK_REFCOUNT(pFrameC, 2);
+ ok(hr == D3DRM_OK, "Cannot get parent frame (hr = %x)\n", hr);
+ ok(pFrameTmp == pFrameP2, "pFrameTmp = %p\n", pFrameTmp);
+ CHECK_REFCOUNT(pFrameP2, 2);
+ CHECK_REFCOUNT(pFrameC, 2);
/* Add child again */
hr = IDirect3DRMFrame_AddChild(pFrameP2, pFrameC);
ok(hr == D3DRM_OK, "Cannot add child frame (hr = %x)\n", hr);
- todo_wine CHECK_REFCOUNT(pFrameC, 2);
+ CHECK_REFCOUNT(pFrameC, 2);
pArray = NULL;
hr = IDirect3DRMFrame_GetChildren(pFrameP2, &pArray);
@@ -548,7 +550,7 @@ static void test_Frame(void)
/* Delete child */
hr = IDirect3DRMFrame_DeleteChild(pFrameP2, pFrameC);
ok(hr == D3DRM_OK, "Cannot delete child frame (hr = %x)\n", hr);
- todo_wine CHECK_REFCOUNT(pFrameC, 1);
+ CHECK_REFCOUNT(pFrameC, 1);
pArray = NULL;
hr = IDirect3DRMFrame_GetChildren(pFrameP2, &pArray);
@@ -565,17 +567,17 @@ static void test_Frame(void)
pFrameTmp = (void*)0xdeadbeef;
hr = IDirect3DRMFrame_GetParent(pFrameC, &pFrameTmp);
- todo_wine ok(hr == D3DRM_OK, "Cannot get parent frame (hr = %x)\n", hr);
- todo_wine ok(pFrameTmp == NULL, "pFrameTmp = %p\n", pFrameTmp);
+ ok(hr == D3DRM_OK, "Cannot get parent frame (hr = %x)\n", hr);
+ ok(pFrameTmp == NULL, "pFrameTmp = %p\n", pFrameTmp);
/* Add two children */
hr = IDirect3DRMFrame_AddChild(pFrameP2, pFrameC);
ok(hr == D3DRM_OK, "Cannot add child frame (hr = %x)\n", hr);
- todo_wine CHECK_REFCOUNT(pFrameC, 2);
+ CHECK_REFCOUNT(pFrameC, 2);
hr = IDirect3DRMFrame_AddChild(pFrameP2, pFrameP1);
ok(hr == D3DRM_OK, "Cannot add child frame (hr = %x)\n", hr);
- todo_wine CHECK_REFCOUNT(pFrameP1, 3);
+ CHECK_REFCOUNT(pFrameP1, 3);
pArray = NULL;
hr = IDirect3DRMFrame_GetChildren(pFrameP2, &pArray);
@@ -597,7 +599,7 @@ static void test_Frame(void)
IDirect3DRMMeshBuilder_Release(pFrameP2);
CHECK_REFCOUNT(pFrameC, 2);
- todo_wine CHECK_REFCOUNT(pFrameP1, 3);
+ CHECK_REFCOUNT(pFrameP1, 3);
IDirect3DRMMeshBuilder_Release(pFrameC);
IDirect3DRMMeshBuilder_Release(pFrameP1);
More information about the wine-patches
mailing list