/** * This function locks a surface and get the surface descriptor. */ static int DirectXLockSurface(LPDIRECTDRAWSURFACE2 front_surface, LPDIRECTDRAWSURFACE2 surface, DDSURFACEDESC *ddsd) { HRESULT hr; DDSURFACEDESC ddsd_dummy; if (!ddsd) ddsd = &ddsd_dummy; ZeroMemory(ddsd, sizeof(*ddsd)); ddsd->dwSize = sizeof(*ddsd); hr = IDirectDrawSurface2_Lock(surface, NULL, ddsd, DDLOCK_NOSYSLOCK | DDLOCK_WAIT, NULL); if (hr != DD_OK) { if (hr == DDERR_INVALIDPARAMS) { /* DirectX 3 doesn't support the DDLOCK_NOSYSLOCK flag, resulting * in an invalid params error */ hr = IDirectDrawSurface2_Lock(surface, NULL, ddsd, DDLOCK_WAIT, NULL); } if (hr == DDERR_SURFACELOST) { /* Your surface can be lost so be sure * to check this and restore it if needed */ /* When using overlays with back-buffers, we need to restore * the front buffer so the back-buffers get restored as well. */ if (front_surface != surface) IDirectDrawSurface2_Restore(front_surface); else IDirectDrawSurface2_Restore(surface); hr = IDirectDrawSurface2_Lock(surface, NULL, ddsd, DDLOCK_WAIT, NULL); } if (hr != DD_OK) return VLC_EGENERIC; } return VLC_SUCCESS; }
static Bool winActivateAppShadowDD (ScreenPtr pScreen) { winScreenPriv(pScreen); /* * Do we have a surface? * Are we active? * Are we fullscreen? */ if (pScreenPriv != NULL && pScreenPriv->pddsPrimary != NULL && pScreenPriv->fActive) { /* Primary surface was lost, restore it */ IDirectDrawSurface2_Restore (pScreenPriv->pddsPrimary); } return TRUE; }
/* restore_all_ddraw_surfaces: * Restores all the surfaces. Returns 0 on success or -1 on failure, * in which case restoring is stopped at the first failure. */ int restore_all_ddraw_surfaces(void) { DDRAW_SURFACE *item = ddraw_surface_list; HRESULT hr; _enter_gfx_critical(); while (item) { hr = IDirectDrawSurface2_Restore(item->id); if (FAILED(hr)) { _exit_gfx_critical(); return -1; } item = item->next; } _exit_gfx_critical(); _TRACE(PREFIX_I "all DirectDraw surfaces restored\n"); return 0; }
static Bool winBltExposedRegionsShadowDD (ScreenPtr pScreen) { winScreenPriv(pScreen); winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; RECT rcSrc, rcDest; POINT ptOrigin; HDC hdcUpdate = NULL; PAINTSTRUCT ps; HRESULT ddrval = DD_OK; Bool fReturn = TRUE; Bool fLocked = TRUE; int i; /* BeginPaint gives us an hdc that clips to the invalidated region */ hdcUpdate = BeginPaint (pScreenPriv->hwndScreen, &ps); if (hdcUpdate == NULL) { ErrorF ("winBltExposedRegionsShadowDD - BeginPaint () returned " "a NULL device context handle. Aborting blit attempt.\n"); return FALSE; } /* Unlock the shadow surface, so we can blit */ ddrval = IDirectDrawSurface2_Unlock (pScreenPriv->pddsShadow, NULL); if (FAILED (ddrval)) { fReturn = FALSE; goto winBltExposedRegionsShadowDD_Exit; } else { /* Flag that we have unlocked the shadow surface */ fLocked = FALSE; } /* Get the origin of the window in the screen coords */ ptOrigin.x = pScreenInfo->dwXOffset; ptOrigin.y = pScreenInfo->dwYOffset; MapWindowPoints (pScreenPriv->hwndScreen, HWND_DESKTOP, (LPPOINT)&ptOrigin, 1); rcDest.left = ptOrigin.x; rcDest.right = ptOrigin.x + pScreenInfo->dwWidth; rcDest.top = ptOrigin.y; rcDest.bottom = ptOrigin.y + pScreenInfo->dwHeight; /* Source can be enter shadow surface, as Blt should clip */ rcSrc.left = 0; rcSrc.top = 0; rcSrc.right = pScreenInfo->dwWidth; rcSrc.bottom = pScreenInfo->dwHeight; /* Try to regain the primary surface and blit again if we've lost it */ for (i = 0; i <= WIN_REGAIN_SURFACE_RETRIES; ++i) { /* Our Blt should be clipped to the invalidated region */ ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary, &rcDest, pScreenPriv->pddsShadow, &rcSrc, DDBLT_WAIT, NULL); if (ddrval == DDERR_SURFACELOST) { /* Surface was lost */ ErrorF ("winBltExposedRegionsShadowDD - IDirectDrawSurface2_Blt " "reported that the primary surface was lost, " "trying to restore, retry: %d\n", i + 1); /* Try to restore the surface, once */ ddrval = IDirectDrawSurface2_Restore (pScreenPriv->pddsPrimary); ErrorF ("winBltExposedRegionsShadowDD - " "IDirectDrawSurface2_Restore returned: "); if (ddrval == DD_OK) ErrorF ("DD_OK\n"); else if (ddrval == DDERR_WRONGMODE) ErrorF ("DDERR_WRONGMODE\n"); else if (ddrval == DDERR_INCOMPATIBLEPRIMARY) ErrorF ("DDERR_INCOMPATIBLEPRIMARY\n"); else if (ddrval == DDERR_UNSUPPORTED) ErrorF ("DDERR_UNSUPPORTED\n"); else if (ddrval == DDERR_INVALIDPARAMS) ErrorF ("DDERR_INVALIDPARAMS\n"); else if (ddrval == DDERR_INVALIDOBJECT) ErrorF ("DDERR_INVALIDOBJECT\n"); else ErrorF ("unknown error: %08x\n", (unsigned int) ddrval); /* Loop around to try the blit one more time */ continue; } else if (FAILED (ddrval)) { fReturn = FALSE; ErrorF ("winBltExposedRegionsShadowDD - IDirectDrawSurface2_Blt " "failed, but surface not lost: %08x %d\n", (unsigned int) ddrval, (int) ddrval); goto winBltExposedRegionsShadowDD_Exit; } else { /* Success, stop looping */ break; } } /* Relock the shadow surface */ ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsShadow, NULL, pScreenPriv->pddsdShadow, DDLOCK_WAIT, NULL); if (FAILED (ddrval)) { fReturn = FALSE; ErrorF ("winBltExposedRegionsShadowDD - IDirectDrawSurface2_Lock " "failed\n"); goto winBltExposedRegionsShadowDD_Exit; } else { /* Indicate that we have relocked the shadow surface */ fLocked = TRUE; } /* Has our memory pointer changed? */ if (pScreenInfo->pfb != pScreenPriv->pddsdShadow->lpSurface) winUpdateFBPointer (pScreen, pScreenPriv->pddsdShadow->lpSurface); winBltExposedRegionsShadowDD_Exit: /* EndPaint frees the DC */ if (hdcUpdate != NULL) EndPaint (pScreenPriv->hwndScreen, &ps); /* * Relock the surface if it is not locked. We don't care if locking fails, * as it will cause the server to shutdown within a few more operations. */ if (!fLocked) { IDirectDrawSurface2_Lock (pScreenPriv->pddsShadow, NULL, pScreenPriv->pddsdShadow, DDLOCK_WAIT, NULL); /* Has our memory pointer changed? */ if (pScreenInfo->pfb != pScreenPriv->pddsdShadow->lpSurface) winUpdateFBPointer (pScreen, pScreenPriv->pddsdShadow->lpSurface); fLocked = TRUE; } return fReturn; }
Bool winHotKeyAltTabPrimaryDD (ScreenPtr pScreen) { winScreenPriv(pScreen); winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; RECT rcClient, rcSrc; HRESULT ddrval = DD_OK; ErrorF ("\nwinHotKeyAltTabPrimaryDD\n\n"); /* Alt+Tab was pressed, we will lose focus very soon */ pScreenPriv->fActive = FALSE; /* Check for error conditions */ if (pScreenPriv->pddsPrimary == NULL || pScreenPriv->pddsOffscreen == NULL) return FALSE; /* Get client area in screen coords */ GetClientRect (pScreenPriv->hwndScreen, &rcClient); MapWindowPoints (pScreenPriv->hwndScreen, HWND_DESKTOP, (LPPOINT)&rcClient, 2); /* Did we loose the primary surface? */ ddrval = IDirectDrawSurface2_IsLost (pScreenPriv->pddsPrimary); if (ddrval == DD_OK) { ddrval = IDirectDrawSurface2_Unlock (pScreenPriv->pddsPrimary, NULL); if (FAILED (ddrval)) FatalError ("winHotKeyAltTabPrimaryDD - Failed unlocking primary " "surface\n"); } /* Setup a source rectangle */ rcSrc.left = 0; rcSrc.top = 0; rcSrc.right = pScreenInfo->dwWidth; rcSrc.bottom = pScreenInfo->dwHeight; /* Blit the primary surface to the offscreen surface */ ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsOffscreen, NULL, /* should be rcDest */ pScreenPriv->pddsPrimary, NULL, DDBLT_WAIT, NULL); if (ddrval == DDERR_SURFACELOST) { IDirectDrawSurface2_Restore (pScreenPriv->pddsOffscreen); IDirectDrawSurface2_Restore (pScreenPriv->pddsPrimary); /* Blit the primary surface to the offscreen surface */ ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsOffscreen, NULL, pScreenPriv->pddsPrimary, NULL, DDBLT_WAIT, NULL); if (FAILED (ddrval)) FatalError ("winHotKeyAltTabPrimaryDD - Failed blitting primary " "surface to offscreen surface: %08x\n", ddrval); } else { FatalError ("winHotKeyAltTabPrimaryDD - Unknown error from " "Blt: %08dx\n", ddrval); } /* Lock the offscreen surface */ ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsOffscreen, NULL, pScreenPriv->pddsdOffscreen, DDLOCK_WAIT, NULL); if (ddrval != DD_OK || pScreenPriv->pddsdPrimary->lpSurface == NULL) FatalError ("winHotKeyAltTabPrimaryDD - Could not lock " "offscreen surface\n"); /* Notify FB of the new memory pointer */ winUpdateFBPointer (pScreen, pScreenPriv->pddsdOffscreen->lpSurface); /* Unregister our hotkey */ UnregisterHotKey (pScreenPriv->hwndScreen, 1); return TRUE; }
Bool winActivateAppPrimaryDD (ScreenPtr pScreen) { winScreenPriv(pScreen); winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; RECT rcSrc, rcClient; HRESULT ddrval = DD_OK; /* Check for errors */ if (pScreenPriv == NULL || pScreenPriv->pddsPrimary == NULL || pScreenPriv->pddsOffscreen == NULL) return FALSE; /* Check for do-nothing */ if (!pScreenPriv->fActive) return TRUE; /* We are activating */ ddrval = IDirectDrawSurface2_IsLost (pScreenPriv->pddsOffscreen); if (ddrval == DD_OK) { IDirectDrawSurface2_Unlock (pScreenPriv->pddsOffscreen, NULL); /* * We don't check for an error from Unlock, because it * doesn't matter if the Unlock failed. */ } /* Restore both surfaces, just cause I like it that way */ IDirectDrawSurface2_Restore (pScreenPriv->pddsOffscreen); IDirectDrawSurface2_Restore (pScreenPriv->pddsPrimary); /* Get client area in screen coords */ GetClientRect (pScreenPriv->hwndScreen, &rcClient); MapWindowPoints (pScreenPriv->hwndScreen, HWND_DESKTOP, (LPPOINT)&rcClient, 2); /* Setup a source rectangle */ rcSrc.left = 0; rcSrc.top = 0; rcSrc.right = pScreenInfo->dwWidth; rcSrc.bottom = pScreenInfo->dwHeight; ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary, &rcClient, pScreenPriv->pddsOffscreen, &rcSrc, DDBLT_WAIT, NULL); if (ddrval != DD_OK) FatalError ("winActivateAppPrimaryDD () - Failed blitting offscreen " "surface to primary surface %08x\n", ddrval); /* Lock the primary surface */ ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsPrimary, &rcClient, pScreenPriv->pddsdPrimary, DDLOCK_WAIT, NULL); if (ddrval != DD_OK || pScreenPriv->pddsdPrimary->lpSurface == NULL) FatalError ("winActivateAppPrimaryDD () - Could not lock " "primary surface\n"); /* Notify FB of the new memory pointer */ winUpdateFBPointer (pScreen, pScreenPriv->pddsdPrimary->lpSurface); /* * Register the Alt-Tab combo as a hotkey so we can copy * the primary framebuffer before the display mode changes */ RegisterHotKey (pScreenPriv->hwndScreen, 1, MOD_ALT, 9); 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; }
void DDRestoreSurface( LPDIRECTDRAWSURFACE2 pSurface ) { Assert( pSurface != NULL ); ATTEMPT( IDirectDrawSurface2_Restore( pSurface ) ); }