1692f60a7Smrg
2692f60a7Smrg/*
3692f60a7Smrg   Copyright (c) 1999, 2000 The XFree86 Project Inc.
4692f60a7Smrg   based on code written by Mark Vojkovich <markv@valinux.com>
5692f60a7Smrg*/
6692f60a7Smrg
7692f60a7Smrg#ifdef HAVE_CONFIG_H
8692f60a7Smrg#include "config.h"
9692f60a7Smrg#endif
10692f60a7Smrg
11692f60a7Smrg#include "xf86.h"
12692f60a7Smrg#include "xf86_OSproc.h"
13692f60a7Smrg#include "xf86Pci.h"
14692f60a7Smrg#include "shadowfb.h"
15692f60a7Smrg#include "servermd.h"
16692f60a7Smrg#include "neo.h"
17692f60a7Smrg
18692f60a7Smrgvoid
19692f60a7SmrgneoShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf)
20692f60a7Smrg{
213f6d0e1dSmrg    RegionPtr damage = DamageRegion(pBuf->pDamage);
22692f60a7Smrg    ScrnInfoPtr pScrn;
233f6d0e1dSmrg    pScrn = xf86ScreenToScrn(pScreen);
24692f60a7Smrg
25692f60a7Smrg    (NEOPTR(pScrn))->refreshArea (pScrn, REGION_NUM_RECTS(damage),
26692f60a7Smrg				      REGION_RECTS(damage));
27692f60a7Smrg}
28692f60a7Smrg
29692f60a7Smrgvoid
30692f60a7SmrgneoRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
31692f60a7Smrg{
32692f60a7Smrg    NEOPtr nPtr = NEOPTR(pScrn);
33692f60a7Smrg    int width, height, Bpp, FBPitch;
34692f60a7Smrg    unsigned char *src, *dst;
35692f60a7Smrg
36692f60a7Smrg    Bpp = pScrn->bitsPerPixel >> 3;
37692f60a7Smrg    FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel);
38692f60a7Smrg
39692f60a7Smrg    while(num--) {
40692f60a7Smrg	width = (pbox->x2 - pbox->x1) * Bpp;
41692f60a7Smrg	height = pbox->y2 - pbox->y1;
42692f60a7Smrg	src = nPtr->ShadowPtr + (pbox->y1 * nPtr->ShadowPitch) +
43692f60a7Smrg						(pbox->x1 * Bpp);
44692f60a7Smrg	dst = nPtr->NeoFbBase + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp);
45692f60a7Smrg
46692f60a7Smrg	while(height--) {
47692f60a7Smrg	    memcpy(dst, src, width);
48692f60a7Smrg	    dst += FBPitch;
49692f60a7Smrg	    src += nPtr->ShadowPitch;
50692f60a7Smrg	}
51692f60a7Smrg
52692f60a7Smrg	pbox++;
53692f60a7Smrg    }
54692f60a7Smrg}
55692f60a7Smrg
56692f60a7Smrgvoid
573f6d0e1dSmrgneoPointerMoved(SCRN_ARG_TYPE arg, int x, int y)
58692f60a7Smrg{
593f6d0e1dSmrg    SCRN_INFO_PTR(arg);
60692f60a7Smrg    NEOPtr nPtr = NEOPTR(pScrn);
61692f60a7Smrg    int newX, newY;
62692f60a7Smrg
63692f60a7Smrg    if(nPtr->rotate == 1) {
64692f60a7Smrg	newX = pScrn->pScreen->height - y - 1;
65692f60a7Smrg	newY = x;
66692f60a7Smrg    } else {
67692f60a7Smrg	newX = y;
68692f60a7Smrg	newY = pScrn->pScreen->width - x - 1;
69692f60a7Smrg    }
70692f60a7Smrg
713f6d0e1dSmrg    (*nPtr->PointerMoved)(arg, newX, newY);
72692f60a7Smrg}
73692f60a7Smrg
74692f60a7Smrgvoid
75692f60a7SmrgneoRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
76692f60a7Smrg{
77692f60a7Smrg    NEOPtr nPtr = NEOPTR(pScrn);
78692f60a7Smrg    int count, width, height, y1, y2, dstPitch, srcPitch;
79692f60a7Smrg    CARD8 *dstPtr, *srcPtr, *src;
80692f60a7Smrg    CARD32 *dst;
81692f60a7Smrg
82692f60a7Smrg    dstPitch = pScrn->displayWidth;
83692f60a7Smrg    srcPitch = -nPtr->rotate * nPtr->ShadowPitch;
84692f60a7Smrg
85692f60a7Smrg    while(num--) {
86692f60a7Smrg	width = pbox->x2 - pbox->x1;
87692f60a7Smrg	y1 = pbox->y1 & ~3;
88692f60a7Smrg	y2 = (pbox->y2 + 3) & ~3;
89692f60a7Smrg	height = (y2 - y1) >> 2;  /* in dwords */
90692f60a7Smrg
91692f60a7Smrg	if(nPtr->rotate == 1) {
92692f60a7Smrg	    dstPtr = nPtr->NeoFbBase +
93692f60a7Smrg			(pbox->x1 * dstPitch) + pScrn->virtualX - y2;
94692f60a7Smrg	    srcPtr = nPtr->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1;
95692f60a7Smrg	} else {
96692f60a7Smrg	    dstPtr = nPtr->NeoFbBase +
97692f60a7Smrg			((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
98692f60a7Smrg	    srcPtr = nPtr->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1;
99692f60a7Smrg	}
100692f60a7Smrg
101692f60a7Smrg	while(width--) {
102692f60a7Smrg	    src = srcPtr;
103692f60a7Smrg	    dst = (CARD32*)dstPtr;
104692f60a7Smrg	    count = height;
105692f60a7Smrg	    while(count--) {
106692f60a7Smrg		*(dst++) = src[0] | (src[srcPitch] << 8) |
107692f60a7Smrg					(src[srcPitch * 2] << 16) |
108692f60a7Smrg					(src[srcPitch * 3] << 24);
109692f60a7Smrg		src += srcPitch * 4;
110692f60a7Smrg	    }
111692f60a7Smrg	    srcPtr += nPtr->rotate;
112692f60a7Smrg	    dstPtr += dstPitch;
113692f60a7Smrg	}
114692f60a7Smrg
115692f60a7Smrg	pbox++;
116692f60a7Smrg    }
117692f60a7Smrg}
118692f60a7Smrg
119692f60a7Smrg
120692f60a7Smrgvoid
121692f60a7SmrgneoRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
122692f60a7Smrg{
123692f60a7Smrg    NEOPtr nPtr = NEOPTR(pScrn);
124692f60a7Smrg    int count, width, height, y1, y2, dstPitch, srcPitch;
125692f60a7Smrg    CARD16 *dstPtr, *srcPtr, *src;
126692f60a7Smrg    CARD32 *dst;
127692f60a7Smrg
128692f60a7Smrg    dstPitch = pScrn->displayWidth;
129692f60a7Smrg    srcPitch = -nPtr->rotate * nPtr->ShadowPitch >> 1;
130692f60a7Smrg
131692f60a7Smrg    while(num--) {
132692f60a7Smrg	width = pbox->x2 - pbox->x1;
133692f60a7Smrg	y1 = pbox->y1 & ~1;
134692f60a7Smrg	y2 = (pbox->y2 + 1) & ~1;
135692f60a7Smrg	height = (y2 - y1) >> 1;  /* in dwords */
136692f60a7Smrg
137692f60a7Smrg	if(nPtr->rotate == 1) {
138692f60a7Smrg	    dstPtr = (CARD16*)nPtr->NeoFbBase +
139692f60a7Smrg			(pbox->x1 * dstPitch) + pScrn->virtualX - y2;
140692f60a7Smrg	    srcPtr = (CARD16*)nPtr->ShadowPtr +
141692f60a7Smrg			((1 - y2) * srcPitch) + pbox->x1;
142692f60a7Smrg	} else {
143692f60a7Smrg	    dstPtr = (CARD16*)nPtr->NeoFbBase +
144692f60a7Smrg			((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
145692f60a7Smrg	    srcPtr = (CARD16*)nPtr->ShadowPtr +
146692f60a7Smrg			(y1 * srcPitch) + pbox->x2 - 1;
147692f60a7Smrg	}
148692f60a7Smrg
149692f60a7Smrg	while(width--) {
150692f60a7Smrg	    src = srcPtr;
151692f60a7Smrg	    dst = (CARD32*)dstPtr;
152692f60a7Smrg	    count = height;
153692f60a7Smrg	    while(count--) {
154692f60a7Smrg		*(dst++) = src[0] | (src[srcPitch] << 16);
155692f60a7Smrg		src += srcPitch * 2;
156692f60a7Smrg	    }
157692f60a7Smrg	    srcPtr += nPtr->rotate;
158692f60a7Smrg	    dstPtr += dstPitch;
159692f60a7Smrg	}
160692f60a7Smrg
161692f60a7Smrg	pbox++;
162692f60a7Smrg    }
163692f60a7Smrg}
164692f60a7Smrg
165692f60a7Smrg
166692f60a7Smrg/* this one could be faster */
167692f60a7Smrgvoid
168692f60a7SmrgneoRefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
169692f60a7Smrg{
170692f60a7Smrg    NEOPtr nPtr = NEOPTR(pScrn);
171692f60a7Smrg    int count, width, height, y1, y2, dstPitch, srcPitch;
172692f60a7Smrg    CARD8 *dstPtr, *srcPtr, *src;
173692f60a7Smrg    CARD32 *dst;
174692f60a7Smrg
175692f60a7Smrg    dstPitch = BitmapBytePad(pScrn->displayWidth * 24);
176692f60a7Smrg    srcPitch = -nPtr->rotate * nPtr->ShadowPitch;
177692f60a7Smrg
178692f60a7Smrg    while(num--) {
179692f60a7Smrg        width = pbox->x2 - pbox->x1;
180692f60a7Smrg        y1 = pbox->y1 & ~3;
181692f60a7Smrg        y2 = (pbox->y2 + 3) & ~3;
182692f60a7Smrg        height = (y2 - y1) >> 2;  /* blocks of 3 dwords */
183692f60a7Smrg
184692f60a7Smrg	if(nPtr->rotate == 1) {
185692f60a7Smrg	    dstPtr = nPtr->NeoFbBase +
186692f60a7Smrg			(pbox->x1 * dstPitch) + ((pScrn->virtualX - y2) * 3);
187692f60a7Smrg	    srcPtr = nPtr->ShadowPtr + ((1 - y2) * srcPitch) + (pbox->x1 * 3);
188692f60a7Smrg	} else {
189692f60a7Smrg	    dstPtr = nPtr->NeoFbBase +
190692f60a7Smrg			((pScrn->virtualY - pbox->x2) * dstPitch) + (y1 * 3);
191692f60a7Smrg	    srcPtr = nPtr->ShadowPtr + (y1 * srcPitch) + (pbox->x2 * 3) - 3;
192692f60a7Smrg	}
193692f60a7Smrg
194692f60a7Smrg	while(width--) {
195692f60a7Smrg	    src = srcPtr;
196692f60a7Smrg	    dst = (CARD32*)dstPtr;
197692f60a7Smrg	    count = height;
198692f60a7Smrg	    while(count--) {
199692f60a7Smrg		dst[0] = src[0] | (src[1] << 8) | (src[2] << 16) |
200692f60a7Smrg				(src[srcPitch] << 24);
201692f60a7Smrg		dst[1] = src[srcPitch + 1] | (src[srcPitch + 2] << 8) |
202692f60a7Smrg				(src[srcPitch * 2] << 16) |
203692f60a7Smrg				(src[(srcPitch * 2) + 1] << 24);
204692f60a7Smrg		dst[2] = src[(srcPitch * 2) + 2] | (src[srcPitch * 3] << 8) |
205692f60a7Smrg				(src[(srcPitch * 3) + 1] << 16) |
206692f60a7Smrg				(src[(srcPitch * 3) + 2] << 24);
207692f60a7Smrg		dst += 3;
208692f60a7Smrg		src += srcPitch * 4;
209692f60a7Smrg	    }
210692f60a7Smrg	    srcPtr += nPtr->rotate * 3;
211692f60a7Smrg	    dstPtr += dstPitch;
212692f60a7Smrg	}
213692f60a7Smrg
214692f60a7Smrg	pbox++;
215692f60a7Smrg    }
216692f60a7Smrg}
217692f60a7Smrg
218692f60a7Smrgvoid
219692f60a7SmrgneoRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
220692f60a7Smrg{
221692f60a7Smrg    NEOPtr nPtr = NEOPTR(pScrn);
222692f60a7Smrg    int count, width, height, dstPitch, srcPitch;
223692f60a7Smrg    CARD32 *dstPtr, *srcPtr, *src, *dst;
224692f60a7Smrg
225692f60a7Smrg    dstPitch = pScrn->displayWidth;
226692f60a7Smrg    srcPitch = -nPtr->rotate * nPtr->ShadowPitch >> 2;
227692f60a7Smrg
228692f60a7Smrg    while(num--) {
229692f60a7Smrg	width = pbox->x2 - pbox->x1;
230692f60a7Smrg	height = pbox->y2 - pbox->y1;
231692f60a7Smrg
232692f60a7Smrg	if(nPtr->rotate == 1) {
233692f60a7Smrg	    dstPtr = (CARD32*)nPtr->NeoFbBase +
234692f60a7Smrg			(pbox->x1 * dstPitch) + pScrn->virtualX - pbox->y2;
235692f60a7Smrg	    srcPtr = (CARD32*)nPtr->ShadowPtr +
236692f60a7Smrg			((1 - pbox->y2) * srcPitch) + pbox->x1;
237692f60a7Smrg	} else {
238692f60a7Smrg	    dstPtr = (CARD32*)nPtr->NeoFbBase +
239692f60a7Smrg			((pScrn->virtualY - pbox->x2) * dstPitch) + pbox->y1;
240692f60a7Smrg	    srcPtr = (CARD32*)nPtr->ShadowPtr +
241692f60a7Smrg			(pbox->y1 * srcPitch) + pbox->x2 - 1;
242692f60a7Smrg	}
243692f60a7Smrg
244692f60a7Smrg	while(width--) {
245692f60a7Smrg	    src = srcPtr;
246692f60a7Smrg	    dst = dstPtr;
247692f60a7Smrg	    count = height;
248692f60a7Smrg	    while(count--) {
249692f60a7Smrg		*(dst++) = *src;
250692f60a7Smrg		src += srcPitch;
251692f60a7Smrg	    }
252692f60a7Smrg	    srcPtr += nPtr->rotate;
253692f60a7Smrg	    dstPtr += dstPitch;
254692f60a7Smrg	}
255692f60a7Smrg
256692f60a7Smrg	pbox++;
257692f60a7Smrg    }
258692f60a7Smrg}
259692f60a7Smrg
260692f60a7Smrg
261692f60a7Smrg
262