4017d31902
over to new system. Need to update documentation and address some remaining vestiges of old system such as CursorRec structure, fb "offman" structure, and FontRec privates.
430 lines
13 KiB
C
430 lines
13 KiB
C
|
|
#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;
|
|
}
|
|
}
|