#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include "Ps.h"
#include "gcstruct.h"
#include "pixmapstr.h"
#include "windowstr.h"
#include "migc.h"
#include "scrnintstr.h"
static GCOps PsGCOps =
{
PsFillSpans,
PsSetSpans,
PsPutImage,
PsCopyArea,
PsCopyPlane,
PsPolyPoint,
PsPolyLine,
PsPolySegment,
PsPolyRectangle,
PsPolyArc,
PsFillPolygon,
PsPolyFillRect,
PsPolyFillArc,
PsPolyText8,
PsPolyText16,
PsImageText8,
PsImageText16,
PsImageGlyphBlt,
PsPolyGlyphBlt,
PsPushPixels
};
static GCFuncs PsGCFuncs =
{
PsValidateGC,
PsChangeGC,
PsCopyGC,
PsDestroyGC,
PsChangeClip,
PsDestroyClip,
PsCopyClip
};
Bool
PsCreateGC(pGC)
GCPtr pGC;
{
pGC->clientClip = NULL;
pGC->clientClipType = CT_NONE;
pGC->ops = &PsGCOps;
pGC->funcs = &PsGCFuncs;
pGC->clientClip = (pointer)xalloc(sizeof(PsClipRec));
memset(pGC->clientClip, 0, sizeof(PsClipRec));
return TRUE;
}
static int
PsGetDrawablePrivateStuff(
DrawablePtr pDrawable,
GC *gc,
unsigned long *valid,
PsOutPtr *psOut,
ColormapPtr *cMap)
{
XpContextPtr pCon;
PsContextPrivPtr cPriv;
PsScreenPrivPtr sPriv;
switch(pDrawable->type)
{
case DRAWABLE_PIXMAP:
return FALSE;
case DRAWABLE_WINDOW:
pCon = PsGetContextFromWindow((WindowPtr)pDrawable);
if( pCon==NULL ) return FALSE;
else
{
Colormap c;
ColormapPtr cmap;
c = wColormap((WindowPtr)pDrawable);
cmap = (ColormapPtr)LookupIDByType(c, RT_COLORMAP);
cPriv = pCon->devPrivates[PsContextPrivateIndex].ptr;
sPriv = (PsScreenPrivPtr)
pDrawable->pScreen->devPrivates[PsScreenPrivateIndex].ptr;
*gc = cPriv->lastGC;
*valid = cPriv->validGC;
*psOut = cPriv->pPsOut;
*cMap = cmap;
return TRUE;
}
default:
return FALSE;
}
}
PsContextPrivPtr
PsGetPsContextPriv( DrawablePtr pDrawable )
{
XpContextPtr pCon;
switch(pDrawable->type)
{
case DRAWABLE_PIXMAP:
return FALSE;
case DRAWABLE_WINDOW:
pCon = PsGetContextFromWindow((WindowPtr)pDrawable);
if (pCon != NULL)
{
return pCon->devPrivates[PsContextPrivateIndex].ptr;
}
}
return NULL;
}
int
PsUpdateDrawableGC(
GCPtr pGC,
DrawablePtr pDrawable,
PsOutPtr *psOut,
ColormapPtr *cMap)
{
GC dGC;
unsigned long valid;
int i;
PsContextPrivPtr cPriv;
BoxPtr boxes;
if (!PsGetDrawablePrivateStuff(pDrawable, &dGC, &valid, psOut, cMap))
return FALSE;
switch (pDrawable->type) {
case DRAWABLE_PIXMAP:
return FALSE;
break;
case DRAWABLE_WINDOW:
if( pGC )
{
RegionPtr pReg;
WindowPtr pWin = (WindowPtr)pDrawable;
Bool freeClip;
PsClipPtr clp = (PsClipPtr)pGC->clientClip;
if( clp->outterClips )
{ xfree(clp->outterClips); clp->outterClips = 0; }
clp->nOutterClips = 0;
if( pGC->subWindowMode==IncludeInferiors )
{
pReg = NotClippedByChildren(pWin);
freeClip = TRUE;
}
else
{
pReg = &pWin->clipList;
freeClip = FALSE;
}
if( pReg->data )
{
boxes = (BoxPtr)((char *)pReg->data+sizeof(long)*2);
clp->nOutterClips = pReg->data->numRects;
clp->outterClips =
(PsRectPtr)xalloc(clp->nOutterClips*sizeof(PsRectRec));
for( i=0 ; i<clp->nOutterClips ; i++ )
{
clp->outterClips[i].x = boxes[i].x1;
clp->outterClips[i].y = boxes[i].y1;
clp->outterClips[i].w = (boxes[i].x2-boxes[i].x1)+1;
clp->outterClips[i].h = (boxes[i].y2-boxes[i].y1)+1;
}
}
if( freeClip ) REGION_DESTROY(pGC->pScreen, pReg);
PsOut_Offset(*psOut, pDrawable->x, pDrawable->y);
PsOut_Clip(*psOut, pGC->clientClipType, (PsClipPtr)pGC->clientClip);
}
cPriv = ( PsGetContextFromWindow( (WindowPtr)pDrawable ) )
->devPrivates[PsContextPrivateIndex].ptr;
break;
}
return TRUE;
}
void
PsValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
{
pGC->ops = &PsGCOps;
}
void
PsChangeGC(GCPtr pGC, unsigned long changes)
{
}
void
PsCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst)
{
}
void
PsDestroyGC(GCPtr pGC)
{
PsDestroyClip(pGC);
xfree(pGC->clientClip);
}
void
PsChangeClip(GCPtr pGC, int type, pointer pValue, int nrects)
{
int i;
PsClipPtr clp = (PsClipPtr)pGC->clientClip;
RegionPtr rgn;
BoxPtr boxes;
xRectangle *rects;
PsDestroyClip(pGC);
pGC->clientClipType = type;
switch(type)
{
case CT_NONE: break;
case CT_PIXMAP:
clp->elms = PsCreateFillElementList((PixmapPtr)pValue, &clp->nElms);
(*pGC->pScreen->DestroyPixmap)((PixmapPtr)pValue);
break;
case CT_REGION:
rgn = (RegionPtr)pValue;
boxes = (BoxPtr)((char *)rgn->data+sizeof(long)*2);
clp->nRects = rgn->data->numRects;
clp->rects = (PsRectPtr)xalloc(clp->nRects*sizeof(PsRectRec));
for( i=0 ; i<clp->nRects ; i++ )
{
clp->rects[i].x = boxes[i].x1;
clp->rects[i].y = boxes[i].y1;
clp->rects[i].w = (boxes[i].x2-boxes[i].x1)+1;
clp->rects[i].h = (boxes[i].y2-boxes[i].y1)+1;
}
REGION_DESTROY(pGC->pScreen, (RegionPtr)pValue);
break;
case CT_UNSORTED:
case CT_YSORTED:
case CT_YXSORTED:
case CT_YXBANDED:
rects = (xRectangle *)pValue;
clp->nRects = nrects;
clp->rects = (PsRectPtr)xalloc(clp->nRects*sizeof(PsRectRec));
for( i=0 ; i<clp->nRects ; i++ )
{
clp->rects[i].x = rects[i].x;
clp->rects[i].y = rects[i].y;
clp->rects[i].w = rects[i].width;
clp->rects[i].h = rects[i].height;
}
xfree(pValue);
break;
}
}
void
PsDestroyClip(GCPtr pGC)
{
PsClipPtr clp = (PsClipPtr)pGC->clientClip;
if( clp->rects ) xfree(clp->rects);
if( clp->outterClips ) xfree(clp->outterClips);
clp->rects = (PsRectPtr)0;
clp->outterClips = (PsRectPtr)0;
clp->nRects = 0;
clp->nOutterClips = 0;
if( clp->elms ) PsDestroyFillElementList(clp->nElms, clp->elms);
clp->elms = (PsElmPtr)0;
clp->nElms = 0;
pGC->clientClipType = CT_NONE;
}
void
PsCopyClip(GCPtr pDst, GCPtr pSrc)
{
PsClipPtr src = (PsClipPtr)pSrc->clientClip;
PsClipPtr dst = (PsClipPtr)pDst->clientClip;
PsDestroyClip(pDst);
pDst->clientClipType = pSrc->clientClipType;
*dst = *src;
if( src->rects )
{
dst->rects = (PsRectPtr)xalloc(src->nRects*sizeof(PsRectRec));
memcpy(dst->rects, src->rects, src->nRects*sizeof(PsRectRec));
}
if( src->elms )
dst->elms = PsCloneFillElementList(src->nElms, src->elms);
}
GCPtr
PsCreateAndCopyGC(DrawablePtr pDrawable, GCPtr pSrc)
{
GCPtr pDst;
if (pSrc == NULL) {
fprintf(stderr, "PsCreateAndCopyGC: pSrc == NULL\n");
return NULL;
}
if ((pDst =
CreateScratchGC(pDrawable->pScreen, pDrawable->depth)) == NULL)
{
return NULL;
}
if (CopyGC(pSrc, pDst,
GCFunction | GCPlaneMask | GCForeground | GCBackground |
GCLineWidth | GCLineStyle | GCCapStyle | GCJoinStyle |
GCFillStyle | GCFillRule | GCTile | GCStipple |
GCTileStipXOrigin | GCTileStipYOrigin | GCFont |
GCSubwindowMode | GCGraphicsExposures | GCClipXOrigin |
GCClipYOrigin | GCClipMask | GCDashOffset | GCDashList |
GCArcMode) != Success)
{
(void)FreeGC(pDst, (GContext)0);
return NULL;
}
return pDst;
}