SiS_DDC2Delay: initialize variable before adding to it
[xf86-video-sis.git] / src / sis_shadow.c
blobc191ba0126b818a1aa5d2aa3edd5daf217f771ed
1 /*
2 * Copyright (C) 1999-2004 by The XFree86 Project, Inc.
3 * based on code written by Mark Vojkovich
4 * Copyright (C) 2003-2005 Thomas Winischhofer
6 * Licensed under the following terms:
8 * Permission to use, copy, modify, distribute, and sell this software and its
9 * documentation for any purpose is hereby granted without fee, provided that
10 * the above copyright notice appears in all copies and that both that copyright
11 * notice and this permission notice appear in supporting documentation, and
12 * and that the name of the copyright holder not be used in advertising
13 * or publicity pertaining to distribution of the software without specific,
14 * written prior permission. The copyright holder makes no representations
15 * about the suitability of this software for any purpose. It is provided
16 * "as is" without expressed or implied warranty.
18 * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
19 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
20 * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
21 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
22 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
23 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
24 * PERFORMANCE OF THIS SOFTWARE.
26 * This module doesn't use CurrentLayout, because it is never
27 * active when DGA is active and vice versa.
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
34 #include "sis.h"
35 #include "servermd.h"
37 void SISPointerMoved(SCRN_ARG_TYPE arg, int x, int y);
38 void SISPointerMovedReflect(SCRN_ARG_TYPE arg, int x, int y);
39 void SISRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
40 void SISRefreshAreaReflect(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
41 void SISRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
42 void SISRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
43 void SISRefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
44 void SISRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
46 void
47 SISPointerMoved(SCRN_ARG_TYPE arg, int x, int y)
49 SCRN_INFO_PTR(arg);
50 SISPtr pSiS = SISPTR(pScrn);
52 if(pSiS->Rotate == 1) {
53 (*pSiS->PointerMoved)(arg, pScrn->pScreen->height - y - 1, x);
54 } else {
55 (*pSiS->PointerMoved)(arg, y, pScrn->pScreen->width - x - 1);
59 void
60 SISPointerMovedReflect(SCRN_ARG_TYPE arg, int x, int y)
62 SCRN_INFO_PTR(arg);
63 SISPtr pSiS = SISPTR(pScrn);
65 switch(pSiS->Reflect) {
66 case 1: /* x */
67 (*pSiS->PointerMoved)(arg, pScrn->pScreen->width - x - 1, y);
68 break;
69 case 2: /* y */
70 (*pSiS->PointerMoved)(arg, x, pScrn->pScreen->height - y - 1);
71 break;
72 case 3: /* x + y */
73 (*pSiS->PointerMoved)(arg, pScrn->pScreen->width - x - 1, pScrn->pScreen->height - y - 1);
77 /* Refresh area (unreflected, unrotated) */
79 void
80 SISRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
82 SISPtr pSiS = SISPTR(pScrn);
83 int width, height, Bpp, FBPitch;
84 CARD8 *src, *dst;
86 Bpp = pScrn->bitsPerPixel >> 3;
87 FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel);
89 while(num--) {
91 width = (pbox->x2 - pbox->x1) * Bpp;
92 height = pbox->y2 - pbox->y1;
93 src = pSiS->ShadowPtr + (pbox->y1 * pSiS->ShadowPitch) + (pbox->x1 * Bpp);
94 dst = pSiS->FbBase + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp);
96 while(height--) {
97 SiSMemCopyToVideoRam(pSiS, dst, src, width);
98 dst += FBPitch;
99 src += pSiS->ShadowPitch;
102 pbox++;
106 /* RefreshArea for reflection */
108 void
109 SISRefreshAreaReflect(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
111 SISPtr pSiS = SISPTR(pScrn);
112 int width, height, Bpp, FBPitch, twidth;
113 CARD8 *src, *dst, *tdst, *tsrc;
114 CARD16 *tdst16, *tsrc16;
115 CARD32 *tdst32, *tsrc32;
117 Bpp = pScrn->bitsPerPixel >> 3;
118 FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel);
120 while(num--) {
121 width = (pbox->x2 - pbox->x1) * Bpp;
122 height = pbox->y2 - pbox->y1;
123 src = pSiS->ShadowPtr + (pbox->y1 * pSiS->ShadowPitch) + (pbox->x1 * Bpp);
124 dst = pSiS->FbBase;
125 switch(pSiS->Reflect) {
126 case 1: /* x */
127 dst += (pbox->y1 * FBPitch) + ((pScrn->displayWidth - pbox->x1 - 1) * Bpp);
128 switch(Bpp) {
129 case 1:
130 while(height--) {
131 tdst = dst;
132 tsrc = src;
133 twidth = width;
134 while(twidth--) *tdst-- = *tsrc++;
135 dst += FBPitch;
136 src += pSiS->ShadowPitch;
138 break;
139 case 2:
140 width >>= 1;
141 while(height--) {
142 tdst16 = (CARD16 *)dst;
143 tsrc16 = (CARD16 *)src;
144 twidth = width;
145 while(twidth--) *tdst16-- = *tsrc16++;
146 dst += FBPitch;
147 src += pSiS->ShadowPitch;
149 break;
150 case 4:
151 width >>= 2;
152 while(height--) {
153 tdst32 = (CARD32 *)dst;
154 tsrc32 = (CARD32 *)src;
155 twidth = width;
156 while(twidth--) *tdst32-- = *tsrc32++;
157 dst += FBPitch;
158 src += pSiS->ShadowPitch;
161 break;
162 case 2: /* y */
163 dst += ((pScrn->virtualY - pbox->y1 - 1) * FBPitch) + (pbox->x1 * Bpp);
164 while(height--) {
165 SiSMemCopyToVideoRam(pSiS, dst, src, width);
166 dst -= FBPitch;
167 src += pSiS->ShadowPitch;
169 break;
170 case 3: /* x + y */
171 dst += ((pScrn->virtualY - pbox->y1 - 1) * FBPitch) + ((pScrn->displayWidth - pbox->x1 - 1) * Bpp);
172 switch(Bpp) {
173 case 1:
174 while(height--) {
175 tdst = dst;
176 tsrc = src;
177 twidth = width;
178 while(twidth--) *tdst-- = *tsrc++;
179 dst -= FBPitch;
180 src += pSiS->ShadowPitch;
182 break;
183 case 2:
184 width >>= 1;
185 while(height--) {
186 tdst16 = (CARD16 *)dst;
187 tsrc16 = (CARD16 *)src;
188 twidth = width;
189 while(twidth--) *tdst16-- = *tsrc16++;
190 dst -= FBPitch;
191 src += pSiS->ShadowPitch;
193 break;
194 case 4:
195 width >>= 2;
196 while(height--) {
197 tdst32 = (CARD32 *)dst;
198 tsrc32 = (CARD32 *)src;
199 twidth = width;
200 while(twidth--) *tdst32-- = *tsrc32++;
201 dst -= FBPitch;
202 src += pSiS->ShadowPitch;
204 break;
207 pbox++;
211 /* RefreshArea()s for rotation */
213 void
214 SISRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
216 SISPtr pSiS = SISPTR(pScrn);
217 int count, width, height, y1, y2, dstPitch, srcPitch;
218 CARD8 *dstPtr, *srcPtr, *src;
219 CARD32 *dst;
221 dstPitch = pScrn->displayWidth;
222 srcPitch = -pSiS->Rotate * pSiS->ShadowPitch;
224 while(num--) {
225 width = pbox->x2 - pbox->x1;
226 y1 = pbox->y1 & ~3;
227 y2 = (pbox->y2 + 3) & ~3;
228 height = (y2 - y1) >> 2; /* in dwords */
230 if(pSiS->Rotate == 1) {
231 dstPtr = pSiS->FbBase + (pbox->x1 * dstPitch) + pScrn->virtualX - y2;
232 srcPtr = pSiS->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1;
233 } else {
234 dstPtr = pSiS->FbBase + ((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
235 srcPtr = pSiS->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1;
238 while(width--) {
239 src = srcPtr;
240 dst = (CARD32 *)dstPtr;
241 count = height;
242 while(count--) {
243 *(dst++) = src[0] |
244 (src[srcPitch] << 8) |
245 (src[srcPitch * 2] << 16) |
246 (src[srcPitch * 3] << 24);
247 src += (srcPitch * 4);
249 srcPtr += pSiS->Rotate;
250 dstPtr += dstPitch;
253 pbox++;
257 void
258 SISRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
260 SISPtr pSiS = SISPTR(pScrn);
261 int count, width, height, y1, y2, dstPitch, srcPitch;
262 CARD16 *dstPtr, *srcPtr, *src;
263 CARD32 *dst;
265 dstPitch = pScrn->displayWidth;
266 srcPitch = -pSiS->Rotate * pSiS->ShadowPitch >> 1;
268 while(num--) {
269 width = pbox->x2 - pbox->x1;
270 y1 = pbox->y1 & ~1;
271 y2 = (pbox->y2 + 1) & ~1;
272 height = (y2 - y1) >> 1; /* in dwords */
274 if(pSiS->Rotate == 1) {
275 dstPtr = (CARD16 *)pSiS->FbBase + (pbox->x1 * dstPitch) + pScrn->virtualX - y2;
276 srcPtr = (CARD16 *)pSiS->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1;
277 } else {
278 dstPtr = (CARD16 *)pSiS->FbBase + ((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
279 srcPtr = (CARD16 *)pSiS->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1;
282 while(width--) {
283 src = srcPtr;
284 dst = (CARD32 *)dstPtr;
285 count = height;
286 while(count--) {
287 *(dst++) = src[0] | (src[srcPitch] << 16);
288 src += (srcPitch * 2);
290 srcPtr += pSiS->Rotate;
291 dstPtr += dstPitch;
294 pbox++;
298 /* this one could be faster */
299 void
300 SISRefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
302 SISPtr pSiS = SISPTR(pScrn);
303 int count, width, height, y1, y2, dstPitch, srcPitch;
304 CARD8 *dstPtr, *srcPtr, *src;
305 CARD32 *dst;
307 dstPitch = BitmapBytePad(pScrn->displayWidth * 24);
308 srcPitch = -pSiS->Rotate * pSiS->ShadowPitch;
310 while(num--) {
311 width = pbox->x2 - pbox->x1;
312 y1 = pbox->y1 & ~3;
313 y2 = (pbox->y2 + 3) & ~3;
314 height = (y2 - y1) >> 2; /* blocks of 3 dwords */
316 if(pSiS->Rotate == 1) {
317 dstPtr = pSiS->FbBase + (pbox->x1 * dstPitch) + ((pScrn->virtualX - y2) * 3);
318 srcPtr = pSiS->ShadowPtr + ((1 - y2) * srcPitch) + (pbox->x1 * 3);
319 } else {
320 dstPtr = pSiS->FbBase + ((pScrn->virtualY - pbox->x2) * dstPitch) + (y1 * 3);
321 srcPtr = pSiS->ShadowPtr + (y1 * srcPitch) + (pbox->x2 * 3) - 3;
324 while(width--) {
325 src = srcPtr;
326 dst = (CARD32 *)dstPtr;
327 count = height;
328 while(count--) {
329 dst[0] = src[0] |
330 (src[1] << 8) |
331 (src[2] << 16) |
332 (src[srcPitch] << 24);
333 dst[1] = src[srcPitch + 1] |
334 (src[srcPitch + 2] << 8) |
335 (src[srcPitch * 2] << 16) |
336 (src[(srcPitch * 2) + 1] << 24);
337 dst[2] = src[(srcPitch * 2) + 2] |
338 (src[srcPitch * 3] << 8) |
339 (src[(srcPitch * 3) + 1] << 16) |
340 (src[(srcPitch * 3) + 2] << 24);
341 dst += 3;
342 src += (srcPitch << 2);
344 srcPtr += pSiS->Rotate * 3;
345 dstPtr += dstPitch;
348 pbox++;
352 void
353 SISRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
355 SISPtr pSiS = SISPTR(pScrn);
356 int count, width, height, dstPitch, srcPitch;
357 CARD32 *dstPtr, *srcPtr, *src, *dst;
359 dstPitch = pScrn->displayWidth;
360 srcPitch = -pSiS->Rotate * pSiS->ShadowPitch >> 2;
362 while(num--) {
363 width = pbox->x2 - pbox->x1;
364 height = pbox->y2 - pbox->y1;
366 if(pSiS->Rotate == 1) {
367 dstPtr = (CARD32 *)pSiS->FbBase + (pbox->x1 * dstPitch) + pScrn->virtualX - pbox->y2;
368 srcPtr = (CARD32 *)pSiS->ShadowPtr + ((1 - pbox->y2) * srcPitch) + pbox->x1;
369 } else {
370 dstPtr = (CARD32 *)pSiS->FbBase + ((pScrn->virtualY - pbox->x2) * dstPitch) + pbox->y1;
371 srcPtr = (CARD32 *)pSiS->ShadowPtr + (pbox->y1 * srcPitch) + pbox->x2 - 1;
374 while(width--) {
375 src = srcPtr;
376 dst = dstPtr;
377 count = height;
378 while(count--) {
379 *(dst++) = *src;
380 src += srcPitch;
382 srcPtr += pSiS->Rotate;
383 dstPtr += dstPitch;
386 pbox++;