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