176888252Smrg/*
276888252Smrg   Copyright (c) 1999,2000  The XFree86 Project Inc.
376888252Smrg   based on code written by Mark Vojkovich <markv@valinux.com>
476888252Smrg*/
576888252Smrg
676888252Smrg#ifdef HAVE_CONFIG_H
776888252Smrg#include "config.h"
876888252Smrg#endif
976888252Smrg
1076888252Smrg#include "xf86.h"
1176888252Smrg#include "xf86_OSproc.h"
1276888252Smrg#include "xf86Pci.h"
1376888252Smrg#include "shadowfb.h"
1476888252Smrg#include "servermd.h"
1576888252Smrg#include "cir.h"
1676888252Smrg#include "alp.h"
1776888252Smrg
1863847c39Smrg#define MIN(a, b) (((a) < (b)) ? (a) : (b))
1963847c39Smrg#define MAX(a, b) (((a) > (b)) ? (a) : (b))
2063847c39Smrg
211ae1b5e8Smrg_X_EXPORT void
2276888252SmrgcirRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
2376888252Smrg{
2476888252Smrg    CirPtr pCir = CIRPTR(pScrn);
2563847c39Smrg    int width, height, Bpp, FBPitch, x1, x2, y1, y2;
2676888252Smrg    unsigned char *src, *dst;
2776888252Smrg
2876888252Smrg    Bpp = pScrn->bitsPerPixel >> 3;
2976888252Smrg    FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel);
3076888252Smrg
3176888252Smrg    while(num--) {
3263847c39Smrg        x1 = MAX(pbox->x1, 0);
3363847c39Smrg        y1 = MAX(pbox->y1, 0);
3463847c39Smrg        x2 = MIN(pbox->x2, pScrn->virtualX);
3563847c39Smrg        y2 = MIN(pbox->y2, pScrn->virtualY);
3663847c39Smrg
3763847c39Smrg        width = (x2 - x1) * Bpp;
3863847c39Smrg        height = y2 - y1;
3963847c39Smrg
4063847c39Smrg        if (width <= 0 || height <= 0)
4163847c39Smrg            continue;
4263847c39Smrg
4363847c39Smrg        src = pCir->ShadowPtr + (y1 * pCir->ShadowPitch) + (x1 * Bpp);
4463847c39Smrg        dst = pCir->FbBase + (y1 * FBPitch) + (x1 * Bpp);
4563847c39Smrg
4663847c39Smrg        while(height--) {
4763847c39Smrg            memcpy(dst, src, width);
4863847c39Smrg            dst += FBPitch;
4963847c39Smrg            src += pCir->ShadowPitch;
5063847c39Smrg        }
5163847c39Smrg
5263847c39Smrg        pbox++;
5376888252Smrg    }
5476888252Smrg}
5576888252Smrg
561ae1b5e8Smrg_X_EXPORT void
5763847c39SmrgcirPointerMoved(SCRN_ARG_TYPE arg, int x, int y)
5876888252Smrg{
5963847c39Smrg    SCRN_INFO_PTR(arg);
6076888252Smrg    CirPtr pCir = CIRPTR(pScrn);
6176888252Smrg    int newX, newY;
6276888252Smrg
6376888252Smrg    if(pCir->rotate == 1) {
6476888252Smrg	newX = pScrn->pScreen->height - y - 1;
6576888252Smrg	newY = x;
6676888252Smrg    } else {
6776888252Smrg	newX = y;
6876888252Smrg	newY = pScrn->pScreen->width - x - 1;
6976888252Smrg    }
7076888252Smrg
7163847c39Smrg    (*pCir->PointerMoved)(arg, newX, newY);
7276888252Smrg}
7376888252Smrg
741ae1b5e8Smrg_X_EXPORT void
7576888252SmrgcirRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
7676888252Smrg{
7776888252Smrg    CirPtr pCir = CIRPTR(pScrn);
7863847c39Smrg    int count, width, height, x1, x2, y1, y2, dstPitch, srcPitch;
7976888252Smrg    CARD8 *dstPtr, *srcPtr, *src;
8076888252Smrg    CARD32 *dst;
8176888252Smrg
8276888252Smrg    dstPitch = pScrn->displayWidth;
8376888252Smrg    srcPitch = -pCir->rotate * pCir->ShadowPitch;
8476888252Smrg
8576888252Smrg    while(num--) {
8663847c39Smrg        x1 = MAX(pbox->x1, 0);
8763847c39Smrg        y1 = MAX(pbox->y1, 0);
8863847c39Smrg        x2 = MIN(pbox->x2, pScrn->virtualX);
8963847c39Smrg        y2 = MIN(pbox->y2, pScrn->virtualY);
9063847c39Smrg
9163847c39Smrg        width = x2 - x1;
9263847c39Smrg        y1 = y1 & ~3;
9363847c39Smrg        y2 = (y2 + 3) & ~3;
9463847c39Smrg        height = (y2 - y1) / 4;  /* in dwords */
9563847c39Smrg
9663847c39Smrg        if (width <= 0 || height <= 0)
9763847c39Smrg            continue;
9863847c39Smrg
9963847c39Smrg        if(pCir->rotate == 1) {
10063847c39Smrg            dstPtr = pCir->FbBase +
10163847c39Smrg			(x1 * dstPitch) + pScrn->virtualX - y2;
10263847c39Smrg            srcPtr = pCir->ShadowPtr + ((1 - y2) * srcPitch) + x1;
10363847c39Smrg        } else {
10463847c39Smrg            dstPtr = pCir->FbBase +
10563847c39Smrg			((pScrn->virtualY - x2) * dstPitch) + y1;
10663847c39Smrg            srcPtr = pCir->ShadowPtr + (y1 * srcPitch) + x2 - 1;
10763847c39Smrg        }
10863847c39Smrg
10963847c39Smrg        while(width--) {
11063847c39Smrg            src = srcPtr;
11163847c39Smrg            dst = (CARD32*)dstPtr;
11263847c39Smrg            count = height;
11363847c39Smrg            while(count--) {
11463847c39Smrg                *(dst++) = src[0] | (src[srcPitch] << 8) |
11563847c39Smrg				(src[srcPitch * 2] << 16) |
11663847c39Smrg				(src[srcPitch * 3] << 24);
11763847c39Smrg                src += srcPitch * 4;
11863847c39Smrg            }
11963847c39Smrg            srcPtr += pCir->rotate;
12063847c39Smrg            dstPtr += dstPitch;
12163847c39Smrg        }
12263847c39Smrg
12363847c39Smrg        pbox++;
12476888252Smrg    }
12576888252Smrg}
12676888252Smrg
12776888252Smrg
1281ae1b5e8Smrg_X_EXPORT void
12976888252SmrgcirRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
13076888252Smrg{
13176888252Smrg    CirPtr pCir = CIRPTR(pScrn);
13263847c39Smrg    int count, width, height, x1, x2, y1, y2, dstPitch, srcPitch;
13376888252Smrg    CARD16 *dstPtr, *srcPtr, *src;
13476888252Smrg    CARD32 *dst;
13576888252Smrg
13676888252Smrg    dstPitch = pScrn->displayWidth;
13776888252Smrg    srcPitch = -pCir->rotate * pCir->ShadowPitch >> 1;
13876888252Smrg
13976888252Smrg    while(num--) {
14063847c39Smrg        x1 = MAX(pbox->x1, 0);
14163847c39Smrg        y1 = MAX(pbox->y1, 0);
14263847c39Smrg        x2 = MIN(pbox->x2, pScrn->virtualX);
14363847c39Smrg        y2 = MIN(pbox->y2, pScrn->virtualY);
14463847c39Smrg
14563847c39Smrg        width = x2 - x1;
14663847c39Smrg        y1 = y1 & ~1;
14763847c39Smrg        y2 = (y2 + 1) & ~1;
14863847c39Smrg        height = (y2 - y1) / 2;  /* in dwords */
14963847c39Smrg
15063847c39Smrg        if (width <= 0 || height <= 0)
15163847c39Smrg            continue;
15263847c39Smrg
15363847c39Smrg        if(pCir->rotate == 1) {
15463847c39Smrg            dstPtr = (CARD16*)pCir->FbBase +
15563847c39Smrg			(x1 * dstPitch) + pScrn->virtualX - y2;
15663847c39Smrg            srcPtr = (CARD16*)pCir->ShadowPtr +
15763847c39Smrg			((1 - y2) * srcPitch) + x1;
15863847c39Smrg        } else {
15963847c39Smrg            dstPtr = (CARD16*)pCir->FbBase +
16063847c39Smrg			((pScrn->virtualY - x2) * dstPitch) + y1;
16163847c39Smrg            srcPtr = (CARD16*)pCir->ShadowPtr +
16263847c39Smrg			(y1 * srcPitch) + x2 - 1;
16363847c39Smrg        }
16463847c39Smrg
16563847c39Smrg        while(width--) {
16663847c39Smrg            src = srcPtr;
16763847c39Smrg            dst = (CARD32*)dstPtr;
16863847c39Smrg            count = height;
16963847c39Smrg            while(count--) {
17063847c39Smrg                *(dst++) = src[0] | (src[srcPitch] << 16);
17163847c39Smrg                src += srcPitch * 2;
17263847c39Smrg            }
17363847c39Smrg            srcPtr += pCir->rotate;
17463847c39Smrg            dstPtr += dstPitch;
17563847c39Smrg        }
17663847c39Smrg
17763847c39Smrg        pbox++;
17876888252Smrg    }
17976888252Smrg}
18076888252Smrg
18176888252Smrg
18276888252Smrg/* this one could be faster */
1831ae1b5e8Smrg_X_EXPORT void
18476888252SmrgcirRefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
18576888252Smrg{
18676888252Smrg    CirPtr pCir = CIRPTR(pScrn);
18763847c39Smrg    int count, width, height, x1, x2, y1, y2, dstPitch, srcPitch;
18876888252Smrg    CARD8 *dstPtr, *srcPtr, *src;
18976888252Smrg    CARD32 *dst;
19076888252Smrg
19176888252Smrg    dstPitch = BitmapBytePad(pScrn->displayWidth * 24);
19276888252Smrg    srcPitch = -pCir->rotate * pCir->ShadowPitch;
19376888252Smrg
19476888252Smrg    while(num--) {
19563847c39Smrg        x1 = MAX(pbox->x1, 0);
19663847c39Smrg        y1 = MAX(pbox->y1, 0);
19763847c39Smrg        x2 = MIN(pbox->x2, pScrn->virtualX);
19863847c39Smrg        y2 = MIN(pbox->y2, pScrn->virtualY);
19963847c39Smrg
20063847c39Smrg        width = x2 - x1;
20163847c39Smrg        y1 = y1 & ~3;
20263847c39Smrg        y2 = (y2 + 3) & ~3;
20363847c39Smrg        height = (y2 - y1) / 4;  /* blocks of 3 dwords */
20463847c39Smrg
20563847c39Smrg        if (width <= 0 || height <= 0)
20663847c39Smrg            continue;
20763847c39Smrg
20863847c39Smrg        if(pCir->rotate == 1) {
20963847c39Smrg            dstPtr = pCir->FbBase +
21063847c39Smrg			(x1 * dstPitch) + ((pScrn->virtualX - y2) * 3);
21163847c39Smrg            srcPtr = pCir->ShadowPtr + ((1 - y2) * srcPitch) + (x1 * 3);
21263847c39Smrg        } else {
21363847c39Smrg            dstPtr = pCir->FbBase +
21463847c39Smrg                ((pScrn->virtualY - x2) * dstPitch) + (y1 * 3);
21563847c39Smrg            srcPtr = pCir->ShadowPtr + (y1 * srcPitch) + (x2 * 3) - 3;
21663847c39Smrg        }
21763847c39Smrg
21863847c39Smrg        while(width--) {
21963847c39Smrg            src = srcPtr;
22063847c39Smrg            dst = (CARD32*)dstPtr;
22163847c39Smrg            count = height;
22263847c39Smrg            while(count--) {
22363847c39Smrg                dst[0] = src[0] | (src[1] << 8) | (src[2] << 16) |
22476888252Smrg				(src[srcPitch] << 24);
22563847c39Smrg                dst[1] = src[srcPitch + 1] | (src[srcPitch + 2] << 8) |
22676888252Smrg				(src[srcPitch * 2] << 16) |
22776888252Smrg				(src[(srcPitch * 2) + 1] << 24);
22863847c39Smrg                dst[2] = src[(srcPitch * 2) + 2] | (src[srcPitch * 3] << 8) |
22976888252Smrg				(src[(srcPitch * 3) + 1] << 16) |
23076888252Smrg				(src[(srcPitch * 3) + 2] << 24);
23163847c39Smrg                dst += 3;
23263847c39Smrg                src += srcPitch * 4;
23363847c39Smrg            }
23463847c39Smrg            srcPtr += pCir->rotate * 3;
23563847c39Smrg            dstPtr += dstPitch;
23663847c39Smrg        }
23763847c39Smrg
23863847c39Smrg        pbox++;
23976888252Smrg    }
24076888252Smrg}
24176888252Smrg
2421ae1b5e8Smrg_X_EXPORT void
24376888252SmrgcirRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
24476888252Smrg{
24576888252Smrg    CirPtr pCir = CIRPTR(pScrn);
24663847c39Smrg    int count, width, height, x1, x2, y1, y2, dstPitch, srcPitch;
24776888252Smrg    CARD32 *dstPtr, *srcPtr, *src, *dst;
24876888252Smrg
24976888252Smrg    dstPitch = pScrn->displayWidth;
25076888252Smrg    srcPitch = -pCir->rotate * pCir->ShadowPitch >> 2;
25176888252Smrg
25276888252Smrg    while(num--) {
25363847c39Smrg        x1 = MAX(pbox->x1, 0);
25463847c39Smrg        y1 = MAX(pbox->y1, 0);
25563847c39Smrg        x2 = MIN(pbox->x2, pScrn->virtualX);
25663847c39Smrg        y2 = MIN(pbox->y2, pScrn->virtualY);
25763847c39Smrg
25863847c39Smrg        width = x2 - x1;
25963847c39Smrg        height = y2 - y1;
26063847c39Smrg
26163847c39Smrg        if (width <= 0 || height <= 0)
26263847c39Smrg            continue;
26363847c39Smrg
26463847c39Smrg        if(pCir->rotate == 1) {
26563847c39Smrg            dstPtr = (CARD32*)pCir->FbBase +
26663847c39Smrg			(x1 * dstPitch) + pScrn->virtualX - y2;
26763847c39Smrg            srcPtr = (CARD32*)pCir->ShadowPtr +
26863847c39Smrg			((1 - y2) * srcPitch) + x1;
26963847c39Smrg        } else {
27063847c39Smrg            dstPtr = (CARD32*)pCir->FbBase +
27163847c39Smrg			((pScrn->virtualY - x2) * dstPitch) + y1;
27263847c39Smrg            srcPtr = (CARD32*)pCir->ShadowPtr +
27363847c39Smrg			(y1 * srcPitch) + x2 - 1;
27463847c39Smrg        }
27563847c39Smrg
27663847c39Smrg        while(width--) {
27763847c39Smrg            src = srcPtr;
27863847c39Smrg            dst = dstPtr;
27963847c39Smrg            count = height;
28063847c39Smrg            while(count--) {
28163847c39Smrg                *(dst++) = *src;
28263847c39Smrg                src += srcPitch;
28363847c39Smrg            }
28463847c39Smrg            srcPtr += pCir->rotate;
28563847c39Smrg            dstPtr += dstPitch;
28663847c39Smrg        }
28763847c39Smrg
28863847c39Smrg        pbox++;
28976888252Smrg    }
29076888252Smrg}
29176888252Smrg
29276888252Smrg
29376888252Smrg
294