#ifdef HAVE_DIX_CONFIG_H #include #endif #include #include #include "scrnintstr.h" #include "colormapst.h" #include "glyphstr.h" #include "resource.h" #include #include "dixfontstr.h" #include #include "micmap.h" #include "fb.h" #include "fbpseudocolor.h" static Bool xxCreateGC(GCPtr pGC); static void xxValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDraw); static void xxDestroyGC(GCPtr pGC); static void xxChangeGC (GCPtr pGC, unsigned long mask); static void xxCopyGC (GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst); static void xxChangeClip (GCPtr pGC, int type, void * pvalue, int nrects); static void xxCopyClip(GCPtr pgcDst, GCPtr pgcSrc); static void xxDestroyClip(GCPtr pGC); static void xxFillSpans(DrawablePtr pDraw, GC *pGC, int nInit, DDXPointPtr pptInit, int *pwidthInit, int fSorted); static void xxSetSpans(DrawablePtr pDraw, GCPtr pGC, char *pcharsrc, DDXPointPtr pptInit, int *pwidthInit, int nspans, int fSorted); static void xxPutImage(DrawablePtr pDraw, GCPtr pGC, int depth, int x, int y, int w, int h,int leftPad, int format, char *pImage); static RegionPtr xxCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,int srcx, int srcy, int width, int height, int dstx, int dsty, unsigned long bitPlane); static void xxPolyPoint(DrawablePtr pDraw, GCPtr pGC, int mode, int npt, xPoint *pptInit); static void xxPolylines(DrawablePtr pDraw, GCPtr pGC, int mode, int npt, DDXPointPtr pptInit); static void xxPolySegment(DrawablePtr pDraw, GCPtr pGC, int nseg, xSegment *pSeg); static void xxPolyRectangle(DrawablePtr pDraw, GCPtr pGC, int nRects, xRectangle *pRects); static void xxPolyArc( DrawablePtr pDraw, GCPtr pGC, int narcs, xArc *parcs); static void xxFillPolygon(DrawablePtr pDraw, GCPtr pGC, int shape, int mode, int count, DDXPointPtr pptInit); static void xxPolyFillRect(DrawablePtr pDraw, GCPtr pGC, int nRectsInit, xRectangle *pRectsInit); static RegionPtr xxCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GC *pGC, int srcx, int srcy, int width, int height, int dstx, int dsty); static void xxPolyFillArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc *parcs); static int xxPolyText8(DrawablePtr pDraw, GCPtr pGC, int x, int y, int count, char *chars); static int xxPolyText16(DrawablePtr pDraw, GCPtr pGC, int x, int y, int count, unsigned short *chars); static void xxImageText8(DrawablePtr pDraw, GCPtr pGC, int x, int y, int count, char *chars); static void xxImageText16(DrawablePtr pDraw, GCPtr pGC, int x, int y, int count, unsigned short *chars); static void xxImageGlyphBlt(DrawablePtr pDraw, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr *ppci, void * pglyphBase); static void xxPolyGlyphBlt(DrawablePtr pDraw, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr *ppci, void * pglyphBase); static void xxPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDraw, int dx, int dy, int xOrg, int yOrg); static void xxComposite (CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height); static void xxGlyphs (CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr *glyphs); typedef struct _xxCmapPrivRec { CARD32* cmap; ColormapPtr pmap; Bool dirty; struct _xxCmapPrivRec *next; } xxCmapPrivRec, *xxCmapPrivPtr; typedef struct { CloseScreenProcPtr CloseScreen; CreateScreenResourcesProcPtr CreateScreenResources; CreateWindowProcPtr CreateWindow; CopyWindowProcPtr CopyWindow; PaintWindowProcPtr PaintWindowBackground; PaintWindowProcPtr PaintWindowBorder; WindowExposuresProcPtr WindowExposures; CreateGCProcPtr CreateGC; CreateColormapProcPtr CreateColormap; DestroyColormapProcPtr DestroyColormap; InstallColormapProcPtr InstallColormap; UninstallColormapProcPtr UninstallColormap; ListInstalledColormapsProcPtr ListInstalledColormaps; StoreColorsProcPtr StoreColors; #ifdef RENDER CompositeProcPtr Composite; GlyphsProcPtr Glyphs; #endif PixmapPtr pPixmap; char * addr; void *pBits; RegionRec region; VisualPtr bVisual; RegionRec bRegion; int myDepth; int depth; ColormapPtr baseCmap; ColormapPtr* InstalledCmaps; xxCmapPrivPtr Cmaps; int numInstalledColormaps; int colormapDirty; xxSyncFunc sync; } xxScrPrivRec, *xxScrPrivPtr; #define xxGetScrPriv(s) ((xxScrPrivPtr) \ (xxScrPrivateIndex != -1) \ ? (s)->devPrivates[xxScrPrivateIndex].ptr\ : NULL) #define xxScrPriv(s) xxScrPrivPtr pScrPriv = xxGetScrPriv(s) #define xxGetCmapPriv(s) ((xxCmapPrivPtr) \ (s)->devPrivates[xxColormapPrivateIndex].ptr) #define xxCmapPriv(s) xxCmapPrivPtr pCmapPriv = xxGetCmapPriv(s); typedef struct _xxGCPriv { GCOps *ops; GCFuncs *funcs; } xxGCPrivRec, *xxGCPrivPtr; #define xxGetGCPriv(pGC) ((xxGCPrivPtr) \ (pGC)->devPrivates[xxGCPrivateIndex].ptr) #define xxGCPriv(pGC) xxGCPrivPtr pGCPriv = xxGetGCPriv(pGC) int xxScrPrivateIndex = -1; int xxGCPrivateIndex; int xxColormapPrivateIndex = -1; int xxGeneration; #define wrap(priv,real,mem,func) {\ priv->mem = real->mem; \ real->mem = func; \ } #define unwrap(priv,real,mem) {\ real->mem = priv->mem; \ } #define MARK_DIRTY (1 << 31) #define MAX_NUM_XX_INSTALLED_CMAPS 255 /* #define DEBUG */ #ifdef DEBUG # define DBG ErrorF # define DBG_ARGS(x) ErrorF x # define PRINT_RECTS(rec) {\ int i;\ BoxPtr box;\ ErrorF("RECTS: %i\n",RegionNumRects(&rec));\ if (RegionNumRects(&rec) > 1) { \ for (i = 0; i < RegionNumRects(&rec); i++ ) {\ box = RegionBox(&rec,i);\ ErrorF("x1: %hi x2: %hi y1: %hi y2: %hi\n", \ box->x1,box->x2,box->y1,box->y2);\ }\ } else { \ box = &(rec.extents); \ ErrorF("x1: %hi x2: %hi y1: %hi y2: %hi\n", \ box->x1,box->x2,box->y1,box->y2);\ } \ } #else # define DBG(x) # define DBG_ARGS(x) # define PRINT_RECTS(rec) #endif #if 0 static void xxCopyPseudocolorRegion(ScreenPtr pScreen, RegionPtr pReg, xxCmapPrivPtr pCmapPriv); static void xxUpdateFb(ScreenPtr pScreen); static void xxUpdateWindowImmediately(WindowPtr pWin) { xxScrPriv(pWin->drawable.pScreen); xxCmapPrivPtr pCmapPriv; ColormapPtr pmap; pmap = (ColormapPtr)LookupIDByType(wColormap(pWin),RT_COLORMAP); if (pmap && (pCmapPriv = xxGetCmapPriv(pmap)) != (void *)-1) { xxCopyPseudocolorRegion(pWin->drawable.pScreen, &pScrPriv->region, pCmapPriv); } } #else # define xxUpdateWindowImmediately(x) #endif static ColormapPtr xxGetBaseColormap(ScreenPtr pScreen) { xxScrPriv(pScreen); DepthPtr pDepth = pScreen->allowedDepths; int i,j,k; ColormapPtr pDefMap = (ColormapPtr) LookupIDByType(pScreen->defColormap,RT_COLORMAP); ColormapPtr cmap = NULL; VisualPtr pVisual = NULL; for (i = 0; i < pScreen->numDepths; i++, pDepth++) if (pDepth->depth == pScrPriv->depth) { for (j = 0; j < pDepth->numVids; j++) { if (pDefMap->pVisual->vid == pDepth->vids[j] && pDefMap->pVisual->class == TrueColor) { cmap = pDefMap; break; } if (!pVisual) { for (k = 0; k < pScreen->numVisuals; k++) { if (pScreen->visuals[k].class == TrueColor && pScreen->visuals[k].vid == pDepth->vids[j]) { pVisual = &pScreen->visuals[k]; break; } } } } if (cmap) break; } if (!cmap) { CreateColormap(FakeClientID(0),pScreen,pVisual,&cmap,AllocNone,0); } return cmap; } static Bool xxCreateScreenResources(ScreenPtr pScreen) { PixmapPtr pPix; xxScrPriv(pScreen); Bool ret; PixmapPtr pPixmap; BoxRec box; int depth = pScrPriv->myDepth; void *pBits; unwrap (pScrPriv,pScreen, CreateScreenResources); ret = pScreen->CreateScreenResources(pScreen); wrap(pScrPriv,pScreen,CreateScreenResources,xxCreateScreenResources); if (!ret) return FALSE; pScrPriv->pBits = NULL; if (pScrPriv->addr) pBits = pScrPriv->addr; else pBits = xalloc(pScreen->width * pScreen->height * (BitsPerPixel(depth) >> 3)); if (!pBits) return FALSE; pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, depth); if (!pPixmap) { xfree(pBits); return FALSE; } if (!(*pScreen->ModifyPixmapHeader)(pPixmap, pScreen->width, pScreen->height, depth, BitsPerPixel(depth), PixmapBytePad(pScreen->width, depth), pBits)) { xfree(pBits); return FALSE; } if (pScreen->rootDepth == pScrPriv->myDepth) { pPix = (PixmapPtr)pScreen->devPrivate; if (!(*pScreen->ModifyPixmapHeader)(pPix, 0,0, pScrPriv->depth, BitsPerPixel(pScrPriv->depth), PixmapBytePad(pScreen->width, pScrPriv->depth), 0)) { xfree(pBits); return FALSE; } } pScrPriv->baseCmap = xxGetBaseColormap(pScreen); pScrPriv->pBits = pBits; pScrPriv->pPixmap = pPixmap; box.x1 = 0; box.y1 = 0; box.x2 = pScreen->width; box.y2 = pScreen->height; RegionNull(&pScrPriv->region); RegionInit(&pScrPriv->bRegion, &box, 0); return TRUE; } static Bool xxCloseScreen (int iScreen, ScreenPtr pScreen) { xxScrPriv(pScreen); Bool ret; (*pScreen->DestroyPixmap)(pScrPriv->pPixmap); /* We don't need to free the baseColormap as FreeClientResourcess will have taken care of it. */ RegionUninit(&pScrPriv->region); unwrap (pScrPriv,pScreen, CloseScreen); ret = pScreen->CloseScreen(iScreen,pScreen); xfree(pScrPriv->pBits); xfree(pScrPriv->InstalledCmaps); xfree(pScrPriv); return TRUE; } static Bool xxMyVisual(ScreenPtr pScreen, VisualID vid) { xxScrPriv(pScreen); DepthPtr pDepth = pScreen->allowedDepths; int i,j; for (i = 0; i < pScreen->numDepths; i++, pDepth++) if (pDepth->depth == pScrPriv->myDepth) { for (j = 0; j < pDepth->numVids; j++) { if (vid == pDepth->vids[j]) { return TRUE; } } } return FALSE; } static Bool xxInitColormapDummy(ColormapPtr pmap, int index) { return TRUE; } static Bool xxInitColormapPrivate(ColormapPtr pmap) { xxScrPriv(pmap->pScreen); xxCmapPrivPtr pCmapPriv; void *cmap; pmap->devPrivates[xxColormapPrivateIndex].ptr = (void *) -1; if (xxMyVisual(pmap->pScreen,pmap->pVisual->vid)) { DBG("CreateColormap\n"); pCmapPriv = (xxCmapPrivPtr) xalloc (sizeof (xxCmapPrivRec)); if (!pCmapPriv) return FALSE; pmap->devPrivates[xxColormapPrivateIndex].ptr = (void *) pCmapPriv; cmap = xalloc(sizeof (CARD32) * (1 << pScrPriv->myDepth)); if (!cmap) return FALSE; memset(cmap,0,sizeof (CARD32) * (1 << pScrPriv->myDepth)); pCmapPriv->cmap = cmap; pCmapPriv->dirty = FALSE; pCmapPriv->pmap = pmap; pCmapPriv->next = pScrPriv->Cmaps; pScrPriv->Cmaps = pCmapPriv; } return TRUE; } static Bool xxCreateColormap(ColormapPtr pmap) { xxScrPriv(pmap->pScreen); Bool ret; if (!xxInitColormapPrivate(pmap)) return FALSE; unwrap(pScrPriv,pmap->pScreen, CreateColormap); ret = pmap->pScreen->CreateColormap(pmap); wrap(pScrPriv,pmap->pScreen,CreateColormap,xxCreateColormap); return ret; } static int xxCmapInstalled(ColormapPtr pmap) { xxScrPriv(pmap->pScreen); int i; for (i = 0; i < pScrPriv->numInstalledColormaps; i++) if (pScrPriv->InstalledCmaps[i] == pmap) break; if (i == pScrPriv->numInstalledColormaps) /* not installed */ return -1; return i; } static void xxInstalledCmapDelete(ScreenPtr pScreen, int num) { xxScrPriv(pScreen); int i; pScrPriv->numInstalledColormaps--; for (i = num; i < pScrPriv->numInstalledColormaps; i++) pScrPriv->InstalledCmaps[i] = pScrPriv->InstalledCmaps[i+1]; } static void xxDestroyColormap(ColormapPtr pmap) { xxScrPriv(pmap->pScreen); xxCmapPriv(pmap); if (pCmapPriv != (void *) -1) { xxCmapPrivPtr tmpCmapPriv = pScrPriv->Cmaps; xxCmapPrivPtr *prevCmapPriv = &pScrPriv->Cmaps; int n; DBG("DestroyColormap\n"); if ((n = xxCmapInstalled(pmap)) != -1) xxInstalledCmapDelete(pmap->pScreen,n); while (tmpCmapPriv) { if (tmpCmapPriv->pmap == pmap) { *prevCmapPriv = tmpCmapPriv->next; break; } prevCmapPriv = &tmpCmapPriv->next; tmpCmapPriv = tmpCmapPriv->next; } xfree(pCmapPriv->cmap); xfree(pCmapPriv); } unwrap(pScrPriv,pmap->pScreen, DestroyColormap); pmap->pScreen->DestroyColormap(pmap); wrap(pScrPriv,pmap->pScreen,DestroyColormap,xxDestroyColormap); } #define Shift(v,d) ((d) < 0 ? ((v) >> (-d)) : ((v) << (d))) static int xxComputeCmapShift (unsigned long mask) { int shift; unsigned long bit; shift = 16; bit = 0x80000000; while (!(mask & bit)) { shift--; bit >>= 1; } return shift; } static void xxStoreColors(ColormapPtr pmap, int nColors, xColorItem *pColors) { xxScrPriv(pmap->pScreen); xxCmapPriv(pmap); if (pCmapPriv != (void *) -1) { xColorItem *expanddefs; int i; VisualPtr bVisual; int rs, gs, bs; if (nColors == 0) return; DBG("StoreColors\n"); expanddefs = ALLOCATE_LOCAL(sizeof(xColorItem) * (1 << pScrPriv->myDepth)); if (!expanddefs) return; bVisual = pScrPriv->bVisual; DBG("StoreColors\n"); rs = xxComputeCmapShift(bVisual->redMask); gs = xxComputeCmapShift(bVisual->greenMask); bs = xxComputeCmapShift(bVisual->blueMask); if ((pmap->pVisual->class | DynamicClass) == DirectColor) { nColors = miExpandDirectColors(pmap, nColors, pColors, expanddefs); pColors = expanddefs; } for (i = 0; i < nColors; i++) { DBG_ARGS(("index: %i r 0x%x g 0x%x b 0x%x\n", pColors->pixel, pColors->red, pColors->green, pColors->blue)); pCmapPriv->cmap[pColors->pixel] = MARK_DIRTY | (Shift(pColors->red, rs) & bVisual->redMask) | (Shift(pColors->green, gs) & bVisual->greenMask) | (Shift(pColors->blue, bs) & bVisual->blueMask); pColors++; } DEALLOCATE_LOCAL(expanddefs); pCmapPriv->dirty = TRUE; pScrPriv->colormapDirty = TRUE; return; } unwrap(pScrPriv,pmap->pScreen, StoreColors); pmap->pScreen->StoreColors(pmap,nColors,pColors); wrap(pScrPriv,pmap->pScreen,StoreColors,xxStoreColors); } static void xxInstallColormap(ColormapPtr pmap) { int i; xxScrPriv(pmap->pScreen); xxCmapPriv(pmap); if (pCmapPriv != (void *) -1) { Pixel *pixels; xrgb *colors; int i; VisualPtr pVisual; xColorItem *defs; DBG("InstallColormap\n"); if (xxCmapInstalled(pmap) != -1) return; if (!pScrPriv->numInstalledColormaps) { unwrap(pScrPriv,pmap->pScreen, InstallColormap); pmap->pScreen->InstallColormap(pScrPriv->baseCmap); wrap(pScrPriv,pmap->pScreen,InstallColormap,xxInstallColormap); } pixels = ALLOCATE_LOCAL(sizeof(Pixel) * (1 << pScrPriv->myDepth)); colors = ALLOCATE_LOCAL(sizeof(xrgb) * (1 << pScrPriv->myDepth)); defs = ALLOCATE_LOCAL(sizeof(xColorItem) * (1 << pScrPriv->myDepth)); if (!pixels || !colors) return; /* if we have more than max installed delete the oldest */ if (pScrPriv->numInstalledColormaps == MAX_NUM_XX_INSTALLED_CMAPS) xxInstalledCmapDelete(pmap->pScreen,0); pScrPriv->InstalledCmaps[pScrPriv->numInstalledColormaps] = pmap; pScrPriv->numInstalledColormaps++; pVisual = pScrPriv->bVisual; for (i = 0; i < (1 << pScrPriv->myDepth); i++) pixels[i] = i; QueryColors (pmap, (1 << pScrPriv->myDepth), pixels, colors); for (i = 0; i < (1 << pScrPriv->myDepth); i++) { defs[i].pixel = pixels[i]; defs[i].red = colors[i].red; defs[i].green = colors[i].green; defs[i].blue = colors[i].blue; defs[i].flags = DoRed|DoGreen|DoBlue; } xxStoreColors(pmap,(1 << pScrPriv->myDepth),defs); DEALLOCATE_LOCAL(pixels); DEALLOCATE_LOCAL(colors); DEALLOCATE_LOCAL(defs); return; } for (i = pScrPriv->numInstalledColormaps; i ; i--) WalkTree(pmap->pScreen, TellLostMap, (char *)&pScrPriv->InstalledCmaps[i-1]->mid); pScrPriv->numInstalledColormaps = 0; unwrap(pScrPriv,pmap->pScreen, InstallColormap); pmap->pScreen->InstallColormap(pmap); wrap(pScrPriv,pmap->pScreen,InstallColormap,xxInstallColormap); } static void xxUninstallColormap(ColormapPtr pmap) { xxScrPriv(pmap->pScreen); xxCmapPriv(pmap); if (pCmapPriv != (void *) -1) { int num; if ((num = xxCmapInstalled(pmap)) == -1) return; DBG("UninstallColormap\n"); xxInstalledCmapDelete(pmap->pScreen,num); return; } unwrap(pScrPriv,pmap->pScreen, UninstallColormap); pmap->pScreen->UninstallColormap(pmap); wrap(pScrPriv,pmap->pScreen,UninstallColormap,xxUninstallColormap); } static int xxListInstalledColormaps(ScreenPtr pScreen, Colormap *pCmapIds) { int n,i; xxScrPriv(pScreen); unwrap(pScrPriv,pScreen, ListInstalledColormaps); n = pScreen->ListInstalledColormaps(pScreen, pCmapIds); wrap (pScrPriv,pScreen,ListInstalledColormaps,xxListInstalledColormaps); pCmapIds += n; for (i = 0; i < pScrPriv->numInstalledColormaps; i++) { *pCmapIds++ = pScrPriv->InstalledCmaps[i]->mid; n++; } return n; } static Bool xxCreateWindow(WindowPtr pWin) { xxScrPriv(pWin->drawable.pScreen); if (pWin->drawable.class != InputOutput || pScrPriv->myDepth != pWin->drawable.depth) { Bool ret; DBG("CreateWindow NoPseudo\n"); unwrap (pScrPriv, pWin->drawable.pScreen, CreateWindow); ret = pWin->drawable.pScreen->CreateWindow(pWin); wrap(pScrPriv, pWin->drawable.pScreen, CreateWindow, xxCreateWindow); return ret; } DBG("CreateWindow\n"); pWin->devPrivates[fbWinPrivateIndex].ptr = (void *) pScrPriv->pPixmap; PRINT_RECTS(pScrPriv->region); if (!pWin->parent) { RegionEmpty(&pScrPriv->region); } PRINT_RECTS(pScrPriv->region); return TRUE; } static void xxWalkChildren(WindowPtr pWin, RegionPtr pReg, PixmapPtr pPixmap) { WindowPtr pCurWin = pWin; do { if (fbGetWindowPixmap(pCurWin) == pPixmap) { DBG("WalkWindow Add\n"); RegionUnion(pReg,pReg, &pCurWin->borderClip); } else { DBG("WalkWindow Sub\n"); RegionSubtract(pReg,pReg, &pCurWin->borderClip); } if (pCurWin->lastChild) xxWalkChildren(pCurWin->lastChild,pReg, pPixmap); } while ((pCurWin = pCurWin->prevSib)); } static void xxPickMyWindows(WindowPtr pWin, RegionPtr pRgn) { ScreenPtr pScreen = pWin->drawable.pScreen; xxScrPriv(pScreen); if (fbGetWindowPixmap(pWin) == pScrPriv->pPixmap) { RegionUnion(pRgn,pRgn,&pWin->borderClip); } if (pWin->lastChild) xxWalkChildren(pWin->lastChild,pRgn,pScrPriv->pPixmap); } static void xxCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) { ScreenPtr pScreen = pWin->drawable.pScreen; xxScrPriv(pScreen); RegionRec rgn; RegionRec rgn_new; int dx, dy; PixmapPtr pPixmap = fbGetWindowPixmap(pWin); DBG("xxCopyWindow\n"); dx = ptOldOrg.x - pWin->drawable.x; dy = ptOldOrg.y - pWin->drawable.y; RegionNull(&rgn_new); RegionUnion(&rgn_new,&rgn_new,prgnSrc); RegionTranslate(&rgn_new,-dx,-dy); RegionNull(&rgn); xxPickMyWindows(pWin,&rgn); unwrap (pScrPriv, pScreen, CopyWindow); pWin->devPrivates[fbWinPrivateIndex].ptr = fbGetScreenPixmap(pScreen); pScreen->CopyWindow(pWin, ptOldOrg, prgnSrc); pWin->devPrivates[fbWinPrivateIndex].ptr = pPixmap; wrap(pScrPriv, pScreen, CopyWindow, xxCopyWindow); RegionIntersect(&rgn,&rgn,&rgn_new); if (RegionNotEmpty(&rgn)) { fbCopyRegion(&pScrPriv->pPixmap->drawable,&pScrPriv->pPixmap->drawable, 0,&rgn,dx,dy,fbCopyWindowProc,0,(void*)0); RegionTranslate(&rgn,dx,dy); RegionIntersect(&rgn_new,&pScrPriv->region,&rgn); RegionSubtract(&pScrPriv->region,&pScrPriv->region,&rgn); RegionTranslate(&rgn_new,-dx,-dy); RegionUnion(&pScrPriv->region,&pScrPriv->region,&rgn_new); } #if 1 RegionUninit(&rgn_new); RegionUninit(&rgn); #endif } static void xxWindowExposures (WindowPtr pWin, RegionPtr prgn, RegionPtr other_exposed) { xxScrPriv(pWin->drawable.pScreen); if (fbGetWindowPixmap(pWin) == pScrPriv->pPixmap) { DBG("WindowExposures\n"); PRINT_RECTS(pScrPriv->region); RegionUnion(&pScrPriv->region, &pScrPriv->region, prgn); PRINT_RECTS(pScrPriv->region); } else { DBG("WindowExposures NonPseudo\n"); PRINT_RECTS(pScrPriv->region); RegionSubtract(&pScrPriv->region, &pScrPriv->region, prgn); PRINT_RECTS(pScrPriv->region); } unwrap (pScrPriv, pWin->drawable.pScreen, WindowExposures); pWin->drawable.pScreen->WindowExposures(pWin, prgn, other_exposed); wrap(pScrPriv, pWin->drawable.pScreen, WindowExposures, xxWindowExposures); } static void xxPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what) { xxScrPriv(pWin->drawable.pScreen); RegionRec rgni; DBG("xxPaintWindow\n"); RegionNull(&rgni); #if 0 RegionUnion(&rgni, &rgni, &pWin->borderClip); RegionIntersect(&rgni, &rgni, pRegion); #else RegionUnion(&rgni, &rgni, pRegion); #endif switch (what) { case PW_BORDER: RegionSubtract(&rgni, &rgni, &pWin->winSize); if (fbGetWindowPixmap(pWin) == pScrPriv->pPixmap) { DBG("PaintWindowBorder\n"); RegionUnion(&pScrPriv->region, &pScrPriv->region, &rgni); } else { DBG("PaintWindowBorder NoOverlay\n"); RegionSubtract(&pScrPriv->region, &pScrPriv->region, &rgni); } unwrap (pScrPriv, pWin->drawable.pScreen, PaintWindowBorder); pWin->drawable.pScreen->PaintWindowBorder (pWin, pRegion, what); wrap(pScrPriv, pWin->drawable.pScreen, PaintWindowBorder, xxPaintWindow); break; case PW_BACKGROUND: switch (pWin->backgroundState) { case None: break; default: RegionIntersect(&rgni, &rgni,&pWin->winSize); if (fbGetWindowPixmap(pWin) == pScrPriv->pPixmap) { DBG("PaintWindowBackground\n"); RegionUnion(&pScrPriv->region, &pScrPriv->region, &rgni); } else { DBG("PaintWindowBackground NoOverlay\n"); RegionSubtract(&pScrPriv->region, &pScrPriv->region, &rgni); } break; } unwrap (pScrPriv, pWin->drawable.pScreen, PaintWindowBackground); pWin->drawable.pScreen->PaintWindowBackground (pWin, pRegion, what); wrap(pScrPriv, pWin->drawable.pScreen, PaintWindowBackground, xxPaintWindow); break; } PRINT_RECTS(rgni); PRINT_RECTS(pScrPriv->region); #if 1 RegionUninit(&rgni); #endif } static void xxCopyPseudocolorRegion(ScreenPtr pScreen, RegionPtr pReg, xxCmapPrivPtr pCmapPriv) { xxScrPriv(pScreen); CARD32 mask = (1 << pScrPriv->myDepth) - 1; int num = RegionNumRects(pReg); BoxPtr pbox = RegionRects(pReg); int width, height; CARD8 *src; CARD16 *dst, *dst_base; int dst_stride; register CARD32 *cmap = pCmapPriv->cmap; register CARD8 *s; register CARD16 *d; int w; dst_base = (CARD16*) ((PixmapPtr)pScreen->devPrivate)->devPrivate.ptr; dst_stride = (int)((PixmapPtr)pScreen->devPrivate)->devKind / sizeof (CARD16); while (num--) { height = pbox->y2 - pbox->y1; width = pbox->x2 - pbox->x1; src = (unsigned char *) pScrPriv->pBits + (pbox->y1 * pScreen->width) + pbox->x1; dst = dst_base + (pbox->y1 * dst_stride) + pbox->x1; while (height--) { w = width; s = src; d = dst; while(w--) { *(d++) = (CARD16)*(cmap + ((*(s++)) & mask)); } src += pScreen->width; dst += dst_stride; } pbox++; } } static void xxUpdateCmapPseudocolorRegion(ScreenPtr pScreen, RegionPtr pReg, xxCmapPrivPtr pCmapPriv) { xxScrPriv(pScreen); CARD32 mask = (1 << pScrPriv->myDepth) - 1; int num = RegionNumRects(pReg); BoxPtr pbox = RegionRects(pReg); int width, height; CARD8 *src; CARD16 *dst, *dst_base; int dst_stride; register CARD32 val; register CARD32 *cmap = pCmapPriv->cmap; register CARD8 *s; register CARD16 *d; int w; dst_base = (CARD16*) ((PixmapPtr)pScreen->devPrivate)->devPrivate.ptr; dst_stride = (int)((PixmapPtr)pScreen->devPrivate)->devKind / sizeof (CARD16); while (num--) { height = pbox->y2 - pbox->y1; width = pbox->x2 - pbox->x1; src = (unsigned char *) pScrPriv->pBits + (pbox->y1 * pScreen->width) + pbox->x1; dst = dst_base + (pbox->y1 * dst_stride) + pbox->x1; while (height--) { w = width; s = src; d = dst; while(w--) { val = *(cmap + ((*(s++)) & mask)); if (val & MARK_DIRTY) { *d = (CARD16) val; } d++; } src += pScreen->width; dst += dst_stride; } pbox++; } } static void xxGetWindowRegion(WindowPtr pWin,RegionPtr winreg) { RegionNull(winreg); /* get visible part of the border ...Argh */ RegionSubtract(winreg,&pWin->borderSize, &pWin->winSize); RegionIntersect(winreg,winreg, &pWin->borderClip); /* add window interior excluding children */ RegionUnion(winreg,winreg, &pWin->clipList); } static int xxUpdateRegion(WindowPtr pWin, void * unused) { ScreenPtr pScreen = pWin->drawable.pScreen; xxScrPriv(pScreen); ColormapPtr pmap = (void *) -1; RegionRec winreg, rgni; if (pScrPriv->myDepth == pWin->drawable.depth) { xxCmapPrivPtr pCmapPriv = (void *)-1; xxGetWindowRegion(pWin,&winreg); if (pScrPriv->colormapDirty) { pmap = (ColormapPtr)LookupIDByType(wColormap(pWin),RT_COLORMAP); if (!pmap) goto CONTINUE; /* return ? */ pCmapPriv = xxGetCmapPriv(pmap); if (pCmapPriv == (void *) -1) return WT_WALKCHILDREN; if (!pCmapPriv->dirty) goto CONTINUE; RegionNull(&rgni); /* This will be taken care of when damaged regions are updated */ RegionSubtract(&rgni, &winreg, &pScrPriv->region); if (RegionNotEmpty(&rgni)) xxUpdateCmapPseudocolorRegion(pScreen,&rgni, pCmapPriv); } CONTINUE: RegionNull(&rgni); RegionIntersect(&rgni, &winreg, &pScrPriv->region); if (RegionNotEmpty(&rgni)) { if (pmap == (void *) -1) { pmap = (ColormapPtr)LookupIDByType(wColormap(pWin),RT_COLORMAP); if (!pmap) /* return ? */ pmap = (ColormapPtr)LookupIDByType(pScreen->defColormap, RT_COLORMAP); pCmapPriv = xxGetCmapPriv(pmap); } if (pCmapPriv != (void *)-1) xxCopyPseudocolorRegion(pScreen,&rgni, pCmapPriv); RegionSubtract(&pScrPriv->region, &pScrPriv->region, &rgni); } #if 1 RegionUninit(&rgni); RegionUninit(&winreg); #endif } return WT_WALKCHILDREN; } static void xxUpdateFb(ScreenPtr pScreen) { xxScrPriv(pScreen); DBG("Update FB\n"); PRINT_RECTS(pScrPriv->region); if (pScrPriv->sync) pScrPriv->sync(pScreen); /*@!@*/ WalkTree(pScreen,xxUpdateRegion,NULL); #if 0 if (RegionNotEmpty(&pScrPriv->region)) { ColormapPtr pmap = (void *) -1; xxCmapPrivPtr pCmapPriv; pmap = (ColormapPtr)LookupIDByType(pScreen->defColormap, RT_COLORMAP); pCmapPriv = xxGetCmapPriv(pmap); if (pCmapPriv != (void *)-1) xxCopyPseudocolorRegion(pScreen,&pScrPriv->region, pCmapPriv); RegionSubtract(&pScrPriv->region, &pScrPriv->region, &pScrPriv->region); } #endif if (pScrPriv->colormapDirty) { xxCmapPrivPtr pCmap = pScrPriv->Cmaps; while (pCmap) { int j; if (pCmap->dirty) { for (j = 0; j < (1 << pScrPriv->myDepth); j++) pCmap->cmap[j] &= ~MARK_DIRTY; pCmap->dirty = FALSE; } pCmap = pCmap->next; } pScrPriv->colormapDirty = FALSE; } } static void xxBlockHandler (void * data, OSTimePtr pTimeout, void * pRead) { ScreenPtr pScreen = (ScreenPtr) data; xxScrPriv(pScreen); if (RegionNotEmpty(&pScrPriv->region) || pScrPriv->colormapDirty) xxUpdateFb (pScreen); } static void xxWakeupHandler (void * data, int i, void * LastSelectMask) { } Bool xxSetup(ScreenPtr pScreen, int myDepth, int baseDepth, char* addr, xxSyncFunc sync) { xxScrPrivPtr pScrPriv; DepthPtr pDepths; ColormapPtr pDefMap; int i,j,k; #ifdef RENDER PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); #endif if (xxGeneration != serverGeneration) { xxScrPrivateIndex = AllocateScreenPrivateIndex (); if (xxScrPrivateIndex == -1) return FALSE; xxColormapPrivateIndex = AllocateColormapPrivateIndex (xxInitColormapDummy); if (xxColormapPrivateIndex == -1) return FALSE; xxGCPrivateIndex = AllocateGCPrivateIndex (); if (xxGCPrivateIndex == -1) return FALSE; xxGeneration = serverGeneration; } if (!AllocateGCPrivate (pScreen, xxGCPrivateIndex, sizeof (xxGCPrivRec))) return FALSE; pScrPriv = (xxScrPrivPtr) xalloc (sizeof (xxScrPrivRec)); if (!pScrPriv) return FALSE; if (baseDepth) pScrPriv->depth = baseDepth; else { pDepths = pScreen->allowedDepths; for (i = 0; i < pScreen->numDepths; i++, pDepths++) if (pDepths->depth != myDepth) pScrPriv->depth = pDepths->depth; } if (!pScrPriv->depth) return FALSE; pDepths = pScreen->allowedDepths; for (i = 0; i < pScreen->numDepths; i++, pDepths++) if (pDepths->depth == pScrPriv->depth) { for (j = 0; i < pDepths->numVids; j++) { for (k = 0; k < pScreen->numVisuals; k++) { if (pScreen->visuals[k].vid == pDepths[i].vids[j] && pScreen->visuals[k].class == TrueColor) { pScrPriv->bVisual = &pScreen->visuals[k]; goto DONE; } } } } DONE: if (!pScrPriv->bVisual) return FALSE; pScrPriv->myDepth = myDepth; pScrPriv->numInstalledColormaps = 0; pScrPriv->colormapDirty = FALSE; pScrPriv->Cmaps = NULL; pScrPriv->sync = sync; pScreen->maxInstalledCmaps += MAX_NUM_XX_INSTALLED_CMAPS; pScrPriv->InstalledCmaps = xcalloc(MAX_NUM_XX_INSTALLED_CMAPS, sizeof(ColormapPtr)); if (!pScrPriv->InstalledCmaps) return FALSE; if (!RegisterBlockAndWakeupHandlers (xxBlockHandler, xxWakeupHandler, (void *) pScreen)) return FALSE; wrap (pScrPriv, pScreen, CloseScreen, xxCloseScreen); wrap (pScrPriv, pScreen, CreateScreenResources, xxCreateScreenResources); wrap (pScrPriv, pScreen, CreateWindow, xxCreateWindow); wrap (pScrPriv, pScreen, CopyWindow, xxCopyWindow); wrap (pScrPriv, pScreen, PaintWindowBorder, xxPaintWindow); wrap (pScrPriv, pScreen, PaintWindowBackground, xxPaintWindow); #if 0 /* can we leave this out even with backing store enabled ? */ wrap (pScrPriv, pScreen, WindowExposures, xxWindowExposures); #endif wrap (pScrPriv, pScreen, CreateGC, xxCreateGC); wrap (pScrPriv, pScreen, CreateColormap, xxCreateColormap); wrap (pScrPriv, pScreen, DestroyColormap, xxDestroyColormap); wrap (pScrPriv, pScreen, InstallColormap, xxInstallColormap); wrap (pScrPriv, pScreen, UninstallColormap, xxUninstallColormap); wrap (pScrPriv, pScreen, ListInstalledColormaps, xxListInstalledColormaps); wrap (pScrPriv, pScreen, StoreColors, xxStoreColors); #ifdef RENDER if (ps) { wrap (pScrPriv, ps, Glyphs, xxGlyphs); wrap (pScrPriv, ps, Composite, xxComposite); } #endif pScrPriv->addr = addr; pScreen->devPrivates[xxScrPrivateIndex].ptr = (void *) pScrPriv; pDefMap = (ColormapPtr) LookupIDByType(pScreen->defColormap, RT_COLORMAP); if (!xxInitColormapPrivate(pDefMap)) return FALSE; return TRUE; } GCFuncs xxGCFuncs = { xxValidateGC, xxChangeGC, xxCopyGC, xxDestroyGC, xxChangeClip, xxDestroyClip, xxCopyClip }; GCOps xxGCOps = { xxFillSpans, xxSetSpans, xxPutImage, xxCopyArea, xxCopyPlane, xxPolyPoint, xxPolylines, xxPolySegment, xxPolyRectangle, xxPolyArc, xxFillPolygon, xxPolyFillRect, xxPolyFillArc, xxPolyText8, xxPolyText16, xxImageText8, xxImageText16, xxImageGlyphBlt, xxPolyGlyphBlt, xxPushPixels, #ifdef NEED_LINEHELPER NULL, #endif {NULL} /* devPrivate */ }; #define IS_VISIBLE(pDraw) (pDraw->type == DRAWABLE_WINDOW \ && (fbGetWindowPixmap((WindowPtr) pDraw) == pScrPriv->pPixmap)) #define TRANSLATE_BOX(box, pDraw) { \ box.x1 += pDraw->x; \ box.x2 += pDraw->x; \ box.y1 += pDraw->y; \ box.y2 += pDraw->y; \ } #define TRIM_BOX(box, pGC) { \ BoxPtr extents = &pGC->pCompositeClip->extents;\ if(box.x1 < extents->x1) box.x1 = extents->x1; \ if(box.x2 > extents->x2) box.x2 = extents->x2; \ if(box.y1 < extents->y1) box.y1 = extents->y1; \ if(box.y2 > extents->y2) box.y2 = extents->y2; \ } #define BOX_NOT_EMPTY(box) \ (((box.x2 - box.x1) > 0) && ((box.y2 - box.y1) > 0)) #define _ADD_BOX(box,pGC) {\ if (BOX_NOT_EMPTY(box)) { \ RegionRec region; \ ScreenPtr pScreen = pGC->pScreen;\ RegionInit(®ion, &box, 1); \ RegionIntersect(®ion,®ion,\ (pGC)->pCompositeClip);\ if (RegionNotEmpty(®ion)) { \ xxScrPriv(pScreen);\ PRINT_RECTS(pScrPriv->region);\ RegionUnion(&pScrPriv->region,&pScrPriv->region,®ion);\ PRINT_RECTS(pScrPriv->region);\ RegionUninit(®ion);\ }\ }\ } #define TRANSLATE_AND_ADD_BOX(box,pGC) {\ TRANSLATE_BOX(box,pDraw); \ TRIM_BOX(box,pGC); \ _ADD_BOX(box,pGC); \ } #define ADD_BOX(box,pGC) { \ TRIM_BOX(box,pGC); \ _ADD_BOX(box,pGC); \ } #define XX_GC_FUNC_PROLOGUE(pGC) \ xxGCPriv(pGC); \ unwrap(pGCPriv, pGC, funcs); \ if (pGCPriv->ops) unwrap(pGCPriv, pGC, ops) #define XX_GC_FUNC_EPILOGUE(pGC) \ wrap(pGCPriv, pGC, funcs, &xxGCFuncs); \ if (pGCPriv->ops) wrap(pGCPriv, pGC, ops, &xxGCOps) static Bool xxCreateGC(GCPtr pGC) { ScreenPtr pScreen = pGC->pScreen; xxScrPriv(pScreen); xxGCPriv(pGC); Bool ret; unwrap (pScrPriv, pScreen, CreateGC); if((ret = (*pScreen->CreateGC) (pGC))) { pGCPriv->ops = NULL; pGCPriv->funcs = pGC->funcs; pGC->funcs = &xxGCFuncs; } wrap (pScrPriv, pScreen, CreateGC, xxCreateGC); return ret; } static void xxValidateGC( GCPtr pGC, unsigned long changes, DrawablePtr pDraw ){ XX_GC_FUNC_PROLOGUE (pGC); (*pGC->funcs->ValidateGC)(pGC, changes, pDraw); if(pDraw->type == DRAWABLE_WINDOW) pGCPriv->ops = pGC->ops; /* just so it's not NULL */ else pGCPriv->ops = NULL; XX_GC_FUNC_EPILOGUE (pGC); } static void xxDestroyGC(GCPtr pGC) { XX_GC_FUNC_PROLOGUE (pGC); (*pGC->funcs->DestroyGC)(pGC); XX_GC_FUNC_EPILOGUE (pGC); } static void xxChangeGC ( GCPtr pGC, unsigned long mask ){ XX_GC_FUNC_PROLOGUE (pGC); (*pGC->funcs->ChangeGC) (pGC, mask); XX_GC_FUNC_EPILOGUE (pGC); } static void xxCopyGC ( GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst ){ XX_GC_FUNC_PROLOGUE (pGCDst); (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst); XX_GC_FUNC_EPILOGUE (pGCDst); } static void xxChangeClip ( GCPtr pGC, int type, void * pvalue, int nrects ){ XX_GC_FUNC_PROLOGUE (pGC); (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects); XX_GC_FUNC_EPILOGUE (pGC); } static void xxCopyClip(GCPtr pgcDst, GCPtr pgcSrc) { XX_GC_FUNC_PROLOGUE (pgcDst); (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc); XX_GC_FUNC_EPILOGUE (pgcDst); } static void xxDestroyClip(GCPtr pGC) { XX_GC_FUNC_PROLOGUE (pGC); (* pGC->funcs->DestroyClip)(pGC); XX_GC_FUNC_EPILOGUE (pGC); } #define XX_GC_OP_PROLOGUE(pGC,pDraw) \ xxScrPriv(pDraw->pScreen); \ xxGCPriv(pGC); \ GCFuncs *oldFuncs = pGC->funcs; \ unwrap(pGCPriv, pGC, funcs); \ unwrap(pGCPriv, pGC, ops); \ #define XX_GC_OP_EPILOGUE(pGC,pDraw) \ wrap(pGCPriv, pGC, funcs, oldFuncs); \ wrap(pGCPriv, pGC, ops, &xxGCOps) static void xxFillSpans( DrawablePtr pDraw, GC *pGC, int nInit, DDXPointPtr pptInit, int *pwidthInit, int fSorted ){ XX_GC_OP_PROLOGUE(pGC, pDraw); if(IS_VISIBLE(pDraw) && nInit) { DDXPointPtr ppt = pptInit; int *pwidth = pwidthInit; int i = nInit; BoxRec box; DBG("FillSpans\n"); box.x1 = ppt->x; box.x2 = box.x1 + *pwidth; box.y2 = box.y1 = ppt->y; while(--i) { ppt++; pwidthInit++; if(box.x1 > ppt->x) box.x1 = ppt->x; if(box.x2 < (ppt->x + *pwidth)) box.x2 = ppt->x + *pwidth; if(box.y1 > ppt->y) box.y1 = ppt->y; else if(box.y2 < ppt->y) box.y2 = ppt->y; } box.y2++; (*pGC->ops->FillSpans)(pDraw, pGC, nInit, pptInit, pwidthInit, fSorted); TRANSLATE_AND_ADD_BOX(box, pGC); } else (*pGC->ops->FillSpans)(pDraw, pGC, nInit, pptInit, pwidthInit, fSorted); XX_GC_OP_EPILOGUE(pGC, pDraw); } static void xxSetSpans( DrawablePtr pDraw, GCPtr pGC, char *pcharsrc, DDXPointPtr pptInit, int *pwidthInit, int nspans, int fSorted ){ XX_GC_OP_PROLOGUE(pGC, pDraw); if(IS_VISIBLE(pDraw) && nspans) { DDXPointPtr ppt = pptInit; int *pwidth = pwidthInit; int i = nspans; BoxRec box; DBG("SetSpans\n"); box.x1 = ppt->x; box.x2 = box.x1 + *pwidth; box.y2 = box.y1 = ppt->y; while(--i) { ppt++; pwidth++; if(box.x1 > ppt->x) box.x1 = ppt->x; if(box.x2 < (ppt->x + *pwidth)) box.x2 = ppt->x + *pwidth; if(box.y1 > ppt->y) box.y1 = ppt->y; else if(box.y2 < ppt->y) box.y2 = ppt->y; } box.y2++; (*pGC->ops->SetSpans)(pDraw, pGC, pcharsrc, pptInit, pwidthInit, nspans, fSorted); TRANSLATE_AND_ADD_BOX(box, pGC); } else (*pGC->ops->SetSpans)(pDraw, pGC, pcharsrc, pptInit, pwidthInit, nspans, fSorted); XX_GC_OP_EPILOGUE(pGC, pDraw); } static void xxPutImage( DrawablePtr pDraw, GCPtr pGC, int depth, int x, int y, int w, int h, int leftPad, int format, char *pImage ){ XX_GC_OP_PROLOGUE(pGC, pDraw); (*pGC->ops->PutImage)(pDraw, pGC, depth, x, y, w, h, leftPad, format, pImage); XX_GC_OP_EPILOGUE(pGC, pDraw); if(IS_VISIBLE(pDraw)) { BoxRec box; DBG("PutImage\n"); box.x1 = x + pDraw->x; box.x2 = box.x1 + w; box.y1 = y + pDraw->y; box.y2 = box.y1 + h; ADD_BOX(box, pGC); } } static RegionPtr xxCopyArea( DrawablePtr pSrc, DrawablePtr pDst, GC *pGC, int srcx, int srcy, int width, int height, int dstx, int dsty ){ RegionPtr ret; XX_GC_OP_PROLOGUE(pGC, pDst); DBG("xxCopyArea\n"); ret = (*pGC->ops->CopyArea)(pSrc, pDst, pGC, srcx, srcy, width, height, dstx, dsty); XX_GC_OP_EPILOGUE(pGC, pDst); if(IS_VISIBLE(pDst)) { BoxRec box; DBG("CopyArea\n"); box.x1 = dstx + pDst->x; box.x2 = box.x1 + width; box.y1 = dsty + pDst->y; box.y2 = box.y1 + height; ADD_BOX(box, pGC); } return ret; } static RegionPtr xxCopyPlane( DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy, int width, int height, int dstx, int dsty, unsigned long bitPlane ){ RegionPtr ret; XX_GC_OP_PROLOGUE(pGC, pDst); ret = (*pGC->ops->CopyPlane)(pSrc, pDst, pGC, srcx, srcy, width, height, dstx, dsty, bitPlane); XX_GC_OP_EPILOGUE(pGC, pDst); if(IS_VISIBLE(pDst)) { BoxRec box; DBG("CopyPlane\n"); box.x1 = dstx + pDst->x; box.x2 = box.x1 + width; box.y1 = dsty + pDst->y; box.y2 = box.y1 + height; ADD_BOX(box, pGC); } return ret; } static void xxPolyPoint( DrawablePtr pDraw, GCPtr pGC, int mode, int npt, xPoint *pptInit ){ XX_GC_OP_PROLOGUE(pGC, pDraw); (*pGC->ops->PolyPoint)(pDraw, pGC, mode, npt, pptInit); XX_GC_OP_EPILOGUE(pGC, pDraw); if(IS_VISIBLE(pDraw) && npt) { BoxRec box; DBG("PolyPoint\n"); box.x2 = box.x1 = pptInit->x; box.y2 = box.y1 = pptInit->y; /* this could be slow if the points were spread out */ while(--npt) { pptInit++; if(box.x1 > pptInit->x) box.x1 = pptInit->x; else if(box.x2 < pptInit->x) box.x2 = pptInit->x; if(box.y1 > pptInit->y) box.y1 = pptInit->y; else if(box.y2 < pptInit->y) box.y2 = pptInit->y; } box.x2++; box.y2++; TRANSLATE_AND_ADD_BOX(box, pGC); } } static void xxPolylines( DrawablePtr pDraw, GCPtr pGC, int mode, int npt, DDXPointPtr pptInit ){ XX_GC_OP_PROLOGUE(pGC, pDraw); (*pGC->ops->Polylines)(pDraw, pGC, mode, npt, pptInit); XX_GC_OP_EPILOGUE(pGC, pDraw); if(IS_VISIBLE(pDraw) && npt) { BoxRec box; int extra = pGC->lineWidth >> 1; DBG("PolyLine\n"); box.x2 = box.x1 = pptInit->x; box.y2 = box.y1 = pptInit->y; if(npt > 1) { if(pGC->joinStyle == JoinMiter) extra = 6 * pGC->lineWidth; else if(pGC->capStyle == CapProjecting) extra = pGC->lineWidth; } if(mode == CoordModePrevious) { int x = box.x1; int y = box.y1; while(--npt) { pptInit++; x += pptInit->x; y += pptInit->y; if(box.x1 > x) box.x1 = x; else if(box.x2 < x) box.x2 = x; if(box.y1 > y) box.y1 = y; else if(box.y2 < y) box.y2 = y; } } else { while(--npt) { pptInit++; if(box.x1 > pptInit->x) box.x1 = pptInit->x; else if(box.x2 < pptInit->x) box.x2 = pptInit->x; if(box.y1 > pptInit->y) box.y1 = pptInit->y; else if(box.y2 < pptInit->y) box.y2 = pptInit->y; } } box.x2++; box.y2++; if(extra) { box.x1 -= extra; box.x2 += extra; box.y1 -= extra; box.y2 += extra; } TRANSLATE_AND_ADD_BOX(box, pGC); } } static void xxPolySegment( DrawablePtr pDraw, GCPtr pGC, int nseg, xSegment *pSeg ){ XX_GC_OP_PROLOGUE(pGC, pDraw); (*pGC->ops->PolySegment)(pDraw, pGC, nseg, pSeg); XX_GC_OP_EPILOGUE(pGC, pDraw); if(IS_VISIBLE(pDraw) && nseg) { BoxRec box; int extra = pGC->lineWidth; DBG("PolySegment\n"); if(pGC->capStyle != CapProjecting) extra >>= 1; if(pSeg->x2 > pSeg->x1) { box.x1 = pSeg->x1; box.x2 = pSeg->x2; } else { box.x2 = pSeg->x1; box.x1 = pSeg->x2; } if(pSeg->y2 > pSeg->y1) { box.y1 = pSeg->y1; box.y2 = pSeg->y2; } else { box.y2 = pSeg->y1; box.y1 = pSeg->y2; } while(--nseg) { pSeg++; if(pSeg->x2 > pSeg->x1) { if(pSeg->x1 < box.x1) box.x1 = pSeg->x1; if(pSeg->x2 > box.x2) box.x2 = pSeg->x2; } else { if(pSeg->x2 < box.x1) box.x1 = pSeg->x2; if(pSeg->x1 > box.x2) box.x2 = pSeg->x1; } if(pSeg->y2 > pSeg->y1) { if(pSeg->y1 < box.y1) box.y1 = pSeg->y1; if(pSeg->y2 > box.y2) box.y2 = pSeg->y2; } else { if(pSeg->y2 < box.y1) box.y1 = pSeg->y2; if(pSeg->y1 > box.y2) box.y2 = pSeg->y1; } } box.x2++; box.y2++; if(extra) { box.x1 -= extra; box.x2 += extra; box.y1 -= extra; box.y2 += extra; } TRANSLATE_AND_ADD_BOX(box, pGC); } } static void xxPolyRectangle( DrawablePtr pDraw, GCPtr pGC, int nRects, xRectangle *pRects ){ XX_GC_OP_PROLOGUE(pGC, pDraw); (*pGC->ops->PolyRectangle)(pDraw, pGC, nRects, pRects); XX_GC_OP_EPILOGUE(pGC, pDraw); if(IS_VISIBLE(pDraw) && nRects) { BoxRec box; int offset1, offset2, offset3; DBG("PolyRectangle\n"); offset2 = pGC->lineWidth; if(!offset2) offset2 = 1; offset1 = offset2 >> 1; offset3 = offset2 - offset1; while(nRects--) { box.x1 = pRects->x - offset1; box.y1 = pRects->y - offset1; box.x2 = box.x1 + pRects->width + offset2; box.y2 = box.y1 + offset2; TRANSLATE_AND_ADD_BOX(box, pGC); box.x1 = pRects->x - offset1; box.y1 = pRects->y + offset3; box.x2 = box.x1 + offset2; box.y2 = box.y1 + pRects->height - offset2; TRANSLATE_AND_ADD_BOX(box, pGC); box.x1 = pRects->x + pRects->width - offset1; box.y1 = pRects->y + offset3; box.x2 = box.x1 + offset2; box.y2 = box.y1 + pRects->height - offset2; TRANSLATE_AND_ADD_BOX(box, pGC); box.x1 = pRects->x - offset1; box.y1 = pRects->y + pRects->height - offset1; box.x2 = box.x1 + pRects->width + offset2; box.y2 = box.y1 + offset2; TRANSLATE_AND_ADD_BOX(box, pGC); pRects++; } } } static void xxPolyArc( DrawablePtr pDraw, GCPtr pGC, int narcs, xArc *parcs ){ XX_GC_OP_PROLOGUE(pGC, pDraw); (*pGC->ops->PolyArc)(pDraw, pGC, narcs, parcs); XX_GC_OP_EPILOGUE(pGC, pDraw); if(IS_VISIBLE(pDraw) && narcs) { int extra = pGC->lineWidth >> 1; BoxRec box; DBG("PolyArc\n"); box.x1 = parcs->x; box.x2 = box.x1 + parcs->width; box.y1 = parcs->y; box.y2 = box.y1 + parcs->height; /* should I break these up instead ? */ while(--narcs) { parcs++; if(box.x1 > parcs->x) box.x1 = parcs->x; if(box.x2 < (parcs->x + parcs->width)) box.x2 = parcs->x + parcs->width; if(box.y1 > parcs->y) box.y1 = parcs->y; if(box.y2 < (parcs->y + parcs->height)) box.y2 = parcs->y + parcs->height; } if(extra) { box.x1 -= extra; box.x2 += extra; box.y1 -= extra; box.y2 += extra; } box.x2++; box.y2++; TRANSLATE_AND_ADD_BOX(box, pGC); } } static void xxFillPolygon( DrawablePtr pDraw, GCPtr pGC, int shape, int mode, int count, DDXPointPtr pptInit ){ XX_GC_OP_PROLOGUE(pGC, pDraw); if(IS_VISIBLE(pDraw) && (count > 2)) { DDXPointPtr ppt = pptInit; int i = count; BoxRec box; DBG("FillPolygon\n"); box.x2 = box.x1 = ppt->x; box.y2 = box.y1 = ppt->y; if(mode != CoordModeOrigin) { int x = box.x1; int y = box.y1; while(--i) { ppt++; x += ppt->x; y += ppt->y; if(box.x1 > x) box.x1 = x; else if(box.x2 < x) box.x2 = x; if(box.y1 > y) box.y1 = y; else if(box.y2 < y) box.y2 = y; } } else { while(--i) { ppt++; if(box.x1 > ppt->x) box.x1 = ppt->x; else if(box.x2 < ppt->x) box.x2 = ppt->x; if(box.y1 > ppt->y) box.y1 = ppt->y; else if(box.y2 < ppt->y) box.y2 = ppt->y; } } box.x2++; box.y2++; (*pGC->ops->FillPolygon)(pDraw, pGC, shape, mode, count, pptInit); TRANSLATE_AND_ADD_BOX(box, pGC); } else (*pGC->ops->FillPolygon)(pDraw, pGC, shape, mode, count, pptInit); XX_GC_OP_EPILOGUE(pGC, pDraw); } static void xxPolyFillRect( DrawablePtr pDraw, GCPtr pGC, int nRectsInit, xRectangle *pRectsInit ){ XX_GC_OP_PROLOGUE(pGC, pDraw); if(IS_VISIBLE(pDraw) && nRectsInit) { BoxRec box; xRectangle *pRects = pRectsInit; int nRects = nRectsInit; DBG("PolyFillRect\n"); box.x1 = pRects->x; box.x2 = box.x1 + pRects->width; box.y1 = pRects->y; box.y2 = box.y1 + pRects->height; while(--nRects) { pRects++; if(box.x1 > pRects->x) box.x1 = pRects->x; if(box.x2 < (pRects->x + pRects->width)) box.x2 = pRects->x + pRects->width; if(box.y1 > pRects->y) box.y1 = pRects->y; if(box.y2 < (pRects->y + pRects->height)) box.y2 = pRects->y + pRects->height; } /* cfb messes with the pRectsInit so we have to do our calculations first */ (*pGC->ops->PolyFillRect)(pDraw, pGC, nRectsInit, pRectsInit); TRANSLATE_AND_ADD_BOX(box, pGC); } else (*pGC->ops->PolyFillRect)(pDraw, pGC, nRectsInit, pRectsInit); XX_GC_OP_EPILOGUE(pGC, pDraw); } static void xxPolyFillArc( DrawablePtr pDraw, GCPtr pGC, int narcs, xArc *parcs ){ XX_GC_OP_PROLOGUE(pGC, pDraw); (*pGC->ops->PolyFillArc)(pDraw, pGC, narcs, parcs); XX_GC_OP_EPILOGUE(pGC, pDraw); if(IS_VISIBLE(pDraw) && narcs) { BoxRec box; DBG("PolyFillArc\n"); box.x1 = parcs->x; box.x2 = box.x1 + parcs->width; box.y1 = parcs->y; box.y2 = box.y1 + parcs->height; /* should I break these up instead ? */ while(--narcs) { parcs++; if(box.x1 > parcs->x) box.x1 = parcs->x; if(box.x2 < (parcs->x + parcs->width)) box.x2 = parcs->x + parcs->width; if(box.y1 > parcs->y) box.y1 = parcs->y; if(box.y2 < (parcs->y + parcs->height)) box.y2 = parcs->y + parcs->height; } TRANSLATE_AND_ADD_BOX(box, pGC); } } static int xxPolyText8( DrawablePtr pDraw, GCPtr pGC, int x, int y, int count, char *chars ){ int width; XX_GC_OP_PROLOGUE(pGC, pDraw); width = (*pGC->ops->PolyText8)(pDraw, pGC, x, y, count, chars); XX_GC_OP_EPILOGUE(pGC, pDraw); width -= x; if(IS_VISIBLE(pDraw) && (width > 0)) { BoxRec box; DBG("PolyText8\n"); /* ugh */ box.x1 = pDraw->x + x + FONTMINBOUNDS(pGC->font, leftSideBearing); box.x2 = pDraw->x + x + FONTMAXBOUNDS(pGC->font, rightSideBearing); if(count > 1) { if(width > 0) box.x2 += width; else box.x1 += width; } box.y1 = pDraw->y + y - FONTMAXBOUNDS(pGC->font, ascent); box.y2 = pDraw->y + y + FONTMAXBOUNDS(pGC->font, descent); ADD_BOX(box, pGC); } return (width + x); } static int xxPolyText16( DrawablePtr pDraw, GCPtr pGC, int x, int y, int count, unsigned short *chars ){ int width; XX_GC_OP_PROLOGUE(pGC, pDraw); width = (*pGC->ops->PolyText16)(pDraw, pGC, x, y, count, chars); XX_GC_OP_EPILOGUE(pGC, pDraw); width -= x; if(IS_VISIBLE(pDraw) && (width > 0)) { BoxRec box; DBG("PolyText16\n"); /* ugh */ box.x1 = pDraw->x + x + FONTMINBOUNDS(pGC->font, leftSideBearing); box.x2 = pDraw->x + x + FONTMAXBOUNDS(pGC->font, rightSideBearing); if(count > 1) { if(width > 0) box.x2 += width; else box.x1 += width; } box.y1 = pDraw->y + y - FONTMAXBOUNDS(pGC->font, ascent); box.y2 = pDraw->y + y + FONTMAXBOUNDS(pGC->font, descent); ADD_BOX(box, pGC); } return (width + x); } static void xxImageText8( DrawablePtr pDraw, GCPtr pGC, int x, int y, int count, char *chars ){ XX_GC_OP_PROLOGUE(pGC, pDraw); (*pGC->ops->ImageText8)(pDraw, pGC, x, y, count, chars); XX_GC_OP_EPILOGUE(pGC, pDraw); if(IS_VISIBLE(pDraw) && count) { int top, bot, Min, Max; BoxRec box; DBG("ImageText8\n"); top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font)); bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font)); Min = count * FONTMINBOUNDS(pGC->font, characterWidth); if(Min > 0) Min = 0; Max = count * FONTMAXBOUNDS(pGC->font, characterWidth); if(Max < 0) Max = 0; /* ugh */ box.x1 = pDraw->x + x + Min + FONTMINBOUNDS(pGC->font, leftSideBearing); box.x2 = pDraw->x + x + Max + FONTMAXBOUNDS(pGC->font, rightSideBearing); box.y1 = pDraw->y + y - top; box.y2 = pDraw->y + y + bot; ADD_BOX(box, pGC); } } static void xxImageText16( DrawablePtr pDraw, GCPtr pGC, int x, int y, int count, unsigned short *chars ){ XX_GC_OP_PROLOGUE(pGC, pDraw); (*pGC->ops->ImageText16)(pDraw, pGC, x, y, count, chars); XX_GC_OP_EPILOGUE(pGC, pDraw); if(IS_VISIBLE(pDraw) && count) { int top, bot, Min, Max; BoxRec box; DBG("ImageText16\n"); top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font)); bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font)); Min = count * FONTMINBOUNDS(pGC->font, characterWidth); if(Min > 0) Min = 0; Max = count * FONTMAXBOUNDS(pGC->font, characterWidth); if(Max < 0) Max = 0; /* ugh */ box.x1 = pDraw->x + x + Min + FONTMINBOUNDS(pGC->font, leftSideBearing); box.x2 = pDraw->x + x + Max + FONTMAXBOUNDS(pGC->font, rightSideBearing); box.y1 = pDraw->y + y - top; box.y2 = pDraw->y + y + bot; ADD_BOX(box, pGC); } } static void xxImageGlyphBlt( DrawablePtr pDraw, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr *ppci, void * pglyphBase ){ XX_GC_OP_PROLOGUE(pGC, pDraw); (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, x, y, nglyph, ppci, pglyphBase); XX_GC_OP_EPILOGUE(pGC, pDraw); if(IS_VISIBLE(pDraw) && nglyph) { int top, bot, width = 0; BoxRec box; DBG("ImageGlyphBlt\n"); top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font)); bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font)); box.x1 = ppci[0]->metrics.leftSideBearing; if(box.x1 > 0) box.x1 = 0; box.x2 = ppci[nglyph - 1]->metrics.rightSideBearing - ppci[nglyph - 1]->metrics.characterWidth; if(box.x2 < 0) box.x2 = 0; box.x2 += pDraw->x + x; box.x1 += pDraw->x + x; while(nglyph--) { width += (*ppci)->metrics.characterWidth; ppci++; } if(width > 0) box.x2 += width; else box.x1 += width; box.y1 = pDraw->y + y - top; box.y2 = pDraw->y + y + bot; ADD_BOX(box, pGC); } } static void xxPolyGlyphBlt( DrawablePtr pDraw, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr *ppci, void * pglyphBase ){ XX_GC_OP_PROLOGUE(pGC, pDraw); (*pGC->ops->PolyGlyphBlt)(pDraw, pGC, x, y, nglyph, ppci, pglyphBase); XX_GC_OP_EPILOGUE(pGC, pDraw); if(IS_VISIBLE(pDraw) && nglyph) { BoxRec box; DBG("PolyGlyphBlt\n"); /* ugh */ box.x1 = pDraw->x + x + ppci[0]->metrics.leftSideBearing; box.x2 = pDraw->x + x + ppci[nglyph - 1]->metrics.rightSideBearing; if(nglyph > 1) { int width = 0; while(--nglyph) { width += (*ppci)->metrics.characterWidth; ppci++; } if(width > 0) box.x2 += width; else box.x1 += width; } box.y1 = pDraw->y + y - FONTMAXBOUNDS(pGC->font, ascent); box.y2 = pDraw->y + y + FONTMAXBOUNDS(pGC->font, descent); ADD_BOX(box, pGC); } } static void xxPushPixels( GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDraw, int dx, int dy, int xOrg, int yOrg ){ XX_GC_OP_PROLOGUE(pGC, pDraw); (*pGC->ops->PushPixels)(pGC, pBitMap, pDraw, dx, dy, xOrg, yOrg); XX_GC_OP_EPILOGUE(pGC, pDraw); if(IS_VISIBLE(pDraw)) { BoxRec box; DBG("PushPixels\n"); box.x1 = xOrg + pDraw->x; box.x2 = box.x1 + dx; box.y1 = yOrg + pDraw->y; box.y2 = box.y1 + dy; ADD_BOX(box, pGC); } } #ifdef RENDER #define RENDER_MAKE_BOX(pDrawable,X,Y,W,H) { \ box.x1 = X + pDrawable->x; \ box.x2 = X + pDrawable->x + W; \ box.y1 = Y + pDrawable->y; \ box.y2 = Y + pDrawable->y + H; \ } #define RENDER_ADD_BOX(pScreen,box) {\ if (BOX_NOT_EMPTY(box)) { \ RegionRec region; \ xxScrPriv(pScreen);\ ScreenPtr pScreen = pScreen;\ RegionInit(®ion, &box, 1); \ PRINT_RECTS(pScrPriv->region);\ RegionUnion(&pScrPriv->region,&pScrPriv->region,®ion);\ PRINT_RECTS(pScrPriv->region);\ RegionUninit(®ion);\ }\ } static void xxComposite (CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height) { ScreenPtr pScreen = pDst->pDrawable->pScreen; PictureScreenPtr ps = GetPictureScreen(pScreen); xxScrPriv(pScreen); BoxRec box; unwrap (pScrPriv, ps, Composite); (*ps->Composite) (op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height); wrap (pScrPriv, ps, Composite, xxComposite); if (pDst->pDrawable->type == DRAWABLE_WINDOW) { RENDER_MAKE_BOX(pDst->pDrawable, xDst, yDst, width, height); RENDER_ADD_BOX(pScreen,box); } } static void xxGlyphs (CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr *glyphs) { ScreenPtr pScreen = pDst->pDrawable->pScreen; PictureScreenPtr ps = GetPictureScreen(pScreen); xxScrPriv(pScreen); int x, y; int n; GlyphPtr glyph; BoxRec box; unwrap (pScrPriv, ps, Glyphs); (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs); wrap (pScrPriv, ps, Glyphs, xxGlyphs); if (pDst->pDrawable->type == DRAWABLE_WINDOW) { x = xSrc; y = ySrc; while (nlist--) { x += list->xOff; y += list->yOff; n = list->len; while (n--) { glyph = *glyphs++; RENDER_MAKE_BOX(pDst->pDrawable, x - glyph->info.x, y - glyph->info.y, glyph->info.width, glyph->info.height); RENDER_ADD_BOX(pScreen,box); x += glyph->info.xOff; y += glyph->info.yOff; } list++; } } } #endif void xxPrintVisuals(void) { int k,i,j; DepthPtr pDepth; VisualPtr pVisual; for (k = 0; k < screenInfo.numScreens; k++) { ScreenPtr pScreen = screenInfo.screens[k]; pDepth = pScreen->allowedDepths; for (i = 0; i < pScreen->numDepths; i++, pDepth++) for (j = 0; j < pDepth->numVids; j++) { ErrorF("depth: %i vid: 0x%lx\n", pDepth->depth, pDepth->vids[j]); } pVisual = pScreen->visuals; for (i = 0; i < pScreen->numVisuals; i++, pVisual++) ErrorF("vid: 0x%x rm: 0x%lx gm: 0x%lx bm: 0x%lx\n", (unsigned int)pVisual->vid, pVisual->redMask, pVisual->greenMask, pVisual->blueMask); } }