| 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 | |
| 96 | void |
| 97 | FUNC(ScreenPtr pScreen, shadowBufPtr pBuf) |
| 98 | { |
| 99 | RegionPtr damage = shadowDamage(pBuf); |
| 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 | } |