miPaintWindow draw to window for background.

Instead of drawing to window pixmap for everything, draw to window for
background as that works for Xnest and Xdmx; draw to pixmap for borders
which neither of those X servers use.
This commit is contained in:
Keith Packard 2007-09-12 22:39:31 +01:00
parent 6da39c6790
commit dd3992eb86

View File

@ -587,62 +587,72 @@ miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what)
ScreenPtr pScreen = pWin->drawable.pScreen;
ChangeGCVal gcval[5];
BITS32 gcmask;
PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
GCPtr pGC;
int i;
BoxPtr pbox;
xRectangle *prect;
int numRects;
int xoff, yoff;
int tile_x_off = 0, tile_y_off = 0;
int draw_x_off = 0, draw_y_off = 0;
PixUnion fill;
Bool solid = TRUE;
DrawablePtr drawable = &pWin->drawable;
draw_x_off = pWin->drawable.x;
draw_y_off = pWin->drawable.y;
while (pWin->backgroundState == ParentRelative)
pWin = pWin->parent;
#ifdef COMPOSITE
xoff = -pPixmap->screen_x;
yoff = -pPixmap->screen_y;
#else
xoff = 0;
yoff = 0;
#endif
gcval[0].val = GXcopy;
gcmask = GCFunction;
if (what == PW_BACKGROUND)
{
tile_x_off = -pWin->drawable.x;
tile_y_off = -pWin->drawable.y;
fill = pWin->background;
switch (pWin->backgroundState) {
case None:
return;
case BackgroundPixel:
gcval[1].val = pWin->background.pixel;
gcval[2].val = FillSolid;
gcmask |= GCForeground | GCFillStyle;
break;
case BackgroundPixmap:
gcval[1].val = FillTiled;
gcval[2].ptr = (pointer)pWin->background.pixmap;
gcval[3].val = pWin->drawable.x + xoff;
gcval[4].val = pWin->drawable.y + yoff;
gcmask |= GCFillStyle | GCTile | GCTileStipXOrigin | GCTileStipYOrigin;
solid = FALSE;
break;
}
}
else
{
if (pWin->borderIsPixel)
{
gcval[1].val = pWin->border.pixel;
gcval[2].val = FillSolid;
gcmask |= GCForeground | GCFillStyle;
}
else
{
gcval[1].val = FillTiled;
gcval[2].ptr = (pointer)pWin->border.pixmap;
gcval[3].val = pWin->drawable.x + xoff;
gcval[4].val = pWin->drawable.y + yoff;
gcmask |= GCFillStyle | GCTile | GCTileStipXOrigin | GCTileStipYOrigin;
}
PixmapPtr pPixmap;
/* servers without pixmaps draw their own borders */
if (!pScreen->GetWindowPixmap)
return;
pPixmap = (*pScreen->GetWindowPixmap) (pWin);
drawable = &pPixmap->drawable;
#ifdef COMPOSITE
draw_x_off = -pPixmap->screen_x;
draw_y_off = -pPixmap->screen_y;
#else
draw_x_off = 0;
draw_y_off = 0;
#endif
fill = pWin->border;
solid = pWin->borderIsPixel;
}
gcval[0].val = GXcopy;
gcmask = GCFunction;
if (solid)
{
gcval[1].val = fill.pixel;
gcval[2].val = FillSolid;
gcmask |= GCForeground | GCFillStyle;
}
else
{
gcval[1].val = FillTiled;
gcval[2].ptr = (pointer)fill.pixmap;
gcval[3].val = tile_x_off + draw_x_off;
gcval[4].val = tile_y_off + draw_y_off;
gcmask |= GCFillStyle | GCTile | GCTileStipXOrigin | GCTileStipYOrigin;
}
prect = (xRectangle *)ALLOCATE_LOCAL(REGION_NUM_RECTS(prgn) *
@ -650,27 +660,27 @@ miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what)
if (!prect)
return;
pGC = GetScratchGC(pPixmap->drawable.depth, pPixmap->drawable.pScreen);
pGC = GetScratchGC(drawable->depth, drawable->pScreen);
if (!pGC)
{
DEALLOCATE_LOCAL(prect);
return;
}
dixChangeGC(NullClient, pGC, gcmask, NULL, gcval);
ValidateGC(&pPixmap->drawable, pGC);
dixChangeGC (NullClient, pGC, gcmask, NULL, gcval);
ValidateGC (drawable, pGC);
numRects = REGION_NUM_RECTS(prgn);
pbox = REGION_RECTS(prgn);
for (i= numRects; --i >= 0; pbox++, prect++)
{
prect->x = pbox->x1 + xoff;
prect->y = pbox->y1 + yoff;
prect->x = pbox->x1 + draw_x_off;
prect->y = pbox->y1 + draw_y_off;
prect->width = pbox->x2 - pbox->x1;
prect->height = pbox->y2 - pbox->y1;
}
prect -= numRects;
(*pGC->ops->PolyFillRect)(&pPixmap->drawable, pGC, numRects, prect);
(*pGC->ops->PolyFillRect)(drawable, pGC, numRects, prect);
DEALLOCATE_LOCAL(prect);
FreeScratchGC(pGC);