// // CreateNewSurface // static inline IDirectDrawSurface* CreateNewSurface(int dwWidth, int dwHeight, int dwSurfaceCaps) { DDSURFACEDESC ddsd; HRESULT hr; LPDIRECTDRAWSURFACE psurf; ZeroMemory(&ddsd, sizeof (ddsd)); ddsd.dwSize = sizeof (ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH; ddsd.ddsCaps.dwCaps = dwSurfaceCaps; ddsd.dwHeight = dwHeight; ddsd.dwWidth = dwWidth; hr = IDirectDraw2_CreateSurface (DDr2, &ddsd, &psurf, NULL); if (hr == DD_OK) { //DDCOLORKEY ddck; IDirectDrawSurface_Restore(psurf); //hr = IDirectDrawSurface_GetColorKey(DDCKEY_SRCBLT, &ddck); //psurf->SetColorKey(DDCKEY_SRCBLT, &ddck); } else psurf = NULL; return psurf; }
static Bool winCreatePrimarySurfaceShadowDD (ScreenPtr pScreen) { winScreenPriv(pScreen); HRESULT ddrval = DD_OK; DDSURFACEDESC ddsd; /* Describe the primary surface */ ZeroMemory (&ddsd, sizeof (ddsd)); ddsd.dwSize = sizeof (ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; /* Create the primary surface */ ddrval = IDirectDraw2_CreateSurface (pScreenPriv->pdd2, &ddsd, &pScreenPriv->pddsPrimary, NULL); if (FAILED (ddrval)) { ErrorF ("winCreatePrimarySurfaceShadowDD - Could not create primary " "surface: %08x\n", (unsigned int) ddrval); return FALSE; } #if CYGDEBUG winDebug ("winCreatePrimarySurfaceShadowDD - Created primary surface\n"); #endif /* * Attach a clipper to the primary surface that will clip our blits to our * display window. */ ddrval = IDirectDrawSurface2_SetClipper (pScreenPriv->pddsPrimary, pScreenPriv->pddcPrimary); if (FAILED (ddrval)) { ErrorF ("winCreatePrimarySurfaceShadowDD - Primary attach clipper " "failed: %08x\n", (unsigned int) ddrval); return FALSE; } #if CYGDEBUG winDebug ("winCreatePrimarySurfaceShadowDD - Attached clipper to " "primary surface\n"); #endif /* Everything was correct */ return TRUE; }
// DirectDrawSurface2 Calls void DDCreateSurface ( LPDIRECTDRAW2 pExistingDirectDraw, DDSURFACEDESC *pNewSurfaceDesc, LPDIRECTDRAWSURFACE *ppNewSurface1, LPDIRECTDRAWSURFACE2 *ppNewSurface2 ) { Assert ( pExistingDirectDraw != NULL ); Assert ( pNewSurfaceDesc != NULL ); Assert ( ppNewSurface1 != NULL ); Assert ( ppNewSurface2 != NULL ); // create the directdraw surface ATTEMPT ( IDirectDraw2_CreateSurface ( pExistingDirectDraw, pNewSurfaceDesc, ppNewSurface1, NULL ) ); //get the direct draw surface 2 interface ATTEMPT ( IDirectDrawSurface_QueryInterface ( *ppNewSurface1, &IID_IDirectDrawSurface2, (LPVOID*) ppNewSurface2 ) ); }
/** * Create and initialize display according to preferences specified in the vout * thread fields. */ static int DirectXOpenDisplay(vout_display_t *vd) { vout_display_sys_t *sys = vd->sys; HRESULT hr; /* Now get the primary surface. This surface is what you actually see * on your screen */ DDSURFACEDESC ddsd; ZeroMemory(&ddsd, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; LPDIRECTDRAWSURFACE display; hr = IDirectDraw2_CreateSurface(sys->ddobject, &ddsd, &display, NULL); if (hr != DD_OK) { msg_Err(vd, "cannot get primary surface (error %li)", hr); return VLC_EGENERIC; } void *ptr; hr = IDirectDrawSurface_QueryInterface(display, &IID_IDirectDrawSurface2, &ptr); /* Release the old interface */ IDirectDrawSurface_Release(display); if (hr != DD_OK) { msg_Err(vd, "cannot query IDirectDrawSurface2 interface (error %li)", hr); sys->display = NULL; return VLC_EGENERIC; } sys->display = ptr; /* The clipper will be used only in non-overlay mode */ DirectXCreateClipper(vd); /* Make sure the colorkey will be painted */ sys->i_colorkey = 1; sys->i_rgb_colorkey = DirectXFindColorkey(vd, &sys->i_colorkey); return VLC_SUCCESS; }
static Bool winAllocateFBShadowDD (ScreenPtr pScreen) { winScreenPriv(pScreen); winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; HRESULT ddrval = DD_OK; DDSURFACEDESC ddsd; DDSURFACEDESC *pddsdShadow = NULL; #if CYGDEBUG winDebug ("winAllocateFBShadowDD\n"); #endif /* Create a clipper */ ddrval = (*g_fpDirectDrawCreateClipper) (0, &pScreenPriv->pddcPrimary, NULL); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDD - Could not create clipper: %08x\n", (unsigned int) ddrval); return FALSE; } #if CYGDEBUG winDebug ("winAllocateFBShadowDD - Created a clipper\n"); #endif /* Get a device context for the screen */ pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen); /* Attach the clipper to our display window */ ddrval = IDirectDrawClipper_SetHWnd (pScreenPriv->pddcPrimary, 0, pScreenPriv->hwndScreen); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDD - Clipper not attached to " "window: %08x\n", (unsigned int) ddrval); return FALSE; } #if CYGDEBUG winDebug ("winAllocateFBShadowDD - Attached clipper to window\n"); #endif /* Create a DirectDraw object, store the address at lpdd */ ddrval = (*g_fpDirectDrawCreate) (NULL, &pScreenPriv->pdd, NULL); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDD - Could not start DirectDraw: %08x\n", (unsigned int) ddrval); return FALSE; } #if CYGDEBUG winDebug ("winAllocateFBShadowDD () - Created and initialized DD\n"); #endif /* Get a DirectDraw2 interface pointer */ ddrval = IDirectDraw_QueryInterface (pScreenPriv->pdd, &IID_IDirectDraw2, (LPVOID*) &pScreenPriv->pdd2); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDD - Failed DD2 query: %08x\n", (unsigned int) ddrval); return FALSE; } /* Are we full screen? */ if (pScreenInfo->fFullScreen) { DDSURFACEDESC ddsdCurrent; DWORD dwRefreshRateCurrent = 0; HDC hdc = NULL; /* Set the cooperative level to full screen */ ddrval = IDirectDraw2_SetCooperativeLevel (pScreenPriv->pdd2, pScreenPriv->hwndScreen, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDD - 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 = IDirectDraw2_GetDisplayMode (pScreenPriv->pdd2, &ddsdCurrent); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDD - 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 ("winAllocateFBShadowDD - 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)) { ErrorF ("winAllocateFBShadowDD - Changing video mode\n"); /* Change the video mode to the mode requested, and use the driver default refresh rate on failure */ ddrval = IDirectDraw2_SetDisplayMode (pScreenPriv->pdd2, pScreenInfo->dwWidth, pScreenInfo->dwHeight, pScreenInfo->dwBPP, pScreenInfo->dwRefreshRate, 0); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDD - Could not set "\ "full screen display mode: %08x\n", (unsigned int) ddrval); ErrorF ("winAllocateFBShadowDD - Using default driver refresh rate\n"); ddrval = IDirectDraw2_SetDisplayMode (pScreenPriv->pdd2, pScreenInfo->dwWidth, pScreenInfo->dwHeight, pScreenInfo->dwBPP, 0, 0); if (FAILED(ddrval)) { ErrorF ("winAllocateFBShadowDD - Could not set default refresh rate " "full screen display mode: %08x\n", (unsigned int) ddrval); return FALSE; } } } else { ErrorF ("winAllocateFBShadowDD - Not changing video mode\n"); } /* Release our DC */ ReleaseDC (NULL, hdc); hdc = NULL; } else { /* Set the cooperative level for windowed mode */ ddrval = IDirectDraw2_SetCooperativeLevel (pScreenPriv->pdd2, pScreenPriv->hwndScreen, DDSCL_NORMAL); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDD - Could not set "\ "cooperative level: %08x\n", (unsigned int) ddrval); return FALSE; } } /* Create the primary surface */ if (!winCreatePrimarySurfaceShadowDD (pScreen)) { ErrorF ("winAllocateFBShadowDD - winCreatePrimarySurfaceShadowDD " "failed\n"); return FALSE; } /* 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 (&ddsd, sizeof (ddsd)); ddsd.dwSize = sizeof (ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; ddsd.dwHeight = pScreenInfo->dwHeight; ddsd.dwWidth = pScreenInfo->dwWidth; /* Create the shadow surface */ ddrval = IDirectDraw2_CreateSurface (pScreenPriv->pdd2, &ddsd, &pScreenPriv->pddsShadow, NULL); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDD - Could not create shadow "\ "surface: %08x\n", (unsigned int) ddrval); return FALSE; } #if CYGDEBUG winDebug ("winAllocateFBShadowDD - Created shadow\n"); #endif /* Allocate a DD surface description for our screen privates */ pddsdShadow = pScreenPriv->pddsdShadow = malloc (sizeof (DDSURFACEDESC)); if (pddsdShadow == NULL) { ErrorF ("winAllocateFBShadowDD - Could not allocate surface "\ "description memory\n"); return FALSE; } ZeroMemory (pddsdShadow, sizeof (*pddsdShadow)); pddsdShadow->dwSize = sizeof (*pddsdShadow); #if CYGDEBUG winDebug ("winAllocateFBShadowDD - Locking shadow\n"); #endif /* Lock the shadow surface */ ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsShadow, NULL, pddsdShadow, DDLOCK_WAIT, NULL); if (FAILED (ddrval) || pddsdShadow->lpSurface == NULL) { ErrorF ("winAllocateFBShadowDD - Could not lock shadow "\ "surface: %08x\n", (unsigned int) ddrval); return FALSE; } #if CYGDEBUG winDebug ("winAllocateFBShadowDD - Locked shadow\n"); #endif /* We don't know how to deal with anything other than RGB */ if (!(pddsdShadow->ddpfPixelFormat.dwFlags & DDPF_RGB)) { ErrorF ("winAllocateFBShadowDD - Color format other than RGB\n"); return FALSE; } /* Grab the pitch from the surface desc */ pScreenInfo->dwStride = (pddsdShadow->u1.lPitch * 8) / pScreenInfo->dwBPP; /* Save the pointer to our surface memory */ pScreenInfo->pfb = pddsdShadow->lpSurface; /* Grab the color depth and masks from the surface description */ pScreenPriv->dwRedMask = pddsdShadow->ddpfPixelFormat.u2.dwRBitMask; pScreenPriv->dwGreenMask = pddsdShadow->ddpfPixelFormat.u3.dwGBitMask; pScreenPriv->dwBlueMask = pddsdShadow->ddpfPixelFormat.u4.dwBBitMask; #if CYGDEBUG winDebug ("winAllocateFBShadowDD - Returning\n"); #endif return TRUE; }
/** * Create an YUV overlay or RGB surface for the video. * * The best method of display is with an YUV overlay because the YUV->RGB * conversion is done in hardware. * You can also create a plain RGB surface. * (Maybe we could also try an RGB overlay surface, which could have hardware * scaling and which would also be faster in window mode because you don't * need to do any blitting to the main display...) */ static int DirectXCreateSurface(vout_display_t *vd, LPDIRECTDRAWSURFACE2 *surface, const video_format_t *fmt, DWORD fourcc, bool use_overlay, bool use_sysmem, int backbuffer_count) { vout_display_sys_t *sys = vd->sys; DDSURFACEDESC ddsd; ZeroMemory(&ddsd, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat); ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH; ddsd.dwWidth = fmt->i_width; ddsd.dwHeight = fmt->i_height; if (fourcc) { ddsd.dwFlags |= DDSD_PIXELFORMAT; ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC; ddsd.ddpfPixelFormat.dwFourCC = fourcc; } if (use_overlay) { ddsd.dwFlags |= DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY; if (backbuffer_count > 0) ddsd.ddsCaps.dwCaps |= DDSCAPS_COMPLEX | DDSCAPS_FLIP; if (backbuffer_count > 0) { ddsd.dwFlags |= DDSD_BACKBUFFERCOUNT; ddsd.dwBackBufferCount = backbuffer_count; } } else { ddsd.dwFlags |= DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; if (use_sysmem) ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; else ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY; } /* Create the video surface */ LPDIRECTDRAWSURFACE surface_v1; if (IDirectDraw2_CreateSurface(sys->ddobject, &ddsd, &surface_v1, NULL) != DD_OK) return VLC_EGENERIC; /* Now that the surface is created, try to get a newer DirectX interface */ HRESULT hr = IDirectDrawSurface_QueryInterface(surface_v1, &IID_IDirectDrawSurface2, (LPVOID *)surface); IDirectDrawSurface_Release(surface_v1); if (hr != DD_OK) { msg_Err(vd, "cannot query IDirectDrawSurface2 interface (error %li)", hr); return VLC_EGENERIC; } if (use_overlay) { /* Check the overlay is useable as some graphics cards allow creating * several overlays but only one can be used at one time. */ if (DirectXUpdateOverlay(vd, *surface)) { IDirectDrawSurface2_Release(*surface); msg_Err(vd, "overlay unuseable (might already be in use)"); return VLC_EGENERIC; } } return VLC_SUCCESS; }
// // - returns true if DirectDraw was initialized properly // int InitDirectDrawe (HWND appWin, int width, int height, int bpp, int fullScr) { DDSURFACEDESC ddsd; // DirectDraw surface description for allocating DDSCAPS ddscaps; HRESULT ddrval; DWORD dwStyle; RECT rect; // enumerate directdraw devices //if (FAILED(DirectDrawEnumerate (myEnumDDDevicesCallback, NULL))) // I_Error("Error with DirectDrawEnumerate"); if (!DDr2) CreateDirectDrawInstance(); // remember what screen mode we are in bAppFullScreen = fullScr; ScreenHeight = height; ScreenWidth = width; if (bAppFullScreen) { // Change window attributes dwStyle = WS_POPUP | WS_VISIBLE; SetWindowLong (appWin, GWL_STYLE, dwStyle); SetWindowPos(appWin, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER); // Get exclusive mode ddrval = IDirectDraw2_SetCooperativeLevel(DDr2, appWin, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT); if (ddrval != DD_OK) I_Error("SetCooperativeLevel FAILED: %s\n", DXErrorToString(ddrval)); // Switch from windows desktop to fullscreen #ifdef NT4COMPAT ddrval = IDirectDraw2_SetDisplayMode(DDr2, width, height, bpp, 0, 0); #else ddrval = IDirectDraw2_SetDisplayMode(DDr2, width, height, bpp, 0, DDSDM_STANDARDVGAMODE); #endif if (ddrval != DD_OK) I_Error("SetDisplayMode FAILED: %s\n", DXErrorToString(ddrval)); // This is not really needed, except in certain cases. One case // is while using MFC. When the desktop is initally at 16bpp, a mode // switch to 8bpp somehow causes the MFC window to not fully initialize // and a CreateSurface will fail with DDERR_NOEXCLUSIVEMODE. This will // ensure that the window is initialized properly after a mode switch. ShowWindow(appWin, SW_SHOW); // Create the primary surface with 1 back buffer. Always zero the // DDSURFACEDESC structure and set the dwSize member! ZeroMemory(&ddsd, sizeof (ddsd)); ddsd.dwSize = sizeof (ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; // for fullscreen we use page flipping, for windowed mode, we blit the hidden surface to // the visible surface, in both cases we have a visible (or 'real') surface, and a hidden // (or 'virtual', or 'backbuffer') surface. ddsd.dwBackBufferCount = 2; ddrval = IDirectDraw2_CreateSurface(DDr2,&ddsd, &ScreenReal, NULL); if (ddrval != DD_OK) I_Error("CreateSurface Primary Screen FAILED"); // Get a pointer to the back buffer ddscaps.dwCaps = DDSCAPS_BACKBUFFER; ddrval = IDirectDrawSurface_GetAttachedSurface(ScreenReal,&ddscaps, &ScreenVirtual); if (ddrval != DD_OK) I_Error("GetAttachedSurface FAILED"); } else { rect.top = 0; rect.left = 0; rect.bottom = height; rect.right = width; // Change window attributes dwStyle = GetWindowStyle(appWin); dwStyle &= ~WS_POPUP; dwStyle |= WS_OVERLAPPED | WS_SYSMENU | WS_CAPTION; SetWindowLong(appWin, GWL_STYLE, dwStyle); // Resize the window so that the client area is the requested width/height AdjustWindowRectEx(&rect, GetWindowStyle(appWin), GetMenu(appWin) != NULL, GetWindowExStyle(appWin)); // Just in case the window was moved off the visible area of the // screen. SetWindowPos(appWin, NULL, 0, 0, rect.right-rect.left, rect.bottom-rect.top, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); SetWindowPos(appWin, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); // Exclusive mode is normal since it's in windowed mode and needs // to cooperate with GDI ddrval = IDirectDraw2_SetCooperativeLevel(DDr2,appWin, DDSCL_NORMAL); if (ddrval != DD_OK) I_Error("SetCooperativeLevel FAILED"); // Always zero the DDSURFACEDESC structure and set the dwSize member! ZeroMemory(&ddsd, sizeof (ddsd)); ddsd.dwSize = sizeof (ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; // Create the primary surface ddrval = IDirectDraw2_CreateSurface(DDr2,&ddsd, &ScreenReal, NULL); if (ddrval != DD_OK) I_Error("CreateSurface Primary Screen FAILED"); // Create a back buffer for offscreen rendering, this will be used to // blt to the primary ScreenVirtual = CreateNewSurface(width, height, DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY); if (ScreenVirtual == NULL) I_Error("CreateSurface Secondary Screen FAILED"); /// \todo get the desktop bit depth, and build a lookup table /// for quick conversions of 8bit color indexes 0-255 to desktop colors /// eg: 256 entries of equivalent of palette colors 0-255 in 15,16,24,32 bit format /// when blit virtual to real, convert pixels through lookup table.. // Use a clipper object for clipping when in windowed mode // (make sure our drawing doesn't affect other windows) ddrval = IDirectDraw2_CreateClipper (DDr2, 0, &windclip, 0); if (ddrval != DD_OK) I_Error("CreateClipper FAILED"); // Associate the clipper with the window. ddrval = IDirectDrawClipper_SetHWnd (windclip,0, appWin); if (ddrval != DD_OK) I_Error("Clipper -> SetHWnd FAILED"); // Attach the clipper to the surface. ddrval = IDirectDrawSurface_SetClipper (ScreenReal,windclip); if (ddrval != DD_OK) I_Error("PrimaryScreen -> SetClipperClipper FAILED"); } return TRUE; }
Bool winAllocateFBPrimaryDD (ScreenPtr pScreen) { winScreenPriv(pScreen); winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; HRESULT ddrval = DD_OK; DDSURFACEDESC ddsd; DDSURFACEDESC *pddsdPrimary = NULL; DDSURFACEDESC *pddsdOffscreen = NULL; RECT rcClient; ErrorF ("winAllocateFBPrimaryDD\n"); /* Get client area location in screen coords */ GetClientRect (pScreenPriv->hwndScreen, &rcClient); MapWindowPoints (pScreenPriv->hwndScreen, HWND_DESKTOP, (LPPOINT)&rcClient, 2); /* Create a DirectDraw object, store the address at lpdd */ ddrval = (*g_fpDirectDrawCreate) (NULL, &pScreenPriv->pdd, NULL); if (ddrval != DD_OK) FatalError ("winAllocateFBPrimaryDD - Could not start DirectDraw\n"); /* Get a DirectDraw2 interface pointer */ ddrval = IDirectDraw_QueryInterface (pScreenPriv->pdd, &IID_IDirectDraw2, (LPVOID*) &pScreenPriv->pdd2); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDD - Failed DD2 query: %08x\n", ddrval); return FALSE; } ErrorF ("winAllocateFBPrimaryDD - Created and initialized DD\n"); /* Are we windowed or fullscreen? */ if (pScreenInfo->fFullScreen) { /* Full screen mode */ ddrval = IDirectDraw2_SetCooperativeLevel (pScreenPriv->pdd2, pScreenPriv->hwndScreen, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE); if (FAILED (ddrval)) FatalError ("winAllocateFBPrimaryDD - Could not set " "cooperative level\n"); /* Change the video mode to the mode requested */ ddrval = IDirectDraw2_SetDisplayMode (pScreenPriv->pdd2, pScreenInfo->dwWidth, pScreenInfo->dwHeight, pScreenInfo->dwBPP, pScreenInfo->dwRefreshRate, 0); if (FAILED (ddrval)) FatalError ("winAllocateFBPrimaryDD - Could not set " "full screen display mode\n"); } else { /* Windowed mode */ ddrval = IDirectDraw2_SetCooperativeLevel (pScreenPriv->pdd2, pScreenPriv->hwndScreen, DDSCL_NORMAL); if (FAILED (ddrval)) FatalError ("winAllocateFBPrimaryDD - Could not set " "cooperative level\n"); } /* Describe the primary surface */ ZeroMemory (&ddsd, sizeof (ddsd)); ddsd.dwSize = sizeof (ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; /* Create the primary surface */ ddrval = IDirectDraw2_CreateSurface (pScreenPriv->pdd2, &ddsd, &pScreenPriv->pddsPrimary, NULL); if (FAILED (ddrval)) FatalError ("winAllocateFBPrimaryDD - Could not create primary " "surface %08x\n", ddrval); ErrorF ("winAllocateFBPrimaryDD - Created primary\n"); /* Allocate a DD surface description for our screen privates */ pddsdPrimary = pScreenPriv->pddsdPrimary = malloc (sizeof (DDSURFACEDESC)); if (pddsdPrimary == NULL) FatalError ("winAllocateFBPrimaryDD - Could not allocate surface " "description memory\n"); ZeroMemory (pddsdPrimary, sizeof (*pddsdPrimary)); pddsdPrimary->dwSize = sizeof (*pddsdPrimary); /* Describe the offscreen 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 (&ddsd, sizeof (ddsd)); ddsd.dwSize = sizeof (ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; ddsd.dwHeight = pScreenInfo->dwHeight; ddsd.dwWidth = pScreenInfo->dwWidth; /* Create the shadow surface */ ddrval = IDirectDraw2_CreateSurface (pScreenPriv->pdd2, &ddsd, &pScreenPriv->pddsOffscreen, NULL); if (ddrval != DD_OK) FatalError ("winAllocateFBPrimaryDD - Could not create shadow " "surface\n"); ErrorF ("winAllocateFBPrimaryDD - Created offscreen\n"); /* Allocate a DD surface description for our screen privates */ pddsdOffscreen = pScreenPriv->pddsdOffscreen = malloc (sizeof (DDSURFACEDESC)); if (pddsdOffscreen == NULL) FatalError ("winAllocateFBPrimaryDD - Could not allocate surface " "description memory\n"); ZeroMemory (pddsdOffscreen, sizeof (*pddsdOffscreen)); pddsdOffscreen->dwSize = sizeof (*pddsdOffscreen); ErrorF ("winAllocateFBPrimaryDD - Locking primary\n"); /* Lock the primary surface */ ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsPrimary, pScreenInfo->fFullScreen ? NULL:&rcClient, pddsdPrimary, DDLOCK_WAIT, NULL); if (ddrval != DD_OK || pddsdPrimary->lpSurface == NULL) FatalError ("winAllocateFBPrimaryDD - Could not lock " "primary surface\n"); ErrorF ("winAllocateFBPrimaryDD - Locked primary\n"); /* We don't know how to deal with anything other than RGB */ if (!(pddsdPrimary->ddpfPixelFormat.dwFlags & DDPF_RGB)) FatalError ("winAllocateFBPrimaryDD - Color format other than RGB\n"); /* Grab the pitch from the surface desc */ pScreenInfo->dwStride = (pddsdPrimary->u1.lPitch * 8) / pScreenInfo->dwBPP; /* Save the pointer to our surface memory */ pScreenInfo->pfb = pddsdPrimary->lpSurface; /* Grab the color depth and masks from the surface description */ pScreenPriv->dwRedMask = pddsdPrimary->ddpfPixelFormat.u2.dwRBitMask; pScreenPriv->dwGreenMask = pddsdPrimary->ddpfPixelFormat.u3.dwGBitMask; pScreenPriv->dwBlueMask = pddsdPrimary->ddpfPixelFormat.u4.dwBBitMask; ErrorF ("winAllocateFBPrimaryDD - Returning\n"); return TRUE; }
int directdraw_draw(void *pic, int w, int h) { DDSURFACEDESC descriptor; RECT rct; HWND hwndp; #define fourcc(a,b,c,d) (( ((uint32_t)a) | ( ((uint32_t)b) << 8 ) | ( ((uint32_t)c) << 16 ) | ( ((uint32_t)d) << 24 ) )) int bh = h, bw = w; //w = default_sw; //h = default_sh; vdata.getdata(get_window_video, 0, &hwndp, 0); if(!hwndp) return 0; if(video_window_parent != hwndp) { video_uninit(); video_init(hwndp); video_window_parent = hwndp; } if(w != d_width || h != d_height) { if(size_in_list(w, h))size_is_ok = 1; else size_is_ok = 0; if(w && h) { d_width = w; d_height = h; if(lpDDS_secondary) IDirectDrawSurface2_Release(lpDDS_secondary); memset(&descriptor, 0, sizeof(descriptor)); descriptor.dwSize = sizeof(descriptor); descriptor.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; descriptor.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; descriptor.dwWidth = d_width; descriptor.dwHeight = d_height; if(FAILED(IDirectDraw2_CreateSurface(lpDD, &descriptor, &lpDDS_secondary, 0))) return 0; lpDDS_back = lpDDS_secondary; } } if(use_osd_surface) { GetClientRect(video_window, &rct); if(rct.right != window_w || rct.bottom != window_h || osd_created == 0) { window_w = rct.right; window_h = rct.bottom; if(surface_osd) IDirectDrawSurface2_Release(surface_osd); memset( &descriptor, 0, sizeof(descriptor)); descriptor.dwSize = sizeof(descriptor); descriptor.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; descriptor.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; descriptor.dwWidth = window_w; descriptor.dwHeight = window_h; if(FAILED(IDirectDraw2_CreateSurface(lpDD, &descriptor, &surface_osd, 0))) return 0; osd_created = 1; } } IDirectDrawSurface2_Restore(lpDDS); if(pic) IDirectDrawSurface2_Restore(lpDDS_secondary); memset(&descriptor, 0, sizeof(descriptor)); descriptor.dwSize = sizeof(descriptor); if(pic) { HRESULT res; if(size_is_ok) { res = IDirectDrawSurface2_Lock(lpDDS_back, 0, &descriptor, DDLOCK_WAIT | DDLOCK_WRITEONLY, 0); if(FAILED(res)) return 0; memcpy(descriptor.lpSurface, pic, w * h * 4); IDirectDrawSurface2_Unlock(lpDDS_back, descriptor.lpSurface); }else{ HBITMAP bmp; HDC hdc, cdc; bmp = CreateBitmap(w, h, 1, 32, pic); if(!FAILED(IDirectDrawSurface2_GetDC(lpDDS_back, &hdc))) { cdc = CreateCompatibleDC(0); SelectObject(cdc, bmp); BitBlt(hdc, 0, 0, w, h, cdc, 0, 0, SRCCOPY); IDirectDrawSurface2_ReleaseDC(lpDDS_back, hdc); DeleteDC(cdc); } DeleteObject(bmp); } IDirectDrawSurface2_Flip(lpDDS, 0, DDFLIP_WAIT); } return 1; }
int directdraw_init(HWND hwndp) { int width = 320, height = 200; RECT rect; DDPIXELFORMAT format; DDSURFACEDESC descriptor; DIRECTDRAWCREATE DirectDrawCreate; if(lpDDS) return 0; if(!hwndp) return 0; if(video_window) return 0; /* you gotta uninitialize it first */ library = (HMODULE) LoadLibrary(uni("ddraw.dll")); if(!library) return 0; DirectDrawCreate = (DIRECTDRAWCREATE) GetProcAddress(library, "DirectDrawCreate"); if(!DirectDrawCreate) return 0; if(FAILED(DirectDrawCreate(0,&lpDD,0))) return 0; wc.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = 0; wc.hIcon = 0; wc.hCursor = LoadCursor(0, IDC_ARROW); wc.hbrBackground = 0; wc.lpszMenuName = 0; wc.lpszClassName = window_class_name; RegisterClass(&wc); video_window = CreateWindow(window_class_name, uni("Video"), WS_CHILD, 0, 0, width, height, hwndp, 0, 0, 0); ShowWindow(video_window, SW_NORMAL); if(FAILED(IDirectDraw2_SetCooperativeLevel(lpDD, video_window, DDSCL_NORMAL))) return 0; descriptor.dwSize = sizeof(descriptor); descriptor.dwFlags = DDSD_CAPS; descriptor.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY; if(FAILED(IDirectDraw2_CreateSurface(lpDD, &descriptor, &lpDDS, 0))) return 0; descriptor.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; descriptor.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; descriptor.dwWidth = d_width ; descriptor.dwHeight = d_height; if(FAILED(IDirectDraw2_CreateSurface(lpDD, &descriptor, &lpDDS_secondary, 0))) return 0; if(FAILED(IDirectDraw2_CreateClipper(lpDD, 0, &lpDDC, 0))) return 0; if(FAILED(IDirectDrawClipper_SetHWnd(lpDDC, 0, video_window))) return 0; if(FAILED(IDirectDrawSurface2_SetClipper(lpDDS, lpDDC))) return 0; lpDDS_back = lpDDS_secondary; format.dwSize = sizeof(format); if(FAILED(IDirectDrawSurface2_GetPixelFormat(lpDDS, &format))) return 0; if(!(format.dwFlags & DDPF_RGB)) return 0; IDirectDraw2_EnumDisplayModes(lpDD, DDEDM_STANDARDVGAMODES, 0, 0, EnumDisplayModesCallback); osd_initialize(); osd_created = 0; return 1; }
static int DDCreateSurface(directx_priv *priv, ggi_mode *mode) { HRESULT hr; LPDIRECTDRAWCLIPPER pClipper; DDSURFACEDESC pddsd, bddsd; int i; if (!priv->fullscreen) IDirectDraw2_SetCooperativeLevel(priv->lpddext, priv->hWnd, DDSCL_NORMAL); else { /* Only the thread that has excluse access (Cooperative level) * may restore the surfaces when they are lost. Therefore * let the helper thread get exclusive access so that it can * later do restores. */ directx_fullscreen dxfull; dxfull.priv = priv; dxfull.mode = mode; dxfull.event = CreateEvent(NULL, FALSE, FALSE, NULL); PostThreadMessage(priv->nThreadID, WM_DDFULLSCREEN, 0, (long)&dxfull); WaitForSingleObject(dxfull.event, INFINITE); CloseHandle(dxfull.event); } /* create the primary surface */ memset(&pddsd, 0, sizeof(pddsd)); pddsd.dwSize = sizeof(pddsd); pddsd.dwFlags = DDSD_CAPS; pddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; if (priv->fullscreen) pddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY; hr = IDirectDraw2_CreateSurface(priv->lpddext, &pddsd, &priv->lppdds, NULL); if (hr != 0) { fprintf(stderr, "Init Primary Surface Failed RC = %lx. Exiting\n", hr); exit(-1); } IDirectDraw2_CreateClipper(priv->lpddext, 0, &pClipper, NULL); IDirectDrawClipper_SetHWnd(pClipper, 0, priv->hWnd); IDirectDrawSurface_SetClipper(priv->lppdds, pClipper); IDirectDrawClipper_Release(pClipper); pddsd.dwSize = sizeof(pddsd); IDirectDrawSurface_GetSurfaceDesc(priv->lppdds, &pddsd); DPRINT_MISC("DDraw pixel format:\n"); DPRINT_MISC(" Size %u\n", pddsd.ddpfPixelFormat.dwSize); DPRINT_MISC(" Flags %08x\n", pddsd.ddpfPixelFormat.dwFlags); DPRINT_MISC(" FourCC %08x\n", pddsd.ddpfPixelFormat.dwFourCC); DPRINT_MISC(" Count %u\n", pddsd.ddpfPixelFormat.dwRGBBitCount); DPRINT_MISC(" R-Mask(etc) %08x\n", pddsd.ddpfPixelFormat.dwRBitMask); DPRINT_MISC(" G-Mask(etc) %08x\n", pddsd.ddpfPixelFormat.dwGBitMask); DPRINT_MISC(" B-Mask(etc) %08x\n", pddsd.ddpfPixelFormat.dwBBitMask); DPRINT_MISC(" Z-Mask(etc) %08x\n", pddsd.ddpfPixelFormat.dwRGBZBitMask); /* create the back storages */ for (i = 0; i < mode->frames; ++i) { memset(&bddsd, 0, sizeof(bddsd)); bddsd.dwSize = sizeof(bddsd); bddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT; bddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; bddsd.dwWidth = mode->virt.x; bddsd.dwHeight = mode->virt.y; /* set up the pixel format */ ZeroMemory(&bddsd.ddpfPixelFormat, sizeof(DDPIXELFORMAT)); bddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); bddsd.ddpfPixelFormat.dwFlags = pddsd.ddpfPixelFormat.dwFlags; bddsd.ddpfPixelFormat.dwFourCC = pddsd.ddpfPixelFormat.dwFourCC; bddsd.ddpfPixelFormat.dwRGBBitCount = pddsd.ddpfPixelFormat.dwRGBBitCount; bddsd.ddpfPixelFormat.dwRBitMask = pddsd.ddpfPixelFormat.dwRBitMask; bddsd.ddpfPixelFormat.dwGBitMask = pddsd.ddpfPixelFormat.dwGBitMask; bddsd.ddpfPixelFormat.dwBBitMask = pddsd.ddpfPixelFormat.dwBBitMask; bddsd.ddpfPixelFormat.dwRGBAlphaBitMask = pddsd.ddpfPixelFormat.dwRGBAlphaBitMask; hr = IDirectDraw2_CreateSurface(priv->lpddext, &bddsd, &priv->lpbdds[i], NULL); if (hr) { fprintf(stderr, "Init Backup Failed RC = %lx. Exiting\n", hr); exit(-1); } IDirectDrawSurface2_Lock(priv->lpbdds[i], NULL, &bddsd, DDLOCK_SURFACEMEMORYPTR, NULL); priv->lpSurfaceAdd[i] = (char *) bddsd.lpSurface; IDirectDrawSurface2_Unlock(priv->lpbdds[i], bddsd.lpSurface); } /* set private mode parameters */ priv->maxX = mode->virt.x; priv->maxY = mode->virt.y; priv->ColorDepth = pddsd.ddpfPixelFormat.dwRGBBitCount; priv->pitch = bddsd.lPitch; if (pddsd.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) { static PALETTEENTRY pal[256]; /* todo fill in pal */ hr = IDirectDraw_CreatePalette(priv->lpddext, DDPCAPS_8BIT|DDPCAPS_ALLOW256, pal, &priv->lpddp, NULL); if (hr) { fprintf(stderr, "Init Palette failed RC = %lx. Exiting\n", hr); exit(-1); } hr = IDirectDrawSurface_SetPalette(priv->lppdds, priv->lpddp); if (hr) { fprintf(stderr, "Install Palette failed RC = %lx. Exiting\n", hr); exit(-1); } } return 1; }
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); }
/* create_directdraw2_surface: * Wrapper around DirectDraw2::CreateSurface taking the surface characteristics * as parameters. Returns a DirectDrawSurface2 interface if successful. */ static LPDIRECTDRAWSURFACE2 create_directdraw2_surface(int w, int h, LPDDPIXELFORMAT pixel_format, int type, int n_backbuffers) { DDSURFACEDESC ddsurf_desc; LPDIRECTDRAWSURFACE ddsurf1; LPVOID ddsurf2; HRESULT hr; /* describe surface characteristics */ memset(&ddsurf_desc, 0, sizeof(DDSURFACEDESC)); ddsurf_desc.dwSize = sizeof(DDSURFACEDESC); ddsurf_desc.dwFlags = DDSD_CAPS; switch (type) { case DDRAW_SURFACE_PRIMARY: ddsurf_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; _TRACE(PREFIX_I "Creating primary surface..."); break; case DDRAW_SURFACE_OVERLAY: ddsurf_desc.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_OVERLAY; ddsurf_desc.dwFlags |= DDSD_HEIGHT | DDSD_WIDTH; ddsurf_desc.dwHeight = h; ddsurf_desc.dwWidth = w; if (pixel_format) { /* use pixel format */ ddsurf_desc.dwFlags |= DDSD_PIXELFORMAT; ddsurf_desc.ddpfPixelFormat = *pixel_format; } _TRACE(PREFIX_I "Creating overlay surface..."); break; case DDRAW_SURFACE_VIDEO: ddsurf_desc.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_OFFSCREENPLAIN; ddsurf_desc.dwFlags |= DDSD_HEIGHT | DDSD_WIDTH; ddsurf_desc.dwHeight = h; ddsurf_desc.dwWidth = w; _TRACE(PREFIX_I "Creating video surface..."); break; case DDRAW_SURFACE_SYSTEM: ddsurf_desc.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN; ddsurf_desc.dwFlags |= DDSD_HEIGHT | DDSD_WIDTH; ddsurf_desc.dwHeight = h; ddsurf_desc.dwWidth = w; if (pixel_format) { /* use pixel format */ ddsurf_desc.dwFlags |= DDSD_PIXELFORMAT; ddsurf_desc.ddpfPixelFormat = *pixel_format; } _TRACE(PREFIX_I "Creating system surface..."); break; default: _TRACE(PREFIX_E "Unknown surface type\n"); return NULL; } /* set backbuffer requirements */ if (n_backbuffers > 0) { ddsurf_desc.ddsCaps.dwCaps |= DDSCAPS_COMPLEX | DDSCAPS_FLIP; ddsurf_desc.dwFlags |= DDSD_BACKBUFFERCOUNT; ddsurf_desc.dwBackBufferCount = n_backbuffers; _TRACE("...with %d backbuffer(s)\n", n_backbuffers); } /* create the surface */ hr = IDirectDraw2_CreateSurface(directdraw, &ddsurf_desc, &ddsurf1, NULL); if (FAILED(hr)) { _TRACE(PREFIX_E "Unable to create the surface (%s)\n", dd_err(hr)); return NULL; } /* retrieve the DirectDrawSurface2 interface */ hr = IDirectDrawSurface_QueryInterface(ddsurf1, &IID_IDirectDrawSurface2, &ddsurf2); /* there is a bug in the COM part of DirectX 3: * If we release the DirectSurface interface, the actual * object is also released. It is fixed in DirectX 5. */ if (_dx_ver >= 0x500) IDirectDrawSurface_Release(ddsurf1); if (FAILED(hr)) { _TRACE(PREFIX_E "Unable to retrieve the DirectDrawSurface2 interface (%s)\n", dd_err(hr)); return NULL; } return (LPDIRECTDRAWSURFACE2)ddsurf2; }
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); }