1/*
2   Copyright (c) 1999,2000  The XFree86 Project Inc.
3   based on code written by Mark Vojkovich <markv@valinux.com>
4*/
5
6#ifdef HAVE_CONFIG_H
7#include "config.h"
8#endif
9
10#include "xf86.h"
11#include "xf86_OSproc.h"
12#include "xf86Pci.h"
13#include "shadowfb.h"
14#include "servermd.h"
15#include "cir.h"
16#include "alp.h"
17
18#define MIN(a, b) (((a) < (b)) ? (a) : (b))
19#define MAX(a, b) (((a) > (b)) ? (a) : (b))
20
21_X_EXPORT void
22cirRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
23{
24    CirPtr pCir = CIRPTR(pScrn);
25    int width, height, Bpp, FBPitch, x1, x2, y1, y2;
26    unsigned char *src, *dst;
27
28    Bpp = pScrn->bitsPerPixel >> 3;
29    FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel);
30
31    while(num--) {
32        x1 = MAX(pbox->x1, 0);
33        y1 = MAX(pbox->y1, 0);
34        x2 = MIN(pbox->x2, pScrn->virtualX);
35        y2 = MIN(pbox->y2, pScrn->virtualY);
36
37        width = (x2 - x1) * Bpp;
38        height = y2 - y1;
39
40        if (width <= 0 || height <= 0)
41            continue;
42
43        src = pCir->ShadowPtr + (y1 * pCir->ShadowPitch) + (x1 * Bpp);
44        dst = pCir->FbBase + (y1 * FBPitch) + (x1 * Bpp);
45
46        while(height--) {
47            memcpy(dst, src, width);
48            dst += FBPitch;
49            src += pCir->ShadowPitch;
50        }
51
52        pbox++;
53    }
54}
55
56_X_EXPORT void
57cirPointerMoved(SCRN_ARG_TYPE arg, int x, int y)
58{
59    SCRN_INFO_PTR(arg);
60    CirPtr pCir = CIRPTR(pScrn);
61    int newX, newY;
62
63    if(pCir->rotate == 1) {
64	newX = pScrn->pScreen->height - y - 1;
65	newY = x;
66    } else {
67	newX = y;
68	newY = pScrn->pScreen->width - x - 1;
69    }
70
71    (*pCir->PointerMoved)(arg, newX, newY);
72}
73
74_X_EXPORT void
75cirRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
76{
77    CirPtr pCir = CIRPTR(pScrn);
78    int count, width, height, x1, x2, y1, y2, dstPitch, srcPitch;
79    CARD8 *dstPtr, *srcPtr, *src;
80    CARD32 *dst;
81
82    dstPitch = pScrn->displayWidth;
83    srcPitch = -pCir->rotate * pCir->ShadowPitch;
84
85    while(num--) {
86        x1 = MAX(pbox->x1, 0);
87        y1 = MAX(pbox->y1, 0);
88        x2 = MIN(pbox->x2, pScrn->virtualX);
89        y2 = MIN(pbox->y2, pScrn->virtualY);
90
91        width = x2 - x1;
92        y1 = y1 & ~3;
93        y2 = (y2 + 3) & ~3;
94        height = (y2 - y1) / 4;  /* in dwords */
95
96        if (width <= 0 || height <= 0)
97            continue;
98
99        if(pCir->rotate == 1) {
100            dstPtr = pCir->FbBase +
101			(x1 * dstPitch) + pScrn->virtualX - y2;
102            srcPtr = pCir->ShadowPtr + ((1 - y2) * srcPitch) + x1;
103        } else {
104            dstPtr = pCir->FbBase +
105			((pScrn->virtualY - x2) * dstPitch) + y1;
106            srcPtr = pCir->ShadowPtr + (y1 * srcPitch) + x2 - 1;
107        }
108
109        while(width--) {
110            src = srcPtr;
111            dst = (CARD32*)dstPtr;
112            count = height;
113            while(count--) {
114                *(dst++) = src[0] | (src[srcPitch] << 8) |
115				(src[srcPitch * 2] << 16) |
116				(src[srcPitch * 3] << 24);
117                src += srcPitch * 4;
118            }
119            srcPtr += pCir->rotate;
120            dstPtr += dstPitch;
121        }
122
123        pbox++;
124    }
125}
126
127
128_X_EXPORT void
129cirRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
130{
131    CirPtr pCir = CIRPTR(pScrn);
132    int count, width, height, x1, x2, y1, y2, dstPitch, srcPitch;
133    CARD16 *dstPtr, *srcPtr, *src;
134    CARD32 *dst;
135
136    dstPitch = pScrn->displayWidth;
137    srcPitch = -pCir->rotate * pCir->ShadowPitch >> 1;
138
139    while(num--) {
140        x1 = MAX(pbox->x1, 0);
141        y1 = MAX(pbox->y1, 0);
142        x2 = MIN(pbox->x2, pScrn->virtualX);
143        y2 = MIN(pbox->y2, pScrn->virtualY);
144
145        width = x2 - x1;
146        y1 = y1 & ~1;
147        y2 = (y2 + 1) & ~1;
148        height = (y2 - y1) / 2;  /* in dwords */
149
150        if (width <= 0 || height <= 0)
151            continue;
152
153        if(pCir->rotate == 1) {
154            dstPtr = (CARD16*)pCir->FbBase +
155			(x1 * dstPitch) + pScrn->virtualX - y2;
156            srcPtr = (CARD16*)pCir->ShadowPtr +
157			((1 - y2) * srcPitch) + x1;
158        } else {
159            dstPtr = (CARD16*)pCir->FbBase +
160			((pScrn->virtualY - x2) * dstPitch) + y1;
161            srcPtr = (CARD16*)pCir->ShadowPtr +
162			(y1 * srcPitch) + x2 - 1;
163        }
164
165        while(width--) {
166            src = srcPtr;
167            dst = (CARD32*)dstPtr;
168            count = height;
169            while(count--) {
170                *(dst++) = src[0] | (src[srcPitch] << 16);
171                src += srcPitch * 2;
172            }
173            srcPtr += pCir->rotate;
174            dstPtr += dstPitch;
175        }
176
177        pbox++;
178    }
179}
180
181
182/* this one could be faster */
183_X_EXPORT void
184cirRefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
185{
186    CirPtr pCir = CIRPTR(pScrn);
187    int count, width, height, x1, x2, y1, y2, dstPitch, srcPitch;
188    CARD8 *dstPtr, *srcPtr, *src;
189    CARD32 *dst;
190
191    dstPitch = BitmapBytePad(pScrn->displayWidth * 24);
192    srcPitch = -pCir->rotate * pCir->ShadowPitch;
193
194    while(num--) {
195        x1 = MAX(pbox->x1, 0);
196        y1 = MAX(pbox->y1, 0);
197        x2 = MIN(pbox->x2, pScrn->virtualX);
198        y2 = MIN(pbox->y2, pScrn->virtualY);
199
200        width = x2 - x1;
201        y1 = y1 & ~3;
202        y2 = (y2 + 3) & ~3;
203        height = (y2 - y1) / 4;  /* blocks of 3 dwords */
204
205        if (width <= 0 || height <= 0)
206            continue;
207
208        if(pCir->rotate == 1) {
209            dstPtr = pCir->FbBase +
210			(x1 * dstPitch) + ((pScrn->virtualX - y2) * 3);
211            srcPtr = pCir->ShadowPtr + ((1 - y2) * srcPitch) + (x1 * 3);
212        } else {
213            dstPtr = pCir->FbBase +
214                ((pScrn->virtualY - x2) * dstPitch) + (y1 * 3);
215            srcPtr = pCir->ShadowPtr + (y1 * srcPitch) + (x2 * 3) - 3;
216        }
217
218        while(width--) {
219            src = srcPtr;
220            dst = (CARD32*)dstPtr;
221            count = height;
222            while(count--) {
223                dst[0] = src[0] | (src[1] << 8) | (src[2] << 16) |
224				(src[srcPitch] << 24);
225                dst[1] = src[srcPitch + 1] | (src[srcPitch + 2] << 8) |
226				(src[srcPitch * 2] << 16) |
227				(src[(srcPitch * 2) + 1] << 24);
228                dst[2] = src[(srcPitch * 2) + 2] | (src[srcPitch * 3] << 8) |
229				(src[(srcPitch * 3) + 1] << 16) |
230				(src[(srcPitch * 3) + 2] << 24);
231                dst += 3;
232                src += srcPitch * 4;
233            }
234            srcPtr += pCir->rotate * 3;
235            dstPtr += dstPitch;
236        }
237
238        pbox++;
239    }
240}
241
242_X_EXPORT void
243cirRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
244{
245    CirPtr pCir = CIRPTR(pScrn);
246    int count, width, height, x1, x2, y1, y2, dstPitch, srcPitch;
247    CARD32 *dstPtr, *srcPtr, *src, *dst;
248
249    dstPitch = pScrn->displayWidth;
250    srcPitch = -pCir->rotate * pCir->ShadowPitch >> 2;
251
252    while(num--) {
253        x1 = MAX(pbox->x1, 0);
254        y1 = MAX(pbox->y1, 0);
255        x2 = MIN(pbox->x2, pScrn->virtualX);
256        y2 = MIN(pbox->y2, pScrn->virtualY);
257
258        width = x2 - x1;
259        height = y2 - y1;
260
261        if (width <= 0 || height <= 0)
262            continue;
263
264        if(pCir->rotate == 1) {
265            dstPtr = (CARD32*)pCir->FbBase +
266			(x1 * dstPitch) + pScrn->virtualX - y2;
267            srcPtr = (CARD32*)pCir->ShadowPtr +
268			((1 - y2) * srcPitch) + x1;
269        } else {
270            dstPtr = (CARD32*)pCir->FbBase +
271			((pScrn->virtualY - x2) * dstPitch) + y1;
272            srcPtr = (CARD32*)pCir->ShadowPtr +
273			(y1 * srcPitch) + x2 - 1;
274        }
275
276        while(width--) {
277            src = srcPtr;
278            dst = dstPtr;
279            count = height;
280            while(count--) {
281                *(dst++) = *src;
282                src += srcPitch;
283            }
284            srcPtr += pCir->rotate;
285            dstPtr += dstPitch;
286        }
287
288        pbox++;
289    }
290}
291
292
293
294