5 #include "../vgavideo/vgavideo.h"
9 typedef BOOL (*PFN_VGABlt
)(SURFOBJ
*, SURFOBJ
*, XLATEOBJ
*, RECTL
*, POINTL
*);
10 typedef BOOL
STDCALL (*PBLTRECTFUNC
)(SURFOBJ
* OutputObj
,
13 XLATEOBJ
* ColorTranslation
,
21 static BOOL FASTCALL
VGADDI_IntersectRect(RECTL
* prcDst
, RECTL
* prcSrc1
, RECTL
* prcSrc2
)
23 static const RECTL rclEmpty
= { 0, 0, 0, 0 };
25 prcDst
->left
= max(prcSrc1
->left
, prcSrc2
->left
);
26 prcDst
->right
= min(prcSrc1
->right
, prcSrc2
->right
);
28 if (prcDst
->left
< prcDst
->right
)
30 prcDst
->top
= max(prcSrc1
->top
, prcSrc2
->top
);
31 prcDst
->bottom
= min(prcSrc1
->bottom
, prcSrc2
->bottom
);
33 if (prcDst
->top
< prcDst
->bottom
) return(TRUE
);
41 void DIB_BltToVGA_Fixed(int x
, int y
, int w
, int h
, void *b
, int Source_lDelta
, int mod
);
44 DIBtoVGA(SURFOBJ
*Dest
, SURFOBJ
*Source
, XLATEOBJ
*ColorTranslation
,
45 RECTL
*DestRect
, POINTL
*SourcePoint
)
49 dx
= DestRect
->right
- DestRect
->left
;
50 dy
= DestRect
->bottom
- DestRect
->top
;
52 if (NULL
== ColorTranslation
|| 0 != (ColorTranslation
->flXlate
& XO_TRIVIAL
))
54 DIB_BltToVGA(DestRect
->left
, DestRect
->top
, dx
, dy
,
55 Source
->pvScan0
+ SourcePoint
->y
* Source
->lDelta
+ (SourcePoint
->x
>> 1),
56 Source
->lDelta
, SourcePoint
->x
% 2);
60 /* Perform color translation */
61 DIB_BltToVGAWithXlate(DestRect
->left
, DestRect
->top
, dx
, dy
,
62 Source
->pvScan0
+ SourcePoint
->y
* Source
->lDelta
+ (SourcePoint
->x
>> 1),
63 Source
->lDelta
, ColorTranslation
);
69 VGAtoDIB(SURFOBJ
*Dest
, SURFOBJ
*Source
, XLATEOBJ
*ColorTranslation
,
70 RECTL
*DestRect
, POINTL
*SourcePoint
)
73 BYTE
*GDIpos
, *initial
;
75 // Used by the temporary DFB
78 // FIXME: Optimize to retrieve entire bytes at a time (see /display/vgavideo/vgavideo.c:vgaGetByte)
80 GDIpos
= Dest
->pvScan0
/* + (DestRect->top * Dest->lDelta) + (DestRect->left >> 1) */ ;
81 dx
= DestRect
->right
- DestRect
->left
;
82 dy
= DestRect
->bottom
- DestRect
->top
;
84 if(ColorTranslation
== NULL
)
86 // Prepare a Dest Dev Target and copy from the DFB to the DIB
87 DestDevSurf
.NextScan
= Dest
->lDelta
;
88 DestDevSurf
.StartBmp
= Dest
->pvScan0
;
90 DIB_BltFromVGA(SourcePoint
->x
, SourcePoint
->y
, dx
, dy
, Dest
->pvScan0
, Dest
->lDelta
);
94 for(j
=SourcePoint
->y
; j
<SourcePoint
->y
+dy
; j
++)
97 for(i
=SourcePoint
->x
; i
<SourcePoint
->x
+dx
; i
++)
99 *GDIpos
= XLATEOBJ_iXlate(ColorTranslation
, vgaGetPixel(i
, j
));
102 GDIpos
= initial
+ Dest
->lDelta
;
109 DFBtoVGA(SURFOBJ
*Dest
, SURFOBJ
*Source
, XLATEOBJ
*ColorTranslation
,
110 RECTL
*DestRect
, POINTL
*SourcePoint
)
113 // Do DFBs need color translation??
117 VGAtoDFB(SURFOBJ
*Dest
, SURFOBJ
*Source
, XLATEOBJ
*ColorTranslation
,
118 RECTL
*DestRect
, POINTL
*SourcePoint
)
121 // Do DFBs need color translation??
125 VGAtoVGA(SURFOBJ
*Dest
, SURFOBJ
*Source
, XLATEOBJ
*ColorTranslation
,
126 RECTL
*DestRect
, POINTL
*SourcePoint
)
128 LONG i
, i2
, j
, dx
, dy
, alterx
, altery
;
129 //LARGE_INTEGER Start, End; // for performance measurement only
130 static char buf
[640];
134 dx
= DestRect
->right
- DestRect
->left
;
135 dy
= DestRect
->bottom
- DestRect
->top
;
137 alterx
= DestRect
->left
- SourcePoint
->x
;
138 altery
= DestRect
->top
- SourcePoint
->y
;
140 //KeQueryTickCount ( &Start );
145 if (SourcePoint
->y
>= DestRect
->top
)
147 for(j
=SourcePoint
->y
; j
<SourcePoint
->y
+dy
; j
++)
149 LONG j2
= j
+ altery
;
150 vgaReadScan ( i
, j
, dx
, buf
);
151 vgaWriteScan ( i2
, j2
, dx
, buf
);
156 for(j
=(SourcePoint
->y
+dy
-1); j
>=SourcePoint
->y
; j
--)
158 LONG j2
= j
+ altery
;
159 vgaReadScan ( i
, j
, dx
, buf
);
160 vgaWriteScan ( i2
, j2
, dx
, buf
);
164 //KeQueryTickCount ( &End );
165 //DbgPrint ( "VgaBitBlt timing: %lu\n", (ULONG)(End.QuadPart-Start.QuadPart) );
171 VGADDI_BltBrush(SURFOBJ
* Dest
, SURFOBJ
* Source
, SURFOBJ
* MaskSurf
,
172 XLATEOBJ
* ColorTranslation
, RECTL
* DestRect
,
173 POINTL
* SourcePoint
, POINTL
* MaskPoint
,
174 BRUSHOBJ
* Brush
, POINTL
* BrushPoint
, ROP4 Rop4
)
176 UCHAR SolidColor
= 0;
182 ULONG RasterOp
= VGA_NORMAL
;
184 /* Punt brush blts to non-device surfaces. */
185 if (Dest
->iType
!= STYPE_DEVICE
)
190 /* Punt pattern fills. */
191 if ((GET_OPINDEX_FROM_ROP4(Rop4
) == GET_OPINDEX_FROM_ROP3(PATCOPY
)
192 || GET_OPINDEX_FROM_ROP4(Rop4
) == GET_OPINDEX_FROM_ROP3(PATINVERT
)) &&
193 Brush
->iSolidColor
== 0xFFFFFFFF)
198 /* Get the brush colour. */
199 switch (GET_OPINDEX_FROM_ROP4(Rop4
))
201 case GET_OPINDEX_FROM_ROP3(PATCOPY
): SolidColor
= Brush
->iSolidColor
; break;
202 case GET_OPINDEX_FROM_ROP3(PATINVERT
): SolidColor
= Brush
->iSolidColor
; RasterOp
= VGA_XOR
; break;
203 case GET_OPINDEX_FROM_ROP3(WHITENESS
): SolidColor
= 0xF; break;
204 case GET_OPINDEX_FROM_ROP3(BLACKNESS
): SolidColor
= 0x0; break;
205 case GET_OPINDEX_FROM_ROP3(DSTINVERT
): SolidColor
= 0xF; RasterOp
= VGA_XOR
; break;
208 /* Select write mode 3. */
209 WRITE_PORT_UCHAR((PUCHAR
)GRA_I
, 0x05);
210 WRITE_PORT_UCHAR((PUCHAR
)GRA_D
, 0x03);
212 /* Setup set/reset register. */
213 WRITE_PORT_UCHAR((PUCHAR
)GRA_I
, 0x00);
214 WRITE_PORT_UCHAR((PUCHAR
)GRA_D
, (UCHAR
)SolidColor
);
216 /* Enable writes to all pixels. */
217 WRITE_PORT_UCHAR((PUCHAR
)GRA_I
, 0x08);
218 WRITE_PORT_UCHAR((PUCHAR
)GRA_D
, 0xFF);
220 /* Set up data rotate. */
221 WRITE_PORT_UCHAR((PUCHAR
)GRA_I
, 0x03);
222 WRITE_PORT_UCHAR((PUCHAR
)GRA_D
, RasterOp
);
224 /* Fill any pixels on the left which don't fall into a full row of eight. */
225 if ((DestRect
->left
% 8) != 0)
227 /* Disable writes to pixels outside of the destination rectangle. */
228 Mask
= (1 << (8 - (DestRect
->left
% 8))) - 1;
229 if ((DestRect
->right
- DestRect
->left
) < (8 - (DestRect
->left
% 8)))
231 Mask
&= ~((1 << (8 - (DestRect
->right
% 8))) - 1);
234 /* Write the same color to each pixel. */
235 Video
= (PUCHAR
)vidmem
+ DestRect
->top
* 80 + (DestRect
->left
>> 3);
236 for (i
= DestRect
->top
; i
< DestRect
->bottom
; i
++, Video
+=80)
238 (VOID
)READ_REGISTER_UCHAR(Video
);
239 WRITE_REGISTER_UCHAR(Video
, Mask
);
242 /* Have we finished. */
243 if ((DestRect
->right
- DestRect
->left
) < (8 - (DestRect
->left
% 8)))
245 /* Restore write mode 2. */
246 WRITE_PORT_UCHAR((PUCHAR
)GRA_I
, 0x05);
247 WRITE_PORT_UCHAR((PUCHAR
)GRA_D
, 0x02);
249 /* Set up data rotate. */
250 WRITE_PORT_UCHAR((PUCHAR
)GRA_I
, 0x03);
251 WRITE_PORT_UCHAR((PUCHAR
)GRA_D
, 0x00);
257 /* Fill any whole rows of eight pixels. */
258 Left
= (DestRect
->left
+ 7) & ~0x7;
259 Length
= (DestRect
->right
>> 3) - (Left
>> 3);
260 for (i
= DestRect
->top
; i
< DestRect
->bottom
; i
++)
262 Video
= (PUCHAR
)vidmem
+ i
* 80 + (Left
>> 3);
263 for (j
= 0; j
< Length
; j
++, Video
++)
266 (VOID
)READ_REGISTER_UCHAR(Video
);
267 WRITE_REGISTER_UCHAR(Video
, 0xFF);
269 char volatile Temp
= *Video
;
276 /* Fill any pixels on the right which don't fall into a complete row. */
277 if ((DestRect
->right
% 8) != 0)
279 /* Disable writes to pixels outside the destination rectangle. */
280 Mask
= ~((1 << (8 - (DestRect
->right
% 8))) - 1);
282 Video
= (PUCHAR
)vidmem
+ DestRect
->top
* 80 + (DestRect
->right
>> 3);
283 for (i
= DestRect
->top
; i
< DestRect
->bottom
; i
++, Video
+=80)
285 (VOID
)READ_REGISTER_UCHAR(Video
);
286 WRITE_REGISTER_UCHAR(Video
, Mask
);
290 /* Restore write mode 2. */
291 WRITE_PORT_UCHAR((PUCHAR
)GRA_I
, 0x05);
292 WRITE_PORT_UCHAR((PUCHAR
)GRA_D
, 0x02);
294 /* Set up data rotate. */
295 WRITE_PORT_UCHAR((PUCHAR
)GRA_I
, 0x03);
296 WRITE_PORT_UCHAR((PUCHAR
)GRA_D
, 0x00);
302 VGADDI_BltSrc(SURFOBJ
* Dest
, SURFOBJ
* Source
, SURFOBJ
* Mask
,
303 XLATEOBJ
* ColorTranslation
, RECTL
* DestRect
, POINTL
* SourcePoint
,
304 POINTL
* MaskOrigin
, BRUSHOBJ
* Brush
, POINTL
* BrushOrigin
, ROP4 Rop4
)
306 PFN_VGABlt BltOperation
;
309 SourceType
= Source
->iType
;
311 if (SourceType
== STYPE_BITMAP
&& Dest
->iType
== STYPE_DEVICE
)
313 BltOperation
= DIBtoVGA
;
315 else if (SourceType
== STYPE_DEVICE
&& Dest
->iType
== STYPE_BITMAP
)
317 BltOperation
= VGAtoDIB
;
319 else if (SourceType
== STYPE_DEVICE
&& Dest
->iType
== STYPE_DEVICE
)
321 BltOperation
= VGAtoVGA
;
323 else if (SourceType
== STYPE_DEVBITMAP
&& Dest
->iType
== STYPE_DEVICE
)
325 BltOperation
= DFBtoVGA
;
327 else if (SourceType
== STYPE_DEVICE
&& Dest
->iType
== STYPE_DEVBITMAP
)
329 BltOperation
= VGAtoDFB
;
333 /* Punt blts not involving a device or a device-bitmap. */
337 BltOperation(Dest
, Source
, ColorTranslation
, DestRect
, SourcePoint
);
342 VGADDI_BltMask(SURFOBJ
* Dest
, SURFOBJ
* Source
, SURFOBJ
* Mask
,
343 XLATEOBJ
* ColorTranslation
, RECTL
* DestRect
,
344 POINTL
* SourcePoint
, POINTL
* MaskPoint
, BRUSHOBJ
* Brush
,
345 POINTL
* BrushPoint
, ROP4 Rop4
)
347 LONG i
, j
, dx
, dy
, c8
;
350 dx
= DestRect
->right
- DestRect
->left
;
351 dy
= DestRect
->bottom
- DestRect
->top
;
353 if (ColorTranslation
== NULL
)
357 tMask
= Mask
->pvScan0
;
364 if((*lMask
& maskbit
[c8
]) != 0)
366 vgaPutPixel(DestRect
->left
+ i
, DestRect
->top
+ j
, Brush
->iSolidColor
);
369 if(c8
== 8) { lMask
++; c8
=0; }
371 tMask
+= Mask
->lDelta
;
379 DrvBitBlt(SURFOBJ
*Dest
,
383 XLATEOBJ
*ColorTranslation
,
391 PBLTRECTFUNC BltRectFunc
;
402 case ROP3_TO_ROP4(BLACKNESS
):
403 case ROP3_TO_ROP4(PATCOPY
):
404 case ROP3_TO_ROP4(WHITENESS
):
405 case ROP3_TO_ROP4(PATINVERT
):
406 case ROP3_TO_ROP4(DSTINVERT
):
407 BltRectFunc
= VGADDI_BltBrush
;
410 case ROP3_TO_ROP4(SRCCOPY
):
411 if (BMF_4BPP
== Source
->iBitmapFormat
&& BMF_4BPP
== Dest
->iBitmapFormat
)
413 BltRectFunc
= VGADDI_BltSrc
;
422 BltRectFunc
= VGADDI_BltMask
;
429 switch(NULL
== Clip
? DC_TRIVIAL
: Clip
->iDComplexity
)
432 Ret
= (*BltRectFunc
)(Dest
, Source
, Mask
, ColorTranslation
, DestRect
,
433 SourcePoint
, MaskPoint
, Brush
, BrushPoint
,
437 // Clip the blt to the clip rectangle
438 VGADDI_IntersectRect(&CombinedRect
, DestRect
, &(Clip
->rclBounds
));
439 Pt
.x
= SourcePoint
->x
+ CombinedRect
.left
- DestRect
->left
;
440 Pt
.y
= SourcePoint
->y
+ CombinedRect
.top
- DestRect
->top
;
441 Ret
= (*BltRectFunc
)(Dest
, Source
, Mask
, ColorTranslation
, &CombinedRect
,
442 &Pt
, MaskPoint
, Brush
, BrushPoint
,
449 if (DestRect
->top
<= SourcePoint
->y
)
451 Direction
= DestRect
->left
< SourcePoint
->x
? CD_RIGHTDOWN
: CD_LEFTDOWN
;
455 Direction
= DestRect
->left
< SourcePoint
->x
? CD_RIGHTUP
: CD_LEFTUP
;
462 CLIPOBJ_cEnumStart(Clip
, FALSE
, CT_RECTANGLES
, Direction
, 0);
465 EnumMore
= CLIPOBJ_bEnum(Clip
, (ULONG
) sizeof(RectEnum
), (PVOID
) &RectEnum
);
467 for (i
= 0; i
< RectEnum
.c
; i
++)
469 VGADDI_IntersectRect(&CombinedRect
, DestRect
, RectEnum
.arcl
+ i
);
470 Pt
.x
= SourcePoint
->x
+ CombinedRect
.left
- DestRect
->left
;
471 Pt
.y
= SourcePoint
->y
+ CombinedRect
.top
- DestRect
->top
;
472 Ret
= (*BltRectFunc
)(Dest
, Source
, Mask
, ColorTranslation
, &CombinedRect
,
473 &Pt
, MaskPoint
, Brush
, BrushPoint
, rop4
) &&