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; }
/** * It finds out the 32bits RGB pixel value of the colorkey. */ static uint32_t DirectXFindColorkey(vout_display_t *vd, uint32_t *color) { vout_display_sys_t *sys = vd->sys; HRESULT hr; /* */ DDSURFACEDESC ddsd; ddsd.dwSize = sizeof(ddsd); hr = IDirectDrawSurface2_Lock(sys->display, NULL, &ddsd, DDLOCK_WAIT, NULL); if (hr != DD_OK) return 0; uint32_t backup = *(uint32_t *)ddsd.lpSurface; switch (ddsd.ddpfPixelFormat.dwRGBBitCount) { case 4: *(uint8_t *)ddsd.lpSurface = *color | (*color << 4); break; case 8: *(uint8_t *)ddsd.lpSurface = *color; break; case 15: case 16: *(uint16_t *)ddsd.lpSurface = *color; break; case 24: /* Seems to be problematic so we'll just put black as the colorkey */ *color = 0; default: *(uint32_t *)ddsd.lpSurface = *color; break; } IDirectDrawSurface2_Unlock(sys->display, NULL); /* */ HDC hdc; COLORREF rgb; if (IDirectDrawSurface2_GetDC(sys->display, &hdc) == DD_OK) { rgb = GetPixel(hdc, 0, 0); IDirectDrawSurface2_ReleaseDC(sys->display, hdc); } else { rgb = 0; } /* Restore the pixel value */ ddsd.dwSize = sizeof(ddsd); if (IDirectDrawSurface2_Lock(sys->display, NULL, &ddsd, DDLOCK_WAIT, NULL) == DD_OK) { *(uint32_t *)ddsd.lpSurface = backup; IDirectDrawSurface2_Unlock(sys->display, NULL); } return rgb; }
void DDUnlockSurface( LPDIRECTDRAWSURFACE2 pSurface, PTR pSurfaceData ) { Assert( pSurface != NULL ); ATTEMPT( IDirectDrawSurface2_Unlock( pSurface, pSurfaceData ) ); }
/* gfx_directx_unlock: * Unlocks the surface. */ void gfx_directx_unlock(BITMAP *bmp) { DDRAW_SURFACE *surf; BITMAP *parent; HRESULT hr; if (bmp->id & BMP_ID_SUB) { /* recurse when unlocking sub-bitmaps */ parent = (BITMAP *)bmp->extra; gfx_directx_unlock(parent); if (!(parent->id & BMP_ID_LOCKED)) bmp->id &= ~BMP_ID_LOCKED; } else { /* regular bitmaps can be unlocked directly */ surf = DDRAW_SURFACE_OF(bmp); if (surf->lock_nesting > 0) { surf->lock_nesting--; if ((!surf->lock_nesting) && (bmp->id & BMP_ID_LOCKED)) { if (!(surf->flags & DDRAW_SURFACE_LOST)) { /* only unlock if it doesn't use pseudo video memory */ hr = IDirectDrawSurface2_Unlock(surf->id, NULL); /* If the surface has been lost, try to restore all surfaces * and, on success, try again to unlock the surface. */ if (hr == DDERR_SURFACELOST) { if (restore_all_ddraw_surfaces() == 0) hr = IDirectDrawSurface2_Unlock(surf->id, NULL); } if (FAILED(hr)) _TRACE(PREFIX_E "Can't unlock surface (%x)\n", hr); } bmp->id &= ~BMP_ID_LOCKED; } /* release bitmap for other threads */ _exit_gfx_critical(); } } }
/* gfx_directx_release_lock: * Releases the surface lock, for hardware accelerated drawing. */ void gfx_directx_release_lock(BITMAP *bmp) { DDRAW_SURFACE *surf; HRESULT hr; /* handle display switch */ if (!_win_app_foreground) gfx_directx_switch_out(); /* find parent */ while (bmp->id & BMP_ID_SUB) { bmp->id &= ~BMP_ID_LOCKED; bmp = (BITMAP *)bmp->extra; } if (bmp->id & BMP_ID_LOCKED) { surf = DDRAW_SURFACE_OF(bmp); if (!(surf->flags & DDRAW_SURFACE_LOST)) { /* only unlock if it doesn't use pseudo video memory */ hr = IDirectDrawSurface2_Unlock(surf->id, NULL); /* If the surface has been lost, try to restore all surfaces * and, on success, try again to unlock the surface. */ if (hr == DDERR_SURFACELOST) { if (restore_all_ddraw_surfaces() == 0) hr = IDirectDrawSurface2_Unlock(surf->id, NULL); } if (FAILED(hr)) _TRACE(PREFIX_E "Can't release lock (%x)\n", hr); } bmp->id &= ~BMP_ID_LOCKED; } }
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; }
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; }
static void winShadowUpdateDD (ScreenPtr pScreen, shadowBufPtr pBuf) { winScreenPriv(pScreen); winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; RegionPtr damage = shadowDamage(pBuf); HRESULT ddrval = DD_OK; RECT rcDest, rcSrc; POINT ptOrigin; DWORD dwBox = REGION_NUM_RECTS (damage); BoxPtr pBox = REGION_RECTS (damage); HRGN hrgnTemp = NULL, hrgnCombined = NULL; /* * Return immediately if the app is not active * and we are fullscreen, or if we have a bad display depth */ if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen) || pScreenPriv->fBadDepth) return; /* 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); /* Unlock the shadow surface, so we can blit */ ddrval = IDirectDrawSurface2_Unlock (pScreenPriv->pddsShadow, NULL); if (FAILED (ddrval)) { ErrorF ("winShadowUpdateDD - Unlock failed\n"); return; } /* * Handle small regions with multiple blits, * handle large regions by creating a clipping region and * doing a single blit constrained to that clipping region. */ if (pScreenInfo->dwClipUpdatesNBoxes == 0 || dwBox < pScreenInfo->dwClipUpdatesNBoxes) { /* Loop through all boxes in the damaged region */ while (dwBox--) { /* Assign damage box to source rectangle */ rcSrc.left = pBox->x1; rcSrc.top = pBox->y1; rcSrc.right = pBox->x2; rcSrc.bottom = pBox->y2; /* Calculate destination rectange */ rcDest.left = ptOrigin.x + rcSrc.left; rcDest.top = ptOrigin.y + rcSrc.top; rcDest.right = ptOrigin.x + rcSrc.right; rcDest.bottom = ptOrigin.y + rcSrc.bottom; /* Blit the damaged areas */ ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary, &rcDest, pScreenPriv->pddsShadow, &rcSrc, DDBLT_WAIT, NULL); /* Get a pointer to the next box */ ++pBox; } } else { BoxPtr pBoxExtents = REGION_EXTENTS (pScreen, damage); /* Compute a GDI region from the damaged region */ hrgnCombined = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2); dwBox--; pBox++; while (dwBox--) { hrgnTemp = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2); CombineRgn (hrgnCombined, hrgnCombined, hrgnTemp, RGN_OR); DeleteObject (hrgnTemp); pBox++; } /* Install the GDI region as a clipping region */ SelectClipRgn (pScreenPriv->hdcScreen, hrgnCombined); DeleteObject (hrgnCombined); hrgnCombined = NULL; /* Calculating a bounding box for the source is easy */ rcSrc.left = pBoxExtents->x1; rcSrc.top = pBoxExtents->y1; rcSrc.right = pBoxExtents->x2; rcSrc.bottom = pBoxExtents->y2; /* Calculating a bounding box for the destination is trickier */ rcDest.left = ptOrigin.x + rcSrc.left; rcDest.top = ptOrigin.y + rcSrc.top; rcDest.right = ptOrigin.x + rcSrc.right; rcDest.bottom = ptOrigin.y + rcSrc.bottom; /* Our Blt should be clipped to the invalidated region */ ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary, &rcDest, pScreenPriv->pddsShadow, &rcSrc, DDBLT_WAIT, NULL); /* Reset the clip region */ SelectClipRgn (pScreenPriv->hdcScreen, NULL); } /* Relock the shadow surface */ ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsShadow, NULL, pScreenPriv->pddsdShadow, DDLOCK_WAIT, NULL); if (FAILED (ddrval)) { ErrorF ("winShadowUpdateDD - Lock failed\n"); return; } /* Has our memory pointer changed? */ if (pScreenInfo->pfb != pScreenPriv->pddsdShadow->lpSurface) { ErrorF ("winShadowUpdateDD - Memory location of the shadow " "surface has changed, trying to update the root window " "pixmap header to point to the new address. If you get " "this message and "PROJECT_NAME" freezes or crashes " "after this message then send a problem report and your " "%s file to " BUILDERADDR, g_pszLogFile); /* Location of shadow framebuffer has changed */ pScreenInfo->pfb = pScreenPriv->pddsdShadow->lpSurface; /* Update the screen pixmap */ if (!(*pScreen->ModifyPixmapHeader)(pScreen->devPrivate, pScreen->width, pScreen->height, pScreen->rootDepth, BitsPerPixel (pScreen->rootDepth), PixmapBytePad (pScreenInfo->dwStride, pScreenInfo->dwBPP), pScreenInfo->pfb)) { ErrorF ("winShadowUpdateDD - Bits changed, could not " "notify fb.\n"); return; } } }
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; }
static void DirectXUnlockSurface(LPDIRECTDRAWSURFACE2 front_surface, LPDIRECTDRAWSURFACE2 surface) { VLC_UNUSED(front_surface); IDirectDrawSurface2_Unlock(surface, NULL); }
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; }
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; }
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; }
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; }