[PATCH 1/2] d3drm: Implement IDirect3DRMFrameX_GetParent and update tests. (try 3)

Christian Costa titan.costa at gmail.com
Thu May 3 02:19:37 CDT 2012


Try 3: Update with current Visual tests.
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 |   58 +++++++++++++++++-----------------
 2 files changed, 96 insertions(+), 41 deletions(-)

diff --git a/dlls/d3drm/frame.c b/dlls/d3drm/frame.c
index 8e74264..9276f80 100644
--- a/dlls/d3drm/frame.c
+++ b/dlls/d3drm/frame.c
@@ -30,10 +30,13 @@
 
 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;
@@ -43,7 +46,7 @@ typedef struct {
     ULONG nb_lights;
     ULONG lights_capacity;
     IDirect3DRMLight** lights;
-} IDirect3DRMFrameImpl;
+};
 
 static inline IDirect3DRMFrameImpl *impl_from_IDirect3DRMFrame2(IDirect3DRMFrame2 *iface)
 {
@@ -56,6 +59,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,
@@ -333,9 +337,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,
@@ -1065,22 +1082,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)
         {
@@ -1102,6 +1130,7 @@ static HRESULT WINAPI IDirect3DRMFrame3Impl_AddChild(IDirect3DRMFrame3* iface,
 
     This->children[This->nb_children++] = child;
     IDirect3DRMFrame3_AddRef(child);
+    child_obj->parent = This;
 
     return D3DRM_OK;
 }
@@ -1294,9 +1323,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,
@@ -1440,11 +1482,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 */
@@ -1457,6 +1500,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;
@@ -2118,6 +2162,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 783b7c2..64219d0 100644
--- a/dlls/d3drm/tests/d3drm.c
+++ b/dlls/d3drm/tests/d3drm.c
@@ -442,10 +442,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;
@@ -467,7 +469,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 */
@@ -482,8 +484,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);
@@ -506,9 +508,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);
@@ -516,7 +518,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);
@@ -547,15 +549,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);
@@ -574,7 +576,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);
@@ -591,17 +593,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);
@@ -624,11 +626,11 @@ static void test_Frame(void)
     /* [Add/Delete]Visual with NULL pointer */
     hr = IDirect3DRMFrame_AddVisual(pFrameP1, NULL);
     ok(hr == D3DRMERR_BADOBJECT, "Should have returned D3DRMERR_BADOBJECT (hr = %x)\n", hr);
-    todo_wine CHECK_REFCOUNT(pFrameP1, 3);
+    CHECK_REFCOUNT(pFrameP1, 3);
 
     hr = IDirect3DRMFrame_DeleteVisual(pFrameP1, NULL);
     ok(hr == D3DRMERR_BADOBJECT, "Should have returned D3DRMERR_BADOBJECT (hr = %x)\n", hr);
-    todo_wine CHECK_REFCOUNT(pFrameP1, 3);
+    CHECK_REFCOUNT(pFrameP1, 3);
 
     /* Create Visual */
     hr = IDirect3DRM_CreateMeshBuilder(pD3DRM, &pMeshBuilder);
@@ -638,7 +640,7 @@ static void test_Frame(void)
     /* Add Visual to first parent */
     hr = IDirect3DRMFrame_AddVisual(pFrameP1, pVisual1);
     ok(hr == D3DRM_OK, "Cannot add visual (hr = %x)\n", hr);
-    todo_wine CHECK_REFCOUNT(pFrameP1, 3);
+    CHECK_REFCOUNT(pFrameP1, 3);
     CHECK_REFCOUNT(pVisual1, 2);
 
     pVisualArray = NULL;
@@ -658,17 +660,17 @@ static void test_Frame(void)
     /* Delete Visual */
     hr = IDirect3DRMFrame_DeleteVisual(pFrameP1, pVisual1);
     ok(hr == D3DRM_OK, "Cannot delete visual (hr = %x)\n", hr);
-    todo_wine CHECK_REFCOUNT(pFrameP1, 3);
+    CHECK_REFCOUNT(pFrameP1, 3);
     IDirect3DRMMeshBuilder_Release(pMeshBuilder);
 
     /* [Add/Delete]Light with NULL pointer */
     hr = IDirect3DRMFrame_AddLight(pFrameP1, NULL);
     ok(hr == D3DRMERR_BADOBJECT, "Should have returned D3DRMERR_BADOBJECT (hr = %x)\n", hr);
-    todo_wine CHECK_REFCOUNT(pFrameP1, 3);
+    CHECK_REFCOUNT(pFrameP1, 3);
 
     hr = IDirect3DRMFrame_DeleteLight(pFrameP1, NULL);
     ok(hr == D3DRMERR_BADOBJECT, "Should have returned D3DRMERR_BADOBJECT (hr = %x)\n", hr);
-    todo_wine CHECK_REFCOUNT(pFrameP1, 3);
+    CHECK_REFCOUNT(pFrameP1, 3);
 
     /* Create Light */
     hr = IDirect3DRM_CreateLightRGB(pD3DRM, D3DRMLIGHT_SPOT, 0.1, 0.2, 0.3, &pLight1);
@@ -677,7 +679,7 @@ static void test_Frame(void)
     /* Add Light to first parent */
     hr = IDirect3DRMFrame_AddLight(pFrameP1, pLight1);
     ok(hr == D3DRM_OK, "Cannot add light (hr = %x)\n", hr);
-    todo_wine CHECK_REFCOUNT(pFrameP1, 3);
+    CHECK_REFCOUNT(pFrameP1, 3);
     CHECK_REFCOUNT(pLight1, 2);
 
     pLightArray = NULL;
@@ -697,13 +699,13 @@ static void test_Frame(void)
     /* Delete Light */
     hr = IDirect3DRMFrame_DeleteLight(pFrameP1, pLight1);
     ok(hr == D3DRM_OK, "Cannot delete light (hr = %x)\n", hr);
-    todo_wine CHECK_REFCOUNT(pFrameP1, 3);
+    CHECK_REFCOUNT(pFrameP1, 3);
     IDirect3DRMLight_Release(pLight1);
 
     /* Cleanup */
     IDirect3DRMFrame_Release(pFrameP2);
     CHECK_REFCOUNT(pFrameC, 2);
-    todo_wine CHECK_REFCOUNT(pFrameP1, 3);
+    CHECK_REFCOUNT(pFrameP1, 3);
 
     IDirect3DRMFrame_Release(pFrameC);
     IDirect3DRMFrame_Release(pFrameP1);




More information about the wine-patches mailing list