+++ /dev/null
-/*
- * PROJECT: ReactOS VGA display driver
- * LICENSE: GPL - See COPYING in the top level directory
- * FILE: drivers/video/displays/vga/objects/bitblt.c
- * PURPOSE:
- * PROGRAMMERS:
- */
-
-#include <vgaddi.h>
-
-#include "bitblt.h"
-
-typedef BOOL (*PFN_VGABlt)(SURFOBJ*, SURFOBJ*, XLATEOBJ*, RECTL*, POINTL*);
-typedef BOOL (APIENTRY *PBLTRECTFUNC)(SURFOBJ* OutputObj,
- SURFOBJ* InputObj,
- SURFOBJ* Mask,
- XLATEOBJ* ColorTranslation,
- RECTL* OutputRect,
- POINTL* InputPoint,
- POINTL* MaskOrigin,
- BRUSHOBJ* Brush,
- POINTL* BrushOrigin,
- ROP4 Rop4);
-
-static BOOL FASTCALL VGADDI_IntersectRect(
- OUT RECTL* prcDst,
- IN RECTL* prcSrc1,
- IN RECTL* prcSrc2)
-{
- static const RECTL rclEmpty = { 0, 0, 0, 0 };
-
- prcDst->left = max(prcSrc1->left, prcSrc2->left);
- prcDst->right = min(prcSrc1->right, prcSrc2->right);
-
- if (prcDst->left < prcDst->right)
- {
- prcDst->top = max(prcSrc1->top, prcSrc2->top);
- prcDst->bottom = min(prcSrc1->bottom, prcSrc2->bottom);
-
- if (prcDst->top < prcDst->bottom) return(TRUE);
- }
-
- *prcDst = rclEmpty;
-
- return FALSE;
-}
-
-void DIB_BltToVGA_Fixed(int x, int y, int w, int h, void *b, int Source_lDelta, int mod);
-
-BOOL
-DIBtoVGA(
- IN SURFOBJ *Dest,
- IN SURFOBJ *Source,
- IN XLATEOBJ *ColorTranslation,
- IN RECTL *DestRect,
- IN POINTL *SourcePoint)
-{
- LONG dx, dy;
-
- dx = DestRect->right - DestRect->left;
- dy = DestRect->bottom - DestRect->top;
-
- if (NULL == ColorTranslation || 0 != (ColorTranslation->flXlate & XO_TRIVIAL))
- {
- DIB_BltToVGA(DestRect->left, DestRect->top, dx, dy,
- (PVOID)((ULONG_PTR)Source->pvScan0 + SourcePoint->y * Source->lDelta + (SourcePoint->x >> 1)),
- Source->lDelta, SourcePoint->x % 2);
- }
- else
- {
- /* Perform color translation */
- DIB_BltToVGAWithXlate(DestRect->left, DestRect->top, dx, dy,
- (PVOID)((ULONG_PTR)Source->pvScan0 + SourcePoint->y * Source->lDelta + (SourcePoint->x >> 1)),
- Source->lDelta, ColorTranslation);
- }
- return FALSE;
-}
-
-BOOL
-VGAtoDIB(
- IN SURFOBJ *Dest,
- IN SURFOBJ *Source,
- IN XLATEOBJ *ColorTranslation,
- IN RECTL *DestRect,
- IN POINTL *SourcePoint)
-{
- LONG i, j, dx, dy;
- UCHAR *GDIpos, *initial;
-
- /* Used by the temporary DFB */
- //DEVSURF DestDevSurf;
-
- /* FIXME: Optimize to retrieve entire bytes at a time (see ../vgavideo/vgavideo.c:vgaGetByte) */
-
- GDIpos = Dest->pvScan0 /* + (DestRect->top * Dest->lDelta) + (DestRect->left >> 1) */ ;
- dx = DestRect->right - DestRect->left;
- dy = DestRect->bottom - DestRect->top;
-
- if (ColorTranslation == NULL)
- {
- /* Prepare a Dest Dev Target and copy from the DFB to the DIB */
- //DestDevSurf.NextScan = Dest->lDelta;
- //DestDevSurf.StartBmp = Dest->pvScan0;
-
- DIB_BltFromVGA(SourcePoint->x, SourcePoint->y, dx, dy, Dest->pvScan0, Dest->lDelta);
- }
- else
- {
- /* Color translation */
- for (j = SourcePoint->y; j < SourcePoint->y + dy; j++)
- {
- initial = GDIpos;
- for (i = SourcePoint->x; i < SourcePoint->x + dx; i++)
- {
- *GDIpos = XLATEOBJ_iXlate(ColorTranslation, vgaGetPixel(i, j));
- GDIpos++;
- }
- GDIpos = initial + Dest->lDelta;
- }
- }
- return FALSE;
-}
-
-BOOL
-DFBtoVGA(
- IN SURFOBJ *Dest,
- IN SURFOBJ *Source,
- IN XLATEOBJ *ColorTranslation,
- IN RECTL *DestRect,
- IN POINTL *SourcePoint)
-{
- /* Do DFBs need color translation?? */
- return FALSE;
-}
-
-BOOL
-VGAtoDFB(
- IN SURFOBJ *Dest,
- IN SURFOBJ *Source,
- IN XLATEOBJ *ColorTranslation,
- IN RECTL *DestRect,
- IN POINTL *SourcePoint)
-{
- /* Do DFBs need color translation?? */
- return FALSE;
-}
-
-BOOL
-VGAtoVGA(
- IN SURFOBJ *Dest,
- IN SURFOBJ *Source,
- IN XLATEOBJ *ColorTranslation,
- IN RECTL *DestRect,
- IN POINTL *SourcePoint)
-{
- LONG i, i2, j, dx, dy, alterx, altery;
- static char buf[SCREEN_X];
-
- /* Calculate deltas */
- dx = DestRect->right - DestRect->left;
- dy = DestRect->bottom - DestRect->top;
-
- alterx = DestRect->left - SourcePoint->x;
- altery = DestRect->top - SourcePoint->y;
-
- i = SourcePoint->x;
- i2 = i + alterx;
-
- if (SourcePoint->y >= DestRect->top)
- {
- for (j = SourcePoint->y; j < SourcePoint->y + dy; j++)
- {
- LONG j2 = j + altery;
- vgaReadScan ( i, j, dx, buf );
- vgaWriteScan ( i2, j2, dx, buf );
- }
- }
- else
- {
- for(j = (SourcePoint->y + dy - 1); j >= SourcePoint->y; j--)
- {
- LONG j2 = j + altery;
- vgaReadScan ( i, j, dx, buf );
- vgaWriteScan ( i2, j2, dx, buf );
- }
- }
-
- return TRUE;
-}
-
-BOOL APIENTRY
-VGADDI_BltBrush(
- IN SURFOBJ* Dest,
- IN SURFOBJ* Source,
- IN SURFOBJ* MaskSurf,
- IN XLATEOBJ* ColorTranslation,
- IN RECTL* DestRect,
- IN POINTL* SourcePoint,
- IN POINTL* MaskPoint,
- IN BRUSHOBJ* Brush,
- IN POINTL* BrushPoint,
- IN ROP4 Rop4)
-{
- UCHAR SolidColor = 0;
- LONG Left;
- LONG Length;
- PUCHAR Video;
- UCHAR Mask;
- INT i, j;
- ULONG RasterOp = VGA_NORMAL;
-
- /* Punt brush blts to non-device surfaces. */
- if (Dest->iType != STYPE_DEVICE)
- return FALSE;
-
- /* Punt pattern fills. */
- if ((GET_OPINDEX_FROM_ROP4(Rop4) == GET_OPINDEX_FROM_ROP3(PATCOPY)
- || GET_OPINDEX_FROM_ROP4(Rop4) == GET_OPINDEX_FROM_ROP3(PATINVERT)) &&
- Brush->iSolidColor == 0xFFFFFFFF)
- {
- return FALSE;
- }
-
- /* Get the brush colour. */
- switch (GET_OPINDEX_FROM_ROP4(Rop4))
- {
- case GET_OPINDEX_FROM_ROP3(PATCOPY): SolidColor = Brush->iSolidColor; break;
- case GET_OPINDEX_FROM_ROP3(PATINVERT): SolidColor = Brush->iSolidColor; RasterOp = VGA_XOR; break;
- case GET_OPINDEX_FROM_ROP3(WHITENESS): SolidColor = 0xF; break;
- case GET_OPINDEX_FROM_ROP3(BLACKNESS): SolidColor = 0x0; break;
- case GET_OPINDEX_FROM_ROP3(DSTINVERT): SolidColor = 0xF; RasterOp = VGA_XOR; break;
- }
-
- /* Select write mode 3. */
- WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x05);
- WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x03);
-
- /* Setup set/reset register. */
- WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x00);
- WRITE_PORT_UCHAR((PUCHAR)GRA_D, (UCHAR)SolidColor);
-
- /* Enable writes to all pixels. */
- WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x08);
- WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0xFF);
-
- /* Set up data rotate. */
- WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x03);
- WRITE_PORT_UCHAR((PUCHAR)GRA_D, RasterOp);
-
- /* Fill any pixels on the left which don't fall into a full row of eight. */
- if ((DestRect->left % 8) != 0)
- {
- /* Disable writes to pixels outside of the destination rectangle. */
- Mask = (1 << (8 - (DestRect->left % 8))) - 1;
- if ((DestRect->right - DestRect->left) < (8 - (DestRect->left % 8)))
- Mask &= ~((1 << (8 - (DestRect->right % 8))) - 1);
-
- /* Write the same color to each pixel. */
- Video = (PUCHAR)vidmem + DestRect->top * 80 + (DestRect->left >> 3);
- for (i = DestRect->top; i < DestRect->bottom; i++, Video += 80)
- {
- (VOID)READ_REGISTER_UCHAR(Video);
- WRITE_REGISTER_UCHAR(Video, Mask);
- }
-
- /* Have we finished. */
- if ((DestRect->right - DestRect->left) < (8 - (DestRect->left % 8)))
- {
- /* Restore write mode 2. */
- WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x05);
- WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x02);
-
- /* Set up data rotate. */
- WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x03);
- WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x00);
-
- return TRUE;
- }
- }
-
- /* Fill any whole rows of eight pixels. */
- Left = (DestRect->left + 7) & ~0x7;
- Length = (DestRect->right >> 3) - (Left >> 3);
- for (i = DestRect->top; i < DestRect->bottom; i++)
- {
- Video = (PUCHAR)vidmem + i * 80 + (Left >> 3);
- for (j = 0; j < Length; j++, Video++)
- {
-#if 0
- (VOID)READ_REGISTER_UCHAR(Video);
- WRITE_REGISTER_UCHAR(Video, 0xFF);
-#else
- char volatile Temp = *Video;
- Temp |= 0;
- *Video = 0xFF;
-#endif
- }
- }
-
- /* Fill any pixels on the right which don't fall into a complete row. */
- if ((DestRect->right % 8) != 0)
- {
- /* Disable writes to pixels outside the destination rectangle. */
- Mask = ~((1 << (8 - (DestRect->right % 8))) - 1);
-
- Video = (PUCHAR)vidmem + DestRect->top * 80 + (DestRect->right >> 3);
- for (i = DestRect->top; i < DestRect->bottom; i++, Video += 80)
- {
- (VOID)READ_REGISTER_UCHAR(Video);
- WRITE_REGISTER_UCHAR(Video, Mask);
- }
- }
-
- /* Restore write mode 2. */
- WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x05);
- WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x02);
-
- /* Set up data rotate. */
- WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x03);
- WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x00);
-
- return TRUE;
-}
-
-BOOL APIENTRY
-VGADDI_BltSrc(
- IN SURFOBJ* Dest,
- IN SURFOBJ* Source,
- IN SURFOBJ* Mask,
- IN XLATEOBJ* ColorTranslation,
- IN RECTL* DestRect,
- IN POINTL* SourcePoint,
- IN POINTL* MaskOrigin,
- IN BRUSHOBJ* Brush,
- IN POINTL* BrushOrigin,
- IN ROP4 Rop4)
-{
- PFN_VGABlt BltOperation;
- ULONG SourceType;
-
- SourceType = Source->iType;
-
- if (SourceType == STYPE_BITMAP && Dest->iType == STYPE_DEVICE)
- BltOperation = DIBtoVGA;
- else if (SourceType == STYPE_DEVICE && Dest->iType == STYPE_BITMAP)
- BltOperation = VGAtoDIB;
- else if (SourceType == STYPE_DEVICE && Dest->iType == STYPE_DEVICE)
- BltOperation = VGAtoVGA;
- else if (SourceType == STYPE_DEVBITMAP && Dest->iType == STYPE_DEVICE)
- BltOperation = DFBtoVGA;
- else if (SourceType == STYPE_DEVICE && Dest->iType == STYPE_DEVBITMAP)
- BltOperation = VGAtoDFB;
- else
- {
- /* Punt blts not involving a device or a device-bitmap. */
- return FALSE;
- }
-
- BltOperation(Dest, Source, ColorTranslation, DestRect, SourcePoint);
- return TRUE;
-}
-
-BOOL APIENTRY
-VGADDI_BltMask(
- IN SURFOBJ* Dest,
- IN SURFOBJ* Source,
- IN SURFOBJ* Mask,
- IN XLATEOBJ* ColorTranslation,
- IN RECTL* DestRect,
- IN POINTL* SourcePoint,
- IN POINTL* MaskPoint,
- IN BRUSHOBJ* Brush,
- IN POINTL* BrushPoint,
- IN ROP4 Rop4)
-{
- LONG i, j, dx, dy, c8;
- BYTE *tMask, *lMask;
-
- dx = DestRect->right - DestRect->left;
- dy = DestRect->bottom - DestRect->top;
-
- if (ColorTranslation == NULL)
- {
- if (Mask != NULL)
- {
- tMask = Mask->pvScan0;
- for (j = 0; j < dy; j++)
- {
- lMask = tMask;
- c8 = 0;
- for (i = 0; i < dx; i++)
- {
- if((*lMask & maskbit[c8]) != 0)
- vgaPutPixel(DestRect->left + i, DestRect->top + j, Brush->iSolidColor);
- c8++;
- if(c8 == 8)
- {
- lMask++;
- c8=0;
- }
- }
- tMask += Mask->lDelta;
- }
- }
- }
- return TRUE;
-}
-
-BOOL APIENTRY
-DrvBitBlt(
- IN SURFOBJ *Dest,
- IN SURFOBJ *Source,
- IN SURFOBJ *Mask,
- IN CLIPOBJ *Clip,
- IN XLATEOBJ *ColorTranslation,
- IN RECTL *DestRect,
- IN POINTL *SourcePoint,
- IN POINTL *MaskPoint,
- IN BRUSHOBJ *Brush,
- IN POINTL *BrushPoint,
- IN ROP4 rop4)
-{
- PBLTRECTFUNC BltRectFunc;
- RECTL CombinedRect;
- BOOL Ret = FALSE;
- RECT_ENUM RectEnum;
- BOOL EnumMore;
- UINT i;
- POINTL Pt;
- ULONG Direction;
- POINTL FinalSourcePoint;
-
- if (Source && SourcePoint)
- {
- FinalSourcePoint.x = SourcePoint->x;
- FinalSourcePoint.y = SourcePoint->y;
- }
- else
- {
- FinalSourcePoint.x = 0;
- FinalSourcePoint.y = 0;
- }
-
- switch (rop4)
- {
- case ROP3_TO_ROP4(BLACKNESS):
- case ROP3_TO_ROP4(PATCOPY):
- case ROP3_TO_ROP4(WHITENESS):
- case ROP3_TO_ROP4(PATINVERT):
- case ROP3_TO_ROP4(DSTINVERT):
- BltRectFunc = VGADDI_BltBrush;
- break;
-
- case ROP3_TO_ROP4(SRCCOPY):
- if (BMF_4BPP == Source->iBitmapFormat && BMF_4BPP == Dest->iBitmapFormat)
- BltRectFunc = VGADDI_BltSrc;
- else
- return FALSE;
- break;
-
- case R4_MASK:
- BltRectFunc = VGADDI_BltMask;
- break;
-
- default:
- return FALSE;
- }
-
- switch (NULL == Clip ? DC_TRIVIAL : Clip->iDComplexity)
- {
- case DC_TRIVIAL:
- Ret = (*BltRectFunc)(Dest, Source, Mask, ColorTranslation, DestRect,
- SourcePoint, MaskPoint, Brush, BrushPoint,
- rop4);
- break;
- case DC_RECT:
- /* Clip the blt to the clip rectangle */
- VGADDI_IntersectRect(&CombinedRect, DestRect, &(Clip->rclBounds));
- Pt.x = FinalSourcePoint.x + CombinedRect.left - DestRect->left;
- Pt.y = FinalSourcePoint.y + CombinedRect.top - DestRect->top;
- Ret = (*BltRectFunc)(Dest, Source, Mask, ColorTranslation, &CombinedRect,
- &Pt, MaskPoint, Brush, BrushPoint,
- rop4);
- break;
- case DC_COMPLEX:
- Ret = TRUE;
- if (Dest == Source)
- {
- if (DestRect->top <= FinalSourcePoint.y)
- Direction = DestRect->left < FinalSourcePoint.y ? CD_RIGHTDOWN : CD_LEFTDOWN;
- else
- Direction = DestRect->left < FinalSourcePoint.x ? CD_RIGHTUP : CD_LEFTUP;
- }
- else
- {
- Direction = CD_ANY;
- }
- CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, Direction, 0);
- do
- {
- EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
-
- for (i = 0; i < RectEnum.c; i++)
- {
- VGADDI_IntersectRect(&CombinedRect, DestRect, RectEnum.arcl + i);
- Pt.x = FinalSourcePoint.x + CombinedRect.left - DestRect->left;
- Pt.y = FinalSourcePoint.y + CombinedRect.top - DestRect->top;
- Ret = (*BltRectFunc)(Dest, Source, Mask, ColorTranslation, &CombinedRect,
- &Pt, MaskPoint, Brush, BrushPoint, rop4) &&
- Ret;
- }
- } while (EnumMore);
- break;
- }
-
- return Ret;
-}