diff options
Diffstat (limited to 'src/alp_hwcurs.c')
-rw-r--r-- | src/alp_hwcurs.c | 258 |
1 files changed, 258 insertions, 0 deletions
diff --git a/src/alp_hwcurs.c b/src/alp_hwcurs.c new file mode 100644 index 0000000..a4f0581 --- /dev/null +++ b/src/alp_hwcurs.c @@ -0,0 +1,258 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cirrus/alp_hwcurs.c,v 1.5 2001/05/07 21:59:06 tsi Exp $ */ + +/* (c) Itai Nahshon */ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" +#include "compiler.h" + +#include "xf86Pci.h" +#include "xf86PciInfo.h" + +#include "vgaHW.h" + +#include "cir.h" +#define _ALP_PRIVATE_ +#include "alp.h" + +#define CURSORWIDTH pAlp->CursorWidth +#define CURSORHEIGHT pAlp->CursorHeight +#define CURSORSIZE (CURSORWIDTH*CURSORHEIGHT/8) +#define MAXCURSORSIZE (64*64>>3) + +static void +AlpSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) +{ + const AlpPtr pAlp = ALPPTR(CIRPTR(pScrn)); + vgaHWPtr hwp = VGAHWPTR(pScrn); +#ifdef ALP_DEBUG + ErrorF("AlpSetCursorColors\n"); +#endif + hwp->writeSeq(hwp, 0x12, pAlp->ModeReg.ExtVga[SR12]|0x02); + hwp->writeDacWriteAddr(hwp, 0x00); + hwp->writeDacData(hwp, 0x3f & (bg >> 18)); + hwp->writeDacData(hwp, 0x3f & (bg >> 10)); + hwp->writeDacData(hwp, 0x3f & (bg >> 2)); + hwp->writeDacWriteAddr(hwp, 0x0F); + hwp->writeDacData(hwp, 0x3F & (fg >> 18)); + hwp->writeDacData(hwp, 0x3F & (fg >> 10)); + hwp->writeDacData(hwp, 0x3F & (fg >> 2)); + hwp->writeSeq(hwp, 0x12, pAlp->ModeReg.ExtVga[SR12]); +} + +static void +AlpLoadSkewedCursor(CirPtr pCir, int x, int y) { + + const AlpPtr pAlp = ALPPTR(pCir); + + unsigned char *memx = pAlp->HWCursorBits; + unsigned char *CursorBits = pAlp->CursorBits; + + unsigned char mem[2*MAXCURSORSIZE]; + unsigned char *p1, *p2; + int i, j, m, a, b; + Bool cur64 = (CURSORWIDTH == 64); + int shift = (cur64? 1 : 0); + + if (x > 0) x = 0; else x = -x; + if (y > 0) y = 0; else y = -y; + + + a = ((y*CURSORWIDTH<<shift)+x)>>3; + b = x & 7; + + /* Copy the skewed mask bits */ + p1 = mem; + p2 = CursorBits + a; + for (i = 0; i < (CURSORSIZE << shift)-a-1; i++) { + *p1++ = (p2[0] << b) | (p2[1] >> (8-b)); + p2++; + } + /* last mask byte */ + *p1++ = (p2[0] << b); + + /* Clear to end (bottom) of mask. */ + for (i = i+1; i < (CURSORSIZE << shift); i++) + *p1++ = 0; + + if (!cur64) { + /* Now copy the cursor bits */ + /* p1 is already right */ + p2 = CursorBits+CURSORSIZE+a; + for (i = 0; i < CURSORSIZE-a-1; i++) { + *p1++ = (p2[0] << b) | (p2[1] >> (8-b)); + p2++; + } + /* last cursor byte */ + *p1++ = (p2[0] << b); + } + + /* Clear to end (bottom) of cursor. */ + for (i = i+1; i < CURSORSIZE; i++) + *p1++ = 0; + + /* Clear the right unused area of the mask + and cyrsor bits. */ + p2 = mem + CURSORWIDTH/8 - (x>>3) - 1; + for (i = 0; i < 2*CURSORHEIGHT; i++) { + m = (-1)<<(x&7); + p1 = p2; + p2 += CURSORWIDTH/8; + for (j = x>>3; j >= 0; j--) { + *p1 &= m; + m = 0; + p1++; + } + } + memcpy(memx, mem, 2*CURSORSIZE); +} + + +static void +AlpSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) +{ + const CirPtr pCir = CIRPTR(pScrn); + const AlpPtr pAlp = ALPPTR(pCir); + vgaHWPtr hwp = VGAHWPTR(pScrn); + +#if 0 +#ifdef ALP_DEBUG + ErrorF("AlpSetCursorPosition %d %d\n", x, y); +#endif +#endif + + if (x < 0 || y < 0) { + if (x+CURSORWIDTH <= 0 || y+CURSORHEIGHT <= 0) { + hwp->writeSeq(hwp, 0x12, pAlp->ModeReg.ExtVga[SR12] & ~0x01); + return; + } + AlpLoadSkewedCursor(pCir, x, y); + pCir->CursorIsSkewed = TRUE; + if (x < 0) x = 0; + if (y < 0) y = 0; + } else if (pCir->CursorIsSkewed) { + memcpy(pAlp->HWCursorBits, pAlp->CursorBits, 2*CURSORSIZE); + pCir->CursorIsSkewed = FALSE; + } + hwp->writeSeq(hwp, 0x12, pAlp->ModeReg.ExtVga[SR12]); + hwp->writeSeq(hwp, ((x << 5)|0x10)&0xff, x >> 3); + hwp->writeSeq(hwp, ((y << 5)|0x11)&0xff, y >> 3); +} + +static void +AlpLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *bits) +{ + const AlpPtr pAlp = ALPPTR(CIRPTR(pScrn)); + vgaHWPtr hwp = VGAHWPTR(pScrn); + +#ifdef ALP_DEBUG + ErrorF("AlpLoadCursorImage\n"); +#endif + + pAlp->CursorBits = bits; + memcpy(pAlp->HWCursorBits, bits, 2*CURSORSIZE); + /* this should work for both 64 and 32 bit cursors */ + pAlp->ModeReg.ExtVga[SR13] = 0x3f; + hwp->writeSeq(hwp, 0x13, pAlp->ModeReg.ExtVga[SR13]); +} + +static void +AlpHideCursor(ScrnInfoPtr pScrn) +{ + AlpPtr pAlp = ALPPTR(CIRPTR(pScrn)); + vgaHWPtr hwp = VGAHWPTR(pScrn); + +#ifdef ALP_DEBUG + ErrorF("AlpHideCursor\n"); +#endif + pAlp->ModeReg.ExtVga[SR12] &= ~0x01; + hwp->writeSeq(hwp, 0x12, pAlp->ModeReg.ExtVga[SR12]); +} + +static void +AlpShowCursor(ScrnInfoPtr pScrn) +{ + AlpPtr pAlp = ALPPTR(CIRPTR(pScrn)); + vgaHWPtr hwp = VGAHWPTR(pScrn); + +#ifdef ALP_DEBUG + ErrorF("AlpShowCursor\n"); +#endif + pAlp->ModeReg.ExtVga[SR12] |= 0x01; + hwp->writeSeq(hwp, 0x12, pAlp->ModeReg.ExtVga[SR12]); +} + +static Bool +AlpUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; +#ifdef ALP_DEBUG + ErrorF("AlpUseHWCursor\n"); +#endif + if (pScrn->bitsPerPixel < 8) + return FALSE; + + return TRUE; +} + +Bool +AlpHWCursorInit(ScreenPtr pScreen, int size) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + const CirPtr pCir = CIRPTR(pScrn); + const AlpPtr pAlp = ALPPTR(pCir); + + xf86CursorInfoPtr infoPtr; + +#ifdef ALP_DEBUG + ErrorF("AlpHWCursorInit\n"); +#endif + if (!size) return FALSE; + + infoPtr = xf86CreateCursorInfoRec(); + if (!infoPtr) return FALSE; + + pCir->CursorInfoRec = infoPtr; + pCir->CursorIsSkewed = FALSE; + pAlp->CursorBits = NULL; + + if (size == 64) + CURSORWIDTH = CURSORHEIGHT = 64; + else + CURSORWIDTH = CURSORHEIGHT = 32; + + pAlp->HWCursorBits = pCir->FbBase + 1024*pScrn->videoRam - 2*CURSORSIZE; + + infoPtr->MaxWidth = CURSORWIDTH; + infoPtr->MaxHeight = CURSORHEIGHT; + if (CURSORWIDTH == 64) + infoPtr->Flags = +#if X_BYTE_ORDER == X_LITTLE_ENDIAN + HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | +#endif + HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 | + HARDWARE_CURSOR_TRUECOLOR_AT_8BPP; + else + infoPtr->Flags = +#if X_BYTE_ORDER == X_LITTLE_ENDIAN + HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | +#endif + HARDWARE_CURSOR_TRUECOLOR_AT_8BPP; + + infoPtr->SetCursorColors = AlpSetCursorColors; + infoPtr->SetCursorPosition = AlpSetCursorPosition; + infoPtr->LoadCursorImage = AlpLoadCursorImage; + infoPtr->HideCursor = AlpHideCursor; + infoPtr->ShowCursor = AlpShowCursor; + infoPtr->UseHWCursor = AlpUseHWCursor; + +#ifdef ALP_DEBUG + ErrorF("AlpHWCursorInit before xf86InitCursor\n"); +#endif + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Hardware cursor: %ix%i\n", + CURSORWIDTH,CURSORHEIGHT); + return(xf86InitCursor(pScreen, infoPtr)); +} + + |