/* * SafeAlphaPaintWindow * Paint the window while filling in the alpha channel with all on. * We can't use fbPaintWindow because it zeros the alpha channel. */ void SafeAlphaPaintWindow( WindowPtr pWin, RegionPtr pRegion, int what) { switch (what) { case PW_BACKGROUND: switch (pWin->backgroundState) { case None: break; case ParentRelative: do { pWin = pWin->parent; } while (pWin->backgroundState == ParentRelative); (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, pRegion, what); break; case BackgroundPixmap: SafeAlphaFillRegionTiled (&pWin->drawable, pRegion, pWin->background.pixmap); break; case BackgroundPixel: { Pixel pixel = pWin->background.pixel | RootlessAlphaMask(pWin->drawable.bitsPerPixel); fbFillRegionSolid (&pWin->drawable, pRegion, 0, fbReplicatePixel (pixel, pWin->drawable.bitsPerPixel)); break; } } break; case PW_BORDER: if (pWin->borderIsPixel) { Pixel pixel = pWin->border.pixel | RootlessAlphaMask(pWin->drawable.bitsPerPixel); fbFillRegionSolid (&pWin->drawable, pRegion, 0, fbReplicatePixel (pixel, pWin->drawable.bitsPerPixel)); } else { WindowPtr pBgWin; for (pBgWin = pWin; pBgWin->backgroundState == ParentRelative; pBgWin = pBgWin->parent); SafeAlphaFillRegionTiled (&pBgWin->drawable, pRegion, pWin->border.pixmap); } break; } fbValidateDrawable (&pWin->drawable); }
void miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what) { ScreenPtr pScreen = pWin->drawable.pScreen; ChangeGCVal gcval[6]; BITS32 gcmask; GCPtr pGC; int i; BoxPtr pbox; xRectangle *prect; int numRects; /* * 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 = pWin->drawable.x - draw_x_off; tile_y_off = pWin->drawable.y - draw_y_off; fill = pWin->background; #ifdef COMPOSITE if (pWin->inhibitBGPaint) return; #endif switch (pWin->backgroundState) { case None: return; case BackgroundPixmap: solid = FALSE; break; } } else { PixmapPtr pixmap; fill = pWin->border; solid = pWin->borderIsPixel; /* servers without pixmaps draw their own borders */ if (!pScreen->GetWindowPixmap) return; pixmap = (*pScreen->GetWindowPixmap) ((WindowPtr) drawable); drawable = &pixmap->drawable; while (pWin->backgroundState == ParentRelative) pWin = pWin->parent; tile_x_off = pWin->drawable.x; tile_y_off = pWin->drawable.y; #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 } gcval[0].val = GXcopy; gcmask = GCFunction; #ifdef ROOTLESS_SAFEALPHA /* Bit mask for alpha channel with a particular number of bits per * pixel. Note that we only care for 32bpp data. Mac OS X uses planar * alpha for 16bpp. */ #define RootlessAlphaMask(bpp) ((bpp) == 32 ? 0xFF000000 : 0) #endif if (solid) { #ifdef ROOTLESS_SAFEALPHA gcval[1].val = fill.pixel | RootlessAlphaMask(pWin->drawable.bitsPerPixel); #else gcval[1].val = fill.pixel; #endif gcval[2].val = FillSolid; gcmask |= GCForeground | GCFillStyle; } else { int c = 1; #ifdef ROOTLESS_SAFEALPHA gcval[c++].val = ((CARD32) -1) & ~RootlessAlphaMask(pWin->drawable.bitsPerPixel); gcmask |= GCPlaneMask; #endif gcval[c++].val = FillTiled; gcval[c++].ptr = (void *) fill.pixmap; gcval[c++].val = tile_x_off; gcval[c++].val = tile_y_off; gcmask |= GCFillStyle | GCTile | GCTileStipXOrigin | GCTileStipYOrigin; } prect = xallocarray(RegionNumRects(prgn), sizeof(xRectangle)); if (!prect) return; pGC = GetScratchGC(drawable->depth, drawable->pScreen); if (!pGC) { free(prect); return; } ChangeGC(NullClient, pGC, gcmask, gcval); ValidateGC(drawable, pGC); numRects = RegionNumRects(prgn); pbox = RegionRects(prgn); for (i = numRects; --i >= 0; pbox++, prect++) { 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) (drawable, pGC, numRects, prect); free(prect); FreeScratchGC(pGC); }