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