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