1/*
2   Copyright (c) 1999,  The XFree86 Project Inc.
3   Written by Mark Vojkovich <markv@valinux.com>
4*/
5
6#ifdef HAVE_CONFIG_H
7#include "config.h"
8#endif
9
10#include "nv_local.h"
11#include "nv_include.h"
12#include "nv_type.h"
13#include "shadowfb.h"
14#include "servermd.h"
15
16void
17NVShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf)
18{
19    RegionPtr damage = DamageRegion(pBuf->pDamage);
20    ScrnInfoPtr pScrn;
21    pScrn = xf86ScreenToScrn(pScreen);
22
23    (NVPTR(pScrn))->refreshArea (pScrn, REGION_NUM_RECTS(damage),
24	REGION_RECTS(damage));
25}
26
27
28void
29NVRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
30{
31    NVPtr pNv = NVPTR(pScrn);
32    int width, height, Bpp, FBPitch;
33    unsigned char *src, *dst;
34
35    Bpp = pScrn->bitsPerPixel >> 3;
36    FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel);
37
38    while(num--) {
39	width = (pbox->x2 - pbox->x1) * Bpp;
40	height = pbox->y2 - pbox->y1;
41	src = pNv->ShadowPtr + (pbox->y1 * pNv->ShadowPitch) +
42						(pbox->x1 * Bpp);
43	dst = pNv->FbStart + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp);
44
45	while(height--) {
46	    memcpy(dst, src, width);
47	    dst += FBPitch;
48	    src += pNv->ShadowPitch;
49	}
50
51	pbox++;
52    }
53}
54
55void
56NVPointerMoved(SCRN_ARG_TYPE arg, int x, int y)
57{
58    SCRN_INFO_PTR(arg);
59    NVPtr pNv = NVPTR(pScrn);
60    int newX, newY;
61
62    if(pNv->Rotate == 1) {
63	newX = pScrn->pScreen->height - y - 1;
64	newY = x;
65    } else {
66	newX = y;
67	newY = pScrn->pScreen->width - x - 1;
68    }
69
70    (*pNv->PointerMoved)(arg, newX, newY);
71}
72
73void
74NVRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
75{
76    NVPtr pNv = NVPTR(pScrn);
77    int count, width, height, y1, y2, dstPitch, srcPitch;
78    CARD8 *dstPtr, *srcPtr, *src;
79    CARD32 *dst;
80
81    if(!pNv->Rotate) {
82       NVRefreshArea(pScrn, num, pbox);
83       return;
84    }
85
86    dstPitch = pScrn->displayWidth;
87    srcPitch = -pNv->Rotate * pNv->ShadowPitch;
88
89    while(num--) {
90	width = pbox->x2 - pbox->x1;
91	y1 = pbox->y1 & ~3;
92	y2 = (pbox->y2 + 3) & ~3;
93	height = (y2 - y1) >> 2;  /* in dwords */
94
95	if(pNv->Rotate == 1) {
96	    dstPtr = pNv->FbStart +
97			(pbox->x1 * dstPitch) + pScrn->virtualX - y2;
98	    srcPtr = pNv->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1;
99	} else {
100	    dstPtr = pNv->FbStart +
101			((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
102	    srcPtr = pNv->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1;
103	}
104
105	while(width--) {
106	    src = srcPtr;
107	    dst = (CARD32*)dstPtr;
108	    count = height;
109	    while(count--) {
110		*(dst++) = src[0] | (src[srcPitch] << 8) |
111					(src[srcPitch * 2] << 16) |
112					(src[srcPitch * 3] << 24);
113		src += srcPitch * 4;
114	    }
115	    srcPtr += pNv->Rotate;
116	    dstPtr += dstPitch;
117	}
118
119	pbox++;
120    }
121}
122
123
124void
125NVRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
126{
127    NVPtr pNv = NVPTR(pScrn);
128    int count, width, height, y1, y2, dstPitch, srcPitch;
129    CARD16 *dstPtr, *srcPtr, *src;
130    CARD32 *dst;
131
132    if(!pNv->Rotate) {
133       NVRefreshArea(pScrn, num, pbox);
134       return;
135    }
136
137    dstPitch = pScrn->displayWidth;
138    srcPitch = -pNv->Rotate * pNv->ShadowPitch >> 1;
139
140    while(num--) {
141	width = pbox->x2 - pbox->x1;
142	y1 = pbox->y1 & ~1;
143	y2 = (pbox->y2 + 1) & ~1;
144	height = (y2 - y1) >> 1;  /* in dwords */
145
146	if(pNv->Rotate == 1) {
147	    dstPtr = (CARD16*)pNv->FbStart +
148			(pbox->x1 * dstPitch) + pScrn->virtualX - y2;
149	    srcPtr = (CARD16*)pNv->ShadowPtr +
150			((1 - y2) * srcPitch) + pbox->x1;
151	} else {
152	    dstPtr = (CARD16*)pNv->FbStart +
153			((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
154	    srcPtr = (CARD16*)pNv->ShadowPtr +
155			(y1 * srcPitch) + pbox->x2 - 1;
156	}
157
158	while(width--) {
159	    src = srcPtr;
160	    dst = (CARD32*)dstPtr;
161	    count = height;
162	    while(count--) {
163		*(dst++) = src[0] | (src[srcPitch] << 16);
164		src += srcPitch * 2;
165	    }
166	    srcPtr += pNv->Rotate;
167	    dstPtr += dstPitch;
168	}
169
170	pbox++;
171    }
172}
173
174
175void
176NVRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
177{
178    NVPtr pNv = NVPTR(pScrn);
179    int count, width, height, dstPitch, srcPitch;
180    CARD32 *dstPtr, *srcPtr, *src, *dst;
181
182    if(!pNv->Rotate) {
183       NVRefreshArea(pScrn, num, pbox);
184       return;
185    }
186
187    dstPitch = pScrn->displayWidth;
188    srcPitch = -pNv->Rotate * pNv->ShadowPitch >> 2;
189
190    while(num--) {
191	width = pbox->x2 - pbox->x1;
192	height = pbox->y2 - pbox->y1;
193
194	if(pNv->Rotate == 1) {
195	    dstPtr = (CARD32*)pNv->FbStart +
196			(pbox->x1 * dstPitch) + pScrn->virtualX - pbox->y2;
197	    srcPtr = (CARD32*)pNv->ShadowPtr +
198			((1 - pbox->y2) * srcPitch) + pbox->x1;
199	} else {
200	    dstPtr = (CARD32*)pNv->FbStart +
201			((pScrn->virtualY - pbox->x2) * dstPitch) + pbox->y1;
202	    srcPtr = (CARD32*)pNv->ShadowPtr +
203			(pbox->y1 * srcPitch) + pbox->x2 - 1;
204	}
205
206	while(width--) {
207	    src = srcPtr;
208	    dst = dstPtr;
209	    count = height;
210	    while(count--) {
211		*(dst++) = *src;
212		src += srcPitch;
213	    }
214	    srcPtr += pNv->Rotate;
215	    dstPtr += dstPitch;
216	}
217
218	pbox++;
219    }
220}
221