xserver-multidpi/fb/fbpseudocolor.c
Aaron Plattner f2e310132f Add CreatePixmap allocation hints.
These hints allow an acceleration architecture to optimize allocation of certain
types of pixmaps, such as pixmaps that will serve as backing pixmaps for
redirected windows.
2007-11-04 16:11:28 -08:00

2271 lines
54 KiB
C

#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <string.h>
#include <X11/X.h>
#include <X11/Xproto.h>
#include "scrnintstr.h"
#include "colormapst.h"
#include "glyphstr.h"
#include "resource.h"
#include <X11/fonts/font.h>
#include "dixfontstr.h"
#include <X11/fonts/fontstruct.h>
#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, pointer 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,
pointer pglyphBase);
static void xxPolyGlyphBlt(DrawablePtr pDraw, GCPtr pGC, int x, int y,
unsigned int nglyph, CharInfoPtr *ppci,
pointer 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;
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;
pointer 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",REGION_NUM_RECTS(&rec));\
if (REGION_NUM_RECTS(&rec) > 1) { \
for (i = 0; i < REGION_NUM_RECTS(&rec); i++ ) {\
box = REGION_BOX(&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)) != (pointer)-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;
pointer 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, 0);
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;
REGION_NULL(pScreen, &pScrPriv->region);
REGION_INIT(pScreen, &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. */
REGION_UNINIT (pScreen, &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;
pointer cmap;
pmap->devPrivates[xxColormapPrivateIndex].ptr = (pointer) -1;
if (xxMyVisual(pmap->pScreen,pmap->pVisual->vid)) {
DBG("CreateColormap\n");
pCmapPriv = (xxCmapPrivPtr) xalloc (sizeof (xxCmapPrivRec));
if (!pCmapPriv)
return FALSE;
pmap->devPrivates[xxColormapPrivateIndex].ptr = (pointer) 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 != (pointer) -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 != (pointer) -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 != (pointer) -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 != (pointer) -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 = (pointer) pScrPriv->pPixmap;
PRINT_RECTS(pScrPriv->region);
if (!pWin->parent) {
REGION_EMPTY (pWin->drawable.pScreen, &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");
REGION_UNION(pWin->drawable.pScreen,pReg,pReg,
&pCurWin->borderClip);
} else {
DBG("WalkWindow Sub\n");
REGION_SUBTRACT(pWin->drawable.pScreen,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) {
REGION_UNION(pWin->drawable.pScreen,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;
REGION_NULL(pScreen, &rgn_new);
REGION_UNION(pScreen, &rgn_new,&rgn_new,prgnSrc);
REGION_TRANSLATE(pScreen,&rgn_new,-dx,-dy);
REGION_NULL(pScreen, &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);
REGION_INTERSECT(pScreen,&rgn,&rgn,&rgn_new);
if (REGION_NOTEMPTY (pScreen,&rgn)) {
fbCopyRegion(&pScrPriv->pPixmap->drawable,&pScrPriv->pPixmap->drawable,
0,&rgn,dx,dy,fbCopyWindowProc,0,(void*)0);
REGION_TRANSLATE(pScreen,&rgn,dx,dy);
REGION_INTERSECT(pScreen,&rgn_new,&pScrPriv->region,&rgn);
REGION_SUBTRACT(pScreen,&pScrPriv->region,&pScrPriv->region,&rgn);
REGION_TRANSLATE(pScreen,&rgn_new,-dx,-dy);
REGION_UNION(pScreen,&pScrPriv->region,&pScrPriv->region,&rgn_new);
}
#if 1
REGION_UNINIT(pScreen,&rgn_new);
REGION_UNINIT(pScreen,&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);
REGION_UNION(pWin->drawable.pScreen,&pScrPriv->region,
&pScrPriv->region,
prgn);
PRINT_RECTS(pScrPriv->region);
} else {
DBG("WindowExposures NonPseudo\n");
PRINT_RECTS(pScrPriv->region);
REGION_SUBTRACT(pWin->drawable.pScreen,&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
xxCopyPseudocolorRegion(ScreenPtr pScreen, RegionPtr pReg,
xxCmapPrivPtr pCmapPriv)
{
xxScrPriv(pScreen);
CARD32 mask = (1 << pScrPriv->myDepth) - 1;
int num = REGION_NUM_RECTS(pReg);
BoxPtr pbox = REGION_RECTS(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;
fbPrepareAccess((DrawablePtr)pScreen->devPrivate);
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++;
}
fbFinishAccess(&((PixmapPtr)pScreen->devPrivate)->drawable);
}
static void
xxUpdateCmapPseudocolorRegion(ScreenPtr pScreen, RegionPtr pReg,
xxCmapPrivPtr pCmapPriv)
{
xxScrPriv(pScreen);
CARD32 mask = (1 << pScrPriv->myDepth) - 1;
int num = REGION_NUM_RECTS(pReg);
BoxPtr pbox = REGION_RECTS(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)
{
REGION_NULL(pWin->drawable.pScreen,winreg);
/* get visible part of the border ...Argh */
REGION_SUBTRACT(pWin->drawable.pScreen,winreg,&pWin->borderSize,
&pWin->winSize);
REGION_INTERSECT(pWin->drawable.pScreen,winreg,winreg,
&pWin->borderClip);
/* add window interior excluding children */
REGION_UNION(pWin->drawable.pScreen,winreg,winreg,
&pWin->clipList);
}
static int
xxUpdateRegion(WindowPtr pWin, pointer unused)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
xxScrPriv(pScreen);
ColormapPtr pmap = (pointer) -1;
RegionRec winreg, rgni;
if (pScrPriv->myDepth == pWin->drawable.depth) {
xxCmapPrivPtr pCmapPriv = (pointer)-1;
xxGetWindowRegion(pWin,&winreg);
if (pScrPriv->colormapDirty) {
pmap = (ColormapPtr)LookupIDByType(wColormap(pWin),RT_COLORMAP);
if (!pmap)
goto CONTINUE; /* return ? */
pCmapPriv = xxGetCmapPriv(pmap);
if (pCmapPriv == (pointer) -1)
return WT_WALKCHILDREN;
if (!pCmapPriv->dirty)
goto CONTINUE;
REGION_NULL (pScreen, &rgni);
/* This will be taken care of when damaged regions are updated */
REGION_SUBTRACT(pScreen, &rgni, &winreg, &pScrPriv->region);
if (REGION_NOTEMPTY (pScreen,&rgni))
xxUpdateCmapPseudocolorRegion(pScreen,&rgni, pCmapPriv);
}
CONTINUE:
REGION_NULL (pScreen, &rgni);
REGION_INTERSECT (pScreen, &rgni, &winreg, &pScrPriv->region);
if (REGION_NOTEMPTY (pScreen,&rgni)) {
if (pmap == (pointer) -1) {
pmap =
(ColormapPtr)LookupIDByType(wColormap(pWin),RT_COLORMAP);
if (!pmap) /* return ? */
pmap = (ColormapPtr)LookupIDByType(pScreen->defColormap,
RT_COLORMAP);
pCmapPriv = xxGetCmapPriv(pmap);
}
if (pCmapPriv != (pointer)-1)
xxCopyPseudocolorRegion(pScreen,&rgni, pCmapPriv);
REGION_SUBTRACT(pScreen, &pScrPriv->region, &pScrPriv->region,
&rgni);
}
#if 1
REGION_UNINIT(pScreen,&rgni);
REGION_UNINIT(pScreen,&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 (REGION_NOTEMPTY (pScreen,&pScrPriv->region)) {
ColormapPtr pmap = (pointer) -1;
xxCmapPrivPtr pCmapPriv;
pmap = (ColormapPtr)LookupIDByType(pScreen->defColormap,
RT_COLORMAP);
pCmapPriv = xxGetCmapPriv(pmap);
if (pCmapPriv != (pointer)-1)
xxCopyPseudocolorRegion(pScreen,&pScrPriv->region, pCmapPriv);
REGION_SUBTRACT(pScreen, &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 (pointer data,
OSTimePtr pTimeout,
pointer pRead)
{
ScreenPtr pScreen = (ScreenPtr) data;
xxScrPriv(pScreen);
if (REGION_NOTEMPTY (pScreen,&pScrPriv->region) || pScrPriv->colormapDirty)
xxUpdateFb (pScreen);
}
static void
xxWakeupHandler (pointer data, int i, pointer 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,
(pointer) pScreen))
return FALSE;
wrap (pScrPriv, pScreen, CloseScreen, xxCloseScreen);
wrap (pScrPriv, pScreen, CreateScreenResources, xxCreateScreenResources);
wrap (pScrPriv, pScreen, CreateWindow, xxCreateWindow);
wrap (pScrPriv, pScreen, CopyWindow, xxCopyWindow);
#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 = (pointer) pScrPriv;
pDefMap = (ColormapPtr) LookupIDByType(pScreen->defColormap, RT_COLORMAP);
if (!xxInitColormapPrivate(pDefMap))
return FALSE;
return TRUE;
}
GCFuncs xxGCFuncs = {
xxValidateGC, xxChangeGC, xxCopyGC, xxDestroyGC,
xxChangeClip, xxDestroyClip, xxCopyClip
};
static GCOps xxGCOps = {
xxFillSpans, xxSetSpans,
xxPutImage, xxCopyArea,
xxCopyPlane, xxPolyPoint,
xxPolylines, xxPolySegment,
xxPolyRectangle, xxPolyArc,
xxFillPolygon, xxPolyFillRect,
xxPolyFillArc, xxPolyText8,
xxPolyText16, xxImageText8,
xxImageText16, xxImageGlyphBlt,
xxPolyGlyphBlt, xxPushPixels,
{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;\
REGION_INIT (pScreen, &region, &box, 1); \
REGION_INTERSECT(pScreen,&region,&region,\
(pGC)->pCompositeClip);\
if (REGION_NOTEMPTY(pScreen,&region)) { \
xxScrPriv(pScreen);\
PRINT_RECTS(pScrPriv->region);\
REGION_UNION(pScreen,&pScrPriv->region,&pScrPriv->region,&region);\
PRINT_RECTS(pScrPriv->region);\
REGION_UNINIT(pScreen,&region);\
}\
}\
}
#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,
pointer 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,
pointer 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,
pointer 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;\
REGION_INIT (pScreen, &region, &box, 1); \
PRINT_RECTS(pScrPriv->region);\
REGION_UNION(pScreen,&pScrPriv->region,&pScrPriv->region,&region);\
PRINT_RECTS(pScrPriv->region);\
REGION_UNINIT(pScreen,&region);\
}\
}
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);
}
}