1692f60a7Smrg 2692f60a7Smrg/* 3692f60a7Smrg Copyright (c) 1999, 2000 The XFree86 Project Inc. 4692f60a7Smrg based on code written by Mark Vojkovich <markv@valinux.com> 5692f60a7Smrg*/ 6692f60a7Smrg 7692f60a7Smrg#ifdef HAVE_CONFIG_H 8692f60a7Smrg#include "config.h" 9692f60a7Smrg#endif 10692f60a7Smrg 11692f60a7Smrg#include "xf86.h" 12692f60a7Smrg#include "xf86_OSproc.h" 13692f60a7Smrg#include "xf86Pci.h" 14692f60a7Smrg#include "shadowfb.h" 15692f60a7Smrg#include "servermd.h" 16692f60a7Smrg#include "neo.h" 17692f60a7Smrg 18692f60a7Smrgvoid 19692f60a7SmrgneoShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf) 20692f60a7Smrg{ 213f6d0e1dSmrg RegionPtr damage = DamageRegion(pBuf->pDamage); 22692f60a7Smrg ScrnInfoPtr pScrn; 233f6d0e1dSmrg pScrn = xf86ScreenToScrn(pScreen); 24692f60a7Smrg 25692f60a7Smrg (NEOPTR(pScrn))->refreshArea (pScrn, REGION_NUM_RECTS(damage), 26692f60a7Smrg REGION_RECTS(damage)); 27692f60a7Smrg} 28692f60a7Smrg 29692f60a7Smrgvoid 30692f60a7SmrgneoRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 31692f60a7Smrg{ 32692f60a7Smrg NEOPtr nPtr = NEOPTR(pScrn); 33692f60a7Smrg int width, height, Bpp, FBPitch; 34692f60a7Smrg unsigned char *src, *dst; 35692f60a7Smrg 36692f60a7Smrg Bpp = pScrn->bitsPerPixel >> 3; 37692f60a7Smrg FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel); 38692f60a7Smrg 39692f60a7Smrg while(num--) { 40692f60a7Smrg width = (pbox->x2 - pbox->x1) * Bpp; 41692f60a7Smrg height = pbox->y2 - pbox->y1; 42692f60a7Smrg src = nPtr->ShadowPtr + (pbox->y1 * nPtr->ShadowPitch) + 43692f60a7Smrg (pbox->x1 * Bpp); 44692f60a7Smrg dst = nPtr->NeoFbBase + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp); 45692f60a7Smrg 46692f60a7Smrg while(height--) { 47692f60a7Smrg memcpy(dst, src, width); 48692f60a7Smrg dst += FBPitch; 49692f60a7Smrg src += nPtr->ShadowPitch; 50692f60a7Smrg } 51692f60a7Smrg 52692f60a7Smrg pbox++; 53692f60a7Smrg } 54692f60a7Smrg} 55692f60a7Smrg 56692f60a7Smrgvoid 573f6d0e1dSmrgneoPointerMoved(SCRN_ARG_TYPE arg, int x, int y) 58692f60a7Smrg{ 593f6d0e1dSmrg SCRN_INFO_PTR(arg); 60692f60a7Smrg NEOPtr nPtr = NEOPTR(pScrn); 61692f60a7Smrg int newX, newY; 62692f60a7Smrg 63692f60a7Smrg if(nPtr->rotate == 1) { 64692f60a7Smrg newX = pScrn->pScreen->height - y - 1; 65692f60a7Smrg newY = x; 66692f60a7Smrg } else { 67692f60a7Smrg newX = y; 68692f60a7Smrg newY = pScrn->pScreen->width - x - 1; 69692f60a7Smrg } 70692f60a7Smrg 713f6d0e1dSmrg (*nPtr->PointerMoved)(arg, newX, newY); 72692f60a7Smrg} 73692f60a7Smrg 74692f60a7Smrgvoid 75692f60a7SmrgneoRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 76692f60a7Smrg{ 77692f60a7Smrg NEOPtr nPtr = NEOPTR(pScrn); 78692f60a7Smrg int count, width, height, y1, y2, dstPitch, srcPitch; 79692f60a7Smrg CARD8 *dstPtr, *srcPtr, *src; 80692f60a7Smrg CARD32 *dst; 81692f60a7Smrg 82692f60a7Smrg dstPitch = pScrn->displayWidth; 83692f60a7Smrg srcPitch = -nPtr->rotate * nPtr->ShadowPitch; 84692f60a7Smrg 85692f60a7Smrg while(num--) { 86692f60a7Smrg width = pbox->x2 - pbox->x1; 87692f60a7Smrg y1 = pbox->y1 & ~3; 88692f60a7Smrg y2 = (pbox->y2 + 3) & ~3; 89692f60a7Smrg height = (y2 - y1) >> 2; /* in dwords */ 90692f60a7Smrg 91692f60a7Smrg if(nPtr->rotate == 1) { 92692f60a7Smrg dstPtr = nPtr->NeoFbBase + 93692f60a7Smrg (pbox->x1 * dstPitch) + pScrn->virtualX - y2; 94692f60a7Smrg srcPtr = nPtr->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1; 95692f60a7Smrg } else { 96692f60a7Smrg dstPtr = nPtr->NeoFbBase + 97692f60a7Smrg ((pScrn->virtualY - pbox->x2) * dstPitch) + y1; 98692f60a7Smrg srcPtr = nPtr->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1; 99692f60a7Smrg } 100692f60a7Smrg 101692f60a7Smrg while(width--) { 102692f60a7Smrg src = srcPtr; 103692f60a7Smrg dst = (CARD32*)dstPtr; 104692f60a7Smrg count = height; 105692f60a7Smrg while(count--) { 106692f60a7Smrg *(dst++) = src[0] | (src[srcPitch] << 8) | 107692f60a7Smrg (src[srcPitch * 2] << 16) | 108692f60a7Smrg (src[srcPitch * 3] << 24); 109692f60a7Smrg src += srcPitch * 4; 110692f60a7Smrg } 111692f60a7Smrg srcPtr += nPtr->rotate; 112692f60a7Smrg dstPtr += dstPitch; 113692f60a7Smrg } 114692f60a7Smrg 115692f60a7Smrg pbox++; 116692f60a7Smrg } 117692f60a7Smrg} 118692f60a7Smrg 119692f60a7Smrg 120692f60a7Smrgvoid 121692f60a7SmrgneoRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 122692f60a7Smrg{ 123692f60a7Smrg NEOPtr nPtr = NEOPTR(pScrn); 124692f60a7Smrg int count, width, height, y1, y2, dstPitch, srcPitch; 125692f60a7Smrg CARD16 *dstPtr, *srcPtr, *src; 126692f60a7Smrg CARD32 *dst; 127692f60a7Smrg 128692f60a7Smrg dstPitch = pScrn->displayWidth; 129692f60a7Smrg srcPitch = -nPtr->rotate * nPtr->ShadowPitch >> 1; 130692f60a7Smrg 131692f60a7Smrg while(num--) { 132692f60a7Smrg width = pbox->x2 - pbox->x1; 133692f60a7Smrg y1 = pbox->y1 & ~1; 134692f60a7Smrg y2 = (pbox->y2 + 1) & ~1; 135692f60a7Smrg height = (y2 - y1) >> 1; /* in dwords */ 136692f60a7Smrg 137692f60a7Smrg if(nPtr->rotate == 1) { 138692f60a7Smrg dstPtr = (CARD16*)nPtr->NeoFbBase + 139692f60a7Smrg (pbox->x1 * dstPitch) + pScrn->virtualX - y2; 140692f60a7Smrg srcPtr = (CARD16*)nPtr->ShadowPtr + 141692f60a7Smrg ((1 - y2) * srcPitch) + pbox->x1; 142692f60a7Smrg } else { 143692f60a7Smrg dstPtr = (CARD16*)nPtr->NeoFbBase + 144692f60a7Smrg ((pScrn->virtualY - pbox->x2) * dstPitch) + y1; 145692f60a7Smrg srcPtr = (CARD16*)nPtr->ShadowPtr + 146692f60a7Smrg (y1 * srcPitch) + pbox->x2 - 1; 147692f60a7Smrg } 148692f60a7Smrg 149692f60a7Smrg while(width--) { 150692f60a7Smrg src = srcPtr; 151692f60a7Smrg dst = (CARD32*)dstPtr; 152692f60a7Smrg count = height; 153692f60a7Smrg while(count--) { 154692f60a7Smrg *(dst++) = src[0] | (src[srcPitch] << 16); 155692f60a7Smrg src += srcPitch * 2; 156692f60a7Smrg } 157692f60a7Smrg srcPtr += nPtr->rotate; 158692f60a7Smrg dstPtr += dstPitch; 159692f60a7Smrg } 160692f60a7Smrg 161692f60a7Smrg pbox++; 162692f60a7Smrg } 163692f60a7Smrg} 164692f60a7Smrg 165692f60a7Smrg 166692f60a7Smrg/* this one could be faster */ 167692f60a7Smrgvoid 168692f60a7SmrgneoRefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 169692f60a7Smrg{ 170692f60a7Smrg NEOPtr nPtr = NEOPTR(pScrn); 171692f60a7Smrg int count, width, height, y1, y2, dstPitch, srcPitch; 172692f60a7Smrg CARD8 *dstPtr, *srcPtr, *src; 173692f60a7Smrg CARD32 *dst; 174692f60a7Smrg 175692f60a7Smrg dstPitch = BitmapBytePad(pScrn->displayWidth * 24); 176692f60a7Smrg srcPitch = -nPtr->rotate * nPtr->ShadowPitch; 177692f60a7Smrg 178692f60a7Smrg while(num--) { 179692f60a7Smrg width = pbox->x2 - pbox->x1; 180692f60a7Smrg y1 = pbox->y1 & ~3; 181692f60a7Smrg y2 = (pbox->y2 + 3) & ~3; 182692f60a7Smrg height = (y2 - y1) >> 2; /* blocks of 3 dwords */ 183692f60a7Smrg 184692f60a7Smrg if(nPtr->rotate == 1) { 185692f60a7Smrg dstPtr = nPtr->NeoFbBase + 186692f60a7Smrg (pbox->x1 * dstPitch) + ((pScrn->virtualX - y2) * 3); 187692f60a7Smrg srcPtr = nPtr->ShadowPtr + ((1 - y2) * srcPitch) + (pbox->x1 * 3); 188692f60a7Smrg } else { 189692f60a7Smrg dstPtr = nPtr->NeoFbBase + 190692f60a7Smrg ((pScrn->virtualY - pbox->x2) * dstPitch) + (y1 * 3); 191692f60a7Smrg srcPtr = nPtr->ShadowPtr + (y1 * srcPitch) + (pbox->x2 * 3) - 3; 192692f60a7Smrg } 193692f60a7Smrg 194692f60a7Smrg while(width--) { 195692f60a7Smrg src = srcPtr; 196692f60a7Smrg dst = (CARD32*)dstPtr; 197692f60a7Smrg count = height; 198692f60a7Smrg while(count--) { 199692f60a7Smrg dst[0] = src[0] | (src[1] << 8) | (src[2] << 16) | 200692f60a7Smrg (src[srcPitch] << 24); 201692f60a7Smrg dst[1] = src[srcPitch + 1] | (src[srcPitch + 2] << 8) | 202692f60a7Smrg (src[srcPitch * 2] << 16) | 203692f60a7Smrg (src[(srcPitch * 2) + 1] << 24); 204692f60a7Smrg dst[2] = src[(srcPitch * 2) + 2] | (src[srcPitch * 3] << 8) | 205692f60a7Smrg (src[(srcPitch * 3) + 1] << 16) | 206692f60a7Smrg (src[(srcPitch * 3) + 2] << 24); 207692f60a7Smrg dst += 3; 208692f60a7Smrg src += srcPitch * 4; 209692f60a7Smrg } 210692f60a7Smrg srcPtr += nPtr->rotate * 3; 211692f60a7Smrg dstPtr += dstPitch; 212692f60a7Smrg } 213692f60a7Smrg 214692f60a7Smrg pbox++; 215692f60a7Smrg } 216692f60a7Smrg} 217692f60a7Smrg 218692f60a7Smrgvoid 219692f60a7SmrgneoRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 220692f60a7Smrg{ 221692f60a7Smrg NEOPtr nPtr = NEOPTR(pScrn); 222692f60a7Smrg int count, width, height, dstPitch, srcPitch; 223692f60a7Smrg CARD32 *dstPtr, *srcPtr, *src, *dst; 224692f60a7Smrg 225692f60a7Smrg dstPitch = pScrn->displayWidth; 226692f60a7Smrg srcPitch = -nPtr->rotate * nPtr->ShadowPitch >> 2; 227692f60a7Smrg 228692f60a7Smrg while(num--) { 229692f60a7Smrg width = pbox->x2 - pbox->x1; 230692f60a7Smrg height = pbox->y2 - pbox->y1; 231692f60a7Smrg 232692f60a7Smrg if(nPtr->rotate == 1) { 233692f60a7Smrg dstPtr = (CARD32*)nPtr->NeoFbBase + 234692f60a7Smrg (pbox->x1 * dstPitch) + pScrn->virtualX - pbox->y2; 235692f60a7Smrg srcPtr = (CARD32*)nPtr->ShadowPtr + 236692f60a7Smrg ((1 - pbox->y2) * srcPitch) + pbox->x1; 237692f60a7Smrg } else { 238692f60a7Smrg dstPtr = (CARD32*)nPtr->NeoFbBase + 239692f60a7Smrg ((pScrn->virtualY - pbox->x2) * dstPitch) + pbox->y1; 240692f60a7Smrg srcPtr = (CARD32*)nPtr->ShadowPtr + 241692f60a7Smrg (pbox->y1 * srcPitch) + pbox->x2 - 1; 242692f60a7Smrg } 243692f60a7Smrg 244692f60a7Smrg while(width--) { 245692f60a7Smrg src = srcPtr; 246692f60a7Smrg dst = dstPtr; 247692f60a7Smrg count = height; 248692f60a7Smrg while(count--) { 249692f60a7Smrg *(dst++) = *src; 250692f60a7Smrg src += srcPitch; 251692f60a7Smrg } 252692f60a7Smrg srcPtr += nPtr->rotate; 253692f60a7Smrg dstPtr += dstPitch; 254692f60a7Smrg } 255692f60a7Smrg 256692f60a7Smrg pbox++; 257692f60a7Smrg } 258692f60a7Smrg} 259692f60a7Smrg 260692f60a7Smrg 261692f60a7Smrg 262