alp_hwcurs.c revision 76888252
176888252Smrg/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cirrus/alp_hwcurs.c,v 1.4 2000/12/06 15:35:15 eich Exp $ */ 276888252Smrg 376888252Smrg#ifdef HAVE_CONFIG_H 476888252Smrg#include "config.h" 576888252Smrg#endif 676888252Smrg 776888252Smrg/* (c) Itai Nahshon */ 876888252Smrg 976888252Smrg#include "xf86.h" 1076888252Smrg#include "xf86_OSproc.h" 1176888252Smrg#include "compiler.h" 1276888252Smrg 1376888252Smrg#include "xf86Pci.h" 1476888252Smrg#include "xf86PciInfo.h" 1576888252Smrg 1676888252Smrg#include "vgaHW.h" 1776888252Smrg 1876888252Smrg#include "cir.h" 1976888252Smrg#define _ALP_PRIVATE_ 2076888252Smrg#include "alp.h" 2176888252Smrg 2276888252Smrg#define CURSORWIDTH pAlp->CursorWidth 2376888252Smrg#define CURSORHEIGHT pAlp->CursorHeight 2476888252Smrg#define CURSORSIZE (CURSORWIDTH*CURSORHEIGHT/8) 2576888252Smrg#define MAXCURSORSIZE (64*64>>3) 2676888252Smrg 2776888252Smrgstatic void 2876888252SmrgAlpSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) 2976888252Smrg{ 3076888252Smrg const AlpPtr pAlp = ALPPTR(CIRPTR(pScrn)); 3176888252Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 3276888252Smrg#ifdef ALP_DEBUG 3376888252Smrg ErrorF("AlpSetCursorColors\n"); 3476888252Smrg#endif 3576888252Smrg hwp->writeSeq(hwp, 0x12, pAlp->ModeReg.ExtVga[SR12]|0x02); 3676888252Smrg hwp->writeDacWriteAddr(hwp, 0x00); 3776888252Smrg hwp->writeDacData(hwp, 0x3f & (bg >> 18)); 3876888252Smrg hwp->writeDacData(hwp, 0x3f & (bg >> 10)); 3976888252Smrg hwp->writeDacData(hwp, 0x3f & (bg >> 2)); 4076888252Smrg hwp->writeDacWriteAddr(hwp, 0x0F); 4176888252Smrg hwp->writeDacData(hwp, 0x3F & (fg >> 18)); 4276888252Smrg hwp->writeDacData(hwp, 0x3F & (fg >> 10)); 4376888252Smrg hwp->writeDacData(hwp, 0x3F & (fg >> 2)); 4476888252Smrg hwp->writeSeq(hwp, 0x12, pAlp->ModeReg.ExtVga[SR12]); 4576888252Smrg} 4676888252Smrg 4776888252Smrgstatic void 4876888252SmrgAlpLoadSkewedCursor(CirPtr pCir, int x, int y) { 4976888252Smrg 5076888252Smrg const AlpPtr pAlp = ALPPTR(pCir); 5176888252Smrg 5276888252Smrg unsigned char *memx = pAlp->HWCursorBits; 5376888252Smrg unsigned char *CursorBits = pAlp->CursorBits; 5476888252Smrg 5576888252Smrg unsigned char mem[2*MAXCURSORSIZE]; 5676888252Smrg unsigned char *p1, *p2; 5776888252Smrg int i, j, m, a, b; 5876888252Smrg Bool cur64 = (CURSORWIDTH == 64); 5976888252Smrg int shift = (cur64? 1 : 0); 6076888252Smrg 6176888252Smrg if (x > 0) x = 0; else x = -x; 6276888252Smrg if (y > 0) y = 0; else y = -y; 6376888252Smrg 6476888252Smrg 6576888252Smrg a = ((y*CURSORWIDTH<<shift)+x)>>3; 6676888252Smrg b = x & 7; 6776888252Smrg 6876888252Smrg /* Copy the skewed mask bits */ 6976888252Smrg p1 = mem; 7076888252Smrg p2 = CursorBits + a; 7176888252Smrg for (i = 0; i < (CURSORSIZE << shift)-a-1; i++) { 7276888252Smrg *p1++ = (p2[0] << b) | (p2[1] >> (8-b)); 7376888252Smrg p2++; 7476888252Smrg } 7576888252Smrg /* last mask byte */ 7676888252Smrg *p1++ = (p2[0] << b); 7776888252Smrg 7876888252Smrg /* Clear to end (bottom) of mask. */ 7976888252Smrg for (i = i+1; i < (CURSORSIZE << shift); i++) 8076888252Smrg *p1++ = 0; 8176888252Smrg 8276888252Smrg if (!cur64) { 8376888252Smrg /* Now copy the cursor bits */ 8476888252Smrg /* p1 is already right */ 8576888252Smrg p2 = CursorBits+CURSORSIZE+a; 8676888252Smrg for (i = 0; i < CURSORSIZE-a-1; i++) { 8776888252Smrg *p1++ = (p2[0] << b) | (p2[1] >> (8-b)); 8876888252Smrg p2++; 8976888252Smrg } 9076888252Smrg /* last cursor byte */ 9176888252Smrg *p1++ = (p2[0] << b); 9276888252Smrg } 9376888252Smrg 9476888252Smrg /* Clear to end (bottom) of cursor. */ 9576888252Smrg for (i = i+1; i < CURSORSIZE; i++) 9676888252Smrg *p1++ = 0; 9776888252Smrg 9876888252Smrg /* Clear the right unused area of the mask 9976888252Smrg and cyrsor bits. */ 10076888252Smrg p2 = mem + CURSORWIDTH/8 - (x>>3) - 1; 10176888252Smrg for (i = 0; i < 2*CURSORHEIGHT; i++) { 10276888252Smrg m = (-1)<<(x&7); 10376888252Smrg p1 = p2; 10476888252Smrg p2 += CURSORWIDTH/8; 10576888252Smrg for (j = x>>3; j >= 0; j--) { 10676888252Smrg *p1 &= m; 10776888252Smrg m = 0; 10876888252Smrg p1++; 10976888252Smrg } 11076888252Smrg } 11176888252Smrg memcpy(memx, mem, 2*CURSORSIZE); 11276888252Smrg} 11376888252Smrg 11476888252Smrg 11576888252Smrgstatic void 11676888252SmrgAlpSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) 11776888252Smrg{ 11876888252Smrg const CirPtr pCir = CIRPTR(pScrn); 11976888252Smrg const AlpPtr pAlp = ALPPTR(pCir); 12076888252Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 12176888252Smrg 12276888252Smrg#if 0 12376888252Smrg#ifdef ALP_DEBUG 12476888252Smrg ErrorF("AlpSetCursorPosition %d %d\n", x, y); 12576888252Smrg#endif 12676888252Smrg#endif 12776888252Smrg 12876888252Smrg if (x < 0 || y < 0) { 12976888252Smrg if (x+CURSORWIDTH <= 0 || y+CURSORHEIGHT <= 0) { 13076888252Smrg hwp->writeSeq(hwp, 0x12, pAlp->ModeReg.ExtVga[SR12] & ~0x01); 13176888252Smrg return; 13276888252Smrg } 13376888252Smrg AlpLoadSkewedCursor(pCir, x, y); 13476888252Smrg pCir->CursorIsSkewed = TRUE; 13576888252Smrg if (x < 0) x = 0; 13676888252Smrg if (y < 0) y = 0; 13776888252Smrg } else if (pCir->CursorIsSkewed) { 13876888252Smrg memcpy(pAlp->HWCursorBits, pAlp->CursorBits, 2*CURSORSIZE); 13976888252Smrg pCir->CursorIsSkewed = FALSE; 14076888252Smrg } 14176888252Smrg hwp->writeSeq(hwp, 0x12, pAlp->ModeReg.ExtVga[SR12]); 14276888252Smrg hwp->writeSeq(hwp, ((x << 5)|0x10)&0xff, x >> 3); 14376888252Smrg hwp->writeSeq(hwp, ((y << 5)|0x11)&0xff, y >> 3); 14476888252Smrg} 14576888252Smrg 14676888252Smrgstatic void 14776888252SmrgAlpLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *bits) 14876888252Smrg{ 14976888252Smrg const AlpPtr pAlp = ALPPTR(CIRPTR(pScrn)); 15076888252Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 15176888252Smrg 15276888252Smrg#ifdef ALP_DEBUG 15376888252Smrg ErrorF("AlpLoadCursorImage\n"); 15476888252Smrg#endif 15576888252Smrg 15676888252Smrg pAlp->CursorBits = bits; 15776888252Smrg memcpy(pAlp->HWCursorBits, bits, 2*CURSORSIZE); 15876888252Smrg /* this should work for both 64 and 32 bit cursors */ 15976888252Smrg pAlp->ModeReg.ExtVga[SR13] = 0x3f; 16076888252Smrg hwp->writeSeq(hwp, 0x13, pAlp->ModeReg.ExtVga[SR13]); 16176888252Smrg} 16276888252Smrg 16376888252Smrgstatic void 16476888252SmrgAlpHideCursor(ScrnInfoPtr pScrn) 16576888252Smrg{ 16676888252Smrg AlpPtr pAlp = ALPPTR(CIRPTR(pScrn)); 16776888252Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 16876888252Smrg 16976888252Smrg#ifdef ALP_DEBUG 17076888252Smrg ErrorF("AlpHideCursor\n"); 17176888252Smrg#endif 17276888252Smrg pAlp->ModeReg.ExtVga[SR12] &= ~0x01; 17376888252Smrg hwp->writeSeq(hwp, 0x12, pAlp->ModeReg.ExtVga[SR12]); 17476888252Smrg} 17576888252Smrg 17676888252Smrgstatic void 17776888252SmrgAlpShowCursor(ScrnInfoPtr pScrn) 17876888252Smrg{ 17976888252Smrg AlpPtr pAlp = ALPPTR(CIRPTR(pScrn)); 18076888252Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 18176888252Smrg 18276888252Smrg#ifdef ALP_DEBUG 18376888252Smrg ErrorF("AlpShowCursor\n"); 18476888252Smrg#endif 18576888252Smrg pAlp->ModeReg.ExtVga[SR12] |= 0x01; 18676888252Smrg hwp->writeSeq(hwp, 0x12, pAlp->ModeReg.ExtVga[SR12]); 18776888252Smrg} 18876888252Smrg 18976888252Smrgstatic Bool 19076888252SmrgAlpUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) 19176888252Smrg{ 19276888252Smrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 19376888252Smrg#ifdef ALP_DEBUG 19476888252Smrg ErrorF("AlpUseHWCursor\n"); 19576888252Smrg#endif 19676888252Smrg if (pScrn->bitsPerPixel < 8) 19776888252Smrg return FALSE; 19876888252Smrg 19976888252Smrg return TRUE; 20076888252Smrg} 20176888252Smrg 20276888252SmrgBool 20376888252SmrgAlpHWCursorInit(ScreenPtr pScreen, int size) 20476888252Smrg{ 20576888252Smrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 20676888252Smrg const CirPtr pCir = CIRPTR(pScrn); 20776888252Smrg const AlpPtr pAlp = ALPPTR(pCir); 20876888252Smrg 20976888252Smrg xf86CursorInfoPtr infoPtr; 21076888252Smrg 21176888252Smrg#ifdef ALP_DEBUG 21276888252Smrg ErrorF("AlpHWCursorInit\n"); 21376888252Smrg#endif 21476888252Smrg if (!size) return FALSE; 21576888252Smrg 21676888252Smrg infoPtr = xf86CreateCursorInfoRec(); 21776888252Smrg if (!infoPtr) return FALSE; 21876888252Smrg 21976888252Smrg pCir->CursorInfoRec = infoPtr; 22076888252Smrg pCir->CursorIsSkewed = FALSE; 22176888252Smrg pAlp->CursorBits = NULL; 22276888252Smrg 22376888252Smrg if (size == 64) 22476888252Smrg CURSORWIDTH = CURSORHEIGHT = 64; 22576888252Smrg else 22676888252Smrg CURSORWIDTH = CURSORHEIGHT = 32; 22776888252Smrg 22876888252Smrg pAlp->HWCursorBits = pCir->FbBase + 1024*pScrn->videoRam - 2*CURSORSIZE; 22976888252Smrg 23076888252Smrg infoPtr->MaxWidth = CURSORWIDTH; 23176888252Smrg infoPtr->MaxHeight = CURSORHEIGHT; 23276888252Smrg if (CURSORWIDTH == 64) 23376888252Smrg infoPtr->Flags = 23476888252Smrg#if X_BYTE_ORDER == X_LITTLE_ENDIAN 23576888252Smrg HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | 23676888252Smrg#endif 23776888252Smrg HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 | 23876888252Smrg HARDWARE_CURSOR_TRUECOLOR_AT_8BPP; 23976888252Smrg else 24076888252Smrg infoPtr->Flags = 24176888252Smrg#if X_BYTE_ORDER == X_LITTLE_ENDIAN 24276888252Smrg HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | 24376888252Smrg#endif 24476888252Smrg HARDWARE_CURSOR_TRUECOLOR_AT_8BPP; 24576888252Smrg 24676888252Smrg infoPtr->SetCursorColors = AlpSetCursorColors; 24776888252Smrg infoPtr->SetCursorPosition = AlpSetCursorPosition; 24876888252Smrg infoPtr->LoadCursorImage = AlpLoadCursorImage; 24976888252Smrg infoPtr->HideCursor = AlpHideCursor; 25076888252Smrg infoPtr->ShowCursor = AlpShowCursor; 25176888252Smrg infoPtr->UseHWCursor = AlpUseHWCursor; 25276888252Smrg 25376888252Smrg#ifdef ALP_DEBUG 25476888252Smrg ErrorF("AlpHWCursorInit before xf86InitCursor\n"); 25576888252Smrg#endif 25676888252Smrg xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Hardware cursor: %ix%i\n", 25776888252Smrg CURSORWIDTH,CURSORHEIGHT); 25876888252Smrg return(xf86InitCursor(pScreen, infoPtr)); 25976888252Smrg} 26076888252Smrg 26176888252Smrg 262