From dd3992eb86377684a5dbe86fa19c756a9e53cda2 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 12 Sep 2007 22:39:31 +0100 Subject: [PATCH 1/2] 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. --- mi/miexpose.c | 94 ++++++++++++++++++++++++++++----------------------- 1 file changed, 52 insertions(+), 42 deletions(-) diff --git a/mi/miexpose.c b/mi/miexpose.c index e82a0b573..ad1356f24 100644 --- a/mi/miexpose.c +++ b/mi/miexpose.c @@ -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); From 06d27f8045966c1fb154eafaff308a01b93f265b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 12 Sep 2007 23:57:30 +0100 Subject: [PATCH 2/2] Try again to fix drawable and tile offsets in miPaintWindow Many coordinate spaces are hard. Let's go drinking. --- mi/miexpose.c | 45 +++++++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/mi/miexpose.c b/mi/miexpose.c index ad1356f24..2dc8f1508 100644 --- a/mi/miexpose.c +++ b/mi/miexpose.c @@ -592,22 +592,30 @@ miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what) BoxPtr pbox; xRectangle *prect; int numRects; - int tile_x_off = 0, tile_y_off = 0; - int draw_x_off = 0, draw_y_off = 0; + /* + * 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; - draw_x_off = pWin->drawable.x; - draw_y_off = pWin->drawable.y; - while (pWin->backgroundState == ParentRelative) pWin = pWin->parent; if (what == PW_BACKGROUND) { - tile_x_off = -pWin->drawable.x; - tile_y_off = -pWin->drawable.y; + 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: @@ -619,16 +627,21 @@ miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what) } else { - PixmapPtr pPixmap; + PixmapPtr pixmap; + tile_x_off = drawable->x; + tile_y_off = drawable->y; + /* servers without pixmaps draw their own borders */ if (!pScreen->GetWindowPixmap) return; - pPixmap = (*pScreen->GetWindowPixmap) (pWin); - drawable = &pPixmap->drawable; + pixmap = (*pScreen->GetWindowPixmap) ((WindowPtr) drawable); + drawable = &pixmap->drawable; #ifdef COMPOSITE - draw_x_off = -pPixmap->screen_x; - draw_y_off = -pPixmap->screen_y; + 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; @@ -650,8 +663,8 @@ miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what) { 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; + gcval[3].val = tile_x_off; + gcval[4].val = tile_y_off; gcmask |= GCFillStyle | GCTile | GCTileStipXOrigin | GCTileStipYOrigin; } @@ -674,8 +687,8 @@ miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what) pbox = REGION_RECTS(prgn); for (i= numRects; --i >= 0; pbox++, prect++) { - prect->x = pbox->x1 + draw_x_off; - prect->y = pbox->y1 + draw_y_off; + 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; }