040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync/*
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync *
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * Copyright © 2000 Keith Packard
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync *
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * Permission to use, copy, modify, distribute, and sell this software and its
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * documentation for any purpose is hereby granted without fee, provided that
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * the above copyright notice appear in all copies and that both that
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * copyright notice and this permission notice appear in supporting
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * documentation, and that the name of Keith Packard not be used in
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * advertising or publicity pertaining to distribution of the software without
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * specific, written prior permission. Keith Packard makes no
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * representations about the suitability of this software for any purpose. It
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * is provided "as is" without express or implied warranty.
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync *
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * PERFORMANCE OF THIS SOFTWARE.
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync */
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync/*
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * Thanks to Daniel Chemko <dchemko@intrinsyc.com> for making the 90 and 180
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync * orientations work.
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync */
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#ifdef HAVE_DIX_CONFIG_H
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#include <dix-config.h>
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#endif
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#include <stdlib.h>
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#include <X11/X.h>
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#include "scrnintstr.h"
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#include "windowstr.h"
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#include <X11/fonts/font.h>
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#include "dixfontstr.h"
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#include <X11/fonts/fontstruct.h>
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#include "mi.h"
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#include "regionstr.h"
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#include "globals.h"
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#include "gcstruct.h"
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#include "shadow.h"
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#include "fb.h"
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#define DANDEBUG 0
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#if ROTATE == 270
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#define SCRLEFT(x,y,w,h) (pScreen->height - ((y) + (h)))
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#define SCRY(x,y,w,h) (x)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#define SCRWIDTH(x,y,w,h) (h)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#define FIRSTSHA(x,y,w,h) (((y) + (h) - 1) * shaStride + (x))
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#define STEPDOWN(x,y,w,h) ((w)--)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#define NEXTY(x,y,w,h) ((x)++)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#define SHASTEPX(stride) -(stride)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#define SHASTEPY(stride) (1)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#elif ROTATE == 90
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#define SCRLEFT(x,y,w,h) (y)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#define SCRY(x,y,w,h) (pScreen->width - ((x) + (w)) - 1)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#define SCRWIDTH(x,y,w,h) (h)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#define FIRSTSHA(x,y,w,h) ((y) * shaStride + (x + w - 1))
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#define STEPDOWN(x,y,w,h) ((w)--)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#define NEXTY(x,y,w,h) ((void)(x))
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#define SHASTEPX(stride) (stride)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#define SHASTEPY(stride) (-1)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#elif ROTATE == 180
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#define SCRLEFT(x,y,w,h) (pScreen->width - ((x) + (w)))
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#define SCRY(x,y,w,h) (pScreen->height - ((y) + (h)) - 1)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#define SCRWIDTH(x,y,w,h) (w)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#define FIRSTSHA(x,y,w,h) ((y + h - 1) * shaStride + (x + w - 1))
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#define STEPDOWN(x,y,w,h) ((h)--)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#define NEXTY(x,y,w,h) ((void)(y))
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#define SHASTEPX(stride) (-1)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#define SHASTEPY(stride) -(stride)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#else
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#define SCRLEFT(x,y,w,h) (x)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#define SCRY(x,y,w,h) (y)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#define SCRWIDTH(x,y,w,h) (w)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#define FIRSTSHA(x,y,w,h) ((y) * shaStride + (x))
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#define STEPDOWN(x,y,w,h) ((h)--)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#define NEXTY(x,y,w,h) ((y)++)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#define SHASTEPX(stride) (1)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#define SHASTEPY(stride) (stride)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#endif
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsyncvoid
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsyncFUNC (ScreenPtr pScreen,
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync shadowBufPtr pBuf)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync{
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync RegionPtr damage = shadowDamage (pBuf);
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync PixmapPtr pShadow = pBuf->pPixmap;
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync int nbox = REGION_NUM_RECTS (damage);
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync BoxPtr pbox = REGION_RECTS (damage);
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync FbBits *shaBits;
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync Data *shaBase, *shaLine, *sha;
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync FbStride shaStride;
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync int scrBase, scrLine, scr;
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync int shaBpp;
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync int shaXoff, shaYoff; /* XXX assumed to be zero */
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync int x, y, w, h, width;
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync int i;
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync Data *winBase = NULL, *win;
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync CARD32 winSize;
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync fbGetDrawable (&pShadow->drawable, shaBits, shaStride, shaBpp, shaXoff, shaYoff);
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync shaBase = (Data *) shaBits;
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync shaStride = shaStride * sizeof (FbBits) / sizeof (Data);
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#if (DANDEBUG > 1)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync ErrorF ("-> Entering Shadow Update:\r\n |- Origins: pShadow=%x, pScreen=%x, damage=%x\r\n |- Metrics: shaStride=%d, shaBase=%x, shaBpp=%d\r\n | \n", pShadow, pScreen, damage, shaStride, shaBase, shaBpp);
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#endif
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync while (nbox--)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync {
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync x = pbox->x1;
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync y = pbox->y1;
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync w = (pbox->x2 - pbox->x1);
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync h = pbox->y2 - pbox->y1;
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#if (DANDEBUG > 2)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync ErrorF (" |-> Redrawing box - Metrics: X=%d, Y=%d, Width=%d, Height=%d\n", x, y, w, h);
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#endif
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync scrLine = SCRLEFT(x,y,w,h);
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync shaLine = shaBase + FIRSTSHA(x,y,w,h);
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync while (STEPDOWN(x,y,w,h))
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync {
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync winSize = 0;
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync scrBase = 0;
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync width = SCRWIDTH(x,y,w,h);
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync scr = scrLine;
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync sha = shaLine;
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#if (DANDEBUG > 3)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync ErrorF (" | |-> StepDown - Metrics: width=%d, scr=%x, sha=%x\n", width, scr, sha);
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#endif
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync while (width)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync {
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync /* how much remains in this window */
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync i = scrBase + winSize - scr;
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync if (i <= 0 || scr < scrBase)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync {
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync winBase = (Data *) (*pBuf->window) (pScreen,
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync SCRY(x,y,w,h),
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync scr * sizeof (Data),
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync SHADOW_WINDOW_WRITE,
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync &winSize,
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync pBuf->closure);
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync if(!winBase)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync return;
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync scrBase = scr;
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync winSize /= sizeof (Data);
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync i = winSize;
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#if(DANDEBUG > 4)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync ErrorF (" | | |-> Starting New Line - Metrics: winBase=%x, scrBase=%x, winSize=%d\r\n | | | Xstride=%d, Ystride=%d, w=%d h=%d\n", winBase, scrBase, winSize, SHASTEPX(shaStride), SHASTEPY(shaStride), w, h);
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#endif
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync }
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync win = winBase + (scr - scrBase);
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync if (i > width)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync i = width;
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync width -= i;
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync scr += i;
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#if(DANDEBUG > 5)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync ErrorF (" | | |-> Writing Line - Metrics: win=%x, sha=%x\n", win, sha);
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#endif
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync while (i--)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync {
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#if(DANDEBUG > 6)
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync ErrorF (" | | |-> Writing Pixel - Metrics: win=%x, sha=%d, remaining=%d\n", win, sha, i);
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync#endif
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync *win++ = *sha;
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync sha += SHASTEPX(shaStride);
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync } /* i */
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync } /* width */
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync shaLine += SHASTEPY(shaStride);
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync NEXTY(x,y,w,h);
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync } /* STEPDOWN */
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync pbox++;
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync } /* nbox */
040abec2534dadc53ebc8fa378ef03f4feecb7dbvboxsync}