diff --git a/mi/miexpose.c b/mi/miexpose.c index 03d4c27e0..6ace9f589 100644 --- a/mi/miexpose.c +++ b/mi/miexpose.c @@ -539,64 +539,85 @@ miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what) ScreenPtr pScreen = pWin->drawable.pScreen; ChangeGCVal gcval[5]; BITS32 gcmask; - PixmapPtr pPixmap; GCPtr pGC; int i; BoxPtr pbox; xRectangle *prect; int numRects; - int xoff, yoff; - - pPixmap = (*pScreen->GetWindowPixmap) (pWin); - -#ifdef COMPOSITE - xoff = -pPixmap->screen_x; - yoff = -pPixmap->screen_y; -#else - xoff = 0; - yoff = 0; -#endif - gcval[0].val = GXcopy; - gcmask = GCFunction; + /* + * Distance from screen to destination drawable, use this + * to adjust rendering coordinates which come in in screen space + */ + int draw_x_off, draw_y_off; + /* + * Tile offset for drawing; these need to align the tile + * to the appropriate window origin + */ + int tile_x_off, tile_y_off; + PixUnion fill; + Bool solid = TRUE; + DrawablePtr drawable = &pWin->drawable; if (what == PW_BACKGROUND) { while (pWin->backgroundState == ParentRelative) pWin = pWin->parent; + draw_x_off = drawable->x; + draw_y_off = drawable->y; + + tile_x_off = 0; + tile_y_off = 0; + 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 pixmap; + + tile_x_off = drawable->x; + tile_y_off = drawable->y; + + /* servers without pixmaps draw their own borders */ + if (!pScreen->GetWindowPixmap) + return; + pixmap = (*pScreen->GetWindowPixmap) ((WindowPtr) drawable); + drawable = &pixmap->drawable; +#ifdef COMPOSITE + draw_x_off = pixmap->screen_x; + draw_y_off = pixmap->screen_y; + tile_x_off -= draw_x_off; + tile_y_off -= draw_y_off; +#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; + gcval[4].val = tile_y_off; + gcmask |= GCFillStyle | GCTile | GCTileStipXOrigin | GCTileStipYOrigin; } prect = (xRectangle *)ALLOCATE_LOCAL(REGION_NUM_RECTS(prgn) * @@ -604,27 +625,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);