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); }
static BOOL CreateDrawArea(PDev *pdev, UINT8 *base_mem, ULONG format, UINT32 cx, UINT32 cy, UINT32 stride, UINT32 surface_id) { SIZEL size; DrawArea *drawarea; size.cx = cx; size.cy = cy; drawarea = &GetSurfaceInfo(pdev, surface_id)->draw_area; if (!(drawarea->bitmap = (HSURF)EngCreateBitmap(size, stride, format, 0, base_mem))) { DEBUG_PRINT((pdev, 0, "%s: EngCreateBitmap failed\n", __FUNCTION__)); return FALSE; } if (!EngAssociateSurface(drawarea->bitmap, pdev->eng, 0)) { DEBUG_PRINT((pdev, 0, "%s: EngAssociateSurface failed\n", __FUNCTION__)); goto error; } if (!(drawarea->surf_obj = EngLockSurface(drawarea->bitmap))) { DEBUG_PRINT((pdev, 0, "%s: EngLockSurface failed\n", __FUNCTION__)); goto error; } drawarea->base_mem = base_mem; return TRUE; error: EngDeleteSurface(drawarea->bitmap); return FALSE; }
VOID DrvDisableSurface( DHPDEV dhpdev) { EngDeleteSurface(((PPDEV) dhpdev)->hsurfEng); vDisableSURF((PPDEV) dhpdev); ((PPDEV) dhpdev)->hsurfEng = (HSURF) 0; }
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); }
/** * This function is not exported, because it makes no sense for * The driver to punt back to this function */ BOOL APIENTRY EngRealizeBrush( BRUSHOBJ *pbo, SURFOBJ *psoDst, SURFOBJ *psoPattern, SURFOBJ *psoMask, XLATEOBJ *pxlo, ULONG iHatch) { EBRUSHOBJ *pebo; HBITMAP hbmpRealize; SURFOBJ *psoRealize; PSURFACE psurfRealize; POINTL ptlSrc = {0, 0}; RECTL rclDest; ULONG lWidth; /* Calculate width in bytes of the realized brush */ lWidth = WIDTH_BYTES_ALIGN32(psoPattern->sizlBitmap.cx, BitsPerFormat(psoDst->iBitmapFormat)); /* Allocate a bitmap */ hbmpRealize = EngCreateBitmap(psoPattern->sizlBitmap, lWidth, psoDst->iBitmapFormat, BMF_NOZEROINIT, NULL); if (!hbmpRealize) { return FALSE; } /* Lock the bitmap */ psurfRealize = SURFACE_ShareLockSurface(hbmpRealize); /* Already delete the pattern bitmap (will be kept until dereferenced) */ EngDeleteSurface((HSURF)hbmpRealize); if (!psurfRealize) { return FALSE; } /* Copy the bits to the new format bitmap */ rclDest.left = rclDest.top = 0; rclDest.right = psoPattern->sizlBitmap.cx; rclDest.bottom = psoPattern->sizlBitmap.cy; psoRealize = &psurfRealize->SurfObj; EngCopyBits(psoRealize, psoPattern, NULL, pxlo, &rclDest, &ptlSrc); pebo = CONTAINING_RECORD(pbo, EBRUSHOBJ, BrushObject); pebo->pengbrush = (PVOID)psurfRealize; return TRUE; }
VOID DrvDisableSurface(DHPDEV dhpdev) { PPDEV ppdev = (PPDEV) dhpdev; PDEVSURF pdsurf = ppdev->pdsurf; PSAVED_SCREEN_BITS pSSB, pSSBNext; DISPDBG((2, "disabling surface\n")); // Free up banking-related stuff. EngFreeMem(pdsurf->pBankSelectInfo); if (pdsurf->pbiBankInfo != NULL) { EngFreeMem(pdsurf->pbiBankInfo); } if (pdsurf->pbiBankInfo2RW != NULL) { EngFreeMem(pdsurf->pbiBankInfo2RW); } if (pdsurf->pvBankBufferPlane0 != NULL) { EngFreeMem(pdsurf->pvBankBufferPlane0); } if (ppdev->pPointerAttributes != NULL) { EngFreeMem(ppdev->pPointerAttributes); } // Free any pending saved screen bit blocks. pSSB = pdsurf->ssbList; while (pSSB != (PSAVED_SCREEN_BITS) NULL) { // // Point to the next saved screen bits block // pSSBNext = (PSAVED_SCREEN_BITS) pSSB->pvNextSSB; // // Free the current block // EngFreeMem(pSSB); pSSB = pSSBNext; } EngDeleteSurface((HSURF) ppdev->hsurfEng); EngFreeMem(pdsurf); // free the surface DISPDBG((2, "disabled surface\n")); }
VOID DrvDisableSurface( DHPDEV dhpdev ) { LPFAXDEV lpFaxDev = (LPFAXDEV)dhpdev; LOGDEBUG(("WOWFAX!DrvDisableSurface, lpFaxDev: %X\n", lpFaxDev)); if (ValidateFaxDev(lpFaxDev)) { if (lpFaxDev->hbm) { EngDeleteSurface((HSURF)lpFaxDev->hbm); lpFaxDev->hbm = 0; return; } } return; }
HBITMAP CreateDeviceBitmap(PDev *pdev, SIZEL size, ULONG format, QXLPHYSICAL *phys_mem, UINT8 **base_mem, UINT32 surface_id, UINT8 allocation_type) { UINT32 surface_format, depth; HBITMAP hbitmap; INT32 stride; SurfaceInfo *surface_info; DEBUG_PRINT((pdev, 9, "%s: %p: %d, (%dx%d), %d\n", __FUNCTION__, pdev, surface_id, size.cx, size.cy, format)); surface_info = GetSurfaceInfo(pdev, surface_id); if (!(hbitmap = EngCreateDeviceBitmap((DHSURF)surface_info, size, format))) { DEBUG_PRINT((pdev, 0, "%s: EngCreateDeviceBitmap failed, pdev 0x%lx, surface_id=%d\n", __FUNCTION__, pdev, surface_id)); goto out_error1; } if (!EngAssociateSurface((HSURF)hbitmap, pdev->eng, QXL_SURFACE_HOOKS)) { DEBUG_PRINT((pdev, 0, "%s: EngAssociateSurface failed\n", __FUNCTION__)); goto out_error2; } surface_info->u.pdev = pdev; surface_info->hbitmap = hbitmap; surface_info->copy = NULL; surface_info->size = size; surface_info->bitmap_format = format; if ((*base_mem = CreateSurfaceHelper(pdev, surface_id, size.cx, size.cy, format, allocation_type, &stride, &surface_format, phys_mem)) == NULL) { DEBUG_PRINT((pdev, 0, "%s: failed, pdev 0x%lx, surface_id=%d\n", __FUNCTION__, pdev, surface_id)); goto out_error2; } surface_info->stride = stride; if (allocation_type != DEVICE_BITMAP_ALLOCATION_TYPE_SURF0) { SendSurfaceCreateCommand(pdev, surface_id, size, surface_format, -stride, *phys_mem, 0); } return hbitmap; out_error2: EngDeleteSurface((HSURF)hbitmap); out_error1: return 0; }
PVOID NTAPI EBRUSHOBJ_pvGetEngBrush(EBRUSHOBJ *pebo) { BOOL bResult; if (!pebo->pengbrush) { bResult = EBRUSHOBJ_bRealizeBrush(pebo, FALSE); if (!bResult) { if (pebo->pengbrush) EngDeleteSurface(pebo->pengbrush); pebo->pengbrush = NULL; } } return pebo->pengbrush; }
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 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; }
HSURF DrvEnableSurface( DHPDEV dhpdev) { PPDEV ppdev; HSURF hsurf; SIZEL sizl; ULONG ulBitmapType; FLONG flHooks; // Create engine bitmap around frame buffer. ppdev = (PPDEV) dhpdev; if (!bInitSURF(ppdev, TRUE)) { RIP("DISP DrvEnableSurface failed bInitSURF\n"); return(FALSE); } sizl.cx = ppdev->cxScreen; sizl.cy = ppdev->cyScreen; if (ppdev->ulBitCount == 8) { if (!bInit256ColorPalette(ppdev)) { RIP("DISP DrvEnableSurface failed to init the 8bpp palette\n"); return(FALSE); } ulBitmapType = BMF_8BPP; flHooks = HOOKS_BMF8BPP; } else if (ppdev->ulBitCount == 16) { ulBitmapType = BMF_16BPP; flHooks = HOOKS_BMF16BPP; } else if (ppdev->ulBitCount == 24) { ulBitmapType = BMF_24BPP; flHooks = HOOKS_BMF24BPP; } else { ulBitmapType = BMF_32BPP; flHooks = HOOKS_BMF32BPP; } hsurf = (HSURF) EngCreateBitmap(sizl, ppdev->lDeltaScreen, ulBitmapType, (ppdev->lDeltaScreen > 0) ? BMF_TOPDOWN : 0, (PVOID) (ppdev->pjScreen)); if (hsurf == (HSURF) 0) { RIP("DISP DrvEnableSurface failed EngCreateBitmap\n"); return(FALSE); } if (!EngAssociateSurface(hsurf, ppdev->hdevEng, flHooks)) { RIP("DISP DrvEnableSurface failed EngAssociateSurface\n"); EngDeleteSurface(hsurf); return(FALSE); } ppdev->hsurfEng = hsurf; return(hsurf); }
OH* pohMoveOffscreenDfbToDib( PDEV* ppdev, OH* poh) { DSURF* pdsurf; HBITMAP hbmDib; SURFOBJ* pso; RECTL rclDst; POINTL ptlSrc; DISPDBG((1, "Throwing out %li x %li at (%li, %li)!", poh->cx, poh->cy, poh->x, poh->y)); pdsurf = poh->pdsurf; ASSERTDD((poh->x != 0) || (poh->y != 0), "Can't make the visible screen into a DIB"); ASSERTDD(pdsurf->dt != DT_DIB, "Can't make a DIB into even more of a DIB"); hbmDib = EngCreateBitmap(pdsurf->sizl, 0, ppdev->iBitmapFormat, BMF_TOPDOWN, NULL); if (hbmDib) { if (EngAssociateSurface((HSURF) hbmDib, ppdev->hdevEng, 0)) { pso = EngLockSurface((HSURF) hbmDib); if (pso != NULL) { rclDst.left = 0; rclDst.top = 0; rclDst.right = pdsurf->sizl.cx; rclDst.bottom = pdsurf->sizl.cy; ptlSrc.x = poh->x; ptlSrc.y = poh->y; vGetBits(ppdev, pso, &rclDst, &ptlSrc); pdsurf->dt = DT_DIB; pdsurf->pso = pso; // Don't even bother checking to see if this DIB should // be put back into off-screen memory until the next // heap 'free' occurs: pdsurf->iUniq = ppdev->iHeapUniq; pdsurf->cBlt = 0; // Remove this node from the off-screen DFB list, and free // it. 'pohFree' will never return NULL: return(pohFree(ppdev, poh)); } } // Fail case: EngDeleteSurface((HSURF) hbmDib); } return(NULL); }
HBITMAP DrvCreateDeviceBitmap( DHPDEV dhpdev, SIZEL sizl, ULONG iFormat) { PDEV* ppdev; OH* poh; DSURF* pdsurf; HBITMAP hbmDevice; FLONG flHooks; ppdev = (PDEV*) dhpdev; // If we're in full-screen mode, we hardly have any off-screen memory // in which to allocate a DFB. LATER: We could still allocate an // OH node and put the bitmap on the DIB DFB list for later promotion. if (!ppdev->bEnabled) return(0); // We only support device bitmaps when we're in a fully accelerated // mode: if (ppdev->iBitmapFormat != BMF_8BPP) return(0); // We only support device bitmaps that are the same colour depth // as our display. // // Actually, those are the only kind GDI will ever call us with, // but we may as well check. Note that this implies you'll never // get a crack at 1bpp bitmaps. if (iFormat != ppdev->iBitmapFormat) return(0); poh = pohAllocate(ppdev, sizl.cx, sizl.cy, 0); if (poh != NULL) { pdsurf = EngAllocMem(0, sizeof(DSURF), ALLOC_TAG); if (pdsurf != NULL) { hbmDevice = EngCreateDeviceBitmap((DHSURF) pdsurf, sizl, iFormat); if (hbmDevice != NULL) { flHooks = ppdev->flHooks; #if SYNCHRONIZEACCESS_WORKS { // Setting the SYNCHRONIZEACCESS flag tells GDI that we // want all drawing to the bitmaps to be synchronized (GDI // is multi-threaded and by default does not synchronize // device bitmap drawing -- it would be a Bad Thing for us // to have multiple threads using the accelerator at the // same time): flHooks |= HOOK_SYNCHRONIZEACCESS; } #endif // SYNCHRONIZEACCESS_WORKS if (EngAssociateSurface((HSURF) hbmDevice, ppdev->hdevEng, flHooks)) { pdsurf->dt = DT_SCREEN; pdsurf->poh = poh; pdsurf->sizl = sizl; pdsurf->ppdev = ppdev; poh->pdsurf = pdsurf; return(hbmDevice); } EngDeleteSurface((HSURF) hbmDevice); } EngFreeMem(pdsurf); } pohFree(ppdev, poh); } return(0); }
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; }
/* * @implemented */ ULONG APIENTRY EngSetPointerShape( _In_ SURFOBJ *pso, _In_opt_ SURFOBJ *psoMask, _In_opt_ SURFOBJ *psoColor, _In_opt_ XLATEOBJ *pxlo, _In_ LONG xHot, _In_ LONG yHot, _In_ LONG x, _In_ LONG y, _In_ RECTL *prcl, _In_ FLONG fl) { PDEVOBJ *ppdev; GDIPOINTER *pgp; LONG lDelta = 0; HBITMAP hbmSave = NULL, hbmColor = NULL, hbmMask = NULL; PSURFACE psurfSave = NULL, psurfColor = NULL, psurfMask = NULL; RECTL rectl; SIZEL sizel = {0, 0}; ASSERT(pso); ppdev = GDIDEV(pso); pgp = &ppdev->Pointer; /* Handle the case where we have no XLATEOBJ */ if (pxlo == NULL) pxlo = &gexloTrivial.xlo; /* Do we have any bitmap at all? */ if (psoColor || psoMask) { /* Get the size of the new pointer */ if (psoColor) { sizel.cx = psoColor->sizlBitmap.cx; sizel.cy = psoColor->sizlBitmap.cy; } else// if (psoMask) { sizel.cx = psoMask->sizlBitmap.cx; sizel.cy = psoMask->sizlBitmap.cy / 2; } rectl.left = 0; rectl.top = 0; rectl.right = sizel.cx; rectl.bottom = sizel.cy; /* Calculate lDelta for our surfaces. */ lDelta = WIDTH_BYTES_ALIGN32(sizel.cx, BitsPerFormat(pso->iBitmapFormat)); /* Create a bitmap for saving the pixels under the cursor. */ hbmSave = EngCreateBitmap(sizel, lDelta, pso->iBitmapFormat, BMF_TOPDOWN | BMF_NOZEROINIT, NULL); psurfSave = SURFACE_ShareLockSurface(hbmSave); if (!psurfSave) goto failure; } if (psoColor) { if (fl & SPS_ALPHA) { /* Always store the alpha cursor in RGB. */ EXLATEOBJ exloSrcRGB; PEXLATEOBJ pexlo; pexlo = CONTAINING_RECORD(pxlo, EXLATEOBJ, xlo); EXLATEOBJ_vInitialize(&exloSrcRGB, pexlo->ppalSrc, &gpalRGB, 0, 0, 0); hbmColor = EngCreateBitmap(psoColor->sizlBitmap, WIDTH_BYTES_ALIGN32(sizel.cx, 32), BMF_32BPP, BMF_TOPDOWN | BMF_NOZEROINIT, NULL); psurfColor = SURFACE_ShareLockSurface(hbmColor); if (!psurfColor) goto failure; /* Now copy the given bitmap. */ rectl.bottom = psoColor->sizlBitmap.cy; IntEngCopyBits(&psurfColor->SurfObj, psoColor, NULL, &exloSrcRGB.xlo, &rectl, (POINTL*)&rectl); EXLATEOBJ_vCleanup(&exloSrcRGB); } else { /* Color bitmap must have the same format as the dest surface */ if (psoColor->iBitmapFormat != pso->iBitmapFormat) { DPRINT1("Screen surface and cursor color bitmap format don't match!.\n"); goto failure; } /* Create a bitmap to copy the color bitmap to */ hbmColor = EngCreateBitmap(psoColor->sizlBitmap, lDelta, pso->iBitmapFormat, BMF_TOPDOWN | BMF_NOZEROINIT, NULL); psurfColor = SURFACE_ShareLockSurface(hbmColor); if (!psurfColor) goto failure; /* Now copy the given bitmap. */ rectl.bottom = psoColor->sizlBitmap.cy; IntEngCopyBits(&psurfColor->SurfObj, psoColor, NULL, pxlo, &rectl, (POINTL*)&rectl); } } /* Create a mask surface */ if (psoMask) { EXLATEOBJ exlo; PPALETTE ppal; lDelta = WIDTH_BYTES_ALIGN32(sizel.cx, BitsPerFormat(pso->iBitmapFormat)); /* Create a bitmap for the mask */ hbmMask = EngCreateBitmap(psoMask->sizlBitmap, lDelta, pso->iBitmapFormat, BMF_TOPDOWN | BMF_NOZEROINIT, NULL); psurfMask = SURFACE_ShareLockSurface(hbmMask); if (!psurfMask) goto failure; /* Initialize an EXLATEOBJ */ ppal = PALETTE_ShareLockPalette(ppdev->devinfo.hpalDefault); EXLATEOBJ_vInitialize(&exlo, gppalMono, ppal, 0, RGB(0xff,0xff,0xff), RGB(0,0,0)); /* Copy the mask bitmap */ rectl.bottom = psoMask->sizlBitmap.cy; IntEngCopyBits(&psurfMask->SurfObj, psoMask, NULL, &exlo.xlo, &rectl, (POINTL*)&rectl); /* Cleanup */ EXLATEOBJ_vCleanup(&exlo); if (ppal) PALETTE_ShareUnlockPalette(ppal); } /* Hide mouse pointer */ IntHideMousePointer(ppdev, pso); /* Free old color bitmap */ if (pgp->psurfColor) { EngDeleteSurface(pgp->psurfColor->BaseObject.hHmgr); SURFACE_ShareUnlockSurface(pgp->psurfColor); pgp->psurfColor = NULL; } /* Free old mask bitmap */ if (pgp->psurfMask) { EngDeleteSurface(pgp->psurfMask->BaseObject.hHmgr); SURFACE_ShareUnlockSurface(pgp->psurfMask); pgp->psurfMask = NULL; } /* Free old save bitmap */ if (pgp->psurfSave) { EngDeleteSurface(pgp->psurfSave->BaseObject.hHmgr); SURFACE_ShareUnlockSurface(pgp->psurfSave); pgp->psurfSave = NULL; } /* See if we are being asked to hide the pointer. */ if (psoMask == NULL && psoColor == NULL) { /* We're done */ return SPS_ACCEPT_NOEXCLUDE; } /* Now set the new cursor */ pgp->psurfColor = psurfColor; pgp->psurfMask = psurfMask; pgp->psurfSave = psurfSave; pgp->HotSpot.x = xHot; pgp->HotSpot.y = yHot; pgp->Size = sizel; pgp->flags = fl; if (x != -1) { ppdev->ptlPointer.x = x; ppdev->ptlPointer.y = y; IntShowMousePointer(ppdev, pso); if (prcl != NULL) { prcl->left = x - pgp->HotSpot.x; prcl->top = y - pgp->HotSpot.x; prcl->right = prcl->left + pgp->Size.cx; prcl->bottom = prcl->top + pgp->Size.cy; } } else if (prcl != NULL) { prcl->left = prcl->top = prcl->right = prcl->bottom = -1; } return SPS_ACCEPT_NOEXCLUDE; failure: /* Cleanup surfaces */ if (hbmMask) EngDeleteSurface((HSURF)hbmMask); if (psurfMask) SURFACE_ShareUnlockSurface(psurfMask); if (hbmColor) EngDeleteSurface((HSURF)hbmColor); if (psurfColor) SURFACE_ShareUnlockSurface(psurfColor); if (hbmSave) EngDeleteSurface((HSURF)hbmSave); if (psurfSave) SURFACE_ShareUnlockSurface(psurfSave); return SPS_ERROR; }
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; }
HSURF DrvEnableSurface(DHPDEV dhpdev) { PPDEV ppdev; PDEVSURF pdsurf; DHSURF dhsurf; HSURF hsurf; DISPDBG((2, "enabling Surface\n")); ppdev = (PPDEV) dhpdev; // // Initialize the VGA device into the selected mode which will also map // the video frame buffer // if (!bInitVGA(ppdev, TRUE)) { goto error_done; } dhsurf = (DHSURF) EngAllocMem(0, sizeof(DEVSURF), ALLOC_TAG); if (dhsurf == (DHSURF) 0) { goto error_done; } pdsurf = (PDEVSURF) dhsurf; pdsurf->ident = DEVSURF_IDENT; pdsurf->flSurf = 0; pdsurf->iFormat = BMF_PHYSDEVICE; pdsurf->jReserved1 = 0; pdsurf->jReserved2 = 0; pdsurf->ppdev = ppdev; pdsurf->sizlSurf.cx = ppdev->sizlSurf.cx; pdsurf->sizlSurf.cy = ppdev->sizlSurf.cy; pdsurf->lNextPlane = 0; pdsurf->pvScan0 = ppdev->pjScreen; pdsurf->pvBitmapStart = ppdev->pjScreen; pdsurf->pvStart = ppdev->pjScreen; pdsurf->pvConv = &ajConvertBuffer[0]; // Initialize pointer information. // // bInitPointer must be called before bInitSavedBits. // if (!bInitPointer(ppdev)) { DISPDBG((0, "DrvEnablePDEV failed bInitPointer\n")); goto error_clean; } if (!SetUpBanking(pdsurf, ppdev)) { DISPDBG((0, "DrvEnablePDEV failed SetUpBanking\n")); goto error_clean; } if ((hsurf = EngCreateDeviceSurface(dhsurf, ppdev->sizlSurf, BMF_4BPP)) == (HSURF) 0) { DISPDBG((0, "DrvEnablePDEV failed EngCreateDeviceSurface\n")); goto error_clean; } // // vInitSavedBits must be called after bInitPointer. // vInitSavedBits(ppdev); if (EngAssociateSurface(hsurf, ppdev->hdevEng, HOOK_BITBLT | HOOK_TEXTOUT | HOOK_STROKEPATH | HOOK_COPYBITS | HOOK_PAINT | HOOK_FILLPATH )) { ppdev->hsurfEng = hsurf; ppdev->pdsurf = pdsurf; // Set up an empty saved screen block list pdsurf->ssbList = NULL; DISPDBG((2, "enabled surface\n")); return(hsurf); } DISPDBG((0, "DrvEnablePDEV failed EngDeleteSurface\n")); EngDeleteSurface(hsurf); error_clean: // We created the surface, so delete it EngFreeMem(dhsurf); error_done: return((HSURF) 0); }