Ejemplo n.º 1
0
int directdraw_uninit(void)
{
	if(!video_window) return 0;

	if(!lpDDS) return 0;

	KillTimer(video_window, 131);

    if(lpDDS_secondary) IDirectDrawSurface2_Release(lpDDS_secondary);
	if(lpDDS)           IDirectDrawSurface2_Release(lpDDS);
	if(surface_osd)     IDirectDrawSurface2_Release(surface_osd);
	if(lpDD)            IDirectDraw2_RestoreDisplayMode(lpDD);
	if(lpDD)            IDirectDraw2_SetCooperativeLevel(lpDD, video_window, DDSCL_NORMAL);
	if(lpDD)            IDirectDraw2_Release(lpDD);
	if(video_window)    DestroyWindow(video_window);
	if(library)         FreeLibrary(library);
	
	library         = 0;
	lpDD            = 0;
	lpDDS           = 0;
	lpDDS_secondary = 0;
	surface_osd     = 0;

	video_window    = 0;
	return 1;
}
Ejemplo n.º 2
0
static void
winFreeFBPrimaryDD(ScreenPtr pScreen)
{
    winScreenPriv(pScreen);
    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;

    /* Free the offscreen surface, if there is one */
    if (pScreenPriv->pddsOffscreen) {
        IDirectDrawSurface2_Unlock(pScreenPriv->pddsOffscreen, NULL);
        IDirectDrawSurface2_Release(pScreenPriv->pddsOffscreen);
        pScreenPriv->pddsOffscreen = NULL;
    }

    /* Release the primary surface, if there is one */
    if (pScreenPriv->pddsPrimary) {
        IDirectDrawSurface2_Unlock(pScreenPriv->pddsPrimary, NULL);
        IDirectDrawSurface2_Release(pScreenPriv->pddsPrimary);
        pScreenPriv->pddsPrimary = NULL;
    }

    /* Free the DirectDraw object, if there is one */
    if (pScreenPriv->pdd) {
        IDirectDraw2_RestoreDisplayMode(pScreenPriv->pdd);
        IDirectDraw2_Release(pScreenPriv->pdd);
        pScreenPriv->pdd = NULL;
    }

    /* Invalidate the ScreenInfo's fb pointer */
    pScreenInfo->pfb = NULL;
}
Ejemplo n.º 3
0
/* uninitialize DirectX */
static void DeInitDD(void)
{
    if (captured)
	ReleaseCapture(), captured = 0;	// free mouse

    // free DirectX objects
    if (lpSurfaces[0])
	IDirectDrawSurface_Release(lpSurfaces[0]);
    lpSurfaces[0] = NULL;
    if (BackSurface[0])
	IDirectDrawSurface_Release(BackSurface[0]);
    BackSurface[0] = NULL;
    if (BackSurface[1])
	IDirectDrawSurface_Release(BackSurface[1]);
    BackSurface[1] = NULL;
    if (dxPalette)
	IDirectDrawPalette_Release(dxPalette);
    dxPalette = NULL;
    if (lpDD2)
	IDirectDraw2_Release(lpDD2);
    lpDD2 = NULL;
    if (lpDD)
	IDirectDraw_Release(lpDD);
    lpDD = NULL;
    DeInitWindow();
    if (hModule != NULL)
	FreeLibrary(hModule), hModule = NULL;
    hWnd = NULL;
    directX = 0;
}
Ejemplo n.º 4
0
//
// Free all memory
//
VOID CloseDirectDraw (VOID)
{
	ReleaseChtuff();
	if (DDr2)
	{
		IDirectDraw2_Release(DDr2);
		DDr2 = NULL;
	}
	UnLoadDirectDraw();
}
Ejemplo n.º 5
0
static void DirectXCloseDDraw(vout_display_t *vd)
{
    vout_display_sys_t *sys = vd->sys;
    if (sys->ddobject)
        IDirectDraw2_Release(sys->ddobject);

    sys->ddobject = NULL;

    free(sys->display_driver);
    sys->display_driver = NULL;

    sys->hmonitor = NULL;
}
Ejemplo n.º 6
0
static void
winFreeFBShadowDD (ScreenPtr pScreen)
{
  winScreenPriv(pScreen);
  winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;

  /* Free the shadow surface, if there is one */
  if (pScreenPriv->pddsShadow)
    {
      IDirectDrawSurface2_Unlock (pScreenPriv->pddsShadow, NULL);
      IDirectDrawSurface2_Release (pScreenPriv->pddsShadow);
      pScreenPriv->pddsShadow = NULL;
    }

  /* Detach the clipper from the primary surface and release the primary surface, if there is one */
  winReleasePrimarySurfaceShadowDD(pScreen);

  /* Release the clipper object */
  if (pScreenPriv->pddcPrimary)
    {
      IDirectDrawClipper_Release (pScreenPriv->pddcPrimary);
      pScreenPriv->pddcPrimary = NULL;
    }

  /* Free the DirectDraw2 object, if there is one */
  if (pScreenPriv->pdd2)
    {
      IDirectDraw2_RestoreDisplayMode (pScreenPriv->pdd2);
      IDirectDraw2_Release (pScreenPriv->pdd2);
      pScreenPriv->pdd2 = NULL;
    }

  /* Free the DirectDraw object, if there is one */
  if (pScreenPriv->pdd)
    {
      IDirectDraw_Release (pScreenPriv->pdd);
      pScreenPriv->pdd = NULL;
    }

  /* Invalidate the ScreenInfo's fb pointer */
  pScreenInfo->pfb = NULL;
}
Ejemplo n.º 7
0
static Bool
winCloseScreenShadowDD (int nIndex, ScreenPtr pScreen)
{
  winScreenPriv(pScreen);
  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
  Bool			fReturn;
  
#if CYGDEBUG
  winDebug ("winCloseScreenShadowDD - Freeing screen resources\n");
#endif

  /* Flag that the screen is closed */
  pScreenPriv->fClosed = TRUE;
  pScreenPriv->fActive = FALSE;

  /* Call the wrapped CloseScreen procedure */
  WIN_UNWRAP(CloseScreen);
  fReturn = (*pScreen->CloseScreen) (nIndex, pScreen);

  /* Free the screen DC */
  ReleaseDC (pScreenPriv->hwndScreen, pScreenPriv->hdcScreen);

  /* Delete the window property */
  RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP);

  /* Free the shadow surface, if there is one */
  if (pScreenPriv->pddsShadow)
    {
      IDirectDrawSurface2_Unlock (pScreenPriv->pddsShadow, NULL);
      IDirectDrawSurface2_Release (pScreenPriv->pddsShadow);
      pScreenPriv->pddsShadow = NULL;
    }

  /* Detach the clipper from the primary surface and release the clipper. */
  if (pScreenPriv->pddcPrimary)
    {
      /* Detach the clipper */
      IDirectDrawSurface2_SetClipper (pScreenPriv->pddsPrimary,
				      NULL);

      /* Release the clipper object */
      IDirectDrawClipper_Release (pScreenPriv->pddcPrimary);
      pScreenPriv->pddcPrimary = NULL;
    }

  /* Release the primary surface, if there is one */
  if (pScreenPriv->pddsPrimary)
    {
      IDirectDrawSurface2_Release (pScreenPriv->pddsPrimary);
      pScreenPriv->pddsPrimary = NULL;
    }

  /* Free the DirectDraw2 object, if there is one */
  if (pScreenPriv->pdd2)
    {
      IDirectDraw2_RestoreDisplayMode (pScreenPriv->pdd2);
      IDirectDraw2_Release (pScreenPriv->pdd2);
      pScreenPriv->pdd2 = NULL;
    }

  /* Free the DirectDraw object, if there is one */
  if (pScreenPriv->pdd)
    {
      IDirectDraw_Release (pScreenPriv->pdd);
      pScreenPriv->pdd = NULL;
    }

  /* Delete tray icon, if we have one */
  if (!pScreenInfo->fNoTrayIcon)
    winDeleteNotifyIcon (pScreenPriv);
  
  /* Free the exit confirmation dialog box, if it exists */
  if (g_hDlgExit != NULL)
    {
      DestroyWindow (g_hDlgExit);
      g_hDlgExit = NULL;
    }

  /* Kill our window */
  if (pScreenPriv->hwndScreen)
    {
      DestroyWindow (pScreenPriv->hwndScreen);
      pScreenPriv->hwndScreen = NULL;
    }

