105b261ecSmrg/*
205b261ecSmrg *
305b261ecSmrg * Copyright © 2000 Keith Packard
405b261ecSmrg *
505b261ecSmrg * Permission to use, copy, modify, distribute, and sell this software and its
605b261ecSmrg * documentation for any purpose is hereby granted without fee, provided that
705b261ecSmrg * the above copyright notice appear in all copies and that both that
805b261ecSmrg * copyright notice and this permission notice appear in supporting
905b261ecSmrg * documentation, and that the name of Keith Packard not be used in
1005b261ecSmrg * advertising or publicity pertaining to distribution of the software without
1105b261ecSmrg * specific, written prior permission.  Keith Packard makes no
1205b261ecSmrg * representations about the suitability of this software for any purpose.  It
1305b261ecSmrg * is provided "as is" without express or implied warranty.
1405b261ecSmrg *
1505b261ecSmrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
1605b261ecSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
1705b261ecSmrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
1805b261ecSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
1905b261ecSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
2005b261ecSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2105b261ecSmrg * PERFORMANCE OF THIS SOFTWARE.
2205b261ecSmrg */
2305b261ecSmrg
2405b261ecSmrg#ifdef HAVE_DIX_CONFIG_H
2505b261ecSmrg#include <dix-config.h>
2605b261ecSmrg#endif
2705b261ecSmrg
2805b261ecSmrg#include <stdlib.h>
2905b261ecSmrg
3005b261ecSmrg#include    <X11/X.h>
3105b261ecSmrg#include    "scrnintstr.h"
3205b261ecSmrg#include    "windowstr.h"
3305b261ecSmrg#include    <X11/fonts/font.h>
3405b261ecSmrg#include    "dixfontstr.h"
3505b261ecSmrg#include    <X11/fonts/fontstruct.h>
3605b261ecSmrg#include    "mi.h"
3705b261ecSmrg#include    "regionstr.h"
3805b261ecSmrg#include    "globals.h"
3905b261ecSmrg#include    "gcstruct.h"
4005b261ecSmrg#include    "shadow.h"
4105b261ecSmrg#include    "fb.h"
4205b261ecSmrg
4305b261ecSmrgvoid
4435c4bbdfSmrgshadowUpdatePacked(ScreenPtr pScreen, shadowBufPtr pBuf)
4505b261ecSmrg{
461b5d61b8Smrg    RegionPtr damage = DamageRegion(pBuf->pDamage);
4735c4bbdfSmrg    PixmapPtr pShadow = pBuf->pPixmap;
4835c4bbdfSmrg    int nbox = RegionNumRects(damage);
4935c4bbdfSmrg    BoxPtr pbox = RegionRects(damage);
5035c4bbdfSmrg    FbBits *shaBase, *shaLine, *sha;
5135c4bbdfSmrg    FbStride shaStride;
5235c4bbdfSmrg    int scrBase, scrLine, scr;
5335c4bbdfSmrg    int shaBpp;
5435c4bbdfSmrg    _X_UNUSED int shaXoff, shaYoff;
5535c4bbdfSmrg    int x, y, w, h, width;
5635c4bbdfSmrg    int i;
5735c4bbdfSmrg    FbBits *winBase = NULL, *win;
5835c4bbdfSmrg    CARD32 winSize;
5905b261ecSmrg
6035c4bbdfSmrg    fbGetDrawable(&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff,
6135c4bbdfSmrg                  shaYoff);
6235c4bbdfSmrg    while (nbox--) {
6335c4bbdfSmrg        x = pbox->x1 * shaBpp;
6435c4bbdfSmrg        y = pbox->y1;
6535c4bbdfSmrg        w = (pbox->x2 - pbox->x1) * shaBpp;
6635c4bbdfSmrg        h = pbox->y2 - pbox->y1;
6705b261ecSmrg
6835c4bbdfSmrg        scrLine = (x >> FB_SHIFT);
6935c4bbdfSmrg        shaLine = shaBase + y * shaStride + (x >> FB_SHIFT);
7035c4bbdfSmrg
7135c4bbdfSmrg        x &= FB_MASK;
7235c4bbdfSmrg        w = (w + x + FB_MASK) >> FB_SHIFT;
7335c4bbdfSmrg
7435c4bbdfSmrg        while (h--) {
7535c4bbdfSmrg            winSize = 0;
7635c4bbdfSmrg            scrBase = 0;
7735c4bbdfSmrg            width = w;
7835c4bbdfSmrg            scr = scrLine;
7935c4bbdfSmrg            sha = shaLine;
8035c4bbdfSmrg            while (width) {
8135c4bbdfSmrg                /* how much remains in this window */
8235c4bbdfSmrg                i = scrBase + winSize - scr;
8335c4bbdfSmrg                if (i <= 0 || scr < scrBase) {
8435c4bbdfSmrg                    winBase = (FbBits *) (*pBuf->window) (pScreen,
8535c4bbdfSmrg                                                          y,
8635c4bbdfSmrg                                                          scr * sizeof(FbBits),
8735c4bbdfSmrg                                                          SHADOW_WINDOW_WRITE,
8835c4bbdfSmrg                                                          &winSize,
8935c4bbdfSmrg                                                          pBuf->closure);
9035c4bbdfSmrg                    if (!winBase)
9135c4bbdfSmrg                        return;
9235c4bbdfSmrg                    scrBase = scr;
9335c4bbdfSmrg                    winSize /= sizeof(FbBits);
9435c4bbdfSmrg                    i = winSize;
9535c4bbdfSmrg                }
9635c4bbdfSmrg                win = winBase + (scr - scrBase);
9735c4bbdfSmrg                if (i > width)
9835c4bbdfSmrg                    i = width;
9935c4bbdfSmrg                width -= i;
10035c4bbdfSmrg                scr += i;
10135c4bbdfSmrg                memcpy(win, sha, i * sizeof(FbBits));
10235c4bbdfSmrg                sha += i;
10335c4bbdfSmrg            }
10435c4bbdfSmrg            shaLine += shaStride;
10535c4bbdfSmrg            y++;
10635c4bbdfSmrg        }
10735c4bbdfSmrg        pbox++;
10805b261ecSmrg    }
10905b261ecSmrg}
110