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, shadowBufPtr pBuf) 98{ 99 RegionPtr damage = DamageRegion(pBuf->pDamage); 100 PixmapPtr pShadow = pBuf->pPixmap; 101 int nbox = RegionNumRects(damage); 102 BoxPtr pbox = RegionRects(damage); 103 FbBits *shaBits; 104 Data *shaBase, *shaLine, *sha; 105 FbStride shaStride; 106 int scrBase, scrLine, scr; 107 int shaBpp; 108 _X_UNUSED int shaXoff, shaYoff; 109 int x, y, w, h, width; 110 int i; 111 Data *winBase = NULL, *win; 112 CARD32 winSize; 113 114 fbGetDrawable(&pShadow->drawable, shaBits, shaStride, shaBpp, shaXoff, 115 shaYoff); 116 shaBase = (Data *) shaBits; 117 shaStride = shaStride * sizeof(FbBits) / sizeof(Data); 118#if (DANDEBUG > 1) 119 ErrorF 120 ("-> Entering Shadow Update:\r\n |- Origins: pShadow=%x, pScreen=%x, damage=%x\r\n |- Metrics: shaStride=%d, shaBase=%x, shaBpp=%d\r\n | \n", 121 pShadow, pScreen, damage, shaStride, shaBase, shaBpp); 122#endif 123 while (nbox--) { 124 x = pbox->x1; 125 y = pbox->y1; 126 w = (pbox->x2 - pbox->x1); 127 h = pbox->y2 - pbox->y1; 128 129#if (DANDEBUG > 2) 130 ErrorF 131 (" |-> Redrawing box - Metrics: X=%d, Y=%d, Width=%d, Height=%d\n", 132 x, y, w, h); 133#endif 134 scrLine = SCRLEFT(x, y, w, h); 135 shaLine = shaBase + FIRSTSHA(x, y, w, h); 136 137 while (STEPDOWN(x, y, w, h)) { 138 winSize = 0; 139 scrBase = 0; 140 width = SCRWIDTH(x, y, w, h); 141 scr = scrLine; 142 sha = shaLine; 143#if (DANDEBUG > 3) 144 ErrorF(" | |-> StepDown - Metrics: width=%d, scr=%x, sha=%x\n", 145 width, scr, sha); 146#endif 147 while (width) { 148 /* how much remains in this window */ 149 i = scrBase + winSize - scr; 150 if (i <= 0 || scr < scrBase) { 151 winBase = (Data *) (*pBuf->window) (pScreen, 152 SCRY(x, y, w, h), 153 scr * sizeof(Data), 154 SHADOW_WINDOW_WRITE, 155 &winSize, 156 pBuf->closure); 157 if (!winBase) 158 return; 159 scrBase = scr; 160 winSize /= sizeof(Data); 161 i = winSize; 162#if(DANDEBUG > 4) 163 ErrorF 164 (" | | |-> Starting New Line - Metrics: winBase=%x, scrBase=%x, winSize=%d\r\n | | | Xstride=%d, Ystride=%d, w=%d h=%d\n", 165 winBase, scrBase, winSize, SHASTEPX(shaStride), 166 SHASTEPY(shaStride), w, h); 167#endif 168 } 169 win = winBase + (scr - scrBase); 170 if (i > width) 171 i = width; 172 width -= i; 173 scr += i; 174#if(DANDEBUG > 5) 175 ErrorF 176 (" | | |-> Writing Line - Metrics: win=%x, sha=%x\n", 177 win, sha); 178#endif 179 while (i--) { 180#if(DANDEBUG > 6) 181 ErrorF 182 (" | | |-> Writing Pixel - Metrics: win=%x, sha=%d, remaining=%d\n", 183 win, sha, i); 184#endif 185 *win++ = *sha; 186 sha += SHASTEPX(shaStride); 187 } /* i */ 188 } /* width */ 189 shaLine += SHASTEPY(shaStride); 190 NEXTY(x, y, w, h); 191 } /* STEPDOWN */ 192 pbox++; 193 } /* nbox */ 194} 195