#ifdef HAVE_XORG_CONFIG_H
#include <xorg-config.h>
#endif
#include <stdlib.h>
#include "xf4bpp.h"
#include "mfbmap.h"
#include "mfb.h"
#include "mi.h"
#include "scrnintstr.h"
#include "ppcGCstr.h"
#include "vgaVideo.h"
#include "ibmTrace.h"
#define ppcGCInterestValidateMask \
( GCLineStyle | GCLineWidth | GCJoinStyle | GCBackground | GCForeground \
| GCFunction | GCPlaneMask | GCFillStyle | GC_CALL_VALIDATE_BIT \
| GCClipXOrigin | GCClipYOrigin | GCClipMask | GCSubwindowMode )
static void xf4bppValidateGC(GCPtr, unsigned long, DrawablePtr);
static void xf4bppDestroyGC(GC *);
static GCFuncs vgaGCFuncs = {
xf4bppValidateGC,
(void (*)(GCPtr, unsigned long))NoopDDA,
(void (*)(GCPtr, unsigned long, GCPtr))NoopDDA,
xf4bppDestroyGC,
xf4bppChangeClip,
xf4bppDestroyClip,
xf4bppCopyClip,
{ NULL }
};
static ppcPrivGC vgaPrototypeGCPriv = {
GXcopy,
0,
0,
{0, },
NULL,
{
VGA_ALLPLANES,
1,
0,
GXcopy,
FillSolid,
},
-1,
-1,
0
} ;
static GCOps vgaGCOps = {
xf4bppSolidWindowFS,
xf4bppSetSpans,
miPutImage,
xf4bppCopyArea,
miCopyPlane,
xf4bppPolyPoint,
miZeroLine,
miPolySegment,
miPolyRectangle,
xf4bppZeroPolyArc,
miFillPolygon,
miPolyFillRect,
xf4bppPolyFillArc,
miPolyText8,
miPolyText16,
miImageText8,
miImageText16,
xf4bppImageGlyphBlt,
miPolyGlyphBlt,
miPushPixels,
{NULL}
};
Bool
xf4bppCreateGC( pGC )
register GCPtr pGC ;
{
ppcPrivGC *pPriv ;
GCOps *pOps ;
if ( pGC->depth == 1 )
{
return (mfbCreateGC(pGC));
}
if ( !( pPriv = xalloc( sizeof( ppcPrivGC ) ) ) )
return FALSE ;
if ( !( pOps = xalloc( sizeof( GCOps ) ) ) ) {
xfree(pPriv);
return FALSE;
}
pGC->miTranslate = 1;
pGC->unused = 0;
pGC->planemask = VGA_ALLPLANES;
pGC->fgPixel = VGA_BLACK_PIXEL;
pGC->bgPixel = VGA_WHITE_PIXEL;
pGC->funcs = &vgaGCFuncs;
pGC->fExpose = TRUE;
pGC->freeCompClip = FALSE;
pGC->pRotatedPixmap = NullPixmap;
*pPriv = vgaPrototypeGCPriv;
(pGC->devPrivates[mfbGetGCPrivateIndex()].ptr) = (pointer) pPriv;
*pOps = vgaGCOps;
pOps->devPrivate.val = 1;
pGC->ops = pOps;
return TRUE ;
}
static void
xf4bppDestroyGC( pGC )
register GC *pGC ;
{
TRACE( ( "xf4bppDestroyGC(pGC=0x%x)\n", pGC ) ) ;
if ( pGC->pRotatedPixmap )
mfbDestroyPixmap( pGC->pRotatedPixmap ) ;
if ( pGC->freeCompClip && pGC->pCompositeClip )
REGION_DESTROY(pGC->pScreen, pGC->pCompositeClip);
if(pGC->ops->devPrivate.val) xfree( pGC->ops );
xfree( pGC->devPrivates[mfbGetGCPrivateIndex()].ptr ) ;
return ;
}
static Mask
ppcChangePixmapGC
(
register GC *pGC,
register Mask changes
)
{
register ppcPrivGCPtr devPriv = (ppcPrivGCPtr) (pGC->devPrivates[mfbGetGCPrivateIndex()].ptr ) ;
register unsigned long int idx ;
#define LOWBIT( x ) ( x & - x )
while ((idx = LOWBIT(changes))) {
switch ( idx ) {
case GCLineStyle:
case GCLineWidth:
pGC->ops->Polylines = ( ! pGC->lineWidth )
? miZeroLine
: ( ( pGC->lineStyle == LineSolid )
? miWideLine : miWideDash ) ;
changes &= ~( GCLineStyle | GCLineWidth ) ;
break ;
case GCJoinStyle:
changes &= ~ idx ;
break ;
case GCBackground:
if ( pGC->fillStyle != FillOpaqueStippled ) {
changes &= ~ idx ;
break ;
}
case GCForeground:
if ( pGC->fillStyle == FillTiled ) {
changes &= ~ idx ;
break ;
}
case GCFunction:
case GCPlaneMask:
case GCFillStyle:
{
int fillStyle = devPriv->colorRrop.fillStyle ;
if ( fillStyle == FillSolid )
pGC->ops->FillSpans = xf4bppSolidPixmapFS ;
else if ( fillStyle == FillStippled )
pGC->ops->FillSpans = xf4bppStipplePixmapFS ;
else if ( fillStyle == FillOpaqueStippled )
pGC->ops->FillSpans = xf4bppOpStipplePixmapFS ;
else
pGC->ops->FillSpans = xf4bppTilePixmapFS ;
changes &= ~( GCBackground | GCForeground
| GCFunction | GCPlaneMask | GCFillStyle ) ;
break ;
}
default:
ErrorF( "ppcChangePixmapGC: Unexpected GC Change\n" ) ;
changes &= ~ idx ;
break ;
}
}
return 0 ;
}
static void
xf4bppValidateGC( pGC, changes, pDrawable )
GCPtr pGC;
unsigned long changes;
DrawablePtr pDrawable;
{
register ppcPrivGCPtr devPriv ;
WindowPtr pWin ;
devPriv = (ppcPrivGCPtr) (pGC->devPrivates[mfbGetGCPrivateIndex()].ptr ) ;
if ( pDrawable->type != devPriv->lastDrawableType ) {
devPriv->lastDrawableType = pDrawable->type ;
xf4bppChangeGCtype( pGC, devPriv ) ;
changes = (unsigned)~0 ;
}
if ( pDrawable->depth == 1 ) {
xf4bppNeverCalled();
}
if ( pDrawable->type == DRAWABLE_WINDOW ) {
pWin = (WindowPtr) pDrawable ;
pGC->lastWinOrg.x = pWin->drawable.x ;
pGC->lastWinOrg.y = pWin->drawable.y ;
}
else {
pWin = (WindowPtr) NULL ;
pGC->lastWinOrg.x = 0 ;
pGC->lastWinOrg.y = 0 ;
}
changes &= ppcGCInterestValidateMask ;
if ( pDrawable->serialNumber == (pGC->serialNumber & DRAWABLE_SERIAL_BITS) )
if ( !( changes &= ~ GC_CALL_VALIDATE_BIT ) )
return ;
if ((changes & (GCClipXOrigin|GCClipYOrigin|GCClipMask|GCSubwindowMode)) ||
(pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS))
)
{
if (pWin) {
RegionPtr pregWin;
Bool freeTmpClip, freeCompClip;
if (pGC->subWindowMode == IncludeInferiors) {
pregWin = NotClippedByChildren(pWin);
freeTmpClip = TRUE;
}
else {
pregWin = &pWin->clipList;
freeTmpClip = FALSE;
}
freeCompClip = pGC->freeCompClip;
if (pGC->clientClipType == CT_NONE) {
if (freeCompClip)
REGION_DESTROY(pGC->pScreen, pGC->pCompositeClip);
pGC->pCompositeClip = pregWin;
pGC->freeCompClip = freeTmpClip;
}
else {
REGION_TRANSLATE(pGC->pScreen, pGC->clientClip,
pDrawable->x + pGC->clipOrg.x,
pDrawable->y + pGC->clipOrg.y);
if (freeCompClip)
{
REGION_INTERSECT(pGC->pScreen, pGC->pCompositeClip,
pregWin, pGC->clientClip);
if (freeTmpClip)
REGION_DESTROY(pGC->pScreen, pregWin);
}
else if (freeTmpClip)
{
REGION_INTERSECT(pGC->pScreen, pregWin, pregWin,
pGC->clientClip);
pGC->pCompositeClip = pregWin;
}
else
{
pGC->pCompositeClip = REGION_CREATE(pGC->pScreen, NullBox, 0);
REGION_INTERSECT(pGC->pScreen, pGC->pCompositeClip,
pregWin, pGC->clientClip);
}
pGC->freeCompClip = TRUE;
REGION_TRANSLATE(pGC->pScreen, pGC->clientClip,
-(pDrawable->x + pGC->clipOrg.x),
-(pDrawable->y + pGC->clipOrg.y));
}
}
else {
BoxRec pixbounds;
pixbounds.x1 = 0;
pixbounds.y1 = 0;
pixbounds.x2 = pDrawable->width;
pixbounds.y2 = pDrawable->height;
if (pGC->freeCompClip) {
REGION_RESET(pGC->pScreen, pGC->pCompositeClip, &pixbounds);
} else {
pGC->freeCompClip = TRUE;
pGC->pCompositeClip = REGION_CREATE(pGC->pScreen, &pixbounds, 1);
}
if (pGC->clientClipType == CT_REGION)
{
REGION_TRANSLATE(pGC->pScreen, pGC->pCompositeClip,
-pGC->clipOrg.x, -pGC->clipOrg.y);
REGION_INTERSECT(pGC->pScreen, pGC->pCompositeClip,
pGC->pCompositeClip, pGC->clientClip);
REGION_TRANSLATE(pGC->pScreen, pGC->pCompositeClip,
pGC->clipOrg.x, pGC->clipOrg.y);
}
}
}
changes &= ~ ( GCClipXOrigin | GCClipYOrigin | GCClipMask | GCSubwindowMode
| GC_CALL_VALIDATE_BIT ) ;
if ( changes & ( GCFillStyle | GCBackground | GCForeground
| GCPlaneMask | GCFunction ) )
xf4bppGetReducedColorRrop( pGC, pDrawable->depth,
&devPriv->colorRrop ) ;
(* ( ( pDrawable->type == DRAWABLE_WINDOW )
? xf4bppChangeWindowGC
: ppcChangePixmapGC ) )( pGC, changes ) ;
return ;
}