Пример #1
0
static void
RootlessPaintWindowBackground(WindowPtr pWin, RegionPtr pRegion, int what)
{
    int oldBackgroundState = 0;
    PixUnion oldBackground;
    ScreenPtr pScreen = pWin->drawable.pScreen;

    SCREEN_UNWRAP(pScreen, PaintWindowBackground);
    RL_DEBUG_MSG("paintwindowbackground start (win 0x%x) ", pWin);
    if (IsFramedWindow(pWin)) {
        if (IsRoot(pWin)) {
            // set root background to magic transparent color
            oldBackgroundState = pWin->backgroundState;
            oldBackground = pWin->background;
            pWin->backgroundState = BackgroundPixel;
            pWin->background.pixel = 0x00fffffe;
        }
    }

    pScreen->PaintWindowBackground(pWin, pRegion, what);

    if (IsFramedWindow(pWin)) {
        RootlessDamageRegion(pWin, pRegion);
        if (IsRoot(pWin)) {
            pWin->backgroundState = oldBackgroundState;
            pWin->background = oldBackground;
        }
    }
    SCREEN_WRAP(pScreen, PaintWindowBackground);
    RL_DEBUG_MSG("paintwindowbackground end\n");
}
Пример #2
0
/* changed area is *dest* rect */
static RegionPtr
RootlessCopyPlane(DrawablePtr pSrc, DrawablePtr dst,
                  GCPtr pGC, int srcx, int srcy,
                  int w, int h, int dstx, int dsty, unsigned long plane)
{
    RegionPtr result;
    BoxRec box;

    GCOP_UNWRAP(pGC);

    RL_DEBUG_MSG("copy plane start ");

    if (pSrc->type == DRAWABLE_WINDOW && IsFramedWindow((WindowPtr) pSrc)) {
        RootlessStartDrawing((WindowPtr) pSrc);
    }
    RootlessStartDrawing((WindowPtr) dst);
    result = pGC->ops->CopyPlane(pSrc, dst, pGC, srcx, srcy, w, h,
                                 dstx, dsty, plane);

    box.x1 = dstx + dst->x;
    box.x2 = box.x1 + w;
    box.y1 = dsty + dst->y;
    box.y2 = box.y1 + h;

    TRIM_BOX(box, pGC);
    if (BOX_NOT_EMPTY(box))
        RootlessDamageBox((WindowPtr) dst, &box);

    GCOP_WRAP(pGC);
    RL_DEBUG_MSG("copy plane end\n");
    return result;
}
Пример #3
0
static void
RootlessComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
                  INT16 xSrc, INT16 ySrc, INT16  xMask, INT16  yMask,
                  INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
{
    ScreenPtr pScreen = pDst->pDrawable->pScreen;
    PictureScreenPtr ps = GetPictureScreen(pScreen);
    WindowPtr dstWin;

    dstWin  = (pDst->pDrawable->type  == DRAWABLE_WINDOW) ?
        (WindowPtr)pDst->pDrawable  :  NULL;

    // SCREEN_UNWRAP(ps, Composite);
    ps->Composite = SCREENREC(pScreen)->Composite;

    ps->Composite(op, pSrc, pMask, pDst,
                  xSrc, ySrc, xMask, yMask,
                  xDst, yDst, width, height);

    if (dstWin  && IsFramedWindow(dstWin)) {
        RootlessDamageRect(dstWin, xDst, yDst, width, height);
    }

    ps->Composite = RootlessComposite;
    // SCREEN_WRAP(ps, Composite);
}
Пример #4
0
static void
RootlessPaintWindowBorder(WindowPtr pWin, RegionPtr pRegion, int what)
{
    SCREEN_UNWRAP(pWin->drawable.pScreen, PaintWindowBorder);
    RL_DEBUG_MSG("paintwindowborder start (win 0x%x) ", pWin);
    pWin->drawable.pScreen->PaintWindowBorder(pWin, pRegion, what);
    if (IsFramedWindow(pWin)) {
        RootlessDamageRegion(pWin, pRegion);
    }
    SCREEN_WRAP(pWin->drawable.pScreen, PaintWindowBorder);
    RL_DEBUG_MSG("paintwindowborder end\n");
}
Пример #5
0
/* changed area is *dest* rect */
static RegionPtr
RootlessCopyArea(DrawablePtr pSrc, DrawablePtr dst, GCPtr pGC,
                 int srcx, int srcy, int w, int h, int dstx, int dsty)
{
    RegionPtr result;
    BoxRec box;

    GC_SAVE(pGC);
    GCOP_UNWRAP(pGC);

    RL_DEBUG_MSG("copy area start (src 0x%x, dst 0x%x)", pSrc, dst);

    if (pSrc->type == DRAWABLE_WINDOW && IsFramedWindow((WindowPtr) pSrc)) {
        /* If both source and dest are windows, and we're doing
           a simple copy operation, we can remove the alpha-protecting
           planemask (since source has opaque alpha as well) */

        if (canAccelBlit(pSrc, pGC)) {
            GC_UNSET_PM(pGC, dst);
        }

        RootlessStartDrawing((WindowPtr) pSrc);
    }
    RootlessStartDrawing((WindowPtr) dst);
    result = pGC->ops->CopyArea(pSrc, dst, pGC, srcx, srcy, w, h, dstx, dsty);

    box.x1 = dstx + dst->x;
    box.x2 = box.x1 + w;
    box.y1 = dsty + dst->y;
    box.y2 = box.y1 + h;

    TRIM_BOX(box, pGC);
    if (BOX_NOT_EMPTY(box))
        RootlessDamageBox((WindowPtr) dst, &box);

    GC_RESTORE(pGC, dst);
    GCOP_WRAP(pGC);
    RL_DEBUG_MSG("copy area end\n");
    return result;
}
Пример #6
0
static void
RootlessGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
               PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
               int nlist, GlyphListPtr list, GlyphPtr *glyphs)
{
    ScreenPtr pScreen = pDst->pDrawable->pScreen;
    PictureScreenPtr ps = GetPictureScreen(pScreen);
    int x, y;
    int n;
    GlyphPtr glyph;
    WindowPtr dstWin;

    dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ?
        (WindowPtr)pDst->pDrawable  :  NULL;

    //SCREEN_UNWRAP(ps, Glyphs);
    ps->Glyphs = SCREENREC(pScreen)->Glyphs;
    ps->Glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
    ps->Glyphs = RootlessGlyphs;
    //SCREEN_WRAP(ps, Glyphs);

    if (dstWin && IsFramedWindow(dstWin)) {
        x = xSrc;
        y = ySrc;
        while (nlist--) {
            x += list->xOff;
            y += list->yOff;
            n = list->len;
            while (n--) {
                glyph = *glyphs++;
                RootlessDamageRect(dstWin,
                                   x - glyph->info.x, y - glyph->info.y,
                                   glyph->info.width, glyph->info.height);
                x += glyph->info.xOff;
                y += glyph->info.yOff;
            }
            list++;
        }
    }
}
Пример #7
0
static void
RootlessGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
               PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
               int nlist, GlyphListPtr list, GlyphPtr *glyphs)
{
    ScreenPtr pScreen = pDst->pDrawable->pScreen;
    PictureScreenPtr ps = GetPictureScreen(pScreen);
    int x, y;
    int n;
    GlyphPtr glyph;
    WindowPtr srcWin, dstWin;

    srcWin = (pSrc->pDrawable && pSrc->pDrawable->type == DRAWABLE_WINDOW) ?
             (WindowPtr)pSrc->pDrawable  :  NULL;
    dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ?
             (WindowPtr)pDst->pDrawable  :  NULL;

    if (srcWin && IsFramedWindow(srcWin)) RootlessStartDrawing(srcWin);
    if (dstWin && IsFramedWindow(dstWin)) RootlessStartDrawing(dstWin);

    //SCREEN_UNWRAP(ps, Glyphs);
    ps->Glyphs = SCREENREC(pScreen)->Glyphs;
    ps->Glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
    ps->Glyphs = RootlessGlyphs;
    //SCREEN_WRAP(ps, Glyphs);

    if (dstWin && IsFramedWindow(dstWin)) {
        x = xSrc;
        y = ySrc;

        while (nlist--) {
            x += list->xOff;
            y += list->yOff;
            n = list->len;

            /* Calling DamageRect for the bounding box of each glyph is
               inefficient. So compute the union of all glyphs in a list
               and damage that. */

            if (n > 0) {
                BoxRec box;

                glyph = *glyphs++;

                box.x1 = x - glyph->info.x;
                box.y1 = y - glyph->info.y;
                box.x2 = box.x1 + glyph->info.width;
                box.y2 = box.y1 + glyph->info.height;

                x += glyph->info.xOff;
                y += glyph->info.yOff;

                while (--n > 0) {
                    short x1, y1, x2, y2;

                    glyph = *glyphs++;

                    x1 = x - glyph->info.x;
                    y1 = y - glyph->info.y;
                    x2 = x1 + glyph->info.width;
                    y2 = y1 + glyph->info.height;

                    box.x1 = max (box.x1, x1);
                    box.y1 = max (box.y1, y1);
                    box.x2 = max (box.x2, x2);
                    box.y2 = max (box.y2, y2);

                    x += glyph->info.xOff;
                    y += glyph->info.yOff;
                }

                RootlessDamageBox(dstWin, &box);
            }
            list++;
        }
    }
}
Пример #8
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;

#ifdef ROOTLESS
    if (!drawable || drawable->type == UNDRAWABLE_WINDOW)
        return;

    if (IsFramedWindow(pWin)) {
        RootlessStartDrawing(pWin);
        RootlessDamageRegion(pWin, prgn);

        if (pWin->backgroundState == ParentRelative) {
            if ((what == PW_BACKGROUND) ||
                (what == PW_BORDER && !pWin->borderIsPixel))
                RootlessSetPixmapOfAncestors(pWin);
        }
    }
#endif

    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;

        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;

#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 = malloc(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);
}