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