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