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