diff options
Diffstat (limited to 'src/apm_cursor.c')
-rw-r--r-- | src/apm_cursor.c | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/src/apm_cursor.c b/src/apm_cursor.c new file mode 100644 index 0000000..4bf0f98 --- /dev/null +++ b/src/apm_cursor.c @@ -0,0 +1,208 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/apm/apm_cursor.c,v 1.14 2000/06/30 18:27:02 dawes Exp $ */ + + +#include "X.h" +#include "Xproto.h" +#include "misc.h" +#include "input.h" +#include "cursorstr.h" +#include "regionstr.h" +#include "scrnintstr.h" +#include "servermd.h" +#include "windowstr.h" +#include "mfb.h" +#include "mipointer.h" + +#include "apm.h" + +#define CURSORWIDTH 64 +#define CURSORHEIGHT 64 +#define CURSORSIZE (CURSORWIDTH * CURSORHEIGHT / 8) +#define CURSORALIGN ((CURSORSIZE + 1023) & ~1023l) + +static void ApmShowCursor(ScrnInfoPtr pScrn); +static void ApmHideCursor(ScrnInfoPtr pScrn); +static void ApmSetCursorPosition(ScrnInfoPtr pScrn, int x, int y); +static void ApmSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg); +static void ApmLoadCursorImage(ScrnInfoPtr pScrn, u8* data); +static Bool ApmUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs); + +static u8 ConvertTable[256]; + +/* Inline functions */ +static __inline__ void +WaitForFifo(ApmPtr pApm, int slots) +{ + if (!pApm->UsePCIRetry) { + volatile int i; +#define MAXLOOP 1000000 + + for(i = 0; i < MAXLOOP; i++) { + if ((STATUS() & STATUS_FIFO) >= slots) + break; + } + if (i == MAXLOOP) { + unsigned int status = STATUS(); + + WRXB(0x1FF, 0); + if (!xf86ServerIsExiting()) + FatalError("Hung in WaitForFifo() (Status = 0x%08X)\n", status); + } + } +} + +void ApmHWCursorReserveSpace(ApmPtr pApm) +{ + pApm->OffscreenReserved += 2 * CURSORALIGN; + pApm->DisplayedCursorAddress = pApm->BaseCursorAddress = + pApm->CursorAddress = 1024 * xf86Screens[pApm->pScreen->myNum]->videoRam - + pApm->OffscreenReserved; +} + + +int ApmHWCursorInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + APMDECL(pScrn); + xf86CursorInfoPtr infoPtr; + u32 i; + + infoPtr = xf86CreateCursorInfoRec(); + if (!infoPtr) + return FALSE; + + pApm->CursorInfoRec = infoPtr; + + infoPtr->MaxWidth = CURSORWIDTH; + infoPtr->MaxHeight = CURSORHEIGHT; + + infoPtr->Flags = HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1; + infoPtr->SetCursorColors = ApmSetCursorColors; + infoPtr->SetCursorPosition = ApmSetCursorPosition; + infoPtr->LoadCursorImage = ApmLoadCursorImage; + infoPtr->HideCursor = ApmHideCursor; + infoPtr->ShowCursor = ApmShowCursor; + infoPtr->UseHWCursor = ApmUseHWCursor; + + /*ErrorF("%s %s: %s: Using hardware cursor (XAA).\n", + XCONFIG_PROBED, vga256InfoRec.name, vga256InfoRec.chipset); + + if(XAACursorInfoRec.Flags & USE_HARDWARE_CURSOR) { + vgaHWCursor.Init = XAACursorInit; + vgaHWCursor.Initialized = TRUE; + vgaHWCursor.Restore = XAARestoreCursor; + vgaHWCursor.Warp = XAAWarpCursor; + vgaHWCursor.QueryBestSize = XAAQueryBestSize; + }*/ + + /* Set up the convert table for the input cursor data */ + for (i = 0; i < 256; i++) + ConvertTable[i] = ((~i) & 0xAA) | (i & (i >> 1) & 0x55); + + return xf86InitCursor(pScreen, infoPtr); +} + + +static void +ApmShowCursor(ScrnInfoPtr pScrn) +{ + APMDECL(pScrn); + + WaitForFifo(pApm, 2); + WRXW(0x144, pApm->CursorAddress >> 10); + WRXB(0x140, 1); + pApm->DisplayedCursorAddress = pApm->CursorAddress; +} + + +static void +ApmHideCursor(ScrnInfoPtr pScrn) +{ + APMDECL(pScrn); + + WaitForFifo(pApm, 1); + WRXB(0x140, 0); +} + +static Bool ApmUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) +{ + return APMPTR(xf86Screens[pScreen->myNum])->CurrentLayout.bitsPerPixel >= 8; +} + +static void +ApmSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) +{ + APMDECL(pScrn); + int xoff, yoff; + + if (x < -CURSORWIDTH || y < -CURSORHEIGHT) { + WaitForFifo(pApm, 1); + WRXB(0x140, 0); + return; + } + + if (x < 0) { + xoff = -x; + x = 0; + } + else + xoff = 0; + if (y < 0) { + yoff = -y; + y = 0; + } + else + yoff = 0; + + WaitForFifo(pApm, 2); + WRXW(0x14C, (yoff << 8) | (xoff & 0xFF)); + WRXL(0x148, (y << 16) | (x & 0xFFFF)); +} + + +static void +ApmSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) +{ + APMDECL(pScrn); + u16 packedcolfg, packedcolbg; + + if (pApm->CurrentLayout.bitsPerPixel == 8) + { + WaitForFifo(pApm, 2); + WRXB(0x141, fg); + WRXB(0x142, bg); + } + else + { + packedcolfg = + ((fg & 0xE00000) >> 16) | + ((fg & 0x00E000) >> 11) | + ((fg & 0x0000C0) >> 6); + packedcolbg = + ((bg & 0xE00000) >> 16) | + ((bg & 0x00E000) >> 11) | + ((bg & 0x0000C0) >> 6); + WaitForFifo(pApm, 2); + WRXB(0x141, packedcolfg); + WRXB(0x142, packedcolbg); + } +} + + +static void +ApmLoadCursorImage(ScrnInfoPtr pScrn, u8* data) +{ + APMDECL(pScrn); + u32 i; + u8 tmp[2 * CURSORSIZE]; + + /* Correct input data */ + for (i = 0; i < sizeof tmp; i++) + tmp[i] = ConvertTable[data[i]]; + /* + * To avoid flicker. + * Note: 2*pApm->BaseCursorAddress + CURSORALIGN (=1024) < 2^31 all the time. + */ + pApm->CursorAddress = 2*pApm->BaseCursorAddress + CURSORALIGN - pApm->DisplayedCursorAddress; + memcpy((u8*)pApm->FbBase + pApm->CursorAddress, tmp, sizeof tmp); +} |