1 /* 2 * PROJECT: ReactOS VGA display driver 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: drivers/video/displays/vga/objects/paint.c 5 * PURPOSE: 6 * PROGRAMMERS: 7 */ 8 9 #include <vgaddi.h> 10 11 BOOL VGADDIFillSolid(SURFOBJ *Surface, RECTL Dimensions, ULONG iColor) 12 { 13 int x, y, x2, y2, w, h, j; 14 ULONG orgx, pre1, midpre1, tmppre1; 15 //ULONG offset, orgpre1; 16 int ileftpix, imidpix, irightpix; 17 /* double leftpix, midpix, rightpix;*/ 18 19 /* Swap dimensions so that x, y are at topmost left */ 20 if ( Dimensions.right < Dimensions.left ) 21 { 22 x = Dimensions.right; 23 x2 = Dimensions.left; 24 } 25 else 26 { 27 x2 = Dimensions.right; 28 x = Dimensions.left; 29 } 30 if ( Dimensions.bottom < Dimensions.top ) 31 { 32 y = Dimensions.bottom; 33 y2 = Dimensions.top; 34 } 35 else 36 { 37 y2 = Dimensions.bottom; 38 y = Dimensions.top; 39 } 40 41 /* Calculate the width and height */ 42 w = x2 - x; 43 h = y2 - y; 44 45 DPRINT("VGADDIFillSolid: x:%d, y:%d, w:%d, h:%d\n", x, y, w, h); 46 47 /* Calculate the starting offset */ 48 //offset = xconv[x]+y80[y]; 49 50 /* Make a note of original x */ 51 orgx = x; 52 53 /* Calculate the left mask pixels, middle bytes and right mask pixel */ 54 ileftpix = 7 - mod8(x-1); 55 irightpix = mod8(x+w); 56 imidpix = (w-ileftpix-irightpix) / 8; 57 58 pre1 = xconv[(x-1)&~7] + y80[y]; 59 //orgpre1=pre1; 60 61 /* check for overlap ( very horizontally skinny rect ) */ 62 if ( (ileftpix+irightpix) > w ) 63 { 64 int mask = startmasks[ileftpix] & endmasks[irightpix]; 65 66 WRITE_PORT_UCHAR((PUCHAR)GRA_I,0x08); // set the mask 67 WRITE_PORT_UCHAR((PUCHAR)GRA_D,mask); 68 69 tmppre1 = pre1; 70 for ( j = y; j < y+h; j++ ) 71 { 72 READ_REGISTER_UCHAR ( vidmem+tmppre1 ); 73 WRITE_REGISTER_UCHAR ( vidmem+tmppre1, iColor ); 74 tmppre1 += 80; 75 } 76 return TRUE; 77 } 78 79 if ( ileftpix > 0 ) 80 { 81 /* Write left pixels */ 82 WRITE_PORT_UCHAR((PUCHAR)GRA_I,0x08); // set the mask 83 WRITE_PORT_UCHAR((PUCHAR)GRA_D,startmasks[ileftpix]); 84 85 tmppre1 = pre1; 86 for ( j = y; j < y+h; j++ ) 87 { 88 READ_REGISTER_UCHAR(vidmem + tmppre1); 89 WRITE_REGISTER_UCHAR(vidmem + tmppre1, iColor); 90 tmppre1 += 80; 91 } 92 93 /* Prepare new x for the middle */ 94 x = orgx + 8; 95 } 96 97 if ( imidpix > 0 ) 98 { 99 midpre1=xconv[x] + y80[y]; 100 101 /* Set mask to all pixels in byte */ 102 WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x08); 103 104 WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0xff); 105 106 for ( j = y; j < y+h; j++ ) 107 { 108 memset(vidmem+midpre1, iColor, imidpix); // write middle pixels, no need to read in latch because of the width 109 midpre1 += 80; 110 } 111 } 112 113 x = orgx + w - irightpix; 114 pre1 = xconv[x] + y80[y]; 115 116 /* Write right pixels */ 117 WRITE_PORT_UCHAR((PUCHAR)GRA_I,0x08); // set the mask bits 118 WRITE_PORT_UCHAR((PUCHAR)GRA_D,endmasks[irightpix]); 119 120 for ( j = y; j < y+h; j++ ) 121 { 122 READ_REGISTER_UCHAR(vidmem + pre1); 123 WRITE_REGISTER_UCHAR(vidmem + pre1, iColor); 124 pre1 += 80; 125 } 126 127 return TRUE; 128 } 129 130 BOOL VGADDIPaintRgn( 131 IN SURFOBJ *Surface, 132 IN CLIPOBJ *ClipRegion, 133 IN ULONG iColor, 134 IN MIX Mix, 135 IN BRUSHINST *BrushInst, 136 IN POINTL *BrushPoint) 137 { 138 RECT_ENUM RectEnum; 139 BOOL EnumMore; 140 141 DPRINT("VGADDIPaintRgn: iMode: %d, iDComplexity: %d\n Color:%d\n", ClipRegion->iMode, ClipRegion->iDComplexity, iColor); 142 switch(ClipRegion->iMode) 143 { 144 case TC_RECTANGLES: 145 146 /* Rectangular clipping can be handled without enumeration. 147 Note that trivial clipping is not possible, since the clipping 148 region defines the area to fill */ 149 150 if (ClipRegion->iDComplexity == DC_RECT) 151 { 152 DPRINT("VGADDIPaintRgn Rect:%d %d %d %d\n", ClipRegion->rclBounds.left, ClipRegion->rclBounds.top, ClipRegion->rclBounds.right, ClipRegion->rclBounds.bottom); 153 VGADDIFillSolid(Surface, ClipRegion->rclBounds, iColor); 154 } 155 else 156 { 157 /* Enumerate all the rectangles and draw them */ 158 159 CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, CD_ANY, 0); 160 161 do 162 { 163 UINT i; 164 EnumMore = CLIPOBJ_bEnum(ClipRegion, sizeof(RectEnum), (PVOID) &RectEnum); 165 DPRINT("EnumMore: %d, count: %d\n", EnumMore, RectEnum.c); 166 for( i=0; i<RectEnum.c; i++) 167 { 168 DPRINT("VGADDI enum Rect:%d %d %d %d\n", RectEnum.arcl[i].left, RectEnum.arcl[i].top, RectEnum.arcl[i].right, RectEnum.arcl[i].bottom); 169 VGADDIFillSolid(Surface, RectEnum.arcl[i], iColor); 170 } 171 } while (EnumMore); 172 } 173 return TRUE; 174 175 default: 176 return FALSE; 177 } 178 } 179 180 181 BOOL APIENTRY 182 DrvPaint( 183 IN SURFOBJ *Surface, 184 IN CLIPOBJ *ClipRegion, 185 IN BRUSHOBJ *Brush, 186 IN POINTL *BrushOrigin, 187 IN MIX Mix) 188 { 189 ULONG iSolidColor; 190 191 iSolidColor = Brush->iSolidColor; // FIXME: Realizations and the like 192 193 // If the foreground and background Mixes are the same, 194 // (LATER or if there's no brush mask) 195 // then see if we can use the solid brush accelerators 196 197 // FIXME: Put in the mix switch below 198 // Brush color parameter doesn't matter for these rops 199 return(VGADDIPaintRgn(Surface, ClipRegion, iSolidColor, Mix, NULL, BrushOrigin)); 200 201 if ((Mix & 0xFF) == ((Mix >> 8) & 0xFF)) 202 { 203 switch (Mix & 0xFF) 204 { 205 case 0: 206 break; 207 208 // FIXME: Implement all these millions of ROPs 209 // For now we don't support brushes -- everything is solid 210 211 case R2_MASKNOTPEN: 212 case R2_NOTCOPYPEN: 213 case R2_XORPEN: 214 case R2_MASKPEN: 215 case R2_NOTXORPEN: 216 case R2_MERGENOTPEN: 217 case R2_COPYPEN: 218 case R2_MERGEPEN: 219 case R2_NOTMERGEPEN: 220 case R2_MASKPENNOT: 221 case R2_NOTMASKPEN: 222 case R2_MERGEPENNOT: 223 224 // Rops that are implicit solid colors 225 case R2_NOT: 226 case R2_WHITE: 227 case R2_BLACK: 228 229 230 // FIXME: The Paint region belongs HERE 231 232 case R2_NOP: 233 return TRUE; 234 235 default: 236 break; 237 } 238 } 239 240 /* 241 doBitBlt: 242 243 // If VGADDIPaint can't do it, VGADDIBitBlt can.. or it might just loop back 244 // here and we have a nice infinite loop 245 246 return( VGADDIBitBlt(Surface, (SURFOBJ *)NULL, (SURFOBJ *)NULL, ClipRegion, 247 (XLATEOBJ *)NULL, &ClipRegion->rclBounds, 248 NULL, (POINTL *)NULL, Brush, BrushOrigin, 249 NULL) ); UNIMPLEMENTED */ 250 } 251