#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
  /* Destroy the thread startup mutex */
  pthread_mutex_destroy (&pScreenPriv->pmServerStarted);
#endif

  /* Kill our screeninfo's pointer to the screen */
  pScreenInfo->pScreen = NULL;

  /* Invalidate the ScreenInfo's fb pointer */
  pScreenInfo->pfb = NULL;

  /* Free the screen privates for this screen */
  free ((pointer) pScreenPriv);

  return fReturn;
}
Ejemplo n.º 8
0
Bool
winCloseScreenPrimaryDD (int nIndex, ScreenPtr pScreen)
{
  winScreenPriv(pScreen);
  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
  Bool			fReturn;
  
  ErrorF ("winCloseScreenPrimaryDD - Freeing screen resources\n");

  /* Flag that the screen is closed */
  pScreenPriv->fClosed = TRUE;
  pScreenPriv->fActive = FALSE;

  /* Call the wrapped CloseScreen procedure */
  pScreen->CloseScreen = pScreenPriv->CloseScreen;
  fReturn = (*pScreen->CloseScreen) (nIndex, pScreen);

  /* Delete the window property */
  RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP);

  /* Free the offscreen surface, if there is one */
  if (pScreenPriv->pddsOffscreen)
    {
      IDirectDrawSurface2_Unlock (pScreenPriv->pddsOffscreen, NULL);
      IDirectDrawSurface2_Release (pScreenPriv->pddsOffscreen);
      pScreenPriv->pddsOffscreen = NULL;
    }

  /* Release the primary surface, if there is one */
  if (pScreenPriv->pddsPrimary)
    {
      IDirectDrawSurface2_Unlock (pScreenPriv->pddsPrimary, NULL);
      IDirectDrawSurface2_Release (pScreenPriv->pddsPrimary);
      pScreenPriv->pddsPrimary = NULL;
    }

  /* Free the DirectDraw object, if there is one */
  if (pScreenPriv->pdd)
    {
      IDirectDraw2_RestoreDisplayMode (pScreenPriv->pdd);
      IDirectDraw2_Release (pScreenPriv->pdd);
      pScreenPriv->pdd = NULL;
    }

  /* Kill our window */
  if (pScreenPriv->hwndScreen)
    {
      DestroyWindow (pScreenPriv->hwndScreen);
      pScreenPriv->hwndScreen = NULL;
    }

  /* Kill our screeninfo's pointer to the screen */
  pScreenInfo->pScreen = NULL;

  /* Invalidate the ScreenInfo's fb pointer */
  pScreenInfo->pfb = NULL;

  /* Free the screen privates for this screen */
  free ((pointer) pScreenPriv);

  return fReturn;
}
Ejemplo n.º 9
0
void
GGI_directx_DDShutdown(directx_priv *priv)
{
	void *res;

	/* kill the timer callback */
	if (priv->timer_id)
		KillTimer(priv->hWnd, priv->timer_id);

	/* destroy the window and the surface */
	if (priv->hWnd && !priv->hParent) {
		DPRINT("End session\n");
		PostThreadMessage(priv->nThreadID, WM_DDEND, 0, 0);
	}
	DDDestroySurface(priv);

	if (priv->lpddext != NULL) {
		IDirectDraw2_Release(priv->lpddext);
		priv->lpddext = NULL;
	}
	if (priv->lpdd != NULL) {
		IDirectDraw_Release(priv->lpdd);
		priv->lpdd = NULL;
	}

#ifdef __CYGWIN__
	DPRINT("Join helper thread\n");
	if (priv->hThread &&
	    pthread_join((pthread_t)priv->hThread, &res))
	{
		DPRINT("Failed to join helper thread\n");
	}
#else
	/* stop the event loop */
	if (priv->hThread &&
	    WaitForSingleObject(priv->hThread, 2000) != WAIT_OBJECT_0) {
		/* asta la vista, baby */
		DPRINT("Terminating helper thread harshly\n");
		TerminateThread(priv->hThread, 0);
	}
	if (priv->hThread)
		CloseHandle(priv->hThread);
#endif

	/* Get rid of the window class if we registered it */
	if (priv->wndclass)
		UnregisterClass((LPCTSTR)(INT_PTR)priv->wndclass,
			priv->hInstance);

	/* get rid of the cursor if we created one */
	if (priv->hCursor)
		DestroyCursor(priv->hCursor);

	if (priv->hInit)
		CloseHandle(priv->hInit);

	priv->hWnd = NULL;
	priv->wndclass = 0;
	priv->hThread = NULL;
	priv->nThreadID = 0;
	priv->hCursor = NULL;
	priv->hInit = NULL;
	priv->timer_id = 0;
}
Ejemplo n.º 10
0
static void test_ddraw_objects(void)
{
    HRESULT hr;
    unsigned long ref;
    IDirectDraw7 *DDraw7;
    IDirectDraw4 *DDraw4;
    IDirectDraw2 *DDraw2;
    IDirectDraw  *DDraw1;
    IDirectDrawPalette *palette;
    IDirectDrawSurface7 *surface;
    IDirectDrawSurface *surface1;
    IDirectDrawSurface4 *surface4;
    PALETTEENTRY Table[256];
    DDSURFACEDESC2 ddsd;

    hr = pDirectDrawCreateEx(NULL, (void **) &DDraw7, &IID_IDirectDraw7, NULL);
    ok(hr == DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", hr);
    if(!DDraw7)
    {
        trace("Couldn't create DDraw interface, skipping tests\n");
        return;
    }

    hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirectDraw4, (void **) &DDraw4);
    ok(hr == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", hr);
    hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirectDraw2, (void **) &DDraw2);
    ok(hr == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", hr);
    hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirectDraw, (void **) &DDraw1);
    ok(hr == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", hr);

    ref = getRefcount( (IUnknown *) DDraw7);
    ok(ref == 1, "Got refcount %ld, expected 1\n", ref);

    /* Fails without a cooplevel */
    hr = IDirectDraw7_CreatePalette(DDraw7, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
    ok(hr == DDERR_NOCOOPERATIVELEVELSET, "CreatePalette returned %08x\n", hr);

    /* This check is before the cooplevel check */
    hr = IDirectDraw7_CreatePalette(DDraw7, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, (void *) 0xdeadbeef);
    ok(hr == CLASS_E_NOAGGREGATION, "CreatePalette returned %08x\n", hr);

    hr = IDirectDraw7_SetCooperativeLevel(DDraw7, 0, DDSCL_NORMAL);
    ok(hr == DD_OK, "SetCooperativeLevel failed with %08x\n", hr);

    memset(&ddsd, 0, sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);
    ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
    ddsd.dwWidth = 64;
    ddsd.dwHeight = 64;
    ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
    U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
    U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8 | DDPF_RGB;
    U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 8;

    hr = IDirectDraw7_CreateSurface(DDraw7, &ddsd, &surface, NULL);
    ok(hr == DD_OK, "CreateSurface failed with %08x\n", hr);

    /* DDraw refcount increased by 1 */
    ref = getRefcount( (IUnknown *) DDraw7);
    ok(ref == 2, "Got refcount %ld, expected 2\n", ref);

    /* Surface refcount starts with 1 */
    ref = getRefcount( (IUnknown *) surface);
    ok(ref == 1, "Got refcount %ld, expected 1\n", ref);

    hr = IDirectDraw7_CreatePalette(DDraw7, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
    ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);

    /* DDraw refcount increased by 1 */
    ref = getRefcount( (IUnknown *) DDraw7);
    ok(ref == 3, "Got refcount %ld, expected 3\n", ref);

    /* Palette starts with 1 */
    ref = getRefcount( (IUnknown *) palette);
    ok(ref == 1, "Got refcount %ld, expected 1\n", ref);

    /* Test attaching a palette to a surface */
    hr = IDirectDrawSurface7_SetPalette(surface, palette);
    ok(hr == DD_OK, "IDirectDrawSurface_SetPalette failed with %08x\n", hr);

    /* Palette refcount increased, surface stays the same */
    ref = getRefcount( (IUnknown *) palette);
    ok(ref == 2, "Got refcount %ld, expected 2\n", ref);
    ref = getRefcount( (IUnknown *) surface);
    ok(ref == 1, "Got refcount %ld, expected 1\n", ref);

    IDirectDrawSurface7_Release(surface);
    /* Increased before - decrease now */
    ref = getRefcount( (IUnknown *) DDraw7);
    ok(ref == 2, "Got refcount %ld, expected 2\n", ref);

    /* Releasing the surface detaches the palette */
    ref = getRefcount( (IUnknown *) palette);
    ok(ref == 1, "Got refcount %ld, expected 1\n", ref);

    IDirectDrawPalette_Release(palette);

    /* Increased before - decrease now */
    ref = getRefcount( (IUnknown *) DDraw7);
    ok(ref == 1, "Got refcount %ld, expected 1\n", ref);

    /* Not all interfaces are AddRefed when a palette is created */
    hr = IDirectDraw4_CreatePalette(DDraw4, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
    ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
    ref = getRefcount( (IUnknown *) DDraw4);
    ok(ref == 2, "Got refcount %ld, expected 2\n", ref);
    IDirectDrawPalette_Release(palette);

    /* No addref here */
    hr = IDirectDraw2_CreatePalette(DDraw2, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
    ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
    ref = getRefcount( (IUnknown *) DDraw2);
    ok(ref == 1, "Got refcount %ld, expected 1\n", ref);
    IDirectDrawPalette_Release(palette);

    /* No addref here */
    hr = IDirectDraw_CreatePalette(DDraw1, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
    ok(hr == DD_OK, "CreatePalette returned %08x\n", hr);
    ref = getRefcount( (IUnknown *) DDraw1);
    ok(ref == 1, "Got refcount %ld, expected 1\n", ref);
    IDirectDrawPalette_Release(palette);

    /* Similar for surfaces */
    hr = IDirectDraw4_CreateSurface(DDraw4, &ddsd, &surface4, NULL);
    ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
    ref = getRefcount( (IUnknown *) DDraw4);
    ok(ref == 2, "Got refcount %ld, expected 2\n", ref);
    IDirectDrawSurface4_Release(surface4);

    ddsd.dwSize = sizeof(DDSURFACEDESC);
    hr = IDirectDraw2_CreateSurface(DDraw2, (DDSURFACEDESC *) &ddsd, &surface1, NULL);
    ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
    ref = getRefcount( (IUnknown *) DDraw2);
    ok(ref == 1, "Got refcount %ld, expected 1\n", ref);
    IDirectDrawSurface_Release(surface1);

    hr = IDirectDraw_CreateSurface(DDraw1, (DDSURFACEDESC *) &ddsd, &surface1, NULL);
    ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
    ref = getRefcount( (IUnknown *) DDraw1);
    ok(ref == 1, "Got refcount %ld, expected 1\n", ref);
    IDirectDrawSurface_Release(surface1);

    IDirectDraw7_Release(DDraw7);
    IDirectDraw4_Release(DDraw4);
    IDirectDraw2_Release(DDraw2);
    IDirectDraw_Release(DDraw1);
}
Ejemplo n.º 11
0
static void test_d3d_ifaces(void)
{
    IDirectDraw *DDraw1;
    IDirectDraw2 *DDraw2;
    IDirectDraw4 *DDraw4;
    IDirect3D *D3D1;
    IDirect3D2 *D3D2;
    IDirect3D3 *D3D3;
    IDirect3D7 *D3D7;
    HRESULT hr;
    long ref;

    hr = DirectDrawCreate(NULL, &DDraw1, NULL);
    ok(hr == DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", hr);
    if(!DDraw1)
    {
        trace("DirectDrawCreate failed with %08x\n", hr);
        return;
    }

    hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirectDraw2, (void **) &DDraw2);
    ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
    hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirectDraw4, (void **) &DDraw4);
    ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);

    ref = getRefcount( (IUnknown *) DDraw4);
    ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref);
    ref = getRefcount( (IUnknown *) DDraw2);
    ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
    ref = getRefcount( (IUnknown *) DDraw1);
    ok(ref == 1, "IDirectDraw reference count is %ld\n", ref);

    hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirect3D, (void **) &D3D1);
    ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
    ref = getRefcount( (IUnknown *) DDraw4);
    ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref);
    ref = getRefcount( (IUnknown *) DDraw2);
    ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
    ref = getRefcount( (IUnknown *) DDraw1);
    ok(ref == 2, "IDirectDraw reference count is %ld\n", ref);
    IDirect3D_Release(D3D1);

    hr = IDirectDraw2_QueryInterface(DDraw2, &IID_IDirect3D2, (void **) &D3D2);
    ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
    ref = getRefcount( (IUnknown *) DDraw4);
    ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref);
    ref = getRefcount( (IUnknown *) DDraw2);
    ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
    ref = getRefcount( (IUnknown *) DDraw1);
    ok(ref == 2, "IDirectDraw reference count is %ld\n", ref);
    IDirect3D2_Release(D3D2);

    hr = IDirectDraw4_QueryInterface(DDraw4, &IID_IDirect3D3, (void **) &D3D3);
    ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
    ref = getRefcount( (IUnknown *) DDraw4);
    ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref);
    ref = getRefcount( (IUnknown *) DDraw2);
    ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
    ref = getRefcount( (IUnknown *) DDraw1);
    ok(ref == 2, "IDirectDraw reference count is %ld\n", ref);
    IDirect3D3_Release(D3D3);

    /* Try to AddRef the D3D3 interface that has been released already */
    IDirect3D3_AddRef(D3D3);
    ref = getRefcount( (IUnknown *) DDraw1);
    ok(ref == 2, "IDirectDraw reference count is %ld\n", ref);
    ref = getRefcount( (IUnknown *) D3D3);
    ok(ref == 2, "IDirect3D3 reference count is %ld\n", ref);
    /* The newer interfaces remain untouched */
    ref = getRefcount( (IUnknown *) DDraw4);
    ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref);
    ref = getRefcount( (IUnknown *) DDraw2);
    ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
    IDirect3D3_Release(D3D3);
    ref = getRefcount( (IUnknown *) DDraw1);
    ok(ref == 1, "IDirectDraw reference count is %ld\n", ref);
    ref = getRefcount( (IUnknown *) DDraw1);
    ok(ref == 1, "IDirectDraw reference count is %ld\n", ref);

    /* It is possible to query any IDirect3D interfaces from any IDirectDraw interface,
     * Except IDirect3D7, it can only be returned by IDirectDraw7(which can't return older ifaces)
     */
    hr = IDirectDraw_QueryInterface(DDraw2, &IID_IDirect3D, (void **) &D3D1);
    ok(hr == DD_OK, "IDirectDraw2_QueryInterface returned %08x\n", hr);
    IDirect3D_Release(D3D1);
    hr = IDirectDraw4_QueryInterface(DDraw4, &IID_IDirect3D, (void **) &D3D1);
    ok(hr == DD_OK, "IDirectDraw4_QueryInterface returned %08x\n", hr);
    IDirect3D_Release(D3D1);

    hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirect3D2, (void **) &D3D2);
    ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
    IDirect3D_Release(D3D2);
    hr = IDirectDraw4_QueryInterface(DDraw4, &IID_IDirect3D2, (void **) &D3D2);
    ok(hr == DD_OK, "IDirectDraw4_QueryInterface returned %08x\n", hr);
    IDirect3D_Release(D3D2);

    hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirect3D3, (void **) &D3D3);
    ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
    IDirect3D_Release(D3D3);
    hr = IDirectDraw2_QueryInterface(DDraw2, &IID_IDirect3D3, (void **) &D3D3);
    ok(hr == DD_OK, "IDirectDraw2_QueryInterface returned %08x\n", hr);
    IDirect3D_Release(D3D3);

    /* This does NOT work */
    hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirect3D7, (void **) &D3D7);
    todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw_QueryInterface returned %08x\n", hr);
    if(D3D7) IDirect3D_Release(D3D7);
    hr = IDirectDraw2_QueryInterface(DDraw2, &IID_IDirect3D7, (void **) &D3D7);
    todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw2_QueryInterface returned %08x\n", hr);
    if(D3D7) IDirect3D_Release(D3D7);
    hr = IDirectDraw4_QueryInterface(DDraw4, &IID_IDirect3D7, (void **) &D3D7);
    todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw4_QueryInterface returned %08x\n", hr);
    if(D3D7) IDirect3D_Release(D3D7);

    /* Release the interfaces */
    IDirectDraw4_Release(DDraw4);
    IDirectDraw2_Release(DDraw2);
    IDirectDraw_Release(DDraw1);
}
Ejemplo n.º 12
0
static void test_iface_refcnt(void)
{
    HRESULT hr;
    IDirectDraw  *DDraw1;
    IDirectDraw2 *DDraw2;
    IDirectDraw4 *DDraw4;
    IDirectDraw7 *DDraw7;
    IDirect3D7   *D3D7;
    IDirect3D3   *D3D3;
    IDirect3D2   *D3D2;
    IDirect3D    *D3D1;
    long ref;

    hr = pDirectDrawCreateEx(NULL, (void **) &DDraw7, &IID_IDirectDraw7, NULL);
    ok(hr == DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", hr);
    if(!DDraw7)
    {
        trace("Couldn't create DDraw interface, skipping tests\n");
        return;
    }

    ref = getRefcount( (IUnknown *) DDraw7);
    ok(ref == 1, "Initial IDirectDraw7 reference count is %ld\n", ref);

    hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirectDraw4, (void **) &DDraw4);
    ok(hr == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", hr);
    hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirectDraw2, (void **) &DDraw2);
    ok(hr == DD_OK, "IDirectDraw7_QueryInterf&ace returned %08x\n", hr);
    hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirectDraw, (void **) &DDraw1);
    ok(hr == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", hr);

    /* All interfaces now have refcount 1! */
    ref = getRefcount( (IUnknown *) DDraw7);
    ok(ref == 1, "IDirectDraw7 reference count is %ld\n", ref);
    ref = getRefcount( (IUnknown *) DDraw7);
    ok(ref == 1, "IDirectDraw7 reference count is %ld\n", ref);
    ref = getRefcount( (IUnknown *) DDraw4);
    ok(ref == 1, "IDirectDraw4 reference count is %ld\n", ref);
    ref = getRefcount( (IUnknown *) DDraw2);
    ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
    ref = getRefcount( (IUnknown *) DDraw1);
    ok(ref == 1, "IDirectDraw reference count is %ld\n", ref);

    hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirect3D7, (void **) &D3D7);
    ok(hr == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", hr);

    /* Apparently IDirectDrawX and IDirect3DX are linked together */
    ref = getRefcount( (IUnknown *) D3D7);
    ok(ref == 2, "IDirect3D7 reference count is %ld\n", ref);
    ref = getRefcount( (IUnknown *) DDraw7);
    ok(ref == 2, "IDirectDraw7 reference count is %ld\n", ref);

    IDirectDraw7_AddRef(DDraw7);
    ref = getRefcount( (IUnknown *) D3D7);
    ok(ref == 3, "IDirect3D7 reference count is %ld\n", ref);
    ref = getRefcount( (IUnknown *) DDraw7);
    ok(ref == 3, "IDirectDraw7 reference count is %ld\n", ref);

    IDirect3D7_Release(D3D7);
    ref = getRefcount( (IUnknown *) D3D7);
    ok(ref == 2, "IDirect3D7 reference count is %ld\n", ref);
    ref = getRefcount( (IUnknown *) DDraw7);
    ok(ref == 2, "IDirectDraw7 reference count is %ld\n", ref);

    /* Can't get older d3d interfaces. WHY????? */
    hr = IDirectDraw7_QueryInterface(DDraw4, &IID_IDirect3D3, (void **) &D3D3);
    todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw7_QueryInterface returned %08x\n", hr);
    if(hr == DD_OK && D3D3) IDirect3D3_Release(D3D3);

    hr = IDirectDraw4_QueryInterface(DDraw4, &IID_IDirect3D3, (void **) &D3D3);
    todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw4_QueryInterface returned %08x\n", hr);
    if(hr == DD_OK && D3D3) IDirect3D3_Release(D3D3);

    hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirect3D2, (void **) &D3D2);
    todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw7_QueryInterface returned %08x\n", hr);
    if(hr == DD_OK && D3D2) IDirect3D2_Release(D3D2);

    hr = IDirectDraw2_QueryInterface(DDraw2, &IID_IDirect3D2, (void **) &D3D2);
    todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw2_QueryInterface returned %08x\n", hr);
    if(hr == DD_OK && D3D2) IDirect3D2_Release(D3D2);

    hr = IDirectDraw7_QueryInterface(DDraw7, &IID_IDirect3D, (void **) &D3D1);
    todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw7_QueryInterface returned %08x\n", hr);
    if(hr == DD_OK && D3D1) IDirect3D_Release(D3D1);

    hr = IDirectDraw_QueryInterface(DDraw1, &IID_IDirect3D, (void **) &D3D1);
    todo_wine ok(hr == E_NOINTERFACE, "IDirectDraw_QueryInterface returned %08x\n", hr);
    if(hr == DD_OK && D3D1) IDirect3D_Release(D3D1);

    hr = IDirect3D7_QueryInterface(D3D7, &IID_IDirect3D, (void **) &D3D1);
    todo_wine ok(hr == E_NOINTERFACE, "IDirect3D7_QueryInterface returned %08x\n", hr);
    if(hr == DD_OK && D3D1) IDirect3D_Release(D3D1);

    /* Try an AddRef, it only affects the AddRefed interface */
    IDirectDraw4_AddRef(DDraw4);
    ref = getRefcount( (IUnknown *) DDraw7);
    ok(ref == 2, "IDirectDraw7 reference count is %ld\n", ref); /* <-- From the d3d query */
    ref = getRefcount( (IUnknown *) DDraw4);
    ok(ref == 2, "IDirectDraw4 reference count is %ld\n", ref); /* <-- The AddRef call */
    ref = getRefcount( (IUnknown *) DDraw2);
    ok(ref == 1, "IDirectDraw2 reference count is %ld\n", ref);
    ref = getRefcount( (IUnknown *) DDraw1);
    ok(ref == 1, "IDirectDraw reference count is %ld\n", ref);
    ref = getRefcount( (IUnknown *) D3D7);
    ok(ref == 2, "IDirect3D7 reference count is %ld\n", ref); /* <-- From the d3d query */
    IDirectDraw4_Release(DDraw4);

    /* Make sure that they are one object, not different ones */
    hr = IDirectDraw4_SetCooperativeLevel(DDraw4, GetDesktopWindow(), DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
    ok(hr == DD_OK, "IDirectDraw4::SetCooperativeLevel returned %08x\n", hr);
    /* After an window has been set, DDSCL_SETFOCUSWINDOW should return DDERR_HWNDALREADYSET, see the mode test */
    hr = IDirectDraw7_SetCooperativeLevel(DDraw7, NULL, DDSCL_SETFOCUSWINDOW);
    ok(hr == DDERR_HWNDALREADYSET, "IDirectDraw7::SetCooperativeLevel returned %08x\n", hr);

    /* All done, release all interfaces */
    IDirectDraw7_Release(DDraw7);
    IDirectDraw4_Release(DDraw4);
    IDirectDraw2_Release(DDraw2);
    IDirectDraw_Release(DDraw1);
    IDirect3D7_Release(D3D7);
}
Ejemplo n.º 13
0
/* get_dx_ver:
 *  returns the DirectX dx_version number:
 *
 *          0       no DirectX installed
 *          0x100   DirectX 1 installed
 *          0x200   DirectX 2 installed
 *          0x300   DirectX 3 installed
 *          0x500   at least DirectX 5 installed
 *          0x600   at least DirectX 6 installed
 *          0x700   at least DirectX 7 installed
 */
