14178061cSmrg/* 24178061cSmrgCopyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. 34178061cSmrg 44178061cSmrgPermission is hereby granted, free of charge, to any person obtaining a copy of 54178061cSmrgthis software and associated documentation files (the "Software"), to deal in 64178061cSmrgthe Software without restriction, including without limitation the rights to 74178061cSmrguse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 84178061cSmrgof the Software, and to permit persons to whom the Software is furnished to do 94178061cSmrgso, subject to the following conditions: 104178061cSmrg 114178061cSmrgThe above copyright notice and this permission notice shall be included in all 124178061cSmrgcopies or substantial portions of the Software. 134178061cSmrg 144178061cSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 154178061cSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- 164178061cSmrgNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 174178061cSmrgXFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 184178061cSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 194178061cSmrgWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 204178061cSmrg 214178061cSmrgExcept as contained in this notice, the name of the XFree86 Project shall not 224178061cSmrgbe used in advertising or otherwise to promote the sale, use or other dealings 234178061cSmrgin this Software without prior written authorization from the XFree86 Project. 244178061cSmrg*/ 254178061cSmrg 264178061cSmrg/* 274178061cSmrg Copyright (c) 1999,2000 The XFree86 Project Inc. 284178061cSmrg based on code written by Mark Vojkovich <markv@valinux.com> 294178061cSmrg*/ 304178061cSmrg 314178061cSmrg#ifdef HAVE_CONFIG_H 324178061cSmrg#include "config.h" 334178061cSmrg#endif 344178061cSmrg 354178061cSmrg#include "xf86.h" 364178061cSmrg#include "xf86_OSproc.h" 374178061cSmrg#include "xf86Pci.h" 384178061cSmrg#include "shadowfb.h" 394178061cSmrg#include "servermd.h" 404178061cSmrg#include "s3.h" 414178061cSmrg 424178061cSmrg 434178061cSmrgvoid 444178061cSmrgS3RefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 454178061cSmrg{ 464178061cSmrg S3Ptr pS3 = S3PTR(pScrn); 474178061cSmrg int width, height, Bpp, FBPitch; 484178061cSmrg unsigned char *src, *dst; 494178061cSmrg 504178061cSmrg Bpp = pScrn->bitsPerPixel >> 3; 514178061cSmrg FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel); 524178061cSmrg 534178061cSmrg while(num--) { 544178061cSmrg width = (pbox->x2 - pbox->x1) * Bpp; 554178061cSmrg height = pbox->y2 - pbox->y1; 564178061cSmrg src = pS3->ShadowPtr + (pbox->y1 * pS3->ShadowPitch) + 574178061cSmrg (pbox->x1 * Bpp); 584178061cSmrg dst = pS3->FBBase + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp); 594178061cSmrg 604178061cSmrg while(height--) { 614178061cSmrg memcpy(dst, src, width); 624178061cSmrg dst += FBPitch; 634178061cSmrg src += pS3->ShadowPitch; 644178061cSmrg } 654178061cSmrg 664178061cSmrg pbox++; 674178061cSmrg } 684178061cSmrg} 694178061cSmrg 704178061cSmrgvoid 71b27e1915SmrgS3PointerMoved(SCRN_ARG_TYPE arg, int x, int y) 724178061cSmrg{ 73b27e1915Smrg SCRN_INFO_PTR(arg); 744178061cSmrg S3Ptr pS3 = S3PTR(pScrn); 754178061cSmrg int newX, newY; 764178061cSmrg 774178061cSmrg if(pS3->rotate == 1) { 784178061cSmrg newX = pScrn->pScreen->height - y - 1; 794178061cSmrg newY = x; 804178061cSmrg } else { 814178061cSmrg newX = y; 824178061cSmrg newY = pScrn->pScreen->width - x - 1; 834178061cSmrg } 844178061cSmrg 85b27e1915Smrg (*pS3->PointerMoved)(arg, newX, newY); 864178061cSmrg} 874178061cSmrg 884178061cSmrgvoid 894178061cSmrgS3RefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 904178061cSmrg{ 914178061cSmrg S3Ptr pS3 = S3PTR(pScrn); 924178061cSmrg int count, width, height, y1, y2, dstPitch, srcPitch; 934178061cSmrg CARD8 *dstPtr, *srcPtr, *src; 944178061cSmrg CARD32 *dst; 954178061cSmrg 964178061cSmrg dstPitch = pScrn->displayWidth; 974178061cSmrg srcPitch = -pS3->rotate * pS3->ShadowPitch; 984178061cSmrg 994178061cSmrg while(num--) { 1004178061cSmrg width = pbox->x2 - pbox->x1; 1014178061cSmrg y1 = pbox->y1 & ~3; 1024178061cSmrg y2 = (pbox->y2 + 3) & ~3; 1034178061cSmrg height = (y2 - y1) >> 2; /* in dwords */ 1044178061cSmrg 1054178061cSmrg if(pS3->rotate == 1) { 1064178061cSmrg dstPtr = pS3->FBBase + 1074178061cSmrg (pbox->x1 * dstPitch) + pScrn->virtualX - y2; 1084178061cSmrg srcPtr = pS3->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1; 1094178061cSmrg } else { 1104178061cSmrg dstPtr = pS3->FBBase + 1114178061cSmrg ((pScrn->virtualY - pbox->x2) * dstPitch) + y1; 1124178061cSmrg srcPtr = pS3->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1; 1134178061cSmrg } 1144178061cSmrg 1154178061cSmrg while(width--) { 1164178061cSmrg src = srcPtr; 1174178061cSmrg dst = (CARD32*)dstPtr; 1184178061cSmrg count = height; 1194178061cSmrg while(count--) { 1204178061cSmrg *(dst++) = src[0] | (src[srcPitch] << 8) | 1214178061cSmrg (src[srcPitch * 2] << 16) | 1224178061cSmrg (src[srcPitch * 3] << 24); 1234178061cSmrg src += srcPitch * 4; 1244178061cSmrg } 1254178061cSmrg srcPtr += pS3->rotate; 1264178061cSmrg dstPtr += dstPitch; 1274178061cSmrg } 1284178061cSmrg 1294178061cSmrg pbox++; 1304178061cSmrg } 1314178061cSmrg} 1324178061cSmrg 1334178061cSmrg 1344178061cSmrgvoid 1354178061cSmrgS3RefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 1364178061cSmrg{ 1374178061cSmrg S3Ptr pS3 = S3PTR(pScrn); 1384178061cSmrg int count, width, height, y1, y2, dstPitch, srcPitch; 1394178061cSmrg CARD16 *dstPtr, *srcPtr, *src; 1404178061cSmrg CARD32 *dst; 1414178061cSmrg 1424178061cSmrg dstPitch = pScrn->displayWidth; 1434178061cSmrg srcPitch = -pS3->rotate * pS3->ShadowPitch >> 1; 1444178061cSmrg 1454178061cSmrg while(num--) { 1464178061cSmrg width = pbox->x2 - pbox->x1; 1474178061cSmrg y1 = pbox->y1 & ~1; 1484178061cSmrg y2 = (pbox->y2 + 1) & ~1; 1494178061cSmrg height = (y2 - y1) >> 1; /* in dwords */ 1504178061cSmrg 1514178061cSmrg if(pS3->rotate == 1) { 1524178061cSmrg dstPtr = (CARD16*)pS3->FBBase + 1534178061cSmrg (pbox->x1 * dstPitch) + pScrn->virtualX - y2; 1544178061cSmrg srcPtr = (CARD16*)pS3->ShadowPtr + 1554178061cSmrg ((1 - y2) * srcPitch) + pbox->x1; 1564178061cSmrg } else { 1574178061cSmrg dstPtr = (CARD16*)pS3->FBBase + 1584178061cSmrg ((pScrn->virtualY - pbox->x2) * dstPitch) + y1; 1594178061cSmrg srcPtr = (CARD16*)pS3->ShadowPtr + 1604178061cSmrg (y1 * srcPitch) + pbox->x2 - 1; 1614178061cSmrg } 1624178061cSmrg 1634178061cSmrg while(width--) { 1644178061cSmrg src = srcPtr; 1654178061cSmrg dst = (CARD32*)dstPtr; 1664178061cSmrg count = height; 1674178061cSmrg while(count--) { 1684178061cSmrg *(dst++) = src[0] | (src[srcPitch] << 16); 1694178061cSmrg src += srcPitch * 2; 1704178061cSmrg } 1714178061cSmrg srcPtr += pS3->rotate; 1724178061cSmrg dstPtr += dstPitch; 1734178061cSmrg } 1744178061cSmrg 1754178061cSmrg pbox++; 1764178061cSmrg } 1774178061cSmrg} 1784178061cSmrg 1794178061cSmrg 1804178061cSmrg/* this one could be faster */ 1814178061cSmrgvoid 1824178061cSmrgS3RefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 1834178061cSmrg{ 1844178061cSmrg S3Ptr pS3 = S3PTR(pScrn); 1854178061cSmrg int count, width, height, y1, y2, dstPitch, srcPitch; 1864178061cSmrg CARD8 *dstPtr, *srcPtr, *src; 1874178061cSmrg CARD32 *dst; 1884178061cSmrg 1894178061cSmrg dstPitch = BitmapBytePad(pScrn->displayWidth * 24); 1904178061cSmrg srcPitch = -pS3->rotate * pS3->ShadowPitch; 1914178061cSmrg 1924178061cSmrg while(num--) { 1934178061cSmrg width = pbox->x2 - pbox->x1; 1944178061cSmrg y1 = pbox->y1 & ~3; 1954178061cSmrg y2 = (pbox->y2 + 3) & ~3; 1964178061cSmrg height = (y2 - y1) >> 2; /* blocks of 3 dwords */ 1974178061cSmrg 1984178061cSmrg if(pS3->rotate == 1) { 1994178061cSmrg dstPtr = pS3->FBBase + 2004178061cSmrg (pbox->x1 * dstPitch) + ((pScrn->virtualX - y2) * 3); 2014178061cSmrg srcPtr = pS3->ShadowPtr + ((1 - y2) * srcPitch) + (pbox->x1 * 3); 2024178061cSmrg } else { 2034178061cSmrg dstPtr = pS3->FBBase + 2044178061cSmrg ((pScrn->virtualY - pbox->x2) * dstPitch) + (y1 * 3); 2054178061cSmrg srcPtr = pS3->ShadowPtr + (y1 * srcPitch) + (pbox->x2 * 3) - 3; 2064178061cSmrg } 2074178061cSmrg 2084178061cSmrg while(width--) { 2094178061cSmrg src = srcPtr; 2104178061cSmrg dst = (CARD32*)dstPtr; 2114178061cSmrg count = height; 2124178061cSmrg while(count--) { 2134178061cSmrg dst[0] = src[0] | (src[1] << 8) | (src[2] << 16) | 2144178061cSmrg (src[srcPitch] << 24); 2154178061cSmrg dst[1] = src[srcPitch + 1] | (src[srcPitch + 2] << 8) | 2164178061cSmrg (src[srcPitch * 2] << 16) | 2174178061cSmrg (src[(srcPitch * 2) + 1] << 24); 2184178061cSmrg dst[2] = src[(srcPitch * 2) + 2] | (src[srcPitch * 3] << 8) | 2194178061cSmrg (src[(srcPitch * 3) + 1] << 16) | 2204178061cSmrg (src[(srcPitch * 3) + 2] << 24); 2214178061cSmrg dst += 3; 2224178061cSmrg src += srcPitch * 4; 2234178061cSmrg } 2244178061cSmrg srcPtr += pS3->rotate * 3; 2254178061cSmrg dstPtr += dstPitch; 2264178061cSmrg } 2274178061cSmrg 2284178061cSmrg pbox++; 2294178061cSmrg } 2304178061cSmrg} 2314178061cSmrg 2324178061cSmrgvoid 2334178061cSmrgS3RefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 2344178061cSmrg{ 2354178061cSmrg S3Ptr pS3 = S3PTR(pScrn); 2364178061cSmrg int count, width, height, dstPitch, srcPitch; 2374178061cSmrg CARD32 *dstPtr, *srcPtr, *src, *dst; 2384178061cSmrg 2394178061cSmrg dstPitch = pScrn->displayWidth; 2404178061cSmrg srcPitch = -pS3->rotate * pS3->ShadowPitch >> 2; 2414178061cSmrg 2424178061cSmrg while(num--) { 2434178061cSmrg width = pbox->x2 - pbox->x1; 2444178061cSmrg height = pbox->y2 - pbox->y1; 2454178061cSmrg 2464178061cSmrg if(pS3->rotate == 1) { 2474178061cSmrg dstPtr = (CARD32*)pS3->FBBase + 2484178061cSmrg (pbox->x1 * dstPitch) + pScrn->virtualX - pbox->y2; 2494178061cSmrg srcPtr = (CARD32*)pS3->ShadowPtr + 2504178061cSmrg ((1 - pbox->y2) * srcPitch) + pbox->x1; 2514178061cSmrg } else { 2524178061cSmrg dstPtr = (CARD32*)pS3->FBBase + 2534178061cSmrg ((pScrn->virtualY - pbox->x2) * dstPitch) + pbox->y1; 2544178061cSmrg srcPtr = (CARD32*)pS3->ShadowPtr + 2554178061cSmrg (pbox->y1 * srcPitch) + pbox->x2 - 1; 2564178061cSmrg } 2574178061cSmrg 2584178061cSmrg while(width--) { 2594178061cSmrg src = srcPtr; 2604178061cSmrg dst = dstPtr; 2614178061cSmrg count = height; 2624178061cSmrg while(count--) { 2634178061cSmrg *(dst++) = *src; 2644178061cSmrg src += srcPitch; 2654178061cSmrg } 2664178061cSmrg srcPtr += pS3->rotate; 2674178061cSmrg dstPtr += dstPitch; 2684178061cSmrg } 2694178061cSmrg 2704178061cSmrg pbox++; 2714178061cSmrg } 2724178061cSmrg} 273