1/* 2Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. 3 4Permission is hereby granted, free of charge, to any person obtaining a copy of 5this software and associated documentation files (the "Software"), to deal in 6the Software without restriction, including without limitation the rights to 7use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 8of the Software, and to permit persons to whom the Software is furnished to do 9so, subject to the following conditions: 10 11The above copyright notice and this permission notice shall be included in all 12copies or substantial portions of the Software. 13 14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- 16NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 19WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 21Except as contained in this notice, the name of the XFree86 Project shall not 22be used in advertising or otherwise to promote the sale, use or other dealings 23in this Software without prior written authorization from the XFree86 Project. 24*/ 25 26/* 27 Copyright (c) 1999,2000 The XFree86 Project Inc. 28 based on code written by Mark Vojkovich <markv@valinux.com> 29*/ 30 31#ifdef HAVE_CONFIG_H 32#include "config.h" 33#endif 34 35#include "xf86.h" 36#include "xf86_OSproc.h" 37#include "xf86Pci.h" 38#include "shadowfb.h" 39#include "servermd.h" 40#include "s3.h" 41 42 43void 44S3RefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 45{ 46 S3Ptr pS3 = S3PTR(pScrn); 47 int width, height, Bpp, FBPitch; 48 unsigned char *src, *dst; 49 50 Bpp = pScrn->bitsPerPixel >> 3; 51 FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel); 52 53 while(num--) { 54 width = (pbox->x2 - pbox->x1) * Bpp; 55 height = pbox->y2 - pbox->y1; 56 src = pS3->ShadowPtr + (pbox->y1 * pS3->ShadowPitch) + 57 (pbox->x1 * Bpp); 58 dst = pS3->FBBase + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp); 59 60 while(height--) { 61 memcpy(dst, src, width); 62 dst += FBPitch; 63 src += pS3->ShadowPitch; 64 } 65 66 pbox++; 67 } 68} 69 70void 71S3PointerMoved(SCRN_ARG_TYPE arg, int x, int y) 72{ 73 SCRN_INFO_PTR(arg); 74 S3Ptr pS3 = S3PTR(pScrn); 75 int newX, newY; 76 77 if(pS3->rotate == 1) { 78 newX = pScrn->pScreen->height - y - 1; 79 newY = x; 80 } else { 81 newX = y; 82 newY = pScrn->pScreen->width - x - 1; 83 } 84 85 (*pS3->PointerMoved)(arg, newX, newY); 86} 87 88void 89S3RefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 90{ 91 S3Ptr pS3 = S3PTR(pScrn); 92 int count, width, height, y1, y2, dstPitch, srcPitch; 93 CARD8 *dstPtr, *srcPtr, *src; 94 CARD32 *dst; 95 96 dstPitch = pScrn->displayWidth; 97 srcPitch = -pS3->rotate * pS3->ShadowPitch; 98 99 while(num--) { 100 width = pbox->x2 - pbox->x1; 101 y1 = pbox->y1 & ~3; 102 y2 = (pbox->y2 + 3) & ~3; 103 height = (y2 - y1) >> 2; /* in dwords */ 104 105 if(pS3->rotate == 1) { 106 dstPtr = pS3->FBBase + 107 (pbox->x1 * dstPitch) + pScrn->virtualX - y2; 108 srcPtr = pS3->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1; 109 } else { 110 dstPtr = pS3->FBBase + 111 ((pScrn->virtualY - pbox->x2) * dstPitch) + y1; 112 srcPtr = pS3->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1; 113 } 114 115 while(width--) { 116 src = srcPtr; 117 dst = (CARD32*)dstPtr; 118 count = height; 119 while(count--) { 120 *(dst++) = src[0] | (src[srcPitch] << 8) | 121 (src[srcPitch * 2] << 16) | 122 (src[srcPitch * 3] << 24); 123 src += srcPitch * 4; 124 } 125 srcPtr += pS3->rotate; 126 dstPtr += dstPitch; 127 } 128 129 pbox++; 130 } 131} 132 133 134void 135S3RefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 136{ 137 S3Ptr pS3 = S3PTR(pScrn); 138 int count, width, height, y1, y2, dstPitch, srcPitch; 139 CARD16 *dstPtr, *srcPtr, *src; 140 CARD32 *dst; 141 142 dstPitch = pScrn->displayWidth; 143 srcPitch = -pS3->rotate * pS3->ShadowPitch >> 1; 144 145 while(num--) { 146 width = pbox->x2 - pbox->x1; 147 y1 = pbox->y1 & ~1; 148 y2 = (pbox->y2 + 1) & ~1; 149 height = (y2 - y1) >> 1; /* in dwords */ 150 151 if(pS3->rotate == 1) { 152 dstPtr = (CARD16*)pS3->FBBase + 153 (pbox->x1 * dstPitch) + pScrn->virtualX - y2; 154 srcPtr = (CARD16*)pS3->ShadowPtr + 155 ((1 - y2) * srcPitch) + pbox->x1; 156 } else { 157 dstPtr = (CARD16*)pS3->FBBase + 158 ((pScrn->virtualY - pbox->x2) * dstPitch) + y1; 159 srcPtr = (CARD16*)pS3->ShadowPtr + 160 (y1 * srcPitch) + pbox->x2 - 1; 161 } 162 163 while(width--) { 164 src = srcPtr; 165 dst = (CARD32*)dstPtr; 166 count = height; 167 while(count--) { 168 *(dst++) = src[0] | (src[srcPitch] << 16); 169 src += srcPitch * 2; 170 } 171 srcPtr += pS3->rotate; 172 dstPtr += dstPitch; 173 } 174 175 pbox++; 176 } 177} 178 179 180/* this one could be faster */ 181void 182S3RefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 183{ 184 S3Ptr pS3 = S3PTR(pScrn); 185 int count, width, height, y1, y2, dstPitch, srcPitch; 186 CARD8 *dstPtr, *srcPtr, *src; 187 CARD32 *dst; 188 189 dstPitch = BitmapBytePad(pScrn->displayWidth * 24); 190 srcPitch = -pS3->rotate * pS3->ShadowPitch; 191 192 while(num--) { 193 width = pbox->x2 - pbox->x1; 194 y1 = pbox->y1 & ~3; 195 y2 = (pbox->y2 + 3) & ~3; 196 height = (y2 - y1) >> 2; /* blocks of 3 dwords */ 197 198 if(pS3->rotate == 1) { 199 dstPtr = pS3->FBBase + 200 (pbox->x1 * dstPitch) + ((pScrn->virtualX - y2) * 3); 201 srcPtr = pS3->ShadowPtr + ((1 - y2) * srcPitch) + (pbox->x1 * 3); 202 } else { 203 dstPtr = pS3->FBBase + 204 ((pScrn->virtualY - pbox->x2) * dstPitch) + (y1 * 3); 205 srcPtr = pS3->ShadowPtr + (y1 * srcPitch) + (pbox->x2 * 3) - 3; 206 } 207 208 while(width--) { 209 src = srcPtr; 210 dst = (CARD32*)dstPtr; 211 count = height; 212 while(count--) { 213 dst[0] = src[0] | (src[1] << 8) | (src[2] << 16) | 214 (src[srcPitch] << 24); 215 dst[1] = src[srcPitch + 1] | (src[srcPitch + 2] << 8) | 216 (src[srcPitch * 2] << 16) | 217 (src[(srcPitch * 2) + 1] << 24); 218 dst[2] = src[(srcPitch * 2) + 2] | (src[srcPitch * 3] << 8) | 219 (src[(srcPitch * 3) + 1] << 16) | 220 (src[(srcPitch * 3) + 2] << 24); 221 dst += 3; 222 src += srcPitch * 4; 223 } 224 srcPtr += pS3->rotate * 3; 225 dstPtr += dstPitch; 226 } 227 228 pbox++; 229 } 230} 231 232void 233S3RefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 234{ 235 S3Ptr pS3 = S3PTR(pScrn); 236 int count, width, height, dstPitch, srcPitch; 237 CARD32 *dstPtr, *srcPtr, *src, *dst; 238 239 dstPitch = pScrn->displayWidth; 240 srcPitch = -pS3->rotate * pS3->ShadowPitch >> 2; 241 242 while(num--) { 243 width = pbox->x2 - pbox->x1; 244 height = pbox->y2 - pbox->y1; 245 246 if(pS3->rotate == 1) { 247 dstPtr = (CARD32*)pS3->FBBase + 248 (pbox->x1 * dstPitch) + pScrn->virtualX - pbox->y2; 249 srcPtr = (CARD32*)pS3->ShadowPtr + 250 ((1 - pbox->y2) * srcPitch) + pbox->x1; 251 } else { 252 dstPtr = (CARD32*)pS3->FBBase + 253 ((pScrn->virtualY - pbox->x2) * dstPitch) + pbox->y1; 254 srcPtr = (CARD32*)pS3->ShadowPtr + 255 (pbox->y1 * srcPitch) + pbox->x2 - 1; 256 } 257 258 while(width--) { 259 src = srcPtr; 260 dst = dstPtr; 261 count = height; 262 while(count--) { 263 *(dst++) = *src; 264 src += srcPitch; 265 } 266 srcPtr += pS3->rotate; 267 dstPtr += dstPitch; 268 } 269 270 pbox++; 271 } 272} 273