int get_dx_ver(void)
{
   HRESULT hr;
   HINSTANCE ddraw_hinst = NULL;
   HINSTANCE dinput_hinst = NULL;
   HINSTANCE dsetup_hinst = NULL;
   LPDIRECTDRAW directdraw = NULL;
   LPDIRECTDRAW2 directdraw2 = NULL;
   DIRECTDRAWCREATE DirectDrawCreate = NULL;
   DIRECTINPUTCREATE DirectInputCreate = NULL;
   DSETUPCREATE DSetupCreate = NULL;
   OSVERSIONINFO os_version;
   LPDIRECTDRAWSURFACE ddraw_surf = NULL;
   LPDIRECTDRAWSURFACE3 ddraw_surf3 = NULL;
   DWORD dsetup_revision;
   DWORD dsetup_version;
   INT dsetup_result;

#if DIRECTX_SDK_VERSION >= 0x600
   LPDIRECTDRAWSURFACE4 ddraw_surf4 = NULL;

#if DIRECTX_SDK_VERSION >= 0x700
   LPDIRECTDRAWSURFACE7 ddraw_surf7 = NULL;
#endif

#endif

   DDSURFACEDESC ddraw_surf_desc;
   LPVOID temp;
   int dx_version = 0;

   /* first get the Windows platform */
   os_version.dwOSVersionInfoSize = sizeof(os_version);
   if (!GetVersionEx(&os_version))
      return dx_version;

   if (os_version.dwPlatformId == VER_PLATFORM_WIN32_NT) {
      /* NT is easy... NT 4.0 is DX2, 4.0 SP3 is DX3, 5.0 is DX5 at least
       * and no DX on earlier versions
       */
      if (os_version.dwMajorVersion < 4) {
         /* No DX on NT 3.51 or earlier */
         return dx_version;
      }

      /* First check for DX 8 and 9 */
      dsetup_hinst = LoadLibrary( "DSETUP.DLL" );
      if ( dsetup_hinst ) {
         DSetupCreate = (DSETUPCREATE)GetProcAddress(dsetup_hinst, "DirectXSetupGetVersion");
         if ( DSetupCreate ) {
            dsetup_result = DSetupCreate( &dsetup_version, &dsetup_revision );  // returns 0 on failure
            if ( dsetup_result ) {
               switch (dsetup_version) {
                  case 0x00040005:
                     dx_version = 0x500;
                     break;
                  case 0x00040006:
                     dx_version = 0x600;
                     break;
                  case 0x00040007:
                     dx_version = 0x700;
                     break;
                  case 0x00040008:              /* v8.x */
                     dx_version = 0x800;
                     switch (dsetup_revision) {
                        case 0x0001032A:
                        case 0x00010371:
                           dx_version = 0x810; /* 8.1 */
                           dx_version = 0x810; /* 8.1 */
                           break;
                        case 0x00010385:
                           dx_version = 0x81a; /* 8.1a or b (stupid MS...) */
                           break;
                        case 0x00020386:
                           dx_version = 0x820; /* 8.2 */
                           break;
                        default:
                           dx_version = 0x800; /* 8.0 */
                     } /* switch (dsetup_revision) */
                  case 0x00040009:
                     switch (dsetup_revision) {
                        case 0x00000384:
                           dx_version = 0x900; /* 9.0 */
                           break;
                        case 0x00000385:
                           dx_version = 0x90a; /* 9.0a */
                           break;
                        case 0x00000386:
                           dx_version = 0x90b; /* 9.0b */
                           break;
                        case 0x00000387:
                           dx_version = 0x90b; /* 9.0(b or c) */
                           break;
                        case 0x00000388:
                           dx_version = 0x90c; /* 9.0c */
                           break;
                        default:
                           dx_version = 0x900;
                     } /* switch (dsetup_revision) */
               } /* switch (dsetup_version) */
            }
         }
         FreeLibrary( dsetup_hinst );
         if ( dx_version )
            return dx_version;
      }

      if (os_version.dwMajorVersion == 4) {
         /* NT4 up to SP2 is DX2, and SP3 onwards is DX3, so we are at least DX2 */
         dx_version = 0x200;

         /* we are not supposed to be able to tell which SP we are on, so check for DInput */
         dinput_hinst = LoadLibrary("DINPUT.DLL");
         if (!dinput_hinst) {
            /* no DInput... must be DX2 on NT 4 pre-SP3 */
            OutputDebugString("Couldn't LoadLibrary DInput\r\n");
            return dx_version;
         }

         DirectInputCreate = (DIRECTINPUTCREATE) GetProcAddress(dinput_hinst, "DirectInputCreateA");
         FreeLibrary(dinput_hinst);

         if (!DirectInputCreate) {
            /* no DInput... must DX2 on NT 4 pre-SP3 */
            return dx_version;
         }

         /* DX3 on NT4 SP3 or higher */
         dx_version = 0x300;

         return dx_version;
      }

      /* it's at least NT 5 and it's DX5a or higher:
       *  drop through to Win9x tests for a test of DDraw
       */
   }

   /* now we know we are in Windows 9x (or maybe 3.1), so anything's possible;
    * first see if DDRAW.DLL even exists.
    */
   ddraw_hinst = LoadLibrary("DDRAW.DLL");
   if (!ddraw_hinst) {
      dx_version = 0;
      goto End;
   }

   /* see if we can create the DirectDraw object */
   DirectDrawCreate = (DIRECTDRAWCREATE) GetProcAddress(ddraw_hinst, "DirectDrawCreate");
   if (!DirectDrawCreate) {
      dx_version = 0;
      goto End;
   }

   hr = DirectDrawCreate(NULL, &directdraw, NULL);
   if (FAILED(hr)) {
      dx_version = 0;
      goto End;
   }

   /* so DirectDraw exists, we are at least DX1 */
   dx_version = 0x100;

   /* let's see if IDirectDraw2 exists */
   hr = IDirectDraw_QueryInterface(directdraw, &IID_IDirectDraw2, &temp);
   if (FAILED(hr)) {
      /* no IDirectDraw2 exists... must be DX1 */
      goto End;
   }

   directdraw2 = temp;

   /* IDirectDraw2 exists... must be at least DX2 */
   IDirectDraw2_Release(directdraw2);
   dx_version = 0x200;

   /* see if we can create the DirectInput object */
   dinput_hinst = LoadLibrary("DINPUT.DLL");
   if (!dinput_hinst) {
      /* no DInput... must be DX2 */
      goto End;
   }

   DirectInputCreate = (DIRECTINPUTCREATE) GetProcAddress(dinput_hinst, "DirectInputCreateA");
   FreeLibrary(dinput_hinst);

   if (!DirectInputCreate) {
      /* no DInput... must be DX2 */
      goto End;
   }

   /* DirectInputCreate exists; that's enough to tell us that we are at least DX3 */
   dx_version = 0x300;

   /* we can tell if DX5 is present by checking for the existence of IDirectDrawSurface3;
    * first we need a surface to QI off of
    */
   memset(&ddraw_surf_desc, 0, sizeof(ddraw_surf_desc));
   ddraw_surf_desc.dwSize = sizeof(ddraw_surf_desc);
   ddraw_surf_desc.dwFlags = DDSD_CAPS;
   ddraw_surf_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

   hr = IDirectDraw_SetCooperativeLevel(directdraw, NULL, DDSCL_NORMAL);
   if (FAILED(hr)) {
      /* failure: this means DDraw isn't properly installed */
      dx_version = 0;
      goto End;
   }

   hr = IDirectDraw_CreateSurface(directdraw, &ddraw_surf_desc, &ddraw_surf, NULL);
   if (FAILED(hr)) {
      /* failure: this means DDraw isn't properly installed */
      dx_version = 0;
      goto End;
   }

   /* try for the IDirectDrawSurface3 interface; if it works, we're on DX5 at least */
   hr = IDirectDrawSurface_QueryInterface(ddraw_surf, &IID_IDirectDrawSurface3, &temp);
   if (FAILED(hr))
      goto End;

   ddraw_surf3 = temp;

   /* QI for IDirectDrawSurface3 succeeded; we must be at least DX5 */
   dx_version = 0x500;

#if DIRECTX_SDK_VERSION >= 0x600
   /* try for the IDirectDrawSurface4 interface; if it works, we're on DX6 at least */
   hr = IDirectDrawSurface_QueryInterface(ddraw_surf, &IID_IDirectDrawSurface4, (LPVOID *) &ddraw_surf4);
   if (FAILED(hr))
      goto End;

   /* QI for IDirectDrawSurface4 succeeded; we must be at least DX6 */
   dx_version = 0x600;

#if DIRECTX_SDK_VERSION >= 0x700
   /* try for the IDirectDrawSurface7 interface; if it works, we're on DX7 at least */
   hr = IDirectDrawSurface_QueryInterface(ddraw_surf, &IID_IDirectDrawSurface7, (LPVOID *) &ddraw_surf7);
   if (FAILED(hr))
      goto End;

   /* QI for IDirectDrawSurface7 succeeded; we must be at least DX7 */
   dx_version = 0x700;
#endif

#endif

 End:
   if (directdraw)
      IDirectDraw_Release(directdraw);

   if (ddraw_hinst)
      FreeLibrary(ddraw_hinst);

   return dx_version;
}
Ejemplo n.º 14
0
static void GetDCTest_main(DDSURFACEDESC *ddsd, DDSURFACEDESC2 *ddsd2, void (*testfunc)(IDirectDrawSurface *surf, int ddsdver))
{
    IDirectDrawSurface *surf;
    IDirectDrawSurface2 *surf2;
    IDirectDrawSurface2 *surf3;
    IDirectDrawSurface4 *surf4;
    HRESULT hr;
    IDirectDraw  *dd1 = createDD();
    IDirectDraw2 *dd2;
    IDirectDraw3 *dd3;
    IDirectDraw4 *dd4;

    hr = IDirectDraw_CreateSurface(dd1, ddsd, &surf, NULL);
    if (hr == DDERR_UNSUPPORTEDMODE) {
        win_skip("Unsupported mode\n");
        return;
    }
    ok(hr == DD_OK, "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
    testfunc(surf, 1);
    IDirectDrawSurface_Release(surf);

    hr = IDirectDraw_QueryInterface(dd1, &IID_IDirectDraw2, (void **) &dd2);
    ok(hr == DD_OK, "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);

    hr = IDirectDraw2_CreateSurface(dd2, ddsd, &surf, NULL);
    ok(hr == DD_OK, "IDirectDraw2_CreateSurface failed: 0x%08x\n", hr);
    testfunc(surf, 1);

    hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface2, (void **) &surf2);
    ok(hr == DD_OK, "IDirectDrawSurface_QueryInterface failed: 0x%08x\n", hr);
    testfunc((IDirectDrawSurface *) surf2, 1);

    IDirectDrawSurface2_Release(surf2);
    IDirectDrawSurface_Release(surf);
    IDirectDraw2_Release(dd2);

    hr = IDirectDraw_QueryInterface(dd1, &IID_IDirectDraw3, (void **) &dd3);
    ok(hr == DD_OK, "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);

    hr = IDirectDraw3_CreateSurface(dd3, ddsd, &surf, NULL);
    ok(hr == DD_OK, "IDirectDraw3_CreateSurface failed: 0x%08x\n", hr);
    testfunc(surf, 1);

    hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface3, (void **) &surf3);
    ok(hr == DD_OK, "IDirectDrawSurface_QueryInterface failed: 0x%08x\n", hr);
    testfunc((IDirectDrawSurface *) surf3, 1);

    IDirectDrawSurface3_Release(surf3);
    IDirectDrawSurface_Release(surf);
    IDirectDraw3_Release(dd3);

    hr = IDirectDraw_QueryInterface(dd1, &IID_IDirectDraw4, (void **) &dd4);
    ok(hr == DD_OK, "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);

    surf = NULL;
    hr = IDirectDraw4_CreateSurface(dd4, ddsd2, &surf4, NULL);
    ok(hr == DD_OK, "IDirectDraw4_CreateSurface failed: 0x%08x\n", hr);
    testfunc((IDirectDrawSurface *) surf4, 2);

    IDirectDrawSurface4_Release(surf4);
    IDirectDraw4_Release(dd4);

    IDirectDraw_Release(dd1);
}