VOID APIENTRY VBoxDispDrvDisableSurface(DHPDEV dhpdev) { PVBOXDISPDEV pDev = (PVBOXDISPDEV)dhpdev; LOGF_ENTER(); if (pDev->surface.hSurface) { EngDeleteSurface(pDev->surface.hSurface); pDev->surface.hSurface = NULL; } if (pDev->surface.psoBitmap) { Assert(pDev->surface.hBitmap); EngUnlockSurface(pDev->surface.psoBitmap); pDev->surface.psoBitmap = NULL; } if (pDev->surface.hBitmap) { EngDeleteSurface((HSURF) pDev->surface.hBitmap); pDev->surface.hBitmap = NULL; } int rc; rc = VBoxDispMPUnmapMemory(pDev); VBOX_WARNRC(rc); LOGF_LEAVE(); }
VOID DrvDeleteDeviceBitmap( DHSURF dhsurf) { DSURF* pdsurf; PDEV* ppdev; SURFOBJ* psoDib; HSURF hsurfDib; pdsurf = (DSURF*) dhsurf; ppdev = pdsurf->ppdev; if (pdsurf->dt == DT_SCREEN) { pohFree(ppdev, pdsurf->poh); } else { ASSERTDD(pdsurf->dt == DT_DIB, "Expected DIB type"); psoDib = pdsurf->pso; // Get the hsurf from the SURFOBJ before we unlock it (it's not // legal to dereference psoDib when it's unlocked): hsurfDib = psoDib->hsurf; EngUnlockSurface(psoDib); EngDeleteSurface(hsurfDib); } EngFreeMem(pdsurf); }
BOOL APIENTRY IntEngLeave(PINTENG_ENTER_LEAVE EnterLeave) { POINTL SrcPoint; BOOL Result = TRUE; if (EnterLeave->OutputObj != EnterLeave->DestObj && NULL != EnterLeave->OutputObj) { if (! EnterLeave->ReadOnly) { SrcPoint.x = 0; SrcPoint.y = 0; if (EnterLeave->DestRect.left < 0) { SrcPoint.x = - EnterLeave->DestRect.left; EnterLeave->DestRect.left = 0; } if (EnterLeave->DestObj->sizlBitmap.cx < EnterLeave->DestRect.right) { EnterLeave->DestRect.right = EnterLeave->DestObj->sizlBitmap.cx; } if (EnterLeave->DestRect.top < 0) { SrcPoint.y = - EnterLeave->DestRect.top; EnterLeave->DestRect.top = 0; } if (EnterLeave->DestObj->sizlBitmap.cy < EnterLeave->DestRect.bottom) { EnterLeave->DestRect.bottom = EnterLeave->DestObj->sizlBitmap.cy; } if (SrcPoint.x < EnterLeave->OutputObj->sizlBitmap.cx && EnterLeave->DestRect.left <= EnterLeave->DestRect.right && EnterLeave->DestRect.left < EnterLeave->DestObj->sizlBitmap.cx && SrcPoint.y < EnterLeave->OutputObj->sizlBitmap.cy && EnterLeave->DestRect.top <= EnterLeave->DestRect.bottom && EnterLeave->DestRect.top < EnterLeave->DestObj->sizlBitmap.cy) { Result = GDIDEVFUNCS(EnterLeave->DestObj).CopyBits( EnterLeave->DestObj, EnterLeave->OutputObj, EnterLeave->TrivialClipObj, NULL, &EnterLeave->DestRect, &SrcPoint); } else { Result = TRUE; } } EngUnlockSurface(EnterLeave->OutputObj); EngDeleteSurface((HSURF)EnterLeave->OutputBitmap); EngDeleteClip(EnterLeave->TrivialClipObj); } else { Result = TRUE; } return Result; }
static VOID FreeDrawArea(DrawArea *drawarea) { if (drawarea->surf_obj) { EngUnlockSurface(drawarea->surf_obj); EngDeleteSurface(drawarea->bitmap); drawarea->surf_obj = NULL; } }
BOOL bMoveDibToOffscreenDfbIfRoom( PDEV* ppdev, DSURF* pdsurf) { OH* poh; SURFOBJ* pso; RECTL rclDst; POINTL ptlSrc; HSURF hsurf; ASSERTDD(pdsurf->dt == DT_DIB, "Can't move a bitmap off-screen when it's already off-screen"); // If we're in full-screen mode, we can't move anything to off-screen // memory: if (!ppdev->bEnabled) return(FALSE); poh = pohAllocate(ppdev, pdsurf->sizl.cx, pdsurf->sizl.cy, FLOH_ONLY_IF_ROOM); if (poh == NULL) { // There wasn't any free room. return(FALSE); } // 'pdsurf->sizl' is the actual bitmap dimension, not 'poh->cx' or // 'poh->cy'. rclDst.left = poh->x; rclDst.top = poh->y; rclDst.right = rclDst.left + pdsurf->sizl.cx; rclDst.bottom = rclDst.top + pdsurf->sizl.cy; ptlSrc.x = 0; ptlSrc.y = 0; vPutBits(ppdev, pdsurf->pso, &rclDst, &ptlSrc); // Update the data structures to reflect the new off-screen node: pso = pdsurf->pso; pdsurf->dt = DT_SCREEN; pdsurf->poh = poh; poh->pdsurf = pdsurf; // Now free the DIB. Get the hsurf from the SURFOBJ before we unlock // it (it's not legal to dereference psoDib when it's unlocked): hsurf = pso->hsurf; EngUnlockSurface(pso); EngDeleteSurface(hsurf); return(TRUE); }
VOID DrvDisableSurface( DHPDEV dhpdev) { PDEV* ppdev; HSURF hsurf; ppdev = (PDEV*) dhpdev; // Note: In an error case, some of the following relies on the // fact that the PDEV is zero-initialized, so fields like // 'hsurfScreen' will be zero unless the surface has been // sucessfully initialized, and makes the assumption that // EngDeleteSurface can take '0' as a parameter. vDisableHardware(ppdev); hsurf = ppdev->pso->hsurf; EngUnlockSurface(ppdev->pso); EngDeleteSurface(hsurf); }
BOOL bSetSimPointerShape ( SURFOBJ *pso, SURFOBJ *psoMask, SURFOBJ *psoColor, XLATEOBJ *pxlo, LONG x, LONG y, FLONG fl ) { PPDEV ppdev = (PPDEV) pso->dhpdev; PVIDEO_POINTER_ATTRIBUTES pPointerAttributes = ppdev->pPointerAttributes; ULONG cxSrc, cySrc, cxSrcBytes; ULONG ulOffset; HSURF hsurf; SIZEL sizl; ULONG ulBitmapType; FLONG flBitmap; SURFOBJ *psoSrc; SURFOBJ *psoDst; RECTL prclDst; POINTL pptlSrc; XLATEOBJ xlo; ULONG ulXlate[2]; if (!(ppdev->flCaps & CAPS_NEED_SW_POINTER)) { return FALSE; } /* endif */ // // Check if we have enough off-screen memory to hold the screen image underneath // the new pointer // cxSrc = psoMask->sizlBitmap.cx; cySrc = psoMask->sizlBitmap.cy >> 1; cxSrcBytes = (cxSrc + 7) / 8; ulOffset = ppdev->cyScreen * ppdev->lDeltaScreen; ulOffset += 64; // skip over solid color pattern used in bitblt.c ulOffset += 1024; // skip over hardware pointer bitmap if ((ppdev->cScreenSize < ulOffset + cxSrc * cySrc * (ppdev->ulBitCount/8)) || (psoMask->iType & STYPE_BITMAP) || (!(psoMask->fjBitmap & BMF_TOPDOWN))) { return FALSE; } /* endif */ // // Update the attributes of pointer // pPointerAttributes->Width = cxSrc; pPointerAttributes->Height = cySrc; pPointerAttributes->WidthInBytes = cxSrcBytes; // // Discard the old pointer // if (ppdev->hsurfMask != NULL) { EngDeleteSurface(ppdev->hsurfMask); EngDeleteSurface(ppdev->hsurfColor); } /* endif */ // // Create a copy of mask bitmap // sizl.cx = cxSrc; sizl.cy = cySrc; flBitmap = BMF_TOPDOWN; prclDst.top = 0; prclDst.bottom = cySrc; prclDst.left = 0; prclDst.right = cxSrc; psoSrc = psoMask; ulBitmapType = BMF_1BPP; pptlSrc.x = 0; pptlSrc.y = 0; if (NULL == (hsurf = (HSURF) EngCreateBitmap(sizl, 0, // Let GDI choose ulWidth ulBitmapType, flBitmap, NULL))) { // Let GDI allocate return FALSE; } else { ppdev->hsurfMask = hsurf; } /* endif */ psoDst = EngLockSurface(ppdev->hsurfMask); if (!EngCopyBits(psoDst, // Target surface psoSrc, // Source surface (CLIPOBJ *) NULL, // Clip through this (XLATEOBJ *) NULL, // Color translation &prclDst, // Target offset and extent &pptlSrc)) { // Source offset EngDeleteSurface(ppdev->hsurfMask); return FALSE; } /* endif */ EngUnlockSurface(psoDst); // // Create a copy of pointer bitmap // ulBitmapType = pso->iBitmapFormat; if (psoColor == (SURFOBJ *) NULL) { // // Use second half of mask bitmap if it is monochrome // pPointerAttributes->Flags |= VIDEO_MODE_MONO_POINTER; pPointerAttributes->Flags &= ~VIDEO_MODE_COLOR_POINTER; psoSrc = psoMask; pptlSrc.x = 0; pptlSrc.y = cySrc; // // Create the translation table for monochrome-to-color conversion // pxlo = &xlo; xlo.iUniq = 0; xlo.flXlate = XO_TABLE; xlo.iSrcType = PAL_INDEXED; xlo.iDstType = (ppdev->ulBitCount == 8) ? PAL_INDEXED : PAL_RGB; xlo.cEntries = 2; xlo.pulXlate = (ULONG *)ulXlate; ulXlate[0] = 0x00000000; // Black ulXlate[1] = (ppdev->ulBitCount == 8) ? 0x000000FF : 0x00FFFFFF; // White } else { pPointerAttributes->Flags &= ~VIDEO_MODE_MONO_POINTER; pPointerAttributes->Flags |= VIDEO_MODE_COLOR_POINTER; psoSrc = psoColor; pptlSrc.x = 0; pptlSrc.y = 0; } /* endif */ if (NULL == (hsurf = (HSURF) EngCreateBitmap(sizl, 0, // Let GDI choose ulWidth ulBitmapType, flBitmap, NULL))) { // Let GDI allocate EngDeleteSurface(ppdev->hsurfMask); return FALSE; } else { ppdev->hsurfColor = hsurf; } /* endif */ psoDst = EngLockSurface(ppdev->hsurfColor); if (!EngCopyBits(psoDst, // Target surface psoSrc, // Source surface (CLIPOBJ *) NULL, // Clip through this pxlo, // Color translation &prclDst, // Target offset and extent &pptlSrc)) { // Source offset EngDeleteSurface(ppdev->hsurfMask); EngDeleteSurface(ppdev->hsurfColor); return FALSE; } /* endif */ EngUnlockSurface(psoDst); return TRUE; }
VOID vShowSimPointer ( PPDEV ppdev, SURFOBJ *pso, RECTL *prcl, BOOL bShow ) { PVIDEO_POINTER_ATTRIBUTES pPointerAttributes = ppdev->pPointerAttributes; RECTL rclScreen, rclPointer; POINTL ptlPointerOffset; ULONG ulOffset; BOOL b; SURFOBJ *psoMask; SURFOBJ *psoColor; ulOffset = ppdev->cyScreen * ppdev->lDeltaScreen; ulOffset += 64; // skip over solid color pattern used in bitblt.c ulOffset += 1024; // skip over hardware pointer bitmap if (bShow) { rclScreen.top = 0; rclScreen.bottom = ppdev->cyScreen; rclScreen.left = 0; rclScreen.right = ppdev->cxScreen; rclPointer.top = pPointerAttributes->Row - ppdev->ptlHotSpot.y; rclPointer.bottom = rclPointer.top + pPointerAttributes->Height; rclPointer.left = pPointerAttributes->Column - ppdev->ptlHotSpot.x; rclPointer.right = rclPointer.left + pPointerAttributes->Width; // // Trim down the simulation cursor beyond the screen // if (bIntersect(&rclScreen, &rclPointer, &ppdev->rclPrevPointer)) { prcl->top = ppdev->rclPrevPointer.top; prcl->bottom = ppdev->rclPrevPointer.bottom; prcl->left = ppdev->rclPrevPointer.left; prcl->right = ppdev->rclPrevPointer.right; ptlPointerOffset.x = (rclPointer.left >= 0) ? 0 : (rclPointer.left * (-1)); ptlPointerOffset.y = (rclPointer.top >= 0) ? 0 : (rclPointer.top * (-1)); // // Save the screen image where the pointer affects // vHwSaveScreen(ppdev, &ppdev->rclPrevPointer, ulOffset); // // Draw the pointer // // Note: Clipping the transparent portion of pointer is required for // better performance. // if ((pso != NULL) && (pso->iType == STYPE_DEVICE)) pso = (SURFOBJ *)(((PPDEV)(pso->dhpdev))->pSurfObj); psoMask = EngLockSurface(ppdev->hsurfMask); psoColor = EngLockSurface(ppdev->hsurfColor); b = EngBitBlt(pso, // Target surface psoColor, // Source surface psoMask, // Mask (CLIPOBJ *) NULL, // Clip through this (XLATEOBJ *) NULL, // Color translation prcl, // Target offset and extent &ptlPointerOffset, // Source offset &ptlPointerOffset, // Mask offset (BRUSHOBJ *) NULL, // Brush data (from cbRealizeBrush) (POINTL *) NULL, // Brush offset (origin) 0x0000CC66); // Raster operation EngUnlockSurface(psoMask); EngUnlockSurface(psoColor); } else { // // The entire pointer is outside of screen // pPointerAttributes->Enable = 0; } /* endif */ } else { // // Restore the screen image corrupted by the simulation pointer // vHwRestoreScreen(ppdev, &ppdev->rclPrevPointer, ulOffset); } /* endif */ }
HBITMAP APIENTRY VBoxDispDrvDeriveSurface(DD_DIRECTDRAW_GLOBAL *pDirectDraw, DD_SURFACE_LOCAL *pSurface) { PVBOXDISPDEV pDev = (PVBOXDISPDEV)pDirectDraw->dhpdev; LOGF_ENTER(); if (pSurface->ddsCaps.dwCaps & DDSCAPS_NONLOCALVIDMEM) { WARN(("Can't derive surface DDSCAPS_NONLOCALVIDMEM")); return NULL; } if (pSurface->lpSurfMore->ddsCapsEx.dwCaps2 & DDSCAPS2_TEXTUREMANAGE) { WARN(("Can't derive surface DDSCAPS2_TEXTUREMANAGE")); return NULL; } if (pSurface->lpGbl->ddpfSurface.dwRGBBitCount != pDev->mode.ulBitsPerPel) { WARN(("Can't derive surface with different bpp")); return NULL; } Assert(pDev->surface.hSurface); /* Create GDI managed bitmap, which resides in our DDraw heap memory */ HBITMAP hBitmap; SIZEL size; size.cx = pDev->mode.ulWidth; size.cy = pDev->mode.ulHeight; hBitmap = EngCreateBitmap(size, pSurface->lpGbl->lPitch, pDev->surface.ulFormat, pDev->mode.lScanlineStride>0 ? BMF_TOPDOWN:0, (PBYTE)pDev->memInfo.VideoRamBase + pSurface->lpGbl->fpVidMem); if (!hBitmap) { WARN(("EngCreateBitmap failed")); return 0; } if (pSurface->lpGbl->fpVidMem == 0) { /* Screen surface, mark it so it will be recognized by the driver. * so the driver will be called on any operations on the surface * (required for VBVA and VRDP). */ SURFOBJ *pso; if (!EngAssociateSurface((HSURF)hBitmap, pDev->hDevGDI, pDev->flDrawingHooks)) { WARN(("EngAssociateSurface failed")); EngDeleteSurface((HSURF)hBitmap); return NULL; } pso = EngLockSurface((HSURF)hBitmap); if (!pso) { WARN(("EngLockSurface failed")); EngDeleteSurface((HSURF)hBitmap); return NULL; } pso->dhpdev = (DHPDEV)pDev; EngUnlockSurface(pso); } LOGF_LEAVE(); return hBitmap; }
BOOL APIENTRY IntEngEnter(PINTENG_ENTER_LEAVE EnterLeave, SURFOBJ *psoDest, RECTL *DestRect, BOOL ReadOnly, POINTL *Translate, SURFOBJ **ppsoOutput) { LONG Exchange; SIZEL BitmapSize; POINTL SrcPoint; LONG Width; RECTL ClippedDestRect; /* Normalize */ if (DestRect->right < DestRect->left) { Exchange = DestRect->left; DestRect->left = DestRect->right; DestRect->right = Exchange; } if (DestRect->bottom < DestRect->top) { Exchange = DestRect->top; DestRect->top = DestRect->bottom; DestRect->bottom = Exchange; } if (NULL != psoDest && STYPE_BITMAP != psoDest->iType && (NULL == psoDest->pvScan0 || 0 == psoDest->lDelta)) { /* Driver needs to support DrvCopyBits, else we can't do anything */ SURFACE *psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj); if (!(psurfDest->flags & HOOK_COPYBITS)) { return FALSE; } /* Allocate a temporary bitmap */ BitmapSize.cx = DestRect->right - DestRect->left; BitmapSize.cy = DestRect->bottom - DestRect->top; Width = WIDTH_BYTES_ALIGN32(BitmapSize.cx, BitsPerFormat(psoDest->iBitmapFormat)); EnterLeave->OutputBitmap = EngCreateBitmap(BitmapSize, Width, psoDest->iBitmapFormat, BMF_TOPDOWN | BMF_NOZEROINIT, NULL); if (!EnterLeave->OutputBitmap) { DPRINT1("EngCreateBitmap() failed\n"); return FALSE; } *ppsoOutput = EngLockSurface((HSURF)EnterLeave->OutputBitmap); if (*ppsoOutput == NULL) { EngDeleteSurface((HSURF)EnterLeave->OutputBitmap); return FALSE; } EnterLeave->DestRect.left = 0; EnterLeave->DestRect.top = 0; EnterLeave->DestRect.right = BitmapSize.cx; EnterLeave->DestRect.bottom = BitmapSize.cy; SrcPoint.x = DestRect->left; SrcPoint.y = DestRect->top; ClippedDestRect = EnterLeave->DestRect; if (SrcPoint.x < 0) { ClippedDestRect.left -= SrcPoint.x; SrcPoint.x = 0; } if (psoDest->sizlBitmap.cx < SrcPoint.x + ClippedDestRect.right - ClippedDestRect.left) { ClippedDestRect.right = ClippedDestRect.left + psoDest->sizlBitmap.cx - SrcPoint.x; } if (SrcPoint.y < 0) { ClippedDestRect.top -= SrcPoint.y; SrcPoint.y = 0; } if (psoDest->sizlBitmap.cy < SrcPoint.y + ClippedDestRect.bottom - ClippedDestRect.top) { ClippedDestRect.bottom = ClippedDestRect.top + psoDest->sizlBitmap.cy - SrcPoint.y; } EnterLeave->TrivialClipObj = EngCreateClip(); if (EnterLeave->TrivialClipObj == NULL) { EngUnlockSurface(*ppsoOutput); EngDeleteSurface((HSURF)EnterLeave->OutputBitmap); return FALSE; } EnterLeave->TrivialClipObj->iDComplexity = DC_TRIVIAL; if (ClippedDestRect.left < (*ppsoOutput)->sizlBitmap.cx && 0 <= ClippedDestRect.right && SrcPoint.x < psoDest->sizlBitmap.cx && ClippedDestRect.top <= (*ppsoOutput)->sizlBitmap.cy && 0 <= ClippedDestRect.bottom && SrcPoint.y < psoDest->sizlBitmap.cy && ! GDIDEVFUNCS(psoDest).CopyBits( *ppsoOutput, psoDest, EnterLeave->TrivialClipObj, NULL, &ClippedDestRect, &SrcPoint)) { EngDeleteClip(EnterLeave->TrivialClipObj); EngUnlockSurface(*ppsoOutput); EngDeleteSurface((HSURF)EnterLeave->OutputBitmap); return FALSE; } EnterLeave->DestRect.left = DestRect->left; EnterLeave->DestRect.top = DestRect->top; EnterLeave->DestRect.right = DestRect->right; EnterLeave->DestRect.bottom = DestRect->bottom; Translate->x = - DestRect->left; Translate->y = - DestRect->top; } else { Translate->x = 0; Translate->y = 0; *ppsoOutput = psoDest; } if (NULL != *ppsoOutput) { SURFACE* psurfOutput = CONTAINING_RECORD(*ppsoOutput, SURFACE, SurfObj); if (0 != (psurfOutput->flags & HOOK_SYNCHRONIZE)) { if (NULL != GDIDEVFUNCS(*ppsoOutput).SynchronizeSurface) { GDIDEVFUNCS(*ppsoOutput).SynchronizeSurface(*ppsoOutput, DestRect, 0); } else if (STYPE_BITMAP == (*ppsoOutput)->iType && NULL != GDIDEVFUNCS(*ppsoOutput).Synchronize) { GDIDEVFUNCS(*ppsoOutput).Synchronize((*ppsoOutput)->dhpdev, DestRect); } } } else return FALSE; EnterLeave->DestObj = psoDest; EnterLeave->OutputObj = *ppsoOutput; EnterLeave->ReadOnly = ReadOnly; return TRUE; }