1
2/*
3Copyright (C) 1994-2000 The XFree86 Project, Inc.  All Rights Reserved.
4
5Permission is hereby granted, free of charge, to any person obtaining a copy of
6this software and associated documentation files (the "Software"), to deal in
7the Software without restriction, including without limitation the rights to
8use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9of the Software, and to permit persons to whom the Software is furnished to do
10so, subject to the following conditions:
11
12The above copyright notice and this permission notice shall be included in all
13copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
17NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the name of the XFree86 Project shall not
23be used in advertising or otherwise to promote the sale, use or other dealings
24in this Software without prior written authorization from the XFree86 Project.
25*/
26
27/*
28Copyright (C) 1994-2000 The XFree86 Project, Inc.  All Rights Reserved.
29
30Permission is hereby granted, free of charge, to any person obtaining a copy of
31this software and associated documentation files (the "Software"), to deal in
32the Software without restriction, including without limitation the rights to
33use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
34of the Software, and to permit persons to whom the Software is furnished to do
35so, subject to the following conditions:
36
37The above copyright notice and this permission notice shall be included in all
38copies or substantial portions of the Software.
39
40THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
41IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
42NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
43XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
44AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
45WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
46
47Except as contained in this notice, the name of the XFree86 Project shall not
48be used in advertising or otherwise to promote the sale, use or other dealings
49in this Software without prior written authorization from the XFree86 Project.
50*/
51
52/*
53   Copyright (c) 1999,2000  The XFree86 Project Inc.
54   based on code written by Mark Vojkovich <markv@valinux.com>
55*/
56
57#ifdef HAVE_CONFIG_H
58#include "config.h"
59#endif
60
61#include "xf86.h"
62#include "xf86_OSproc.h"
63#include "xf86Pci.h"
64#include "shadowfb.h"
65#include "servermd.h"
66#include "s3v.h"
67
68
69void
70s3vRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
71{
72    S3VPtr ps3v = S3VPTR(pScrn);
73    int width, height, Bpp, FBPitch;
74    unsigned char *src, *dst;
75
76    Bpp = pScrn->bitsPerPixel >> 3;
77    FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel);
78
79    while(num--) {
80	width = (pbox->x2 - pbox->x1) * Bpp;
81	height = pbox->y2 - pbox->y1;
82	src = ps3v->ShadowPtr + (pbox->y1 * ps3v->ShadowPitch) +
83						(pbox->x1 * Bpp);
84	dst = ps3v->FBStart + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp);
85
86	while(height--) {
87	    memcpy(dst, src, width);
88	    dst += FBPitch;
89	    src += ps3v->ShadowPitch;
90	}
91
92	pbox++;
93    }
94}
95
96void
97s3vPointerMoved(SCRN_ARG_TYPE arg, int x, int y)
98{
99    SCRN_INFO_PTR(arg);
100    S3VPtr ps3v = S3VPTR(pScrn);
101    int newX, newY;
102
103    if(ps3v->rotate == 1) {
104	newX = pScrn->pScreen->height - y - 1;
105	newY = x;
106    } else {
107	newX = y;
108	newY = pScrn->pScreen->width - x - 1;
109    }
110
111    (*ps3v->PointerMoved)(arg, newX, newY);
112}
113
114void
115s3vRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
116{
117    S3VPtr ps3v = S3VPTR(pScrn);
118    int count, width, height, y1, y2, dstPitch, srcPitch;
119    CARD8 *dstPtr, *srcPtr, *src;
120    CARD32 *dst;
121
122    dstPitch = pScrn->displayWidth;
123    srcPitch = -ps3v->rotate * ps3v->ShadowPitch;
124
125    while(num--) {
126	width = pbox->x2 - pbox->x1;
127	y1 = pbox->y1 & ~3;
128	y2 = (pbox->y2 + 3) & ~3;
129	height = (y2 - y1) >> 2;  /* in dwords */
130
131	if(ps3v->rotate == 1) {
132	    dstPtr = ps3v->FBStart +
133			(pbox->x1 * dstPitch) + pScrn->virtualX - y2;
134	    srcPtr = ps3v->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1;
135	} else {
136	    dstPtr = ps3v->FBStart +
137			((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
138	    srcPtr = ps3v->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1;
139	}
140
141	while(width--) {
142	    src = srcPtr;
143	    dst = (CARD32*)dstPtr;
144	    count = height;
145	    while(count--) {
146		*(dst++) = src[0] | (src[srcPitch] << 8) |
147					(src[srcPitch * 2] << 16) |
148					(src[srcPitch * 3] << 24);
149		src += srcPitch * 4;
150	    }
151	    srcPtr += ps3v->rotate;
152	    dstPtr += dstPitch;
153	}
154
155	pbox++;
156    }
157}
158
159
160void
161s3vRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
162{
163    S3VPtr ps3v = S3VPTR(pScrn);
164    int count, width, height, y1, y2, dstPitch, srcPitch;
165    CARD16 *dstPtr, *srcPtr, *src;
166    CARD32 *dst;
167
168    dstPitch = pScrn->displayWidth;
169    srcPitch = -ps3v->rotate * ps3v->ShadowPitch >> 1;
170
171    while(num--) {
172	width = pbox->x2 - pbox->x1;
173	y1 = pbox->y1 & ~1;
174	y2 = (pbox->y2 + 1) & ~1;
175	height = (y2 - y1) >> 1;  /* in dwords */
176
177	if(ps3v->rotate == 1) {
178	    dstPtr = (CARD16*)ps3v->FBStart +
179			(pbox->x1 * dstPitch) + pScrn->virtualX - y2;
180	    srcPtr = (CARD16*)ps3v->ShadowPtr +
181			((1 - y2) * srcPitch) + pbox->x1;
182	} else {
183	    dstPtr = (CARD16*)ps3v->FBStart +
184			((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
185	    srcPtr = (CARD16*)ps3v->ShadowPtr +
186			(y1 * srcPitch) + pbox->x2 - 1;
187	}
188
189	while(width--) {
190	    src = srcPtr;
191	    dst = (CARD32*)dstPtr;
192	    count = height;
193	    while(count--) {
194		*(dst++) = src[0] | (src[srcPitch] << 16);
195		src += srcPitch * 2;
196	    }
197	    srcPtr += ps3v->rotate;
198	    dstPtr += dstPitch;
199	}
200
201	pbox++;
202    }
203}
204
205
206/* this one could be faster */
207void
208s3vRefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
209{
210    S3VPtr ps3v = S3VPTR(pScrn);
211    int count, width, height, y1, y2, dstPitch, srcPitch;
212    CARD8 *dstPtr, *srcPtr, *src;
213    CARD32 *dst;
214
215    dstPitch = BitmapBytePad(pScrn->displayWidth * 24);
216    srcPitch = -ps3v->rotate * ps3v->ShadowPitch;
217
218    while(num--) {
219        width = pbox->x2 - pbox->x1;
220        y1 = pbox->y1 & ~3;
221        y2 = (pbox->y2 + 3) & ~3;
222        height = (y2 - y1) >> 2;  /* blocks of 3 dwords */
223
224	if(ps3v->rotate == 1) {
225	    dstPtr = ps3v->FBStart +
226			(pbox->x1 * dstPitch) + ((pScrn->virtualX - y2) * 3);
227	    srcPtr = ps3v->ShadowPtr + ((1 - y2) * srcPitch) + (pbox->x1 * 3);
228	} else {
229	    dstPtr = ps3v->FBStart +
230			((pScrn->virtualY - pbox->x2) * dstPitch) + (y1 * 3);
231	    srcPtr = ps3v->ShadowPtr + (y1 * srcPitch) + (pbox->x2 * 3) - 3;
232	}
233
234	while(width--) {
235	    src = srcPtr;
236	    dst = (CARD32*)dstPtr;
237	    count = height;
238	    while(count--) {
239		dst[0] = src[0] | (src[1] << 8) | (src[2] << 16) |
240				(src[srcPitch] << 24);
241		dst[1] = src[srcPitch + 1] | (src[srcPitch + 2] << 8) |
242				(src[srcPitch * 2] << 16) |
243				(src[(srcPitch * 2) + 1] << 24);
244		dst[2] = src[(srcPitch * 2) + 2] | (src[srcPitch * 3] << 8) |
245				(src[(srcPitch * 3) + 1] << 16) |
246				(src[(srcPitch * 3) + 2] << 24);
247		dst += 3;
248		src += srcPitch * 4;
249	    }
250	    srcPtr += ps3v->rotate * 3;
251	    dstPtr += dstPitch;
252	}
253
254	pbox++;
255    }
256}
257
258void
259s3vRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
260{
261    S3VPtr ps3v = S3VPTR(pScrn);
262    int count, width, height, dstPitch, srcPitch;
263    CARD32 *dstPtr, *srcPtr, *src, *dst;
264
265    dstPitch = pScrn->displayWidth;
266    srcPitch = -ps3v->rotate * ps3v->ShadowPitch >> 2;
267
268    while(num--) {
269	width = pbox->x2 - pbox->x1;
270	height = pbox->y2 - pbox->y1;
271
272	if(ps3v->rotate == 1) {
273	    dstPtr = (CARD32*)ps3v->FBStart +
274			(pbox->x1 * dstPitch) + pScrn->virtualX - pbox->y2;
275	    srcPtr = (CARD32*)ps3v->ShadowPtr +
276			((1 - pbox->y2) * srcPitch) + pbox->x1;
277	} else {
278	    dstPtr = (CARD32*)ps3v->FBStart +
279			((pScrn->virtualY - pbox->x2) * dstPitch) + pbox->y1;
280	    srcPtr = (CARD32*)ps3v->ShadowPtr +
281			(pbox->y1 * srcPitch) + pbox->x2 - 1;
282	}
283
284	while(width--) {
285	    src = srcPtr;
286	    dst = dstPtr;
287	    count = height;
288	    while(count--) {
289		*(dst++) = *src;
290		src += srcPitch;
291	    }
292	    srcPtr += ps3v->rotate;
293	    dstPtr += dstPitch;
294	}
295
296	pbox++;
297    }
298}
299
300
301
302