diff options
Diffstat (limited to 'xorg-server/hw/xfree86/xaa/xaaGCmisc.c')
-rw-r--r-- | xorg-server/hw/xfree86/xaa/xaaGCmisc.c | 429 |
1 files changed, 429 insertions, 0 deletions
diff --git a/xorg-server/hw/xfree86/xaa/xaaGCmisc.c b/xorg-server/hw/xfree86/xaa/xaaGCmisc.c new file mode 100644 index 000000000..5823cc064 --- /dev/null +++ b/xorg-server/hw/xfree86/xaa/xaaGCmisc.c @@ -0,0 +1,429 @@ + +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include "misc.h" +#include "xf86.h" +#include "xf86_OSproc.h" + +#include <X11/X.h> +#include "scrnintstr.h" +#include <X11/fonts/fontstruct.h> +#include "dixfontstr.h" +#include "xf86str.h" +#include "xaa.h" +#include "xaalocal.h" +#include "migc.h" +#include "mi.h" +#include "gcstruct.h" +#include "pixmapstr.h" + +void +XAAValidateCopyArea( + GCPtr pGC, + unsigned long changes, + DrawablePtr pDraw ) +{ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); + + if(infoRec->CopyArea && + CHECK_PLANEMASK(pGC,infoRec->CopyAreaFlags) && + CHECK_ROP(pGC,infoRec->CopyAreaFlags) && + CHECK_ROPSRC(pGC,infoRec->CopyAreaFlags) + ) + pGC->ops->CopyArea = infoRec->CopyArea; + else + pGC->ops->CopyArea = XAAFallbackOps.CopyArea; +} + +void +XAAValidatePutImage( + GCPtr pGC, + unsigned long changes, + DrawablePtr pDraw ) +{ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); + + if(infoRec->PutImage && + CHECK_PLANEMASK(pGC,infoRec->PutImageFlags) && + CHECK_ROP(pGC,infoRec->PutImageFlags) && + CHECK_ROPSRC(pGC,infoRec->PutImageFlags) && + CHECK_COLORS(pGC,infoRec->PutImageFlags) + ) + pGC->ops->PutImage = infoRec->PutImage; + else + pGC->ops->PutImage = XAAFallbackOps.PutImage; +} + +void +XAAValidateCopyPlane( + GCPtr pGC, + unsigned long changes, + DrawablePtr pDraw ) +{ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); + + if(infoRec->CopyPlane && + CHECK_PLANEMASK(pGC,infoRec->CopyPlaneFlags) && + CHECK_ROP(pGC,infoRec->CopyPlaneFlags) && + CHECK_ROPSRC(pGC,infoRec->CopyPlaneFlags) && + CHECK_COLORS(pGC,infoRec->CopyPlaneFlags) + ) + pGC->ops->CopyPlane = infoRec->CopyPlane; + else + pGC->ops->CopyPlane = XAAFallbackOps.CopyPlane; +} + +void +XAAValidatePushPixels( + GCPtr pGC, + unsigned long changes, + DrawablePtr pDraw ) +{ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); + + if(infoRec->PushPixelsSolid && + (pGC->fillStyle == FillSolid) && + CHECK_PLANEMASK(pGC,infoRec->PushPixelsFlags) && + CHECK_ROP(pGC,infoRec->PushPixelsFlags) && + CHECK_ROPSRC(pGC,infoRec->PushPixelsFlags) && + CHECK_FG(pGC,infoRec->PushPixelsFlags) && + (!(infoRec->PushPixelsFlags & TRANSPARENCY_GXCOPY_ONLY) || + (pGC->alu == GXcopy)) + ) + pGC->ops->PushPixels = infoRec->PushPixelsSolid; + else + pGC->ops->PushPixels = XAAFallbackOps.PushPixels; + +} + + +/* We make the assumption that the FillSpans, PolyFillRect, FillPolygon + and PolyFillArc functions are linked in a way that they all have + the same rop/color/planemask restrictions. If the driver provides + a GC level replacement for these, it will need to supply a new + Validate functions if it breaks this assumption */ + + +void +XAAValidateFillSpans( + GCPtr pGC, + unsigned long changes, + DrawablePtr pDraw ) +{ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); + + if(pGC->fillStyle != FillTiled) changes &= ~GCTile; + if((pGC->fillStyle == FillTiled) || (pGC->fillStyle == FillSolid)) + changes &= ~GCStipple; + if(!changes) return; + + + pGC->ops->FillSpans = XAAFallbackOps.FillSpans; + pGC->ops->PolyFillRect = XAAFallbackOps.PolyFillRect; + pGC->ops->FillPolygon = XAAFallbackOps.FillPolygon; + pGC->ops->PolyFillArc = XAAFallbackOps.PolyFillArc; + + switch(pGC->fillStyle){ + case FillSolid: + if(infoRec->FillSpansSolid && + CHECK_PLANEMASK(pGC,infoRec->FillSpansSolidFlags) && + CHECK_ROP(pGC,infoRec->FillSpansSolidFlags) && + CHECK_ROPSRC(pGC,infoRec->FillSpansSolidFlags) && + CHECK_FG(pGC,infoRec->FillSpansSolidFlags) + ) { + pGC->ops->FillSpans = infoRec->FillSpansSolid; + pGC->ops->PolyFillRect = infoRec->PolyFillRectSolid; + pGC->ops->FillPolygon = infoRec->FillPolygonSolid; + pGC->ops->PolyFillArc = infoRec->PolyFillArcSolid; + } + break; + /* The [Stippled/OpaqueStippled/Tiled]FillChooser + functions do the validating */ + case FillStippled: + if(infoRec->FillSpansStippled) { + pGC->ops->FillSpans = infoRec->FillSpansStippled; + pGC->ops->PolyFillRect = infoRec->PolyFillRectStippled; + if(infoRec->FillPolygonStippled) + pGC->ops->FillPolygon = infoRec->FillPolygonStippled; + else pGC->ops->FillPolygon = miFillPolygon; + pGC->ops->PolyFillArc = miPolyFillArc; + } + break; + case FillOpaqueStippled: + if(infoRec->FillSpansOpaqueStippled) { + pGC->ops->FillSpans = infoRec->FillSpansOpaqueStippled; + pGC->ops->PolyFillRect = infoRec->PolyFillRectOpaqueStippled; + if(infoRec->FillPolygonOpaqueStippled) + pGC->ops->FillPolygon = infoRec->FillPolygonOpaqueStippled; + else pGC->ops->FillPolygon = miFillPolygon; + pGC->ops->PolyFillArc = miPolyFillArc; + } + break; + case FillTiled: + if(infoRec->FillSpansTiled) { + pGC->ops->FillSpans = infoRec->FillSpansTiled; + pGC->ops->PolyFillRect = infoRec->PolyFillRectTiled; + if(infoRec->FillPolygonTiled) + pGC->ops->FillPolygon = infoRec->FillPolygonTiled; + else pGC->ops->FillPolygon = miFillPolygon; + pGC->ops->PolyFillArc = miPolyFillArc; + } + break; + default: return; + } +} + + +/* We make the assumption that these Text8/16 and GlyphBlt functions + are linked in a way that they all have the same rop/color/planemask + restrictions. If the driver provides a GC level replacement for + these, it will need to supply a new Validate functions if it breaks + this assumption */ + +void +XAAValidatePolyGlyphBlt( + GCPtr pGC, + unsigned long changes, + DrawablePtr pDraw ) +{ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); + Bool BigFont = FALSE; + + pGC->ops->PolyText8 = XAAFallbackOps.PolyText8; + pGC->ops->PolyText16 = XAAFallbackOps.PolyText16; + pGC->ops->PolyGlyphBlt = XAAFallbackOps.PolyGlyphBlt; + + if(!pGC->font) return; + if(pGC->fillStyle != FillSolid) return; + + if((FONTMAXBOUNDS(pGC->font, rightSideBearing) - + FONTMINBOUNDS(pGC->font, leftSideBearing) > 32)) + BigFont = TRUE; + + /* no funny business */ + if((FONTMINBOUNDS(pGC->font, characterWidth) <= 0) || + ((FONTASCENT(pGC->font) + FONTDESCENT(pGC->font)) <= 0)) + return; + + /* Check for TE Fonts */ + if(!TERMINALFONT(pGC->font) || BigFont) { + if(infoRec->PolyGlyphBltNonTE && + CHECK_PLANEMASK(pGC,infoRec->PolyGlyphBltNonTEFlags) && + CHECK_ROP(pGC,infoRec->PolyGlyphBltNonTEFlags) && + CHECK_ROPSRC(pGC,infoRec->PolyGlyphBltNonTEFlags) && + CHECK_FG(pGC,infoRec->PolyGlyphBltNonTEFlags) && + (!(infoRec->PolyGlyphBltNonTEFlags & TRANSPARENCY_GXCOPY_ONLY) || + (pGC->alu == GXcopy)) + ) { + pGC->ops->PolyText8 = infoRec->PolyText8NonTE; + pGC->ops->PolyText16 = infoRec->PolyText16NonTE; + pGC->ops->PolyGlyphBlt = infoRec->PolyGlyphBltNonTE; + } + } else { + if(infoRec->PolyGlyphBltTE && + CHECK_PLANEMASK(pGC,infoRec->PolyGlyphBltTEFlags) && + CHECK_ROP(pGC,infoRec->PolyGlyphBltTEFlags) && + CHECK_ROPSRC(pGC,infoRec->PolyGlyphBltNonTEFlags) && + CHECK_FG(pGC,infoRec->PolyGlyphBltTEFlags) && + (!(infoRec->PolyGlyphBltTEFlags & TRANSPARENCY_GXCOPY_ONLY) || + (pGC->alu == GXcopy)) + ) { + pGC->ops->PolyText8 = infoRec->PolyText8TE; + pGC->ops->PolyText16 = infoRec->PolyText16TE; + pGC->ops->PolyGlyphBlt = infoRec->PolyGlyphBltTE; + } + } +} + +void +XAAValidateImageGlyphBlt( + GCPtr pGC, + unsigned long changes, + DrawablePtr pDraw ) +{ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); + Bool BigFont = FALSE; + + pGC->ops->ImageText8 = XAAFallbackOps.ImageText8; + pGC->ops->ImageText16 = XAAFallbackOps.ImageText16; + pGC->ops->ImageGlyphBlt = XAAFallbackOps.ImageGlyphBlt; + + if(!pGC->font) return; + + if((FONTMAXBOUNDS(pGC->font, rightSideBearing) - + FONTMINBOUNDS(pGC->font, leftSideBearing) > 32)) + BigFont = TRUE; + + /* no funny business */ + if((FONTMINBOUNDS(pGC->font, characterWidth) <= 0) || + ((FONTASCENT(pGC->font) + FONTDESCENT(pGC->font)) <= 0)) + return; + + + /* Check for TE Fonts */ + if(!TERMINALFONT(pGC->font) || BigFont || (pGC->depth == 32)) { + if(infoRec->ImageGlyphBltNonTE && + CHECK_PLANEMASK(pGC,infoRec->ImageGlyphBltNonTEFlags) && + CHECK_FG(pGC,infoRec->ImageGlyphBltNonTEFlags) && + infoRec->SetupForSolidFill && + CHECK_PLANEMASK(pGC,infoRec->SolidFillFlags) && + CHECK_BG(pGC,infoRec->SolidFillFlags)) + { + pGC->ops->ImageText8 = infoRec->ImageText8NonTE; + pGC->ops->ImageText16 = infoRec->ImageText16NonTE; + pGC->ops->ImageGlyphBlt = infoRec->ImageGlyphBltNonTE; + } + } else if(infoRec->ImageGlyphBltTE && + CHECK_PLANEMASK(pGC,infoRec->ImageGlyphBltTEFlags)){ + if(!(infoRec->ImageGlyphBltTEFlags & TRANSPARENCY_ONLY) && + CHECK_COLORS(pGC,infoRec->ImageGlyphBltTEFlags)) + { + pGC->ops->ImageText8 = infoRec->ImageText8TE; + pGC->ops->ImageText16 = infoRec->ImageText16TE; + pGC->ops->ImageGlyphBlt = infoRec->ImageGlyphBltTE; + } else { + if(CHECK_FG(pGC,infoRec->ImageGlyphBltTEFlags) && + infoRec->SetupForSolidFill && + CHECK_PLANEMASK(pGC,infoRec->SolidFillFlags) && + CHECK_BG(pGC,infoRec->SolidFillFlags)) + { + pGC->ops->ImageText8 = infoRec->ImageText8TE; + pGC->ops->ImageText16 = infoRec->ImageText16TE; + pGC->ops->ImageGlyphBlt = infoRec->ImageGlyphBltTE; + } + } + } +} + + +void +XAAValidatePolylines( + GCPtr pGC, + unsigned long changes, + DrawablePtr pDraw ) +{ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); + XAAGCPtr pGCPriv = (XAAGCPtr)dixLookupPrivate(&pGC->devPrivates, + XAAGetGCKey()); + + if(pGC->lineStyle == LineSolid) changes &= ~GCDashList; + if(!changes) return; + + pGC->ops->PolySegment = XAAFallbackOps.PolySegment; + pGC->ops->Polylines = XAAFallbackOps.Polylines; + pGC->ops->PolyRectangle = XAAFallbackOps.PolyRectangle; + pGC->ops->PolyArc = XAAFallbackOps.PolyArc; + + if((pGC->ops->FillSpans != XAAFallbackOps.FillSpans) && + (pGC->lineWidth > 0)){ + + pGC->ops->PolyArc = miPolyArc; + pGC->ops->PolySegment = miPolySegment; + pGC->ops->PolyRectangle = miPolyRectangle; + if(pGC->lineStyle == LineSolid) + pGC->ops->Polylines = miWideLine; + else + pGC->ops->Polylines = miWideDash; + } + + if((pGC->lineWidth == 0) && (pGC->fillStyle == FillSolid)) { + + if(pGC->lineStyle == LineSolid) { + + if(infoRec->PolyRectangleThinSolid && + CHECK_PLANEMASK(pGC,infoRec->PolyRectangleThinSolidFlags) && + CHECK_ROP(pGC,infoRec->PolyRectangleThinSolidFlags) && + CHECK_ROPSRC(pGC,infoRec->PolyRectangleThinSolidFlags) && + CHECK_FG(pGC,infoRec->PolyRectangleThinSolidFlags)) { + + pGC->ops->PolyRectangle = infoRec->PolyRectangleThinSolid; + } + + if(infoRec->PolySegmentThinSolid && + CHECK_PLANEMASK(pGC,infoRec->PolySegmentThinSolidFlags) && + CHECK_ROP(pGC,infoRec->PolySegmentThinSolidFlags) && + CHECK_ROPSRC(pGC,infoRec->PolySegmentThinSolidFlags) && + CHECK_FG(pGC,infoRec->PolySegmentThinSolidFlags)) { + + pGC->ops->PolySegment = infoRec->PolySegmentThinSolid; + } + + if(infoRec->PolylinesThinSolid && + CHECK_PLANEMASK(pGC,infoRec->PolylinesThinSolidFlags) && + CHECK_ROP(pGC,infoRec->PolylinesThinSolidFlags) && + CHECK_ROPSRC(pGC,infoRec->PolylinesThinSolidFlags) && + CHECK_FG(pGC,infoRec->PolylinesThinSolidFlags)) { + + pGC->ops->Polylines = infoRec->PolylinesThinSolid; + } + } else if((pGC->lineStyle == LineOnOffDash) && pGCPriv->DashPattern){ + + if(infoRec->PolySegmentThinDashed && + !(infoRec->PolySegmentThinDashedFlags & NO_TRANSPARENCY) && + ((pGC->alu == GXcopy) || !(infoRec->PolySegmentThinDashedFlags & + TRANSPARENCY_GXCOPY_ONLY)) && + CHECK_PLANEMASK(pGC,infoRec->PolySegmentThinDashedFlags) && + CHECK_ROP(pGC,infoRec->PolySegmentThinDashedFlags) && + CHECK_ROPSRC(pGC,infoRec->PolySegmentThinDashedFlags) && + CHECK_FG(pGC,infoRec->PolySegmentThinDashedFlags)) { + + pGC->ops->PolySegment = infoRec->PolySegmentThinDashed; + } + + if(infoRec->PolylinesThinDashed && + !(infoRec->PolylinesThinDashedFlags & NO_TRANSPARENCY) && + ((pGC->alu == GXcopy) || !(infoRec->PolylinesThinDashedFlags & + TRANSPARENCY_GXCOPY_ONLY)) && + CHECK_PLANEMASK(pGC,infoRec->PolylinesThinDashedFlags) && + CHECK_ROP(pGC,infoRec->PolylinesThinDashedFlags) && + CHECK_ROPSRC(pGC,infoRec->PolylinesThinDashedFlags) && + CHECK_FG(pGC,infoRec->PolylinesThinDashedFlags)) { + + pGC->ops->Polylines = infoRec->PolylinesThinDashed; + } + + if(pGC->ops->Polylines != XAAFallbackOps.Polylines) + pGC->ops->PolyRectangle = miPolyRectangle; + + } else if(pGCPriv->DashPattern && (pGC->depth != 32)) { + /* LineDoubleDash */ + if(infoRec->PolySegmentThinDashed && + !(infoRec->PolySegmentThinDashedFlags & TRANSPARENCY_ONLY) && + CHECK_PLANEMASK(pGC,infoRec->PolySegmentThinDashedFlags) && + CHECK_ROP(pGC,infoRec->PolySegmentThinDashedFlags) && + CHECK_ROPSRC(pGC,infoRec->PolySegmentThinDashedFlags) && + CHECK_COLORS(pGC,infoRec->PolySegmentThinDashedFlags)) { + + pGC->ops->PolySegment = infoRec->PolySegmentThinDashed; + } + + if(infoRec->PolylinesThinDashed && + !(infoRec->PolylinesThinDashedFlags & TRANSPARENCY_ONLY) && + CHECK_PLANEMASK(pGC,infoRec->PolylinesThinDashedFlags) && + CHECK_ROP(pGC,infoRec->PolylinesThinDashedFlags) && + CHECK_ROPSRC(pGC,infoRec->PolylinesThinDashedFlags) && + CHECK_COLORS(pGC,infoRec->PolylinesThinDashedFlags)) { + + pGC->ops->Polylines = infoRec->PolylinesThinDashed; + } + + if(pGC->ops->Polylines != XAAFallbackOps.Polylines) + pGC->ops->PolyRectangle = miPolyRectangle; + + } + } + + if(infoRec->PolylinesWideSolid && + (pGC->lineWidth > 0) && + (pGC->fillStyle == FillSolid) && + (pGC->lineStyle == LineSolid) && + CHECK_PLANEMASK(pGC,infoRec->PolylinesWideSolidFlags) && + CHECK_ROP(pGC,infoRec->PolylinesWideSolidFlags) && + CHECK_ROPSRC(pGC,infoRec->PolylinesWideSolidFlags) && + CHECK_FG(pGC,infoRec->PolylinesWideSolidFlags)) { + + pGC->ops->Polylines = infoRec->PolylinesWideSolid; + } +} |