#ifdef HAVE_DMX_CONFIG_H
#include <dmx-config.h>
#endif
#include "dmx.h"
#include "dmxsync.h"
#include "dmxgc.h"
#include "dmxgcops.h"
#include "dmxpixmap.h"
#include "dmxfont.h"
#include "gcstruct.h"
#include "pixmapstr.h"
#include "migc.h"
static GCFuncs dmxGCFuncs = {
dmxValidateGC,
dmxChangeGC,
dmxCopyGC,
dmxDestroyGC,
dmxChangeClip,
dmxDestroyClip,
dmxCopyClip,
};
static GCOps dmxGCOps = {
dmxFillSpans,
dmxSetSpans,
dmxPutImage,
dmxCopyArea,
dmxCopyPlane,
dmxPolyPoint,
dmxPolylines,
dmxPolySegment,
dmxPolyRectangle,
dmxPolyArc,
dmxFillPolygon,
dmxPolyFillRect,
dmxPolyFillArc,
dmxPolyText8,
dmxPolyText16,
dmxImageText8,
dmxImageText16,
dmxImageGlyphBlt,
dmxPolyGlyphBlt,
dmxPushPixels
};
Bool dmxInitGC(ScreenPtr pScreen)
{
if (!dixRegisterPrivateKey(&dmxGCPrivateKeyRec, PRIVATE_GC, sizeof(dmxGCPrivRec)))
return FALSE;
return TRUE;
}
void dmxBECreateGC(ScreenPtr pScreen, GCPtr pGC)
{
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
int i;
for (i = 0; i < dmxScreen->beNumPixmapFormats; i++) {
if (pGC->depth == dmxScreen->bePixmapFormats[i].depth) {
unsigned long mask;
XGCValues gcvals;
mask = GCGraphicsExposures;
gcvals.graphics_exposures = FALSE;
pGCPriv->gc = XCreateGC(dmxScreen->beDisplay,
dmxScreen->scrnDefDrawables[i],
mask, &gcvals);
break;
}
}
}
Bool dmxCreateGC(GCPtr pGC)
{
ScreenPtr pScreen = pGC->pScreen;
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
Bool ret;
DMX_UNWRAP(CreateGC, dmxScreen, pScreen);
if ((ret = pScreen->CreateGC(pGC))) {
pGCPriv->funcs = pGC->funcs;
pGCPriv->ops = NULL;
pGC->funcs = &dmxGCFuncs;
if (dmxScreen->beDisplay) {
dmxBECreateGC(pScreen, pGC);
} else {
pGCPriv->gc = NULL;
}
pGCPriv->msc = (!pGC->tileIsPixel && !pGC->tile.pixmap);
}
DMX_WRAP(CreateGC, dmxCreateGC, dmxScreen, pScreen);
return ret;
}
void dmxValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
{
dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
DMX_GC_FUNC_PROLOGUE(pGC);
#if 0
pGC->funcs->ValidateGC(pGC, changes, pDrawable);
#endif
if (pDrawable->type == DRAWABLE_WINDOW ||
pDrawable->type == DRAWABLE_PIXMAP) {
pGCPriv->ops = pGC->ops;
} else {
pGCPriv->ops = NULL;
}
if ((changes & (GCClipXOrigin |
GCClipYOrigin |
GCClipMask |
GCSubwindowMode)) ||
(pDrawable->serialNumber !=
(pGC->serialNumber & DRAWABLE_SERIAL_BITS))) {
miComputeCompositeClip(pGC, pDrawable);
}
DMX_GC_FUNC_EPILOGUE(pGC);
}
void dmxChangeGC(GCPtr pGC, unsigned long mask)
{
ScreenPtr pScreen = pGC->pScreen;
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
XGCValues v;
DMX_GC_FUNC_PROLOGUE(pGC);
#if 0
pGC->funcs->ChangeGC(pGC, mask);
#endif
if (pGCPriv->msc) {
if (pGC->tile.pixmap) mask |= GCTile;
pGCPriv->msc = FALSE;
}
if (mask & GCFunction) v.function = pGC->alu;
if (mask & GCPlaneMask) v.plane_mask = pGC->planemask;
if (mask & GCForeground) v.foreground = pGC->fgPixel;
if (mask & GCBackground) v.background = pGC->bgPixel;
if (mask & GCLineWidth) v.line_width = pGC->lineWidth;
if (mask & GCLineStyle) v.line_style = pGC->lineStyle;
if (mask & GCCapStyle) v.cap_style = pGC->capStyle;
if (mask & GCJoinStyle) v.join_style = pGC->joinStyle;
if (mask & GCFillStyle) v.fill_style = pGC->fillStyle;
if (mask & GCFillRule) v.fill_rule = pGC->fillRule;
if (mask & GCTile) {
if (pGC->tileIsPixel) {
mask &= ~GCTile;
} else {
dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pGC->tile.pixmap);
v.tile = (Drawable)pPixPriv->pixmap;
}
}
if (mask & GCStipple) {
dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pGC->stipple);
v.stipple = (Drawable)pPixPriv->pixmap;
}
if (mask & GCTileStipXOrigin) v.ts_x_origin = pGC->patOrg.x;
if (mask & GCTileStipYOrigin) v.ts_y_origin = pGC->patOrg.y;
if (mask & GCFont) {
if (dmxScreen->beDisplay) {
dmxFontPrivPtr pFontPriv;
pFontPriv = FontGetPrivate(pGC->font, dmxFontPrivateIndex);
v.font = pFontPriv->font[pScreen->myNum]->fid;
} else {
mask &= ~GCFont;
}
}
if (mask & GCSubwindowMode) v.subwindow_mode = pGC->subWindowMode;
if (mask & GCGraphicsExposures) mask &= ~GCGraphicsExposures;
if (mask & GCClipXOrigin) v.clip_x_origin = pGC->clipOrg.x;
if (mask & GCClipYOrigin) v.clip_y_origin = pGC->clipOrg.y;
if (mask & GCClipMask) mask &= ~GCClipMask;
if (mask & GCDashOffset) v.dash_offset = pGC->dashOffset;
if (mask & GCDashList) {
mask &= ~GCDashList;
if (dmxScreen->beDisplay)
XSetDashes(dmxScreen->beDisplay, pGCPriv->gc,
pGC->dashOffset, (char *)pGC->dash,
pGC->numInDashList);
}
if (mask & GCArcMode) v.arc_mode = pGC->arcMode;
if (mask && dmxScreen->beDisplay) {
XChangeGC(dmxScreen->beDisplay, pGCPriv->gc, mask, &v);
dmxSync(dmxScreen, FALSE);
}
DMX_GC_FUNC_EPILOGUE(pGC);
}
void dmxCopyGC(GCPtr pGCSrc, unsigned long changes, GCPtr pGCDst)
{
ScreenPtr pScreen = pGCSrc->pScreen;
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
dmxGCPrivPtr pGCSrcPriv = DMX_GET_GC_PRIV(pGCSrc);
dmxGCPrivPtr pGCDstPriv = DMX_GET_GC_PRIV(pGCDst);
DMX_GC_FUNC_PROLOGUE(pGCDst);
pGCDst->funcs->CopyGC(pGCSrc, changes, pGCDst);
if (dmxScreen->beDisplay)
XCopyGC(dmxScreen->beDisplay, pGCSrcPriv->gc, changes, pGCDstPriv->gc);
DMX_GC_FUNC_EPILOGUE(pGCDst);
}
Bool dmxBEFreeGC(GCPtr pGC)
{
ScreenPtr pScreen = pGC->pScreen;
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
if (pGCPriv->gc) {
XFreeGC(dmxScreen->beDisplay, pGCPriv->gc);
pGCPriv->gc = NULL;
return TRUE;
}
return FALSE;
}
void dmxDestroyGC(GCPtr pGC)
{
ScreenPtr pScreen = pGC->pScreen;
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
DMX_GC_FUNC_PROLOGUE(pGC);
if (dmxScreen->beDisplay)
dmxBEFreeGC(pGC);
pGC->funcs->DestroyGC(pGC);
DMX_GC_FUNC_EPILOGUE(pGC);
}
void dmxChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects)
{
ScreenPtr pScreen = pGC->pScreen;
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
XRectangle *pRects;
BoxPtr pBox;
int i, nRects;
DMX_GC_FUNC_PROLOGUE(pGC);
pGC->funcs->ChangeClip(pGC, type, pvalue, nrects);
switch (pGC->clientClipType) {
case CT_NONE:
if (dmxScreen->beDisplay)
XSetClipMask(dmxScreen->beDisplay, pGCPriv->gc, None);
break;
case CT_REGION:
if (dmxScreen->beDisplay) {
nRects = RegionNumRects((RegionPtr)pGC->clientClip);
pRects = malloc(nRects * sizeof(*pRects));
pBox = RegionRects((RegionPtr)pGC->clientClip);
for (i = 0; i < nRects; i++) {
pRects[i].x = pBox[i].x1;
pRects[i].y = pBox[i].y1;
pRects[i].width = pBox[i].x2 - pBox[i].x1;
pRects[i].height = pBox[i].y2 - pBox[i].y1;
}
XSetClipRectangles(dmxScreen->beDisplay, pGCPriv->gc,
pGC->clipOrg.x, pGC->clipOrg.y,
pRects, nRects, Unsorted);
free(pRects);
}
break;
case CT_PIXMAP:
break;
}
DMX_GC_FUNC_EPILOGUE(pGC);
}
void dmxDestroyClip(GCPtr pGC)
{
ScreenPtr pScreen = pGC->pScreen;
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
DMX_GC_FUNC_PROLOGUE(pGC);
pGC->funcs->DestroyClip(pGC);
if (dmxScreen->beDisplay)
XSetClipMask(dmxScreen->beDisplay, pGCPriv->gc, None);
DMX_GC_FUNC_EPILOGUE(pGC);
}
void dmxCopyClip(GCPtr pGCDst, GCPtr pGCSrc)
{
DMX_GC_FUNC_PROLOGUE(pGCDst);
pGCDst->funcs->CopyClip(pGCDst, pGCSrc);
DMX_GC_FUNC_EPILOGUE(pGCDst);
}