1/*
2 * file rendition_shadow.h
3 *
4 * The functions used by ShadowFB
5 * Based on code written by Mark Vojkovich <markv@valinux.com>
6 */
7
8#ifdef HAVE_CONFIG_H
9#include "config.h"
10#endif
11
12#include "rendition.h"
13#include "vtypes.h"
14#include "rendition_shadow.h"
15#include "shadowfb.h"
16#include "servermd.h"
17
18
19
20void
21renditionRefreshArea(ScrnInfoPtr pScreenInfo, int num, BoxPtr pbox)
22{
23    renditionPtr pRendition = RENDITIONPTR(pScreenInfo);
24    int width, height, Bpp, FBPitch;
25    unsigned char *src, *dst;
26
27    Bpp = pScreenInfo->bitsPerPixel >> 3;
28    FBPitch = BitmapBytePad(pScreenInfo->displayWidth *
29			    pScreenInfo->bitsPerPixel);
30
31    while(num--) {
32	width = (pbox->x2 - pbox->x1) * Bpp;
33	height = pbox->y2 - pbox->y1;
34	src = pRendition->board.shadowPtr +
35	      (pbox->y1 * pRendition->board.shadowPitch) + (pbox->x1 * Bpp);
36
37	dst = pRendition->board.vmem_base+pRendition->board.fbOffset +
38	      (pbox->y1 * FBPitch) + (pbox->x1 * Bpp);
39
40	while(height--) {
41	    memcpy(dst, src, width);
42	    dst += FBPitch;
43	    src += pRendition->board.shadowPitch;
44	}
45
46	pbox++;
47    }
48}
49
50void
51renditionPointerMoved(SCRN_ARG_TYPE arg, int x, int y)
52{
53    SCRN_INFO_PTR(arg);
54    renditionPtr pRendition = RENDITIONPTR(pScreenInfo);
55    int newX, newY;
56
57    if(pRendition->board.rotate == 1) {
58	newX = pScreenInfo->pScreen->height - y - 1;
59	newY = x;
60    } else {
61	newX = y;
62	newY = pScreenInfo->pScreen->width - x - 1;
63    }
64
65    (*pRendition->board.PointerMoved)(arg, newX, newY);
66}
67
68void
69renditionRefreshArea8(ScrnInfoPtr pScreenInfo, int num, BoxPtr pbox)
70{
71    renditionPtr pRendition = RENDITIONPTR(pScreenInfo);
72    int count, width, height, y1, y2, dstPitch, srcPitch;
73    CARD8 *dstPtr, *srcPtr, *src;
74    CARD32 *dst;
75
76    dstPitch = pScreenInfo->displayWidth;
77    srcPitch = -pRendition->board.rotate * pRendition->board.shadowPitch;
78
79    while(num--) {
80	width = pbox->x2 - pbox->x1;
81	y1 = pbox->y1 & ~3;
82	y2 = (pbox->y2 + 3) & ~3;
83	height = (y2 - y1) >> 2;  /* in dwords */
84
85	if(pRendition->board.rotate == 1) {
86	    dstPtr = pRendition->board.vmem_base+pRendition->board.fbOffset +
87  	             (pbox->x1 * dstPitch) + pScreenInfo->virtualX - y2;
88	    srcPtr = pRendition->board.shadowPtr + ((1 - y2) * srcPitch) + pbox->x1;
89	} else {
90	    dstPtr = pRendition->board.vmem_base+pRendition->board.fbOffset +
91	             ((pScreenInfo->virtualY - pbox->x2) * dstPitch) + y1;
92	    srcPtr = pRendition->board.shadowPtr + (y1 * srcPitch) + pbox->x2 - 1;
93	}
94
95	while(width--) {
96	    src = srcPtr;
97	    dst = (CARD32*)dstPtr;
98	    count = height;
99	    while(count--) {
100		*(dst++) = src[0] | (src[srcPitch] << 8) |
101					(src[srcPitch * 2] << 16) |
102					(src[srcPitch * 3] << 24);
103		src += srcPitch * 4;
104	    }
105	    srcPtr += pRendition->board.rotate;
106	    dstPtr += dstPitch;
107	}
108
109	pbox++;
110    }
111}
112
113
114void
115renditionRefreshArea16(ScrnInfoPtr pScreenInfo, int num, BoxPtr pbox)
116{
117    renditionPtr pRendition = RENDITIONPTR(pScreenInfo);
118    int count, width, height, y1, y2, dstPitch, srcPitch;
119    CARD16 *dstPtr, *srcPtr, *src;
120    CARD32 *dst;
121
122    dstPitch = pScreenInfo->displayWidth;
123    srcPitch = -pRendition->board.rotate * pRendition->board.shadowPitch >> 1;
124
125    while(num--) {
126	width = pbox->x2 - pbox->x1;
127	y1 = pbox->y1 & ~1;
128	y2 = (pbox->y2 + 1) & ~1;
129	height = (y2 - y1) >> 1;  /* in dwords */
130
131	if(pRendition->board.rotate == 1) {
132	    dstPtr = (CARD16*)(pRendition->board.vmem_base+
133	                      pRendition->board.fbOffset) +
134			(pbox->x1 * dstPitch) + pScreenInfo->virtualX - y2;
135	    srcPtr = (CARD16*)pRendition->board.shadowPtr +
136			((1 - y2) * srcPitch) + pbox->x1;
137	} else {
138	    dstPtr = (CARD16*)(pRendition->board.vmem_base+
139			       pRendition->board.fbOffset) +
140			((pScreenInfo->virtualY - pbox->x2) * dstPitch) + y1;
141	    srcPtr = (CARD16*)pRendition->board.shadowPtr +
142			(y1 * srcPitch) + pbox->x2 - 1;
143	}
144
145	while(width--) {
146	    src = srcPtr;
147	    dst = (CARD32*)dstPtr;
148	    count = height;
149	    while(count--) {
150		*(dst++) = src[0] | (src[srcPitch] << 16);
151		src += srcPitch * 2;
152	    }
153	    srcPtr += pRendition->board.rotate;
154	    dstPtr += dstPitch;
155	}
156
157	pbox++;
158    }
159}
160
161
162/* this one could be faster */
163void
164renditionRefreshArea24(ScrnInfoPtr pScreenInfo, int num, BoxPtr pbox)
165{
166    renditionPtr pRendition = RENDITIONPTR(pScreenInfo);
167    int count, width, height, y1, y2, dstPitch, srcPitch;
168    CARD8 *dstPtr, *srcPtr, *src;
169    CARD32 *dst;
170
171    dstPitch = BitmapBytePad(pScreenInfo->displayWidth * 24);
172    srcPitch = -pRendition->board.rotate * pRendition->board.shadowPitch;
173
174    while(num--) {
175        width = pbox->x2 - pbox->x1;
176        y1 = pbox->y1 & ~3;
177        y2 = (pbox->y2 + 3) & ~3;
178        height = (y2 - y1) >> 2;  /* blocks of 3 dwords */
179
180	if(pRendition->board.rotate == 1) {
181	    dstPtr = pRendition->board.vmem_base+pRendition->board.fbOffset+
182		     (pbox->x1 * dstPitch) + ((pScreenInfo->virtualX - y2) * 3);
183	    srcPtr = pRendition->board.shadowPtr + ((1 - y2) * srcPitch) +
184	             (pbox->x1 * 3);
185	} else {
186	    dstPtr = pRendition->board.vmem_base+pRendition->board.fbOffset +
187	             ((pScreenInfo->virtualY - pbox->x2) * dstPitch) + (y1 * 3);
188	    srcPtr = pRendition->board.shadowPtr + (y1 * srcPitch) +
189	             (pbox->x2 * 3) - 3;
190	}
191
192	while(width--) {
193	    src = srcPtr;
194	    dst = (CARD32*)dstPtr;
195	    count = height;
196	    while(count--) {
197		dst[0] = src[0] | (src[1] << 8) | (src[2] << 16) |
198				(src[srcPitch] << 24);
199		dst[1] = src[srcPitch + 1] | (src[srcPitch + 2] << 8) |
200				(src[srcPitch * 2] << 16) |
201				(src[(srcPitch * 2) + 1] << 24);
202		dst[2] = src[(srcPitch * 2) + 2] | (src[srcPitch * 3] << 8) |
203				(src[(srcPitch * 3) + 1] << 16) |
204				(src[(srcPitch * 3) + 2] << 24);
205		dst += 3;
206		src += srcPitch * 4;
207	    }
208	    srcPtr += pRendition->board.rotate * 3;
209	    dstPtr += dstPitch;
210	}
211
212	pbox++;
213    }
214}
215
216void
217renditionRefreshArea32(ScrnInfoPtr pScreenInfo, int num, BoxPtr pbox)
218{
219    renditionPtr pRendition = RENDITIONPTR(pScreenInfo);
220    int count, width, height, dstPitch, srcPitch;
221    CARD32 *dstPtr, *srcPtr, *src, *dst;
222
223    dstPitch = pScreenInfo->displayWidth;
224    srcPitch = -pRendition->board.rotate * pRendition->board.shadowPitch >> 2;
225
226    while(num--) {
227	width = pbox->x2 - pbox->x1;
228	height = pbox->y2 - pbox->y1;
229
230	if(pRendition->board.rotate == 1) {
231	    dstPtr = (CARD32*)(pRendition->board.vmem_base+
232			       pRendition->board.fbOffset) +
233		     (pbox->x1 * dstPitch) + pScreenInfo->virtualX - pbox->y2;
234	    srcPtr = (CARD32*)pRendition->board.shadowPtr +
235		     ((1 - pbox->y2) * srcPitch) + pbox->x1;
236	} else {
237	    dstPtr = (CARD32*)(pRendition->board.vmem_base+
238			       pRendition->board.fbOffset) +
239		     ((pScreenInfo->virtualY - pbox->x2) * dstPitch) + pbox->y1;
240	    srcPtr = (CARD32*)pRendition->board.shadowPtr +
241		     (pbox->y1 * srcPitch) + pbox->x2 - 1;
242	}
243
244	while(width--) {
245	    src = srcPtr;
246	    dst = dstPtr;
247	    count = height;
248	    while(count--) {
249		*(dst++) = *src;
250		src += srcPitch;
251	    }
252	    srcPtr += pRendition->board.rotate;
253	    dstPtr += dstPitch;
254	}
255
256	pbox++;
257    }
258}
259
260