Bool winAllocateFBShadowDDNL (ScreenPtr pScreen) { winScreenPriv(pScreen); winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; HRESULT ddrval = DD_OK; DDSURFACEDESC2 ddsdShadow; char *lpSurface = NULL; DDPIXELFORMAT ddpfPrimary; #if CYGDEBUG winDebug ("winAllocateFBShadowDDNL - w %d h %d d %d\n", pScreenInfo->dwWidth, pScreenInfo->dwHeight, pScreenInfo->dwDepth); #endif /* Set the padded screen width */ pScreenInfo->dwPaddedWidth = PixmapBytePad (pScreenInfo->dwWidth, pScreenInfo->dwBPP); /* Allocate memory for our shadow surface */ lpSurface = malloc (pScreenInfo->dwPaddedWidth * pScreenInfo->dwHeight); if (lpSurface == NULL) { ErrorF ("winAllocateFBShadowDDNL - Could not allocate bits\n"); return FALSE; } /* * Initialize the framebuffer memory so we don't get a * strange display at startup */ ZeroMemory (lpSurface, pScreenInfo->dwPaddedWidth * pScreenInfo->dwHeight); /* Create a clipper */ ddrval = (*g_fpDirectDrawCreateClipper) (0, &pScreenPriv->pddcPrimary, NULL); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDDNL - Could not attach clipper: %08x\n", (unsigned int) ddrval); return FALSE; } #if CYGDEBUG winDebug ("winAllocateFBShadowDDNL - Created a clipper\n"); #endif /* Attach the clipper to our display window */ ddrval = IDirectDrawClipper_SetHWnd (pScreenPriv->pddcPrimary, 0, pScreenPriv->hwndScreen); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDDNL - Clipper not attached " "to window: %08x\n", (unsigned int) ddrval); return FALSE; } #if CYGDEBUG winDebug ("winAllocateFBShadowDDNL - Attached clipper to window\n"); #endif /* Create a DirectDraw object, store the address at lpdd */ ddrval = (*g_fpDirectDrawCreate) (NULL, (LPDIRECTDRAW*) &pScreenPriv->pdd, NULL); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDDNL - Could not start " "DirectDraw: %08x\n", (unsigned int) ddrval); return FALSE; } #if CYGDEBUG winDebug ("winAllocateFBShadowDDNL - Created and initialized DD\n"); #endif /* Get a DirectDraw4 interface pointer */ ddrval = IDirectDraw_QueryInterface (pScreenPriv->pdd, &IID_IDirectDraw4, (LPVOID*) &pScreenPriv->pdd4); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDDNL - Failed DD4 query: %08x\n", (unsigned int) ddrval); return FALSE; } /* Are we full screen? */ if (pScreenInfo->fFullScreen) { DDSURFACEDESC2 ddsdCurrent; DWORD dwRefreshRateCurrent = 0; HDC hdc = NULL; /* Set the cooperative level to full screen */ ddrval = IDirectDraw4_SetCooperativeLevel (pScreenPriv->pdd4, pScreenPriv->hwndScreen, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDDNL - Could not set " "cooperative level: %08x\n", (unsigned int) ddrval); return FALSE; } /* * We only need to get the current refresh rate for comparison * if a refresh rate has been passed on the command line. */ if (pScreenInfo->dwRefreshRate != 0) { ZeroMemory (&ddsdCurrent, sizeof (ddsdCurrent)); ddsdCurrent.dwSize = sizeof (ddsdCurrent); /* Get information about current display settings */ ddrval = IDirectDraw4_GetDisplayMode (pScreenPriv->pdd4, &ddsdCurrent); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDDNL - Could not get current " "refresh rate: %08x. Continuing.\n", (unsigned int) ddrval); dwRefreshRateCurrent = 0; } else { /* Grab the current refresh rate */ dwRefreshRateCurrent = ddsdCurrent.u2.dwRefreshRate; } } /* Clean up the refresh rate */ if (dwRefreshRateCurrent == pScreenInfo->dwRefreshRate) { /* * Refresh rate is non-specified or equal to current. */ pScreenInfo->dwRefreshRate = 0; } /* Grab a device context for the screen */ hdc = GetDC (NULL); if (hdc == NULL) { ErrorF ("winAllocateFBShadowDDNL - GetDC () failed\n"); return FALSE; } /* Only change the video mode when different than current mode */ if (!pScreenInfo->fMultipleMonitors && (pScreenInfo->dwWidth != GetSystemMetrics (SM_CXSCREEN) || pScreenInfo->dwHeight != GetSystemMetrics (SM_CYSCREEN) || pScreenInfo->dwBPP != GetDeviceCaps (hdc, BITSPIXEL) || pScreenInfo->dwRefreshRate != 0)) { winDebug ("winAllocateFBShadowDDNL - Changing video mode\n"); /* Change the video mode to the mode requested, and use the driver default refresh rate on failure */ ddrval = IDirectDraw4_SetDisplayMode (pScreenPriv->pdd4, pScreenInfo->dwWidth, pScreenInfo->dwHeight, pScreenInfo->dwBPP, pScreenInfo->dwRefreshRate, 0); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDDNL - Could not set " "full screen display mode: %08x\n", (unsigned int) ddrval); ErrorF ("winAllocateFBShadowDDNL - Using default driver refresh rate\n"); ddrval = IDirectDraw4_SetDisplayMode (pScreenPriv->pdd4, pScreenInfo->dwWidth, pScreenInfo->dwHeight, pScreenInfo->dwBPP, 0, 0); if (FAILED(ddrval)) { ErrorF ("winAllocateFBShadowDDNL - Could not set default refresh rate " "full screen display mode: %08x\n", (unsigned int) ddrval); return FALSE; } } } else { winDebug ("winAllocateFBShadowDDNL - Not changing video mode\n"); } /* Release our DC */ ReleaseDC (NULL, hdc); hdc = NULL; } else { /* Set the cooperative level for windowed mode */ ddrval = IDirectDraw4_SetCooperativeLevel (pScreenPriv->pdd4, pScreenPriv->hwndScreen, DDSCL_NORMAL); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDDNL - Could not set " "cooperative level: %08x\n", (unsigned int) ddrval); return FALSE; } } /* Create the primary surface */ if (!winCreatePrimarySurfaceShadowDDNL (pScreen)) { ErrorF ("winAllocateFBShadowDDNL - winCreatePrimarySurfaceShadowDDNL " "failed\n"); return FALSE; } /* Get primary surface's pixel format */ ZeroMemory (&ddpfPrimary, sizeof (ddpfPrimary)); ddpfPrimary.dwSize = sizeof (ddpfPrimary); ddrval = IDirectDrawSurface4_GetPixelFormat (pScreenPriv->pddsPrimary4, &ddpfPrimary); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDDNL - Could not get primary " "pixformat: %08x\n", (unsigned int) ddrval); return FALSE; } #if CYGDEBUG winDebug ("winAllocateFBShadowDDNL - Primary masks: %08x %08x %08x " "dwRGBBitCount: %d\n", ddpfPrimary.u2.dwRBitMask, ddpfPrimary.u3.dwGBitMask, ddpfPrimary.u4.dwBBitMask, ddpfPrimary.u1.dwRGBBitCount); #endif /* Describe the shadow surface to be created */ /* * NOTE: Do not use a DDSCAPS_VIDEOMEMORY surface, * as drawing, locking, and unlocking take forever * with video memory surfaces. In addition, * video memory is a somewhat scarce resource, * so you shouldn't be allocating video memory when * you have the option of using system memory instead. */ ZeroMemory (&ddsdShadow, sizeof (ddsdShadow)); ddsdShadow.dwSize = sizeof (ddsdShadow); ddsdShadow.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_LPSURFACE | DDSD_PITCH | DDSD_PIXELFORMAT; ddsdShadow.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; ddsdShadow.dwHeight = pScreenInfo->dwHeight; ddsdShadow.dwWidth = pScreenInfo->dwWidth; ddsdShadow.u1.lPitch = pScreenInfo->dwPaddedWidth; ddsdShadow.lpSurface = lpSurface; ddsdShadow.u4.ddpfPixelFormat = ddpfPrimary; winDebug ("winAllocateFBShadowDDNL - lPitch: %d\n", (int) pScreenInfo->dwPaddedWidth); /* Create the shadow surface */ ddrval = IDirectDraw4_CreateSurface (pScreenPriv->pdd4, &ddsdShadow, &pScreenPriv->pddsShadow4, NULL); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDDNL - Could not create shadow " "surface: %08x\n", (unsigned int) ddrval); return FALSE; } #if CYGDEBUG || YES winDebug ("winAllocateFBShadowDDNL - Created shadow pitch: %d\n", (int) ddsdShadow.u1.lPitch); #endif /* Grab the pitch from the surface desc */ pScreenInfo->dwStride = (ddsdShadow.u1.lPitch * 8) / pScreenInfo->dwBPP; #if CYGDEBUG || YES winDebug ("winAllocateFBShadowDDNL - Created shadow stride: %d\n", (int) pScreenInfo->dwStride); #endif /* Save the pointer to our surface memory */ pScreenInfo->pfb = lpSurface; /* Grab the masks from the surface description */ pScreenPriv->dwRedMask = ddsdShadow.u4.ddpfPixelFormat.u2.dwRBitMask; pScreenPriv->dwGreenMask = ddsdShadow.u4.ddpfPixelFormat.u3.dwGBitMask; pScreenPriv->dwBlueMask = ddsdShadow.u4.ddpfPixelFormat.u4.dwBBitMask; #if CYGDEBUG winDebug ("winAllocateFBShadowDDNL - Returning\n"); #endif return TRUE; }
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); }