1/* 2 * 3 * Copyright © 2000 Keith Packard 4 * 5 * Permission to use, copy, modify, distribute, and sell this software and its 6 * documentation for any purpose is hereby granted without fee, provided that 7 * the above copyright notice appear in all copies and that both that 8 * copyright notice and this permission notice appear in supporting 9 * documentation, and that the name of Keith Packard not be used in 10 * advertising or publicity pertaining to distribution of the software without 11 * specific, written prior permission. Keith Packard makes no 12 * representations about the suitability of this software for any purpose. It 13 * is provided "as is" without express or implied warranty. 14 * 15 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 17 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 19 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 20 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21 * PERFORMANCE OF THIS SOFTWARE. 22 */ 23 24/* 25 * Thanks to Daniel Chemko <dchemko@intrinsyc.com> for making the 90 and 180 26 * orientations work. 27 */ 28 29#ifdef HAVE_DIX_CONFIG_H 30#include <dix-config.h> 31#endif 32 33#include <stdlib.h> 34 35#include <X11/X.h> 36#include "scrnintstr.h" 37#include "windowstr.h" 38#include <X11/fonts/font.h> 39#include "dixfontstr.h" 40#include <X11/fonts/fontstruct.h> 41#include "mi.h" 42#include "regionstr.h" 43#include "globals.h" 44#include "gcstruct.h" 45#include "shadow.h" 46#include "fb.h" 47 48#define DANDEBUG 0 49 50#if ROTATE == 270 51 52#define SCRLEFT(x,y,w,h) (pScreen->height - ((y) + (h))) 53#define SCRY(x,y,w,h) (x) 54#define SCRWIDTH(x,y,w,h) (h) 55#define FIRSTSHA(x,y,w,h) (((y) + (h) - 1) * shaStride + (x)) 56#define STEPDOWN(x,y,w,h) ((w)--) 57#define NEXTY(x,y,w,h) ((x)++) 58#define SHASTEPX(stride) -(stride) 59#define SHASTEPY(stride) (1) 60 61#elif ROTATE == 90 62 63#define SCRLEFT(x,y,w,h) (y) 64#define SCRY(x,y,w,h) (pScreen->width - ((x) + (w)) - 1) 65#define SCRWIDTH(x,y,w,h) (h) 66#define FIRSTSHA(x,y,w,h) ((y) * shaStride + (x + w - 1)) 67#define STEPDOWN(x,y,w,h) ((w)--) 68#define NEXTY(x,y,w,h) ((void)(x)) 69#define SHASTEPX(stride) (stride) 70#define SHASTEPY(stride) (-1) 71 72#elif ROTATE == 180 73 74#define SCRLEFT(x,y,w,h) (pScreen->width - ((x) + (w))) 75#define SCRY(x,y,w,h) (pScreen->height - ((y) + (h)) - 1) 76#define SCRWIDTH(x,y,w,h) (w) 77#define FIRSTSHA(x,y,w,h) ((y + h - 1) * shaStride + (x + w - 1)) 78#define STEPDOWN(x,y,w,h) ((h)--) 79#define NEXTY(x,y,w,h) ((void)(y)) 80#define SHASTEPX(stride) (-1) 81#define SHASTEPY(stride) -(stride) 82 83#else 84 85#define SCRLEFT(x,y,w,h) (x) 86#define SCRY(x,y,w,h) (y) 87#define SCRWIDTH(x,y,w,h) (w) 88#define FIRSTSHA(x,y,w,h) ((y) * shaStride + (x)) 89#define STEPDOWN(x,y,w,h) ((h)--) 90#define NEXTY(x,y,w,h) ((y)++) 91#define SHASTEPX(stride) (1) 92#define SHASTEPY(stride) (stride) 93 94#endif 95 96void 97FUNC (ScreenPtr pScreen, 98 shadowBufPtr pBuf) 99{ 100 RegionPtr damage = shadowDamage (pBuf); 101 PixmapPtr pShadow = pBuf->pPixmap; 102 int nbox = RegionNumRects (damage); 103 BoxPtr pbox = RegionRects (damage); 104 FbBits *shaBits; 105 Data *shaBase, *shaLine, *sha; 106 FbStride shaStride; 107 int scrBase, scrLine, scr; 108 int shaBpp; 109 int shaXoff, shaYoff; /* XXX assumed to be zero */ 110 int x, y, w, h, width; 111 int i; 112 Data *winBase = NULL, *win; 113 CARD32 winSize; 114 115 fbGetDrawable (&pShadow->drawable, shaBits, shaStride, shaBpp, shaXoff, shaYoff); 116 shaBase = (Data *) shaBits; 117 shaStride = shaStride * sizeof (FbBits) / sizeof (Data); 118#if (DANDEBUG > 1) 119 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); 120#endif 121 while (nbox--) 122 { 123 x = pbox->x1; 124 y = pbox->y1; 125 w = (pbox->x2 - pbox->x1); 126 h = pbox->y2 - pbox->y1; 127 128#if (DANDEBUG > 2) 129 ErrorF (" |-> Redrawing box - Metrics: X=%d, Y=%d, Width=%d, Height=%d\n", x, y, w, h); 130#endif 131 scrLine = SCRLEFT(x,y,w,h); 132 shaLine = shaBase + FIRSTSHA(x,y,w,h); 133 134 while (STEPDOWN(x,y,w,h)) 135 { 136 winSize = 0; 137 scrBase = 0; 138 width = SCRWIDTH(x,y,w,h); 139 scr = scrLine; 140 sha = shaLine; 141#if (DANDEBUG > 3) 142 ErrorF (" | |-> StepDown - Metrics: width=%d, scr=%x, sha=%x\n", width, scr, sha); 143#endif 144 while (width) 145 { 146 /* how much remains in this window */ 147 i = scrBase + winSize - scr; 148 if (i <= 0 || scr < scrBase) 149 { 150 winBase = (Data *) (*pBuf->window) (pScreen, 151 SCRY(x,y,w,h), 152 scr * sizeof (Data), 153 SHADOW_WINDOW_WRITE, 154 &winSize, 155 pBuf->closure); 156 if(!winBase) 157 return; 158 scrBase = scr; 159 winSize /= sizeof (Data); 160 i = winSize; 161#if(DANDEBUG > 4) 162 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); 163#endif 164 } 165 win = winBase + (scr - scrBase); 166 if (i > width) 167 i = width; 168 width -= i; 169 scr += i; 170#if(DANDEBUG > 5) 171 ErrorF (" | | |-> Writing Line - Metrics: win=%x, sha=%x\n", win, sha); 172#endif 173 while (i--) 174 { 175#if(DANDEBUG > 6) 176 ErrorF (" | | |-> Writing Pixel - Metrics: win=%x, sha=%d, remaining=%d\n", win, sha, i); 177#endif 178 *win++ = *sha; 179 sha += SHASTEPX(shaStride); 180 } /* i */ 181 } /* width */ 182 shaLine += SHASTEPY(shaStride); 183 NEXTY(x,y,w,h); 184 } /* STEPDOWN */ 185 pbox++; 186 } /* nbox */ 187} 188