sunGX.c revision ee7c6486
1/* 2static char *rid="$Xorg: sunGX.c,v 1.5 2001/02/09 02:04:44 xorgcvs Exp $"; 3 */ 4/* 5Copyright 1991, 1998 The Open Group 6 7Permission to use, copy, modify, distribute, and sell this software and its 8documentation for any purpose is hereby granted without fee, provided that 9the above copyright notice appear in all copies and that both that 10copyright notice and this permission notice appear in supporting 11documentation. 12 13The above copyright notice and this permission notice shall be included in 14all copies or substantial portions of the Software. 15 16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 20AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 23Except as contained in this notice, the name of The Open Group shall not be 24used in advertising or otherwise to promote the sale, use or other dealings 25in this Software without prior written authorization from The Open Group. 26 * 27 * Author: Keith Packard, MIT X Consortium 28 */ 29 30/* $XFree86: xc/programs/Xserver/hw/sun/sunGX.c,v 1.9 2003/11/17 22:20:36 dawes Exp $ */ 31 32#include "sun.h" 33 34#include <X11/Xmd.h> 35#include "gcstruct.h" 36#include "pixmapstr.h" 37#include "regionstr.h" 38#include "mistruct.h" 39#include <X11/fonts/fontstruct.h> 40#include "dixfontstr.h" 41#include "fb.h" 42#include "sunGX.h" 43#include "migc.h" 44#include "mispans.h" 45 46#define sunGXFillSpan(gx,y,x1,x2,r) {\ 47 (gx)->apointy = (y); \ 48 (gx)->apointx = (x1); \ 49 (gx)->arectx = (x2); \ 50 GXDrawDone(gx,r); \ 51} 52 53#define GXSetClip(gx,pbox) {\ 54 (gx)->clipminx = (pbox)->x1; \ 55 (gx)->clipminy = (pbox)->y1; \ 56 (gx)->clipmaxx = (pbox)->x2 - 1; \ 57 (gx)->clipmaxy = (pbox)->y2 - 1; \ 58} 59 60#define GXSetOff(gx,x,y) {\ 61 (gx)->offx = (x); \ 62 (gx)->offy = (y); \ 63} 64 65#define GXResetClip(gx,pScreen) { \ 66 (gx)->clipminx = 0; \ 67 (gx)->clipminy = 0; \ 68 (gx)->clipmaxx = (pScreen)->width - 1; \ 69 (gx)->clipmaxy = (pScreen)->height - 1; \ 70} 71 72#define GXResetOff(gx) {\ 73 (gx)->offx = 0; \ 74 (gx)->offy = 0; \ 75} 76 77#define sunGXGetAddrRange(pDrawable,extents,base,lo,hi) {\ 78 int __x__; \ 79 cfbGetWindowByteWidthAndPointer((WindowPtr)pDrawable,__x__,base); \ 80 lo = (base) + WIDTH_MUL((extents)->y1) + (extents)->x1; \ 81 hi = (base) + WIDTH_MUL((extents)->y2 - 1) + (extents)->x2 - 1; \ 82 (base) = (base) + WIDTH_MUL(pDrawable->y) + pDrawable->x; \ 83} 84 85/* 86 rop_tables 87 ========== 88 lookup tables for GX raster ops, with the plane_mask,pixel_mask,pattern_mask 89 ,attrib_sel, polygon_draw,raster_mode encoded into the top half. 90 There is a lookup table for each commonly used combination. 91*/ 92 93/* rops for bit blit / copy area 94 with: 95 Plane Mask - use plane mask reg. 96 Pixel Mask - use all ones. 97 Patt Mask - use all ones. 98*/ 99 100#define POLY_O GX_POLYG_OVERLAP 101#define POLY_N GX_POLYG_NONOVERLAP 102 103#define ROP_STANDARD (GX_PLANE_MASK |\ 104 GX_PIXEL_ONES |\ 105 GX_ATTR_SUPP |\ 106 GX_RAST_BOOL |\ 107 GX_PLOT_PLOT) 108 109/* fg = don't care bg = don't care */ 110 111#define ROP_BLIT(O,I) (ROP_STANDARD | \ 112 GX_PATTERN_ONES |\ 113 GX_ROP_11_1(I) |\ 114 GX_ROP_11_0(O) |\ 115 GX_ROP_10_1(I) |\ 116 GX_ROP_10_0(O) |\ 117 GX_ROP_01_1(I) |\ 118 GX_ROP_01_0(O) |\ 119 GX_ROP_00_1(I) |\ 120 GX_ROP_00_0(O)) 121 122/* fg = fgPixel bg = don't care */ 123 124#define ROP_FILL(O,I) (ROP_STANDARD | \ 125 GX_PATTERN_ONES |\ 126 GX_ROP_11_1(I) |\ 127 GX_ROP_11_0(I) |\ 128 GX_ROP_10_1(I) |\ 129 GX_ROP_10_0(I) | \ 130 GX_ROP_01_1(O) |\ 131 GX_ROP_01_0(O) |\ 132 GX_ROP_00_1(O) |\ 133 GX_ROP_00_0(O)) 134 135/* fg = fgPixel bg = don't care */ 136 137#define ROP_STIP(O,I) (ROP_STANDARD |\ 138 GX_ROP_11_1(I) |\ 139 GX_ROP_11_0(GX_ROP_NOOP) |\ 140 GX_ROP_10_1(I) |\ 141 GX_ROP_10_0(GX_ROP_NOOP) | \ 142 GX_ROP_01_1(O) |\ 143 GX_ROP_01_0(GX_ROP_NOOP) |\ 144 GX_ROP_00_1(O) |\ 145 GX_ROP_00_0(GX_ROP_NOOP)) 146 147/* fg = fgPixel bg = bgPixel */ 148 149#define ROP_OSTP(O,I) (ROP_STANDARD |\ 150 GX_ROP_11_1(I) |\ 151 GX_ROP_11_0(I) |\ 152 GX_ROP_10_1(I) |\ 153 GX_ROP_10_0(O) |\ 154 GX_ROP_01_1(O) |\ 155 GX_ROP_01_0(I) |\ 156 GX_ROP_00_1(O) |\ 157 GX_ROP_00_0(O)) 158 159#define ROP_ITXT(O,I) (ROP_STANDARD |\ 160 GX_PATTERN_ONES |\ 161 GX_ROP_11_1(I) |\ 162 GX_ROP_11_0(I) |\ 163 GX_ROP_10_1(I) |\ 164 GX_ROP_10_0(O) |\ 165 GX_ROP_01_1(O) |\ 166 GX_ROP_01_0(I) |\ 167 GX_ROP_00_1(O) |\ 168 GX_ROP_00_0(O)) 169 170#define ROP_PTXT(O,I) (ROP_STANDARD |\ 171 GX_PATTERN_ONES |\ 172 GX_ROP_11_1(I) |\ 173 GX_ROP_11_0(GX_ROP_NOOP) |\ 174 GX_ROP_10_1(I) |\ 175 GX_ROP_10_0(GX_ROP_NOOP) | \ 176 GX_ROP_01_1(O) |\ 177 GX_ROP_01_0(GX_ROP_NOOP) |\ 178 GX_ROP_00_1(O) |\ 179 GX_ROP_00_0(GX_ROP_NOOP)) 180 181static void sunGXDoBitblt(DrawablePtr, DrawablePtr, int, RegionPtr, DDXPointPtr, unsigned long); 182static RegionPtr sunGXCopyArea(DrawablePtr, DrawablePtr, GC *, int, int, int, int, int, int); 183static void sunGXCopyPlane1to8(DrawablePtr, DrawablePtr, int, RegionPtr, DDXPointPtr, unsigned long, unsigned long); 184static RegionPtr sunGXCopyPlane(DrawablePtr, DrawablePtr, GCPtr, int, int, int, int, int, int, unsigned long); 185static void sunGXFillRectAll(DrawablePtr, GCPtr, int, BoxPtr); 186static void sunGXPolyFillRect(DrawablePtr, GCPtr, int, xRectangle *); 187static void sunGXFillSpans(DrawablePtr, GCPtr, int, DDXPointPtr, int *, int); 188static void sunGXFillEllipse(DrawablePtr, sunGXPtr, xArc *); 189static void sunGXFillArcSlice(DrawablePtr, GCPtr, sunGXPtr, xArc *); 190static void sunGXPolyFillArc(DrawablePtr, GCPtr, int, xArc *); 191static void sunGXFillPoly1Rect(DrawablePtr, GCPtr, int, int, int, DDXPointPtr); 192 193static Uint gx_blit_rop_table[16]={ 194 ROP_BLIT(GX_ROP_CLEAR, GX_ROP_CLEAR), /* GXclear */ 195 ROP_BLIT(GX_ROP_CLEAR, GX_ROP_NOOP), /* GXand */ 196 ROP_BLIT(GX_ROP_CLEAR, GX_ROP_INVERT), /* GXandReverse */ 197 ROP_BLIT(GX_ROP_CLEAR, GX_ROP_SET), /* GXcopy */ 198 ROP_BLIT(GX_ROP_NOOP, GX_ROP_CLEAR), /* GXandInverted */ 199 ROP_BLIT(GX_ROP_NOOP, GX_ROP_NOOP), /* GXnoop */ 200 ROP_BLIT(GX_ROP_NOOP, GX_ROP_INVERT), /* GXxor */ 201 ROP_BLIT(GX_ROP_NOOP, GX_ROP_SET), /* GXor */ 202 ROP_BLIT(GX_ROP_INVERT, GX_ROP_CLEAR), /* GXnor */ 203 ROP_BLIT(GX_ROP_INVERT, GX_ROP_NOOP), /* GXequiv */ 204 ROP_BLIT(GX_ROP_INVERT, GX_ROP_INVERT), /* GXinvert */ 205 ROP_BLIT(GX_ROP_INVERT, GX_ROP_SET), /* GXorReverse */ 206 ROP_BLIT(GX_ROP_SET, GX_ROP_CLEAR), /* GXcopyInverted */ 207 ROP_BLIT(GX_ROP_SET, GX_ROP_NOOP), /* GXorInverted */ 208 ROP_BLIT(GX_ROP_SET, GX_ROP_INVERT), /* GXnand */ 209 ROP_BLIT(GX_ROP_SET, GX_ROP_SET), /* GXset */ 210}; 211 212/* rops for solid drawing 213 with: 214 Plane Mask - use plane mask reg. 215 Pixel Mask - use all ones. 216 Patt Mask - use all ones. 217*/ 218 219static Uint gx_solid_rop_table[16]={ 220 ROP_FILL(GX_ROP_CLEAR, GX_ROP_CLEAR), /* GXclear */ 221 ROP_FILL(GX_ROP_CLEAR, GX_ROP_NOOP), /* GXand */ 222 ROP_FILL(GX_ROP_CLEAR, GX_ROP_INVERT), /* GXandReverse */ 223 ROP_FILL(GX_ROP_CLEAR, GX_ROP_SET), /* GXcopy */ 224 ROP_FILL(GX_ROP_NOOP, GX_ROP_CLEAR), /* GXandInverted */ 225 ROP_FILL(GX_ROP_NOOP, GX_ROP_NOOP), /* GXnoop */ 226 ROP_FILL(GX_ROP_NOOP, GX_ROP_INVERT), /* GXxor */ 227 ROP_FILL(GX_ROP_NOOP, GX_ROP_SET), /* GXor */ 228 ROP_FILL(GX_ROP_INVERT, GX_ROP_CLEAR), /* GXnor */ 229 ROP_FILL(GX_ROP_INVERT, GX_ROP_NOOP), /* GXequiv */ 230 ROP_FILL(GX_ROP_INVERT, GX_ROP_INVERT), /* GXinvert */ 231 ROP_FILL(GX_ROP_INVERT, GX_ROP_SET), /* GXorReverse */ 232 ROP_FILL(GX_ROP_SET, GX_ROP_CLEAR), /* GXcopyInverted */ 233 ROP_FILL(GX_ROP_SET, GX_ROP_NOOP), /* GXorInverted */ 234 ROP_FILL(GX_ROP_SET, GX_ROP_INVERT), /* GXnand */ 235 ROP_FILL(GX_ROP_SET, GX_ROP_SET), /* GXset */ 236}; 237 238static Uint gx_stipple_rop_table[16]={ 239 ROP_STIP(GX_ROP_CLEAR, GX_ROP_CLEAR), /* GXclear */ 240 ROP_STIP(GX_ROP_CLEAR, GX_ROP_NOOP), /* GXand */ 241 ROP_STIP(GX_ROP_CLEAR, GX_ROP_INVERT), /* GXandReverse */ 242 ROP_STIP(GX_ROP_CLEAR, GX_ROP_SET), /* GXcopy */ 243 ROP_STIP(GX_ROP_NOOP, GX_ROP_CLEAR), /* GXandInverted */ 244 ROP_STIP(GX_ROP_NOOP, GX_ROP_NOOP), /* GXnoop */ 245 ROP_STIP(GX_ROP_NOOP, GX_ROP_INVERT), /* GXxor */ 246 ROP_STIP(GX_ROP_NOOP, GX_ROP_SET), /* GXor */ 247 ROP_STIP(GX_ROP_INVERT, GX_ROP_CLEAR), /* GXnor */ 248 ROP_STIP(GX_ROP_INVERT, GX_ROP_NOOP), /* GXequiv */ 249 ROP_STIP(GX_ROP_INVERT, GX_ROP_INVERT), /* GXinvert */ 250 ROP_STIP(GX_ROP_INVERT, GX_ROP_SET), /* GXorReverse */ 251 ROP_STIP(GX_ROP_SET, GX_ROP_CLEAR), /* GXcopyInverted */ 252 ROP_STIP(GX_ROP_SET, GX_ROP_NOOP), /* GXorInverted */ 253 ROP_STIP(GX_ROP_SET, GX_ROP_INVERT), /* GXnand */ 254 ROP_STIP(GX_ROP_SET, GX_ROP_SET), /* GXset */ 255}; 256 257static Uint gx_opaque_stipple_rop_table[16]={ 258 ROP_OSTP(GX_ROP_CLEAR, GX_ROP_CLEAR), /* GXclear */ 259 ROP_OSTP(GX_ROP_CLEAR, GX_ROP_NOOP), /* GXand */ 260 ROP_OSTP(GX_ROP_CLEAR, GX_ROP_INVERT), /* GXandReverse */ 261 ROP_OSTP(GX_ROP_CLEAR, GX_ROP_SET), /* GXcopy */ 262 ROP_OSTP(GX_ROP_NOOP, GX_ROP_CLEAR), /* GXandInverted */ 263 ROP_OSTP(GX_ROP_NOOP, GX_ROP_NOOP), /* GXnoop */ 264 ROP_OSTP(GX_ROP_NOOP, GX_ROP_INVERT), /* GXxor */ 265 ROP_OSTP(GX_ROP_NOOP, GX_ROP_SET), /* GXor */ 266 ROP_OSTP(GX_ROP_INVERT, GX_ROP_CLEAR), /* GXnor */ 267 ROP_OSTP(GX_ROP_INVERT, GX_ROP_NOOP), /* GXequiv */ 268 ROP_OSTP(GX_ROP_INVERT, GX_ROP_INVERT), /* GXinvert */ 269 ROP_OSTP(GX_ROP_INVERT, GX_ROP_SET), /* GXorReverse */ 270 ROP_OSTP(GX_ROP_SET, GX_ROP_CLEAR), /* GXcopyInverted */ 271 ROP_OSTP(GX_ROP_SET, GX_ROP_NOOP), /* GXorInverted */ 272 ROP_OSTP(GX_ROP_SET, GX_ROP_INVERT), /* GXnand */ 273 ROP_OSTP(GX_ROP_SET, GX_ROP_SET), /* GXset */ 274}; 275 276int sunGXScreenPrivateIndex; 277int sunGXGCPrivateIndex; 278int sunGXWindowPrivateIndex; 279int sunGXGeneration; 280 281/* 282 sunGXDoBitBlt 283 ============= 284 Bit Blit for all window to window blits. 285*/ 286static void 287sunGXDoBitblt(DrawablePtr pSrc, DrawablePtr pDst, int alu, RegionPtr prgnDst, DDXPointPtr pptSrc, unsigned long planemask) 288{ 289 register sunGXPtr gx = sunGXGetScreenPrivate (pSrc->pScreen); 290 register long r; 291 register BoxPtr pboxTmp; 292 register DDXPointPtr pptTmp; 293 register int nbox; 294 BoxPtr pboxNext,pboxBase,pbox; 295 296 /* setup GX ( need fg of 0xff for blits ) */ 297 GXBlitInit(gx,gx_blit_rop_table[alu]|POLY_O,planemask); 298 299 pbox = REGION_RECTS(prgnDst); 300 nbox = REGION_NUM_RECTS(prgnDst); 301 302 /* need to blit rectangles in different orders, depending on the direction of copy 303 so that an area isnt overwritten before it is blitted */ 304 if( (pptSrc->y < pbox->y1) && (nbox > 1) ){ 305 306 if( (pptSrc->x < pbox->x1) && (nbox > 1) ){ 307 308 /* reverse order of bands and rects in each band */ 309 pboxTmp=pbox+nbox; 310 pptTmp=pptSrc+nbox; 311 312 while (nbox--){ 313 pboxTmp--; 314 pptTmp--; 315 gx->x0=pptTmp->x; 316 gx->y0=pptTmp->y; 317 gx->x1=pptTmp->x+(pboxTmp->x2-pboxTmp->x1)-1; 318 gx->y1=pptTmp->y+(pboxTmp->y2-pboxTmp->y1)-1; 319 gx->x2=pboxTmp->x1; 320 gx->y2=pboxTmp->y1; 321 gx->x3=pboxTmp->x2-1; 322 gx->y3=pboxTmp->y2-1; 323 GXBlitDone(gx,r); 324 } 325 } 326 else{ 327 328 /* keep ordering in each band, reverse order of bands */ 329 pboxBase = pboxNext = pbox+nbox-1; 330 331 while (pboxBase >= pbox){ /* for each band */ 332 333 /* find first box in band */ 334 while ((pboxNext >= pbox) && 335 (pboxBase->y1 == pboxNext->y1)) 336 pboxNext--; 337 338 pboxTmp = pboxNext+1; /* first box in band */ 339 pptTmp = pptSrc + (pboxTmp - pbox); /* first point in band */ 340 341 while (pboxTmp <= pboxBase){ /* for each box in band */ 342 gx->x0=pptTmp->x; 343 gx->y0=pptTmp->y; 344 gx->x1=pptTmp->x+(pboxTmp->x2-pboxTmp->x1)-1; 345 gx->y1=pptTmp->y+(pboxTmp->y2-pboxTmp->y1)-1; 346 gx->x2=pboxTmp->x1; 347 gx->y2=pboxTmp->y1; 348 gx->x3=pboxTmp->x2-1; 349 gx->y3=pboxTmp->y2-1; 350 ++pboxTmp; 351 ++pptTmp; 352 GXBlitDone(gx,r); 353 } 354 pboxBase = pboxNext; 355 } 356 } 357 } 358 else{ 359 360 if( (pptSrc->x < pbox->x1) && (nbox > 1) ){ 361 362 /* reverse order of rects in each band */ 363 pboxBase = pboxNext = pbox; 364 365 while (pboxBase < pbox+nbox){ /* for each band */ 366 367 /* find last box in band */ 368 while ((pboxNext < pbox+nbox) && 369 (pboxNext->y1 == pboxBase->y1)) 370 pboxNext++; 371 372 pboxTmp = pboxNext; /* last box in band */ 373 pptTmp = pptSrc + (pboxTmp - pbox); /* last point in band */ 374 375 while (pboxTmp != pboxBase){ /* for each box in band */ 376 --pboxTmp; 377 --pptTmp; 378 gx->x0=pptTmp->x; 379 gx->y0=pptTmp->y; 380 gx->x1=pptTmp->x+(pboxTmp->x2-pboxTmp->x1)-1; 381 gx->y1=pptTmp->y+(pboxTmp->y2-pboxTmp->y1)-1; 382 gx->x2=pboxTmp->x1; 383 gx->y2=pboxTmp->y1; 384 gx->x3=pboxTmp->x2-1; 385 gx->y3=pboxTmp->y2-1; 386 GXBlitDone(gx,r); 387 } 388 pboxBase = pboxNext; 389 } 390 } 391 else{ 392 393 /* dont need to change order of anything */ 394 pptTmp=pptSrc; 395 pboxTmp=pbox; 396 397 while(nbox--){ 398 gx->x0=pptTmp->x; 399 gx->y0=pptTmp->y; 400 gx->x1=pptTmp->x+(pboxTmp->x2-pboxTmp->x1)-1; 401 gx->y1=pptTmp->y+(pboxTmp->y2-pboxTmp->y1)-1; 402 gx->x2=pboxTmp->x1; 403 gx->y2=pboxTmp->y1; 404 gx->x3=pboxTmp->x2-1; 405 gx->y3=pboxTmp->y2-1; 406 pboxTmp++; 407 pptTmp++; 408 GXBlitDone(gx,r); 409 } 410 } 411 } 412 GXWait(gx,r); 413} 414 415static RegionPtr 416sunGXCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GC *pGC, int srcx, int srcy, int width, int height, int dstx, int dsty) 417{ 418 if (pSrcDrawable->type != DRAWABLE_WINDOW) 419 return cfbCopyArea (pSrcDrawable, pDstDrawable, 420 pGC, srcx, srcy, width, height, dstx, dsty); 421 return cfbBitBlt (pSrcDrawable, pDstDrawable, 422 pGC, srcx, srcy, width, height, dstx, dsty, sunGXDoBitblt, 0); 423} 424 425static unsigned long copyPlaneFG, copyPlaneBG; 426 427static void 428sunGXCopyPlane1to8(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, int rop, RegionPtr prgnDst, DDXPointPtr pptSrc, unsigned long planemask, unsigned long bitPlane) 429{ 430 register sunGXPtr gx = sunGXGetScreenPrivate (pDstDrawable->pScreen); 431 int srcx, srcy, dstx, dsty, width, height; 432 int dstLastx, dstRightx; 433 int xoffSrc, widthSrc, widthRest; 434 int widthLast; 435 unsigned long *psrcBase, *psrc; 436 unsigned long bits, tmp; 437 register int leftShift, rightShift; 438 register int nl, nlMiddle; 439 int nbox; 440 BoxPtr pbox; 441 register long r; 442 443 GXDrawInit (gx, copyPlaneFG, 444 gx_opaque_stipple_rop_table[rop]|GX_PATTERN_ONES, 445 planemask); 446 gx->bg = copyPlaneBG; 447 gx->mode = GX_BLIT_NOSRC | GX_MODE_COLOR1; 448 449 cfbGetLongWidthAndPointer (pSrcDrawable, widthSrc, psrcBase) 450 451 nbox = REGION_NUM_RECTS(prgnDst); 452 pbox = REGION_RECTS(prgnDst); 453 gx->incx = BITMAP_SCANLINE_UNIT; 454 gx->incy = 0; 455 while (nbox--) 456 { 457 dstx = pbox->x1; 458 dsty = pbox->y1; 459 srcx = pptSrc->x; 460 srcy = pptSrc->y; 461 dstLastx = pbox->x2; 462 width = dstLastx - dstx; 463 height = pbox->y2 - dsty; 464 pbox++; 465 pptSrc++; 466 if (!width) 467 continue; 468 psrc = psrcBase + srcy * widthSrc + (srcx >> LOG2_BITMAP_PAD); 469 dstLastx--; 470 dstRightx = dstx + BITMAP_SCANLINE_UNIT - 1; 471 nlMiddle = (width + BITMAP_SCANLINE_UNIT - 1) >> LOG2_BITMAP_PAD; 472 widthLast = width & (BITMAP_SCANLINE_UNIT - 1); 473 xoffSrc = srcx & ((1 << LOG2_BITMAP_PAD) - 1); 474 leftShift = xoffSrc; 475 rightShift = BITMAP_SCANLINE_UNIT - leftShift; 476 widthRest = widthSrc - nlMiddle; 477 if (widthLast) 478 nlMiddle--; 479 if (leftShift == 0) 480 { 481 while (height--) 482 { 483 gx->x0 = dstx; 484 gx->x1 = dstRightx; 485 gx->y0 = dsty++; 486 nl = nlMiddle; 487 while (nl--) 488 gx->font = *psrc++; 489 if (widthLast) 490 { 491 gx->x1 = dstLastx; 492#if BITMAP_SCANLINE_UNIT == 64 493 gx->font = (int)((*psrc++)>>32); 494#else 495 gx->font = *psrc++; 496#endif 497 } 498 psrc += widthRest; 499 } 500 } 501 else 502 { 503 widthRest--; 504 while (height--) 505 { 506 gx->x0 = dstx; 507 gx->x1 = dstRightx; 508 gx->y0 = dsty++; 509 bits = *psrc++; 510 nl = nlMiddle; 511 while (nl--) 512 { 513 tmp = BitLeft(bits, leftShift); 514 bits = *psrc++; 515 tmp |= BitRight(bits, rightShift); 516 gx->font = tmp; 517 } 518 if (widthLast) 519 { 520 tmp = BitLeft(bits, leftShift); 521 bits = *psrc++; 522 tmp |= BitRight(bits, rightShift); 523 gx->x1 = dstLastx; 524 gx->font = tmp; 525 } 526 psrc += widthRest; 527 } 528 } 529 } 530 GXWait (gx, r); 531 gx->incx = 0; 532 gx->incy = 0; 533 gx->mode = GX_BLIT_SRC | GX_MODE_COLOR8; 534} 535 536static RegionPtr 537sunGXCopyPlane(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, int srcx, int srcy, int width, int height, int dstx, int dsty, unsigned long bitPlane) 538{ 539 RegionPtr ret; 540 541 if (pSrcDrawable->bitsPerPixel == 1 && pDstDrawable->bitsPerPixel == 8) 542 { 543 if (bitPlane == 1) 544 { 545 copyPlaneFG = pGC->fgPixel; 546 copyPlaneBG = pGC->bgPixel; 547 ret = cfbBitBlt (pSrcDrawable, pDstDrawable, 548 pGC, srcx, srcy, width, height, dstx, dsty, sunGXCopyPlane1to8, bitPlane); 549 } 550 else 551 ret = miHandleExposures (pSrcDrawable, pDstDrawable, 552 pGC, srcx, srcy, width, height, dstx, dsty, bitPlane); 553 } 554 else if (pSrcDrawable->bitsPerPixel == 8 && pDstDrawable->bitsPerPixel == 1) 555 { 556 extern int InverseAlu[16]; 557 int oldalu; 558 559 oldalu = pGC->alu; 560 if ((pGC->fgPixel & 1) == 0 && (pGC->bgPixel&1) == 1) 561 pGC->alu = InverseAlu[pGC->alu]; 562 else if ((pGC->fgPixel & 1) == (pGC->bgPixel & 1)) 563 pGC->alu = mfbReduceRop(pGC->alu, pGC->fgPixel); 564 ret = cfbCopyPlaneReduce (pSrcDrawable, pDstDrawable, 565 pGC, srcx, srcy, width, height, dstx, dsty, cfbCopyPlane8to1, bitPlane); 566 pGC->alu = oldalu; 567 } 568 else 569 { 570 PixmapPtr pBitmap; 571 ScreenPtr pScreen = pSrcDrawable->pScreen; 572 GCPtr pGC1; 573 574 pBitmap = (*pScreen->CreatePixmap) (pScreen, width, height, 1); 575 if (!pBitmap) 576 return NULL; 577 pGC1 = GetScratchGC (1, pScreen); 578 if (!pGC1) 579 { 580 (*pScreen->DestroyPixmap) (pBitmap); 581 return NULL; 582 } 583 /* 584 * don't need to set pGC->fgPixel,bgPixel as copyPlane8to1 585 * ignores pixel values, expecting the rop to "do the 586 * right thing", which GXcopy will. 587 */ 588 ValidateGC ((DrawablePtr) pBitmap, pGC1); 589 /* no exposures here, scratch GC's don't get graphics expose */ 590 (void) cfbCopyPlaneReduce (pSrcDrawable, (DrawablePtr) pBitmap, 591 pGC1, srcx, srcy, width, height, 0, 0, cfbCopyPlane8to1, bitPlane); 592 copyPlaneFG = pGC->fgPixel; 593 copyPlaneBG = pGC->bgPixel; 594 (void) cfbBitBlt ((DrawablePtr) pBitmap, pDstDrawable, pGC, 595 0, 0, width, height, dstx, dsty, sunGXCopyPlane1to8, 1); 596 FreeScratchGC (pGC1); 597 (*pScreen->DestroyPixmap) (pBitmap); 598 /* compute resultant exposures */ 599 ret = miHandleExposures (pSrcDrawable, pDstDrawable, pGC, 600 srcx, srcy, width, height, 601 dstx, dsty, bitPlane); 602 } 603 return ret; 604} 605 606static void 607sunGXFillRectAll(DrawablePtr pDrawable, GCPtr pGC, int nBox, BoxPtr pBox) 608{ 609 register sunGXPtr gx = sunGXGetScreenPrivate (pDrawable->pScreen); 610 register sunGXPrivGCPtr gxPriv = sunGXGetGCPrivate (pGC); 611 register int r; 612 613 GXDrawInit(gx,pGC->fgPixel,gx_solid_rop_table[pGC->alu]|POLY_N,pGC->planemask); 614 if (gxPriv->stipple) 615 GXStippleInit(gx,gxPriv->stipple); 616 while (nBox--) { 617 gx->arecty = pBox->y1; 618 gx->arectx = pBox->x1; 619 gx->arecty = pBox->y2; 620 gx->arectx = pBox->x2; 621 pBox++; 622 GXDrawDone(gx,r); 623 } 624 GXWait(gx,r); 625} 626 627#define NUM_STACK_RECTS 1024 628 629static void 630sunGXPolyFillRect( 631 DrawablePtr pDrawable, 632 GCPtr pGC, 633 int nrectFill, /* number of rectangles to fill */ 634 xRectangle *prectInit /* Pointer to first rectangle to fill */ 635) 636{ 637 xRectangle *prect; 638 RegionPtr prgnClip; 639 register BoxPtr pbox; 640 register BoxPtr pboxClipped; 641 BoxPtr pboxClippedBase; 642 BoxPtr pextent; 643 BoxRec stackRects[NUM_STACK_RECTS]; 644 int numRects; 645 int n; 646 int xorg, yorg; 647 648 prgnClip = pGC->pCompositeClip; 649 prect = prectInit; 650 xorg = pDrawable->x; 651 yorg = pDrawable->y; 652 if (xorg || yorg) 653 { 654 prect = prectInit; 655 n = nrectFill; 656 while(n--) 657 { 658 prect->x += xorg; 659 prect->y += yorg; 660 prect++; 661 } 662 } 663 664 prect = prectInit; 665 666 numRects = REGION_NUM_RECTS(prgnClip) * nrectFill; 667 if (numRects > NUM_STACK_RECTS) 668 { 669 pboxClippedBase = (BoxPtr)ALLOCATE_LOCAL(numRects * sizeof(BoxRec)); 670 if (!pboxClippedBase) 671 return; 672 } 673 else 674 pboxClippedBase = stackRects; 675 676 pboxClipped = pboxClippedBase; 677 678 if (REGION_NUM_RECTS(prgnClip) == 1) 679 { 680 int x1, y1, x2, y2, bx2, by2; 681 682 pextent = REGION_RECTS(prgnClip); 683 x1 = pextent->x1; 684 y1 = pextent->y1; 685 x2 = pextent->x2; 686 y2 = pextent->y2; 687 while (nrectFill--) 688 { 689 if ((pboxClipped->x1 = prect->x) < x1) 690 pboxClipped->x1 = x1; 691 692 if ((pboxClipped->y1 = prect->y) < y1) 693 pboxClipped->y1 = y1; 694 695 bx2 = (int) prect->x + (int) prect->width; 696 if (bx2 > x2) 697 bx2 = x2; 698 pboxClipped->x2 = bx2; 699 700 by2 = (int) prect->y + (int) prect->height; 701 if (by2 > y2) 702 by2 = y2; 703 pboxClipped->y2 = by2; 704 705 prect++; 706 if ((pboxClipped->x1 < pboxClipped->x2) && 707 (pboxClipped->y1 < pboxClipped->y2)) 708 { 709 pboxClipped++; 710 } 711 } 712 } 713 else 714 { 715 int x1, y1, x2, y2, bx2, by2; 716 717 pextent = REGION_EXTENTS(pGC->pScreen, prgnClip); 718 x1 = pextent->x1; 719 y1 = pextent->y1; 720 x2 = pextent->x2; 721 y2 = pextent->y2; 722 while (nrectFill--) 723 { 724 BoxRec box; 725 726 if ((box.x1 = prect->x) < x1) 727 box.x1 = x1; 728 729 if ((box.y1 = prect->y) < y1) 730 box.y1 = y1; 731 732 bx2 = (int) prect->x + (int) prect->width; 733 if (bx2 > x2) 734 bx2 = x2; 735 box.x2 = bx2; 736 737 by2 = (int) prect->y + (int) prect->height; 738 if (by2 > y2) 739 by2 = y2; 740 box.y2 = by2; 741 742 prect++; 743 744 if ((box.x1 >= box.x2) || (box.y1 >= box.y2)) 745 continue; 746 747 n = REGION_NUM_RECTS (prgnClip); 748 pbox = REGION_RECTS(prgnClip); 749 750 /* clip the rectangle to each box in the clip region 751 this is logically equivalent to calling Intersect() 752 */ 753 while(n--) 754 { 755 pboxClipped->x1 = max(box.x1, pbox->x1); 756 pboxClipped->y1 = max(box.y1, pbox->y1); 757 pboxClipped->x2 = min(box.x2, pbox->x2); 758 pboxClipped->y2 = min(box.y2, pbox->y2); 759 pbox++; 760 761 /* see if clipping left anything */ 762 if(pboxClipped->x1 < pboxClipped->x2 && 763 pboxClipped->y1 < pboxClipped->y2) 764 { 765 pboxClipped++; 766 } 767 } 768 } 769 } 770 if (pboxClipped != pboxClippedBase) 771 sunGXFillRectAll(pDrawable, pGC, 772 pboxClipped-pboxClippedBase, pboxClippedBase); 773 if (pboxClippedBase != stackRects) 774 DEALLOCATE_LOCAL(pboxClippedBase); 775} 776 777static void 778sunGXFillSpans( 779 DrawablePtr pDrawable, 780 GCPtr pGC, 781 int n, /* number of spans to fill */ 782 DDXPointPtr ppt, /* pointer to list of start points */ 783 int *pwidth, /* pointer to list of n widths */ 784 int fSorted 785) 786{ 787 int x, y; 788 int width; 789 /* next three parameters are post-clip */ 790 int nTmp; 791 int *pwidthFree;/* copies of the pointers to free */ 792 DDXPointPtr pptFree; 793 register sunGXPtr gx = sunGXGetScreenPrivate (pDrawable->pScreen); 794 cfbPrivGCPtr devPriv = cfbGetGCPrivate(pGC); 795 register sunGXPrivGCPtr gxPriv = sunGXGetGCPrivate (pGC); 796 register int r; 797 BoxPtr extents; 798 799 GXDrawInit(gx,pGC->fgPixel,gx_solid_rop_table[pGC->alu]|POLY_O,pGC->planemask) 800 if (gxPriv->stipple) 801 GXStippleInit(gx,gxPriv->stipple); 802 if (devPriv->oneRect) 803 { 804 extents = &pGC->pCompositeClip->extents; 805 GXSetClip (gx, extents); 806 } 807 else 808 { 809 nTmp = n * miFindMaxBand(pGC->pCompositeClip); 810 pwidthFree = (int *)ALLOCATE_LOCAL(nTmp * sizeof(int)); 811 pptFree = (DDXPointRec *)ALLOCATE_LOCAL(nTmp * sizeof(DDXPointRec)); 812 if(!pptFree || !pwidthFree) 813 { 814 if (pptFree) DEALLOCATE_LOCAL(pptFree); 815 if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree); 816 return; 817 } 818 n = miClipSpans(pGC->pCompositeClip, ppt, pwidth, n, 819 pptFree, pwidthFree, fSorted); 820 pwidth = pwidthFree; 821 ppt = pptFree; 822 } 823 while (n--) 824 { 825 x = ppt->x; 826 y = ppt->y; 827 ppt++; 828 width = *pwidth++; 829 if (width) 830 { 831 sunGXFillSpan(gx,y,x,x + width - 1,r); 832 } 833 } 834 GXWait(gx,r); 835 if (devPriv->oneRect) 836 { 837 GXResetClip (gx, pDrawable->pScreen); 838 } 839 else 840 { 841 DEALLOCATE_LOCAL(pptFree); 842 DEALLOCATE_LOCAL(pwidthFree); 843 } 844} 845 846#ifdef NOTDEF 847/* cfb is faster for dots */ 848void 849sunGXPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, xPoint *pptInit) 850{ 851 register sunGXPtr gx = sunGXGetScreenPrivate (pDrawable->pScreen); 852 RegionPtr cclip; 853 int nbox; 854 register int i; 855 register BoxPtr pbox; 856 cfbPrivGCPtr devPriv; 857 xPoint *ppt; 858 int x, y; 859 int r; 860 int off; 861 862 devPriv = (cfbPrivGC *)(pGC->devPrivates[cfbGCPrivateIndex].ptr); 863 if (devPriv->rop == GXnoop) 864 return; 865 cclip = pGC->pCompositeClip; 866 GXDrawInit(gx,pGC->fgPixel,gx_solid_rop_table[pGC->alu],pGC->planemask); 867 gx->offx = pDrawable->x; 868 gx->offy = pDrawable->y; 869 for (nbox = REGION_NUM_RECTS(cclip), pbox = REGION_RECTS(cclip); 870 --nbox >= 0; 871 pbox++) 872 { 873 sunGXSetClip(gx,pbox); 874 if (mode != CoordModeOrigin) 875 { 876 x = 0; 877 y = 0; 878 for (ppt = pptInit, i = npt; --i >= 0;) 879 { 880 gx->apointy = y += ppt->y; 881 gx->apointx = x += ppt->x; 882 ++ppt; 883 GXDrawDone(gx,r); 884 } 885 } 886 else 887 { 888 for (ppt = pptInit, i = npt; --i >= 0;) 889 { 890 gx->apointy = ppt->y; 891 gx->apointx = ppt->x; 892 ++ppt; 893 GXDrawDone(gx,r); 894 } 895 } 896 } 897 GXWait(gx,r); 898 GXResetOff (gx); 899 GXResetClip(gx,pDrawable->pScreen); 900} 901#endif 902 903#include "mifillarc.h" 904 905#define FILLSPAN(gx,y,x1,x2,r) {\ 906 if (x2 >= x1) {\ 907 sunGXFillSpan(gx,y,x1,x2,r) \ 908 } \ 909} 910 911#define FILLSLICESPANS(flip,y) \ 912 if (!flip) \ 913 { \ 914 FILLSPAN(gx,y,xl,xr,r) \ 915 } \ 916 else \ 917 { \ 918 xc = xorg - x; \ 919 FILLSPAN(gx, y, xc, xr, r) \ 920 xc += slw - 1; \ 921 FILLSPAN(gx, y, xl, xc, r) \ 922 } 923 924static void 925sunGXFillEllipse(DrawablePtr pDraw, sunGXPtr gx, xArc *arc) 926{ 927 int x, y, e; 928 int yk, xk, ym, xm, dx, dy, xorg, yorg; 929 int y_top, y_bot; 930 miFillArcRec info; 931 register int xpos; 932 int r; 933 int slw; 934 935 miFillArcSetup(arc, &info); 936 MIFILLARCSETUP(); 937 y_top = yorg - y; 938 y_bot = yorg + y + dy; 939 while (y) 940 { 941 y_top++; 942 y_bot--; 943 MIFILLARCSTEP(slw); 944 if (!slw) 945 continue; 946 xpos = xorg - x; 947 sunGXFillSpan (gx,y_top,xpos,xpos+slw - 1,r); 948 if (miFillArcLower(slw)) 949 sunGXFillSpan (gx,y_bot,xpos,xpos+slw - 1,r); 950 } 951} 952 953 954static void 955sunGXFillArcSlice(DrawablePtr pDraw, GCPtr pGC, sunGXPtr gx, xArc *arc) 956{ 957 int yk, xk, ym, xm, dx, dy, xorg, yorg, slw; 958 register int x, y, e; 959 miFillArcRec info; 960 miArcSliceRec slice; 961 int xl, xr, xc; 962 int y_top, y_bot; 963 int r; 964 965 miFillArcSetup(arc, &info); 966 miFillArcSliceSetup(arc, &slice, pGC); 967 MIFILLARCSETUP(); 968 y_top = yorg - y; 969 y_bot = yorg + y + dy; 970 while (y > 0) 971 { 972 y_top++; 973 y_bot--; 974 MIFILLARCSTEP(slw); 975 MIARCSLICESTEP(slice.edge1); 976 MIARCSLICESTEP(slice.edge2); 977 if (miFillSliceUpper(slice)) 978 { 979 MIARCSLICEUPPER(xl, xr, slice, slw); 980 FILLSLICESPANS(slice.flip_top, y_top); 981 } 982 if (miFillSliceLower(slice)) 983 { 984 MIARCSLICELOWER(xl, xr, slice, slw); 985 FILLSLICESPANS(slice.flip_bot, y_bot); 986 } 987 } 988} 989 990#define FAST_CIRCLES 991#ifdef FAST_CIRCLES 992#if (BITMAP_BIT_ORDER == MSBFirst) 993#define Bits32(v) (v) 994#define Bits16(v) (v) 995#define Bits8(v) (v) 996#else 997#define FlipBits2(a) ((((a) & 0x1) << 1) | (((a) & 0x2) >> 1)) 998#define FlipBits4(a) ((FlipBits2(a) << 2) | FlipBits2(a >> 2)) 999#define FlipBits8(a) ((FlipBits4(a) << 4) | FlipBits4(a >> 4)) 1000#define FlipBits16(a) ((FlipBits8(a) << 8) | FlipBits8(a >> 8)) 1001#define FlipBits32(a) ((FlipBits16(a) << 16) | FlipBits16(a >> 16)) 1002#define Bits32(v) FlipBits32(v) 1003#define Bits16(v) FlipBits16(v) 1004#define Bits8(v) FlipBits8(v) 1005#endif 1006 1007#define B(x) Bits16(x) 1008#define DO_FILLED_ARCS 1009#include "circleset.h" 1010#undef B 1011#undef Bits8 1012#undef Bits16 1013#undef Bits32 1014#define UNSET_CIRCLE if (old_width) \ 1015 { \ 1016 gx->alu = gx_solid_rop_table[pGC->alu]; \ 1017 old_width = -old_width; \ 1018 } 1019 1020#else 1021#define UNSET_CIRCLE 1022#endif 1023 1024static void 1025sunGXPolyFillArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc *parcs) 1026{ 1027 register xArc *arc; 1028 register int i; 1029 int x, y; 1030 BoxRec box; 1031 BoxPtr extents = NULL; 1032 RegionPtr cclip; 1033 register sunGXPtr gx = sunGXGetScreenPrivate (pDraw->pScreen); 1034 sunGXPrivGCPtr gxPriv = sunGXGetGCPrivate (pGC); 1035 cfbPrivGCPtr devPriv; 1036 register int r; 1037#ifdef FAST_CIRCLES 1038 int old_width = 0; 1039#endif 1040 1041 GXDrawInit(gx,pGC->fgPixel,gx_solid_rop_table[pGC->alu]|POLY_O,pGC->planemask); 1042 if (gxPriv->stipple) 1043 GXStippleInit(gx,gxPriv->stipple); 1044 devPriv = (cfbPrivGC *)(pGC->devPrivates[cfbGCPrivateIndex].ptr); 1045 cclip = pGC->pCompositeClip; 1046 GXSetOff(gx,pDraw->x,pDraw->y) 1047 if (devPriv->oneRect) { 1048 extents = &cclip->extents; 1049 GXSetClip(gx,extents); 1050 } 1051 for (arc = parcs, i = narcs; --i >= 0; arc++) 1052 { 1053 if (miFillArcEmpty(arc)) 1054 continue; 1055 if (miCanFillArc(arc)) 1056 { 1057 x = arc->x; 1058 y = arc->y; 1059 if (!devPriv->oneRect) 1060 { 1061 box.x1 = x + pDraw->x; 1062 box.y1 = y + pDraw->y; 1063 box.x2 = box.x1 + (int)arc->width + 1; 1064 box.y2 = box.y1 + (int)arc->height + 1; 1065 } 1066 if (devPriv->oneRect || 1067 RECT_IN_REGION(pDraw->pScreen, cclip, &box) == rgnIN) 1068 { 1069 if ((arc->angle2 >= FULLCIRCLE) || 1070 (arc->angle2 <= -FULLCIRCLE)) 1071 { 1072#ifdef FAST_CIRCLES 1073/* who really needs fast filled circles? */ 1074 if (arc->width == arc->height && arc->width <= 16 && 1075 !gxPriv->stipple) 1076 { 1077 int offx, offy; 1078 if (arc->width != old_width) 1079 { 1080 int i; 1081 Uint *sp; 1082 VUint *dp; 1083 1084 if (old_width != -arc->width) 1085 { 1086 sp = (Uint *) filled_arcs[arc->width-1]; 1087 dp = gx->pattern; 1088 i = 8; 1089 while (i--) 1090 dp[i] = sp[i]; 1091 } 1092 gx->alu = gx_stipple_rop_table[pGC->alu]|GX_PATTERN_MASK; 1093 old_width = arc->width; 1094 } 1095 offx = 16 - ((x + pDraw->x) & 0x0f); 1096 offy = 16 - ((y + pDraw->y) & 0x0f); 1097 gx->patalign = (offx << 16) | offy; 1098 gx->arecty = y; 1099 gx->arectx = x; 1100 gx->arecty = y + old_width-1; 1101 gx->arectx = x + old_width-1; 1102 GXDrawDone (gx, r); 1103 } 1104 else 1105#endif 1106 { 1107 UNSET_CIRCLE 1108 sunGXFillEllipse (pDraw, gx, arc); 1109 } 1110 } 1111 else 1112 { 1113 UNSET_CIRCLE 1114 sunGXFillArcSlice (pDraw, pGC, gx, arc); 1115 } 1116 continue; 1117 } 1118 } 1119 UNSET_CIRCLE 1120 GXWait (gx,r); 1121 GXResetOff (gx); 1122 if (devPriv->oneRect) 1123 GXResetClip (gx, pDraw->pScreen); 1124 miPolyFillArc(pDraw, pGC, 1, arc); 1125 GXSetOff (gx, pDraw->x, pDraw->y); 1126 if (devPriv->oneRect) 1127 GXSetClip (gx, extents); 1128 } 1129 GXWait (gx, r); 1130 GXResetOff (gx); 1131 if (devPriv->oneRect) 1132 GXResetClip (gx, pDraw->pScreen); 1133} 1134 1135static void 1136sunGXFillPoly1Rect(DrawablePtr pDrawable, GCPtr pGC, int shape, int mode, int count, DDXPointPtr ptsIn) 1137{ 1138 BoxPtr extents; 1139 int x1, x2, x3, x4; 1140 int y1, y2, y3, y4; 1141 sunGXPtr gx = sunGXGetScreenPrivate (pDrawable->pScreen); 1142 sunGXPrivGCPtr gxPriv = sunGXGetGCPrivate (pGC); 1143 int r; 1144 typedef struct { 1145 Uint x; 1146 Uint y; 1147 Uint z; 1148 } GXPointRec, *GXPointPtr; 1149 GXPointPtr tri, qua; 1150 1151 if (count < 3) 1152 return; 1153 if (shape != Convex && count > 4) 1154 { 1155 miFillPolygon (pDrawable, pGC, shape, mode, count, ptsIn); 1156 return; 1157 } 1158 GXDrawInit(gx,pGC->fgPixel,gx_solid_rop_table[pGC->alu]|POLY_N,pGC->planemask); 1159 if (gxPriv->stipple) 1160 GXStippleInit(gx,gxPriv->stipple); 1161 extents = &pGC->pCompositeClip->extents; 1162 GXSetOff(gx,pDrawable->x, pDrawable->y); 1163 GXSetClip(gx,extents); 1164 if (mode == CoordModeOrigin) 1165 { 1166 tri = (GXPointPtr) &gx->atrix; 1167 qua = (GXPointPtr) &gx->aquadx; 1168 } 1169 else 1170 { 1171 tri = (GXPointPtr) &gx->rtrix; 1172 qua = (GXPointPtr) &gx->rquadx; 1173 } 1174 if (count == 3) { 1175 gx->apointy = ptsIn[0].y; 1176 gx->apointx = ptsIn[0].x; 1177 tri->y = ptsIn[1].y; 1178 tri->x = ptsIn[1].x; 1179 tri->y = ptsIn[2].y; 1180 tri->x = ptsIn[2].x; 1181 GXDrawDone (gx, r); 1182 } 1183 else if (count == 4) 1184 { 1185 gx->apointy = ptsIn[0].y; 1186 gx->apointx = ptsIn[0].x; 1187 qua->y = ptsIn[1].y; 1188 qua->x = ptsIn[1].x; 1189 qua->y = ptsIn[2].y; 1190 qua->x = ptsIn[2].x; 1191 qua->y = ptsIn[3].y; 1192 qua->x = ptsIn[3].x; 1193 GXDrawDone (gx, r); 1194 if (r < 0 && shape != Convex) 1195 { 1196 GXWait(gx,r); 1197 GXResetOff(gx); 1198 GXResetClip(gx,pDrawable->pScreen); 1199 miFillPolygon (pDrawable, pGC, shape, mode, count, ptsIn); 1200 return; 1201 } 1202 } 1203 else 1204 { 1205 y1 = ptsIn[0].y; 1206 x1 = ptsIn[0].x; 1207 y2 = ptsIn[1].y; 1208 x2 = ptsIn[1].x; 1209 count -= 2; 1210 ptsIn += 2; 1211 while (count) { 1212 x3 = ptsIn->x; 1213 y3 = ptsIn->y; 1214 ptsIn++; 1215 count--; 1216 gx->apointy = y1; 1217 gx->apointx = x1; 1218 if (count == 0) { 1219 tri->y = y2; 1220 tri->x = x2; 1221 tri->y = y3; 1222 tri->x = x3; 1223 } 1224 else 1225 { 1226 y4 = ptsIn->y; 1227 x4 = ptsIn->x; 1228 ptsIn++; 1229 count--; 1230 qua->y = y2; 1231 qua->x = x2; 1232 qua->y = y3; 1233 qua->x = x3; 1234 qua->y = y4; 1235 qua->x = x4; 1236 if (mode == CoordModeOrigin) 1237 { 1238 x2 = x4; 1239 y2 = y4; 1240 } 1241 else 1242 { 1243 x2 = x2 + x3 + x4; 1244 y2 = y2 + y3 + y4; 1245 } 1246 } 1247 GXDrawDone (gx, r); 1248 } 1249 } 1250 GXWait(gx,r); 1251 GXResetOff(gx); 1252 GXResetClip(gx,pDrawable->pScreen); 1253} 1254 1255/* 1256 * Note that the GX does not allow CapNotLast, so the code fakes it. This is 1257 * expensive to do as the GX is asynchronous and must be synced with GXWait 1258 * before fetching and storing the final line point. If only the hardware was 1259 * designed for X. 1260 */ 1261 1262/* hard code the screen width; otherwise we'd have to check or mul */ 1263 1264#define WIDTH_MUL(y) (((y) << 10) + ((y) << 7)) 1265#define GX_WIDTH 1152 1266#define WID_OK(s) ((s)->width == GX_WIDTH) 1267 1268void 1269sunGXPolySeg1Rect(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment *pSeg) 1270{ 1271 sunGXPtr gx = sunGXGetScreenPrivate (pDrawable->pScreen); 1272 sunGXPrivGCPtr gxPriv = sunGXGetGCPrivate (pGC); 1273 BoxPtr extents; 1274 int x, y; 1275 int r; 1276 unsigned char *baseAddr, *loAddr, *hiAddr, *saveAddr = 0, save = 0; 1277 1278 GXDrawInit(gx,pGC->fgPixel,gx_solid_rop_table[pGC->alu]|POLY_O,pGC->planemask); 1279 if (gxPriv->stipple) 1280 GXStippleInit(gx,gxPriv->stipple); 1281 GXSetOff (gx, pDrawable->x, pDrawable->y); 1282 1283 extents = &pGC->pCompositeClip->extents; 1284 GXSetClip (gx, extents); 1285 if (pGC->capStyle == CapNotLast) 1286 { 1287 sunGXGetAddrRange(pDrawable,extents,baseAddr,loAddr,hiAddr); 1288 while (nseg--) 1289 { 1290 gx->aliney = pSeg->y1; 1291 gx->alinex = pSeg->x1; 1292 y = pSeg->y2; 1293 x = pSeg->x2; 1294 saveAddr = baseAddr + WIDTH_MUL(y) + x; 1295 if (saveAddr < loAddr || hiAddr < saveAddr) 1296 saveAddr = 0; 1297 else 1298 save = *saveAddr; 1299 gx->aliney = y; 1300 gx->alinex = x; 1301 GXDrawDone (gx, r); 1302 if (saveAddr) 1303 { 1304 GXWait(gx,r); 1305 *saveAddr = save; 1306 } 1307 pSeg++; 1308 } 1309 } 1310 else 1311 { 1312 while (nseg--) 1313 { 1314 gx->aliney = pSeg->y1; 1315 gx->alinex = pSeg->x1; 1316 gx->aliney = pSeg->y2; 1317 gx->alinex = pSeg->x2; 1318 pSeg++; 1319 GXDrawDone (gx, r); 1320 } 1321 } 1322 GXWait (gx, r); 1323 GXResetOff (gx); 1324 GXResetClip (gx, pDrawable->pScreen); 1325} 1326 1327void 1328sunGXPolylines1Rect(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr ppt) 1329{ 1330 sunGXPtr gx = sunGXGetScreenPrivate (pDrawable->pScreen); 1331 sunGXPrivGCPtr gxPriv = sunGXGetGCPrivate (pGC); 1332 BoxPtr extents; 1333 unsigned char *baseAddr, *loAddr, *hiAddr, *saveAddr, save = 0; 1334 int r; 1335 Bool careful; 1336 Bool capNotLast; 1337 1338 if (!--npt) 1339 return; 1340 GXDrawInit(gx,pGC->fgPixel,gx_solid_rop_table[pGC->alu]|POLY_O,pGC->planemask); 1341 if (gxPriv->stipple) 1342 GXStippleInit(gx,gxPriv->stipple); 1343 careful = ((pGC->alu & 0xc) == 0x8 || (pGC->alu & 0x3) == 0x2); 1344 capNotLast = pGC->capStyle == CapNotLast; 1345 1346 extents = &pGC->pCompositeClip->extents; 1347 GXSetOff (gx, pDrawable->x, pDrawable->y); 1348 GXSetClip (gx, extents); 1349 if (careful) 1350 { 1351 int x, y; 1352 sunGXGetAddrRange (pDrawable, extents, baseAddr, loAddr, hiAddr); 1353 gx->apointy = y = ppt->y; 1354 gx->apointx = x = ppt->x; 1355 ppt++; 1356 while (npt--) 1357 { 1358 if (mode == CoordModeOrigin) 1359 { 1360 y = ppt->y; 1361 x = ppt->x; 1362 } 1363 else 1364 { 1365 y += ppt->y; 1366 x += ppt->x; 1367 } 1368 ppt++; 1369 saveAddr = baseAddr + WIDTH_MUL(y) + x; 1370 if (saveAddr < loAddr || hiAddr < saveAddr) 1371 saveAddr = 0; 1372 else 1373 save = *saveAddr; 1374 gx->aliney = y; 1375 gx->alinex = x; 1376 GXDrawDone (gx, r); 1377 if (saveAddr) 1378 { 1379 GXWait(gx,r); 1380 *saveAddr = save; 1381 } 1382 } 1383 GXWait(gx,r); 1384 } 1385 else 1386 { 1387 int x, y; 1388 if (capNotLast) 1389 npt--; 1390 if (mode == CoordModeOrigin) 1391 { 1392 x = y = 0; 1393 gx->apointy = ppt->y; 1394 gx->apointx = ppt->x; 1395 ppt++; 1396 while (npt--) 1397 { 1398 gx->aliney = ppt->y; 1399 gx->alinex = ppt->x; 1400 ++ppt; 1401 GXDrawDone(gx,r); 1402 } 1403 } 1404 else 1405 { 1406 y = gx->apointy = ppt->y; 1407 x = gx->apointx = ppt->x; 1408 ppt++; 1409 while (npt--) 1410 { 1411 y += gx->rliney = ppt->y; 1412 x += gx->rlinex = ppt->x; 1413 ++ppt; 1414 GXDrawDone(gx,r); 1415 } 1416 } 1417 if (capNotLast) 1418 { 1419 sunGXGetAddrRange (pDrawable, extents, baseAddr, loAddr, hiAddr); 1420 x += ppt->x; 1421 y += ppt->y; 1422 saveAddr = baseAddr + WIDTH_MUL(y) + x; 1423 if (saveAddr < loAddr || hiAddr < saveAddr) 1424 saveAddr = 0; 1425 else 1426 save = *saveAddr; 1427 gx->aliney = y; 1428 gx->alinex = x; 1429 GXDrawDone(gx,r); 1430 GXWait(gx,r); 1431 if (saveAddr) 1432 *saveAddr = save; 1433 } 1434 else 1435 { 1436 GXWait(gx,r); 1437 } 1438 } 1439 GXResetOff (gx); 1440 GXResetClip (gx, pDrawable->pScreen); 1441} 1442 1443void 1444sunGXPolyFillRect1Rect(DrawablePtr pDrawable, GCPtr pGC, int nrect, xRectangle *prect) 1445{ 1446 sunGXPtr gx = sunGXGetScreenPrivate (pDrawable->pScreen); 1447 sunGXPrivGCPtr gxPriv = sunGXGetGCPrivate (pGC); 1448 BoxPtr extents = &pGC->pCompositeClip->extents; 1449 int r; 1450 int x, y; 1451 1452 GXDrawInit(gx,pGC->fgPixel,gx_solid_rop_table[pGC->alu]|POLY_N,pGC->planemask); 1453 if (gxPriv->stipple) 1454 GXStippleInit(gx,gxPriv->stipple); 1455 GXSetOff (gx, pDrawable->x, pDrawable->y); 1456 GXSetClip (gx, extents); 1457 while (nrect--) 1458 { 1459 gx->arecty = y = prect->y; 1460 gx->arectx = x = prect->x; 1461 gx->arecty = y + (int) prect->height; 1462 gx->arectx = x + (int) prect->width; 1463 prect++; 1464 GXDrawDone (gx, r); 1465 } 1466 GXWait (gx, r); 1467 GXResetOff (gx); 1468 GXResetClip (gx, pDrawable->pScreen); 1469} 1470 1471static void 1472sunGXPolyGlyphBlt( 1473 DrawablePtr pDrawable, 1474 GCPtr pGC, 1475 int x, 1476 int y, 1477 unsigned int nglyph, 1478 CharInfoPtr *ppci, /* array of character info */ 1479 void *pglyphBase 1480) 1481{ 1482 sunGXPtr gx = sunGXGetScreenPrivate (pDrawable->pScreen); 1483 int h; 1484 int w; 1485 CharInfoPtr pci; 1486 unsigned int *bits; 1487 register int r; 1488 RegionPtr clip; 1489 BoxPtr extents; 1490 BoxRec box; 1491 1492 clip = pGC->pCompositeClip; 1493 extents = &clip->extents; 1494 1495 if (REGION_NUM_RECTS(clip) == 1) 1496 { 1497 GXSetClip (gx, extents); 1498 } 1499 else 1500 { 1501 /* compute an approximate (but covering) bounding box */ 1502 box.x1 = 0; 1503 if ((ppci[0]->metrics.leftSideBearing < 0)) 1504 box.x1 = ppci[0]->metrics.leftSideBearing; 1505 h = nglyph - 1; 1506 w = ppci[h]->metrics.rightSideBearing; 1507 while (--h >= 0) 1508 w += ppci[h]->metrics.characterWidth; 1509 box.x2 = w; 1510 box.y1 = -FONTMAXBOUNDS(pGC->font,ascent); 1511 box.y2 = FONTMAXBOUNDS(pGC->font,descent); 1512 1513 box.x1 += pDrawable->x + x; 1514 box.x2 += pDrawable->x + x; 1515 box.y1 += pDrawable->y + y; 1516 box.y2 += pDrawable->y + y; 1517 1518 switch (RECT_IN_REGION(pGC->pScreen, clip, &box)) 1519 { 1520 case rgnPART: 1521 cfbPolyGlyphBlt8 (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); 1522 case rgnOUT: 1523 return; 1524 } 1525 } 1526 1527 GXDrawInit (gx, pGC->fgPixel, 1528 gx_stipple_rop_table[pGC->alu]|GX_PATTERN_ONES|POLY_N, 1529 pGC->planemask); 1530 gx->mode = GX_BLIT_NOSRC | GX_MODE_COLOR1; 1531 x += pDrawable->x; 1532 y += pDrawable->y; 1533 1534 while (nglyph--) 1535 { 1536 pci = *ppci++; 1537 gx->incx = 0; 1538 gx->incy = 1; 1539 gx->x0 = x + pci->metrics.leftSideBearing; 1540 gx->x1 = (x + pci->metrics.rightSideBearing) - 1; 1541 gx->y0 = y - pci->metrics.ascent; 1542 h = pci->metrics.ascent + pci->metrics.descent; 1543 bits = (unsigned int *) pci->bits; 1544 while (h--) { 1545 gx->font = *bits++; 1546 } 1547 x += pci->metrics.characterWidth; 1548 } 1549 GXWait (gx, r); 1550 gx->mode = GX_BLIT_SRC | GX_MODE_COLOR8; 1551 GXResetClip (gx, pDrawable->pScreen); 1552} 1553 1554static void 1555sunGXTEGlyphBlt( 1556 DrawablePtr pDrawable, 1557 GCPtr pGC, 1558 int x, 1559 int y, 1560 unsigned int nglyph, 1561 CharInfoPtr *ppci, /* array of character info */ 1562 void *pglyphBase /* start of array of glyphs */ 1563) 1564{ 1565 sunGXPtr gx = sunGXGetScreenPrivate (pDrawable->pScreen); 1566 int h, hTmp; 1567 FontPtr pfont = pGC->font; 1568 register int r; 1569 unsigned int *char1, *char2, *char3, *char4; 1570 int widthGlyphs, widthGlyph; 1571 BoxRec bbox; 1572 BoxPtr extents; 1573 RegionPtr clip; 1574 unsigned long rop; 1575 1576 widthGlyph = FONTMAXBOUNDS(pfont,characterWidth); 1577 h = FONTASCENT(pfont) + FONTDESCENT(pfont); 1578 clip = pGC->pCompositeClip; 1579 extents = &clip->extents; 1580 1581 if (REGION_NUM_RECTS(clip) == 1) 1582 { 1583 GXSetClip (gx, extents); 1584 } 1585 else 1586 { 1587 bbox.x1 = x + pDrawable->x; 1588 bbox.x2 = bbox.x1 + (widthGlyph * nglyph); 1589 bbox.y1 = y + pDrawable->y - FONTASCENT(pfont); 1590 bbox.y2 = bbox.y1 + h; 1591 1592 switch (RECT_IN_REGION(pGC->pScreen, clip, &bbox)) 1593 { 1594 case rgnPART: 1595 if (pglyphBase) 1596 cfbPolyGlyphBlt8(pDrawable, pGC, x, y, nglyph, ppci, NULL); 1597 else 1598 miImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); 1599 case rgnOUT: 1600 return; 1601 } 1602 } 1603 1604 rop = gx_opaque_stipple_rop_table[GXcopy] | GX_PATTERN_ONES; 1605 if (pglyphBase) 1606 rop = gx_stipple_rop_table[pGC->alu] | GX_PATTERN_ONES; 1607 GXDrawInit (gx, pGC->fgPixel, rop, pGC->planemask); 1608 gx->bg = pGC->bgPixel; 1609 gx->mode = GX_BLIT_NOSRC | GX_MODE_COLOR1; 1610 1611 y = y + pDrawable->y - FONTASCENT(pfont); 1612 x += pDrawable->x; 1613 1614#define LoopIt(count, w, loadup, fetch) \ 1615 while (nglyph >= count) \ 1616 { \ 1617 nglyph -= count; \ 1618 gx->incx = 0; \ 1619 gx->incy = 1; \ 1620 gx->x0 = x; \ 1621 gx->x1 = (x += w) - 1; \ 1622 gx->y0 = y; \ 1623 loadup \ 1624 hTmp = h; \ 1625 while (hTmp--) \ 1626 gx->font = fetch; \ 1627 } 1628 1629 if (widthGlyph <= 8) 1630 { 1631 widthGlyphs = widthGlyph << 2; 1632 LoopIt(4, widthGlyphs, 1633 char1 = (unsigned int *) (*ppci++)->bits; 1634 char2 = (unsigned int *) (*ppci++)->bits; 1635 char3 = (unsigned int *) (*ppci++)->bits; 1636 char4 = (unsigned int *) (*ppci++)->bits;, 1637 (*char1++ | ((*char2++ | ((*char3++ | (*char4++ 1638 >> widthGlyph)) 1639 >> widthGlyph)) 1640 >> widthGlyph))) 1641 } 1642 else if (widthGlyph <= 10) 1643 { 1644 widthGlyphs = (widthGlyph << 1) + widthGlyph; 1645 LoopIt(3, widthGlyphs, 1646 char1 = (unsigned int *) (*ppci++)->bits; 1647 char2 = (unsigned int *) (*ppci++)->bits; 1648 char3 = (unsigned int *) (*ppci++)->bits;, 1649 (*char1++ | ((*char2++ | (*char3++ >> widthGlyph)) >> widthGlyph))) 1650 } 1651 else if (widthGlyph <= 16) 1652 { 1653 widthGlyphs = widthGlyph << 1; 1654 LoopIt(2, widthGlyphs, 1655 char1 = (unsigned int *) (*ppci++)->bits; 1656 char2 = (unsigned int *) (*ppci++)->bits;, 1657 (*char1++ | (*char2++ >> widthGlyph))) 1658 } 1659 while (nglyph--) { 1660 gx->incx = 0; 1661 gx->incy = 1; 1662 gx->x0 = x; 1663 gx->x1 = (x += widthGlyph) - 1; 1664 gx->y0 = y; 1665 char1 = (unsigned int *) (*ppci++)->bits; 1666 hTmp = h; 1667 while (hTmp--) 1668 gx->font = *char1++; 1669 } 1670 gx->incx = 0; 1671 gx->incy = 0; 1672 GXWait (gx, r); 1673 gx->mode = GX_BLIT_SRC | GX_MODE_COLOR8; 1674 GXResetClip (gx, pDrawable->pScreen); 1675} 1676 1677static void 1678sunGXPolyTEGlyphBlt( 1679 DrawablePtr pDrawable, 1680 GCPtr pGC, 1681 int x, 1682 int y, 1683 unsigned int nglyph, 1684 CharInfoPtr *ppci, /* array of character info */ 1685 void *pglyphBase /* start of array of glyphs */ 1686) 1687{ 1688 sunGXTEGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, (char *) 1); 1689} 1690 1691static void 1692sunGXFillBoxSolid(DrawablePtr pDrawable, int nBox, BoxPtr pBox, unsigned long pixel) 1693{ 1694 register sunGXPtr gx = sunGXGetScreenPrivate (pDrawable->pScreen); 1695 register int r; 1696 1697 GXDrawInit(gx,pixel,gx_solid_rop_table[GXcopy]|POLY_N,~0); 1698 while (nBox--) { 1699 gx->arecty = pBox->y1; 1700 gx->arectx = pBox->x1; 1701 gx->arecty = pBox->y2; 1702 gx->arectx = pBox->x2; 1703 pBox++; 1704 GXDrawDone(gx,r); 1705 } 1706 GXWait(gx,r); 1707} 1708 1709void 1710sunGXFillBoxStipple(DrawablePtr pDrawable, int nBox, BoxPtr pBox, sunGXStipplePtr stipple) 1711{ 1712 register sunGXPtr gx = sunGXGetScreenPrivate (pDrawable->pScreen); 1713 register int r; 1714 int patx, paty; 1715 1716 patx = 16 - (pDrawable->x & 0xf); 1717 paty = 16 - (pDrawable->y & 0xf); 1718 stipple->patalign = (patx << 16) | paty; 1719 GXDrawInit(gx,0,gx_solid_rop_table[GXcopy]|POLY_N,~0); 1720 GXStippleInit(gx, stipple); 1721 while (nBox--) { 1722 gx->arecty = pBox->y1; 1723 gx->arectx = pBox->x1; 1724 gx->arecty = pBox->y2; 1725 gx->arectx = pBox->x2; 1726 pBox++; 1727 GXDrawDone(gx,r); 1728 } 1729 GXWait(gx,r); 1730} 1731 1732Bool 1733sunGXCheckTile(PixmapPtr pPixmap, sunGXStipplePtr stipple) 1734{ 1735 unsigned short *sbits; 1736 unsigned int fg = (unsigned int)~0, bg = (unsigned int)~0; 1737 unsigned char *tilebitsLine, *tilebits, tilebit; 1738 unsigned short sbit, mask; 1739 int nbwidth; 1740 int h, w; 1741 int x, y; 1742 int s_y, s_x; 1743 1744 h = pPixmap->drawable.height; 1745 if (h > 16 || (h & (h - 1))) 1746 return FALSE; 1747 w = pPixmap->drawable.width; 1748 if (w > 16 || (w & (w - 1))) 1749 return FALSE; 1750 sbits = (unsigned short *) stipple->bits; 1751 tilebitsLine = (unsigned char *) pPixmap->devPrivate.ptr; 1752 nbwidth = pPixmap->devKind; 1753 for (y = 0; y < h; y++) { 1754 tilebits = tilebitsLine; 1755 tilebitsLine += nbwidth; 1756 sbit = 0; 1757 mask = 1 << 15; 1758 for (x = 0; x < w; x++) 1759 { 1760 tilebit = *tilebits++; 1761 if (tilebit == fg) 1762 sbit |= mask; 1763 else if (tilebit != bg) 1764 { 1765 if (fg == ~0) 1766 { 1767 fg = tilebit; 1768 sbit |= mask; 1769 } 1770 else if (bg == ~0) 1771 { 1772 bg = tilebit; 1773 } 1774 else 1775 { 1776 return FALSE; 1777 } 1778 } 1779 mask >>= 1; 1780 } 1781 for (s_x = w; s_x < 16; s_x <<= 1) 1782 sbit = sbit | (sbit >> s_x); 1783 for (s_y = y; s_y < 16; s_y += h) 1784 sbits[s_y] = sbit; 1785 } 1786 stipple->fore = fg; 1787 stipple->back = bg; 1788 return TRUE; 1789} 1790 1791Bool 1792sunGXCheckStipple(PixmapPtr pPixmap, sunGXStipplePtr stipple) 1793{ 1794 unsigned short *sbits; 1795 unsigned int *stippleBits; 1796 unsigned long sbit, mask; 1797 int h, w; 1798 int y; 1799 int s_y, s_x; 1800 1801 h = pPixmap->drawable.height; 1802 if (h > 16 || (h & (h - 1))) 1803 return FALSE; 1804 w = pPixmap->drawable.width; 1805 if (w > 16 || (w & (w - 1))) 1806 return FALSE; 1807 sbits = (unsigned short *) stipple->bits; 1808 stippleBits = (unsigned int *) pPixmap->devPrivate.ptr; 1809 mask = ((1 << w) - 1) << (16 - w); 1810 for (y = 0; y < h; y++) { 1811 sbit = (*stippleBits++ >> 16) & mask; 1812 for (s_x = w; s_x < 16; s_x <<= 1) 1813 sbit = sbit | (sbit >> s_x); 1814 for (s_y = y; s_y < 16; s_y += h) 1815 sbits[s_y] = sbit; 1816 } 1817 return TRUE; 1818} 1819 1820/* cache one stipple; figuring out if we can use the stipple is as hard as 1821 * computing it, so we just use this one and leave it here if it 1822 * can't be used this time 1823 */ 1824 1825static sunGXStipplePtr tmpStipple; 1826 1827Bool 1828sunGXCheckFill(GCPtr pGC, DrawablePtr pDrawable) 1829{ 1830 sunGXPrivGCPtr gxPriv = sunGXGetGCPrivate (pGC); 1831 sunGXStipplePtr stipple; 1832 Uint alu; 1833 int xrot, yrot; 1834 1835 if (pGC->fillStyle == FillSolid) 1836 { 1837 if (gxPriv->stipple) 1838 { 1839 free (gxPriv->stipple); 1840 gxPriv->stipple = 0; 1841 } 1842 return TRUE; 1843 } 1844 if (!(stipple = gxPriv->stipple)) 1845 { 1846 if (!tmpStipple) 1847 { 1848 tmpStipple = malloc (sizeof *tmpStipple); 1849 if (!tmpStipple) 1850 return FALSE; 1851 } 1852 stipple = tmpStipple; 1853 } 1854 alu = gx_opaque_stipple_rop_table[pGC->alu]|GX_PATTERN_MASK; 1855 switch (pGC->fillStyle) { 1856 case FillTiled: 1857 if (!sunGXCheckTile (pGC->tile.pixmap, stipple)) 1858 { 1859 if (gxPriv->stipple) 1860 { 1861 xfree (gxPriv->stipple); 1862 gxPriv->stipple = 0; 1863 } 1864 return FALSE; 1865 } 1866 break; 1867 case FillStippled: 1868 alu = gx_stipple_rop_table[pGC->alu]|GX_PATTERN_MASK; 1869 case FillOpaqueStippled: 1870 if (!sunGXCheckStipple (pGC->stipple, stipple)) 1871 { 1872 if (gxPriv->stipple) 1873 { 1874 xfree (gxPriv->stipple); 1875 gxPriv->stipple = 0; 1876 } 1877 return FALSE; 1878 } 1879 stipple->fore = pGC->fgPixel; 1880 stipple->back = pGC->bgPixel; 1881 break; 1882 } 1883 xrot = (pGC->patOrg.x + pDrawable->x) & 0xf; 1884 yrot = (pGC->patOrg.y + pDrawable->y) & 0xf; 1885/* 1886 stipple->patalign = ((16 - (xrot & 0xf)) << 16) | (16 - (yrot & 0xf)); 1887*/ 1888 xrot = 16 - xrot; 1889 yrot = 16 - yrot; 1890 stipple->patalign = (xrot << 16) | yrot; 1891 stipple->alu = alu; 1892 gxPriv->stipple = stipple; 1893 if (stipple == tmpStipple) 1894 tmpStipple = 0; 1895 return TRUE; 1896} 1897 1898void sunGXValidateGC(GCPtr, Mask, DrawablePtr); 1899void sunGXDestroyGC(GCPtr); 1900 1901GCFuncs sunGXGCFuncs = { 1902 sunGXValidateGC, 1903 miChangeGC, 1904 miCopyGC, 1905 sunGXDestroyGC, 1906 miChangeClip, 1907 miDestroyClip, 1908 miCopyClip 1909}; 1910 1911GCOps sunGXTEOps1Rect = { 1912 sunGXFillSpans, 1913 cfbSetSpans, 1914 cfbPutImage, 1915 sunGXCopyArea, 1916 sunGXCopyPlane, 1917 cfbPolyPoint, 1918 sunGXPolylines1Rect, 1919 sunGXPolySeg1Rect, 1920 miPolyRectangle, 1921 cfbZeroPolyArcSS8Copy, 1922 sunGXFillPoly1Rect, 1923 sunGXPolyFillRect1Rect, 1924 sunGXPolyFillArc, 1925 miPolyText8, 1926 miPolyText16, 1927 miImageText8, 1928 miImageText16, 1929 sunGXTEGlyphBlt, 1930 sunGXPolyTEGlyphBlt, 1931 cfbPushPixels8 1932#ifdef NEED_LINEHELPER 1933 ,NULL 1934#endif 1935}; 1936 1937GCOps sunGXTEOps = { 1938 sunGXFillSpans, 1939 cfbSetSpans, 1940 cfbPutImage, 1941 sunGXCopyArea, 1942 sunGXCopyPlane, 1943 cfbPolyPoint, 1944 cfbLineSS, 1945 cfbSegmentSS, 1946 miPolyRectangle, 1947 cfbZeroPolyArcSS8Copy, 1948 miFillPolygon, 1949 sunGXPolyFillRect, 1950 sunGXPolyFillArc, 1951 miPolyText8, 1952 miPolyText16, 1953 miImageText8, 1954 miImageText16, 1955 sunGXTEGlyphBlt, 1956 sunGXPolyTEGlyphBlt, 1957 cfbPushPixels8 1958#ifdef NEED_LINEHELPER 1959 ,NULL 1960#endif 1961}; 1962 1963GCOps sunGXNonTEOps1Rect = { 1964 sunGXFillSpans, 1965 cfbSetSpans, 1966 cfbPutImage, 1967 sunGXCopyArea, 1968 sunGXCopyPlane, 1969 cfbPolyPoint, 1970 sunGXPolylines1Rect, 1971 sunGXPolySeg1Rect, 1972 miPolyRectangle, 1973 cfbZeroPolyArcSS8Copy, 1974 sunGXFillPoly1Rect, 1975 sunGXPolyFillRect1Rect, 1976 sunGXPolyFillArc, 1977 miPolyText8, 1978 miPolyText16, 1979 miImageText8, 1980 miImageText16, 1981 miImageGlyphBlt, 1982 sunGXPolyGlyphBlt, 1983 cfbPushPixels8 1984#ifdef NEED_LINEHELPER 1985 ,NULL 1986#endif 1987}; 1988 1989GCOps sunGXNonTEOps = { 1990 sunGXFillSpans, 1991 cfbSetSpans, 1992 cfbPutImage, 1993 sunGXCopyArea, 1994 sunGXCopyPlane, 1995 cfbPolyPoint, 1996 cfbLineSS, 1997 cfbSegmentSS, 1998 miPolyRectangle, 1999 cfbZeroPolyArcSS8Copy, 2000 miFillPolygon, 2001 sunGXPolyFillRect, 2002 sunGXPolyFillArc, 2003 miPolyText8, 2004 miPolyText16, 2005 miImageText8, 2006 miImageText16, 2007 miImageGlyphBlt, 2008 sunGXPolyGlyphBlt, 2009 cfbPushPixels8 2010#ifdef NEED_LINEHELPER 2011 ,NULL 2012#endif 2013}; 2014 2015#define FONTWIDTH(font) (FONTMAXBOUNDS(font,rightSideBearing) - \ 2016 FONTMINBOUNDS(font,leftSideBearing)) 2017 2018GCOps * 2019sunGXMatchCommon(GCPtr pGC, cfbPrivGCPtr devPriv) 2020{ 2021 if (pGC->lineWidth != 0) 2022 return 0; 2023 if (pGC->lineStyle != LineSolid) 2024 return 0; 2025 if (pGC->fillStyle != FillSolid) 2026 return 0; 2027 if (devPriv->rop != GXcopy) 2028 return 0; 2029 if (!WID_OK(pGC->pScreen)) 2030 return 0; 2031 if (pGC->font && 2032 FONTWIDTH (pGC->font) <= 32 && 2033 FONTMINBOUNDS(pGC->font,characterWidth) >= 0) 2034 { 2035 if (TERMINALFONT(pGC->font)) 2036 if (devPriv->oneRect) 2037 return &sunGXTEOps1Rect; 2038 else 2039 return &sunGXTEOps; 2040 else 2041 if (devPriv->oneRect) 2042 return &sunGXNonTEOps1Rect; 2043 else 2044 return &sunGXNonTEOps; 2045 } 2046 return 0; 2047} 2048 2049void 2050sunGXValidateGC(GCPtr pGC, Mask changes, DrawablePtr pDrawable) 2051{ 2052 int mask; /* stateChanges */ 2053 int index; /* used for stepping through bitfields */ 2054 int new_rrop; 2055 int new_line, new_text, new_fillspans, new_fillarea; 2056 int new_rotate; 2057 int xrot, yrot; 2058 /* flags for changing the proc vector */ 2059 cfbPrivGCPtr devPriv; 2060 sunGXPrivGCPtr gxPriv; 2061 int oneRect; 2062 int canGX; 2063 int widOK; 2064 2065 gxPriv = sunGXGetGCPrivate (pGC); 2066 widOK = WID_OK(pGC->pScreen); 2067 if (pDrawable->type != DRAWABLE_WINDOW) 2068 { 2069 if (gxPriv->type == DRAWABLE_WINDOW) 2070 { 2071 extern GCOps cfbNonTEOps; 2072 2073 miDestroyGCOps (pGC->ops); 2074 pGC->ops = &cfbNonTEOps; 2075 changes = (1 << (GCLastBit + 1)) - 1; 2076 pGC->stateChanges = changes; 2077 gxPriv->type = pDrawable->type; 2078 } 2079 cfbValidateGC (pGC, changes, pDrawable); 2080 return; 2081 } 2082 if (gxPriv->type != DRAWABLE_WINDOW) 2083 { 2084 changes = (1 << (GCLastBit + 1)) - 1; 2085 gxPriv->type = DRAWABLE_WINDOW; 2086 } 2087 2088 new_rotate = pGC->lastWinOrg.x != pDrawable->x || 2089 pGC->lastWinOrg.y != pDrawable->y; 2090 2091 pGC->lastWinOrg.x = pDrawable->x; 2092 pGC->lastWinOrg.y = pDrawable->y; 2093 2094 devPriv = ((cfbPrivGCPtr) (pGC->devPrivates[cfbGCPrivateIndex].ptr)); 2095 2096 new_rrop = FALSE; 2097 new_line = FALSE; 2098 new_text = FALSE; 2099 new_fillspans = FALSE; 2100 new_fillarea = FALSE; 2101 2102 /* 2103 * if the client clip is different or moved OR the subwindowMode has 2104 * changed OR the window's clip has changed since the last validation 2105 * we need to recompute the composite clip 2106 */ 2107 2108 if ((changes & (GCClipXOrigin|GCClipYOrigin|GCClipMask|GCSubwindowMode)) || 2109 (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS)) 2110 ) 2111 { 2112 miComputeCompositeClip(pGC, pDrawable); 2113 oneRect = REGION_NUM_RECTS(pGC->pCompositeClip) == 1; 2114 if (oneRect != devPriv->oneRect) 2115 { 2116 new_line = TRUE; 2117 new_fillarea = TRUE; 2118 devPriv->oneRect = oneRect; 2119 } 2120 } 2121 2122 mask = changes; 2123 while (mask) { 2124 index = lowbit (mask); 2125 mask &= ~index; 2126 2127 /* 2128 * this switch acculmulates a list of which procedures might have 2129 * to change due to changes in the GC. in some cases (e.g. 2130 * changing one 16 bit tile for another) we might not really need 2131 * a change, but the code is being paranoid. this sort of batching 2132 * wins if, for example, the alu and the font have been changed, 2133 * or any other pair of items that both change the same thing. 2134 */ 2135 switch (index) { 2136 case GCFunction: 2137 case GCForeground: 2138 new_rrop = TRUE; 2139 break; 2140 case GCPlaneMask: 2141 new_rrop = TRUE; 2142 new_text = TRUE; 2143 break; 2144 case GCBackground: 2145 break; 2146 case GCLineStyle: 2147 case GCLineWidth: 2148 new_line = TRUE; 2149 break; 2150 case GCCapStyle: 2151 break; 2152 case GCJoinStyle: 2153 break; 2154 case GCFillStyle: 2155 new_text = TRUE; 2156 new_fillspans = TRUE; 2157 new_line = TRUE; 2158 new_fillarea = TRUE; 2159 break; 2160 case GCFillRule: 2161 break; 2162 case GCTile: 2163 new_fillspans = TRUE; 2164 new_fillarea = TRUE; 2165 break; 2166 2167 case GCStipple: 2168 new_fillspans = TRUE; 2169 new_fillarea = TRUE; 2170 break; 2171 2172 case GCTileStipXOrigin: 2173 new_rotate = TRUE; 2174 break; 2175 2176 case GCTileStipYOrigin: 2177 new_rotate = TRUE; 2178 break; 2179 2180 case GCFont: 2181 new_text = TRUE; 2182 break; 2183 case GCSubwindowMode: 2184 break; 2185 case GCGraphicsExposures: 2186 break; 2187 case GCClipXOrigin: 2188 break; 2189 case GCClipYOrigin: 2190 break; 2191 case GCClipMask: 2192 break; 2193 case GCDashOffset: 2194 break; 2195 case GCDashList: 2196 break; 2197 case GCArcMode: 2198 break; 2199 default: 2200 break; 2201 } 2202 } 2203 2204 /* 2205 * If the drawable has changed, check its depth & ensure suitable 2206 * entries are in the proc vector. 2207 */ 2208 if (pDrawable->serialNumber != (pGC->serialNumber & (DRAWABLE_SERIAL_BITS))) { 2209 new_fillspans = TRUE; /* deal with FillSpans later */ 2210 } 2211 2212 if ((new_rotate || new_fillspans)) 2213 { 2214 Bool new_pix = FALSE; 2215 xrot = pGC->patOrg.x + pDrawable->x; 2216 yrot = pGC->patOrg.y + pDrawable->y; 2217 2218 if (!sunGXCheckFill (pGC, pDrawable)) 2219 { 2220 switch (pGC->fillStyle) 2221 { 2222 case FillTiled: 2223 if (!pGC->tileIsPixel) 2224 { 2225 int width = pGC->tile.pixmap->drawable.width * PSZ; 2226 2227 if ((width <= 32) && !(width & (width - 1))) 2228 { 2229 cfbCopyRotatePixmap(pGC->tile.pixmap, 2230 &pGC->pRotatedPixmap, 2231 xrot, yrot); 2232 new_pix = TRUE; 2233 } 2234 } 2235 break; 2236 case FillStippled: 2237 case FillOpaqueStippled: 2238 { 2239 int width = pGC->stipple->drawable.width; 2240 2241 if ((width <= 32) && !(width & (width - 1))) 2242 { 2243 mfbCopyRotatePixmap(pGC->stipple, 2244 &pGC->pRotatedPixmap, xrot, yrot); 2245 new_pix = TRUE; 2246 } 2247 } 2248 break; 2249 } 2250 } 2251 if (!new_pix && pGC->pRotatedPixmap) 2252 { 2253 cfbDestroyPixmap(pGC->pRotatedPixmap); 2254 pGC->pRotatedPixmap = NULL; 2255 } 2256 } 2257 2258 if (new_rrop) 2259 { 2260 int old_rrop; 2261 2262 if (gxPriv->stipple) 2263 { 2264 if (pGC->fillStyle == FillStippled) 2265 gxPriv->stipple->alu = gx_stipple_rop_table[pGC->alu]|GX_PATTERN_MASK; 2266 else 2267 gxPriv->stipple->alu = gx_opaque_stipple_rop_table[pGC->alu]|GX_PATTERN_MASK; 2268 if (pGC->fillStyle != FillTiled) 2269 { 2270 gxPriv->stipple->fore = pGC->fgPixel; 2271 gxPriv->stipple->back = pGC->bgPixel; 2272 } 2273 } 2274 old_rrop = devPriv->rop; 2275 devPriv->rop = cfbReduceRasterOp (pGC->alu, pGC->fgPixel, 2276 pGC->planemask, 2277 &devPriv->and, &devPriv->xor); 2278 if (old_rrop == devPriv->rop) 2279 new_rrop = FALSE; 2280 else 2281 { 2282 new_line = TRUE; 2283 new_text = TRUE; 2284 new_fillspans = TRUE; 2285 new_fillarea = TRUE; 2286 } 2287 } 2288 2289 if (new_rrop || new_fillspans || new_text || new_fillarea || new_line) 2290 { 2291 GCOps *newops; 2292 2293 if ((newops = sunGXMatchCommon (pGC, devPriv))) 2294 { 2295 if (pGC->ops->devPrivate.val) 2296 miDestroyGCOps (pGC->ops); 2297 pGC->ops = newops; 2298 new_rrop = new_line = new_fillspans = new_text = new_fillarea = 0; 2299 } 2300 else 2301 { 2302 if (!pGC->ops->devPrivate.val) 2303 { 2304 pGC->ops = miCreateGCOps (pGC->ops); 2305 pGC->ops->devPrivate.val = 1; 2306 } 2307 } 2308 } 2309 2310 canGX = pGC->fillStyle == FillSolid || gxPriv->stipple; 2311 2312 /* deal with the changes we've collected */ 2313 if (new_line) 2314 { 2315 pGC->ops->FillPolygon = miFillPolygon; 2316 if (devPriv->oneRect && canGX) 2317 pGC->ops->FillPolygon = sunGXFillPoly1Rect; 2318 if (pGC->lineWidth == 0) 2319 { 2320 if ((pGC->lineStyle == LineSolid) && (pGC->fillStyle == FillSolid)) 2321 { 2322 switch (devPriv->rop) 2323 { 2324 case GXxor: 2325 pGC->ops->PolyArc = cfbZeroPolyArcSS8Xor; 2326 break; 2327 case GXcopy: 2328 pGC->ops->PolyArc = cfbZeroPolyArcSS8Copy; 2329 break; 2330 default: 2331 pGC->ops->PolyArc = cfbZeroPolyArcSS8General; 2332 break; 2333 } 2334 } 2335 else 2336 pGC->ops->PolyArc = miZeroPolyArc; 2337 } 2338 else 2339 pGC->ops->PolyArc = miPolyArc; 2340 pGC->ops->PolySegment = miPolySegment; 2341 switch (pGC->lineStyle) 2342 { 2343 case LineSolid: 2344 if(pGC->lineWidth == 0) 2345 { 2346 if (devPriv->oneRect && canGX && widOK) 2347 { 2348 pGC->ops->PolySegment = sunGXPolySeg1Rect; 2349 pGC->ops->Polylines = sunGXPolylines1Rect; 2350 } 2351 else if (pGC->fillStyle == FillSolid) 2352 { 2353 if (devPriv->oneRect) 2354 { 2355 pGC->ops->Polylines = cfb8LineSS1Rect; 2356 pGC->ops->PolySegment = cfb8SegmentSS1Rect; 2357 } 2358 else 2359 { 2360 pGC->ops->Polylines = cfbLineSS; 2361 pGC->ops->PolySegment = cfbSegmentSS; 2362 } 2363 } 2364 else 2365 pGC->ops->Polylines = miZeroLine; 2366 } 2367 else 2368 pGC->ops->Polylines = miWideLine; 2369 break; 2370 case LineOnOffDash: 2371 case LineDoubleDash: 2372 if (pGC->lineWidth == 0 && pGC->fillStyle == FillSolid) 2373 { 2374 pGC->ops->Polylines = cfbLineSD; 2375 pGC->ops->PolySegment = cfbSegmentSD; 2376 } else 2377 pGC->ops->Polylines = miWideDash; 2378 break; 2379 } 2380 } 2381 2382 if (new_text && (pGC->font)) 2383 { 2384 if (FONTWIDTH(pGC->font) > 32 || 2385 FONTMINBOUNDS(pGC->font,characterWidth) < 0) 2386 { 2387 pGC->ops->PolyGlyphBlt = miPolyGlyphBlt; 2388 pGC->ops->ImageGlyphBlt = miImageGlyphBlt; 2389 } 2390 else 2391 { 2392 if (pGC->fillStyle == FillSolid) 2393 { 2394 if (TERMINALFONT (pGC->font)) 2395 pGC->ops->PolyGlyphBlt = sunGXPolyTEGlyphBlt; 2396 else 2397 pGC->ops->PolyGlyphBlt = sunGXPolyGlyphBlt; 2398 } 2399 else 2400 pGC->ops->PolyGlyphBlt = miPolyGlyphBlt; 2401 /* special case ImageGlyphBlt for terminal emulator fonts */ 2402 if (TERMINALFONT(pGC->font)) 2403 pGC->ops->ImageGlyphBlt = sunGXTEGlyphBlt; 2404 else 2405 pGC->ops->ImageGlyphBlt = miImageGlyphBlt; 2406 } 2407 } 2408 2409 2410 if (new_fillspans) { 2411 if (canGX) 2412 pGC->ops->FillSpans = sunGXFillSpans; 2413 else switch (pGC->fillStyle) { 2414 case FillTiled: 2415 if (pGC->pRotatedPixmap) 2416 { 2417 if (pGC->alu == GXcopy && (pGC->planemask & PMSK) == PMSK) 2418 pGC->ops->FillSpans = cfbTile32FSCopy; 2419 else 2420 pGC->ops->FillSpans = cfbTile32FSGeneral; 2421 } 2422 else 2423 pGC->ops->FillSpans = cfbUnnaturalTileFS; 2424 break; 2425 case FillStippled: 2426 if (pGC->pRotatedPixmap) 2427 pGC->ops->FillSpans = cfb8Stipple32FS; 2428 else 2429 pGC->ops->FillSpans = cfbUnnaturalStippleFS; 2430 break; 2431 case FillOpaqueStippled: 2432 if (pGC->pRotatedPixmap) 2433 pGC->ops->FillSpans = cfb8OpaqueStipple32FS; 2434 else 2435 pGC->ops->FillSpans = cfbUnnaturalStippleFS; 2436 break; 2437 default: 2438 FatalError("cfbValidateGC: illegal fillStyle\n"); 2439 } 2440 } /* end of new_fillspans */ 2441 2442 if (new_fillarea) { 2443 pGC->ops->PolyFillRect = cfbPolyFillRect; 2444 pGC->ops->PolyFillArc = miPolyFillArc; 2445 if (canGX) 2446 { 2447 pGC->ops->PolyFillArc = sunGXPolyFillArc; 2448 pGC->ops->PolyFillRect = sunGXPolyFillRect; 2449 if (devPriv->oneRect) 2450 pGC->ops->PolyFillRect = sunGXPolyFillRect1Rect; 2451 } 2452 pGC->ops->PushPixels = mfbPushPixels; 2453 if (pGC->fillStyle == FillSolid && devPriv->rop == GXcopy) 2454 pGC->ops->PushPixels = cfbPushPixels8; 2455 } 2456} 2457 2458void 2459sunGXDestroyGC(GCPtr pGC) 2460{ 2461 sunGXPrivGCPtr gxPriv = sunGXGetGCPrivate (pGC); 2462 2463 if (gxPriv->stipple) 2464 xfree (gxPriv->stipple); 2465 miDestroyGC (pGC); 2466} 2467 2468Bool 2469sunGXCreateGC(GCPtr pGC) 2470{ 2471 sunGXPrivGCPtr gxPriv; 2472 if (pGC->depth == 1) 2473 return mfbCreateGC (pGC); 2474 if (!cfbCreateGC (pGC)) 2475 return FALSE; 2476 pGC->ops = &sunGXNonTEOps; 2477 pGC->funcs = &sunGXGCFuncs; 2478 gxPriv = sunGXGetGCPrivate(pGC); 2479 gxPriv->type = DRAWABLE_WINDOW; 2480 gxPriv->stipple = 0; 2481 return TRUE; 2482} 2483 2484Bool 2485sunGXCreateWindow(WindowPtr pWin) 2486{ 2487 if (!cfbCreateWindow (pWin)) 2488 return FALSE; 2489 pWin->devPrivates[sunGXWindowPrivateIndex].ptr = 0; 2490 return TRUE; 2491} 2492 2493Bool 2494sunGXDestroyWindow(WindowPtr pWin) 2495{ 2496 sunGXStipplePtr stipple = sunGXGetWindowPrivate(pWin); 2497 xfree (stipple); 2498 return cfbDestroyWindow (pWin); 2499} 2500 2501Bool 2502sunGXChangeWindowAttributes(WindowPtr pWin, Mask mask) 2503{ 2504 sunGXStipplePtr stipple; 2505 Mask index; 2506 WindowPtr pBgWin; 2507 register cfbPrivWin *pPrivWin; 2508 int width; 2509 2510 pPrivWin = (cfbPrivWin *)(pWin->devPrivates[cfbWindowPrivateIndex].ptr); 2511 /* 2512 * When background state changes from ParentRelative and 2513 * we had previously rotated the fast border pixmap to match 2514 * the parent relative origin, rerotate to match window 2515 */ 2516 if (mask & (CWBackPixmap | CWBackPixel) && 2517 pWin->backgroundState != ParentRelative && 2518 pPrivWin->fastBorder && 2519 (pPrivWin->oldRotate.x != pWin->drawable.x || 2520 pPrivWin->oldRotate.y != pWin->drawable.y)) 2521 { 2522 cfbXRotatePixmap(pPrivWin->pRotatedBorder, 2523 pWin->drawable.x - pPrivWin->oldRotate.x); 2524 cfbYRotatePixmap(pPrivWin->pRotatedBorder, 2525 pWin->drawable.y - pPrivWin->oldRotate.y); 2526 pPrivWin->oldRotate.x = pWin->drawable.x; 2527 pPrivWin->oldRotate.y = pWin->drawable.y; 2528 } 2529 while (mask) 2530 { 2531 index = lowbit(mask); 2532 mask &= ~index; 2533 switch (index) 2534 { 2535 case CWBackPixmap: 2536 stipple = sunGXGetWindowPrivate(pWin); 2537 if (pWin->backgroundState == None || 2538 pWin->backgroundState == ParentRelative) 2539 { 2540 pPrivWin->fastBackground = FALSE; 2541 if (stipple) 2542 { 2543 xfree (stipple); 2544 sunGXSetWindowPrivate(pWin,0); 2545 } 2546 /* Rotate border to match parent origin */ 2547 if (pWin->backgroundState == ParentRelative && 2548 pPrivWin->pRotatedBorder) 2549 { 2550 for (pBgWin = pWin->parent; 2551 pBgWin->backgroundState == ParentRelative; 2552 pBgWin = pBgWin->parent); 2553 cfbXRotatePixmap(pPrivWin->pRotatedBorder, 2554 pBgWin->drawable.x - pPrivWin->oldRotate.x); 2555 cfbYRotatePixmap(pPrivWin->pRotatedBorder, 2556 pBgWin->drawable.y - pPrivWin->oldRotate.y); 2557 } 2558 2559 break; 2560 } 2561 if (!stipple) 2562 { 2563 if (!tmpStipple) 2564 tmpStipple = malloc (sizeof *tmpStipple); 2565 stipple = tmpStipple; 2566 } 2567 if (stipple && sunGXCheckTile (pWin->background.pixmap, stipple)) 2568 { 2569 stipple->alu = gx_opaque_stipple_rop_table[GXcopy]|GX_PATTERN_MASK; 2570 pPrivWin->fastBackground = FALSE; 2571 if (stipple == tmpStipple) 2572 { 2573 sunGXSetWindowPrivate(pWin, stipple); 2574 tmpStipple = 0; 2575 } 2576 break; 2577 } 2578 if ((stipple = sunGXGetWindowPrivate(pWin))) 2579 { 2580 xfree (stipple); 2581 sunGXSetWindowPrivate(pWin,0); 2582 } 2583 if (((width = (pWin->background.pixmap->drawable.width * PSZ)) <= BITMAP_SCANLINE_UNIT) && 2584 !(width & (width - 1))) 2585 { 2586 cfbCopyRotatePixmap(pWin->background.pixmap, 2587 &pPrivWin->pRotatedBackground, 2588 pWin->drawable.x, 2589 pWin->drawable.y); 2590 if (pPrivWin->pRotatedBackground) 2591 { 2592 pPrivWin->fastBackground = TRUE; 2593 pPrivWin->oldRotate.x = pWin->drawable.x; 2594 pPrivWin->oldRotate.y = pWin->drawable.y; 2595 } 2596 else 2597 { 2598 pPrivWin->fastBackground = FALSE; 2599 } 2600 break; 2601 } 2602 pPrivWin->fastBackground = FALSE; 2603 break; 2604 2605 case CWBackPixel: 2606 pPrivWin->fastBackground = FALSE; 2607 break; 2608 2609 case CWBorderPixmap: 2610 /* don't bother with accelerator for border tiles (just lazy) */ 2611 if (((width = (pWin->border.pixmap->drawable.width * PSZ)) <= BITMAP_SCANLINE_UNIT) && 2612 !(width & (width - 1))) 2613 { 2614 for (pBgWin = pWin; 2615 pBgWin->backgroundState == ParentRelative; 2616 pBgWin = pBgWin->parent); 2617 cfbCopyRotatePixmap(pWin->border.pixmap, 2618 &pPrivWin->pRotatedBorder, 2619 pBgWin->drawable.x, 2620 pBgWin->drawable.y); 2621 if (pPrivWin->pRotatedBorder) 2622 { 2623 pPrivWin->fastBorder = TRUE; 2624 pPrivWin->oldRotate.x = pBgWin->drawable.x; 2625 pPrivWin->oldRotate.y = pBgWin->drawable.y; 2626 } 2627 else 2628 { 2629 pPrivWin->fastBorder = TRUE; 2630 } 2631 } 2632 else 2633 { 2634 pPrivWin->fastBorder = FALSE; 2635 } 2636 break; 2637 case CWBorderPixel: 2638 pPrivWin->fastBorder = FALSE; 2639 break; 2640 } 2641 } 2642 return (TRUE); 2643} 2644 2645void 2646sunGXPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what) 2647{ 2648 register cfbPrivWin *pPrivWin; 2649 sunGXStipplePtr stipple; 2650 WindowPtr pBgWin; 2651 pPrivWin = (cfbPrivWin *)(pWin->devPrivates[cfbWindowPrivateIndex].ptr); 2652 2653 switch (what) { 2654 case PW_BACKGROUND: 2655 stipple = sunGXGetWindowPrivate(pWin); 2656 switch (pWin->backgroundState) { 2657 case None: 2658 return; 2659 case ParentRelative: 2660 do { 2661 pWin = pWin->parent; 2662 } while (pWin->backgroundState == ParentRelative); 2663 (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, pRegion, 2664 what); 2665 return; 2666 case BackgroundPixmap: 2667 if (stipple) 2668 { 2669 sunGXFillBoxStipple ((DrawablePtr)pWin, 2670 (int)REGION_NUM_RECTS(pRegion), 2671 REGION_RECTS(pRegion), 2672 stipple); 2673 } 2674 else if (pPrivWin->fastBackground) 2675 { 2676 cfbFillBoxTile32 ((DrawablePtr)pWin, 2677 (int)REGION_NUM_RECTS(pRegion), 2678 REGION_RECTS(pRegion), 2679 pPrivWin->pRotatedBackground); 2680 } 2681 else 2682 { 2683 cfbFillBoxTileOdd ((DrawablePtr)pWin, 2684 (int)REGION_NUM_RECTS(pRegion), 2685 REGION_RECTS(pRegion), 2686 pWin->background.pixmap, 2687 (int) pWin->drawable.x, (int) pWin->drawable.y); 2688 } 2689 return; 2690 case BackgroundPixel: 2691 sunGXFillBoxSolid((DrawablePtr)pWin, 2692 (int)REGION_NUM_RECTS(pRegion), 2693 REGION_RECTS(pRegion), 2694 pWin->background.pixel); 2695 return; 2696 } 2697 break; 2698 case PW_BORDER: 2699 if (pWin->borderIsPixel) 2700 { 2701 sunGXFillBoxSolid((DrawablePtr)pWin, 2702 (int)REGION_NUM_RECTS(pRegion), 2703 REGION_RECTS(pRegion), 2704 pWin->border.pixel); 2705 return; 2706 } 2707 else if (pPrivWin->fastBorder) 2708 { 2709 cfbFillBoxTile32 ((DrawablePtr)pWin, 2710 (int)REGION_NUM_RECTS(pRegion), 2711 REGION_RECTS(pRegion), 2712 pPrivWin->pRotatedBorder); 2713 return; 2714 } 2715 else 2716 { 2717 for (pBgWin = pWin; 2718 pBgWin->backgroundState == ParentRelative; 2719 pBgWin = pBgWin->parent); 2720 2721 cfbFillBoxTileOdd ((DrawablePtr)pWin, 2722 (int)REGION_NUM_RECTS(pRegion), 2723 REGION_RECTS(pRegion), 2724 pWin->border.pixmap, 2725 (int) pBgWin->drawable.x, 2726 (int) pBgWin->drawable.y); 2727 return; 2728 } 2729 break; 2730 } 2731} 2732 2733void 2734sunGXCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) 2735{ 2736 DDXPointPtr pptSrc; 2737 register DDXPointPtr ppt; 2738 RegionPtr prgnDst; 2739 register BoxPtr pbox; 2740 register int dx, dy; 2741 register int i, nbox; 2742 WindowPtr pwinRoot; 2743 extern WindowPtr *WindowTable; 2744 2745 pwinRoot = WindowTable[pWin->drawable.pScreen->myNum]; 2746 2747 prgnDst = REGION_CREATE(pWin->drawable.pScreen, NULL, 1); 2748 2749 dx = ptOldOrg.x - pWin->drawable.x; 2750 dy = ptOldOrg.y - pWin->drawable.y; 2751 REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy); 2752 REGION_INTERSECT(pWin->drawable.pScreen, prgnDst, &pWin->borderClip, prgnSrc); 2753 2754 pbox = REGION_RECTS(prgnDst); 2755 nbox = REGION_NUM_RECTS(prgnDst); 2756 if(!(pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec)))) 2757 return; 2758 ppt = pptSrc; 2759 2760 for (i = nbox; --i >= 0; ppt++, pbox++) 2761 { 2762 ppt->x = pbox->x1 + dx; 2763 ppt->y = pbox->y1 + dy; 2764 } 2765 2766 sunGXDoBitblt ((DrawablePtr)pwinRoot, (DrawablePtr)pwinRoot, 2767 GXcopy, prgnDst, pptSrc, ~0L); 2768 DEALLOCATE_LOCAL(pptSrc); 2769 REGION_DESTROY(pWin->drawable.pScreen, prgnDst); 2770} 2771 2772Bool 2773sunGXInit(ScreenPtr pScreen, fbFd *fb) 2774{ 2775 sunGXPtr gx; 2776 Uint mode; 2777 register long r; 2778 2779 if (serverGeneration != sunGXGeneration) 2780 { 2781 sunGXScreenPrivateIndex = AllocateScreenPrivateIndex(); 2782 if (sunGXScreenPrivateIndex == -1) 2783 return FALSE; 2784 sunGXGCPrivateIndex = AllocateGCPrivateIndex (); 2785 sunGXWindowPrivateIndex = AllocateWindowPrivateIndex (); 2786 sunGXGeneration = serverGeneration; 2787 } 2788 if (!AllocateGCPrivate(pScreen, sunGXGCPrivateIndex, sizeof (sunGXPrivGCRec))) 2789 return FALSE; 2790 if (!AllocateWindowPrivate(pScreen, sunGXWindowPrivateIndex, 0)) 2791 return FALSE; 2792 gx = (sunGXPtr) fb->fb; 2793 mode = gx->mode; 2794 GXWait(gx,r); 2795 mode &= ~( GX_BLIT_ALL | 2796 GX_MODE_ALL | 2797 GX_DRAW_ALL | 2798 GX_BWRITE0_ALL | 2799 GX_BWRITE1_ALL | 2800 GX_BREAD_ALL | 2801 GX_BDISP_ALL); 2802 mode |= GX_BLIT_SRC | 2803 GX_MODE_COLOR8 | 2804 GX_DRAW_RENDER | 2805 GX_BWRITE0_ENABLE | 2806 GX_BWRITE1_DISABLE | 2807 GX_BREAD_0 | 2808 GX_BDISP_0; 2809 gx->mode = mode; 2810 gx->clip = 0; 2811 gx->offx = 0; 2812 gx->offy = 0; 2813 gx->clipminx = 0; 2814 gx->clipminy = 0; 2815 gx->clipmaxx = fb->info.fb_width - 1; 2816 gx->clipmaxy = fb->info.fb_height - 1; 2817 pScreen->devPrivates[sunGXScreenPrivateIndex].ptr = (void *) gx; 2818 /* 2819 * Replace various screen functions 2820 */ 2821 pScreen->CreateGC = sunGXCreateGC; 2822 pScreen->CreateWindow = sunGXCreateWindow; 2823 pScreen->ChangeWindowAttributes = sunGXChangeWindowAttributes; 2824 pScreen->DestroyWindow = sunGXDestroyWindow; 2825 pScreen->PaintWindowBackground = sunGXPaintWindow; 2826 pScreen->PaintWindowBorder = sunGXPaintWindow; 2827 pScreen->CopyWindow = sunGXCopyWindow; 2828 return TRUE; 2829} 2830