1 /*
2    Copyright (c) 1999,2000  The XFree86 Project Inc.
3    based on code written by Mark Vojkovich <markv@valinux.com>
4 */
5 
6 #ifdef HAVE_CONFIG_H
7 #include "config.h"
8 #endif
9 
10 #include "xf86.h"
11 #include "xf86_OSproc.h"
12 #include "xf86Pci.h"
13 #include "shadowfb.h"
14 #include "servermd.h"
15 #include "cir.h"
16 #include "alp.h"
17 
18 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
19 #define MAX(a, b) (((a) > (b)) ? (a) : (b))
20 
21 _X_EXPORT void
cirRefreshArea(ScrnInfoPtr pScrn,int num,BoxPtr pbox)22 cirRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
23 {
24     CirPtr pCir = CIRPTR(pScrn);
25     int width, height, Bpp, FBPitch, x1, x2, y1, y2;
26     unsigned char *src, *dst;
27 
28     Bpp = pScrn->bitsPerPixel >> 3;
29     FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel);
30 
31     while(num--) {
32         x1 = MAX(pbox->x1, 0);
33         y1 = MAX(pbox->y1, 0);
34         x2 = MIN(pbox->x2, pScrn->virtualX);
35         y2 = MIN(pbox->y2, pScrn->virtualY);
36 
37         width = (x2 - x1) * Bpp;
38         height = y2 - y1;
39 
40         if (width <= 0 || height <= 0)
41             continue;
42 
43         src = pCir->ShadowPtr + (y1 * pCir->ShadowPitch) + (x1 * Bpp);
44         dst = pCir->FbBase + (y1 * FBPitch) + (x1 * Bpp);
45 
46         while(height--) {
47             memcpy(dst, src, width);
48             dst += FBPitch;
49             src += pCir->ShadowPitch;
50         }
51 
52         pbox++;
53     }
54 }
55 
56 _X_EXPORT void
cirPointerMoved(SCRN_ARG_TYPE arg,int x,int y)57 cirPointerMoved(SCRN_ARG_TYPE arg, int x, int y)
58 {
59     SCRN_INFO_PTR(arg);
60     CirPtr pCir = CIRPTR(pScrn);
61     int newX, newY;
62 
63     if(pCir->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     (*pCir->PointerMoved)(arg, newX, newY);
72 }
73 
74 _X_EXPORT void
cirRefreshArea8(ScrnInfoPtr pScrn,int num,BoxPtr pbox)75 cirRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
76 {
77     CirPtr pCir = CIRPTR(pScrn);
78     int count, width, height, x1, x2, y1, y2, dstPitch, srcPitch;
79     CARD8 *dstPtr, *srcPtr, *src;
80     CARD32 *dst;
81 
82     dstPitch = pScrn->displayWidth;
83     srcPitch = -pCir->rotate * pCir->ShadowPitch;
84 
85     while(num--) {
86         x1 = MAX(pbox->x1, 0);
87         y1 = MAX(pbox->y1, 0);
88         x2 = MIN(pbox->x2, pScrn->virtualX);
89         y2 = MIN(pbox->y2, pScrn->virtualY);
90 
91         width = x2 - x1;
92         y1 = y1 & ~3;
93         y2 = (y2 + 3) & ~3;
94         height = (y2 - y1) / 4;  /* in dwords */
95 
96         if (width <= 0 || height <= 0)
97             continue;
98 
99         if(pCir->rotate == 1) {
100             dstPtr = pCir->FbBase +
101 			(x1 * dstPitch) + pScrn->virtualX - y2;
102             srcPtr = pCir->ShadowPtr + ((1 - y2) * srcPitch) + x1;
103         } else {
104             dstPtr = pCir->FbBase +
105 			((pScrn->virtualY - x2) * dstPitch) + y1;
106             srcPtr = pCir->ShadowPtr + (y1 * srcPitch) + x2 - 1;
107         }
108 
109         while(width--) {
110             src = srcPtr;
111             dst = (CARD32*)dstPtr;
112             count = height;
113             while(count--) {
114                 *(dst++) = src[0] | (src[srcPitch] << 8) |
115 				(src[srcPitch * 2] << 16) |
116 				(src[srcPitch * 3] << 24);
117                 src += srcPitch * 4;
118             }
119             srcPtr += pCir->rotate;
120             dstPtr += dstPitch;
121         }
122 
123         pbox++;
124     }
125 }
126 
127 
128 _X_EXPORT void
cirRefreshArea16(ScrnInfoPtr pScrn,int num,BoxPtr pbox)129 cirRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
130 {
131     CirPtr pCir = CIRPTR(pScrn);
132     int count, width, height, x1, x2, y1, y2, dstPitch, srcPitch;
133     CARD16 *dstPtr, *srcPtr, *src;
134     CARD32 *dst;
135 
136     dstPitch = pScrn->displayWidth;
137     srcPitch = -pCir->rotate * pCir->ShadowPitch >> 1;
138 
139     while(num--) {
140         x1 = MAX(pbox->x1, 0);
141         y1 = MAX(pbox->y1, 0);
142         x2 = MIN(pbox->x2, pScrn->virtualX);
143         y2 = MIN(pbox->y2, pScrn->virtualY);
144 
145         width = x2 - x1;
146         y1 = y1 & ~1;
147         y2 = (y2 + 1) & ~1;
148         height = (y2 - y1) / 2;  /* in dwords */
149 
150         if (width <= 0 || height <= 0)
151             continue;
152 
153         if(pCir->rotate == 1) {
154             dstPtr = (CARD16*)pCir->FbBase +
155 			(x1 * dstPitch) + pScrn->virtualX - y2;
156             srcPtr = (CARD16*)pCir->ShadowPtr +
157 			((1 - y2) * srcPitch) + x1;
158         } else {
159             dstPtr = (CARD16*)pCir->FbBase +
160 			((pScrn->virtualY - x2) * dstPitch) + y1;
161             srcPtr = (CARD16*)pCir->ShadowPtr +
162 			(y1 * srcPitch) + x2 - 1;
163         }
164 
165         while(width--) {
166             src = srcPtr;
167             dst = (CARD32*)dstPtr;
168             count = height;
169             while(count--) {
170                 *(dst++) = src[0] | (src[srcPitch] << 16);
171                 src += srcPitch * 2;
172             }
173             srcPtr += pCir->rotate;
174             dstPtr += dstPitch;
175         }
176 
177         pbox++;
178     }
179 }
180 
181 
182 /* this one could be faster */
183 _X_EXPORT void
cirRefreshArea24(ScrnInfoPtr pScrn,int num,BoxPtr pbox)184 cirRefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
185 {
186     CirPtr pCir = CIRPTR(pScrn);
187     int count, width, height, x1, x2, y1, y2, dstPitch, srcPitch;
188     CARD8 *dstPtr, *srcPtr, *src;
189     CARD32 *dst;
190 
191     dstPitch = BitmapBytePad(pScrn->displayWidth * 24);
192     srcPitch = -pCir->rotate * pCir->ShadowPitch;
193 
194     while(num--) {
195         x1 = MAX(pbox->x1, 0);
196         y1 = MAX(pbox->y1, 0);
197         x2 = MIN(pbox->x2, pScrn->virtualX);
198         y2 = MIN(pbox->y2, pScrn->virtualY);
199 
200         width = x2 - x1;
201         y1 = y1 & ~3;
202         y2 = (y2 + 3) & ~3;
203         height = (y2 - y1) / 4;  /* blocks of 3 dwords */
204 
205         if (width <= 0 || height <= 0)
206             continue;
207 
208         if(pCir->rotate == 1) {
209             dstPtr = pCir->FbBase +
210 			(x1 * dstPitch) + ((pScrn->virtualX - y2) * 3);
211             srcPtr = pCir->ShadowPtr + ((1 - y2) * srcPitch) + (x1 * 3);
212         } else {
213             dstPtr = pCir->FbBase +
214                 ((pScrn->virtualY - x2) * dstPitch) + (y1 * 3);
215             srcPtr = pCir->ShadowPtr + (y1 * srcPitch) + (x2 * 3) - 3;
216         }
217 
218         while(width--) {
219             src = srcPtr;
220             dst = (CARD32*)dstPtr;
221             count = height;
222             while(count--) {
223                 dst[0] = src[0] | (src[1] << 8) | (src[2] << 16) |
224 				(src[srcPitch] << 24);
225                 dst[1] = src[srcPitch + 1] | (src[srcPitch + 2] << 8) |
226 				(src[srcPitch * 2] << 16) |
227 				(src[(srcPitch * 2) + 1] << 24);
228                 dst[2] = src[(srcPitch * 2) + 2] | (src[srcPitch * 3] << 8) |
229 				(src[(srcPitch * 3) + 1] << 16) |
230 				(src[(srcPitch * 3) + 2] << 24);
231                 dst += 3;
232                 src += srcPitch * 4;
233             }
234             srcPtr += pCir->rotate * 3;
235             dstPtr += dstPitch;
236         }
237 
238         pbox++;
239     }
240 }
241 
242 _X_EXPORT void
cirRefreshArea32(ScrnInfoPtr pScrn,int num,BoxPtr pbox)243 cirRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
244 {
245     CirPtr pCir = CIRPTR(pScrn);
246     int count, width, height, x1, x2, y1, y2, dstPitch, srcPitch;
247     CARD32 *dstPtr, *srcPtr, *src, *dst;
248 
249     dstPitch = pScrn->displayWidth;
250     srcPitch = -pCir->rotate * pCir->ShadowPitch >> 2;
251 
252     while(num--) {
253         x1 = MAX(pbox->x1, 0);
254         y1 = MAX(pbox->y1, 0);
255         x2 = MIN(pbox->x2, pScrn->virtualX);
256         y2 = MIN(pbox->y2, pScrn->virtualY);
257 
258         width = x2 - x1;
259         height = y2 - y1;
260 
261         if (width <= 0 || height <= 0)
262             continue;
263 
264         if(pCir->rotate == 1) {
265             dstPtr = (CARD32*)pCir->FbBase +
266 			(x1 * dstPitch) + pScrn->virtualX - y2;
267             srcPtr = (CARD32*)pCir->ShadowPtr +
268 			((1 - y2) * srcPitch) + x1;
269         } else {
270             dstPtr = (CARD32*)pCir->FbBase +
271 			((pScrn->virtualY - x2) * dstPitch) + y1;
272             srcPtr = (CARD32*)pCir->ShadowPtr +
273 			(y1 * srcPitch) + x2 - 1;
274         }
275 
276         while(width--) {
277             src = srcPtr;
278             dst = dstPtr;
279             count = height;
280             while(count--) {
281                 *(dst++) = *src;
282                 src += srcPitch;
283             }
284             srcPtr += pCir->rotate;
285             dstPtr += dstPitch;
286         }
287 
288         pbox++;
289     }
290 }
291 
292 
293 
294