nv_shadow.c revision bd304fc0
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
16fc5a983dSmrg
17fc5a983dSmrgvoid
18fc5a983dSmrgNVRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
19fc5a983dSmrg{
20fc5a983dSmrg    NVPtr pNv = NVPTR(pScrn);
21fc5a983dSmrg    int width, height, Bpp, FBPitch;
22fc5a983dSmrg    unsigned char *src, *dst;
23fc5a983dSmrg
24fc5a983dSmrg    Bpp = pScrn->bitsPerPixel >> 3;
25fc5a983dSmrg    FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel);
26fc5a983dSmrg
27fc5a983dSmrg    while(num--) {
28fc5a983dSmrg	width = (pbox->x2 - pbox->x1) * Bpp;
29fc5a983dSmrg	height = pbox->y2 - pbox->y1;
30fc5a983dSmrg	src = pNv->ShadowPtr + (pbox->y1 * pNv->ShadowPitch) +
31fc5a983dSmrg						(pbox->x1 * Bpp);
32fc5a983dSmrg	dst = pNv->FbStart + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp);
33fc5a983dSmrg
34fc5a983dSmrg	while(height--) {
35fc5a983dSmrg	    memcpy(dst, src, width);
36fc5a983dSmrg	    dst += FBPitch;
37fc5a983dSmrg	    src += pNv->ShadowPitch;
38fc5a983dSmrg	}
39fc5a983dSmrg
40fc5a983dSmrg	pbox++;
41fc5a983dSmrg    }
42fc5a983dSmrg}
43fc5a983dSmrg
44fc5a983dSmrgvoid
45bd304fc0SmrgNVPointerMoved(SCRN_ARG_TYPE arg, int x, int y)
46fc5a983dSmrg{
47bd304fc0Smrg    SCRN_INFO_PTR(arg);
48fc5a983dSmrg    NVPtr pNv = NVPTR(pScrn);
49fc5a983dSmrg    int newX, newY;
50fc5a983dSmrg
51fc5a983dSmrg    if(pNv->Rotate == 1) {
52fc5a983dSmrg	newX = pScrn->pScreen->height - y - 1;
53fc5a983dSmrg	newY = x;
54fc5a983dSmrg    } else {
55fc5a983dSmrg	newX = y;
56fc5a983dSmrg	newY = pScrn->pScreen->width - x - 1;
57fc5a983dSmrg    }
58fc5a983dSmrg
59bd304fc0Smrg    (*pNv->PointerMoved)(arg, newX, newY);
60fc5a983dSmrg}
61fc5a983dSmrg
62fc5a983dSmrgvoid
63fc5a983dSmrgNVRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
64fc5a983dSmrg{
65fc5a983dSmrg    NVPtr pNv = NVPTR(pScrn);
66fc5a983dSmrg    int count, width, height, y1, y2, dstPitch, srcPitch;
67fc5a983dSmrg    CARD8 *dstPtr, *srcPtr, *src;
68fc5a983dSmrg    CARD32 *dst;
69fc5a983dSmrg
70fc5a983dSmrg    if(!pNv->Rotate) {
71fc5a983dSmrg       NVRefreshArea(pScrn, num, pbox);
72fc5a983dSmrg       return;
73fc5a983dSmrg    }
74fc5a983dSmrg
75fc5a983dSmrg    dstPitch = pScrn->displayWidth;
76fc5a983dSmrg    srcPitch = -pNv->Rotate * pNv->ShadowPitch;
77fc5a983dSmrg
78fc5a983dSmrg    while(num--) {
79fc5a983dSmrg	width = pbox->x2 - pbox->x1;
80fc5a983dSmrg	y1 = pbox->y1 & ~3;
81fc5a983dSmrg	y2 = (pbox->y2 + 3) & ~3;
82fc5a983dSmrg	height = (y2 - y1) >> 2;  /* in dwords */
83fc5a983dSmrg
84fc5a983dSmrg	if(pNv->Rotate == 1) {
85fc5a983dSmrg	    dstPtr = pNv->FbStart +
86fc5a983dSmrg			(pbox->x1 * dstPitch) + pScrn->virtualX - y2;
87fc5a983dSmrg	    srcPtr = pNv->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1;
88fc5a983dSmrg	} else {
89fc5a983dSmrg	    dstPtr = pNv->FbStart +
90fc5a983dSmrg			((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
91fc5a983dSmrg	    srcPtr = pNv->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1;
92fc5a983dSmrg	}
93fc5a983dSmrg
94fc5a983dSmrg	while(width--) {
95fc5a983dSmrg	    src = srcPtr;
96fc5a983dSmrg	    dst = (CARD32*)dstPtr;
97fc5a983dSmrg	    count = height;
98fc5a983dSmrg	    while(count--) {
99fc5a983dSmrg		*(dst++) = src[0] | (src[srcPitch] << 8) |
100fc5a983dSmrg					(src[srcPitch * 2] << 16) |
101fc5a983dSmrg					(src[srcPitch * 3] << 24);
102fc5a983dSmrg		src += srcPitch * 4;
103fc5a983dSmrg	    }
104fc5a983dSmrg	    srcPtr += pNv->Rotate;
105fc5a983dSmrg	    dstPtr += dstPitch;
106fc5a983dSmrg	}
107fc5a983dSmrg
108fc5a983dSmrg	pbox++;
109fc5a983dSmrg    }
110fc5a983dSmrg}
111fc5a983dSmrg
112fc5a983dSmrg
113fc5a983dSmrgvoid
114fc5a983dSmrgNVRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
115fc5a983dSmrg{
116fc5a983dSmrg    NVPtr pNv = NVPTR(pScrn);
117fc5a983dSmrg    int count, width, height, y1, y2, dstPitch, srcPitch;
118fc5a983dSmrg    CARD16 *dstPtr, *srcPtr, *src;
119fc5a983dSmrg    CARD32 *dst;
120fc5a983dSmrg
121fc5a983dSmrg    if(!pNv->Rotate) {
122fc5a983dSmrg       NVRefreshArea(pScrn, num, pbox);
123fc5a983dSmrg       return;
124fc5a983dSmrg    }
125fc5a983dSmrg
126fc5a983dSmrg    dstPitch = pScrn->displayWidth;
127fc5a983dSmrg    srcPitch = -pNv->Rotate * pNv->ShadowPitch >> 1;
128fc5a983dSmrg
129fc5a983dSmrg    while(num--) {
130fc5a983dSmrg	width = pbox->x2 - pbox->x1;
131fc5a983dSmrg	y1 = pbox->y1 & ~1;
132fc5a983dSmrg	y2 = (pbox->y2 + 1) & ~1;
133fc5a983dSmrg	height = (y2 - y1) >> 1;  /* in dwords */
134fc5a983dSmrg
135fc5a983dSmrg	if(pNv->Rotate == 1) {
136fc5a983dSmrg	    dstPtr = (CARD16*)pNv->FbStart +
137fc5a983dSmrg			(pbox->x1 * dstPitch) + pScrn->virtualX - y2;
138fc5a983dSmrg	    srcPtr = (CARD16*)pNv->ShadowPtr +
139fc5a983dSmrg			((1 - y2) * srcPitch) + pbox->x1;
140fc5a983dSmrg	} else {
141fc5a983dSmrg	    dstPtr = (CARD16*)pNv->FbStart +
142fc5a983dSmrg			((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
143fc5a983dSmrg	    srcPtr = (CARD16*)pNv->ShadowPtr +
144fc5a983dSmrg			(y1 * srcPitch) + pbox->x2 - 1;
145fc5a983dSmrg	}
146fc5a983dSmrg
147fc5a983dSmrg	while(width--) {
148fc5a983dSmrg	    src = srcPtr;
149fc5a983dSmrg	    dst = (CARD32*)dstPtr;
150fc5a983dSmrg	    count = height;
151fc5a983dSmrg	    while(count--) {
152fc5a983dSmrg		*(dst++) = src[0] | (src[srcPitch] << 16);
153fc5a983dSmrg		src += srcPitch * 2;
154fc5a983dSmrg	    }
155fc5a983dSmrg	    srcPtr += pNv->Rotate;
156fc5a983dSmrg	    dstPtr += dstPitch;
157fc5a983dSmrg	}
158fc5a983dSmrg
159fc5a983dSmrg	pbox++;
160fc5a983dSmrg    }
161fc5a983dSmrg}
162fc5a983dSmrg
163fc5a983dSmrg
164fc5a983dSmrgvoid
165fc5a983dSmrgNVRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
166fc5a983dSmrg{
167fc5a983dSmrg    NVPtr pNv = NVPTR(pScrn);
168fc5a983dSmrg    int count, width, height, dstPitch, srcPitch;
169fc5a983dSmrg    CARD32 *dstPtr, *srcPtr, *src, *dst;
170fc5a983dSmrg
171fc5a983dSmrg    if(!pNv->Rotate) {
172fc5a983dSmrg       NVRefreshArea(pScrn, num, pbox);
173fc5a983dSmrg       return;
174fc5a983dSmrg    }
175fc5a983dSmrg
176fc5a983dSmrg    dstPitch = pScrn->displayWidth;
177fc5a983dSmrg    srcPitch = -pNv->Rotate * pNv->ShadowPitch >> 2;
178fc5a983dSmrg
179fc5a983dSmrg    while(num--) {
180fc5a983dSmrg	width = pbox->x2 - pbox->x1;
181fc5a983dSmrg	height = pbox->y2 - pbox->y1;
182fc5a983dSmrg
183fc5a983dSmrg	if(pNv->Rotate == 1) {
184fc5a983dSmrg	    dstPtr = (CARD32*)pNv->FbStart +
185fc5a983dSmrg			(pbox->x1 * dstPitch) + pScrn->virtualX - pbox->y2;
186fc5a983dSmrg	    srcPtr = (CARD32*)pNv->ShadowPtr +
187fc5a983dSmrg			((1 - pbox->y2) * srcPitch) + pbox->x1;
188fc5a983dSmrg	} else {
189fc5a983dSmrg	    dstPtr = (CARD32*)pNv->FbStart +
190fc5a983dSmrg			((pScrn->virtualY - pbox->x2) * dstPitch) + pbox->y1;
191fc5a983dSmrg	    srcPtr = (CARD32*)pNv->ShadowPtr +
192fc5a983dSmrg			(pbox->y1 * srcPitch) + pbox->x2 - 1;
193fc5a983dSmrg	}
194fc5a983dSmrg
195fc5a983dSmrg	while(width--) {
196fc5a983dSmrg	    src = srcPtr;
197fc5a983dSmrg	    dst = dstPtr;
198fc5a983dSmrg	    count = height;
199fc5a983dSmrg	    while(count--) {
200fc5a983dSmrg		*(dst++) = *src;
201fc5a983dSmrg		src += srcPitch;
202fc5a983dSmrg	    }
203fc5a983dSmrg	    srcPtr += pNv->Rotate;
204fc5a983dSmrg	    dstPtr += dstPitch;
205fc5a983dSmrg	}
206fc5a983dSmrg
207fc5a983dSmrg	pbox++;
208fc5a983dSmrg    }
209fc5a983dSmrg}
210