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; }
/** * 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; }
INIT_FUNCTION NTSTATUS NTAPI InitBrushImpl(VOID) { ULONG i; SIZEL sizl = {8, 8}; /* Loop all hatch styles */ for (i = 0; i < HS_DDI_MAX; i++) { /* Create a default hatch bitmap */ gahsurfHatch[i] = (HSURF)EngCreateBitmap(sizl, 0, BMF_1BPP, 0, (PVOID)gaulHatchBrushes[i]); } return STATUS_SUCCESS; }
HSURF DrvEnableSurface(DHPDEV dhpdev) { LPFAXDEV lpFaxDev = (LPFAXDEV)dhpdev; HBITMAP hbm = 0; LOGDEBUG(("WOWFAX!DrvEnableSurface, lpFaxDev: %X\n", lpFaxDev)); if (ValidateFaxDev(lpFaxDev)) { // GDI will allocate space for the bitmap bits. We'll use a DrvEscape // to copy them to the client side. hbm = EngCreateBitmap(lpFaxDev->gdiinfo.szlPhysSize, lpFaxDev->bmWidthBytes, lpFaxDev->bmFormat, BMF_TOPDOWN, NULL); if (hbm) { lpFaxDev->hbm = hbm; EngAssociateSurface((HSURF)hbm, lpFaxDev->hdev, 0); return (HSURF)hbm; } LOGDEBUG(("WOWFAX!DrvEnableSurface, EngCreateBitmap failed\n")); } return (HSURF)hbm; }
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; }
/* * @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; }
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; // eVb: 1.3 [VGARISC Change] - Disable dynamic palette and > 4BPP support #if 0 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; } // eVb: 1.3 [DDK Change] - Support new VGA Miniport behavior w.r.t updated framebuffer remapping ppdev->flHooks = flHooks; // eVb: 1.3 [END] #else ulBitmapType = BMF_4BPP; #endif // eVb: 1.3 [END] // eVb: 1.4 [DDK Change] - Use EngCreateDeviceSurface instead of EngCreateBitmap hsurf = (HSURF)EngCreateDeviceSurface((DHSURF)ppdev, sizl, ulBitmapType); if (hsurf == (HSURF) 0) { RIP("DISP DrvEnableSurface failed EngCreateDeviceSurface\n"); return(FALSE); } // eVb: 1.4 [END] // eVb: 1.5 [DDK Change] - Use EngModifySurface instead of EngAssociateSurface if ( !EngModifySurface(hsurf, ppdev->hdevEng, ppdev->flHooks | HOOK_SYNCHRONIZE, MS_NOTSYSTEMMEMORY, (DHSURF)ppdev, ppdev->pjScreen, ppdev->lDeltaScreen, NULL)) { RIP("DISP DrvEnableSurface failed EngModifySurface\n"); return(FALSE); } // eVb: 1.5 [END] ppdev->hsurfEng = hsurf; // eVb: 1.4 [VGARISC Change] - Allocate 4BPP DIB that will store GDI drawing HSURF hSurfBitmap; hSurfBitmap = (HSURF)EngCreateBitmap(sizl, 0, ulBitmapType, 0, NULL); if (hSurfBitmap == (HSURF) 0) { RIP("DISP DrvEnableSurface failed EngCreateBitmap\n"); return(FALSE); } if ( !EngModifySurface(hSurfBitmap, ppdev->hdevEng, ppdev->flHooks | HOOK_SYNCHRONIZE, MS_NOTSYSTEMMEMORY, (DHSURF)ppdev, ppdev->pjScreen, ppdev->lDeltaScreen, NULL)) { RIP("DISP DrvEnableSurface failed second EngModifySurface\n"); return(FALSE); } ppdev->pso = EngLockSurface(hSurfBitmap); if (ppdev->pso == NULL) { RIP("DISP DrvEnableSurface failed EngLockSurface\n"); return(FALSE); } // eVb: 1.4 [END] return(hsurf); }
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); }
/* Called to create and associate surface with device */ HSURF APIENTRY VBoxDispDrvEnableSurface(DHPDEV dhpdev) { int rc; PVBOXDISPDEV pDev = (PVBOXDISPDEV)dhpdev; LOGF_ENTER(); /* Switch device to mode requested in VBoxDispDrvEnablePDEV */ rc = VBoxDispMPSetCurrentMode(pDev->hDriver, pDev->mode.ulIndex); VBOX_WARNRC_RETV(rc, NULL); /* Map fb and vram */ rc = VBoxDispMPMapMemory(pDev, &pDev->memInfo); VBOX_WARNRC_RETV(rc, NULL); /* Clear mapped memory, to avoid garbage while video mode is switching */ /* @todo: VIDEO_MODE_NO_ZERO_MEMORY does nothing in miniport's IOCTL_VIDEO_SET_CURRENT_MODE*/ memset(pDev->memInfo.FrameBufferBase, 0, pDev->mode.ulHeight * abs(pDev->mode.lScanlineStride)); /* Allocate memory for pointer attrs */ rc = VBoxDispInitPointerAttrs(pDev); VBOX_WARNRC_RETV(rc, NULL); /* Init VBVA */ rc = VBoxDispVBVAInit(pDev); VBOX_WARNRC_RETV(rc, NULL); /* Enable VBVA */ if (pDev->hgsmi.bSupported) { if (pDev->mode.ulBitsPerPel==16 || pDev->mode.ulBitsPerPel==24 || pDev->mode.ulBitsPerPel==32) { VBVABUFFER *pVBVA = (VBVABUFFER *)((uint8_t *)pDev->memInfo.VideoRamBase+pDev->layout.offVBVABuffer); pDev->hgsmi.bSupported = VBoxVBVAEnable(&pDev->vbvaCtx, &pDev->hgsmi.ctx, pVBVA, -1); LogRel(("VBoxDisp[%d]: VBVA %senabled\n", pDev->iDevice, pDev->hgsmi.bSupported? "":"not ")); } } /* Inform host */ if (pDev->hgsmi.bSupported) { VBoxHGSMIProcessDisplayInfo(&pDev->hgsmi.ctx, pDev->iDevice, pDev->orgDev.x, pDev->orgDev.y, 0, abs(pDev->mode.lScanlineStride), pDev->mode.ulWidth, pDev->mode.ulHeight, (uint16_t)pDev->mode.ulBitsPerPel, VBVA_SCREEN_F_ACTIVE); } #ifdef VBOX_WITH_VIDEOHWACCEL VBoxDispVHWAEnable(pDev); #endif /* Set device palette if needed */ if (pDev->mode.ulBitsPerPel == 8) { rc = VBoxDispSetPalette8BPP(pDev); VBOX_WARNRC_RETV(rc, NULL); } pDev->orgDisp.x = 0; pDev->orgDisp.y = 0; /* Create GDI managed bitmap, which resides in our framebuffer memory */ ULONG iFormat; SIZEL size; switch (pDev->mode.ulBitsPerPel) { case 8: { iFormat = BMF_8BPP; break; } case 16: { iFormat = BMF_16BPP; break; } case 24: { iFormat = BMF_24BPP; break; } case 32: { iFormat = BMF_32BPP; break; } } size.cx = pDev->mode.ulWidth; size.cy = pDev->mode.ulHeight; pDev->surface.hBitmap = EngCreateBitmap(size, pDev->mode.lScanlineStride, iFormat, pDev->mode.lScanlineStride>0 ? BMF_TOPDOWN:0, pDev->memInfo.FrameBufferBase); if (!pDev->surface.hBitmap) { WARN(("EngCreateBitmap failed!")); return NULL; } pDev->surface.psoBitmap = EngLockSurface((HSURF)pDev->surface.hBitmap); /* Create device-managed surface */ pDev->surface.hSurface = EngCreateDeviceSurface((DHSURF)pDev, size, iFormat); if (!pDev->surface.hSurface) { WARN(("EngCreateDeviceSurface failed!")); VBoxDispDrvDisableSurface(dhpdev); return NULL; } FLONG flHooks = HOOK_BITBLT|HOOK_TEXTOUT|HOOK_FILLPATH|HOOK_COPYBITS|HOOK_STROKEPATH|HOOK_LINETO| HOOK_PAINT|HOOK_STRETCHBLT; /* Associate created surface with our device */ if (!EngAssociateSurface(pDev->surface.hSurface, pDev->hDevGDI, flHooks)) { WARN(("EngAssociateSurface failed!")); VBoxDispDrvDisableSurface(dhpdev); return NULL; } pDev->surface.ulFormat = iFormat; pDev->flDrawingHooks = flHooks; LOG(("Created surface %p for physical device %p", pDev->surface.hSurface, pDev)); LOGF_LEAVE(); return pDev->surface.hSurface; }
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; }
HSURF DrvEnableSurface( DHPDEV dhpdev) { PDEV* ppdev; HSURF hsurfShadow; HSURF hsurfDevice; SIZEL sizl; ppdev = (PDEV*) dhpdev; ///////////////////////////////////////////////////////////////////// // Have GDI create the actual SURFOBJ. // // Our drawing surface is going to be 'device-managed', meaning that // GDI cannot draw on the framebuffer bits directly, and as such we // create the surface via EngCreateSurface. By doing this, we ensure // that GDI will only ever access the bitmaps bits via the Drv calls // that we've HOOKed. sizl.cx = ppdev->cxScreen; sizl.cy = ppdev->cyScreen; hsurfDevice = EngCreateDeviceSurface(NULL, sizl, ppdev->iBitmapFormat); if (hsurfDevice == 0) { DISPDBG((0, "DrvEnableSurface - Failed EngCreateSurface")); goto ReturnFailure; } ppdev->hsurfScreen = hsurfDevice; // Remember it for clean-up ///////////////////////////////////////////////////////////////////// // Now associate the surface and the PDEV. // // We have to associate the surface we just created with our physical // device so that GDI can get information related to the PDEV when // it's drawing to the surface (such as, for example, the length of // styles on the device when simulating styled lines). // if (!EngAssociateSurface(hsurfDevice, ppdev->hdevEng, ppdev->flHooks)) { DISPDBG((0, "DrvEnableSurface - Failed EngAssociateSurface")); goto ReturnFailure; } // Create the 4bpp DIB on which we'll have GDI do all the drawing. // We'll merely occasionally blt portions to the screen to update. sizl.cx = ppdev->cxScreen; sizl.cy = ppdev->cyScreen; hsurfShadow = (HSURF) EngCreateBitmap(sizl, 0, ppdev->iBitmapFormat, 0, NULL); if (hsurfShadow == 0) goto ReturnFailure; if (!EngAssociateSurface(hsurfShadow, ppdev->hdevEng, ppdev->flHooks)) { DISPDBG((0, "DrvEnableSurface - Failed second EngAssociateSurface")); goto ReturnFailure; } ppdev->pso = EngLockSurface(hsurfShadow); if (ppdev->pso == NULL) goto ReturnFailure; ///////////////////////////////////////////////////////////////////// // Now enable all the subcomponents. // // Note that the order in which these 'Enable' functions are called // may be significant in low off-screen memory conditions, because // the off-screen heap manager may fail some of the later // allocations... if (!bEnableHardware(ppdev)) goto ReturnFailure; DISPDBG((5, "Passed DrvEnableSurface")); return(hsurfDevice); ReturnFailure: DrvDisableSurface((DHPDEV) ppdev); DISPDBG((0, "Failed DrvEnableSurface")); return(0); }
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); }