/*
 * 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);
}
Beispiel #2
0
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);
}