HPALETTE FASTCALL GdiSelectPalette( HDC hDC, HPALETTE hpal, BOOL ForceBackground) { PDC pdc; HPALETTE oldPal = NULL; PPALETTE ppal; // FIXME: mark the palette as a [fore\back]ground pal pdc = DC_LockDc(hDC); if (!pdc) { return NULL; } /* Check if this is a valid palette handle */ ppal = PALETTE_ShareLockPalette(hpal); if (!ppal) { DC_UnlockDc(pdc); return NULL; } /* Is this a valid palette for this depth? */ if ((BitsPerFormat(pdc->dclevel.pSurface->SurfObj.iBitmapFormat) <= 8 && (ppal->flFlags & PAL_INDEXED)) || (BitsPerFormat(pdc->dclevel.pSurface->SurfObj.iBitmapFormat) > 8)) { /* Get old palette, set new one */ oldPal = pdc->dclevel.hpal; pdc->dclevel.hpal = hpal; DC_vSelectPalette(pdc, ppal); /* Mark the brushes invalid */ pdc->pdcattr->ulDirty_ |= DIRTY_FILL | DIRTY_LINE | DIRTY_BACKGROUND | DIRTY_TEXT; } if(pdc->dctype == DCTYPE_MEMORY) { // This didn't work anyway //IntGdiRealizePalette(hDC); } PALETTE_ShareUnlockPalette(ppal); DC_UnlockDc(pdc); return oldPal; }
void NTAPI UnsafeSetBitmapBits( PSURFACE psurf, IN ULONG cjBits, IN PVOID pvBits) { PUCHAR pjDst, pjSrc; LONG lDeltaDst, lDeltaSrc; ULONG nWidth, nHeight, cBitsPixel; nWidth = psurf->SurfObj.sizlBitmap.cx; nHeight = psurf->SurfObj.sizlBitmap.cy; cBitsPixel = BitsPerFormat(psurf->SurfObj.iBitmapFormat); /* Get pointers */ pjDst = psurf->SurfObj.pvScan0; pjSrc = pvBits; lDeltaDst = psurf->SurfObj.lDelta; lDeltaSrc = WIDTH_BYTES_ALIGN16(nWidth, cBitsPixel); while (nHeight--) { /* Copy one line */ memcpy(pjDst, pjSrc, lDeltaSrc); pjSrc += lDeltaSrc; pjDst += lDeltaDst; } }
/** * 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; }
BOOL NTAPI UnsafeSetBitmapBits( _Inout_ PSURFACE psurf, _In_ ULONG cjBits, _In_ const VOID *pvBits) { PUCHAR pjDst; const UCHAR *pjSrc; LONG lDeltaDst, lDeltaSrc; ULONG nWidth, nHeight, cBitsPixel; NT_ASSERT(psurf->flags & API_BITMAP); NT_ASSERT(psurf->SurfObj.iBitmapFormat <= BMF_32BPP); nWidth = psurf->SurfObj.sizlBitmap.cx; nHeight = psurf->SurfObj.sizlBitmap.cy; cBitsPixel = BitsPerFormat(psurf->SurfObj.iBitmapFormat); /* Get pointers */ pjDst = psurf->SurfObj.pvScan0; pjSrc = pvBits; lDeltaDst = psurf->SurfObj.lDelta; lDeltaSrc = WIDTH_BYTES_ALIGN16(nWidth, cBitsPixel); NT_ASSERT(lDeltaSrc <= abs(lDeltaDst)); /* Make sure the buffer is large enough*/ if (cjBits < (lDeltaSrc * nHeight)) return FALSE; while (nHeight--) { /* Copy one line */ memcpy(pjDst, pjSrc, lDeltaSrc); pjSrc += lDeltaSrc; pjDst += lDeltaDst; } 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; }
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; }
BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, SURFOBJ *MaskSurf, SURFOBJ *PatternSurface, RECTL *DestRect, RECTL *SourceRect, POINTL *MaskOrigin, BRUSHOBJ *Brush, POINTL *BrushOrigin, XLATEOBJ *ColorTranslation, ROP4 ROP) { LONG sx = 0; LONG sy = 0; LONG DesX; LONG DesY; LONG DstHeight; LONG DstWidth; LONG SrcHeight; LONG SrcWidth; LONG MaskCy; LONG SourceCy; ULONG Color; ULONG Dest, Source = 0, Pattern = 0; ULONG xxBPPMask; BOOLEAN CanDraw; PFN_DIB_GetPixel fnSource_GetPixel = NULL; PFN_DIB_GetPixel fnDest_GetPixel = NULL; PFN_DIB_PutPixel fnDest_PutPixel = NULL; PFN_DIB_GetPixel fnPattern_GetPixel = NULL; PFN_DIB_GetPixel fnMask_GetPixel = NULL; LONG PatternX = 0, PatternY = 0; BOOL UsesSource = ROP4_USES_SOURCE(ROP); BOOL UsesPattern = ROP4_USES_PATTERN(ROP); ASSERT(IS_VALID_ROP4(ROP)); fnDest_GetPixel = DibFunctionsForBitmapFormat[DestSurf->iBitmapFormat].DIB_GetPixel; fnDest_PutPixel = DibFunctionsForBitmapFormat[DestSurf->iBitmapFormat].DIB_PutPixel; DPRINT("Dest BPP: %u, dstRect: (%d,%d)-(%d,%d)\n", BitsPerFormat(DestSurf->iBitmapFormat), DestRect->left, DestRect->top, DestRect->right, DestRect->bottom); if (UsesSource) { SourceCy = abs(SourceSurf->sizlBitmap.cy); fnSource_GetPixel = DibFunctionsForBitmapFormat[SourceSurf->iBitmapFormat].DIB_GetPixel; DPRINT("Source BPP: %u, srcRect: (%d,%d)-(%d,%d)\n", BitsPerFormat(SourceSurf->iBitmapFormat), SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom); } if (MaskSurf) { fnMask_GetPixel = DibFunctionsForBitmapFormat[MaskSurf->iBitmapFormat].DIB_GetPixel; MaskCy = abs(MaskSurf->sizlBitmap.cy); } DstHeight = DestRect->bottom - DestRect->top; DstWidth = DestRect->right - DestRect->left; SrcHeight = SourceRect->bottom - SourceRect->top; SrcWidth = SourceRect->right - SourceRect->left; /* FIXME: MaskOrigin? */ switch(DestSurf->iBitmapFormat) { case BMF_1BPP: xxBPPMask = 0x1; break; case BMF_4BPP: xxBPPMask = 0xF; break; case BMF_8BPP: xxBPPMask = 0xFF; break; case BMF_16BPP: xxBPPMask = 0xFFFF; break; case BMF_24BPP: xxBPPMask = 0xFFFFFF; break; default: xxBPPMask = 0xFFFFFFFF; } if (UsesPattern) { if (PatternSurface) { PatternY = (DestRect->top - BrushOrigin->y) % PatternSurface->sizlBitmap.cy; if (PatternY < 0) { PatternY += PatternSurface->sizlBitmap.cy; } fnPattern_GetPixel = DibFunctionsForBitmapFormat[PatternSurface->iBitmapFormat].DIB_GetPixel; } else { if (Brush) Pattern = Brush->iSolidColor; } } for (DesY = DestRect->top; DesY < DestRect->bottom; DesY++) { if (PatternSurface) { PatternX = (DestRect->left - BrushOrigin->x) % PatternSurface->sizlBitmap.cx; if (PatternX < 0) { PatternX += PatternSurface->sizlBitmap.cx; } } if (UsesSource) sy = SourceRect->top+(DesY - DestRect->top) * SrcHeight / DstHeight; for (DesX = DestRect->left; DesX < DestRect->right; DesX++) { CanDraw = TRUE; if (fnMask_GetPixel) { sx = SourceRect->left+(DesX - DestRect->left) * SrcWidth / DstWidth; if (sx < 0 || sy < 0 || MaskSurf->sizlBitmap.cx < sx || MaskCy < sy || fnMask_GetPixel(MaskSurf, sx, sy) != 0) { CanDraw = FALSE; } } if (UsesSource && CanDraw) { sx = SourceRect->left+(DesX - DestRect->left) * SrcWidth / DstWidth; if (sx >= 0 && sy >= 0 && SourceSurf->sizlBitmap.cx > sx && SourceCy > sy) { Source = XLATEOBJ_iXlate(ColorTranslation, fnSource_GetPixel(SourceSurf, sx, sy)); } else { Source = 0; CanDraw = ((ROP & 0xFF) != R3_OPINDEX_SRCCOPY); } } if (CanDraw) { if (UsesPattern && PatternSurface) { Pattern = fnPattern_GetPixel(PatternSurface, PatternX, PatternY); PatternX++; PatternX %= PatternSurface->sizlBitmap.cx; } Dest = fnDest_GetPixel(DestSurf, DesX, DesY); Color = DIB_DoRop(ROP, Dest, Source, Pattern) & xxBPPMask; fnDest_PutPixel(DestSurf, DesX, DesY, Color); } } if (PatternSurface) { PatternY++; PatternY %= PatternSurface->sizlBitmap.cy; } } return TRUE; }