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